Skip to content

a simple header-only serialization solution based on picojson

Notifications You must be signed in to change notification settings

acidtonic/picojson_serializer

 
 

Repository files navigation

picojson serializer

This is a lightweight header-only solution for serializing objects to and from json using the header-only library picojson.

Build Status

usage

building

Make sure picojson.h can be found, include picojson_serialization.h, no extra build steps necessary.

Premake4 is included and the generated build files are to be found in the Build folder.

declaring objects as serializable

The API is similar to hiberlite's or Boost.Serialization's:

/// A JSON serializable class
struct Point {
    double x, y, z;

    friend class picojson::convert::access;
    template<class Archive>
    void json(Archive & ar)
    {
        ar & picojson::convert::member("x", x);
        ar & picojson::convert::member("y", y);
        ar & picojson::convert::member("z", z);
    }
};

/// Composed serialization is possible
struct NamedPoint {
    std::string name;
    Point point;

    friend class picojson::convert::access;
    template<class Archive>
    void json(Archive & ar)
    {
        ar & picojson::convert::member("name", name);
        ar & picojson::convert::member("point", point);
    }
};

To enable std::vector serialization, use the header picojson_vector_serializer.h

serializing

NamedPoint np = { "test point" , { 1 , 2 , 3 } };
picojson::value npv = picojson::convert::to_value(np);
std::string nps = picojson::convert::to_string(np);

resulting in

{"name":"test point","point":{"x":1,"y":2,"z":3}}

deserializing

NamedPoint np;
std::string json=...
picojson::convert::from_string(json,np);

Currently, if deserialization fails for a member, that member is not modified.

non-intrusive serialization

A class that cannot be extended, but the internals are accessible (following to the Boost.Serialization api):

struct Untouchable {
    int value;
};

With a free function defined in the ::picojson::convert namespace,

namespace picojson {
    namespace convert {

        template <class Archive>
        void json(Archive &ar, Untouchable &u) {
            ar &picojson::convert::member("value", u.value);
        }

    }
}

serialization is again possible:

Untouchable example = { 42 };
std::string example_string( picojson::convert::to_string(example) );

Untouchable example_deserialized = { 0 };
picojson::convert::from_string( example_string, example_deserialized );
CHECK( example.value == example_deserialized.value );

implementing custom value converters

The serialization can be easily customized for types that are not default-convertible. Example class:

struct Example {
	enum Status {
		NONE = 0,
		SOME,
		SOME_OTHER
	};

	Status status;

	friend class picojson::convert::access;
	template<class Archive>
	void json(Archive & ar)
	{
		ar & picojson::convert::member("status", status);
	}
};

Attempting to serialize instances of Example should lead to compile error:

Example e = { Example::NONE };
picojson::value ev = picojson::convert::to_value(e);

However, you can specialize the value converter for the enum, i.e.:

namespace picojson {
namespace convert {

	template<> struct value_converter<Example::Status> {
		static value to_value(Example::Status v) {
			return value(static_cast<double>(v));
		}

		static void from_value(value const& ov, Example::Status& v) {
			if ( ov.is<double>() ) v = Example::Status(static_cast<int>(ov.get<double>()));
		}
	};
}
}

and the test passes:

Example e = { Example::SOME };
picojson::value ev = picojson::convert::to_value(e);
CHECK(has<double>(ev, "status", static_cast<int>(Example::SOME)));

container converters

List of supported standard library containers

  • vector
  • map
  • multimap

mapping between unrelated types

If you have serializable types that may be unrelated, such as a logic component and a data transfer object, you can 'project' the data from one object to another simply by mapping the values through the serialization like so:

Class1 c1=...;
Class2 c2=picojson::project::from(c1).onto<Class2>();

license

Copyright 2013, Dmitry Ledentsov MIT License: http://www.opensource.org/licenses/mit-license.php

About

a simple header-only serialization solution based on picojson

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 94.8%
  • Lua 5.2%