0

I wanted to parse a binary file using modern c++ techniques. I search the internet and found an excellent stack overflow answer from 2014.

Parsing a binary file. What is a modern way?

In that answer, there is an extremely interesting approach using templates. As I am trying to learn c++ templates currently, how to use this example are a little too advanced for me.

I stripped the example back as far as I can, but I cannot figure out how to use it to parse binary data (all Uint16 LE) in a file.

As I really would like to understand how this code works, what do I need to do to get this example code (copied from reference SO link) to parse my file?

Thanks

Densha

#include <iostream>
#include <assert.h>
#include <fstream>

using Buffer = std::pair<unsigned char const*, size_t>;

template <typename OffsetReader>
class UInt16LEReader: private OffsetReader {
public:
    UInt16LEReader() {}
    explicit UInt16LEReader(OffsetReader const osr): OffsetReader(osr) {}

    uint16_t read(Buffer const& buffer) const {
        OffsetReader const& osr = *this;

        size_t const offset = osr.read(buffer);
        assert(offset <= buffer.second && "Incorrect offset");
        assert(offset + 2 <= buffer.second && "Too short buffer");

        unsigned char const* begin = buffer.first + offset;

        // http://commandcenter.blogspot.fr/2012/04/byte-order-fallacy.html
        return (uint16_t(begin[0]) << 0) + (uint16_t(begin[1]) << 8);
}
}; // class UInt16LEReader

template <size_t O>
class FixedOffsetReader {
public:
    size_t read(Buffer const&) const { return O; }
}; // class FixedOffsetReader

class LocalFileHeader {
public:
    template <size_t O>
    using UInt16 = UInt16LEReader<FixedOffsetReader<O>>;

    UInt16< 0> field1;
    UInt16< 2> filed2;
}; // class LocalFileHeader

int main(int argc, const char * argv[]) {
    std::ifstream myfile;
    myfile.open ("file.bin", std::ios::in | std::ios::binary);

    LocalFileHeader lfr = LocalFileHeader();
    // How do I use the parser to read from my file?
    return 0;
}
yam
  • 27
  • 7
densha
  • 157
  • 3
  • 12
  • The example you quote is about *parsing* binary data. Since you haven't specified anything about the structure of the data you are trying to read then it's hard to help. If all you have is an undifferentiated sequence of 16 bit little endian integers then you should use a different approach (IMHO). – john Mar 03 '18 at 11:09
  • But to answer you question it seems that you need to load a `Buffer` object with the data in your file, then call `lfr.field1.read(buffer); lfr.field2.read(buffer);`. I've only just read the code, I haven't tried to run it, so I could be wrong. What advantage this approach has over less clever but more traditional approaches I'm not certain. Seems like archiecture for it's own sake to me. – john Mar 03 '18 at 11:16

0 Answers0