Notes C API探訪: NSFSearch関数をラップ
以前、NSFSearch関数にまつわる説明は「NSFSearch(関数)(その1)」で、簡単なラップ関数については「NSFSearch(関数)(その2)」で紹介しています。特に、その2はテスト的な意味合いもあったので、今回は汎用的に使えそうな関数オブジェクトとしてまとめてみました。
nxpp::Searchクラス
SearchクラスはNSFSearch関数のラップクラスです。インスタンスメソッド1つ、クラスメソッド1つ、インナークラス1つのシンプルなクラスです。
// nxpp/include/nxpp_search.hpp
#ifndef NXPP_SEARCH_HPP
#define NXPP_SEARCH_HPP
#include "./nxpp_status.hpp"
#include "./lmbcs/nxpp_lmbcs.hpp"
#ifdef NT
#pragma pack(push, 1)
#endif
#include <global.h>
#include <nsfsearc.h>
#ifdef NT
#pragma pack(pop)
#endif
namespace nxpp {
/**
* @brief NSFSearch関数のラップクラス(関数オブジェクト)
*/
class Search
{
public:
/**
* @brief 検索コールバック毎に呼び出す関数オブジェクトインターフェース
*/
class Iterator
{
public:
virtual ~Iterator(){}
virtual STATUS operator ()(
const SEARCH_MATCH &match,
ITEM_TABLE *pItemTable
) = 0;
};
/**
* @brief 関数オブジェクト呼び出し
* @param hDB データベース(ディレクトリ)ハンドル
* @param hFormula 検索式ハンドル
* @param viewTitle ビュー名
* @param flags 検索フラグ
* @param noteClassMask 文書クラス(NOTE_CLASS_xxx)またはファイルクラス(FILE_xxx)
* @param pIterator コールバックイテレータへのポインタ
* @param pSince 検索日時指定
* @param retUntil 検索終了日時
*/
virtual void operator ()(
DBHANDLE hDB,
FORMULAHANDLE hFormula,
const Lmbcs &viewTitle,
WORD flags,
WORD noteClassMask,
Iterator *pIterator,
TIMEDATE *pSince = nullptr,
TIMEDATE *retUntil = nullptr
) const noexcept(false) {
Status status = NSFSearch(
hDB,
hFormula,
viewTitle.empty()
? nullptr
: const_cast<char*>(viewTitle.c_str()),
flags,
noteClassMask,
pSince,
_callback,
pIterator,
retUntil
);
if (!status) { throw status; }
}
/**
* @brief NSFSearch関数から呼ばれるコールバック関数
* @param ptr コールバックイテレータへのポインタ
* @param pMatch SEARCH_MATCH構造体へのポインタ
* @param pSummaryBuffer サマリーバッファへのポインタ
* @return STATUS値
*/
static STATUS LNPUBLIC _callback(
void *ptr,
SEARCH_MATCH *pMatch,
ITEM_TABLE *pSummaryBuffer
) {
SEARCH_MATCH match;
memcpy(&match, pMatch, sizeof(SEARCH_MATCH));
Iterator *iter
= reinterpret_cast<Iterator*>(ptr);
return (*iter)(match, pSummaryBuffer);
}
};
} // namespace nxpp
#endif // NXPP_SEARCH_HPP
使い方としては、インナークラスnxpp::Search::Iteratorのサブクラスを作り、NSFSearch関数がコールバックした時の処理内容を、オーバーライドした仮想オーバーロードメソッド「operator()」に記述します。あとは、nxpp::Search::operator ()の6番目の引数に、Iteratorサブクラスのインスタンスのポインタを渡せば、検索処理ができます。
例えば、検索内容をstd::vectorに貯めたい場合は、nxpp::Search::Iteratorのサブクラスにstd::vector変数を定義しておいて、コールバック処理時にstd::vectorに検索結果を追加するようにしておけば、nxpp::Search::operator ()処理が終わった後、Iteratorサブクラスのインスタンスからstd::vectorの内容にアクセスするようにすればよい、という風になります。
まとめ
実際に使ってみたコードについては、次回の記事で紹介してみたいと思っています。