rj_schema 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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_
|