rj_schema 0.2.5 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rj_schema/rapidjson/CMakeLists.txt +23 -1
  3. data/ext/rj_schema/rapidjson/appveyor.yml +49 -1
  4. data/ext/rj_schema/rapidjson/bin/types/alotofkeys.json +502 -0
  5. data/ext/rj_schema/rapidjson/bin/unittestschema/address.json +139 -0
  6. data/ext/rj_schema/rapidjson/bin/unittestschema/allOf_address.json +7 -0
  7. data/ext/rj_schema/rapidjson/bin/unittestschema/anyOf_address.json +7 -0
  8. data/ext/rj_schema/rapidjson/bin/unittestschema/idandref.json +69 -0
  9. data/ext/rj_schema/rapidjson/bin/unittestschema/oneOf_address.json +7 -0
  10. data/ext/rj_schema/rapidjson/doc/stream.md +7 -7
  11. data/ext/rj_schema/rapidjson/doc/stream.zh-cn.md +1 -1
  12. data/ext/rj_schema/rapidjson/doc/tutorial.md +15 -15
  13. data/ext/rj_schema/rapidjson/example/schemavalidator/schemavalidator.cpp +120 -0
  14. data/ext/rj_schema/rapidjson/example/traverseaspointer.cpp +39 -0
  15. data/ext/rj_schema/rapidjson/include/rapidjson/allocators.h +464 -56
  16. data/ext/rj_schema/rapidjson/include/rapidjson/cursorstreamwrapper.h +1 -1
  17. data/ext/rj_schema/rapidjson/include/rapidjson/document.h +367 -72
  18. data/ext/rj_schema/rapidjson/include/rapidjson/encodedstream.h +1 -1
  19. data/ext/rj_schema/rapidjson/include/rapidjson/encodings.h +1 -1
  20. data/ext/rj_schema/rapidjson/include/rapidjson/error/en.h +49 -1
  21. data/ext/rj_schema/rapidjson/include/rapidjson/error/error.h +56 -1
  22. data/ext/rj_schema/rapidjson/include/rapidjson/filereadstream.h +1 -1
  23. data/ext/rj_schema/rapidjson/include/rapidjson/filewritestream.h +1 -1
  24. data/ext/rj_schema/rapidjson/include/rapidjson/fwd.h +1 -1
  25. data/ext/rj_schema/rapidjson/include/rapidjson/internal/biginteger.h +1 -1
  26. data/ext/rj_schema/rapidjson/include/rapidjson/internal/clzll.h +4 -4
  27. data/ext/rj_schema/rapidjson/include/rapidjson/internal/diyfp.h +1 -1
  28. data/ext/rj_schema/rapidjson/include/rapidjson/internal/dtoa.h +1 -1
  29. data/ext/rj_schema/rapidjson/include/rapidjson/internal/ieee754.h +1 -1
  30. data/ext/rj_schema/rapidjson/include/rapidjson/internal/itoa.h +1 -1
  31. data/ext/rj_schema/rapidjson/include/rapidjson/internal/meta.h +1 -1
  32. data/ext/rj_schema/rapidjson/include/rapidjson/internal/pow10.h +1 -1
  33. data/ext/rj_schema/rapidjson/include/rapidjson/internal/regex.h +1 -1
  34. data/ext/rj_schema/rapidjson/include/rapidjson/internal/stack.h +1 -1
  35. data/ext/rj_schema/rapidjson/include/rapidjson/internal/strfunc.h +15 -1
  36. data/ext/rj_schema/rapidjson/include/rapidjson/internal/strtod.h +1 -1
  37. data/ext/rj_schema/rapidjson/include/rapidjson/internal/swap.h +1 -1
  38. data/ext/rj_schema/rapidjson/include/rapidjson/istreamwrapper.h +1 -1
  39. data/ext/rj_schema/rapidjson/include/rapidjson/memorybuffer.h +1 -1
  40. data/ext/rj_schema/rapidjson/include/rapidjson/memorystream.h +1 -1
  41. data/ext/rj_schema/rapidjson/include/rapidjson/ostreamwrapper.h +1 -1
  42. data/ext/rj_schema/rapidjson/include/rapidjson/pointer.h +69 -2
  43. data/ext/rj_schema/rapidjson/include/rapidjson/prettywriter.h +1 -1
  44. data/ext/rj_schema/rapidjson/include/rapidjson/rapidjson.h +77 -12
  45. data/ext/rj_schema/rapidjson/include/rapidjson/reader.h +17 -9
  46. data/ext/rj_schema/rapidjson/include/rapidjson/schema.h +558 -259
  47. data/ext/rj_schema/rapidjson/include/rapidjson/stream.h +1 -1
  48. data/ext/rj_schema/rapidjson/include/rapidjson/stringbuffer.h +1 -1
  49. data/ext/rj_schema/rapidjson/include/rapidjson/uri.h +466 -0
  50. data/ext/rj_schema/rapidjson/include/rapidjson/writer.h +3 -3
  51. data/ext/rj_schema/rapidjson/readme.md +3 -3
  52. data/ext/rj_schema/rapidjson/readme.zh-cn.md +2 -2
  53. data/ext/rj_schema/rapidjson/test/perftest/misctest.cpp +1 -1
  54. data/ext/rj_schema/rapidjson/test/perftest/perftest.cpp +1 -1
  55. data/ext/rj_schema/rapidjson/test/perftest/perftest.h +6 -5
  56. data/ext/rj_schema/rapidjson/test/perftest/platformtest.cpp +1 -1
  57. data/ext/rj_schema/rapidjson/test/perftest/rapidjsontest.cpp +21 -3
  58. data/ext/rj_schema/rapidjson/test/unittest/CMakeLists.txt +3 -0
  59. data/ext/rj_schema/rapidjson/test/unittest/allocatorstest.cpp +194 -2
  60. data/ext/rj_schema/rapidjson/test/unittest/bigintegertest.cpp +1 -1
  61. data/ext/rj_schema/rapidjson/test/unittest/clzlltest.cpp +34 -0
  62. data/ext/rj_schema/rapidjson/test/unittest/cursorstreamwrappertest.cpp +1 -1
  63. data/ext/rj_schema/rapidjson/test/unittest/documenttest.cpp +3 -1
  64. data/ext/rj_schema/rapidjson/test/unittest/dtoatest.cpp +1 -1
  65. data/ext/rj_schema/rapidjson/test/unittest/encodedstreamtest.cpp +1 -1
  66. data/ext/rj_schema/rapidjson/test/unittest/encodingstest.cpp +1 -1
  67. data/ext/rj_schema/rapidjson/test/unittest/filestreamtest.cpp +1 -1
  68. data/ext/rj_schema/rapidjson/test/unittest/fwdtest.cpp +1 -1
  69. data/ext/rj_schema/rapidjson/test/unittest/istreamwrappertest.cpp +1 -1
  70. data/ext/rj_schema/rapidjson/test/unittest/itoatest.cpp +1 -1
  71. data/ext/rj_schema/rapidjson/test/unittest/jsoncheckertest.cpp +1 -1
  72. data/ext/rj_schema/rapidjson/test/unittest/namespacetest.cpp +1 -1
  73. data/ext/rj_schema/rapidjson/test/unittest/ostreamwrappertest.cpp +1 -1
  74. data/ext/rj_schema/rapidjson/test/unittest/platformtest.cpp +40 -0
  75. data/ext/rj_schema/rapidjson/test/unittest/pointertest.cpp +95 -3
  76. data/ext/rj_schema/rapidjson/test/unittest/prettywritertest.cpp +1 -1
  77. data/ext/rj_schema/rapidjson/test/unittest/readertest.cpp +4 -1
  78. data/ext/rj_schema/rapidjson/test/unittest/regextest.cpp +1 -1
  79. data/ext/rj_schema/rapidjson/test/unittest/schematest.cpp +961 -81
  80. data/ext/rj_schema/rapidjson/test/unittest/simdtest.cpp +1 -1
  81. data/ext/rj_schema/rapidjson/test/unittest/strfunctest.cpp +1 -1
  82. data/ext/rj_schema/rapidjson/test/unittest/stringbuffertest.cpp +1 -1
  83. data/ext/rj_schema/rapidjson/test/unittest/strtodtest.cpp +1 -1
  84. data/ext/rj_schema/rapidjson/test/unittest/unittest.cpp +1 -1
  85. data/ext/rj_schema/rapidjson/test/unittest/unittest.h +1 -1
  86. data/ext/rj_schema/rapidjson/test/unittest/uritest.cpp +718 -0
  87. data/ext/rj_schema/rapidjson/test/unittest/valuetest.cpp +13 -3
  88. data/ext/rj_schema/rapidjson/test/unittest/writertest.cpp +1 -1
  89. data/ext/rj_schema/rj_schema.cpp +162 -18
  90. data/lib/rj_schema.rb +1 -1
  91. metadata +14 -3
