Zoadian

Untitled

Apr 25th, 2013
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 3.81 KB | None | 0 0
  1. /*******************************************************************************
  2.  * Authors: $(WEB zoadian.de, Felix 'Zoadian' Hufnagel)                       /
  3.  * Copyright: $(WEB zoadian.de, Felix 'Zoadian' Hufnagel)                    /
  4.  ***************************************************************************/
  5. module zoadge.core.serialize;
  6.  
  7. import std.traits;
  8. import std.typetuple;
  9. import std.stdio;
  10.  
  11. //==========================================================================
  12. /// noserialize
  13. enum noserialize;
  14.  
  15. //==========================================================================
  16. /// serialize  
  17. ubyte[] serialize(T)(T t) pure nothrow {
  18.     ubyte[] data;
  19.     static if(isBasicType!T) {
  20.         data ~= *cast(ubyte[T.sizeof]*)&t;
  21.     } else static if(isDynamicArray!T) {
  22.         uint len = t.length; //max length is uint.max
  23.         data ~= *cast(ubyte[len.sizeof]*)&len;
  24.         data ~= cast(ubyte[])t;
  25.     } else static if(isStaticArray!T) {
  26.         auto l = t.length;
  27.         data ~= cast(ubyte[])t;
  28.     } else {
  29.         pragma(msg,  "serializing: " ~ T.stringof);
  30.         foreach(M; __traits(allMembers, T)) {
  31.             alias typeof(__traits(getAttributes, __traits(getMember, T, M))) ATR_TYPES;
  32.             //pragma(msg, ATR_TYPES);
  33.             static if(staticIndexOf!(noserialize, ATR_TYPES) == -1) {
  34.                 pragma(msg, "\tserializing: " ~ M);
  35.                
  36.                 data ~= serialize(__traits(getMember, t, M));
  37.             }  
  38.         }
  39.     }
  40.     return data;
  41. }
  42.  
  43. //==========================================================================
  44. /// deserialize
  45. auto deserialize(T)(ubyte[] data, size_t* rSize = null)   {
  46.     static if(isBasicType!T) {
  47.         if(rSize !is null) *rSize = T.sizeof;
  48.         return *cast(T*)data.ptr;
  49.     } else static if(isDynamicArray!T) {
  50.         enum TSIZE = ForeachType!(T).sizeof;
  51.         size_t lenInBytes = *cast(uint*)data.ptr * TSIZE;
  52.         enum LSIZE = lenInBytes.sizeof;
  53.         if(rSize !is null) *rSize = LSIZE+lenInBytes;
  54.         return cast(T)data[LSIZE..LSIZE+lenInBytes];
  55.     } else static if(isStaticArray!T) {
  56.         if(rSize !is null) *rSize = T.length * ForeachType!(T).sizeof;
  57.         return (cast(ForeachType!(T)*)data.ptr)[0 .. T.length];
  58.     } else {
  59.         T t;
  60.         size_t tlen = 0;
  61.         pragma(msg,  "deserializing: " ~ T.stringof);
  62.         foreach(M; __traits(allMembers, T)) {  
  63.             alias typeof(__traits(getAttributes, __traits(getMember, T, M))) ATR_TYPES;
  64.             //pragma(msg, ATR_TYPES);
  65.             static if(staticIndexOf!(noserialize, ATR_TYPES) == -1) {
  66.                 pragma(msg, "\tdeserializing: " ~ typeof(__traits(getMember, t, M)).stringof);
  67.  
  68.                 size_t len = 0;
  69.                 __traits(getMember, t, M) = deserialize!(typeof(__traits(getMember, t, M)))(data, &len);
  70.                 data = data[len..$];
  71.                 tlen += len;
  72.             }  
  73.         }
  74.         if(rSize !is null) *rSize = tlen;
  75.         return t;
  76.     }
  77.     assert(0);
  78. }
  79.  
  80. unittest
  81. {
  82.     assert(deserialize!string([5,0,0,0,104,97,108,108,111]) == "hallo");
  83.     assert("hallo".serialize().deserialize!string() == "hallo");
  84.     assert(deserialize!int([42,0,0,0]) == 42);
  85.     assert(deserialize!(short[])([4,0,0,0,42,0,32,0,42,0,32,0]) == [42,32,42,32]);
  86.     assert(deserialize!(short[4])([42,0,32,0,42,0,32,0]) == cast(short[4])[42,32,42,32]);
  87.     assert(serialize(cast(byte)42) == [42]);
  88.     assert(serialize(cast(short)42) == [42,0]);
  89.     assert(serialize(cast(int)42) == [42,0,0,0]);
  90.     assert(serialize(cast(long)42) == [42,0,0,0,0,0,0,0]);
  91.     assert(serialize(cast(float)42.42) == [20,174,41,66]);
  92.     assert(serialize(cast(double)42.42) == [246,40,92,143,194,53,69,64]);
  93.  
  94.     struct ASFG
  95.     {
  96.         int c = 42;
  97.     }
  98.    
  99.     struct ASF
  100.     {
  101.         byte a = 42;
  102.         short b = 42;
  103.         ASFG df;
  104.         @noserialize int h = 42;
  105.         long d = 42;
  106.         float e = 42.42;
  107.         double f = 42.42;
  108.         int[2] arr = [32,23];
  109.         //string sadsd = "asdf"; //works but we can not use == to compare the struct later. -> TODO: write opEquals...
  110.     }
  111.    
  112.     ASF asf;
  113.     asf.serialize().writeln();
  114.     asf.serialize().deserialize!(ASF).writeln();
  115.     asf.writeln();
  116.     assert(asf.serialize().deserialize!(ASF) == asf);
  117. }
Advertisement
Add Comment
Please, Sign In to add comment