![見出し画像](https://assets.st-note.com/production/uploads/images/64581091/rectangle_large_type_2_f585d5d2b1908e6593a4743559cbe224.png?width=1200)
Notes C API探訪: NSFFormulaCompileをラップ
以前の記事で、何回かに分けて@式の扱い方について紹介しました。
NSFFormulaCompile(関数)
式ハンドルの使用方法(その1)
式ハンドルの使用方法(その2)
@式のデコンパイル
今回は、このうちのNSFFormulaCompile関数を使ったラップクラスを作ってみます。
#ifndef NXPP_FORMULA_HPP
#define NXPP_FORMULA_HPP
#include "./nxpp_status.hpp"
#include "./lmbcs/nxpp_lmbcs.hpp"
#include <memory>
#ifdef NT
#pragma pack(push, 1)
#endif
#include <global.h>
#include <nsfsearc.h>
#include <osmem.h>
#ifdef NT
#pragma pack(pop)
#endif
namespace nxpp {
class Formula;
using FormulaPtr = std::shared_ptr<Formula>;
/**
* @brief @式クラス
*/
class Formula
{
FORMULAHANDLE handle_; ///< ハンドル
public:
/**
* @brief コンパイルエラークラス
*/
class CompileError
: public Status
{
WORD line_; ///< 行番号
WORD col_; ///< 列番号
WORD offset_; ///< エラー位置までのオフセット
WORD length_; ///< エラー範囲の文字数
public:
/**
* @brief デフォルトコンストラクタ
*/
CompileError()
: Status()
, line_(0)
, col_(0)
, offset_(0)
, length_(0)
{}
/**
* @brief コンストラクタ
* @param status ステータス値
* @param line 行番号
* @param col 列番号
* @param offset エラー位置までのオフセット
* @param length エラー範囲の文字数
*/
CompileError(STATUS status, WORD line, WORD col, WORD offset, WORD length)
: Status(status)
, line_(line)
, col_(col)
, offset_(offset)
, length_(length)
{}
WORD line() const { return line_; }
WORD col() const { return col_; }
WORD offset() const { return offset_; }
WORD length() const { return length_; }
};
/**
* @brief デフォルトコンストラクタ
*/
Formula() : handle_(NULLHANDLE) {}
/**
* @brief コンストラクタ
* @param handle @式ハンドル
*/
Formula(FORMULAHANDLE handle) : handle_(handle) {}
/**
* @brief デストラクタ
*/
virtual ~Formula() {
close();
}
/**
* @return ハンドルを返す
*/
FORMULAHANDLE handle() const { return handle_; }
/**
* @brief ハンドルを閉じる
*/
void close() {
if (handle_ != NULLHANDLE) {
OSMemFree(handle_);
handle_ = NULLHANDLE;
}
}
/**
* @brief @式をコンパイルする
* @param statement 文字列の@式
* @param column ビューの列の内部名、ビュー以外に使用する場合はヌル文字列
* @return Formulaクラスの共有ポインタ
*/
static FormulaPtr compile(
const Lmbcs &statement,
const Lmbcs &column = ""
) noexcept(false) {
FORMULAHANDLE handle = NULLHANDLE;
STATUS compileStatus = NOERROR;
WORD formulaLen = 0, line = 0, col = 0, offset = 0, length = 0;
Status status = NSFFormulaCompile(
column.empty() ? nullptr : const_cast<char*>(column.c_str()),
static_cast<WORD>(column.size()),
const_cast<char*>(statement.c_str()),
static_cast<WORD>(statement.size()),
&handle,
&formulaLen,
&compileStatus,
&line,
&col,
&offset,
&length
);
if (!status) { throw status; }
CompileError compileError { compileStatus, line, col, offset, length };
if (!compileError) { throw compileError; }
return std::make_shared<Formula>(handle);
}
};
} // namespace nxpp
#endif // NXPP_FORMULA_HPP
例えばこんな風に使います。
auto fPtr = nxpp::Formula::compile("@All;");
まとめ
@式のハンドルだけを受け取るAPI関数であればこれだけで十分です。式を文書上などで評価しなければいけない場合は、ここからさらに計算ハンドルを得る必要があります。