@@ -1,6 +1,6 @@
1
1
  // Tencent is pleased to support the open source community by making RapidJSON available.
2
2
  //
3
- // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
3
+ // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
4
4
  //
5
5
  // Licensed under the MIT License (the "License"); you may not use this file except
6
6
  // in compliance with the License. You may obtain a copy of the License at
@@ -1,6 +1,6 @@
1
1
  // Tencent is pleased to support the open source community by making RapidJSON available.
2
2
  //
3
- // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
3
+ // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
4
4
  //
5
5
  // Licensed under the MIT License (the "License"); you may not use this file except
6
6
  // in compliance with the License. You may obtain a copy of the License at
@@ -42,12 +42,21 @@ RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible lo
42
42
  RAPIDJSON_DIAG_OFF(effc++)
43
43
  #endif // __GNUC__
44
44
 
45
+ #ifdef GetObject
46
+ // see https://github.com/Tencent/rapidjson/issues/1448
47
+ // a former included windows.h might have defined a macro called GetObject, which affects
48
+ // GetObject defined here. This ensures the macro does not get applied
49
+ #pragma push_macro("GetObject")
50
+ #define RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
51
+ #undef GetObject
52
+ #endif
53
+
45
54
  #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
46
55
  #include <iterator> // std::random_access_iterator_tag
