SpencBo
SpencBo

Reputation: 1

How to Unserialize File From Scratch (without library) In C++

I was given a file with data stored in a custom format, for example, "data.asd", and tasked with extracting the information out of it. I was given a file specification of the ".asd" format.

All asd files begin at 0x0 which starts with the 5 bytes "Hello" and a 6th one for the \0 termination. Next 32 bits is a pointer to an entry list, which is an array of 127 entries. Each entry contains a 16 char null terminated string, a pointer to some data, and a size variable that tells the size of the data. The value 0xFFFFFFFF signifies the end of the list.

I've look into using the C++ boost serializing library, but get errors when I tried to open the file. I'm assuming boost can only read files it has wrote.

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

I've since checked out serializing "manually" by opening in ifstream, copying the binary file into a vector, and then using 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

I should be able to figure out where the data, entry list, and strings end by checking for termination bits. That way I can get by using memmove and serialize the file by checking bits.

For my case, is there any better option? If i am stuck using memmove, how do I figure out what the pointers point to? Using memmove I was able to move the six bits into a string 's' and rebuild the variable, but I'm unsure how to handle the pointers.

Upvotes: 0

Views: 164

Answers (1)

sehe
sehe

Reputation: 393114

You could memory map things and use Boost Endian.

Alternatively you could use Boost Spirit's Binary parsers: https://www.boost.org/doc/libs/1_51_0/libs/spirit/doc/html/spirit/qi/reference/binary.html

There's an example:

 std::uint32_t length;

 bool valid = qi::parse(first, last,
      "Hello" >> qi::little_word >> char_('\0'), length);

Upvotes: 1

Related Questions