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 }