Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>(note that this perhaps could be considered advertising, but the "product" is open sourced MIT licensed and even the other referenced "product" is open sourced MIT licensed) (note that I'm the author of the advertised "product" and of the other referenced "product") </p> <p>There wasn't any "good" solution so I have done mine :-) I had to create a library just to create the library: <a href="http://fluentserializer.codeplex.com" rel="nofollow">FluentSerializer</a>. The library can be used to create a "description" of how you want your binary data to be serialized. This description is written in a fluent notation. You can (through the other library I have written, <a href="http://fluentstatement.codeplex.com" rel="nofollow">FluentStatement</a>) include in your fluent description all the usual statements like <code>while</code>, <code>if</code>, <code>for</code>... (clearly using even there a fluent notation). Your description is then compiled as an Expression Tree and then as a group of dynamic methods (Serialize, Deserialize and Size (of serialized data) ).</p> <p>A small sample of the serializer for a test class</p> <pre><code>/// &lt;summary&gt; /// /// &lt;/summary&gt; public class Serializer : ISerializer&lt;MyClass, EmptyParameters&gt; { #region ISerializer&lt;MyClass,EmptyParameters&gt; Members /// &lt;summary&gt; /// /// &lt;/summary&gt; /// &lt;returns&gt;&lt;/returns&gt; public Expression&lt;Serializer&lt;MyClass, EmptyParameters&gt;&gt; GetSerializer() { return (op, obj, par) =&gt; Statement.Start(fl =&gt; fl .Serialize(obj.Version) // Static objects can be serialized/deserialized. .Serialize(MyClass.StaticReadonlyInts1, typeof(FixedLength&lt;&gt;)) // So can readonly collections. .Serialize(obj.ReadonlyInts1, typeof(FixedLength&lt;&gt;)) // Both array and List&lt;&gt; (and Dictionary&lt;,&gt;, and SortedDictionary&lt;,&gt;, and // many other types of collections) ////.Serialize(obj.ReadonlyList1) .Serialize(obj.ReadonlyList1, typeof(VariableLengthByte&lt;&gt;)) ////// Readonly fields can be serialized/deserialized. ////// Sadly you can't Dump() serializers that replace read only fields ////// (replace is the keyword here, readonly int X is a no-no, ////// readonly List&lt;int&gt; X is a yes, readonly int[] X is a yes if it's ////// FixedLength&lt;&gt;. ////.Serialize(obj.ReadonlyInt1) .Serialize(obj.Bool1) .Serialize(obj.Int2) // This will be serialized/deserialized only if obj.Version != 0 // It's only an example of what you can do. You can use the full power of // FluentStatement, and remember that if instead of EmptyParameters you // had used another class as the parameters, you could have manipulated it // through the par object, so par.Version for example. .If(obj.Version != 0, fl.Serialize(obj.Int3)) // This if(s) depend on the operation that is being done // (serialization/deserialization/size) .If(op == Operation.Serialize, fl.Serialize(obj.Int2)) .If(op == Operation.Deserialize, fl.Serialize(obj.Int3)) .Serialize(obj.Short1) // Tuples are supported. .Serialize(obj.Tuple1) // Arrays need to have the length prepended. There are helpers for this. // The default helper can be specified in the Serializer&lt;T&gt; constructor and // will be used if the field serializer isn't specified. ////.Serialize(obj.Ints1) // Or you can specify it: .Serialize(obj.Ints2, typeof(VariableLengthByte&lt;&gt;)) .Serialize(obj.Ints3, typeof(VariableLengthByte&lt;int[]&gt;)) // Nullable types are supported .Serialize(obj.NullableInt1, typeof(Nullable&lt;int&gt;)) ////.Serialize(obj.NullableInt2) // But note that you could even use the Optional&lt;&gt; with value types, // usefull for example if you have to use a modifier that is a class // (like VariableLengthInt32 for example) .Serialize(obj.NullableInt1, typeof(Optional&lt;int&gt;)) .Serialize(obj.NullableInt2, typeof(Optional&lt;&gt;)) // So are "optional" objects (fields that can be null) // (Note that here if we wanted to specify the helper, we would have // to use typeof(Optional&lt;VariableLengthByte&lt;int&gt;&gt;) .Serialize(obj.OptionalInts1, typeof(Optional&lt;VariableLengthInt32&lt;int[]&gt;&gt;)) .Serialize(obj.OptionalInts2, typeof(Optional&lt;&gt;)) .Serialize(obj.OptionalList1, typeof(Optional&lt;VariableLengthInt32&lt;List&lt;int&gt;&gt;&gt;)) .Serialize(obj.OptionalList2, typeof(Optional&lt;&gt;)) // You can serialize a DateTime as the full .NET value .Serialize(obj.DateTime1) // Or, for example, as an Unix datetime (32 or 64 bits) .Serialize(obj.DateTime2, typeof(UnixDateTime&lt;int&gt;)) .Serialize(obj.Float1) .Serialize(obj.Double1) .Serialize(obj.Decimal1) .Serialize(obj.TimeSpan1) // For strings it's a little more complex. There are too many combinations // of possible formats (encoding x string length * (use char or byte length)) // At this time there isn't any helper for C strings (null terminated strings). // You have to "manually" register you string formats. .Serialize(obj.String1, typeof(Program.MyUtf8VariableLengthInt32String)) .Serialize(obj.String2, typeof(Program.MyAsciiVariableLengthInt32String)) .Serialize(obj.String3, typeof(Program.MyUnicodeVariableLengthInt32String)) // Chain serializing the base class can be done in this way .Serialize(obj, typeof(MySimpleClass)) // This is only to make it easy to add new serialization fields. The last ) is // "attached" to the .Empty and doesn't need to be moved. .Empty()); } #endregion } </code></pre> <p>Clearly this library is good only if you have to serialize/deserialize a lot of data. If you only have a single object to serialize/deserialize, <code>BinaryReader</code>/<code>BinaryWriter</code> are probably enough for you (as suggested by me in the original question and by Fantius in his answer).</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload