なんか実引数と仮引数で値ちがうんだけどなにこれ
— izumin (@izumin5210) November 2, 2016
バイナリファイルの扱いわからん pic.twitter.com/MeWGT7XjTG
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とかでもよしなにやってくれるので最高