Nic Foster
Nic Foster

Reputation: 2894

Need library for binary stream serialization, C++

What I'm looking for is similar to the serialization library built into RakNet (which I cannot use on my current project). I need to be able save/load binary streams into a custom format locally, and also send them over a network. The networking part is solved, but I really don't want to write my own methods for serializing all of my different types of data into binary, especially since it would be inefficient without any compression methods.

Here's some pseudocode similar to how RakNet's bitstreams work, this is along the lines of what I'm looking for:

class Foo
{
public:
    void Foo::save(BitStream& out)
    {
        out->write(m_someInt);
        out->write(m_someBool);
        m_someBar.save(out);

        // Alternative syntax
        out->write<int>(m_someInt);

        // Also, you can define custom serialization for custom types so you can do this...
        out->write<Bar>(m_someBar);

        // Or this...
        out->write(m_someBar);     
    }

    void Foo::load(BitStream& in)
    {
        in->read(m_someInt);
        in->read(m_someBool);
        in->read(m_someBar);
    }

private:
    int m_someInt;
    bool m_someBool;
    Bar m_someBar;
};

Are there any free C++ libraries out there that allow for something like this? I basically just want something to pack my data into binary, and compress it for serialization, and then decompress it back into binary that I can feed back into my data.

EDIT, adding more information:
Unfortunately neither Google Protocol Buffers or Boost Serialization will work for my needs. Both expect to serialize object members, I need to simply serialize data. For example, lets say I have a std::vector<Person>, and the class Person has a std::string for name, and other data in it, but I only want to serialize and deserialize their names. With Google Protocol Buffers it expects me to give it the Person object as a whole for serialization. I can achieve however, achieve this with Boost Serialization, but if I have another scenario where I need the entire Person to be serialized, there is no way to do that, you either have to serialize all of it, or none. Basically I need quite a bit of flexibility to craft the binary stream however I see fit, I just want a library to help me manage reading and writing binary data to/from the stream, and compressing/decompressing it.

Upvotes: 1

Views: 1744

Answers (1)

Tomas Andrle
Tomas Andrle

Reputation: 13364

  1. Google Protocol Buffers
  2. Boost serialization

UPDATE

Looking at the updated question I think it might be easiest to write a small custom library that does exactly what is required. I have a similar one and it is only a few hundred lines of code (without compression). It is extremely easy to write unit tests for this kind of code, so it can be reliable from day one.

To serialize custom types, I have a Persistent base class that has save and load methods:

class Storage {
public:
  void writeInt( int i );
  void writeString( string s );
  int readInt();
  string readString();
};

class Persistent {
public:
  virtual void save( Storage & storage ) = 0;
  virtual void load( Storage & storage ) = 0;
};

class Person : public Persistent {
private:
  int height;
  string name;
public:
  void save( Storage & storage ) {
    storage.writeInt( height );
    storage.writeString( name );
  }

  void load( Storage & storage ) {
    storage.readInt( height );
    storage.readString( name );
  }
};

And then there's a simple layer on top of that that stores some type information when saving and uses a Factory to create new objects when loading.

This could be further simplified by using C++'s streams (which I don't like very much, hence the Storage class). Or copying Boost's approach of using the & operator to merge load and save into a single method.

Upvotes: 2

Related Questions