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