見出し画像

Notes C API探訪: PathNetをラップする

「PathNet」という単語はAPIリファレンスには載っていません。サーバー名、パス名、ポート名を合成したものを、リファレンスでは「a full network path」「the full path」「the fully qualified network path」のように書いています。説明の単語は一定しないですが、この合成パスを構築する「OSPathNetConstruct」と、分解する「OSPathNetParse」の両関数から、ここでは合成されたパスを「PathNet」と呼称します。

PathNetはLMBCS文字列でできているので、以前紹介したLmbcsクラスを継承する形にします。

// nxpp/include/nxpp/nxpp_pathnet.hpp

#ifndef NXPP_PATHNET_H
#define NXPP_PATHNET_H

#include "./nxpp_status.hpp"
#include "./lmbcs/nxpp_lmbcs.hpp"

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

#include <global.h>
#include <osfile.h>

#ifdef NT
#pragma pack(pop)
#endif

namespace nxpp {

/**
* @brief パスネットクラス(合成パス文字列)
*/
class PathNet : public Lmbcs
{
public:
 /**
  * @brief デフォルトコンストラクタ
  */
 PathNet(): Lmbcs() {}

 /**
  * @brief コンストラクタ
  * @param p 文字列ポインタ
  */
 PathNet(const char *p): Lmbcs(p) {}

 /**
  * @brief コンストラクタ
  * @param p 文字列ポインタ
  * @param size 文字列サイズ
  */
 PathNet(const char *p, size_t size): Lmbcs(p, size) {}

 /**
  * @brief コンストラクタ
  * @param lmbcs LMBCS文字列
  */
 PathNet(const Lmbcs &lmbcs): Lmbcs(lmbcs) {}

 /**
  * @brief コピーコンストラクタ
  */
 PathNet(const PathNet &other) = default;

 /**
  * @brief パスネットをパス、サーバー、ポートに分解する
  * @return パス、サーバー、ポート各LMBCS文字列のタプル
  */
 std::tuple<Lmbcs, Lmbcs, Lmbcs> parse() const {
   char port[MAXPATH] = "";
   char server[MAXPATH] = "";
   char path[MAXPATH] = "";
   Status status = OSPathNetParse(data(), port, server, path);
   if (!status) { throw status; }
   return std::make_tuple(Lmbcs(path), Lmbcs(server), Lmbcs(port));
 }

 /**
  * @brief パス、サーバー、ポートからパスネットを生成する
  * @param path パス
  * @param server サーバー
  * @param port ポート
  * @return パスネット
  */
 static PathNet construct(
     const Lmbcs &path,
     const Lmbcs &server,
     const Lmbcs &port = Lmbcs()
     ) {
   char buffer[MAXPATH] = "";
   Status status = OSPathNetConstruct(
         port.length() == 0 ? nullptr : port.data(),
         server.data(),
         path.data(),
         buffer
         );
   if (!status) { throw status; }
   return PathNet(buffer, strlen(buffer));
 }
};

} // namespace nxpp

#endif // NXPP_PATHNET_H

基本的な使い方ですが、PathNetを作る場合は以下のようにします。

nxpp::PathNet pathnet = nxpp::PathNet::construct("names.nsf", "");

また、PathNetを分解する場合は以下のようにします。

auto pathData = pathnet.parse();
// std::get<0>(pathData) -> パス
// std::get<1>(pathData) -> サーバ
// std::get<2>(pathData) -> ポート

戻り値はタプルになっているので、std::getテンプレート関数で0(パス)、1(サーバー名)、2(ポート名)を指定すれば値を取得できます。

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