1 // =================================
   2 // Copyright (c) 2021 Seppo Laakko
   3 // Distributed under the MIT license
   4 // =================================
   5 
   6 using System;
   7 using System.Collections;
   8 using System.Concepts;
   9 
  10 namespace System.Json
  11 {
  12     public class JsonImportException : Exception
  13     {
  14         public nothrow JsonImportException(const string& message_) : base(message_)
  15         {
  16         }
  17     }
  18     
  19     public concept JsonConstructible<T>
  20     {
  21         T(JsonValue* value);
  22     }
  23     
  24     public concept JsonValueType<T>
  25     {
  26         where System.Meta.IsBasicType<T>() or System.Meta.IsEnumeratedType<T>() or T is string or T is wstring or T is ustring or T is Date or T is DateTime or T is Timestamp or T is Uuid;
  27     }
  28     
  29     public void FromJson(JsonValue* valueint& field)
  30     {
  31         if (value is JsonNumber*)
  32         {
  33             JsonNumber* number = cast<JsonNumber*>(value);
  34             field = cast<int>(number->Value());
  35         }
  36         else
  37         {
  38             throw JsonImportException("JSON number expected");
  39         }
  40     }
  41 
  42     public void FromJson(JsonValue* valuedouble& field)
  43     {
  44         if (value is JsonNumber*)
  45         {
  46             JsonNumber* number = cast<JsonNumber*>(value);
  47             field = number->Value();
  48         }
  49         else
  50         {
  51             throw JsonImportException("JSON number expected");
  52         }
  53     }
  54 
  55     public void FromJson(JsonValue* valuebool& field)
  56     {
  57         if (value is JsonBool*)
  58         {
  59             JsonBool* b = cast<JsonBool*>(value);
  60             field = b->Value();
  61         }
  62         else
  63         {
  64             throw JsonImportException("JSON Boolean expected");
  65         }
  66     }
  67     
  68     public void FromJson<T>(JsonValue* valueT& field)
  69         where System.Meta.IsEnumeratedType<T>()
  70     {
  71         if (value is JsonNumber*)
  72         {
  73             JsonNumber* number = cast<JsonNumber*>(value);
  74             field = cast<T>(cast<T.UnderlyingType>(number->Value()));
  75         }
  76         else
  77         {
  78             throw JsonImportException("JSON number expected");
  79         }
  80     }
  81 
  82     public void FromJson(JsonValue* valuestring& field)
  83     {
  84         if (value is JsonString*)
  85         {
  86             JsonString* s = cast<JsonString*>(value);
  87             field = ToUtf8(s->Value());
  88         }
  89         else
  90         {
  91             throw JsonImportException("JSON string expected");
  92         }
  93     }
  94                                 
  95     public void FromJson(JsonValue* valuewstring& field)
  96     {
  97         if (value is JsonString*)
  98         {
  99             JsonString* s = cast<JsonString*>(value);
 100             field = ToUtf16(s->Value());
 101         }
 102         else
 103         {
 104             throw JsonImportException("JSON string expected");
 105         }
 106     }
 107                                 
 108     public void FromJson(JsonValue* valueustring& field)
 109     {
 110         if (value is JsonString*)
 111         {
 112             JsonString* s = cast<JsonString*>(value);
 113             field = s->Value();
 114         }
 115         else
 116         {
 117             throw JsonImportException("JSON string expected");
 118         }
 119     }
 120     
 121     public void FromJson(JsonValue* valueDate& field)
 122     {
 123         if (value is JsonString*)
 124         {
 125             JsonString* s = cast<JsonString*>(value);
 126             string str = ToUtf8(s->Value());
 127             field = ParseDate(str);
 128         }
 129         else
 130         {
 131             throw JsonImportException("JSON string expected");
 132         }
 133     }
 134 
 135     public void FromJson(JsonValue* valueDateTime& field)
 136     {
 137         if (value is JsonString*)
 138         {
 139             JsonString* s = cast<JsonString*>(value);
 140             string str = ToUtf8(s->Value());
 141             field = ParseDateTime(str);
 142         }
 143         else
 144         {
 145             throw JsonImportException("JSON string expected");
 146         }
 147     }
 148     
 149     public void FromJson(JsonValue* valueTimestamp& field)
 150     {
 151         if (value is JsonString*)
 152         {
 153             JsonString* s = cast<JsonString*>(value);
 154             string str = ToUtf8(s->Value());
 155             field = ParseTimestamp(str);
 156         }
 157         else
 158         {
 159             throw JsonImportException("JSON string expected");
 160         }
 161     }
 162     
 163     public void FromJson(JsonValue* valueUuid& field)
 164     {
 165         if (value is JsonString*)
 166         {
 167             JsonString* s = cast<JsonString*>(value);
 168             string str = ToUtf8(s->Value());
 169             field = ParseUuid(str);
 170         }
 171         else
 172         {
 173             throw JsonImportException("JSON string expected");
 174         }
 175     }
 176         
 177     public void FromJson<T>(JsonValue* valueList<T>& field)
 178         where T is JsonValueType
 179     {
 180         if (value is JsonArray*)
 181         {
 182             JsonArray* array = cast<JsonArray*>(value);
 183             long n = array->Count();
 184             for (long i = 0; i < n; ++i;)
 185             {
 186                 JsonValue* itemValue = (*array)[i];
 187                 T item;
 188                 FromJson(itemValueitem);
 189                 field.Add(item);
 190             }
 191         }
 192         else
 193         {
 194             throw JsonImportException("JSON array expected");
 195         }
 196     }
 197 
 198     public void FromJson<T>(JsonValue* valueList<T>& field)
 199         where T is JsonConstructible
 200     {
 201         if (value is JsonArray*)
 202         {
 203             JsonArray* array = cast<JsonArray*>(value);
 204             long n = array->Count();
 205             for (long i = 0; i < n; ++i;)
 206             {
 207                 JsonValue* itemValue = (*array)[i];
 208                 T item(itemValue);
 209                 field.Add(item);
 210             }
 211         }
 212         else
 213         {
 214             throw JsonImportException("JSON array expected");
 215         }
 216     }
 217 
 218     public void FromJson<T>(JsonValue* valueList<UniquePtr<T>>& field)
 219         where T is JsonConstructible
 220     {
 221         if (value is JsonArray*)
 222         {
 223             JsonArray* array = cast<JsonArray*>(value);
 224             long n = array->Count();
 225             for (long i = 0; i < n; ++i;)
 226             {
 227                 JsonValue* itemValue = (*array)[i];
 228                 UniquePtr<T> item;
 229                 FromJson(itemValueitem);
 230                 field.Add(Rvalue(item));
 231             }
 232         }
 233         else
 234         {
 235             throw JsonImportException("JSON array expected");
 236         }
 237     }
 238 
 239     public void FromJson<T>(JsonValue* valueList<SharedPtr<T>>& field)
 240         where T is JsonConstructible
 241     {
 242         if (value is JsonArray*)
 243         {
 244             JsonArray* array = cast<JsonArray*>(value);
 245             long n = array->Count();
 246             for (long i = 0; i < n; ++i;)
 247             {
 248                 JsonValue* itemValue = (*array)[i];
 249                 SharedPtr<T> item;
 250                 FromJson(itemValueitem);
 251                 field.Add(item);
 252             }
 253         }
 254         else
 255         {
 256             throw JsonImportException("JSON array expected");
 257         }
 258     }
 259 
 260     public void FromJson<KeyValueKeyCompare>(JsonValue* valueMap<KeyValueKeyCompare>& field)
 261         where Key is ustring and Value is JsonValueType
 262     {
 263         if (value is JsonObject*)
 264         {
 265             JsonObject* object = cast<JsonObject*>(value);
 266             for (const Pair<ustringJsonValue*>& p : object->Fields())
 267             {
 268                 const ustring& fieldName = p.first;
 269                 JsonValue* fieldValue = p.second;
 270                 Value value;
 271                 FromJson(fieldValuevalue);
 272                 field[fieldName] = value;
 273             }
 274         }
 275         else
 276         {
 277             throw JsonImportException("JSON object expected");
 278         }
 279     }
 280 
 281     public void FromJson<KeyValueKeyCompare>(JsonValue* valueMap<KeyValueKeyCompare>& field)
 282         where Key is wstring and Value is JsonValueType
 283     {
 284         if (value is JsonObject*)
 285         {
 286             JsonObject* object = cast<JsonObject*>(value);
 287             for (const Pair<ustringJsonValue*>& p : object->Fields())
 288             {
 289                 const ustring& fieldName = p.first;
 290                 JsonValue* fieldValue = p.second;
 291                 Value value;
 292                 FromJson(fieldValuevalue);
 293                 field[ToUtf16(fieldName)] = value;
 294             }
 295         }
 296         else
 297         {
 298             throw JsonImportException("JSON object expected");
 299         }
 300     }
 301 
 302     public void FromJson<KeyValueKeyCompare>(JsonValue* valueMap<KeyValueKeyCompare>& field)
 303         where Key is string and Value is JsonValueType
 304     {
 305         if (value is JsonObject*)
 306         {
 307             JsonObject* object = cast<JsonObject*>(value);
 308             for (const Pair<ustringJsonValue*>& p : object->Fields())
 309             {
 310                 const ustring& fieldName = p.first;
 311                 JsonValue* fieldValue = p.second;
 312                 Value value;
 313                 FromJson(fieldValuevalue);
 314                 field[ToUtf8(fieldName)] = value;
 315             }
 316         }
 317         else
 318         {
 319             throw JsonImportException("JSON object expected");
 320         }
 321     }
 322 
 323     public void FromJson<KeyValueKeyCompare>(JsonValue* valueMap<KeyValueKeyCompare>& field)
 324         where Key is ustring and Value is JsonConstructible
 325     {
 326         if (value is JsonObject*)
 327         {
 328             JsonObject* object = cast<JsonObject*>(value);
 329             for (const Pair<ustringJsonValue*>& p : object->Fields())
 330             {
 331                 const ustring& fieldName = p.first;
 332                 JsonValue* fieldValue = p.second;
 333                 Value value(fieldValue);
 334                 field[fieldName] = value;
 335             }
 336         }
 337         else
 338         {
 339             throw JsonImportException("JSON object expected");
 340         }
 341     }
 342 
 343     public void FromJson<KeyValueKeyCompare>(JsonValue* valueMap<KeyValueKeyCompare>& field)
 344         where Key is wstring and Value is JsonConstructible
 345     {
 346         if (value is JsonObject*)
 347         {
 348             JsonObject* object = cast<JsonObject*>(value);
 349             for (const Pair<ustringJsonValue*>& p : object->Fields())
 350             {
 351                 const ustring& fieldName = p.first;
 352                 JsonValue* fieldValue = p.second;
 353                 Value value(fieldValue);
 354                 field[ToUtf16(fieldName)] = value;
 355             }
 356         }
 357         else
 358         {
 359             throw JsonImportException("JSON object expected");
 360         }
 361     }
 362 
 363     public void FromJson<KeyValueKeyCompare>(JsonValue* valueMap<KeyValueKeyCompare>& field)
 364         where Key is string and Value is JsonConstructible
 365     {
 366         if (value is JsonObject*)
 367         {
 368             JsonObject* object = cast<JsonObject*>(value);
 369             for (const Pair<ustringJsonValue*>& p : object->Fields())
 370             {
 371                 const ustring& fieldName = p.first;
 372                 JsonValue* fieldValue = p.second;
 373                 Value value(fieldValue);
 374                 field[ToUtf8(fieldName)] = value;
 375             }
 376         }
 377         else
 378         {
 379             throw JsonImportException("JSON object expected");
 380         }
 381     }
 382 
 383     public void FromJson<KTHC>(JsonValue* valueHashMap<KTHC>& field)
 384         where K is ustring and T is JsonValueType
 385     {
 386         if (value is JsonObject*)
 387         {
 388             JsonObject* object = cast<JsonObject*>(value);
 389             for (const Pair<ustringJsonValue*>& p : object->Fields())
 390             {
 391                 const ustring& fieldName = p.first;
 392                 JsonValue* fieldValue = p.second;
 393                 T value;
 394                 FromJson(fieldValuevalue);
 395                 field[fieldName] = value;
 396             }
 397         }
 398         else
 399         {
 400             throw JsonImportException("JSON object expected");
 401         }
 402     }
 403 
 404     public void FromJson<KTHC>(JsonValue* valueHashMap<KTHC>& field)
 405         where K is wstring and T is JsonValueType
 406     {
 407         if (value is JsonObject*)
 408         {
 409             JsonObject* object = cast<JsonObject*>(value);
 410             for (const Pair<ustringJsonValue*>& p : object->Fields())
 411             {
 412                 const ustring& fieldName = p.first;
 413                 JsonValue* fieldValue = p.second;
 414                 T value;
 415                 FromJson(fieldValuevalue);
 416                 field[ToUtf16(fieldName)] = value;
 417             }
 418         }
 419         else
 420         {
 421             throw JsonImportException("JSON object expected");
 422         }
 423     }
 424 
 425     public void FromJson<KTHC>(JsonValue* valueHashMap<KTHC>& field)
 426         where K is string and T is JsonValueType
 427     {
 428         if (value is JsonObject*)
 429         {
 430             JsonObject* object = cast<JsonObject*>(value);
 431             for (const Pair<ustringJsonValue*>& p : object->Fields())
 432             {
 433                 const ustring& fieldName = p.first;
 434                 JsonValue* fieldValue = p.second;
 435                 T value;
 436                 FromJson(fieldValuevalue);
 437                 field[ToUtf8(fieldName)] = value;
 438             }
 439         }
 440         else
 441         {
 442             throw JsonImportException("JSON object expected");
 443         }
 444     }
 445     
 446     public void FromJson<T>(JsonValue* valueT& field)
 447         where T is JsonConstructible
 448     {
 449         field = T(value);
 450     }
 451     
 452     public void FromJson<T>(JsonValue* valueUniquePtr<T>& field)
 453         where T is JsonConstructible
 454     {
 455         if (value is JsonNull*)
 456         {
 457             field.Reset();
 458         }
 459         else if (value is JsonObject*)
 460         {
 461             JsonObject* object = cast<JsonObject*>(value);
 462             JsonValue* classValue = object->GetField("class");
 463             if (classValue != null)
 464             {
 465                 if (classValue is JsonString*)
 466                 {
 467                     JsonString* jsonClassString = cast<JsonString*>(classValue);
 468                     ustring jsonClassName = jsonClassString->Value();
 469                     JsonValue* objectValue = object->GetField("object");
 470                     if (objectValue != null)
 471                     {
 472                         void* jsonClassValue = JsonClassFactory.Instance().CreateJsonClass(jsonClassNameobjectValue);
 473                         field.Reset(cast<T*>(jsonClassValue));
 474                     }
 475                     else
 476                     {
 477                         throw JsonImportException("JSON 'object' field not found");
 478                     }
 479                 }
 480                 else
 481                 {
 482                     throw JsonImportException("JSON string expected");
 483                 }
 484             }
 485             else
 486             {
 487                 throw JsonImportException("JSON 'class' field not found");
 488             }
 489         }
 490         else
 491         {
 492             throw JsonImportException("null or JSON object expected");
 493         }
 494     }
 495     
 496     public void FromJson<T>(JsonValue* valueSharedPtr<T>& field)
 497         where T is JsonConstructible
 498     {
 499         if (value is JsonNull*)
 500         {
 501             field.Reset();
 502         }
 503         else if (value is JsonObject*)
 504         {
 505             JsonObject* object = cast<JsonObject*>(value);
 506             JsonValue* classValue = object->GetField("class");
 507             if (classValue != null)
 508             {
 509                 if (classValue is JsonString*)
 510                 {
 511                     JsonString* jsonClassString = cast<JsonString*>(classValue);
 512                     ustring jsonClassName = jsonClassString->Value();
 513                     JsonValue* objectValue = object->GetField("object");
 514                     if (objectValue != null)
 515                     {
 516                         void* jsonClassValue = JsonClassFactory.Instance().CreateJsonClass(jsonClassNameobjectValue);
 517                         field.Reset(cast<T*>(jsonClassValue));
 518                     }
 519                     else
 520                     {
 521                         throw JsonImportException("JSON 'object' field not found");
 522                     }
 523                 }
 524                 else
 525                 {
 526                     throw JsonImportException("JSON string expected");
 527                 }
 528             }
 529             else
 530             {
 531                 throw JsonImportException("JSON 'class' field not found");
 532             }
 533         }
 534         else
 535         {
 536             throw JsonImportException("null or JSON object expected");
 537         }
 538     }
 539     public void FromJson(JsonValue* containerconst string& fieldNameint& field)
 540     {
 541         FromJson(containerToUtf32(fieldName)field);
 542     }
 543     
 544     public void FromJson(JsonValue* containerconst wstring& fieldNameint& field)
 545     {
 546         FromJson(containerToUtf32(fieldName)field);
 547     }
 548     
 549     public void FromJson(JsonValue* containerconst ustring& fieldNameint& field)
 550     {
 551         if (container is JsonObject*)
 552         {
 553             JsonObject* object = cast<JsonObject*>(container);
 554             JsonValue* value = object->GetField(fieldName);
 555             if (value != null)
 556             {
 557                 FromJson(valuefield);
 558             }
 559             else
 560             {
 561                 throw JsonImportException("field '" + ToUtf8(fieldName) + "' not found");
 562             }
 563         }
 564         else
 565         {
 566             throw JsonImportException("JSON object expected");
 567         }
 568     }
 569 
 570     public void FromJson(JsonValue* containerconst string& fieldNamedouble& field)
 571     {
 572         FromJson(containerToUtf32(fieldName)field);
 573     }
 574     
 575     public void FromJson(JsonValue* containerconst wstring& fieldNamedouble& field)
 576     {
 577         FromJson(containerToUtf32(fieldName)field);
 578     }
 579     
 580     public void FromJson(JsonValue* containerconst ustring& fieldNamedouble& field)
 581     {
 582         if (container is JsonObject*)
 583         {
 584             JsonObject* object = cast<JsonObject*>(container);
 585             JsonValue* value = object->GetField(fieldName);
 586             if (value != null)
 587             {
 588                 FromJson(valuefield);
 589             }
 590             else
 591             {
 592                 throw JsonImportException("field '" + ToUtf8(fieldName) + "' not found");
 593             }
 594         }
 595         else
 596         {
 597             throw JsonImportException("JSON object expected");
 598         }
 599     }
 600                 
 601     public void FromJson(JsonValue* containerconst string& fieldNamebool& field)
 602     {
 603         FromJson(containerToUtf32(fieldName)field);
 604     }
 605     
 606     public void FromJson(JsonValue* containerconst wstring& fieldNamebool& field)
 607     {
 608         FromJson(containerToUtf32(fieldName)field);
 609     }
 610     
 611     public void FromJson(JsonValue* containerconst ustring& fieldNamebool& field)
 612     {
 613         if (container is JsonObject*)
 614         {
 615             JsonObject* object = cast<JsonObject*>(container);
 616             JsonValue* value = object->GetField(fieldName);
 617             if (value != null)
 618             {
 619                 FromJson(valuefield);
 620             }
 621             else
 622             {
 623                 throw JsonImportException("field '" + ToUtf8(fieldName) + "' not found");
 624             }
 625         }
 626         else
 627         {
 628             throw JsonImportException("JSON object expected");
 629         }
 630     }
 631     
 632     public void FromJson<T>(JsonValue* containerconst string& fieldNameT& field)
 633         where System.Meta.IsEnumeratedType<T>()
 634     {
 635         FromJson(containerToUtf32(fieldName)field);
 636     }
 637 
 638     public void FromJson<T>(JsonValue* containerconst wstring& fieldNameT& field)
 639         where System.Meta.IsEnumeratedType<T>()
 640     {
 641         FromJson(containerToUtf32(fieldName)field);
 642     }
 643 
 644     public void FromJson<T>(JsonValue* containerconst ustring& fieldNameT& field)
 645         where System.Meta.IsEnumeratedType<T>()
 646     {
 647         if (container is JsonObject*)
 648         {
 649             JsonObject* object = cast<JsonObject*>(container);
 650             JsonValue* value = object->GetField(fieldName);
 651             if (value != null)
 652             {
 653                 FromJson(valuefield);
 654             }
 655             else
 656             {
 657                 throw JsonImportException("field '" + ToUtf8(fieldName) + "' not found");
 658             }
 659         }
 660         else
 661         {
 662             throw JsonImportException("JSON object expected");
 663         }
 664     }
 665           
 666     public void FromJson(JsonValue* containerconst string& fieldNamestring& field)
 667     {
 668         FromJson(containerToUtf32(fieldName)field);
 669     }
 670     
 671     public void FromJson(JsonValue* containerconst wstring& fieldNamestring& field)
 672     {
 673         FromJson(containerToUtf32(fieldName)field);
 674     }
 675     
 676     public void FromJson(JsonValue* containerconst ustring& fieldNamestring& field)
 677     {
 678         if (container is JsonObject*)
 679         {
 680             JsonObject* object = cast<JsonObject*>(container);
 681             JsonValue* value = object->GetField(fieldName);
 682             if (value != null)
 683             {
 684                 FromJson(valuefield);
 685             }
 686             else
 687             {
 688                 throw JsonImportException("field '" + ToUtf8(fieldName) + "' not found");
 689             }
 690         }
 691         else
 692         {
 693             throw JsonImportException("JSON object expected");
 694         }
 695     }
 696                 
 697     public void FromJson(JsonValue* containerconst string& fieldNamewstring& field)
 698     {
 699         FromJson(containerToUtf32(fieldName)field);
 700     }
 701     
 702     public void FromJson(JsonValue* containerconst wstring& fieldNamewstring& field)
 703     {
 704         FromJson(containerToUtf32(fieldName)field);
 705     }
 706     
 707     public void FromJson(JsonValue* containerconst ustring& fieldNamewstring& field)
 708     {
 709         if (container is JsonObject*)
 710         {
 711             JsonObject* object = cast<JsonObject*>(container);
 712             JsonValue* value = object->GetField(fieldName);
 713             if (value != null)
 714             {
 715                 FromJson(valuefield);
 716             }
 717             else
 718             {
 719                 throw JsonImportException("field '" + ToUtf8(fieldName) + "' not found");
 720             }
 721         }
 722         else
 723         {
 724             throw JsonImportException("JSON object expected");
 725         }
 726     }
 727                 
 728     public void FromJson(JsonValue* containerconst string& fieldNameustring& field)
 729     {
 730         FromJson(containerToUtf32(fieldName)field);
 731     }
 732     
 733     public void FromJson(JsonValue* containerconst wstring& fieldNameustring& field)
 734     {
 735         FromJson(containerToUtf32(fieldName)field);
 736     }
 737     
 738     public void FromJson(JsonValue* containerconst ustring& fieldNameustring& field)
 739     {
 740         if (container is JsonObject*)
 741         {
 742             JsonObject* object = cast<JsonObject*>(container);
 743             JsonValue* value = object->GetField(fieldName);
 744             if (value != null)
 745             {
 746                 FromJson(valuefield);
 747             }
 748             else
 749             {
 750                 throw JsonImportException("field '" + ToUtf8(fieldName) + "' not found");
 751             }
 752         }
 753         else
 754         {
 755             throw JsonImportException("JSON object expected");
 756         }
 757     }
 758 
 759     public void FromJson(JsonValue* containerconst string& fieldNameDate& field)
 760     {
 761         FromJson(containerToUtf32(fieldName)field);
 762     }
 763     
 764     public void FromJson(JsonValue* containerconst wstring& fieldNameDate& field)
 765     {
 766         FromJson(containerToUtf32(fieldName)field);
 767     }
 768     
 769     public void FromJson(JsonValue* containerconst ustring& fieldNameDate& field)
 770     {
 771         if (container is JsonObject*)
 772         {
 773             JsonObject* object = cast<JsonObject*>(container);
 774             JsonValue* value = object->GetField(fieldName);
 775             if (value != null)
 776             {
 777                 FromJson(valuefield);
 778             }
 779             else
 780             {
 781                 throw JsonImportException("field '" + ToUtf8(fieldName) + "' not found");
 782             }
 783         }
 784         else
 785         {
 786             throw JsonImportException("JSON object expected");
 787         }
 788     }
 789 
 790     public void FromJson(JsonValue* containerconst string& fieldNameDateTime& field)
 791     {
 792         FromJson(containerToUtf32(fieldName)field);
 793     }
 794     
 795     public void FromJson(JsonValue* containerconst wstring& fieldNameDateTime& field)
 796     {
 797         FromJson(containerToUtf32(fieldName)field);
 798     }
 799     
 800     public void FromJson(JsonValue* containerconst ustring& fieldNameDateTime& field)
 801     {
 802         if (container is JsonObject*)
 803         {
 804             JsonObject* object = cast<JsonObject*>(container);
 805             JsonValue* value = object->GetField(fieldName);
 806             if (value != null)
 807             {
 808                 FromJson(valuefield);
 809             }
 810             else
 811             {
 812                 throw JsonImportException("field '" + ToUtf8(fieldName) + "' not found");
 813             }
 814         }
 815         else
 816         {
 817             throw JsonImportException("JSON object expected");
 818         }
 819     }
 820     
 821     public void FromJson(JsonValue* containerconst string& fieldNameTimestamp& field)
 822     {
 823         FromJson(containerToUtf32(fieldName)field);
 824     }
 825     
 826     public void FromJson(JsonValue* containerconst wstring& fieldNameTimestamp& field)
 827     {
 828         FromJson(containerToUtf32(fieldName)field);
 829     }
 830     
 831     public void FromJson(JsonValue* containerconst ustring& fieldNameTimestamp& field)
 832     {
 833         if (container is JsonObject*)
 834         {
 835             JsonObject* object = cast<JsonObject*>(container);
 836             JsonValue* value = object->GetField(fieldName);
 837             if (value != null)
 838             {
 839                 FromJson(valuefield);
 840             }
 841             else
 842             {
 843                 throw JsonImportException("field '" + ToUtf8(fieldName) + "' not found");
 844             }
 845         }
 846         else
 847         {
 848             throw JsonImportException("JSON object expected");
 849         }
 850     }
 851     
 852     public void FromJson(JsonValue* containerconst string& fieldNameUuid& field)
 853     {
 854         FromJson(containerToUtf32(fieldName)field);
 855     }
 856     
 857     public void FromJson(JsonValue* containerconst wstring& fieldNameUuid& field)
 858     {
 859         FromJson(containerToUtf32(fieldName)field);
 860     }
 861     
 862     public void FromJson(JsonValue* containerconst ustring& fieldNameUuid& field)
 863     {
 864         if (container is JsonObject*)
 865         {
 866             JsonObject* object = cast<JsonObject*>(container);
 867             JsonValue* value = object->GetField(fieldName);
 868             if (value != null)
 869             {
 870                 FromJson(valuefield);
 871             }
 872             else
 873             {
 874                 throw JsonImportException("field '" + ToUtf8(fieldName) + "' not found");
 875             }
 876         }
 877         else
 878         {
 879             throw JsonImportException("JSON object expected");
 880         }
 881     }
 882                                                                 
 883     public void FromJson<T>(JsonValue* containerconst string& fieldNameList<T>& field)
 884         where T is JsonValueType or T is JsonConstructible
 885     {
 886         FromJson(containerToUtf32(fieldName)field);
 887     }
 888     
 889     public void FromJson<T>(JsonValue* containerconst wstring& fieldNameList<T>& field)
 890         where T is JsonValueType or T is JsonConstructible
 891     {
 892         FromJson(containerToUtf32(fieldName)field);
 893     }
 894     
 895     public void FromJson<T>(JsonValue* containerconst ustring& fieldNameList<T>& field)
 896         where T is JsonValueType or T is JsonConstructible
 897     {
 898         if (container is JsonObject*)
 899         {
 900             JsonObject* object = cast<JsonObject*>(container);
 901             JsonValue* value = object->GetField(fieldName);
 902             if (value != null)
 903             {
 904                 FromJson(valuefield);
 905             }
 906             else
 907             {
 908                 throw JsonImportException("field '" + ToUtf8(fieldName) + "' not found");
 909             }
 910         }
 911         else
 912         {
 913             throw JsonImportException("JSON object expected");
 914         }
 915     }
 916 
 917     public void FromJson<T>(JsonValue* containerconst string& fieldNameList<UniquePtr<T>>& field)
 918         where T is JsonConstructible
 919     {
 920         FromJson(containerToUtf32(fieldName)field);
 921     }
 922     
 923     public void FromJson<T>(JsonValue* containerconst wstring& fieldNameList<UniquePtr<T>>& field)
 924         where T is JsonConstructible
 925     {
 926         FromJson(containerToUtf32(fieldName)field);
 927     }
 928     
 929     public void FromJson<T>(JsonValue* containerconst ustring& fieldNameList<UniquePtr<T>>& field)
 930         where T is JsonConstructible
 931     {
 932         if (container is JsonObject*)
 933         {
 934             JsonObject* object = cast<JsonObject*>(container);
 935             JsonValue* value = object->GetField(fieldName);
 936             if (value != null)
 937             {
 938                 FromJson(valuefield);
 939             }
 940             else
 941             {
 942                 throw JsonImportException("field '" + ToUtf8(fieldName) + "' not found");
 943             }
 944         }
 945         else
 946         {
 947             throw JsonImportException("JSON object expected");
 948         }
 949     }
 950 
 951     public void FromJson<T>(JsonValue* containerconst string& fieldNameList<SharedPtr<T>>& field)
 952         where T is JsonConstructible
 953     {
 954         FromJson(containerToUtf32(fieldName)field);
 955     }
 956     
 957     public void FromJson<T>(JsonValue* containerconst wstring& fieldNameList<SharedPtr<T>>& field)
 958         where T is JsonConstructible
 959     {
 960         FromJson(containerToUtf32(fieldName)field);
 961     }
 962     
 963     public void FromJson<T>(JsonValue* containerconst ustring& fieldNameList<SharedPtr<T>>& field)
 964         where T is JsonConstructible
 965     {
 966         if (container is JsonObject*)
 967         {
 968             JsonObject* object = cast<JsonObject*>(container);
 969             JsonValue* value = object->GetField(fieldName);
 970             if (value != null)
 971             {
 972                 FromJson(valuefield);
 973             }
 974             else
 975             {
 976                 throw JsonImportException("field '" + ToUtf8(fieldName) + "' not found");
 977             }
 978         }
 979         else
 980         {
 981             throw JsonImportException("JSON object expected");
 982         }
 983     }
 984 
 985     public void FromJson<KeyValueKeyCompare>(JsonValue* containerconst string& fieldNameMap<KeyValueKeyCompare>& field)
 986         where Value is JsonValueType or Value is JsonConstructible
 987     {
 988         FromJson(containerToUtf32(fieldName)field);
 989     }
 990     
 991     public void FromJson<KeyValueKeyCompare>(JsonValue* containerconst wstring& fieldNameMap<KeyValueKeyCompare>& field)
 992         where Value is JsonValueType or Value is JsonConstructible
 993     {
 994         FromJson(containerToUtf32(fieldName)field);
 995     }
 996     
 997     public void FromJson<KeyValueKeyCompare>(JsonValue* containerconst ustring& fieldNameMap<KeyValueKeyCompare>& field)
 998         where Value is JsonValueType or Value is JsonConstructible
 999     {
1000         if (container is JsonObject*)
1001         {
1002             JsonObject* object = cast<JsonObject*>(container);
1003             JsonValue* value = object->GetField(fieldName);
1004             if (value != null)
1005             {
1006                 FromJson(valuefield);
1007             }
1008             else
1009             {
1010                 throw JsonImportException("field '" + ToUtf8(fieldName) + "' not found");
1011             }
1012         }
1013         else
1014         {
1015             throw JsonImportException("JSON object expected");
1016         }
1017     }
1018 
1019     public void FromJson<KTHC>(JsonValue* containerconst string& fieldNameHashMap<KTHC>& field)
1020         where T is JsonValueType or T is JsonConstructible
1021     {
1022         FromJson(containerToUtf32(fieldName)field);
1023     }
1024     
1025     public void FromJson<KTHC>(JsonValue* containerconst wstring& fieldNameHashMap<KTHC>& field)
1026         where T is JsonValueType or T is JsonConstructible
1027     {
1028         FromJson(containerToUtf32(fieldName)field);
1029     }
1030     
1031     public void FromJson<KTHC>(JsonValue* containerconst ustring& fieldNameHashMap<KTHC>& field)
1032         where T is JsonValueType or T is JsonConstructible
1033     {
1034         if (container is JsonObject*)
1035         {
1036             JsonObject* object = cast<JsonObject*>(container);
1037             JsonValue* value = object->GetField(fieldName);
1038             if (value != null)
1039             {
1040                 FromJson(valuefield);
1041             }
1042             else
1043             {
1044                 throw JsonImportException("field '" + ToUtf8(fieldName) + "' not found");
1045             }
1046         }
1047         else
1048         {
1049             throw JsonImportException("JSON object expected");
1050         }
1051     }
1052 
1053     public void FromJson<T>(JsonValue* containerconst string& fieldNameT& field)
1054         where T is JsonConstructible
1055     {
1056         FromJson(containerToUtf32(fieldName)field);
1057     }
1058     
1059     public void FromJson<T>(JsonValue* containerconst wstring& fieldNameT& field)
1060         where T is JsonConstructible
1061     {
1062         FromJson(containerToUtf32(fieldName)field);
1063     }
1064         
1065     public void FromJson<T>(JsonValue* containerconst ustring& fieldNameT& field)
1066         where T is JsonConstructible
1067     {
1068         if (container is JsonObject*)
1069         {
1070             JsonObject* object = cast<JsonObject*>(container);
1071             JsonValue* value = object->GetField(fieldName);
1072             if (value != null)
1073             {
1074                 FromJson(valuefield);
1075             }
1076             else
1077             {
1078                 throw JsonImportException("field '" + ToUtf8(fieldName) + "' not found");
1079             }
1080         }
1081         else
1082         {
1083             throw JsonImportException("JSON object expected");
1084         }
1085     }
1086     
1087     public void FromJson<T>(JsonValue* containerconst ustring& fieldNameUniquePtr<T>& field)
1088         where T is JsonConstructible
1089     {
1090         if (container is JsonObject*)
1091         {
1092             JsonObject* object = cast<JsonObject*>(container);
1093             JsonValue* value = object->GetField(fieldName);
1094             if (value != null)
1095             {
1096                 FromJson(valuefield);
1097             }
1098             else
1099             {
1100                 throw JsonImportException("field '" + ToUtf8(fieldName) + "' not found");
1101             }
1102         }
1103         else
1104         {
1105             throw JsonImportException("JSON object expected");
1106         }
1107     }
1108 
1109     public void FromJson<T>(JsonValue* containerconst ustring& fieldNameSharedPtr<T>& field)
1110         where T is JsonConstructible
1111     {
1112         if (container is JsonObject*)
1113         {
1114             JsonObject* object = cast<JsonObject*>(container);
1115             JsonValue* value = object->GetField(fieldName);
1116             if (value != null)
1117             {
1118                 FromJson(valuefield);
1119             }
1120             else
1121             {
1122                 throw JsonImportException("field '" + ToUtf8(fieldName) + "' not found");
1123             }
1124         }
1125         else
1126         {
1127             throw JsonImportException("JSON object expected");
1128         }
1129     }
1130 }