DeeSerializable

DeeSerializable — Interface for classes that can serialize to and from GVariants

Synopsis

#include <dee.h>

struct              DeeSerializableIface;
GObject *           (*DeeSerializableParseFunc)         (GVariant *data);
GVariant *          dee_serializable_externalize        (DeeSerializable *self);
GObject *           dee_serializable_parse              (GVariant *data,
                                                         GType type);
GObject *           dee_serializable_parse_external     (GVariant *data);
void                dee_serializable_register_parser    (GType type,
                                                         const GVariantType *vtype,
                                                         DeeSerializableParseFunc parse_func);
GVariant *          dee_serializable_serialize          (DeeSerializable *self);

Description

Interface for classes that can serialize to and from GVariants.

There are two serialization concepts supported by this API: serialization and externalization. A serialized instance is created with dee_serializable_serialize() and can be read back with dee_serializable_parse() provided you know the correct GType for the serialized data. The GVariant representation of your serialized data is guaranteed to be exactly as you implement yourself in the serialize vfunc of the DeeSerializableIface.

With externalized instances you don't have to know the correct GType to recreate the instance. The GType is encoded in the data itself. When you're using dee_serializable_externalize() your data will be wrapped in a container format with the required object metadata to read it back. For this reason dee_serializable_parse_external() doesn't require you to pass in the GType you want to deserialize.

On Subclasses of DeeSerializable Types

As a rule of thumb you need to re-implement the DeeSerializable interface and install parse functions with dee_serializable_register_parser() every time you create a new class derived from a DeeSerializable superclass.

In case a subclass does not provide it's own serialization interface Dee will recurse upwards in the type hierarchy and use the serialization and parser implementations of the first superclass with the required behaviour. This means that the parsed instance will not be an instance of the subclass but only of the serializable superclass. Caveat emptor.

Details

struct DeeSerializableIface

struct DeeSerializableIface {
  GTypeInterface g_iface;

  GVariant*       (*serialize)         (DeeSerializable *self);
};


DeeSerializableParseFunc ()

GObject *           (*DeeSerializableParseFunc)         (GVariant *data);

data :

A GVariant with type signature as passed to dee_serializable_register_parser() when the parser was registered. The variant is not referenced.

Returns :

A newly constructed GObject of the GType used when registering the parser. Note that since the environment guarantees that the input data is valid according to the registration information this function can not fail. Thus NULL is not a valid return value. [transfer full]

dee_serializable_externalize ()

GVariant *          dee_serializable_externalize        (DeeSerializable *self);

Build an externalized form of self which can be used together with dee_serializable_parse_external() to rebuild a copy of self.

It is important to note that the variant returned from this method does not have the same type signature as returned from a call to dee_serializable_serialize(). Externalization will wrap the serialized data in a container format with versioning information and headers with type information.

self :

The instance to externalize

Returns :

A floating reference to a GVariant with the externalized data.

dee_serializable_parse ()

GObject *           dee_serializable_parse              (GVariant *data,
                                                         GType type);

Reconstruct a DeeSerializable from GVariant data. For this function to work you need to register a parser with dee_serializable_register_parser(). Any native Dee class will do so automatically.

This method only works on data created with dee_serializable_serialize() and not with data from dee_serializable_externalize().

Since a DeeSerializableParseFunc is not allowed to fail - by contract - it can be guaranteed that this function only returns NULL in case there is no known parser for type and GVariant signature of data.

data :

The GVariant data to parse. If this is a floating reference it will be consumed

type :

The GType of the class to instantiate from data

Returns :

A newly constructed GObject build from data or NULL in case no parser has been registered for the given GType or variant signature. Free with g_object_unref(). [transfer full]

dee_serializable_parse_external ()

GObject *           dee_serializable_parse_external     (GVariant *data);

Reconstruct a DeeSerializable from GVariant data. For this function to work you need to register a parser with dee_serializable_register_parser(). Any native Dee class will do so automatically.

This method only works on data created with dee_serializable_externalize() and not with data from dee_serializable_serialize().

Since a DeeSerializableParseFunc is not allowed to fail - by contract - it can be guaranteed that this function only returns NULL in case there is no known parser for the GType or GVariant signature of data.

data :

The GVariant data to parse

Returns :

A newly constructed GObject build from data or NULL in case no parser has been registered for the given GType or variant signature. Free with g_object_unref(). [transfer full]

dee_serializable_register_parser ()

void                dee_serializable_register_parser    (GType type,
                                                         const GVariantType *vtype,
                                                         DeeSerializableParseFunc parse_func);

Register a parser that can convert GVariant data into an instance of a given GType. Note that you can register more than one parser for the same GType provided that you give them different variant type signatures.

If there is already a parser registered for the given type and vtype it will be silently replaced.

The recommended behaviour is that GObject classes register their parsers in their respective class init functions.

type :

The GType of the object class to register a parser for

vtype :

Variants to be converted must have this signature

parse_func :

A function to convert GVariant data into an instance of the given type.

dee_serializable_serialize ()

GVariant *          dee_serializable_serialize          (DeeSerializable *self);

Build a clean serialized representation of self. The signature of the returned variant is entirely determined by the underlying implementation. You can recreate a serialized instance by calling dee_serializable_parse() provided that you know the correct GType for the serialized instance.

self :

The instance to serialize

Returns :

A reference to a GVariant with the serialized data. The variants type signature is entirely dependent of the underlying implementation. Free using g_variant_unref(). [transfer full]