fork download
  1. /** An old serializer utility.
  2.  
  3. Copyright: Denis Shelomovskij 2010
  4.  
  5. License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
  6.  
  7. Authors: Denis Shelomovskij
  8. */
  9. module serializer;
  10.  
  11. version(Win32) static assert(real.sizeof == 10);
  12. else version(linux) static assert(real.sizeof == 12);
  13. else static assert(0, "A new OS? Good!");
  14.  
  15. version(LittleEndian) { }
  16. else version(BigEndian) static assert(0, "BigEndian? Good!");
  17. else static assert(0, "LittleEndian or BigEndian?!");
  18.  
  19. import std.file, std.stream, std.traits;
  20.  
  21.  
  22. ///Data serialization helper
  23. void serialize(T)(Stream s, in T t) {
  24. SerializationStream!false(s).eat!T(t);
  25. }
  26.  
  27. ///ditto
  28. void deserialize(T)(Stream s, out T t) {
  29. SerializationStream!true(s).eat!T(t);
  30. }
  31.  
  32. ///Data serialization helper
  33. void[] serialize(T)(in T t) {
  34. scope s = new MemoryStream();
  35. s.readable = false;
  36. serialize(s, t);
  37. return s.data();
  38. }
  39.  
  40. ///ditto
  41. void deserialize(T)(in void[] data, out T t) {
  42. scope s = new MemoryStream(cast(ubyte[])data);
  43. s.writeable = false;
  44. deserialize(s, t);
  45. }
  46.  
  47. ///File serialization helper
  48. void serialize(T)(in string file, in T t) {
  49. write(file, serialize(t));
  50. }
  51.  
  52. ///ditto
  53. void deserialize(T)(in string file, out T t) {
  54. deserialize(read(file), t);
  55. }
  56.  
  57. private:
  58.  
  59. struct SerializationStream(bool read) {
  60. const bool write = !read;
  61. Stream stream;
  62.  
  63. //int l=0;
  64. void eat(T)(ref T t) {//char[] text;for(int i=0; i<l; ++i) text ~= '\t';
  65. static assert(!is(T == union), "can't eat union");
  66. static if(is(T == struct)) {
  67. //msg(text~"+ struct "~T.stringof);++l;
  68. static if(is(typeof(t.ownStreamProcess)))
  69. t.streamProcess(this);
  70. else
  71. foreach(i, el; t.tupleof)
  72. eat!(typeof(el))(t.tupleof[i]);
  73. //--l;msg(text~"- struct "~T.stringof, t);
  74. } else static if(is(T == class)) {
  75. //msg(text~"+ class "~T.stringof);++l;
  76. bool isNull = t is null;
  77. eat!bool(isNull);
  78. if(isNull) {
  79. static if(read)
  80. t = null;
  81. } else {
  82. static if(read)
  83. t = new T();
  84. static if(is(typeof(t.ownStreamProcess)))
  85. t.streamProcess(this);
  86. else
  87. foreach(i, el; t.tupleof)
  88. eat!(typeof(el))(t.tupleof[i]);
  89. }
  90. //msg(text~"- class "~T.stringof, t);
  91. } else {
  92. //D1: static assert(isAtomicType!(T) | is(T == enum), T.stringof);
  93. static assert(__traits(isArithmetic, T), T.stringof);
  94.  
  95. auto varr = cast(ubyte[])(&t)[0 .. 1];
  96. static if(real.sizeof > 10 && is(T == real)) {
  97. const i = real.sizeof - 10;
  98. static if(write)
  99. assert(varr[10 .. real.sizeof] == (new ubyte[i]));
  100. else
  101. varr[10 .. real.sizeof] = 0;
  102. varr.length = 10;
  103. }
  104. static if(write)
  105. stream.write(varr);
  106. else
  107. stream.read(varr);
  108. }
  109. }
  110.  
  111. //Запоминаем, когда это массив длины 0, а когда null
  112. void eat(T: T[])(ref T[] tarr) {
  113. //msg(write ? "write" : "read", "[]", T.stringof);
  114. int len;
  115. static if(write) {
  116. len = tarr is null ? -1 : tarr.length;
  117. eat!int(len);
  118. foreach(el; tarr)
  119. eat!(typeof(el))(el);
  120. } else {
  121. eat!int(len);
  122. if(len == -1)
  123. tarr = null;
  124. else if(len == 0)
  125. tarr = (cast(T*)"".ptr)[0..0];
  126. else {
  127. tarr.length = len;
  128. foreach(ref el; tarr)
  129. eat!(typeof(el))(el);
  130. }
  131. }
  132. //msg('\t', T.stringof, tarr);
  133. }
  134.  
  135. void eat(T: T[U], size_t U)(T[U] tarr) {
  136. static if(write)
  137. foreach(el; tarr)
  138. eat!(typeof(el))(el);
  139. else
  140. foreach(ref el; tarr)
  141. eat!(typeof(el))(el);
  142. }
  143. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/../../../libphobos2.a(dmain2_2d2_1a5.o): In function `_D2rt6dmain24mainUiPPaZi7runMainMFZv':
src/rt/dmain2.d:(.text._D2rt6dmain24mainUiPPaZi7runMainMFZv+0x10): undefined reference to `_Dmain'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/../../../libphobos2.a(deh2_2a9_525.o): In function `_D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable':
src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x4): undefined reference to `_deh_beg'
src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0xc): undefined reference to `_deh_beg'
src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x13): undefined reference to `_deh_end'
src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x37): undefined reference to `_deh_end'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/../../../libphobos2.a(thread_78_258.o): In function `_D4core6thread6Thread6__ctorMFZC4core6thread6Thread':
src/core/thread.d:(.text._D4core6thread6Thread6__ctorMFZC4core6thread6Thread+0x1d): undefined reference to `_tlsend'
src/core/thread.d:(.text._D4core6thread6Thread6__ctorMFZC4core6thread6Thread+0x24): undefined reference to `_tlsstart'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/../../../libphobos2.a(thread_75_713.o): In function `thread_entryPoint':
src/core/thread.d:(.text.thread_entryPoint+0x4e): undefined reference to `_tlsstart'
src/core/thread.d:(.text.thread_entryPoint+0x57): undefined reference to `_tlsend'
collect2: ld returned 1 exit status
--- errorlevel 1
stdout
Standard output is empty