digitalmars.D.announce - Cerealed v0.2.0 - a(nother) D serialisation library
- Atila Neves (41/41) Nov 18 2013 http://code.dlang.org/packages/cerealed
- Jacob Carlborg (8/10) Nov 18 2013 How does it handle:
- Rory McGuire (7/14) Nov 18 2013 Hi Jacob,
- Jacob Carlborg (8/13) Nov 18 2013 Orange doesn't have any data transport layer or similar. But you can do
- Rory McGuire (7/11) Nov 19 2013 Thanks. I believe that is the example that made me think that its main
- Jacob Carlborg (8/14) Nov 19 2013 Yes, that should be possible. It depends on how the data looks like. The...
- Atila Neves (21/30) Nov 19 2013 It serialises the slice and restores it as it was, not the data
- Rory McGuire (5/9) Nov 19 2013 ...
- Jacob Carlborg (4/7) Nov 19 2013 Yes, exactly.
- Jacob Carlborg (32/43) Nov 19 2013 class Foo
- Atila Neves (14/26) Nov 20 2013 Ah, I see. No, it won't. Which answers the other question about
- Jacob Carlborg (7/10) Nov 20 2013 It's a lot easier to add support for references than slices. The reason
- Vicente (29/29) Sep 08 2014 Hello Atila,
- Atila Neves (3/33) Sep 09 2014 I'll take a look. It's easier to post this on github though.
- Atila Neves (5/35) Sep 11 2014 Done.
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
Nov 18 2013
On 2013-11-18 17:49, Atila Neves wrote:http://code.dlang.org/packages/cerealed https://github.com/atilaneves/cerealedHow 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
Nov 18 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 CarlborgHi 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
Nov 18 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
Nov 18 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 CarlborgThanks. 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?
Nov 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
Nov 19 2013
On Monday, 18 November 2013 at 20:43:51 UTC, Jacob Carlborg wrote:On 2013-11-18 17:49, 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.http://code.dlang.org/packages/cerealed https://github.com/atilaneves/cerealedHow does it handle: * Slices - are they restored?* 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
Nov 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?... AtilaI'm not sure I understand the question.Perhaps Jacob refers to a lot of serialization formats being capable ofstoring references to an object, this makes it possible to store circular lists for example.
Nov 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
Nov 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/Ser alizer.d#L241..L262 and https://github.com/jacob-carlborg/orange/blob/master/orange/serialization/Serializer.d#L787..L788 -- /Jacob Carlborg
Nov 19 2013
assert(foo2.a[1] == 10); // will this pass?Ah, I see. No, it won't. Which answers the other question about serialising references to objects. I'm told this is a common problem, but this being my first bash at a serialisation library... I was certain that Orange would be more mature and handle more corner cases than this library (or else it wouldn't be considered for inclusion in the std lib), but I wanted to share it since it works for what I'm doing, does things a bit differently and does what I need. Also, it was fun coding it. If anything, if you think some of these ideas are worth it, feel free to use them. I'm just glad to not have to write the same old bit twiddling code for networking headers again!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/Ser alizer.d#L241..L262 and https://github.com/jacob-carlborg/orange/blob/master/orange/serialization/Serializer.d#L787..L788True, I thought of doing something like it to simplify my MQTT broker implementation but ended up deciding against it.
Nov 20 2013
On 2013-11-20 18:26, Atila Neves wrote:Ah, I see. No, it won't. Which answers the other question about serialising references to objects. I'm told this is a common problem, but this being my first bash at a serialisation library...It's a lot easier to add support for references than slices. The reason is that you always know when there is a reference type. With arrays you don't know if it's a slice of some array or an actual array. The type system treats both slices and arrays the same. -- /Jacob Carlborg
Nov 20 2013
Hello Atila, I've seen that cerealed has made much progress, it's now at v0.5.0 This post is for a feature request, I would like to use it with a struct like this: import cerealed; struct nested_associative_array { nested_associative_array[int] x; } struct some_struct { string[] x; int[][] y; nested_associative_array[] z; }; void main(char[][] args) { some_struct original, restored; auto enc = Cerealiser(); enc ~= original; auto dec = Decerealiser(enc.bytes); restored = dec.value!(some_struct); assert(original==restored); } The serialization process compiles fine, but the restoring part fails to compile. I've tried to figure out how to do it, but I am still a beginner on D. How difficult do you think it is? The alternative, orange, works fine, but the struct I'm trying to export to disk is a few hundreds of MB in size and orange takes hours to complete and may also run out of memory. Your implementation, instead, is really fast and efficient!
Sep 08 2014
I'll take a look. It's easier to post this on github though. Atila On Monday, 8 September 2014 at 19:09:30 UTC, Vicente wrote:Hello Atila, I've seen that cerealed has made much progress, it's now at v0.5.0 This post is for a feature request, I would like to use it with a struct like this: import cerealed; struct nested_associative_array { nested_associative_array[int] x; } struct some_struct { string[] x; int[][] y; nested_associative_array[] z; }; void main(char[][] args) { some_struct original, restored; auto enc = Cerealiser(); enc ~= original; auto dec = Decerealiser(enc.bytes); restored = dec.value!(some_struct); assert(original==restored); } The serialization process compiles fine, but the restoring part fails to compile. I've tried to figure out how to do it, but I am still a beginner on D. How difficult do you think it is? The alternative, orange, works fine, but the struct I'm trying to export to disk is a few hundreds of MB in size and orange takes hours to complete and may also run out of memory. Your implementation, instead, is really fast and efficient!
Sep 09 2014
Done. Thanks for the feature request and using Cerealed! I hope it's useful to you. Atila On Monday, 8 September 2014 at 19:09:30 UTC, Vicente wrote:Hello Atila, I've seen that cerealed has made much progress, it's now at v0.5.0 This post is for a feature request, I would like to use it with a struct like this: import cerealed; struct nested_associative_array { nested_associative_array[int] x; } struct some_struct { string[] x; int[][] y; nested_associative_array[] z; }; void main(char[][] args) { some_struct original, restored; auto enc = Cerealiser(); enc ~= original; auto dec = Decerealiser(enc.bytes); restored = dec.value!(some_struct); assert(original==restored); } The serialization process compiles fine, but the restoring part fails to compile. I've tried to figure out how to do it, but I am still a beginner on D. How difficult do you think it is? The alternative, orange, works fine, but the struct I'm trying to export to disk is a few hundreds of MB in size and orange takes hours to complete and may also run out of memory. Your implementation, instead, is really fast and efficient!
Sep 11 2014