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

More than 1 year has passed since last update.

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とかでもよしなにやってくれるので最高