jeudi 2 février 2017

How to improve C++ JSON serializer

TLDR: How to improve the serialize method I add to my classes to avoid using the JVAL C macro?

Long story:

I've written a JSON serializer/deserializer in C++ using rapidjson to parse the JSON itself and a reader/writer class to serialize to/from JSON.

C++ doesn't have reflection, and I want to avoid external metafiles or precompilation steps, so to implement it I've had to add an interface to every class I want to be serializabile.

NOTE: by design my class serialize always from and to string buffers, so I can avoid error checking in the serialize() method.

Here is the simple interface:

class RJSerializer;

struct Serializable
{
    virtual void serialize(RJSerializer &) = 0;
    virtual ~Serializable() {}
};

The method serialize is the object of my question, actually for an object like this:

struct Group : Serializable {
    long long id;
    std::string name;
    std::string type;
    bool internal;
    std::vector<Subgroup> subgroups;

    void serialize(RJSerializer &);
};

It's implemented in this way:

void Group::
serialize(RJSerializer &s)
{
    JVAL(s, id);
    JVAL(s, name);
    JVAL(s, type);
    JVAL(s, internal);
    JVAL(s, subgroups);
}

The object of my question is that JVAL that does the actual "magic" using an ugly C style macro, and I'd like to improve it a bit...

#define JVAL(w, a) w.Pair(#a, a)

This method associate the member a to the name "a", then a C++ template method in the RJSerializer class:

template <typename T>
void Pair(const char *k, T &v) { key(k); val(v); }

Does the initial step to the serialize process... and the rest is similar to every other binary C++ serializer you can find on this planet...





Aucun commentaire:

Enregistrer un commentaire