47
56
  #endif
48
57
 
49
- #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
50
- #include <utility> // std::move
58
+ #if RAPIDJSON_USE_MEMBERSMAP
59
+ #include <map> // std::multimap
51
60
  #endif
52
61
 
53
62
  RAPIDJSON_NAMESPACE_BEGIN
@@ -289,12 +298,14 @@ class GenericMemberIterator;
289
298
  //! non-const GenericMemberIterator
290
299
  template <typename Encoding, typename Allocator>
291
300
  class GenericMemberIterator<false,Encoding,Allocator> {
301
+ public:
292
302
  //! use plain pointer as iterator type
293
303
  typedef GenericMember<Encoding,Allocator>* Iterator;
294
304
  };
295
305
  //! const GenericMemberIterator
296
306
  template <typename Encoding, typename Allocator>
297
307
  class GenericMemberIterator<true,Encoding,Allocator> {
308
+ public:
298
309
  //! use plain const pointer as iterator type
299
310
  typedef const GenericMember<Encoding,Allocator>* Iterator;
300
311
  };
@@ -730,18 +741,8 @@ public:
730
741
  template <typename SourceAllocator>
731
742
  GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
732
743
  switch (rhs.GetType()) {
733
- case kObjectType: {
734
- SizeType count = rhs.data_.o.size;
735
- Member* lm = reinterpret_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
736
- const typename GenericValue<Encoding,SourceAllocator>::Member* rm = rhs.GetMembersPointer();
737
- for (SizeType i = 0; i < count; i++) {
738
- new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings);
739
- new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings);
740
- }
741
- data_.f.flags = kObjectFlag;
742
- data_.o.size = data_.o.capacity = count;
743
- SetMembersPointer(lm);
744
- }
744
+ case kObjectType:
745
+ DoCopyMembers(rhs, allocator, copyConstStrings);
745
746
  break;
746
747
  case kArrayType: {
747
748
  SizeType count = rhs.data_.a.size;
@@ -877,25 +878,30 @@ public:
877
878
  /*! Need to destruct elements of array, members of object, or copy-string.
878
879
  */
879
880
  ~GenericValue() {
880
- if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
881
+ // With RAPIDJSON_USE_MEMBERSMAP, the maps need to be destroyed to release
882
+ // their Allocator if it's refcounted (e.g. MemoryPoolAllocator).
883
+ if (Allocator::kNeedFree || (RAPIDJSON_USE_MEMBERSMAP+0 &&
884
+ internal::IsRefCounted<Allocator>::Value)) {
881
885
  switch(data_.f.flags) {
882
886
  case kArrayFlag:
883
887
  {
884
888
  GenericValue* e = GetElementsPointer();
885
889
  for (GenericValue* v = e; v != e + data_.a.size; ++v)
886
890
  v->~GenericValue();
887
- Allocator::Free(e);
891
+ if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
892
+ Allocator::Free(e);
893
+ }
888
894
  }
889
895
  break;
890
896
 
891
897
  case kObjectFlag:
892
- for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
893
- m->~Member();
894
- Allocator::Free(GetMembersPointer());
898
+ DoFreeMembers();
895
899
  break;
896
900
 
897
901
  case kCopyStringFlag:
898
- Allocator::Free(const_cast<Ch*>(GetStringPointer()));
902
+ if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
903
+ Allocator::Free(const_cast<Ch*>(GetStringPointer()));
904
+ }
899
905
  break;
900
906
 
901
907
  default:
@@ -914,8 +920,13 @@ public:
914
920
  */
915
921
  GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
916
922
  if (RAPIDJSON_LIKELY(this != &rhs)) {
923
+ // Can't destroy "this" before assigning "rhs", otherwise "rhs"
924
+ // could be used after free if it's an sub-Value of "this",
925
+ // hence the temporary danse.
926
+ GenericValue temp;
927
+ temp.RawAssign(rhs);
917
928
  this->~GenericValue();
918
- RawAssign(rhs);
929
+ RawAssign(temp);
919
930
  }
920
931
  return *this;
921
932
  }
@@ -1081,6 +1092,7 @@ public:
1081
1092
  */
1082
1093
  template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
1083
1094
 
1095
+ #ifndef __cpp_lib_three_way_comparison
1084
1096
  //! Equal-to operator with arbitrary types (symmetric version)
1085
1097
  /*! \return (rhs == lhs)
1086
1098
  */
@@ -1091,6 +1103,7 @@ public:
1091
1103
  */
1092
1104
  template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
1093
1105
  //@}
1106
+ #endif
1094
1107
 
1095
1108
  //!@name Type
1096
1109
  //@{
@@ -1256,10 +1269,7 @@ public:
1256
1269
  */
1257
1270
  GenericValue& MemberReserve(SizeType newCapacity, Allocator &allocator) {
1258
1271
  RAPIDJSON_ASSERT(IsObject());
1259
- if (newCapacity > data_.o.capacity) {
1260
- SetMembersPointer(reinterpret_cast<Member*>(allocator.Realloc(GetMembersPointer(), data_.o.capacity * sizeof(Member), newCapacity * sizeof(Member))));
1261
- data_.o.capacity = newCapacity;
1262
- }
1272
+ DoReserveMembers(newCapacity, allocator);
1263
1273
  return *this;
1264
1274
  }
1265
1275
 
@@ -1333,11 +1343,7 @@ public:
1333
1343
  MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) {
1334
1344
  RAPIDJSON_ASSERT(IsObject());
1335
1345
  RAPIDJSON_ASSERT(name.IsString());
1336
- MemberIterator member = MemberBegin();
1337
- for ( ; member != MemberEnd(); ++member)
1338
- if (name.StringEqual(member->name))
1339
- break;
1340
- return member;
1346
+ return DoFindMember(name);
1341
1347
  }
