1 /*
2  * Kiss - A refined core library for D programming language.
3  *
4  * Copyright (C) 2015-2018  Shanghai Putao Technology Co., Ltd
5  *
6  * Developer: HuntLabs.cn
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module kiss.util.serialize;
13 
14 import std.traits;
15 import std.string;
16 import core.stdc.string;
17 import std.stdio;
18 import std.bitmanip;
19 import std.math;
20 public import std.json;
21 
22 public:
23 enum IGNORE = 1024;
24 
25 class UnIgnoreArray{
26 	
27 	void setUnIgnore(T)()
28 	{
29 		_unIgnore[T.stringof] = true;
30 	}
31 
32 	bool ignore(T)()
33 	{
34 		return T.stringof !in _unIgnore;
35 	}
36 
37 private:
38 	bool[string] _unIgnore;
39 }
40 
41 
42 private:
43 
44 class RefClass
45 {
46 	size_t[size_t] map;
47 	void*[] arr;
48 	uint level;
49 	bool ignore;	 				///  all class or struct ignore or not. 
50 	UnIgnoreArray unIgnore;			///  part class unignore. 
51 }
52 
53 enum MAGIC_KEY = "o0o0o";
54 
55 enum bool isType(T1, T2) = is(T1 == T2) || is(T1 == ImmutableOf!T2)
56 		|| is(T1 == ConstOf!T2) || is(T1 == InoutOf!T2)
57 		|| is(T1 == SharedOf!T2) || is(T1 == SharedConstOf!T2) || is(T1 == SharedInoutOf!T2);
58 
59 enum bool isSignedType(T) = isType!(T, byte) || isType!(T, short) || isType!(T,
60 			int) || isType!(T, long);
61 enum bool isUnsignedType(T) = isType!(T, ubyte) || isType!(T, ushort)
62 		|| isType!(T, uint) || isType!(T, ulong);
63 enum bool isBigSignedType(T) = isType!(T, int) || isType!(T, long);
64 enum bool isBigUnsignedType(T) = isType!(T, uint) || isType!(T, ulong);
65 
66 //unsigned
67 ulong[] byte_dots = [1 << 7, 1 << 14, 1 << 21, 1 << 28, cast(ulong) 1 << 35,
68 	cast(ulong) 1 << 42, cast(ulong) 1 << 49, cast(ulong) 1 << 56, cast(ulong) 1 << 63,];
69 
70 //signed
71 ulong[] byte_dots_s = [1 << 6, 1 << 13, 1 << 20, 1 << 27, cast(ulong) 1 << 34,
72 	cast(ulong) 1 << 41, cast(ulong) 1 << 48, cast(ulong) 1 << 55, cast(ulong) 1 << 62,];
73 
74 ubyte getbytenum(ulong v)
75 {
76 	ubyte i = 0;
77 	for (; i < byte_dots.length; i++)
78 	{
79 		if (v < byte_dots[i])
80 		{
81 			break;
82 		}
83 	}
84 	return cast(ubyte)(i + 1);
85 }
86 
87 ubyte getbytenums(ulong v)
88 {
89 	ubyte i = 0;
90 	for (; i < byte_dots_s.length; i++)
91 	{
92 		if (v < byte_dots_s[i])
93 		{
94 			break;
95 		}
96 	}
97 
98 	return cast(ubyte)(i + 1);
99 }
100 
101 //signed
102 byte[] toVariant(T)(T t) if (isSignedType!T)
103 {
104 	bool symbol = false;
105 	if (t < 0)
106 		symbol = true;
107 
108 	ulong val = cast(ulong) abs(t);
109 
110 	ubyte num = getbytenums(val);
111 
112 	ubyte[] var;
113 	if(num == 1)
114 	{
115 		if (symbol)
116 			val = val | 0x40;
117 	}
118 	else{
119 		for (size_t i = num; i > 1; i--)
120 		{
121 			auto n = val / (byte_dots_s[i - 2] * 2);
122 			if (symbol && i == num)
123 				n = n | 0x40;
124 			var ~= cast(ubyte) n;
125 			val = (val % (byte_dots_s[i - 2] * 2));
126 		}
127 	}
128 
129 	var ~= cast(ubyte)(val | 0x80);
130 	return cast(byte[]) var;
131 }
132 
133 T toT(T)(const byte[] b, out long index) if (isSignedType!T)
134 {
135 	T val = 0;
136 	ubyte i = 0;
137 	bool symbol = false;
138 
139 	if(b.length == 1)
140 	{
141 		val = (b[i] & 0x3F);
142 		if (b[i] & 0x40)
143 			symbol = true;
144 	}
145 	else
146 	{
147 		for (i = 0; i < b.length; i++)
148 		{
149 			if (i == 0)
150 			{
151 				val = (b[i] & 0x3F);
152 				if (b[i] & 0x40)
153 					symbol = true;			
154 			}
155 			else
156 			{
157 				val = cast(T)((val << 7) + (b[i] & 0x7F));
158 			}
159 		
160 			if (b[i] & 0x80)
161 				break;
162 		}
163 	}
164 
165 	index = i + 1;
166 	if (symbol)
167 		return cast(T)(val * -1);
168 	else
169 		return val;
170 }
171 
172 //unsigned
173 byte[] toVariant(T)(T t) if (isUnsignedType!T)
174 {
175 	ubyte num = getbytenum(cast(ulong) t);
176 	T val = t;
177 	ubyte[] var;
178 	for (size_t i = num; i > 1; i--)
179 	{
180 		auto n = val / (byte_dots[i - 2]);
181 		var ~= cast(ubyte) n;
182 		val = val % (byte_dots[i - 2]);
183 	}
184 	var ~= cast(ubyte)(val | 0x80);
185 	return cast(byte[]) var;
186 }
187 
188 //unsigned
189 T toT(T)(const byte[] b, out long index) if (isUnsignedType!T)
190 {
191 	T val = 0;
192 	ubyte i = 0;
193 	for (i = 0; i < b.length; i++)
194 	{
195 
196 		val = cast(T)((val << 7) + (b[i] & 0x7F));
197 		if (b[i] & 0x80)
198 			break;
199 	}
200 	index = i + 1;
201 	return val;
202 }
203 
204 byte getbasictype(long size)
205 {
206 	if (size == 1)
207 		return 0;
208 	else if (size == 2)
209 		return 1;
210 	else if (size == 4)
211 		return 2;
212 	else if (size == 8)
213 		return 3;
214 	else
215 		assert(0);
216 }
217 
218 byte getbasicsize(byte type)
219 {
220 	if (type == 0)
221 		return 1;
222 	else if (type == 1)
223 		return 2;
224 	else if (type == 2)
225 		return 4;
226 	else if (type == 3)
227 		return 8;
228 	else
229 		assert(0);
230 }
231 
232 string serializeMembers(T)()
233 {
234 	string str;
235 	foreach (m; FieldNameTuple!T)
236 	{
237 		static if (__traits(getProtection, __traits(getMember, T, m)) == "public")
238 		{
239 			str ~= "data ~= serialize(t." ~ m ~ " , stack , level + 1);";
240 		}
241 	}
242 	return str;
243 }
244 
245 string unserializeMembers(T)()
246 {
247 	string str;
248 	str ~= "long parse = 0; ";
249 	foreach (m; FieldNameTuple!T)
250 	{
251 		static if (__traits(getProtection, __traits(getMember, T, m)) == "public")
252 		{
253 			str ~= " if ( index < parse_index)";
254 			str ~= "{";
255 			str ~= "t." ~ m ~ " = unserialize!(typeof(t." ~ m
256 				~ "))(data[cast(uint)index .. data.length] , parse , stack); ";
257 			str ~= "index += parse; }";
258 		}
259 
260 	}
261 	return str;
262 }
263 
264 string getsizeMembers(T)()
265 {
266 	string str;
267 	foreach (m; FieldNameTuple!T)
268 	{
269 		static if (__traits(getProtection, __traits(getMember, T, m)) == "public")
270 		{
271 		str ~= "total += getsize(t." ~ m ~ " , stack , level + 1);";
272 		}		
273 	}
274 	return str;
275 }
276 
277 ///////////////////////////////////////////////////////////
278 // basic
279 // type 		  size
280 //  0     - 		1
281 //  1	 -			2
282 //  2	 -			4
283 //  3	 - 			8
284 //	data
285 ///////////////////////////////////////////////////////////
286 ///
287 byte[] serialize(T)(T t, RefClass stack, uint level)
288 		if (isScalarType!T && !isBigSignedType!T && !isBigUnsignedType!T)
289 {
290 	byte[] data;
291 	data.length = T.sizeof + 1;
292 	data[0] = getbasictype(T.sizeof);
293 	memcpy(data.ptr + 1, &t, T.sizeof);
294 	return data;
295 }
296 
297 T unserialize(T)(const byte[] data, out long parse_index, RefClass stack)
298 		if (isScalarType!T && !isBigSignedType!T && !isBigUnsignedType!T)
299 {
300 	assert(cast(byte) T.sizeof == getbasicsize(data[0]));
301 
302 	T value;
303 	memcpy(&value, data.ptr + 1, T.sizeof);
304 
305 	parse_index = T.sizeof + 1;
306 	return value;
307 }
308 
309 size_t getsize(T)(T t, RefClass stack, uint level)
310 		if (isScalarType!T && !isBigSignedType!T && !isBigUnsignedType!T)
311 {
312 	return T.sizeof + 1;
313 }
314 
315 ///////////////////////////////////////////////////////////
316 // variant
317 // type 		  size
318 //  5 (4)    - 		
319 //  6 (8)	 -
320 //	data
321 ///////////////////////////////////////////////////////////
322 byte[] serialize(T)(T t, RefClass stack, uint level)
323 		if (isBigSignedType!T || isBigUnsignedType!T)
324 {
325 	byte[] data = toVariant!T(t);
326 	long index;
327 	byte[1] h;
328 	h[0] = (T.sizeof == 4) ? 5 : 8;
329 	return h ~ data;
330 }
331 
332 T unserialize(T)(const byte[] data, out long parse_index, RefClass stack)
333 		if (isBigSignedType!T || isBigUnsignedType!T)
334 {
335 	assert((T.sizeof == 4 ? 5 : 8) == data[0]);
336 	long index;
337 	T t = toT!T(data[1 .. $], index);
338 	parse_index = index + 1;
339 	return t;
340 }
341 
342 size_t getsize(T)(T t, RefClass stack, uint level) if (isBigSignedType!T)
343 {
344 	return getbytenums(abs(t)) + 1;
345 }
346 
347 size_t getsize(T)(T t, RefClass stack, uint level) if (isBigUnsignedType!T)
348 {
349 	return getbytenum(abs(t)) + 1;
350 }
351 
352 // TString
353 // 1 type 7
354 // [uint] variant 
355 //  data
356 
357 byte[] serialize(T)(T str, RefClass stack, uint level) if (is(T == string))
358 {
359 	byte[] data;
360 	uint len = cast(uint) str.length;
361 	byte[] dlen = toVariant(len);
362 	data.length = 1 + dlen.length + len;
363 
364 	data[0] = 7;
365 	memcpy(data.ptr + 1, dlen.ptr, dlen.length);
366 	memcpy(data.ptr + 1 + dlen.length, str.ptr, len);
367 	return data;
368 }
369 
370 string unserialize(T)(const byte[] data, out long parse_index, RefClass stack)
371 		if (is(T == string))
372 {
373 	assert(data[0] == 7);
374 	long index;
375 	uint len = toT!uint(data[1 .. $], index);
376 	parse_index += 1 + index + len;
377 	return cast(T)(data[cast(size_t)(1 + index) .. cast(size_t) parse_index].dup);
378 }
379 
380 size_t getsize(T)(T str, RefClass stack, uint level) if (is(T == string))
381 {
382 	uint len = cast(uint) str.length;
383 	return cast(size_t)(1 + toVariant(len).length + str.length);
384 }
385 
386 // TUnion			don't support TUnion
387 // 1 type 6
388 // 1 len 
389 // 	 data
390 
391 /*
392 byte[] serialize(T)(T t) if(is(T == union))
393 {
394 	byte[] data;
395 	data.length = T.sizeof + 2;
396 	data[0] = 5;
397 	data[1] = T.sizeof;
398 	memcpy(data.ptr + 2 , &t , T.sizeof);
399 	return data;
400 }
401 
402 T unserialize(T)(const byte[] data ) if(is(T == union))
403 {
404 	long parser_index;
405 	return unserialize!T(data , parser_index);
406 }
407 
408 T unserialize(T)(const byte[] data , out long parse_index) if(is(T == union))
409 {
410 	assert(data[0] == 5);
411 	
412 	T value;
413 	byte len;
414 	memcpy(&len , data.ptr + 1 , 1);
415 	parse_index = 2 + len;
416 	memcpy(&value , data.ptr + 2 , len);
417 	return value;
418 }
419 
420 size_t getsize(T)(T t) if(is(T == union))
421 {
422 	return 2 + T.sizeof;
423 }
424 
425 */
426 
427 // TSArray
428 // 1 type 8
429 // size[uint] variant
430 // len[uint] variant
431 // data
432 
433 byte[] serialize(T)(T t, RefClass stack, uint level) if (isStaticArray!T)
434 {
435 	byte[1] header;
436 	header[0] = 8;
437 	uint uSize = cast(uint) t.length;
438 	byte[] dh = cast(byte[]) header;
439 	dh ~= toVariant(uSize);
440 
441 	byte[] data;
442 	for (size_t i = 0; i < uSize; i++)
443 	{
444 		data ~= serialize(t[i], stack, level + 1);
445 	}
446 	uint len = cast(uint) data.length;
447 	dh ~= toVariant(len);
448 	return dh ~ data;
449 }
450 
451 T unserialize(T)(const byte[] data, out long parse_index, RefClass stack)
452 		if (isStaticArray!T)
453 {
454 	assert(data[0] == 8);
455 	T value;
456 	uint uSize;
457 	uint len;
458 	long index1;
459 	long index2;
460 	uSize = toT!uint(data[1 .. $], index1);
461 
462 	len = toT!uint(data[cast(size_t)(index1 + 1) .. $], index2);
463 	parse_index += 1 + index1 + index2;
464 
465 	long index = parse_index;
466 	long parse = 0;
467 	for (size_t i = 0; i < uSize; i++)
468 	{
469 		parse = 0;
470 		value[i] = unserialize!(typeof(value[0]))(data[cast(size_t) index .. data.length],
471 				parse, stack);
472 		index += parse;
473 	}
474 
475 	parse_index += len;
476 
477 	return value;
478 }
479 
480 size_t getsize(T)(T t, RefClass stack, uint level) if (isStaticArray!T)
481 {
482 	long total = 1;
483 	total += getbytenum(t.length);
484 	uint uSize = cast(uint) t.length;
485 	for (size_t i = 0; i < uSize; i++)
486 	{
487 		total += getsize(t[i], stack, level + 1);
488 	}
489 	total += getbytenum(total);
490 	return total;
491 }
492 
493 //  TDArray
494 // 1  type 9
495 // size[uint]	variant
496 // length[uint]	variant
497 // data
498 
499 byte[] serialize(T)(T t, RefClass stack, uint level)
500 		if (isDynamicArray!T && !is(T == string))
501 {
502 	byte[1] header;
503 	header[0] = 9;
504 
505 	uint uSize = cast(uint) t.length;
506 	byte[] dh = cast(byte[]) header;
507 	dh ~= toVariant(uSize);
508 
509 	byte[] data;
510 	for (size_t i = 0; i < uSize; i++)
511 	{
512 		data ~= serialize(t[i], stack, level + 1);
513 	}
514 	uint len = cast(uint) data.length;
515 	dh ~= toVariant(len);
516 
517 	return dh ~ data;
518 }
519 
520 T unserialize(T)(const byte[] data, out long parse_index, RefClass stack)
521 		if (isDynamicArray!T && !is(T == string))
522 {
523 	assert(data[0] == 9);
524 
525 	T value;
526 	uint uSize;
527 	uint len;
528 	long index1;
529 	long index2;
530 	uSize = toT!uint(data[1 .. $], index1);
531 	len = toT!uint(data[cast(size_t)(1 + index1) .. $], index2);
532 
533 	parse_index += 1 + index1 + index2;
534 	value.length = uSize;
535 	ulong index = parse_index;
536 	long parse = 0;
537 	for (size_t i = 0; i < uSize; i++)
538 	{
539 		value[i] = unserialize!(typeof(value[0]))(data[cast(size_t) index .. data.length],
540 				parse, stack);
541 		index += parse;
542 	}
543 	parse_index += len;
544 
545 	return value;
546 }
547 
548 size_t getsize(T)(T t, RefClass stack, uint level)
549 		if (isDynamicArray!T && !is(T == string))
550 {
551 	long total = 1;
552 	total += getbytenum(t.length);
553 	uint uSize = cast(uint) t.length;
554 	for (size_t i = 0; i < uSize; i++)
555 	{
556 		total += getsize(t[i], stack, level + 1);
557 	}
558 	total += getbytenum(total);
559 	return total;
560 }
561 
562 // TStruct
563 // 1 type 10
564 // [uint] variant
565 // data
566 
567 byte[] serialize(T)(T t, RefClass stack, uint level) if (is(T == struct))
568 {
569 	byte[1] header;
570 	header[0] = 10;
571 	byte[] data;
572 
573 	mixin(serializeMembers!T());
574 	byte[] dh = cast(byte[]) header;
575 	uint len = cast(uint) data.length;
576 	dh ~= toVariant(len);
577 	return dh ~ data;
578 }
579 
580 T unserialize(T)(const byte[] data, out long parse_index, RefClass stack)
581 		if (is(T == struct))
582 {
583 	assert(data[0] == 10);
584 
585 	T t;
586 	long index1;
587 	uint len = toT!uint(data[1 .. $], index1);
588 
589 	parse_index = 1 + index1 + len;
590 	long index = 1 + index1;
591 	mixin(unserializeMembers!T());
592 
593 	return t;
594 }
595 
596 size_t getsize(T)(T t, RefClass stack, uint level) if (is(T == struct))
597 {
598 	long total = 1;
599 
600 	mixin(getsizeMembers!T());
601 
602 	total += getbytenum(total);
603 	return cast(uint) total;
604 }
605 
606 // TClass 
607 // 1 type 11
608 // [uint] len variant
609 //	data
610 
611 // TClass ref
612 // 1 type 12
613 // id variant
614 
615 byte[] serialize(T)(T t, RefClass stack, uint level) if (is(T == class))
616 {
617 	byte[1] header;
618 	size_t* id = null;
619 
620 	if (t !is null)
621 	{
622 		id = t.toHash() in stack.map;
623 	}
624 
625 	if (id == null)
626 	{
627 		header[0] = 11;
628 		byte[] data;
629 		byte[] dh = cast(byte[]) header;
630 		if (t !is null)
631 		{
632 			stack.map[t.toHash()] = stack.map.length;
633 			mixin(serializeMembers!T());
634 		}
635 		uint len = cast(uint) data.length;
636 		dh ~= toVariant(len);
637 
638 		return dh ~ data;
639 	}
640 	else
641 	{
642 		header[0] = 12;
643 		byte[] dh = cast(byte[]) header;
644 		dh ~= toVariant(*id);
645 		return dh;
646 	}
647 
648 }
649 
650 T unserialize(T)(const byte[] data, out long parse_index, RefClass stack)
651 		if (is(T == class))
652 {
653 	assert(data[0] == 11 || data[0] == 12);
654 
655 	if (data[0] == 11)
656 	{
657 		long index1;
658 		uint len = toT!uint(data[1 .. $], index1);
659 		if (len == 0)
660 			return null;
661 		T t = new T;
662 		parse_index = index1 + 1 + len;
663 		long index = index1 + 1;
664 		stack.arr ~= cast(void*) t;
665 		mixin(unserializeMembers!T());
666 		return t;
667 	}
668 	else
669 	{
670 		long index1;
671 		size_t id = toT!size_t(data[1 .. $], index1);
672 		parse_index += index1 + 1;
673 		return cast(T) stack.arr[id];
674 	}
675 
676 }
677 
678 size_t getsize(T)(T t, RefClass stack, uint level) if (is(T == class))
679 {
680 	long total = 1;
681 
682 	size_t* id = null;
683 
684 	if (t !is null)
685 	{
686 		id = t.toHash() in stack.map;
687 	}
688 
689 	if (id == null)
690 	{
691 		if (t !is null)
692 		{
693 			stack.map[t.toHash()] = stack.map.length;
694 			mixin(getsizeMembers!T());
695 		}
696 
697 		total += getbytenum(total - 1);
698 		return total;
699 	}
700 	else
701 	{
702 		return getbytenum(*id) + 1;
703 	}
704 
705 }
706 
707 // AssociativeArray
708 // 1 type 13
709 // [uint] len variant
710 // (k,v)
711 
712 byte[] serialize(T)(T t, RefClass stack, uint level) if (isAssociativeArray!T)
713 {
714 	byte[1] header;
715 	header[0] = 13;
716 	byte[] dh;
717 	dh ~= cast(byte[]) header;
718 	byte[] data;
719 	foreach (k, v; t)
720 	{
721 		data ~= serialize(k, stack, level + 1);
722 		data ~= serialize(v, stack, level + 1);
723 	}
724 	uint len = cast(uint) data.length;
725 	dh ~= toVariant(len);
726 	return dh ~ data;
727 }
728 
729 T unserialize(T)(const byte[] data, out long parse_index, RefClass stack)
730 		if (isAssociativeArray!T)
731 {
732 	assert(data[0] == 13);
733 
734 	T t;
735 	long index1;
736 	uint len = toT!uint(data[1 .. $], index1);
737 
738 	parse_index = index1 + 1 + len;
739 	long index = index1 + 1;
740 	while (index < parse_index)
741 	{
742 		long out_len;
743 		auto k = unserialize!(KeyType!T)(data[index .. $], out_len, stack);
744 		index += out_len;
745 		out_len = 0;
746 		auto v = unserialize!(ValueType!T)(data[index .. $], out_len, stack);
747 		index += out_len;
748 		t[k] = v;
749 	}
750 	return t;
751 }
752 
753 size_t getsize(T)(T t, RefClass stack, uint level) if (isAssociativeArray!T)
754 {
755 	long total = 1;
756 	foreach (k, v; t)
757 	{
758 		total += serialize(k).length;
759 		total += serialize(v).length;
760 	}
761 	total += getbytenum(total - 1);
762 	return total;
763 }
764 
765 public:
766 
767 T unserialize(T)(const byte[] data )
768 {
769 	long parse_index;
770 	return unserialize!T(data, parse_index);
771 }
772 
773 T unserialize(T)(const byte[] data, out long parse_index )
774 {
775 	RefClass stack = new RefClass();
776 	return unserialize!T(data, parse_index, stack);
777 }
778 
779 byte[] serialize(T)(T t )
780 {
781 	RefClass stack = new RefClass();
782 	return serialize!T(t, stack, 0);
783 }
784 
785 size_t getsize(T)(T t )
786 {
787 	RefClass stack = new RefClass();
788 	return getsize!T(t, stack, 0);
789 }
790 
791 //////////////////////////////////////////////////////////////////json///////////////////////////
792 private:
793 enum bool isFloatType(T) = isType!(T, float) || isType!(T, double);
794 
795 JSONValue toJSON(T)(T t, RefClass stack, uint level)
796 		if (isSignedType!T || isUnsignedType!T || is(T == string) || is(T == bool) || isFloatType!T)
797 {
798 	return JSONValue(t);
799 }
800 
801 // uinteger
802 T toOBJ(T)(JSONValue v, RefClass stack) if (isUnsignedType!T)
803 {
804 	if(v.type() == JSON_TYPE.UINTEGER)
805 		return cast(T) v.uinteger;
806 	else
807 		return T.init;
808 }
809 
810 // integer
811 T toOBJ(T)(JSONValue v, RefClass stack) if (isSignedType!T)
812 {
813 	if(v.type() == JSON_TYPE.INTEGER)
814 		return cast(T) v.integer;
815 	else
816 		return T.init;
817 }
818 
819 // string
820 T toOBJ(T)(JSONValue v, RefClass stack) if (is(T == string))
821 {
822 	if(v.type() == JSON_TYPE.STRING)
823 		return v.str;
824 	else
825 		return T.init;
826 }
827 
828 // bool
829 T toOBJ(T)(JSONValue v, RefClass stack) if (is(T == bool))
830 {
831 	if(v.type() == JSON_TYPE.TRUE || v.type() == JSON_TYPE.FALSE)
832 		return v.type() == JSON_TYPE.TRUE;
833 	else
834 		return T.init;
835 }
836 
837 // floating
838 T toOBJ(T)(JSONValue v, RefClass stack) if (isFloatType!T)
839 {
840 	if(v.type() == JSON_TYPE.FLOAT)
841 		return cast(T) v.floating;
842 	else
843 		return  T.init;
844 }
845 
846 
847 // array
848 JSONValue toJSON(T)(T t, RefClass stack, uint level)
849 		if (isStaticArray!T || (isDynamicArray!T && !is(T == string)))
850 {
851 	JSONValue[] j;
852 	foreach (e; t)
853 	{
854 		j ~= toJSON(e, stack, level);
855 	}
856 
857 	return JSONValue(j);
858 }
859 
860 T toOBJ(T)(JSONValue v, RefClass stack) if (isStaticArray!T)
861 {
862 	T t;
863 	if(v.type() == JSON_TYPE.ARRAY)
864 	{
865 		for (size_t i = 0; i < t.length; i++)
866 		{
867 			t[i] = toOBJ!(typeof(t[i]))(v.array[i], stack);
868 		}
869 	}
870 	return t;
871 	
872 }
873 
874 T toOBJ(T)(JSONValue v, RefClass stack) if (isDynamicArray!T && !is(T == string))
875 {
876 	T t;
877 	if(v.type() == JSON_TYPE.ARRAY)
878 	{
879 		t.length = v.array.length;
880 		for (size_t i = 0; i < t.length; i++)
881 		{
882 			t[i] = toOBJ!(typeof(t[i]))(v.array[i], stack);
883 		}
884 	}
885 	return t;
886 }
887 
888 // struct & class
889 
890 string toJSONMembers(T , bool ignore)()
891 {
892 	string str;
893 	foreach (m; FieldNameTuple!T)
894 	{
895 		static if (__traits(getProtection, __traits(getMember, T, m)) == "public")
896 		{
897 			if(!ignore || !hasUDA!(__traits(getMember , T , m) ,IGNORE ))
898 			{
899 				str ~= "j[\"" ~ m ~ "\"] = toJSON(t." ~ m ~ " , stack , level + 1);";
900 			}	
901 		}
902 	}
903 	return str;
904 }
905 
906 string toJSONMembersAll(T)()
907 {
908 	string str;
909 	foreach (m; FieldNameTuple!T)
910 	{
911 		static if (__traits(getProtection, __traits(getMember, T, m)) == "public")
912 		{		
913 			str ~= "j[\"" ~ m ~ "\"] = toJSON(t." ~ m ~ " , stack , level + 1);";
914 		}
915 	}
916 	return str;
917 }
918 
919 
920 
921 string toOBJMembers(T)()
922 {
923 	string str;
924 	foreach (m; FieldNameTuple!T)
925 	{
926 		static if (__traits(getProtection, __traits(getMember, T, m)) == "public")
927 		{
928 			str ~= " if ( \"" ~ m ~ "\"  in j )";
929 			str ~= "t." ~ m ~ " = toOBJ!(typeof(t." ~ m ~ "))(j[\"" ~ m ~ "\"] , stack);";
930 		}
931 
932 	}
933 	return str;
934 }
935 
936 JSONValue toJSON(T)(T t, RefClass stack, uint level) if (is(T == struct))
937 {
938 	JSONValue j;
939 
940 	static if (is(T == JSONValue))
941 	{
942 		return t;
943 	}
944 	else{
945 		bool ignore = (stack.unIgnore is null)? stack.ignore :(stack.unIgnore.ignore!T);
946 
947 		if(ignore)
948 			mixin(toJSONMembers!(T,true));
949 		else
950 			mixin(toJSONMembers!(T,false));
951 
952 
953 
954 
955 		
956 		return j;
957 	}
958 }
959 
960 T toOBJ(T)(JSONValue j, RefClass stack) if (is(T == struct))
961 {
962 	static if (is(T == JSONValue))
963 	{
964 		return j;
965 	}
966 	else
967 	{
968 		T t;
969 		if(j.type() == JSON_TYPE.OBJECT)
970 		{
971 			mixin(toOBJMembers!T);
972 		}
973 		return t;
974 	}
975 }
976 
977 JSONValue toJSON(T)(T t, RefClass stack, uint level) if (is(T == class))
978 {
979 	if (t is null || level >= stack.level)
980 	{
981 		return JSONValue(null);
982 	}
983 
984 	auto id = t.toHash() in stack.map;
985 	if (id == null)
986 	{
987 		stack.map[t.toHash()] = stack.map.length;
988 		JSONValue j;
989 		bool ignore = (stack.unIgnore is null)? stack.ignore :(stack.unIgnore.ignore!T);
990 
991 		if(ignore)
992 			mixin(toJSONMembers!(T,true));
993 		else
994 			mixin(toJSONMembers!(T,false));
995 		return j;
996 	}
997 	else
998 	{
999 		JSONValue j;
1000 		j[MAGIC_KEY] = *id;
1001 		return j;
1002 	}
1003 }
1004 
1005 T toOBJ(T)(JSONValue j, RefClass stack) if (is(T == class))
1006 {
1007 	if ( j.type() != JSON_TYPE.OBJECT)
1008 		return T.init;
1009 	assert(j.type() == JSON_TYPE.OBJECT);
1010 
1011 	if (MAGIC_KEY in j)
1012 	{
1013 		return cast(T) stack.arr[j[MAGIC_KEY].uinteger];
1014 	}
1015 	else
1016 	{
1017 		T t = new T;
1018 		stack.arr ~= cast(void*) t;
1019 		mixin(toOBJMembers!T);
1020 		return t;
1021 	}
1022 }
1023 
1024 //AssociativeArray
1025 JSONValue toJSON(T)(T t, RefClass stack, uint level) if (isAssociativeArray!T)
1026 {
1027 	JSONValue j;
1028 	import std.conv;
1029 
1030 	foreach (k, v; t)
1031 		j[to!string(k)] = toJSON(v, stack, level);
1032 	return j;
1033 }
1034 
1035 T toOBJ(T)(JSONValue j, RefClass stack) if (isAssociativeArray!T)
1036 {
1037 	import std.conv;
1038 	if ( j.type() != JSON_TYPE.OBJECT)
1039 		return T.init;
1040 	T t;
1041 	foreach (k, v; j.object)
1042 	{
1043 		t[to!(KeyType!T)(k)] = toOBJ!(ValueType!T)(v, stack);
1044 	}
1045 	return t;
1046 }
1047 
1048 public:
1049 
1050 JSONValue toJSON(T)(T t , uint level = uint.max , bool ignore = true)
1051 {
1052 	RefClass stack = new RefClass();
1053 	stack.level = level;
1054 	stack.ignore = ignore;
1055 	return toJSON!T(t, stack, 0);
1056 }
1057 
1058 JSONValue toJSON(T)(T t   , UnIgnoreArray array  ,  uint level = uint.max)
1059 {
1060 	RefClass stack = new RefClass();
1061 	stack.level = level;
1062 	stack.unIgnore = array;
1063 	return toJSON!T(t, stack, 0);
1064 }
1065 
1066 
1067 
1068 T toOBJ(T)(JSONValue j)
1069 {
1070 	RefClass stack = new RefClass();
1071 	return toOBJ!T(j, stack);
1072 }
1073 
1074 alias toJson = toJSON;
1075 alias toObject = toOBJ;
1076 
1077 // only for , nested , new T
1078 /*
1079 version (unittest)
1080 {
1081 	//test struct
1082 
1083 		void test1(T)(T t)
1084 		{
1085 			assert(unserialize!T(serialize(t)) == t);
1086 
1087 			assert(serialize(t).length == getsize(t));
1088 
1089 			assert(toOBJ!T(toJSON(t)) == t);
1090 		}
1091 
1092 		struct T1
1093 		{
1094 			bool b;
1095 			byte ib;
1096 			ubyte ub;
1097 			short ish;
1098 			ushort ush;
1099 			int ii;
1100 			uint ui;
1101 			long il;
1102 			ulong ul;
1103 			string s;
1104 			uint[10] sa;
1105 			long[] sb;
1106 		}
1107 
1108 		struct T2
1109 		{
1110 			string n;
1111 			T1[] t;
1112 		}
1113 
1114 		struct T3
1115 		{
1116 			T1 t1;
1117 			T2 t2;
1118 			string[] name;
1119 		}
1120 
1121 		//test class
1122 		class C
1123 		{
1124 			int age;
1125 			string name;
1126 			T3 t3;
1127 			override bool opEquals(Object c)
1128 			{
1129 				auto c1 = cast(C) c;
1130 				return age == c1.age && name == c1.name && t3 == c1.t3;
1131 			}
1132 
1133 			C clone()
1134 			{
1135 				auto c = new C();
1136 				c.age = age;
1137 				c.name = name;
1138 				c.t3 = t3;
1139 				return c;
1140 			}
1141 
1142 		}
1143 
1144 		class C2
1145 		{
1146 			C[] c;
1147 			C c1;
1148 			T1 t1;
1149 
1150 			override bool opEquals(Object c)
1151 			{
1152 				auto c2 = cast(C2) c;
1153 				return this.c == c2.c && c1 == c2.c1 && t1 == c2.t1;
1154 			}
1155 		}
1156 
1157 		//ref test
1158 		class School
1159 		{
1160 			string name;
1161 			User[] users;
1162 			override bool opEquals(Object c)
1163 			{
1164 				auto school = cast(School) c;
1165 				return school.name == this.name;
1166 			}
1167 		}
1168 
1169 		class User
1170 		{
1171 			int age;
1172 			string name;
1173 			School school;
1174 			override bool opEquals(Object c)
1175 			{
1176 				auto user = cast(User) c;
1177 				return user.age == this.age && user.name == this.name && user.school == this.school;
1178 			}
1179 		}
1180 
1181 		struct J{
1182 			string data;
1183 			JSONValue val;
1184 		
1185 		}
1186 
1187 		void test_json_ser()
1188 		{
1189 			J j;
1190 			j.data = "test";
1191 			j.val = "FUC";
1192 
1193 			toObject!J(toJson(j));
1194 
1195 		}
1196 
1197 		void test_ref_class()
1198 		{
1199 			School school = new School();
1200 
1201 			User user1 = new User();
1202 			user1.age = 30;
1203 			user1.name = "zhangyuchun";
1204 			user1.school = school;
1205 
1206 			User user2 = new User();
1207 			user2.age = 31;
1208 			user2.name = "wulishan";
1209 			user2.school = school;
1210 
1211 			school.name = "putao";
1212 			school.users ~= user1;
1213 			school.users ~= user2;
1214 
1215 			test1(user1);
1216 			test1(user2);
1217 		}
1218 
1219 		void test_struct_class_array()
1220 		{
1221 			T1 t;
1222 			t.b = true;
1223 			t.ib = -11;
1224 			t.ub = 128 + 50;
1225 			t.ish = -50;
1226 			t.ush = (1 << 15) + 50;
1227 			t.ii = -50;
1228 			t.ui = (1 << 31) + 50;
1229 			t.il = (cast(long) 1 << 63) - 50;
1230 			t.ul = (cast(long) 1 << 63) + 50;
1231 			t.s = "test";
1232 			t.sa[0] = 10;
1233 			t.sa[1] = 100;
1234 			t.sb ~= 10;
1235 			t.sb ~= 100;
1236 			test1(t);
1237 
1238 			T2 t2;
1239 			t2.t ~= t;
1240 			t2.t ~= t;
1241 			t2.n = "testt2";
1242 			test1(t2);
1243 
1244 			T3 t3;
1245 			t3.t1 = t;
1246 			t3.t2 = t2;
1247 			t3.name ~= "123";
1248 			t3.name ~= "456";
1249 			test1(t3);
1250 
1251 			C c1 = new C();
1252 			c1.age = 100;
1253 			c1.name = "test";
1254 			c1.t3 = t3;
1255 
1256 			test1(c1);
1257 
1258 			C2 c2 = new C2();
1259 			c2.c ~= c1;
1260 			c2.c ~= c1.clone();
1261 			c2.c1 = c1.clone();
1262 			c2.t1 = t;
1263 
1264 			test1(c2);
1265 
1266 			C2 c3 = null;
1267 
1268 			test1(c3);
1269 
1270 			string[string] map1 = ["1" : "1", "2" : "2"];
1271 			string[int] map2 = [1 : "1", 2 : "2"];
1272 			T1[string] map3;
1273 			T1 a1;
1274 			a1.ib = 1;
1275 			T1 a2;
1276 			a2.ib = 2;
1277 			map3["1"] = a1;
1278 			map3["2"] = a2;
1279 			test1(map1);
1280 			test1(map2);
1281 			test1(map3);
1282 		}
1283 	
1284 }
1285 
1286 unittest
1287 {
1288 	import std.stdio;
1289 
1290 	long index;
1291 
1292 	void test(T)(T v)
1293 	{
1294 		long index;
1295 		byte[] bs = toVariant(v);
1296 		long length = bs.length;
1297 		bs ~= ['x', 'y'];
1298 		assert(toT!T(bs, index) == v && index == length);
1299 
1300 		assert(toOBJ!T(toJSON(v)) == v);
1301 
1302 	}
1303 
1304 	//test variant
1305 
1306 	//unsigned
1307 	{
1308 		ubyte j0 = 0;
1309 		ubyte j1 = 50;
1310 		ubyte j2 = (1 << 7) + 50;
1311 		ubyte j3 = 0xFF;
1312 
1313 		ushort j4 = (1 << 14) + 50;
1314 		ushort j5 = 0xFFFF;
1315 
1316 		uint j6 = (1 << 21) + 50;
1317 		uint j7 = (1 << 28) + 50;
1318 		uint j8 = 128;
1319 		uint j9 = 0xFFFFFFFF;
1320 
1321 		{
1322 
1323 
1324 		}
1325 
1326 		ulong j10 = (cast(ulong) 1 << 35) + 50;
1327 		ulong j11 = (cast(ulong) 1 << 42) + 50;
1328 		ulong j12 = (cast(ulong) 1 << 49) + 50;
1329 		ulong j13 = (cast(ulong) 1 << 56) + 50;
1330 		ulong j14 = j9 + j10 + j11 + j12;
1331 		ulong j15 = 0xFFFFFFFFFFFFFFFF;
1332 		test(j0);
1333 		test(j1);
1334 		test(j2);
1335 		test(j3);
1336 		test(j4);
1337 		test(j5);
1338 		test(j6);
1339 		test(j7);
1340 		test(j8);
1341 		test(j9);
1342 		test(j10);
1343 		test(j11);
1344 		test(j12);
1345 		test(j13);
1346 		test(j14);
1347 		test(j15);
1348 	}
1349 
1350 	//signed
1351 	{
1352 		byte i0 = 0;
1353 		byte i1 = (1 << 6) + 50;
1354 		byte i2 = (1 << 7) - 1;
1355 		byte i3 = -i2;
1356 		byte i4 = -i1;
1357 
1358 		test(i0);
1359 		test(i1);
1360 		test(i2);
1361 		test(i3);
1362 		test(i4);
1363 
1364 		short i5 = (1 << 7) + 50;
1365 		short i6 = (1 << 14) + 50;
1366 		short i7 = -i5;
1367 		short i8 = -i6;
1368 
1369 		test(i5);
1370 		test(i6);
1371 		test(i7);
1372 		test(i8);
1373 
1374 		int i9 = (1 << 16) + 50;
1375 		int i10 = (1 << 25) + 50;
1376 		int i11 = (1 << 30) + 50;
1377 		int i12 = 64;
1378 		int i13 = -i10;
1379 		int i14 = -i11;
1380 		int i15 = i9 + i10 + i11;
1381 		int i16 = -i15;
1382 
1383 
1384 
1385 		test(i9);
1386 		test(i10);
1387 		test(i11);
1388 		test(i12);
1389 		test(i13);
1390 		test(i14);
1391 		test(i15);
1392 		test(i16);
1393 
1394 		long i17 = (cast(long) 1 << 32) + 50;
1395 		long i18 = (cast(long) 1 << 48) + 50;
1396 		long i19 = (cast(long) 1 << 63) + 50;
1397 		long i20 = i17 + i18 + i19;
1398 		long i21 = -i17;
1399 		long i22 = -i20;
1400 
1401 		test(i17);
1402 		test(i18);
1403 		test(i19);
1404 		test(i20);
1405 		test(i21);
1406 		test(i22);
1407 
1408 		int i23 = -11;
1409 		test(i23);
1410 	}
1411 
1412 	//test serialize
1413 
1414 	//basic: byte ubyte short ushort int uint long ulong
1415 	{
1416 		byte b1 = 123;
1417 		byte b2 = -11;
1418 		ubyte b3 = 233;
1419 
1420 		short s1 = -11;
1421 		short s2 = (1 << 8) + 50;
1422 		short s3 = (1 << 15) - 50;
1423 		ushort s4 = (1 << 16) - 50;
1424 
1425 		int i1 = -11;
1426 		int i2 = (1 << 16) + 50;
1427 		int i3 = (1 << 31) - 50;
1428 		uint i4 = (1 << 31) + 50;
1429 
1430 		long l1 = -11;
1431 		long l2 = (cast(long) 1 << 32) + 50;
1432 		long l3 = (cast(long) 1 << 63) - 50;
1433 		ulong l4 = (cast(long) 1 << 63) + 50;
1434 
1435 		test1(b1);
1436 		test1(b2);
1437 		test1(b3);
1438 
1439 		test1(s1);
1440 		test1(s2);
1441 		test1(s3);
1442 		test1(s4);
1443 
1444 		test1(i1);
1445 		test1(i2);
1446 		test1(i3);
1447 		test1(i4);
1448 
1449 		test1(l1);
1450 		test1(l2);
1451 		test1(l3);
1452 		test1(l4);
1453 	}
1454 
1455 	//test string
1456 	{
1457 		string s1 = "";
1458 		string s2 = "1";
1459 		string s3 = "123";
1460 		test1(s1);
1461 		test1(s2);
1462 		test1(s3);
1463 	}
1464 
1465 	//test static arrary
1466 	{
1467 		string[5] sa;
1468 		sa[0] = "test0";
1469 		sa[1] = "test1";
1470 		sa[2] = "test2";
1471 		sa[3] = "test3";
1472 		sa[4] = "test4";
1473 		test1(sa);
1474 	}
1475 
1476 	//test dynamic arrary
1477 	{
1478 		string[] sa;
1479 		sa ~= "test1";
1480 		sa ~= "test2";
1481 		sa ~= "test3";
1482 		sa ~= "test4";
1483 
1484 		test1(sa);
1485 
1486 		string[] sa2;
1487 		test1(sa2);
1488 	}
1489 
1490 	//test struct \ class \ associative array
1491 	test_struct_class_array();
1492 	test_ref_class();
1493 	test_json_ser();
1494 
1495 	////unsigned
1496 		uint ut1 = 1 << 7;
1497 		uint ut2 = 1 << 14;
1498 		uint ut3 = 1 << 21;
1499 		uint ut4 = 1 << 28;
1500 
1501 //signed
1502 		int it1 = 1 << 6;
1503 		int it2 = 1 << 13;
1504 		int it3 = 1 << 20;
1505 		int it4 = 1 << 27;
1506 
1507 		test1(ut1);
1508 		test1(ut2);
1509 		test1(ut3);
1510 		test1(ut4);
1511 
1512 		test1(it1);
1513 		test1(it2);
1514 		test1(it3);
1515 		test1(it4);
1516 }
1517 */