MessagePackでシリアライズされたファイルを読み込むときはchar*を使う

  • 0
    いいね
  • 2
    コメント

    TL;DR

    • ファイルの内容は std::string ではなく char* に 読み込ませる.

    ダメな例

    ファイルの内容をstd::stringに保持するパターン.

    std::ifstream ifs(file.path().string(), std::ios::in | std::ios::binary);
    std::istream_iterator<char> itr_begin(ifs);
    std::istream_iterator<char> itr_end;
    const std::string str(itr_begin, itr_end);
    auto buf = str.data();
    auto size = str.size();
    
    msgpack::object_handle oh;
    msgpack::unpack(oh, buf, size);
    

    バイナリの途中に0x00が紛れ込んでるとそこで切り落とされてしまい,insufficient bytesみたいなダイイングメッセージ残して死ぬ.

    大丈夫な例

    ファイルの内容をchar*に保持するパターン.これだと途中で捨てられることはない.

    char *buf;
    size_t size;
    
    std::ifstream ifs(file.path().string(), std::ios::in | std::ios::binary);
    auto begin = static_cast<size_t>(ifs.tellg());
    ifs.seekg(0, ifs.end);
    auto end = static_cast<size_t>(ifs.tellg());
    ifs.clear();
    ifs.seekg(0, ifs.beg);
    size = end - begin;
    buf = new char[size];
    ifs.read(buf, size);
    
    msgpack::object_handle oh;
    msgpack::unpack(oh, buf, size);
    

    雑記

    • std::stringなのかchar*なのかちゃんと使い分けないと死を招く(あたりまえ)
    • msgpack-cはコンテナに入った適当なstructとかでもよしなにやってくれるので最高