On 2010-06-18 22:18:20 -0400, "Masahiro Nakagawa" <repeate...@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.for...@michelf.com
http://michelf.com/

Reply via email to