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