#c #boost #buffer #ifstream
#c #ускорять #буфер #ifstream
Вопрос:
Я пытаюсь проанализировать XML-файл встроенного ресурса:
HRSRC hresinfo = FindResource(hInstance, MAKEINTRESOURCE(IDR_XML1), _T("XML"));
if (hresinfo)
{
HGLOBAL hRes = LoadResource(hInstance, hresinfo);
DWORD datasize = SizeofResource(hInstance, hresinfo); // this size is correct
LPVOID data = LockResource(hRes);
if (hRes amp;amp; datasize != 0 amp;amp; data) {
ifstream in;
in.rdbuf()->pubsetbuf((char*)data, datasize);
streamsize size = in.rdbuf()->in_avail();
printf("size=%d", size); // this size is 0
pt::read_xml(in, tree); // parses nothing
}
else {
printf("error: %dn", GetLastError());
}
}
memcpy загружает данные в обычный буфер и печатает каждый символ, что наводит меня на мысль, что проблема связана с ifstream.
Комментарии:
1. В чем именно проблема?
2. В rdbuf ничего нет, даже несмотря на то, что в него были введены данные, и указатель данных и datasize указаны правильно. @ted-lyngmo
3. Если вы сначала попробуете средний шаг:
std::string buf(datasize, ''); std::copy_n((char*)data, datasize, buf.data());
получаете ли вы данные вbuf
?4. Какую версию
boost
вы используете?void read_xml(const std::string amp;, Ptree amp;, int = 0, const std::locale amp; = std::locale());
кажется, это лучше, чем настройкаrdbuf
. Это означало бы:pt::read_xml((const char*)data, tree);
должно работать напрямую.5. Первый параметр
void read_xml(const std::string amp;, Ptree amp;, int = 0, const std::locale amp; = std::locale());
указывает имя файла для открытия. Я не могу передать имя файла, поскольку файл является встроенным ресурсом. Другое определение для этой функции принимает входной поток.
Ответ №1:
Я думаю, что pubsetbuf не делает того, что вам нужно (однако я не совсем понимаю, что именно он делает). Чтобы установить std::ifstream
содержимое в том виде, в каком оно было загружено из реального файла, вы можете сделать следующее:
std::ifstream in;
std::stringstream ss{std::string((char*)data, datasize)};
in.basic_ios<char>::rdbuf(ss.rdbuf());
std::string str;
in >> str; // to check if ifstream has expected content
std::cout << "str = " << str << std::endl;
Ваш ifstream
будет использовать тот же контент, который stringstream
создан из необработанного блока памяти, указанного data
.
Редактировать
Извините, забыл std::ifstream
. Я вижу, что это pt::read_xml
принимается std::basic_istream
, поэтому просто передайте std::stringstream
напрямую.
Комментарии:
1. По какой-то причине, хотя
std::string ((char*)data, datasize);
там содержится полное содержимое файла, буфер ifstream содержит только первые 5 символов. Размер буфера ifstream не достигает 5 байтdatasize
.2. Хм, немного странно, что
ifstream
у вас тоже не сработало. У меня это работало с поддельными данными, даже если они содержали нулевой символ:char* buff = "abdcefghijk"; std::stringstream ss{std::string(buff, 13)}; in.basic_ios<char>::rdbuf(ss.rdbuf()); std::string str; in >> str; std::cout << "str = " << str << std::endl;