rj_schema 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/rj_schema/rapidjson/CMakeLists.txt +23 -1
- data/ext/rj_schema/rapidjson/appveyor.yml +49 -1
- data/ext/rj_schema/rapidjson/bin/types/alotofkeys.json +502 -0
- data/ext/rj_schema/rapidjson/bin/unittestschema/idandref.json +69 -0
- data/ext/rj_schema/rapidjson/doc/stream.md +7 -7
- data/ext/rj_schema/rapidjson/doc/stream.zh-cn.md +1 -1
- data/ext/rj_schema/rapidjson/doc/tutorial.md +15 -15
- data/ext/rj_schema/rapidjson/example/schemavalidator/schemavalidator.cpp +2 -0
- data/ext/rj_schema/rapidjson/example/traverseaspointer.cpp +39 -0
- data/ext/rj_schema/rapidjson/include/rapidjson/allocators.h +460 -52
- data/ext/rj_schema/rapidjson/include/rapidjson/document.h +350 -60
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/strfunc.h +14 -0
- data/ext/rj_schema/rapidjson/include/rapidjson/pointer.h +68 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/rapidjson.h +60 -11
- data/ext/rj_schema/rapidjson/include/rapidjson/schema.h +249 -102
- data/ext/rj_schema/rapidjson/include/rapidjson/uri.h +466 -0
- data/ext/rj_schema/rapidjson/test/perftest/perftest.h +5 -4
- data/ext/rj_schema/rapidjson/test/perftest/rapidjsontest.cpp +20 -2
- data/ext/rj_schema/rapidjson/test/unittest/CMakeLists.txt +2 -0
- data/ext/rj_schema/rapidjson/test/unittest/allocatorstest.cpp +193 -1
- data/ext/rj_schema/rapidjson/test/unittest/documenttest.cpp +2 -0
- data/ext/rj_schema/rapidjson/test/unittest/platformtest.cpp +40 -0
- data/ext/rj_schema/rapidjson/test/unittest/pointertest.cpp +62 -2
- data/ext/rj_schema/rapidjson/test/unittest/schematest.cpp +372 -7
- data/ext/rj_schema/rapidjson/test/unittest/uritest.cpp +718 -0
- data/ext/rj_schema/rapidjson/test/unittest/valuetest.cpp +12 -2
- data/ext/rj_schema/rj_schema.cpp +1 -1
- data/lib/rj_schema.rb +1 -1
- metadata +9 -3
@@ -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
|
50
|
-
#include <
|
58
|
+
#if RAPIDJSON_USE_MEMBERSMAP
|
59
|
+
#include <map> // std::multimap
|
51
60
|
#endif
|
52
61
|
|
53
62
|
RAPIDJSON_NAMESPACE_BEGIN
|
@@ -732,18 +741,8 @@ public:
|
|
732
741
|
template <typename SourceAllocator>
|
733
742
|
GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
|
734
743
|
switch (rhs.GetType()) {
|
735
|
-
case kObjectType:
|
736
|
-
|
737
|
-
Member* lm = reinterpret_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
|
738
|
-
const typename GenericValue<Encoding,SourceAllocator>::Member* rm = rhs.GetMembersPointer();
|
739
|
-
for (SizeType i = 0; i < count; i++) {
|
740
|
-
new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings);
|
741
|
-
new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings);
|
742
|
-
}
|
743
|
-
data_.f.flags = kObjectFlag;
|
744
|
-
data_.o.size = data_.o.capacity = count;
|
745
|
-
SetMembersPointer(lm);
|
746
|
-
}
|
744
|
+
case kObjectType:
|
745
|
+
DoCopyMembers(rhs, allocator, copyConstStrings);
|
747
746
|
break;
|
748
747
|
case kArrayType: {
|
749
748
|
SizeType count = rhs.data_.a.size;
|
@@ -879,25 +878,30 @@ public:
|
|
879
878
|
/*! Need to destruct elements of array, members of object, or copy-string.
|
880
879
|
*/
|
881
880
|
~GenericValue() {
|
882
|
-
|
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)) {
|
883
885
|
switch(data_.f.flags) {
|
884
886
|
case kArrayFlag:
|
885
887
|
{
|
886
888
|
GenericValue* e = GetElementsPointer();
|
887
889
|
for (GenericValue* v = e; v != e + data_.a.size; ++v)
|
888
890
|
v->~GenericValue();
|
889
|
-
Allocator::
|
891
|
+
if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
|
892
|
+
Allocator::Free(e);
|
893
|
+
}
|
890
894
|
}
|
891
895
|
break;
|
892
896
|
|
893
897
|
case kObjectFlag:
|
894
|
-
|
895
|
-
m->~Member();
|
896
|
-
Allocator::Free(GetMembersPointer());
|
898
|
+
DoFreeMembers();
|
897
899
|
break;
|
898
900
|
|
899
901
|
case kCopyStringFlag:
|
900
|
-
Allocator::
|
902
|
+
if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
|
903
|
+
Allocator::Free(const_cast<Ch*>(GetStringPointer()));
|
904
|
+
}
|
901
905
|
break;
|
902
906
|
|
903
907
|
default:
|
@@ -916,8 +920,13 @@ public:
|
|
916
920
|
*/
|
917
921
|
GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
|
918
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);
|
919
928
|
this->~GenericValue();
|
920
|
-
RawAssign(
|
929
|
+
RawAssign(temp);
|
921
930
|
}
|
922
931
|
return *this;
|
923
932
|
}
|
@@ -1083,6 +1092,7 @@ public:
|
|
1083
1092
|
*/
|
1084
1093
|
template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
|
1085
1094
|
|
1095
|
+
#ifndef __cpp_lib_three_way_comparison
|
1086
1096
|
//! Equal-to operator with arbitrary types (symmetric version)
|
1087
1097
|
/*! \return (rhs == lhs)
|
1088
1098
|
*/
|
@@ -1093,6 +1103,7 @@ public:
|
|
1093
1103
|
*/
|
1094
1104
|
template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
|
1095
1105
|
//@}
|
1106
|
+
#endif
|
1096
1107
|
|
1097
1108
|
//!@name Type
|
1098
1109
|
//@{
|
@@ -1258,10 +1269,7 @@ public:
|
|
1258
1269
|
*/
|
1259
1270
|
GenericValue& MemberReserve(SizeType newCapacity, Allocator &allocator) {
|
1260
1271
|
RAPIDJSON_ASSERT(IsObject());
|
1261
|
-
|
1262
|
-
SetMembersPointer(reinterpret_cast<Member*>(allocator.Realloc(GetMembersPointer(), data_.o.capacity * sizeof(Member), newCapacity * sizeof(Member))));
|
1263
|
-
data_.o.capacity = newCapacity;
|
1264
|
-
}
|
1272
|
+
DoReserveMembers(newCapacity, allocator);
|
1265
1273
|
return *this;
|
1266
1274
|
}
|
1267
1275
|
|
@@ -1335,11 +1343,7 @@ public:
|
|
1335
1343
|
MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) {
|
1336
1344
|
RAPIDJSON_ASSERT(IsObject());
|
1337
1345
|
RAPIDJSON_ASSERT(name.IsString());
|
1338
|
-
|
1339
|
-
for ( ; member != MemberEnd(); ++member)
|
1340
|
-
if (name.StringEqual(member->name))
|
1341
|
-
break;
|
1342
|
-
return member;
|
1346
|
+
return DoFindMember(name);
|
1343
1347
|
}
|
1344
1348
|
template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
|
1345
1349
|
|
@@ -1368,14 +1372,7 @@ public:
|
|
1368
1372
|
GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
|
1369
1373
|
RAPIDJSON_ASSERT(IsObject());
|
1370
1374
|
RAPIDJSON_ASSERT(name.IsString());
|
1371
|
-
|
1372
|
-
ObjectData& o = data_.o;
|
1373
|
-
if (o.size >= o.capacity)
|
1374
|
-
MemberReserve(o.capacity == 0 ? kDefaultObjectCapacity : (o.capacity + (o.capacity + 1) / 2), allocator);
|
1375
|
-
Member* members = GetMembersPointer();
|
1376
|
-
members[o.size].name.RawAssign(name);
|
1377
|
-
members[o.size].value.RawAssign(value);
|
1378
|
-
o.size++;
|
1375
|
+
DoAddMember(name, value, allocator);
|
1379
1376
|
return *this;
|
1380
1377
|
}
|
1381
1378
|
|
@@ -1509,9 +1506,7 @@ public:
|
|
1509
1506
|
*/
|
1510
1507
|
void RemoveAllMembers() {
|
1511
1508
|
RAPIDJSON_ASSERT(IsObject());
|
1512
|
-
|
1513
|
-
m->~Member();
|
1514
|
-
data_.o.size = 0;
|
1509
|
+
DoClearMembers();
|
1515
1510
|
}
|
1516
1511
|
|
1517
1512
|
//! Remove a member in object by its name.
|
@@ -1555,14 +1550,7 @@ public:
|
|
1555
1550
|
RAPIDJSON_ASSERT(data_.o.size > 0);
|
1556
1551
|
RAPIDJSON_ASSERT(GetMembersPointer() != 0);
|
1557
1552
|
RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
|
1558
|
-
|
1559
|
-
MemberIterator last(GetMembersPointer() + (data_.o.size - 1));
|
1560
|
-
if (data_.o.size > 1 && m != last)
|
1561
|
-
*m = *last; // Move the last one to this place
|
1562
|
-
else
|
1563
|
-
m->~Member(); // Only one left, just destroy
|
1564
|
-
--data_.o.size;
|
1565
|
-
return m;
|
1553
|
+
return DoRemoveMember(m);
|
1566
1554
|
}
|
1567
1555
|
|
1568
1556
|
//! Remove a member from an object by iterator.
|
@@ -1594,13 +1582,7 @@ public:
|
|
1594
1582
|
RAPIDJSON_ASSERT(first >= MemberBegin());
|
1595
1583
|
RAPIDJSON_ASSERT(first <= last);
|
1596
1584
|
RAPIDJSON_ASSERT(last <= MemberEnd());
|
1597
|
-
|
1598
|
-
MemberIterator pos = MemberBegin() + (first - MemberBegin());
|
1599
|
-
for (MemberIterator itr = pos; itr != last; ++itr)
|
1600
|
-
itr->~Member();
|
1601
|
-
std::memmove(static_cast<void*>(&*pos), &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));
|
1602
|
-
data_.o.size -= static_cast<SizeType>(last - first);
|
1603
|
-
return pos;
|
1585
|
+
return DoEraseMembers(first, last);
|
1604
1586
|
}
|
1605
1587
|
|
1606
1588
|
//! Erase a member in object by its name.
|
@@ -1629,7 +1611,9 @@ public:
|
|
1629
1611
|
}
|
1630
1612
|
|
1631
1613
|
Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
|
1614
|
+
Object GetObj() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
|
1632
1615
|
ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
|
1616
|
+
ConstObject GetObj() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
|
1633
1617
|
|
1634
1618
|
//@}
|
1635
1619
|
|
@@ -1851,12 +1835,12 @@ public:
|
|
1851
1835
|
//!@name String
|
1852
1836
|
//@{
|
1853
1837
|
|
1854
|
-
const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data_
|
1838
|
+
const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return DataString(data_); }
|
1855
1839
|
|
1856
1840
|
//! Get the length of string.
|
1857
1841
|
/*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength().
|
1858
1842
|
*/
|
1859
|
-
SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return (
|
1843
|
+
SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return DataStringLength(data_); }
|
1860
1844
|
|
1861
1845
|
//! Set this value as a string without copying source string.
|
1862
1846
|
/*! This version has better performance with supplied length, and also support string containing null character.
|
@@ -1967,7 +1951,7 @@ public:
|
|
1967
1951
|
case kArrayType:
|
1968
1952
|
if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
|
1969
1953
|
return false;
|
1970
|
-
for (
|
1954
|
+
for (ConstValueIterator v = Begin(); v != End(); ++v)
|
1971
1955
|
if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
|
1972
1956
|
return false;
|
1973
1957
|
return handler.EndArray(data_.a.size);
|
@@ -2105,6 +2089,13 @@ private:
|
|
2105
2089
|
Flag f;
|
2106
2090
|
}; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION
|
2107
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
|
+
|
2108
2099
|
RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
|
2109
2100
|
RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
|
2110
2101
|
RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
|
@@ -2112,6 +2103,286 @@ private:
|
|
2112
2103
|
RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
|
2113
2104
|
RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
|
2114
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
|
+
|
2115
2386
|
// Initialize this value as array with initial data, without calling destructor.
|
2116
2387
|
void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
|
2117
2388
|
data_.f.flags = kArrayFlag;
|
@@ -2129,9 +2400,16 @@ private:
|
|
2129
2400
|
void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
|
2130
2401
|
data_.f.flags = kObjectFlag;
|
2131
2402
|
if (count) {
|
2132
|
-
Member* m =
|
2403
|
+
Member* m = DoAllocMembers(count, allocator);
|
2133
2404
|
SetMembersPointer(m);
|
2134
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
|
2135
2413
|
}
|
2136
2414
|
else
|
2137
2415
|
SetMembersPointer(0);
|
@@ -2252,6 +2530,13 @@ public:
|
|
2252
2530
|
#endif
|
2253
2531
|
|
2254
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
|
+
}
|
2255
2540
|
Destroy();
|
2256
2541
|
}
|
2257
2542
|
|
@@ -2734,4 +3019,9 @@ private:
|
|
2734
3019
|
RAPIDJSON_NAMESPACE_END
|
2735
3020
|
RAPIDJSON_DIAG_POP
|
2736
3021
|
|
3022
|
+
#ifdef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
|
3023
|
+
#pragma pop_macro("GetObject")
|
3024
|
+
#undef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
|
3025
|
+
#endif
|
3026
|
+
|
2737
3027
|
#endif // RAPIDJSON_DOCUMENT_H_
|