見出し画像

Notes C API探訪: STATUS(データ型)その2

STATUS型については、以前の記事で意味や構造などを紹介しました。

STATUS型には関数が処理した結果、正しく終了したのか、エラーが起きた場合はどんなエラーが起きたのかを伝える役目があります。STATUS値にエラー検出用マクロERRを通した時、NOERROR値と同じであれば正しく処理されたことがわかります。一方、NOERROR値ではなかった時に何かしらのエラーが起きたことがわかります。

STATUS status = SomethingNotesAPIFunction();
if (ERR(status) == NOERROR) { /* Processed correctly. */ }
else { /* An error occurred. */ }

しかし、それはただの数値に過ぎません。どんなエラーが起きたのか、人間が呼んでわかる文字列にしてくれるのがOSLoadString関数です。

OSLoadString

OSLoadString関数は、ERRマクロでマスクされたSTATUS値を渡すと、エラーコードに対応したエラー文字列を返します。

#include <osmisc.h>
WORD LNPUBLIC OSLoadString (
  HMODULE hModule,
  STATUS StringCode,
  char far *retBuffer,
  WORD BufferLength);

#include <misc.h>
#if (defined(ND64) || defined(NDUNIX64)) && defined(USE_LARGE_MAXSPRINTF)
  #define MAXSPRINTF 1024
#else
  #define MAXSPRINTF 256
#endif

hModuleは、モジュールハンドルを指定します。Unix系では常にNULLHANDLEにします。Windows系でも、基本はNULLHANDLEですが、Windows特有の「文字列リソース」にアクセスすることを目的に、ハンドルを渡してそのモジュールからリソースを得ることもできます。「OSLoadString」という名目に「エラー文字列の取得だけが目的でない」みたいな意味が垣間見える気がします。とは言え、目的がNotes/Dominoのエラー文字列であれば、NULLHANDLEで十分です。
StringCodeは、ERRマクロでマスクされたSTATUS値を指定します。
retBufferとBufferLengthには、エラー文字列を受け取るバッファへのポインタとサイズを指定します。なお、バッファサイズは定数MAXSPRINTFを使えば十分な領域を確保できます。

サンプルコード

#include <global.h>
#include <osmisc.h>
#include <nsfdb.h>
#include <nls.h>

// LMBCSから他の文字コードに変換する1文字当たりの最大比率でバッファサイズを計算
#define MAXMESSAGE (MAXSPRINTF * NLS_MAXRATIO_XLATE_FROM_LMBCS)

void test() {
 DBHANDLE hDB = NULLHANDLE;
 STATUS status = NSFDbOpen("hoge.nsf", &hDB); // 実在しないファイル
 if (ERR(status) != NOERROR) {
   char lmbcs[MAXSPRINTF + 1];
   char buffer[MAXMESSAGE + 1];
   WORD len = OSLoadString(NULLHANDLE, ERR(status), lmbcs, MAXSPRINTF);
   WORD wlen = OSTranslate(
         OS_TRANSLATE_LMBCS_TO_UNICODE, // LMBCSをUNICODE(UTF-16)に変換
         lmbcs, len,
         buffer, MAXMESSAGE);
   std::wstring message(reinterpret_cast<wchar_t*>(buffer), wlen / sizeof(wchar_t));
   // message is "ファイルがありません"
 }
 else {
   // Processed correctly.
   NSFDbClose(hDB);
 }
}

OSLoadStringで返ってくる文字列は、リファレンスによると「LMBCS optimized for Group 1」(言語グループ1に最適化されたLMBCS)であると書かれています。これは、日本語パックを適用したNotes/Dominoを使用していれば、エラー文字列も日本語のLMBCS文字列になるという意味で、改めて翻訳などをする必要がありません。一方でLMBCS文字列であることから、日本語LMBCSは標準出力やUI上にそのまま表示することはできない(必ず文字化けが起きる)ので、必然的に変換処理が必要になってきます。その場合、サンプルコードのようにOSTranslate関数、または(準備が手間ですが)NLS_translate関数で処理できます。

注意: コードの利用においてチブル・システムズは一切の責任を負いません。自己責任でご利用をお願いいたします。

この記事が気に入ったらサポートをしてみませんか?