1342
1348
  template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1343
1349
 
@@ -1366,14 +1372,7 @@ public:
1366
1372
  GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
1367
1373
  RAPIDJSON_ASSERT(IsObject());
1368
1374
  RAPIDJSON_ASSERT(name.IsString());
1369
-
1370
- ObjectData& o = data_.o;
1371
- if (o.size >= o.capacity)
1372
- MemberReserve(o.capacity == 0 ? kDefaultObjectCapacity : (o.capacity + (o.capacity + 1) / 2), allocator);
1373
- Member* members = GetMembersPointer();
1374
- members[o.size].name.RawAssign(name);
1375
- members[o.size].value.RawAssign(value);
1376
- o.size++;
1375
+ DoAddMember(name, value, allocator);
1377
1376
  return *this;
1378
1377
  }
1379
1378
 
@@ -1507,9 +1506,7 @@ public:
1507
1506
  */
1508
1507
  void RemoveAllMembers() {
1509
1508
  RAPIDJSON_ASSERT(IsObject());
1510
- for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
1511
- m->~Member();
1512
- data_.o.size = 0;
1509
+ DoClearMembers();
1513
1510
  }
1514
1511
 
1515
1512
  //! Remove a member in object by its name.
@@ -1553,14 +1550,7 @@ public:
1553
1550
  RAPIDJSON_ASSERT(data_.o.size > 0);
1554
1551
  RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1555
1552
  RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
1556
-
1557
- MemberIterator last(GetMembersPointer() + (data_.o.size - 1));
1558
- if (data_.o.size > 1 && m != last)
1559
- *m = *last; // Move the last one to this place
1560
- else
1561
- m->~Member(); // Only one left, just destroy
1562
- --data_.o.size;
1563
- return m;
1553
+ return DoRemoveMember(m);
1564
1554
  }
1565
1555
 
1566
1556
  //! Remove a member from an object by iterator.
@@ -1592,13 +1582,7 @@ public:
1592
1582
  RAPIDJSON_ASSERT(first >= MemberBegin());
1593
1583
  RAPIDJSON_ASSERT(first <= last);
1594
1584
  RAPIDJSON_ASSERT(last <= MemberEnd());
1595
-
1596
- MemberIterator pos = MemberBegin() + (first - MemberBegin());
1597
- for (MemberIterator itr = pos; itr != last; ++itr)
1598
- itr->~Member();
1599
- std::memmove(static_cast<void*>(&*pos), &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));
1600
- data_.o.size -= static_cast<SizeType>(last - first);
1601
- return pos;
1585
+ return DoEraseMembers(first, last);
1602
1586
  }
1603
1587
 
1604
1588
  //! Erase a member in object by its name.
@@ -1627,7 +1611,9 @@ public:
1627
1611
  }
1628
1612
 
1629
1613
  Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
1614
+ Object GetObj() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
1630
1615
  ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
1616
+ ConstObject GetObj() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
1631
1617
 
1632
1618
  //@}
1633
1619
 
@@ -1849,12 +1835,12 @@ public:
1849
1835
  //!@name String
1850
1836
  //@{
1851
1837
 
1852
- const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); }
1838
+ const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return DataString(data_); }
1853
1839
 
1854
1840
  //! Get the length of string.
1855
1841
  /*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength().
1856
1842
  */
1857
- SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); }
1843
+ SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return DataStringLength(data_); }
1858
1844
 
1859
1845
  //! Set this value as a string without copying source string.
