Как десериализовать файл с нуля (без библиотеки) в C ++ - PullRequest
0 голосов
/ 11 июня 2018

Мне дали файл с данными, хранящимися в произвольном формате, например, «data.asd», и мне было поручено извлечь из него информацию.Мне дали спецификацию файла формата ".asd".

Все файлы asd начинаются с 0x0, который начинается с 5 байтов «Hello» и 6-го для завершения \ 0.Следующие 32 бита - это указатель на список записей, который представляет собой массив из 127 записей.Каждая запись содержит строку с 16 символами, оканчивающимися нулем, указатель на некоторые данные и переменную размера, которая сообщает размер данных.Значение 0xFFFFFFFF означает конец списка.

Я изучал использование библиотеки сериализации C ++ boost, но получаю ошибки, когда пытаюсь открыть файл.Я предполагаю, что boost может только читать файлы, которые он написал.

std::ifstream ifs("data.asd");
boost::archive::binary_iarchive in_arch(ifs);

С тех пор я проверил сериализацию «вручную», открыв ifstream, скопировав двоичный файл в вектор, а затем используя memmove.

ifs.open(fileName, ios::in | ios::binary);

//copy all contents in binary into buffer
vector<char> buffer((
    istreambuf_iterator<char>(ifs)),
    (istreambuf_iterator<char>()));

memmove(s, &buffer.at(0), 6); // move char array 'hello' into string s

Я должен быть в состоянии выяснить, где заканчиваются данные, список записей и строки, проверив биты завершения.Таким образом, я могу получить с помощью memmove и сериализовать файл, проверяя биты.

Для моего случая есть ли лучший вариант?Если я застрял с помощью memmove, как я могу выяснить, на что указывают указатели?Используя memmove, я смог переместить шесть битов в строку 's' и перестроить переменную, но я не уверен, как обращаться с указателями.

1 Ответ

0 голосов
/ 11 июня 2018

Вы можете запоминать вещи на карте и использовать Boost Endian.

В качестве альтернативы вы можете использовать двоичные парсеры Boost Spirit: https://www.boost.org/doc/libs/1_51_0/libs/spirit/doc/html/spirit/qi/reference/binary.html

Есть пример:

 std::uint32_t length;

 bool valid = qi::parse(first, last,
      "Hello" >> qi::little_word >> char_('\0'), length);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...