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.
- 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/address.json +139 -0
- data/ext/rj_schema/rapidjson/bin/unittestschema/allOf_address.json +7 -0
- data/ext/rj_schema/rapidjson/bin/unittestschema/anyOf_address.json +7 -0
- data/ext/rj_schema/rapidjson/bin/unittestschema/idandref.json +69 -0
- data/ext/rj_schema/rapidjson/bin/unittestschema/oneOf_address.json +7 -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 +120 -0
- data/ext/rj_schema/rapidjson/example/traverseaspointer.cpp +39 -0
- data/ext/rj_schema/rapidjson/include/rapidjson/allocators.h +464 -56
- data/ext/rj_schema/rapidjson/include/rapidjson/cursorstreamwrapper.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/document.h +367 -72
- data/ext/rj_schema/rapidjson/include/rapidjson/encodedstream.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/encodings.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/error/en.h +49 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/error/error.h +56 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/filereadstream.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/filewritestream.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/fwd.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/biginteger.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/clzll.h +4 -4
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/diyfp.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/dtoa.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/ieee754.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/itoa.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/meta.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/pow10.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/regex.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/stack.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/strfunc.h +15 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/strtod.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/swap.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/istreamwrapper.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/memorybuffer.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/memorystream.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/ostreamwrapper.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/pointer.h +69 -2
- data/ext/rj_schema/rapidjson/include/rapidjson/prettywriter.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/rapidjson.h +77 -12
- data/ext/rj_schema/rapidjson/include/rapidjson/reader.h +17 -9
- data/ext/rj_schema/rapidjson/include/rapidjson/schema.h +558 -259
- data/ext/rj_schema/rapidjson/include/rapidjson/stream.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/stringbuffer.h +1 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/uri.h +466 -0
- data/ext/rj_schema/rapidjson/include/rapidjson/writer.h +3 -3
- data/ext/rj_schema/rapidjson/readme.md +3 -3
- data/ext/rj_schema/rapidjson/readme.zh-cn.md +2 -2
- data/ext/rj_schema/rapidjson/test/perftest/misctest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/perftest/perftest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/perftest/perftest.h +6 -5
- data/ext/rj_schema/rapidjson/test/perftest/platformtest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/perftest/rapidjsontest.cpp +21 -3
- data/ext/rj_schema/rapidjson/test/unittest/CMakeLists.txt +3 -0
- data/ext/rj_schema/rapidjson/test/unittest/allocatorstest.cpp +194 -2
- data/ext/rj_schema/rapidjson/test/unittest/bigintegertest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/clzlltest.cpp +34 -0
- data/ext/rj_schema/rapidjson/test/unittest/cursorstreamwrappertest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/documenttest.cpp +3 -1
- data/ext/rj_schema/rapidjson/test/unittest/dtoatest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/encodedstreamtest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/encodingstest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/filestreamtest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/fwdtest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/istreamwrappertest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/itoatest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/jsoncheckertest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/namespacetest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/ostreamwrappertest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/platformtest.cpp +40 -0
- data/ext/rj_schema/rapidjson/test/unittest/pointertest.cpp +95 -3
- data/ext/rj_schema/rapidjson/test/unittest/prettywritertest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/readertest.cpp +4 -1
- data/ext/rj_schema/rapidjson/test/unittest/regextest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/schematest.cpp +961 -81
- data/ext/rj_schema/rapidjson/test/unittest/simdtest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/strfunctest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/stringbuffertest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/strtodtest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/unittest.cpp +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/unittest.h +1 -1
- data/ext/rj_schema/rapidjson/test/unittest/uritest.cpp +718 -0
- data/ext/rj_schema/rapidjson/test/unittest/valuetest.cpp +13 -3
- data/ext/rj_schema/rapidjson/test/unittest/writertest.cpp +1 -1
- data/ext/rj_schema/rj_schema.cpp +162 -18
- data/lib/rj_schema.rb +1 -1
- 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.
|
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.
|
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
|
50
|
-
#include <
|
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
|
-
|
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
|
-
|
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::
|
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
|
-
|
893
|
-
m->~Member();
|
894
|
-
Allocator::Free(GetMembersPointer());
|
898
|
+
DoFreeMembers();
|
895
899
|
break;
|
896
900
|
|
897
901
|
case kCopyStringFlag:
|
898
|
-
Allocator::
|
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(
|
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
|
-
|
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
|
-
|
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
|
-
|
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_
|
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 (
|
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 (
|
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
|
-
|
2005
|
-
|
2006
|
-
|
2007
|
-
|
2008
|
-
|
2009
|
-
|
2010
|
-
|
2011
|
-
|
2012
|
-
|
2013
|
-
|
2014
|
-
|
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 =
|
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_
|