Windows版mmapクラス

故あってmmapの調査をしていた。UNIX環境だとファイルディスクリプタを引数にmmapコマンドを呼ぶだけなのだけれどwindowsだとちょい面倒なAPIを呼ばないといけない。そんなわけで今後の利便性のためwindowsmmapのリーダークラスをメモしておく。


テンプレート関数を使って任意の型でデータを切り出せるようにした(めんどいかったのでエンディアンとかのチェックはしてない)。
実装にあたり以下を参考にした。

http://nais.to/~yto/tools/sufary/
http://yokohama.cool.ne.jp/chokuto/urawaza/api/

  class mmap_reader {
    HANDLE hFile_;
    HANDLE hMap_;
    void   *map_;

  public:
    mmap_reader(const char *filename);
    ~mmap_reader();
    template<class T> T at(long offset) {
      T *tmp = (T *)(this->map_);
      return *(tmp + offset);
    }
  };

  mmap_reader::mmap_reader(const char *filename) {
    this->hFile_ = CreateFile(filename,
                              GENERIC_READ,
                              0,
                              NULL, 
                              OPEN_EXISTING,
                              FILE_ATTRIBUTE_NORMAL,
                              NULL);
    if (this->hFile_ == INVALID_HANDLE_VALUE) {
      throw "error at mmap_reader(). cannot open file handle.";
    }

    this->hMap_ = CreateFileMapping(this->hFile_,
                  NULL, 
                  PAGE_READONLY,
                  0, 0, NULL);
    if (this->hMap_ == NULL) {
      CloseHandle(this->hFile_);
      throw "error at mmap_reader(). cannot open map handle.";
    }

    this->map_ = MapViewOfFile(this->hMap_,
                               FILE_MAP_READ,
                               0, 0, 0);
    if (this->map_ == NULL) {
      CloseHandle(this->hMap_);
      CloseHandle(this->hFile_);
      throw "error at mmap_reader(). cannot map view of file.";
    }
    return;
  }

  mmap_reader::~mmap_reader() {
    UnmapViewOfFile(this->map_);
    CloseHandle(this->hMap_);
    CloseHandle(this->hFile_);
    return;
  }