1 module utile.binary.tests; 2 import std, utile.misc, utile.binary, utile.logger, utile.binary.helpers; 3 4 void ensureResult(T)(in T value, const(ubyte)[] data) 5 { 6 const res = value.serializeMem; 7 assert(res == data, res.to!string); 8 9 const parsed = data.deserializeMem!T; 10 assert(parsed == value, parsed.to!string); 11 } 12 13 unittest 14 { 15 static struct B 16 { 17 uint k; 18 string s; 19 } 20 21 static struct A 22 { 23 B b; 24 ubyte v; 25 } 26 27 A a; 28 a.v = 10; 29 a.b.k = 12; 30 a.b.s = `hello`; 31 32 const(ubyte)[] data = [ 33 12, 0, 0, 0, // a.b.k 34 104, 101, 108, 108, 111, 0, // a.b.s 35 10, // a.v 36 ]; 37 38 ensureResult(a, data); 39 } 40 41 unittest 42 { 43 static struct S 44 { 45 @ZeroTerminated const(ubyte)[] str; 46 wstring wstr; 47 48 @(ArrayLength!(_ => 6), ZeroTerminated) string st; 49 @(ArrayLength!(_ => 6), ZeroTerminated) string st2; 50 @(ArrayLength!(_ => 4), ZeroTerminated) ubyte[] st3; 51 52 @ArrayLength!(_ => 6) string st4; 53 @ToTheEnd string st5; 54 } 55 56 S s; 57 s.str = [1, 2, 3]; 58 s.wstr = `1234`w; 59 s.st = `abc`; 60 s.st2 = `abcdef`; 61 s.st3 = [1, 2]; 62 s.st4 = "\0qwert"; 63 s.st5 = "\0a"; 64 65 const(ubyte)[] data = [ 66 1, 2, 3, 0, // str 67 49, 0, 50, 0, 51, 0, 52, 0, 0, 0, // wstr 68 97, 98, 99, 0, 0, 0, // st 69 97, 98, 99, 100, 101, 102, // st2 70 1, 2, 0, 0, // st3 71 0, 113, 119, 101, 114, 116, // st4 72 0, 97, // st5 73 ]; 74 75 ensureResult(s, data); 76 } 77 78 unittest 79 { 80 struct S 81 { 82 ubyte a; 83 @ToTheEnd wstring d; 84 } 85 86 S s; 87 s.a = 10; 88 s.d = `hello`w; 89 90 const(ubyte)[] data = [ 91 10, // a 92 104, 0, 101, 0, 108, 0, 108, 0, 111, 0, // d 93 ]; 94 95 ensureResult(s, data); 96 } 97 98 unittest 99 { 100 struct S 101 { 102 @(ToTheEnd, ZeroTerminated) wstring d; 103 } 104 105 S s; 106 s.d = `hello`w; 107 108 const(ubyte)[] data = [ 109 104, 0, 101, 0, 108, 0, 108, 0, 111, 0, 0, 0, // d 110 ]; 111 112 ensureResult(s, data); 113 } 114 115 unittest 116 { 117 static struct S 118 { 119 ubyte val; 120 S* next; 121 } 122 123 auto s = S(12); 124 s.next = new S(13); 125 126 auto data = s.serializeMem; 127 assert(data == [12, 1, 13, 0]); 128 129 auto v = data.deserializeMem!S; 130 131 assert(v.val == s.val); 132 assert(v.next && *v.next == *s.next); 133 } 134 135 unittest 136 { 137 static struct Test 138 { 139 enum X = 10; 140 141 enum Y 142 { 143 i = 12 144 } 145 146 static struct S 147 { 148 uint k = 4; 149 } 150 151 static int sx = 1; 152 __gshared int gx = 2; 153 154 Y y; 155 static Y sy; 156 157 static void f() 158 { 159 } 160 161 static void f2() pure nothrow @nogc @safe 162 { 163 } 164 165 shared void g() 166 { 167 } 168 169 static void function() fp; 170 __gshared void function() gfp; 171 void function() fpm; 172 173 void delegate() dm; 174 static void delegate() sd; 175 176 void m() 177 { 178 } 179 180 final void m2() const pure nothrow @nogc @safe 181 { 182 } 183 184 inout(int) iom() inout 185 { 186 return 10; 187 } 188 189 static inout(int) iosf(inout int x) 190 { 191 return x; 192 } 193 194 @property int p() 195 { 196 return 10; 197 } 198 199 static @property int sp() 200 { 201 return 10; 202 } 203 204 union 205 { 206 int a; 207 float b; 208 long u; 209 double gg; 210 } 211 212 S s; 213 static immutable char[4] c = `ABCD`; 214 string d; 215 216 @(ArrayLength!uint) int[] e; 217 @(ArrayLength!(a => a.that.e.length)) int[] r; 218 219 @Ignored int kk; 220 @(IgnoreIf!(a => a.that.r.length == 3)) int rt; 221 222 @(ToTheEnd, Skip!(a => a.that.rt)) byte[] q; 223 } 224 225 static assert(fieldsToProcess!Test == [`y`, `u`, `s`, `c`, `d`, `e`, `r`, `rt`, `q`]); 226 227 const(ubyte)[] data = [ 228 12, 0, 0, 0, // y 229 11, 0, 0, 0, 0, 0, 0, 0, // a 230 4, 0, 0, 0, // S.k 231 65, 66, 67, 68, // c 232 97, 98, 99, 0, // d, null terminated 233 3, 0, 0, 0, // e.length 234 1, 0, 0, 0, // e[0] 235 2, 0, 0, 0, // e[1] 236 3, 0, 0, 0, // e[3] 237 4, 0, 0, 0, // r[0], length is set by the user 238 5, 0, 0, 0, // r[1] 239 6, 0, 0, 0, // r[2] 240 1, 2, 3, 4, // q[4] 241 ]; 242 243 Test t = {a: 11, d: `abc`, e: [1, 2, 3], r: [4, 5, 6], q: [1, 2, 3, 4]}; 244 245 ensureResult(t, data); 246 247 enum File = `__tmp`; 248 serializeFile(File, t); 249 250 scope (exit) 251 std.file.remove(File); 252 253 assert(deserializeFile!Test(File) == t); 254 }