Jump to page: 1 2
Thread overview
Cerealed v0.2.0 - a(nother) D serialisation library
Nov 18, 2013
Atila Neves
Nov 18, 2013
Jacob Carlborg
Nov 19, 2013
Rory McGuire
Nov 19, 2013
Jacob Carlborg
Nov 19, 2013
Rory McGuire
Nov 19, 2013
Jacob Carlborg
Nov 19, 2013
Atila Neves
Nov 19, 2013
Rory McGuire
Nov 19, 2013
Jacob Carlborg
Nov 19, 2013
Jacob Carlborg
Nov 20, 2013
Atila Neves
Nov 20, 2013
Jacob Carlborg
Sep 08, 2014
Vicente
Sep 09, 2014
Atila Neves
Sep 11, 2014
Atila Neves
November 18, 2013
http://code.dlang.org/packages/cerealed
https://github.com/atilaneves/cerealed

But what about Orange / std.serialization? Well,
1. I started this before I knew about Orange. This is actually based on a library I wrote in C++ (https://bitbucket.org/atilaneves/cereal) for the game I'm trying to finish, and it dawned on me it would probably be easier in D. It was.
2. Orange serialises to XML, I need/want binary. I could've written a binary archive, I guess, but I'd rather do this.
3. I would've written this for fun anyway.

The deal here is binary serialisation with minimal to no boilerplate. As mentioned in the README, I used this to implement a MQTT broker with minimal fuss. Serialising classes, structs, and normal D types requires writing nothing at all. Custom serialisation can be handled in two different ways and both of them require writing only one function for both struct/class -> bytes and vice-versa. Since a code sample is worth a 1000 words:

    import cerealed; //uses package.d from 2.064

    struct MyStruct {
        ubyte mybyte1;
        @NoCereal uint nocereal1; //won't be serialised
        //the next 3 members will all take up one byte
        @Bits!4 ubyte nibble; //gets packed into 4 bits
        @Bits!1 ubyte bit; //gets packed into 1 bit
        @Bits!3 ubyte bits3; //gets packed into 3 bits
        ubyte mybyte2;
    }

    auto enc = new Cerealiser();
    enc ~= MyStruct(3, 123, 14, 1, 2, 42);
    assert(enc.bytes == [ 3, 0xea /*1110 1 010*/, 42]);

    auto dec = new Decerealizer([ 3, 0xea, 42]); //US spelling works too
    //the 2nd value is 0 and not 123 since that value
    //doesn't get serialised/deserialised
    assert(dec.value!MyStruct == MyStruct(3, 0, 14, 1, 2, 42));

Custom serialisation is explained in the README. I had to use it for my MQTT project and it worked quite well.

I still need to add a bunch of negative tests and accompanying code but this is good enough to fool around with for the moment.

Atila
November 18, 2013
On 2013-11-18 17:49, Atila Neves wrote:
> http://code.dlang.org/packages/cerealed
> https://github.com/atilaneves/cerealed

How does it handle:

* Slices - are they restored?
* Pointers - are they restored?
* Objects - is the same object only serialized once or duplicated?
* Serializing through base class reference - possible?

-- 
/Jacob Carlborg
November 19, 2013
On 18 Nov 2013 22:45, "Jacob Carlborg" <doob@me.com> wrote:
>
> How does it handle:
>
> * Slices - are they restored?
> * Pointers - are they restored?
> * Objects - is the same object only serialized once or duplicated?
> * Serializing through base class reference - possible?
>
> --
> /Jacob Carlborg

Hi Jacob,

Is there an example somewhere of how to use Orange to serialise data that
will not be going to a file?
When I looked at it appeared as though Orange's archives are designed for
file serialising only.

-Rory


November 19, 2013
On 2013-11-19 06:49, Rory McGuire wrote:

> Hi Jacob,
>
> Is there an example somewhere of how to use Orange to serialise data
> that will not be going to a file?
> When I looked at it appeared as though Orange's archives are designed
> for file serialising only.

Orange doesn't have any data transport layer or similar. But you can do whatever you want with the data you get from the archiver.

Check the usage example in the readme[1]. Use "archive.data" to get the typed data after serialization and do whatever you want with it.

https://github.com/jacob-carlborg/orange#simple-usage-example

-- 
/Jacob Carlborg
November 19, 2013
On Tue, Nov 19, 2013 at 9:18 AM, Jacob Carlborg <doob@me.com> wrote:

> On 2013-11-19 06:49, Rory McGuire wrote: https://github.com/jacob-carlborg/orange#simple-usage-example
>
> --
> /Jacob Carlborg
>
Thanks. I believe that is the example that made me think that its main purpose was for archiving.

So is an Archive actually a serialization driver? Can one make a protobuf
driver or a hessian driver?
Are the serializers able to stream data, with something like a range
interface?


November 19, 2013
On 2013-11-19 09:19, Rory McGuire wrote:

> Thanks. I believe that is the example that made me think that its main
> purpose was for archiving.
>
> So is an Archive actually a serialization driver? Can one make a
> protobuf driver or a hessian driver?

Yes, that should be possible. It depends on how the data looks like. The upcoming std.serialization version will relax quite a lot of the requirements of the archiver. That means more archivers can be implemented.

> Are the serializers able to stream data, with something like a range
> interface?

No, unfortunately not. I'm working on including Orange into Phobos as std.serialization. That version will have a range API.

-- 
/Jacob Carlborg
November 19, 2013
On Monday, 18 November 2013 at 20:43:51 UTC, Jacob Carlborg wrote:
> On 2013-11-18 17:49, Atila Neves wrote:
>> http://code.dlang.org/packages/cerealed
>> https://github.com/atilaneves/cerealed
>
> How does it handle:
>
> * Slices - are they restored?

It serialises the slice and restores it as it was, not the data behind it. I should add some tests for that.

> * Pointers - are they restored?

No, good point. I keep forgetting there are legitimate uses of pointers in D. I was looking at the SList implementation the other day and was surprised to see "new" used to create a struct on the heap, something that would seem totally normal to me in C++.

It should be easy enough to extend to pointers, I'll add that in the next version.

> * Objects - is the same object only serialized once or duplicated?

I'm not sure I understand the question.

> * Serializing through base class reference - possible?

No. I can't see how that would be possible without implementing an interface (I may well be wrong), and that was the kind of thing I really didn't want to do. Not only that, but for the kind of code I write, I either want to send something to the network, in which case I know which class to instantiate and don't need a base class reference, or I want to unmarshall bytes that came in. In the latter case there's usually an identifier in the header to tell the factory method which class to instantiante. So that doesn't usually come up.

Atila

November 19, 2013
On Tue, Nov 19, 2013 at 3:24 PM, Atila Neves <atila.neves@gmail.com> wrote:

>
>  * Objects - is the same object only serialized once or duplicated?
>>
>
> I'm not sure I understand the question.

...

Atila
>
> Perhaps Jacob refers to a lot of serialization formats being capable of
storing references to an object, this makes it possible to store circular lists for example.


November 19, 2013
On 2013-11-19 14:30, Rory McGuire wrote:

> Perhaps Jacob refers to a lot of serialization formats being capable of
> storing references to an object, this makes it possible to store
> circular lists for example.

Yes, exactly.

-- 
/Jacob Carlborg
November 19, 2013
On 2013-11-19 14:24, Atila Neves wrote:

> It serialises the slice and restores it as it was, not the data behind
> it. I should add some tests for that.

class Foo
{
    int[] a;
    int[] b;
}

auto foo = new Foo;
foo.a = [1, 2, 3, 4];
foo.b = foo.a[1 .. 3];

auto cereal = new Cerealiser();
cereal ~= foo;

auto decerealiser = new Decerealiser(cereal.bytes);
auto foo2 = decerealiser.value!(Foo);
foo2.b[0] = 10;
assert(foo2.a[1] == 10); // will this pass?

> I'm not sure I understand the question.

auto cereal = new Cerealiser();
cereal ~= foo;
cereal ~= foo; // will this be serialized a second time or will a reference to it be serialized?

> No. I can't see how that would be possible without implementing an
> interface (I may well be wrong), and that was the kind of thing I really
> didn't want to do. Not only that, but for the kind of code I write, I
> either want to send something to the network, in which case I know which
> class to instantiate and don't need a base class reference, or I want to
> unmarshall bytes that came in. In the latter case there's usually an
> identifier in the header to tell the factory method which class to
> instantiante. So that doesn't usually come up.

Even if you know the identifier in the header file you need a static type when deserializing:

decerealiser.value!(Foo)

Even if you can instantiate the right subclass you need to have the static type information to deserialize it.

It is possible to do, as I have done in Orange. The requirement is to register the subclasses that need to be serialized through a base class reference. See https://github.com/jacob-carlborg/orange/blob/master/orange/serialization/Serializer.d#L241..L262 and https://github.com/jacob-carlborg/orange/blob/master/orange/serialization/Serializer.d#L787..L788

-- 
/Jacob Carlborg
« First   ‹ Prev
1 2