1 module yu.tools.serialize.build;
2 
3 import yu.traits;
4 
5 public import yu.tools.serialize.write;
6 public import yu.tools.serialize.read;
7 public import yu.tools.serialize.types;
8 public import yu.tools.buffer;
9 
10 mixin template Serialize(T) if(isStruct!T)
11 {
12 //	enum __buildStr__ = _serializeFun!T();
13 //    pragma(msg,__buildStr__);
14 	mixin(_serializeFun!T());
15 
16 	pragma(inline)
17 	static IBuffer serialize(ref T value, IBuffer buffer)
18 	{
19 		WriteStream stream = WriteStream(buffer);
20 		serialize(value,&stream);
21 		return buffer;
22 	}
23 
24 	pragma(inline)
25 	static T unsSerialize(ReadStream * stream)
26 	{
27 		T value;
28 		unSerialize(&value,stream);
29 		return value;
30 	}
31 }
32 
33 string _serializeFun(T)() if(isStruct!T)
34 {
35 	string str = "static void serialize(ref " ~ T.stringof ~ " value, WriteStream * stream){\n";
36 	str ~= "stream.startStruct();\n scope(success) stream.endStruct();\n";
37 
38 	string  rstr = "static void unSerialize(" ~ T.stringof ~ " * value, ReadStream * stream){\n";
39 	rstr ~= "stream.startReadStruct();\n scope(success) stream.endReadStruct();\n";
40 
41 	foreach(memberName; FieldNameTuple!T)
42 	{
43         alias CurrtType = typeof(__traits(getMember,T, memberName));
44 		static if(isBasicSupport!(CurrtType).isBSupport && !isCallable!(__traits(getMember,T, memberName)))
45 		{
46 			static if(isStruct!(CurrtType))
47 			{
48 				static if(isArray!(CurrtType))
49 				{
50 					str ~= writeStructArray!(CurrtType,"value." ~ memberName)();
51                     rstr ~= readArray!(CurrtType,"value." ~ memberName)();
52 				}
53 				else
54 				{
55 					str ~= CurrtType.stringof ~ ".serialize(value." ~ memberName ~ ", stream);\n";
56 					rstr ~= CurrtType.stringof ~ ".unSerialize(&value." ~ memberName ~ ", stream);\n";
57 				}
58 			}
59 			else
60 			{
61 				str ~= "stream.write!(" ~ CurrtType.stringof ~ ")(" ~ "value." ~ memberName ~ ");\n";
62                 static if(isArray!(CurrtType) && !is(CurrtType == string))
63                 {
64                     rstr ~= readArray!(CurrtType,"value." ~ memberName)();
65                     //rstr ~= "stream.read!(" ~ CurrtType.stringof ~ ")((" ~ ForeachType!(CurrtType).stringof ~ " x){ value." ~ memberName ~ " ~= x;});\n";
66                 }
67                 else 
68                 {
69 				    rstr ~= "value." ~ memberName ~ " = stream.read!(" ~ CurrtType.stringof ~ ")();\n";
70                 }
71 			}
72 		}
73 	}
74 	str ~= "}\n";
75 	rstr ~= "}\n";
76 	return str ~ "\n" ~ rstr;
77 }
78 
79 string writeStructArray(T,string memberName, int i = 0)()
80 {
81 	string str = "{stream.startArray!(";
82 	str ~= ForeachType!(T).stringof ~ ")();\n";
83 	str ~= "foreach(ref v"~ i.stringof ~" ; " ~ memberName ~ "){\n";
84 	static if(isArray!(ForeachType!T))
85 	{
86 		str ~= writeStructArray!(ForeachType!T,"v"~ i.stringof, i + 1)();
87 	}
88 	else
89 	{
90 		str ~= ForeachType!T.stringof ~ ".serialize(v"~ i.stringof ~ " ,stream);\n";
91 	}
92 	str ~= "}\n";
93 	str ~= "stream.endArray();}\n";
94 	return str;
95 }
96 
97 string readArray(T,string memberName, int i = 0)()
98 {
99 	string  str = "{\n/*writeln(\"read array in : "~ memberName ~"\");*/\n ";
100 	str ~= "uint leng" ~ i.stringof ~ " = stream.startReadArray();\n";
101 //	str ~= "writeln(\"======\");\n ";
102 	str ~= memberName ~ " = new " ~ ForeachType!T.stringof ~ "[leng" ~  i.stringof ~ "];\n";
103 	str ~= "foreach(v"~ i.stringof ~" ; 0..leng" ~ i.stringof ~ "){\n";
104 	static if(isArray!(ForeachType!T))
105 	{
106         str ~= readArray!(ForeachType!T,memberName ~"[v"~ i.stringof ~ "]", i + 1)();
107 	}
108     else if(isStruct!(ForeachType!T))
109 	{
110 		str ~= ForeachType!T.stringof ~ ".unSerialize(&"~memberName ~ "[v"~ i.stringof ~ "] , stream);\n";
111 		
112     } else {
113         str ~= memberName ~ "[v"~ i.stringof ~ "] = stream.read!(" ~ ForeachType!T.stringof ~ ")();\n"; 
114     }
115 	str ~= "}\n";
116 	str ~= "stream.endReadArray();\n}\n";
117 	return str;
118 }