1 module yu.tools.serialize; 2 3 public import yu.tools.serialize.write; 4 public import yu.tools.serialize.read; 5 public import yu.tools.serialize.types; 6 7 /** 8 * 按照顺序写入和读出,不关心原来的变量名的,不记录写的顺序。 9 * 存储基本大端字节序存储。 10 * 二进制格式: 11 * 对于基本和内置组合类型: 数据的长度是固定的。 12 * 类型头 数据部分 13 * 00 __data__ 14 * 类型头的定义见type.d 文件 15 * Struct 组合类型: 16 * 类型头 数据部分 结束标志(Types.End) 17 * 0x0F __data__ 0x00 18 * 结构提在写入的时候是每个成员都按照顺序写入,元素是结构提也是嵌套写入,数组一样。 19 * Array 数组类型: 20 * 类型头 元素的类型标志 元素的个数(4Byte) 数据部分 结束标志(Types.End) 21 * 0x10 00 00 00 00 00 __data__ 0x00 22 * 如果数组成员是结构体或者数组,记录的也只是Type.Struct和Types.Array, 其__data__部分也是和单独写一样的遵照标志写的是全部的和单独一样, 23 * 对于结构体不关系结构体的结构信息,根据类型头和结束标志区分。数组一样,不关系数组的类型长度,只根据开始和结束标志区分。 24 * 对于基本类型和内置组合类型,数据部分和单独写不一样的,省略其类型信息,类型信息根据数组的“元素的类型标志”获取的,即认为每个元素类型是一致的,元素自己的长度是固定的。 25 * 26 * 例子: 27 * 对于TAT 结构的二进制后的数据: 28 * 15, // TAT 开始的标志, 0x0F 29 * 30 * 15 // TAT.ta第一个元素ta的开始标志 TA 类型: 0x0F 31 * 13, 0, 1, 1, 1, // TAT.TA.de ,Date类型:0x0D(13), 数据4位 32 * 16 // TAT.TA.data 数组类型,尅是标志0X10(16) 33 * 2 // TAT.TA.data 的元素类型: ubyte (0x02) 34 * 0, 0, 0, 5, //AT.TA.data 的元素个数: 5 个 35 * 0, 1, 3, 4, 5, //AT.TA.data data 数据不部分 36 * 00 // TAT.TA.data 的结束标志位 37 * 16 //TAT.TA.str 数组开始类型头 Note: string 不可变的 char数组 38 * 1 // TAT.TA.str 元素类型: char 39 * 0, 0, 0, 11, // TAT.TA.str 元素个数 40 * 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100 // TAT.TA.str 数据部分 41 * 0 // TAT.TA.str 结束标志 42 * 11, 64, 41, 40, 245, 194, 143, 92, 41, //TAT.TA.db double数据类型 0x0B(11),后面8位为数据部分 43 * 8, 0, 0, 0, 0, 0, 0, 3, 129, //TAT.TA.lo long类型 0x08(8),后面8位为数据部分 44 * 3, 0, // TAT.TA.bl bool类型 0x03(3) , 0 是 flase 45 * 7, 0, 0, 0, 90,// TAT.TA.ui uint类型 0x07(7) , 剩下的是数据部分 46 * 15, // TAT.TA.ta 结构体开始标志位 47 * 10, 62, 131, 18, 111, // TAT.TA.TT.ft float类型0x0A(10),4个字节长度 48 * 14, 7, 223, 2, 15, 10, 25, 30, // TAT.TA.TT.dt DateTime类型0x0E(14),7个字节长度 49 * 0, // TAT.TA.ta 结构体结束标志位 50 * 16 // TAT.TA.iarry 数组开始标志位 51 * 6 // TAT.TA.iarry 数组的元素类型 int : 0x06(6) 52 * 0, 0, 0, 10, // TAT.TA.iarry 数据长度 53 * 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 9,// TAT.TA.iarry 数据部分 54 * 0 //TAT.TA.iarry 结束标志 55 * 0// TAT.ta 结构体结束标志 56 * 57 * 16// TAT.tt 数组的开始标志 58 * 15 // TAT.tt 数组元素类型 59 * 0, 0, 0, 3, TAT.tt 数组元素长度 60 * 15 // TAT.tt[0] 开始标志 61 * 10, 62, 131, 18, 111, // TAT.tt[0].ft 62 * 14, 7, 223, 2, 15, 10, 25, 30, // TAT.tt[0].dt 63 * 00 // TAT.tt[0] 开结束标志 64 * 15, 10, 63, 160, 196, 156, 14, 7, 224, 2, 15, 10, 25, 30, 0, // TAT.tt[1] 65 * 15, 10, 64, 16, 98, 78, 14, 7, 225, 2, 15, 10, 25, 30, 0, // TAT.tt[2] 66 * 0 // TAT.tt 数组的结束标志 67 * 68 * 16, // TAT.ttt 数组的开始标志 69 * 16 // TAT.ttt 数组的元素类型, 还是数组,数组嵌套 70 * 0, 0, 0, 2, //TAT.ttt 数组长度 71 * 16 //TAT.ttt[0] 开始标志 72 * 15 // TAT.ttt[0] 的元素类型, 结构体 73 * 0, 0, 0, 3 // TAT.ttt[0] 的元素个数 74 * 15, 10, 62, 131, 18, 111, 14, 7, 223, 2, 15, 10, 25, 30, 0, //TAT.ttt[0][0] 结构提类型 75 * 15, 10, 62, 182, 69, 162, 14, 7, 224, 2, 15, 10, 25, 30, 0, //TAT.ttt[0][1] 76 * 15, 10, 62, 233, 120, 213, 14, 7, 225, 2, 15, 10, 25, 30, 0, //TAT.ttt[0][2] 77 * 0 //TAT.ttt[0] 结束标志 78 * 16 //TAT.ttt[1] 开始标志 79 * 15 TAT.ttt[1] 的元素类型, 结构体 80 * 0, 0, 0, 3 // TAT.ttt[1] 的元素个数 81 * 15, 10, 63, 160, 196, 156, 14, 7, 226, 2, 15, 10, 25, 30, 0, //TAT.ttt[1][0] 82 * 15, 10, 63, 173, 145, 104, 14, 7, 227, 2, 15, 10, 25, 30, 0, //TAT.ttt[1][1] 83 * 15, 10, 64, 22, 200, 180, 14, 7, 228, 10, 2, 10, 25, 30, 0, //TAT.ttt[1][2] 84 * 0 //TAT.ttt[1] 结束标志 85 * 0// TAT.ttt 数组的结束标志 86 * 87 * 0 // TAT 结束标志 88 * 89 */ 90 91 92 version(unittest) 93 { 94 import yu.tools.serialize.build; 95 import std.experimental.allocator.mallocator; 96 import std.stdio; 97 struct TT 98 { 99 float ft; 100 DateTime dt; 101 mixin Serialize!TT; 102 } 103 104 struct TT2 105 { 106 float ft; 107 DateTime dt; 108 int tt2; 109 mixin Serialize!TT2; 110 } 111 112 struct TA 113 { 114 Date de; 115 ubyte[] data; 116 string str; 117 double db; 118 long lo; 119 bool bl; 120 uint ui; 121 122 123 TT ta; 124 125 int[] iarry; 126 127 mixin Serialize!TA; 128 } 129 130 131 struct TAT 132 { 133 enum AA = 10; 134 TA ta; 135 TT[] tt; 136 TT[][] ttt; 137 mixin Serialize!TAT; 138 139 void intd() 140 {} 141 142 int getD() 143 { 144 return 0; 145 } 146 } 147 148 149 150 void testTAT() 151 { 152 TA ta; 153 ta.data = [0x00,0x01,0x03,0x04,0x05]; 154 ta.str = "hello world"; 155 ta.db = 12.58; 156 ta.lo = 897; 157 ta.bl = false; 158 ta.ui = 90; 159 ta.ta = TT(0.256f,DateTime(2015,2,15,10,25,30)); 160 ta.iarry = [0,1,2,3,4,5,6,7,8,9]; 161 162 TAT tat; 163 tat.ta = ta; 164 tat.tt = [TT(0.256f,DateTime(2015,2,15,10,25,30)),TT(1.256f,DateTime(2016,2,15,10,25,30)),TT(2.256f,DateTime(2017,2,15,10,25,30))]; 165 tat.ttt = new TT[][2]; 166 tat.ttt[0] = [TT(0.256f,DateTime(2015,2,15,10,25,30)),TT(0.356f,DateTime(2016,2,15,10,25,30)),TT(0.456f,DateTime(2017,2,15,10,25,30))]; 167 tat.ttt[1] = [TT(1.256f,DateTime(2018,2,15,10,25,30)),TT(1.356f,DateTime(2019,2,15,10,25,30)),TT(2.356f,DateTime(2020,10,2,10,25,30))]; 168 auto buffer = new Buffer!Mallocator(); 169 WriteStream strem = WriteStream(buffer); 170 TAT.serialize(tat,&strem); 171 ubyte[] data = cast(ubyte[])(buffer.allData.data); 172 writeln("---------TAT.unSerialize----------"); 173 writeln("sridata is : \n", data); 174 TAT ttat; 175 ReadStream steam = ReadStream(data); 176 177 TAT.unSerialize(&ttat,&steam); 178 writeln("AA ", TAT.AA); 179 writeln("ttat.ta.data = ", ttat.ta.data); 180 writeln("ttat.ta.iarry = ", ttat.ta.iarry); 181 writeln("ttat.ta.str = ", ttat.ta.str); 182 writeln("ttat.ta.ta.ft = ", ttat.ta.ta.ft); 183 writeln("ttat.ta.ta.dt = ", ttat.ta.ta.dt.toISOExtString()); 184 writeln("ttat.ta.db = ", ttat.ta.db); 185 writeln("ttat.ta.ui = ", ttat.ta.ui); 186 writeln("ttat.tt.length = ",ttat.tt.length ); 187 writeln("ttat.tt[0].date = ",ttat.tt[0].dt ); 188 writeln("ttat.ttt[0][0].date = ",ttat.ttt[0][0].dt ); 189 } 190 191 void seriTT(ref TT t, WriteStream * strem) 192 { 193 strem.startStruct(); 194 scope(exit)strem.endStruct(); 195 strem.write!float(t.ft); 196 strem.write!DateTime(t.dt); 197 } 198 199 TA readTA(ReadStream * strem) 200 { 201 TA t; 202 strem.startReadStruct(); 203 t.de = strem.read!(Date)(); 204 t.data = strem.read!(ubyte[])(); 205 t.str = strem.read!(string)(); 206 t.db = strem.read!(double)(); 207 t.lo = strem.read!(long)(); 208 t.bl = strem.read!(bool)(); 209 t.ui = strem.read!(uint)(); 210 // strem.append(seriTT(t.ta,&strem)); 211 t.ta = readTT(strem); 212 uint len = strem.startReadArray(); 213 t.iarry = new int[len]; 214 foreach(i;0..len) 215 { 216 t.iarry[i] = strem.read!(int)(); 217 } 218 return t; 219 } 220 221 TT readTT(ReadStream * strem) 222 { 223 TT t; 224 strem.startReadStruct(); 225 t.ft = strem.read!float(); 226 t.dt = strem.read!DateTime(); 227 strem.endReadStruct(); 228 return t; 229 } 230 } 231 232 unittest 233 { 234 writeln("Edit source/app.d to start your project."); 235 236 TT tt; 237 tt.ft = 0.1258f; 238 tt.dt = DateTime(2015,2,15,10,25,30); 239 240 TA ta; 241 ta.data = [0x00,0x01,0x03,0x04,0x05]; 242 ta.str = "hello world"; 243 ta.db = 12.58; 244 ta.lo = 897; 245 ta.bl = false; 246 ta.ui = 90; 247 ta.ta = tt; 248 ta.iarry = [0,1,2,3,4,5,6,7,8,9]; 249 250 TAT tat; 251 tat.ta = ta; 252 tat.tt = [TT(0.256f,DateTime(2015,2,15,10,25,30)),TT(1.256f,DateTime(2016,2,15,10,25,30)),TT(2.256f,DateTime(2017,2,15,10,25,30))]; 253 tat.ttt = new TT[][2]; 254 tat.ttt[0] = [TT(0.256f,DateTime(2015,2,15,10,25,30)),TT(0.356f,DateTime(2016,2,15,10,25,30)),TT(0.456f,DateTime(2017,2,15,10,25,30))]; 255 tat.ttt[1] = [TT(1.256f,DateTime(2018,2,15,10,25,30)),TT(1.356f,DateTime(2019,2,15,10,25,30)),TT(2.356f,DateTime(2020,3,15,10,25,30))]; 256 257 auto buffer = new Buffer!Mallocator(); 258 WriteStream strem = WriteStream(buffer); 259 TA.serialize(ta,&strem); 260 ubyte[] data = cast(ubyte[])(buffer.allData.data); 261 writeln("sridata is : ", data); 262 263 ReadStream steam = ReadStream(data); 264 265 TA tta; 266 writeln("TA.unSerialize"); 267 TA.unSerialize(&tta,&steam); 268 269 assert(ta.data == tta.data); 270 assert(ta.iarry == tta.iarry); 271 assert(ta.str == tta.str); 272 assert(ta.ta.ft == tta.ta.ft); 273 assert(ta.ta.dt == tta.ta.dt); 274 assert(ta.db == tta.db); 275 assert(ta.ui == tta.ui); 276 277 writeln("\n\n\n"); 278 279 import std.traits; 280 string aaa; 281 writeln("char is : ",is(ForeachType!(string) == char) ); 282 283 284 writeln("\n--------------------------\n"); 285 writeln("build fun: \n", _serializeFun!TT(), "\n\n-----------------------------"); 286 enum strin = _serializeFun!TAT(); 287 writeln("build fun: \n", strin, "\n\n-----------------------------"); 288 289 testTAT(); 290 } 291 292 unittest 293 { 294 TT2 tt2; 295 tt2.ft = 0.1258f; 296 tt2.dt = DateTime(2015,2,15,10,25,30); 297 tt2.tt2 = 5000; 298 299 auto buffer = new Buffer!Mallocator(); 300 WriteStream strem = WriteStream(buffer); 301 TT2.serialize(tt2,&strem); 302 ubyte[] data = cast(ubyte[])(buffer.allData.data); 303 304 ReadStream steam = ReadStream(data); 305 306 TT tt; 307 writeln("TT.unSerialize"); 308 TT.unSerialize(&tt,&steam); 309 310 assert(tt.ft == tt2.ft); 311 assert(tt.dt == tt2.dt); 312 }