Review: std.msgpack

Michel Fortin michel.fortin at michelf.com
Sat Jun 19 11:15:28 PDT 2010


On 2010-06-18 22:18:20 -0400, "Masahiro Nakagawa" <repeatedly at gmail.com> said:

> In addition, Michel has serialization module.
> I don't know module detail, but he mentioned at d.announce.
> http://lists.puremagic.com/pipermail/digitalmars-d-announce/2010-April/015271.html

Indeed, 
> 
and I'm still improving it, very slowly though. Here are some highlights.

The serialization format has a few basic types: integer, 
floating-point, string, bytestring, array, associative-array, object, 
but a couple of representation for each for efficient storage. The 
'encode' and 'decode' template functions can be used to encode and 
decode any type to/from an archive:

	MyStruct m;

	archiver.encode(m);
	unarchiver.decode(m);

It throws an exception of the archive format is not compatible with your type.

If you want to serialize a struct, you must define it like this:

	struct MyStruct {
		mixin Archivable!(int, "i");
		mixin Archivable!(string, "s");
	}

or like this:

	struct MyStruct {
		int i;
		string s;
		
		void encode(ref KeyArchiver archive) {
			archive.encode("i", i);
			archive.encode("s", s);
		}
		void decode(ref KeyUnarchiver archive) {
			foreach (key, value; archive) {
				switch (key) {
					case "i": value.decode(i); break;
					case "s": value.decode(s); break;
					default: break;
				}
			}
		}
	}

or like this:

	struct MyStruct {
		int i;
		string s;
		
		void encode(ref KeyArchiver archive) {
			archive.encode("i", i);
			archive.encode("s", s);
		}
		void decode(ref KeyUnarchiver archive) {
			archive.decode("i", i);
			archive.decode("s", s);
		}
	}

This last decode function is more convenient since you can read values 
in a different order than what they're stored, but it but has more 
overhead than the previous one using a 'switch'.

For archiving/unarchiving objects it works the same, but there are two 
more requirements: the class needs a default constructor and it must 
implements the KeyArchivable interface (which contains the 
encode/decode functions above).

I'm using a custom serialization format, derived from Hessian but no 
longer compatible. I started by trying to conform to Hessian but parts 
of the spec seemed inappropriate for D so I decided to fork. The format 
can handle cycles and multiple references to the same object, but 
that's not yet implemented.

The archiver and unarchiver are very much based on templates, and as 
such it's hard to support multiple archive formats when calling the 
virtual encode/decode functions on an object. But there's nothing 
standing in the way of having a slower but more generic interface 
cohabiting with the format-specific one. The archiver would check for 
the generic interface as an alternative when the format-specific one 
isn't implemented for a given class.

-- 
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/



More information about the Digitalmars-d mailing list