見出し画像

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

今回は、以前の記事で紹介したものの中から、ロードとアンロードに関してこんな風にラップしてみましたというお話です。

それではコードをご覧ください。

// nxpp/include/nxpp/nls/nxpp_nlsinfo.hpp

#ifndef NXPP_NLSINFO_HPP
#define NXPP_NLSINFO_HPP

#ifdef NT
#pragma pack(push, 1)
#endif

#include <global.h>
#include <nls.h>
#include <osmisc.h> // OSGetLMBCSCLS

#ifdef NT
#pragma pack(pop)
#endif

namespace nxpp::nls {

/**
* @brief NLS(National Language Service)情報のラッパークラス
*/
class Info
{
protected:
 NLS_PINFO ptr_;

public:
 /**
  * @brief コンストラクタ
  * @param ptr NLS情報へのポインタ
  */
 explicit Info(NLS_PINFO ptr) : ptr_(ptr) {}

 /**
  * @brief デストラクタ
  */
 virtual ~Info() = default;

 /**
  * @brief NLS情報へのポインタを返します。
  * @return NLS情報へのポインタ
  */
 NLS_PINFO get() const { return ptr_; }
};

/**
* @brief ロードして使用するNLS情報クラス
* @tparam CSID 文字セットID
*/
template <WORD CSID>
class LoadTypeInfo
   : public Info
{
public:
 /**
  * @brief コンストラクタ
  */
 explicit LoadTypeInfo() : Info(nullptr) {
   NLS_load_charset(CSID, &ptr_);
 }

 /**
  * @brief デストラクタ
  */
 virtual ~LoadTypeInfo() {
   NLS_unload_charset(ptr_);
 }
};

/**
* @brief LMBCS専用NLS情報クラス
*/
class LmbcsInfo
   : public Info
{
public:
 /**
  * @brief コンストラクタ
  */
 LmbcsInfo() : Info(OSGetLMBCSCLS()) {}

 /**
  * @brief デストラクタ
  */
 virtual ~LmbcsInfo() = default;
};

} // namespace nxpp::nls

#endif // NXPP_NLSINFO_HPP

nxpp::nls::Infoというベースとなるクラスがあって、それぞれロードして使用する文字セット用(nxpp::nls::LoadTypeInfo)と、特定の関数(ここではLMBCS用)を使用する文字セット用(nxpp::nls::LmbcsInfo)の2種類のクラスに派生させています。LMBCS文字セットの場合は、nls_load_charset関数を使わず、OSGetLMBCSCLS関数を使っています。また、nls_unload_charset関数によるアンロードもしないようになっています。

// LMBCS文字セットを定義
nxpp::nls::LmbcsInfo lmbcsInfo;

// UNICODE文字セットを定義
nxpp::nls::LoadTypeInfo<NLS_CS_UNICODE> unicodeInfo;

// NLS_isleadbyte関数で使用
if (NLS_isleadbyte('\x10`, lmbcsInfo.get()) == NLS_SUCCESS) {
  std::cout << "\\x10 is lead-byte for LMBCS." << std::endl;
} else {
  std::cout << "\\x10 is NOT lead-byte for LMBCS." << std::endl;
}

文字セット定義

LMBCS以外の文字セットは非常に多くあり(270以上)、nls.hヘッダーファイルにNLS_CS_***として定義されています。ここでは、日本語に関係がありそうなものを抜粋してみたいと思います。

// nls.h
#define NLS_CS_EUC               0x0017 /* Extended Unix Code */
#define NLS_CS_NECESJIS          0x001C /* NEC Extended Shift-JIS */
#define NLS_CS_UNICODE           0x00A0
#define NLS_CS_ISO10646          0x00A0 /* Also Unicode */
#define NLS_CS_UTF7              0x00AA /* Unicode Transformation Formats */
#define NLS_CS_UTF8              0x00AB
#define NLS_CS_JIS               0x0CCD
#define NLS_CS_JIS2              0x0CE4
#define NLS_CS_EUCJ              0x0CE5
#define NLS_CS_JP1TEXT                0x0CF0 /* OSI/JIS X 5003-1987 X.400 Japanese ISP */
#define NLS_CS_IBMCP930               0x0E00      /* Japan  */
#define NLS_CS_IBMCP939               0x0E04      /* Japan  */
#define NLS_CS_IBMCP300               0x0E80      /* Japan  */
#define NLS_CS_IBMCP930X              0x0E84      /* Japan  */
#define NLS_CS_IBMCP939X              0x0E88      /* Japan  */
#define NLS_CS_IBMCP1399              0x0E8B      /* Japan  */

まとめ

OS自体がマルチバイト文字セット(ShiftJISなど)ではなくワイド文字セット(Unicode/UTF16)を選択しつつある現状では、LMBCSとUTF16間での相互変換が頻繁に行われると思います。また古いプラットフォームでマルチバイト文字セットでないと都合が悪い場合もまだまだ多いでしょう。Notes/DominoがLMBCSを使い続ける以上必須の技術なので、しっかり押さえておきたいところです。

いいなと思ったら応援しよう!