1860
1846
  /*! This version has better performance with supplied length, and also support string containing null character.
@@ -1965,7 +1951,7 @@ public:
1965
1951
  case kArrayType:
1966
1952
  if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
1967
1953
  return false;
1968
- for (const GenericValue* v = Begin(); v != End(); ++v)
1954
+ for (ConstValueIterator v = Begin(); v != End(); ++v)
1969
1955
  if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
1970
1956
  return false;
1971
1957
  return handler.EndArray(data_.a.size);
@@ -2001,17 +1987,18 @@ private:
2001
1987
 
2002
1988
  // Initial flags of different types.
2003
1989
  kNullFlag = kNullType,
2004
- kTrueFlag = kTrueType | kBoolFlag,
2005
- kFalseFlag = kFalseType | kBoolFlag,
2006
- kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag,
2007
- kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag,
2008
- kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag,
2009
- kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag,
2010
- kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag,
2011
- kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag,
2012
- kConstStringFlag = kStringType | kStringFlag,
2013
- kCopyStringFlag = kStringType | kStringFlag | kCopyFlag,
2014
- kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag,
1990
+ // These casts are added to suppress the warning on MSVC about bitwise operations between enums of different types.
1991
+ kTrueFlag = static_cast<int>(kTrueType) | static_cast<int>(kBoolFlag),
1992
+ kFalseFlag = static_cast<int>(kFalseType) | static_cast<int>(kBoolFlag),
1993
+ kNumberIntFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag),
1994
+ kNumberUintFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag),
1995
+ kNumberInt64Flag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kInt64Flag),
1996
+ kNumberUint64Flag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kUint64Flag),
1997
+ kNumberDoubleFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kDoubleFlag),
1998
+ kNumberAnyFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag),
1999
+ kConstStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag),
2000
+ kCopyStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag | kCopyFlag),
2001
+ kShortStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag | kCopyFlag | kInlineStrFlag),
2015
2002
  kObjectFlag = kObjectType,
2016
2003
  kArrayFlag = kArrayType,
2017
2004
 
@@ -2102,6 +2089,13 @@ private:
2102
2089
  Flag f;
2103
2090
  }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION
2104
2091
 
2092
+ static RAPIDJSON_FORCEINLINE const Ch* DataString(const Data& data) {
2093
+ return (data.f.flags & kInlineStrFlag) ? data.ss.str : RAPIDJSON_GETPOINTER(Ch, data.s.str);
2094
+ }
2095
+ static RAPIDJSON_FORCEINLINE SizeType DataStringLength(const Data& data) {
2096
+ return (data.f.flags & kInlineStrFlag) ? data.ss.GetLength() : data.s.length;
2097
+ }
2098
+
2105
2099
  RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
2106
2100
  RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
2107
2101
  RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
@@ -2109,6 +2103,286 @@ private:
2109
2103
  RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
2110
2104
  RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
2111
2105
 
2106
+ #if RAPIDJSON_USE_MEMBERSMAP
2107
+
2108
+ struct MapTraits {
2109
+ struct Less {
2110
+ bool operator()(const Data& s1, const Data& s2) const {
2111
+ SizeType n1 = DataStringLength(s1), n2 = DataStringLength(s2);
2112
+ int cmp = std::memcmp(DataString(s1), DataString(s2), sizeof(Ch) * (n1 < n2 ? n1 : n2));
2113
+ return cmp < 0 || (cmp == 0 && n1 < n2);
2114
+ }
2115
+ };
2116
+ typedef std::pair<const Data, SizeType> Pair;
2117
+ typedef std::multimap<Data, SizeType, Less, StdAllocator<Pair, Allocator> > Map;
2118
+ typedef typename Map::iterator Iterator;
2119
+ };
2120
+ typedef typename MapTraits::Map Map;
2121
+ typedef typename MapTraits::Less MapLess;
2122
+ typedef typename MapTraits::Pair MapPair;
2123
+ typedef typename MapTraits::Iterator MapIterator;
2124
+
2125
+ //
2126
+ // Layout of the members' map/array, re(al)located according to the needed capacity:
2127
+ //
2128
+ // {Map*}<>{capacity}<>{Member[capacity]}<>{MapIterator[capacity]}
2129
+ //
2130
+ // (where <> stands for the RAPIDJSON_ALIGN-ment, if needed)
2131
+ //
2132
+
2133
+ static RAPIDJSON_FORCEINLINE size_t GetMapLayoutSize(SizeType capacity) {
2134
+ return RAPIDJSON_ALIGN(sizeof(Map*)) +
2135
+ RAPIDJSON_ALIGN(sizeof(SizeType)) +
2136
+ RAPIDJSON_ALIGN(capacity * sizeof(Member)) +
2137
+ capacity * sizeof(MapIterator);
2138
+ }
2139
+
2140
+ static RAPIDJSON_FORCEINLINE SizeType &GetMapCapacity(Map* &map) {
2141
+ return *reinterpret_cast<SizeType*>(reinterpret_cast<uintptr_t>(&map) +
2142
+ RAPIDJSON_ALIGN(sizeof(Map*)));
2143
+ }
2144
+
2145
+ static RAPIDJSON_FORCEINLINE Member* GetMapMembers(Map* &map) {
2146
+ return reinterpret_cast<Member*>(reinterpret_cast<uintptr_t>(&map) +
2147
+ RAPIDJSON_ALIGN(sizeof(Map*)) +
2148
+ RAPIDJSON_ALIGN(sizeof(SizeType)));
2149
+ }
2150
+
2151
+ static RAPIDJSON_FORCEINLINE MapIterator* GetMapIterators(Map* &map) {
2152
+ return reinterpret_cast<MapIterator*>(reinterpret_cast<uintptr_t>(&map) +
2153
+ RAPIDJSON_ALIGN(sizeof(Map*)) +
2154
+ RAPIDJSON_ALIGN(sizeof(SizeType)) +
2155
+ RAPIDJSON_ALIGN(GetMapCapacity(map) * sizeof(Member)));
2156
+ }
2157
+
2158
+ static RAPIDJSON_FORCEINLINE Map* &GetMap(Member* members) {
2159
+ RAPIDJSON_ASSERT(members != 0);
2160
+ return *reinterpret_cast<Map**>(reinterpret_cast<uintptr_t>(members) -
2161
+ RAPIDJSON_ALIGN(sizeof(SizeType)) -
2162
+ RAPIDJSON_ALIGN(sizeof(Map*)));
2163
+ }
2164
+
2165
+ // Some compilers' debug mechanisms want all iterators to be destroyed, for their accounting..
2166
+ RAPIDJSON_FORCEINLINE MapIterator DropMapIterator(MapIterator& rhs) {
2167
+ #if RAPIDJSON_HAS_CXX11
2168
+ MapIterator ret = std::move(rhs);
2169
+ #else
2170
+ MapIterator ret = rhs;
2171
+ #endif
2172
+ rhs.~MapIterator();
2173
+ return ret;
2174
+ }
2175
+
2176
+ Map* &DoReallocMap(Map** oldMap, SizeType newCapacity, Allocator& allocator) {
2177
+ Map **newMap = static_cast<Map**>(allocator.Malloc(GetMapLayoutSize(newCapacity)));
2178
+ GetMapCapacity(*newMap) = newCapacity;
2179
+ if (!oldMap) {
2180
+ *newMap = new (allocator.Malloc(sizeof(Map))) Map(MapLess(), allocator);
2181
+ }
2182
+ else {
2183
+ *newMap = *oldMap;
2184
+ size_t count = (*oldMap)->size();
2185
+ std::memcpy(static_cast<void*>(GetMapMembers(*newMap)),
2186
+ static_cast<void*>(GetMapMembers(*oldMap)),
2187
+ count * sizeof(Member));
2188
+ MapIterator *oldIt = GetMapIterators(*oldMap),
2189
+ *newIt = GetMapIterators(*newMap);
2190
+ while (count--) {
2191
+ new (&newIt[count]) MapIterator(DropMapIterator(oldIt[count]));
2192
+ }
2193
+ Allocator::Free(oldMap);
2194
+ }
2195
+ return *newMap;
2196
+ }
2197
+
2198
+ RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator) {
2199
+ return GetMapMembers(DoReallocMap(0, capacity, allocator));
2200
+ }
2201
+
2202
+ void DoReserveMembers(SizeType newCapacity, Allocator& allocator) {
2203
+ ObjectData& o = data_.o;
2204
+ if (newCapacity > o.capacity) {
2205
+ Member* oldMembers = GetMembersPointer();
2206
+ Map **oldMap = oldMembers ? &GetMap(oldMembers) : 0,
2207
+ *&newMap = DoReallocMap(oldMap, newCapacity, allocator);
2208
+ RAPIDJSON_SETPOINTER(Member, o.members, GetMapMembers(newMap));
2209
+ o.capacity = newCapacity;
2210
+ }
2211
+ }
2212
+
2213
+ template <typename SourceAllocator>
2214
+ MemberIterator DoFindMember(const GenericValue<Encoding, SourceAllocator>& name) {
2215
+ if (Member* members = GetMembersPointer()) {
2216
+ Map* &map = GetMap(members);
2217
+ MapIterator mit = map->find(reinterpret_cast<const Data&>(name.data_));
2218
+ if (mit != map->end()) {
2219
+ return MemberIterator(&members[mit->second]);
2220
+ }
2221
+ }
2222
+ return MemberEnd();
2223
+ }
2224
+
2225
+ void DoClearMembers() {
2226
+ if (Member* members = GetMembersPointer()) {
2227
+ Map* &map = GetMap(members);
2228
+ MapIterator* mit = GetMapIterators(map);
2229
+ for (SizeType i = 0; i < data_.o.size; i++) {
2230
+ map->erase(DropMapIterator(mit[i]));
2231
+ members[i].~Member();
2232
+ }
2233
+ data_.o.size = 0;
2234
+ }
2235
+ }
2236
+
2237
+ void DoFreeMembers() {
2238
+ if (Member* members = GetMembersPointer()) {
2239
+ GetMap(members)->~Map();
2240
+ for (SizeType i = 0; i < data_.o.size; i++) {
2241
+ members[i].~Member();
2242
+ }
2243
+ if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
2244
+ Map** map = &GetMap(members);
2245
+ Allocator::Free(*map);
2246
+ Allocator::Free(map);
2247
+ }
2248
+ }
2249
+ }
2250
+
2251
+ #else // !RAPIDJSON_USE_MEMBERSMAP
2252
+
2253
+ RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator) {
2254
+ return Malloc<Member>(allocator, capacity);
2255
+ }
2256
+
2257
+ void DoReserveMembers(SizeType newCapacity, Allocator& allocator) {
2258
+ ObjectData& o = data_.o;
2259
+ if (newCapacity > o.capacity) {
2260
+ Member* newMembers = Realloc<Member>(allocator, GetMembersPointer(), o.capacity, newCapacity);
2261
+ RAPIDJSON_SETPOINTER(Member, o.members, newMembers);
2262
+ o.capacity = newCapacity;
2263
+ }
2264
+ }
2265
+
2266
+ template <typename SourceAllocator>
2267
+ MemberIterator DoFindMember(const GenericValue<Encoding, SourceAllocator>& name) {
2268
+ MemberIterator member = MemberBegin();
2269
+ for ( ; member != MemberEnd(); ++member)
2270
+ if (name.StringEqual(member->name))
2271
+ break;
2272
+ return member;
2273
+ }
2274
+
2275
+ void DoClearMembers() {
2276
+ for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
2277
+ m->~Member();
2278
+ data_.o.size = 0;
2279
+ }
2280
+
2281
+ void DoFreeMembers() {
2282
+ for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
2283
+ m->~Member();
2284
+ Allocator::Free(GetMembersPointer());
2285
+ }
2286
+
2287
+ #endif // !RAPIDJSON_USE_MEMBERSMAP
2288
+
2289
+ void DoAddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
2290
+ ObjectData& o = data_.o;
2291
+ if (o.size >= o.capacity)
2292
+ DoReserveMembers(o.capacity ? (o.capacity + (o.capacity + 1) / 2) : kDefaultObjectCapacity, allocator);
2293
+ Member* members = GetMembersPointer();
2294
+ Member* m = members + o.size;
2295
+ m->name.RawAssign(name);
2296
+ m->value.RawAssign(value);
2297
+ #if RAPIDJSON_USE_MEMBERSMAP
2298
+ Map* &map = GetMap(members);
2299
+ MapIterator* mit = GetMapIterators(map);
2300
+ new (&mit[o.size]) MapIterator(map->insert(MapPair(m->name.data_, o.size)));
2301
+ #endif
2302
+ ++o.size;
2303
+ }
2304
+
2305
+ MemberIterator DoRemoveMember(MemberIterator m) {
2306
+ ObjectData& o = data_.o;
2307
+ Member* members = GetMembersPointer();
2308
+ #if RAPIDJSON_USE_MEMBERSMAP
2309
+ Map* &map = GetMap(members);
2310
+ MapIterator* mit = GetMapIterators(map);
2311
+ SizeType mpos = static_cast<SizeType>(&*m - members);
2312
+ map->erase(DropMapIterator(mit[mpos]));
2313
+ #endif
2314
+ MemberIterator last(members + (o.size - 1));
2315
+ if (o.size > 1 && m != last) {
2316
+ #if RAPIDJSON_USE_MEMBERSMAP
2317
+ new (&mit[mpos]) MapIterator(DropMapIterator(mit[&*last - members]));
2318
+ mit[mpos]->second = mpos;
2319
+ #endif
2320
+ *m = *last; // Move the last one to this place
2321
+ }
2322
+ else {
2323
+ m->~Member(); // Only one left, just destroy
2324
+ }
2325
+ --o.size;
2326
+ return m;
2327
+ }
2328
+
2329
+ MemberIterator DoEraseMembers(ConstMemberIterator first, ConstMemberIterator last) {
2330
+ ObjectData& o = data_.o;
2331
+ MemberIterator beg = MemberBegin(),
2332
+ pos = beg + (first - beg),
2333
+ end = MemberEnd();
2334
+ #if RAPIDJSON_USE_MEMBERSMAP
2335
+ Map* &map = GetMap(GetMembersPointer());
2336
+ MapIterator* mit = GetMapIterators(map);
2337
+ #endif
2338
+ for (MemberIterator itr = pos; itr != last; ++itr) {
2339
+ #if RAPIDJSON_USE_MEMBERSMAP
2340
+ map->erase(DropMapIterator(mit[itr - beg]));
2341
+ #endif
2342
+ itr->~Member();
2343
+ }
2344
+ #if RAPIDJSON_USE_MEMBERSMAP
2345
+ if (first != last) {
2346
+ // Move remaining members/iterators
2347
+ MemberIterator next = pos + (last - first);
2348
+ for (MemberIterator itr = pos; next != end; ++itr, ++next) {
2349
+ std::memcpy(static_cast<void*>(&*itr), &*next, sizeof(Member));
2350
+ SizeType mpos = static_cast<SizeType>(itr - beg);
2351
+ new (&mit[mpos]) MapIterator(DropMapIterator(mit[next - beg]));
2352
+ mit[mpos]->second = mpos;
2353
+ }
2354
+ }
2355
+ #else
2356
+ std::memmove(static_cast<void*>(&*pos), &*last,
2357
+ static_cast<size_t>(end - last) * sizeof(Member));
2358
+ #endif
2359
+ o.size -= static_cast<SizeType>(last - first);
2360
+ return pos;
2361
+ }
2362
+
2363
+ template <typename SourceAllocator>
2364
+ void DoCopyMembers(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings) {
2365
+ RAPIDJSON_ASSERT(rhs.GetType() == kObjectType);
2366
+
2367
+ data_.f.flags = kObjectFlag;
2368
+ SizeType count = rhs.data_.o.size;
2369
+ Member* lm = DoAllocMembers(count, allocator);
2370
+ const typename GenericValue<Encoding,SourceAllocator>::Member* rm = rhs.GetMembersPointer();
2371
+ #if RAPIDJSON_USE_MEMBERSMAP
2372
+ Map* &map = GetMap(lm);
2373
+ MapIterator* mit = GetMapIterators(map);
2374
+ #endif
2375
+ for (SizeType i = 0; i < count; i++) {
2376
+ new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings);
2377
+ new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings);
2378
+ #if RAPIDJSON_USE_MEMBERSMAP
2379
+ new (&mit[i]) MapIterator(map->insert(MapPair(lm[i].name.data_, i)));
2380
+ #endif
2381
+ }
2382
+ data_.o.size = data_.o.capacity = count;
2383
+ SetMembersPointer(lm);
2384
+ }
2385
+
2112
2386
  // Initialize this value as array with initial data, without calling destructor.
2113
2387
  void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
2114
2388
  data_.f.flags = kArrayFlag;
@@ -2126,9 +2400,16 @@ private:
2126
2400
  void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
2127
2401
  data_.f.flags = kObjectFlag;
2128
2402
  if (count) {
2129
- Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
2403
+ Member* m = DoAllocMembers(count, allocator);
2130
2404
  SetMembersPointer(m);
2131
2405
  std::memcpy(static_cast<void*>(m), members, count * sizeof(Member));
2406
+ #if RAPIDJSON_USE_MEMBERSMAP
2407
+ Map* &map = GetMap(m);
2408
+ MapIterator* mit = GetMapIterators(map);
2409
+ for (SizeType i = 0; i < count; i++) {
2410
+ new (&mit[i]) MapIterator(map->insert(MapPair(m[i].name.data_, i)));
2411
+ }
2412
+ #endif
2132
2413
  }
2133
2414
  else
2134
2415
  SetMembersPointer(0);
@@ -2249,6 +2530,13 @@ public:
2249
2530
  #endif
2250
2531
 
2251
2532
  ~GenericDocument() {
2533
+ // Clear the ::ValueType before ownAllocator is destroyed, ~ValueType()
2534
+ // runs last and may access its elements or members which would be freed
2535
+ // with an allocator like MemoryPoolAllocator (CrtAllocator does not
2536
+ // free its data when destroyed, but MemoryPoolAllocator does).
2537
+ if (ownAllocator_) {
2538
+ ValueType::SetNull();
2539
+ }
2252
2540
  Destroy();
2253
2541
  }
2254
2542
 
@@ -2609,6 +2897,7 @@ public:
2609
2897
  GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
2610
2898
  ~GenericArray() {}
2611
2899
 
2900
+ operator ValueType&() const { return value_; }
2612
2901
  SizeType Size() const { return value_.Size(); }
2613
2902
  SizeType Capacity() const { return value_.Capacity(); }
2614
2903
  bool Empty() const { return value_.Empty(); }
@@ -2664,6 +2953,7 @@ public:
2664
2953
  GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
2665
2954
  ~GenericObject() {}
2666
2955
 
2956
+ operator ValueType&() const { return value_; }
2667
2957
  SizeType MemberCount() const { return value_.MemberCount(); }
2668
2958
  SizeType MemberCapacity() const { return value_.MemberCapacity(); }
2669
2959
  bool ObjectEmpty() const { return value_.ObjectEmpty(); }
@@ -2729,4 +3019,9 @@ private:
2729
3019
  RAPIDJSON_NAMESPACE_END
2730
3020
  RAPIDJSON_DIAG_POP
2731
3021
 
3022
+ #ifdef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
3023
+ #pragma pop_macro("GetObject")
3024
+ #undef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
3025
+ #endif
3026
+
2732
3027
  #endif // RAPIDJSON_DOCUMENT_H_