rj_schema 0.2.6 → 1.0.3

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 +161 -17
  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
@@ -0,0 +1,466 @@
1
+ // Tencent is pleased to support the open source community by making RapidJSON available.
2
+ //
3
+ // (C) Copyright IBM Corporation 2021
4
+ //
5
+ // Licensed under the MIT License (the "License"); you may not use this file except
6
+ // in compliance with the License. You may obtain a copy of the License at
7
+ //
8
+ // http://opensource.org/licenses/MIT
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software distributed
11
+ // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12
+ // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13
+ // specific language governing permissions and limitations under the License.
14
+
15
+ #ifndef RAPIDJSON_URI_H_
16
+ #define RAPIDJSON_URI_H_
17
+
18
+ #include "internal/strfunc.h"
19
+
20
+ #if defined(__clang__)
21
+ RAPIDJSON_DIAG_PUSH
22
+ RAPIDJSON_DIAG_OFF(c++98-compat)
23
+ #elif defined(_MSC_VER)
24
+ RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
25
+ #endif
26
+
27
+ RAPIDJSON_NAMESPACE_BEGIN
28
+
29
+ ///////////////////////////////////////////////////////////////////////////////
30
+ // GenericUri
31
+
32
+ template <typename ValueType, typename Allocator=CrtAllocator>
33
+ class GenericUri {
34
+ public:
35
+ typedef typename ValueType::Ch Ch;
36
+ #if RAPIDJSON_HAS_STDSTRING
37
+ typedef std::basic_string<Ch> String;
38
+ #endif
39
+
40
+ //! Constructors
41
+ GenericUri(Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() {
42
+ }
43
+
44
+ GenericUri(const Ch* uri, SizeType len, Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() {
45
+ Parse(uri, len);
46
+ }
47
+
48
+ GenericUri(const Ch* uri, Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() {
49
+ Parse(uri, internal::StrLen<Ch>(uri));
50
+ }
51
+
52
+ // Use with specializations of GenericValue
53
+ template<typename T> GenericUri(const T& uri, Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() {
54
+ const Ch* u = uri.template Get<const Ch*>(); // TypeHelper from document.h
55
+ Parse(u, internal::StrLen<Ch>(u));
56
+ }
57
+
58
+ #if RAPIDJSON_HAS_STDSTRING
59
+ GenericUri(const String& uri, Allocator* allocator = 0) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() {
60
+ Parse(uri.c_str(), internal::StrLen<Ch>(uri.c_str()));
61
+ }
62
+ #endif
63
+
64
+ //! Copy constructor
65
+ GenericUri(const GenericUri& rhs) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(), ownAllocator_() {
66
+ *this = rhs;
67
+ }
68
+
69
+ //! Copy constructor
70
+ GenericUri(const GenericUri& rhs, Allocator* allocator) : uri_(), base_(), scheme_(), auth_(), path_(), query_(), frag_(), allocator_(allocator), ownAllocator_() {
71
+ *this = rhs;
72
+ }
73
+
74
+ //! Destructor.
75
+ ~GenericUri() {
76
+ Free();
77
+ RAPIDJSON_DELETE(ownAllocator_);
78
+ }
79
+
80
+ //! Assignment operator
81
+ GenericUri& operator=(const GenericUri& rhs) {
82
+ if (this != &rhs) {
83
+ // Do not delete ownAllocator
84
+ Free();
85
+ Allocate(rhs.GetStringLength());
86
+ auth_ = CopyPart(scheme_, rhs.scheme_, rhs.GetSchemeStringLength());
87
+ path_ = CopyPart(auth_, rhs.auth_, rhs.GetAuthStringLength());
88
+ query_ = CopyPart(path_, rhs.path_, rhs.GetPathStringLength());
89
+ frag_ = CopyPart(query_, rhs.query_, rhs.GetQueryStringLength());
90
+ base_ = CopyPart(frag_, rhs.frag_, rhs.GetFragStringLength());
91
+ uri_ = CopyPart(base_, rhs.base_, rhs.GetBaseStringLength());
92
+ CopyPart(uri_, rhs.uri_, rhs.GetStringLength());
93
+ }
94
+ return *this;
95
+ }
96
+
97
+ //! Getters
98
+ // Use with specializations of GenericValue
99
+ template<typename T> void Get(T& uri, Allocator& allocator) {
100
+ uri.template Set<const Ch*>(this->GetString(), allocator); // TypeHelper from document.h
101
+ }
102
+
103
+ const Ch* GetString() const { return uri_; }
104
+ SizeType GetStringLength() const { return uri_ == 0 ? 0 : internal::StrLen<Ch>(uri_); }
105
+ const Ch* GetBaseString() const { return base_; }
106
+ SizeType GetBaseStringLength() const { return base_ == 0 ? 0 : internal::StrLen<Ch>(base_); }
107
+ const Ch* GetSchemeString() const { return scheme_; }
108
+ SizeType GetSchemeStringLength() const { return scheme_ == 0 ? 0 : internal::StrLen<Ch>(scheme_); }
109
+ const Ch* GetAuthString() const { return auth_; }
110
+ SizeType GetAuthStringLength() const { return auth_ == 0 ? 0 : internal::StrLen<Ch>(auth_); }
111
+ const Ch* GetPathString() const { return path_; }
112
+ SizeType GetPathStringLength() const { return path_ == 0 ? 0 : internal::StrLen<Ch>(path_); }
113
+ const Ch* GetQueryString() const { return query_; }
114
+ SizeType GetQueryStringLength() const { return query_ == 0 ? 0 : internal::StrLen<Ch>(query_); }
115
+ const Ch* GetFragString() const { return frag_; }
116
+ SizeType GetFragStringLength() const { return frag_ == 0 ? 0 : internal::StrLen<Ch>(frag_); }
117
+
118
+ #if RAPIDJSON_HAS_STDSTRING
119
+ static String Get(const GenericUri& uri) { return String(uri.GetString(), uri.GetStringLength()); }
120
+ static String GetBase(const GenericUri& uri) { return String(uri.GetBaseString(), uri.GetBaseStringLength()); }
121
+ static String GetScheme(const GenericUri& uri) { return String(uri.GetSchemeString(), uri.GetSchemeStringLength()); }
122
+ static String GetAuth(const GenericUri& uri) { return String(uri.GetAuthString(), uri.GetAuthStringLength()); }
123
+ static String GetPath(const GenericUri& uri) { return String(uri.GetPathString(), uri.GetPathStringLength()); }
124
+ static String GetQuery(const GenericUri& uri) { return String(uri.GetQueryString(), uri.GetQueryStringLength()); }
125
+ static String GetFrag(const GenericUri& uri) { return String(uri.GetFragString(), uri.GetFragStringLength()); }
126
+ #endif
127
+
128
+ //! Equality operators
129
+ bool operator==(const GenericUri& rhs) const {
130
+ return Match(rhs, true);
131
+ }
132
+
133
+ bool operator!=(const GenericUri& rhs) const {
134
+ return !Match(rhs, true);
135
+ }
136
+
137
+ bool Match(const GenericUri& uri, bool full = true) const {
138
+ Ch* s1;
139
+ Ch* s2;
140
+ if (full) {
141
+ s1 = uri_;
142
+ s2 = uri.uri_;
143
+ } else {
144
+ s1 = base_;
145
+ s2 = uri.base_;
146
+ }
147
+ if (s1 == s2) return true;
148
+ if (s1 == 0 || s2 == 0) return false;
149
+ return internal::StrCmp<Ch>(s1, s2) == 0;
150
+ }
151
+
152
+ //! Resolve this URI against another (base) URI in accordance with URI resolution rules.
153
+ // See https://tools.ietf.org/html/rfc3986
154
+ // Use for resolving an id or $ref with an in-scope id.
155
+ // Returns a new GenericUri for the resolved URI.
156
+ GenericUri Resolve(const GenericUri& baseuri, Allocator* allocator = 0) {
157
+ GenericUri resuri;
158
+ resuri.allocator_ = allocator;
159
+ // Ensure enough space for combining paths
160
+ resuri.Allocate(GetStringLength() + baseuri.GetStringLength() + 1); // + 1 for joining slash
161
+
162
+ if (!(GetSchemeStringLength() == 0)) {
163
+ // Use all of this URI
164
+ resuri.auth_ = CopyPart(resuri.scheme_, scheme_, GetSchemeStringLength());
165
+ resuri.path_ = CopyPart(resuri.auth_, auth_, GetAuthStringLength());
166
+ resuri.query_ = CopyPart(resuri.path_, path_, GetPathStringLength());
167
+ resuri.frag_ = CopyPart(resuri.query_, query_, GetQueryStringLength());
168
+ resuri.RemoveDotSegments();
169
+ } else {
170
+ // Use the base scheme
171
+ resuri.auth_ = CopyPart(resuri.scheme_, baseuri.scheme_, baseuri.GetSchemeStringLength());
172
+ if (!(GetAuthStringLength() == 0)) {
173
+ // Use this auth, path, query
174
+ resuri.path_ = CopyPart(resuri.auth_, auth_, GetAuthStringLength());
175
+ resuri.query_ = CopyPart(resuri.path_, path_, GetPathStringLength());
176
+ resuri.frag_ = CopyPart(resuri.query_, query_, GetQueryStringLength());
177
+ resuri.RemoveDotSegments();
178
+ } else {
179
+ // Use the base auth
180
+ resuri.path_ = CopyPart(resuri.auth_, baseuri.auth_, baseuri.GetAuthStringLength());
181
+ if (GetPathStringLength() == 0) {
182
+ // Use the base path
183
+ resuri.query_ = CopyPart(resuri.path_, baseuri.path_, baseuri.GetPathStringLength());
184
+ if (GetQueryStringLength() == 0) {
185
+ // Use the base query
186
+ resuri.frag_ = CopyPart(resuri.query_, baseuri.query_, baseuri.GetQueryStringLength());
187
+ } else {
188
+ // Use this query
189
+ resuri.frag_ = CopyPart(resuri.query_, query_, GetQueryStringLength());
190
+ }
191
+ } else {
192
+ if (path_[0] == '/') {
193
+ // Absolute path - use all of this path
194
+ resuri.query_ = CopyPart(resuri.path_, path_, GetPathStringLength());
195
+ resuri.RemoveDotSegments();
196
+ } else {
197
+ // Relative path - append this path to base path after base path's last slash
198
+ size_t pos = 0;
199
+ if (!(baseuri.GetAuthStringLength() == 0) && baseuri.GetPathStringLength() == 0) {
200
+ resuri.path_[pos] = '/';
201
+ pos++;
202
+ }
203
+ size_t lastslashpos = baseuri.GetPathStringLength();
204
+ while (lastslashpos > 0) {
205
+ if (baseuri.path_[lastslashpos - 1] == '/') break;
206
+ lastslashpos--;
207
+ }
208
+ std::memcpy(&resuri.path_[pos], baseuri.path_, lastslashpos * sizeof(Ch));
209
+ pos += lastslashpos;
210
+ resuri.query_ = CopyPart(&resuri.path_[pos], path_, GetPathStringLength());
211
+ resuri.RemoveDotSegments();
212
+ }
213
+ // Use this query
214
+ resuri.frag_ = CopyPart(resuri.query_, query_, GetQueryStringLength());
215
+ }
216
+ }
217
+ }
218
+ // Always use this frag
219
+ resuri.base_ = CopyPart(resuri.frag_, frag_, GetFragStringLength());
220
+
221
+ // Re-constitute base_ and uri_
222
+ resuri.SetBase();
223
+ resuri.uri_ = resuri.base_ + resuri.GetBaseStringLength() + 1;
224
+ resuri.SetUri();
225
+ return resuri;
226
+ }
227
+
228
+ //! Get the allocator of this GenericUri.
229
+ Allocator& GetAllocator() { return *allocator_; }
230
+
231
+ private:
232
+ // Allocate memory for a URI
233
+ // Returns total amount allocated
234
+ std::size_t Allocate(std::size_t len) {
235
+ // Create own allocator if user did not supply.
236
+ if (!allocator_)
237
+ ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
238
+
239
+ // Allocate one block containing each part of the URI (5) plus base plus full URI, all null terminated.
240
+ // Order: scheme, auth, path, query, frag, base, uri
241
+ size_t total = (3 * len + 7) * sizeof(Ch);
242
+ scheme_ = static_cast<Ch*>(allocator_->Malloc(total));
243
+ *scheme_ = '\0';
244
+ auth_ = scheme_ + 1;
245
+ *auth_ = '\0';
246
+ path_ = auth_ + 1;
247
+ *path_ = '\0';
248
+ query_ = path_ + 1;
249
+ *query_ = '\0';
250
+ frag_ = query_ + 1;
251
+ *frag_ = '\0';
252
+ base_ = frag_ + 1;
253
+ *base_ = '\0';
254
+ uri_ = base_ + 1;
255
+ *uri_ = '\0';
256
+ return total;
257
+ }
258
+
259
+ // Free memory for a URI
260
+ void Free() {
261
+ if (scheme_) {
262
+ Allocator::Free(scheme_);
263
+ scheme_ = 0;
264
+ }
265
+ }
266
+
267
+ // Parse a URI into constituent scheme, authority, path, query, & fragment parts
268
+ // Supports URIs that match regex ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))? as per
269
+ // https://tools.ietf.org/html/rfc3986
270
+ void Parse(const Ch* uri, std::size_t len) {
271
+ std::size_t start = 0, pos1 = 0, pos2 = 0;
272
+ Allocate(len);
273
+
274
+ // Look for scheme ([^:/?#]+):)?
275
+ if (start < len) {
276
+ while (pos1 < len) {
277
+ if (uri[pos1] == ':') break;
278
+ pos1++;
279
+ }
280
+ if (pos1 != len) {
281
+ while (pos2 < len) {
282
+ if (uri[pos2] == '/') break;
283
+ if (uri[pos2] == '?') break;
284
+ if (uri[pos2] == '#') break;
285
+ pos2++;
286
+ }
287
+ if (pos1 < pos2) {
288
+ pos1++;
289
+ std::memcpy(scheme_, &uri[start], pos1 * sizeof(Ch));
290
+ scheme_[pos1] = '\0';
291
+ start = pos1;
292
+ }
293
+ }
294
+ }
295
+ // Look for auth (//([^/?#]*))?
296
+ auth_ = scheme_ + GetSchemeStringLength() + 1;
297
+ *auth_ = '\0';
298
+ if (start < len - 1 && uri[start] == '/' && uri[start + 1] == '/') {
299
+ pos2 = start + 2;
300
+ while (pos2 < len) {
301
+ if (uri[pos2] == '/') break;
302
+ if (uri[pos2] == '?') break;
303
+ if (uri[pos2] == '#') break;
304
+ pos2++;
305
+ }
306
+ std::memcpy(auth_, &uri[start], (pos2 - start) * sizeof(Ch));
307
+ auth_[pos2 - start] = '\0';
308
+ start = pos2;
309
+ }
310
+ // Look for path ([^?#]*)
311
+ path_ = auth_ + GetAuthStringLength() + 1;
312
+ *path_ = '\0';
313
+ if (start < len) {
314
+ pos2 = start;
315
+ while (pos2 < len) {
316
+ if (uri[pos2] == '?') break;
317
+ if (uri[pos2] == '#') break;
318
+ pos2++;
319
+ }
320
+ if (start != pos2) {
321
+ std::memcpy(path_, &uri[start], (pos2 - start) * sizeof(Ch));
322
+ path_[pos2 - start] = '\0';
323
+ if (path_[0] == '/')
324
+ RemoveDotSegments(); // absolute path - normalize
325
+ start = pos2;
326
+ }
327
+ }
328
+ // Look for query (\?([^#]*))?
329
+ query_ = path_ + GetPathStringLength() + 1;
330
+ *query_ = '\0';
331
+ if (start < len && uri[start] == '?') {
332
+ pos2 = start + 1;
333
+ while (pos2 < len) {
334
+ if (uri[pos2] == '#') break;
335
+ pos2++;
336
+ }
337
+ if (start != pos2) {
338
+ std::memcpy(query_, &uri[start], (pos2 - start) * sizeof(Ch));
339
+ query_[pos2 - start] = '\0';
340
+ start = pos2;
341
+ }
342
+ }
343
+ // Look for fragment (#(.*))?
344
+ frag_ = query_ + GetQueryStringLength() + 1;
345
+ *frag_ = '\0';
346
+ if (start < len && uri[start] == '#') {
347
+ std::memcpy(frag_, &uri[start], (len - start) * sizeof(Ch));
348
+ frag_[len - start] = '\0';
349
+ }
350
+
351
+ // Re-constitute base_ and uri_
352
+ base_ = frag_ + GetFragStringLength() + 1;
353
+ SetBase();
354
+ uri_ = base_ + GetBaseStringLength() + 1;
355
+ SetUri();
356
+ }
357
+
358
+ // Reconstitute base
359
+ void SetBase() {
360
+ Ch* next = base_;
361
+ std::memcpy(next, scheme_, GetSchemeStringLength() * sizeof(Ch));
362
+ next+= GetSchemeStringLength();
363
+ std::memcpy(next, auth_, GetAuthStringLength() * sizeof(Ch));
364
+ next+= GetAuthStringLength();
365
+ std::memcpy(next, path_, GetPathStringLength() * sizeof(Ch));
366
+ next+= GetPathStringLength();
367
+ std::memcpy(next, query_, GetQueryStringLength() * sizeof(Ch));
368
+ next+= GetQueryStringLength();
369
+ *next = '\0';
370
+ }
371
+
372
+ // Reconstitute uri
373
+ void SetUri() {
374
+ Ch* next = uri_;
375
+ std::memcpy(next, base_, GetBaseStringLength() * sizeof(Ch));
376
+ next+= GetBaseStringLength();
377
+ std::memcpy(next, frag_, GetFragStringLength() * sizeof(Ch));
378
+ next+= GetFragStringLength();
379
+ *next = '\0';
380
+ }
381
+
382
+ // Copy a part from one GenericUri to another
383
+ // Return the pointer to the next part to be copied to
384
+ Ch* CopyPart(Ch* to, Ch* from, std::size_t len) {
385
+ RAPIDJSON_ASSERT(to != 0);
386
+ RAPIDJSON_ASSERT(from != 0);
387
+ std::memcpy(to, from, len * sizeof(Ch));
388
+ to[len] = '\0';
389
+ Ch* next = to + len + 1;
390
+ return next;
391
+ }
392
+
393
+ // Remove . and .. segments from the path_ member.
394
+ // https://tools.ietf.org/html/rfc3986
395
+ // This is done in place as we are only removing segments.
396
+ void RemoveDotSegments() {
397
+ std::size_t pathlen = GetPathStringLength();
398
+ std::size_t pathpos = 0; // Position in path_
399
+ std::size_t newpos = 0; // Position in new path_
400
+
401
+ // Loop through each segment in original path_
402
+ while (pathpos < pathlen) {
403
+ // Get next segment, bounded by '/' or end
404
+ size_t slashpos = 0;
405
+ while ((pathpos + slashpos) < pathlen) {
406
+ if (path_[pathpos + slashpos] == '/') break;
407
+ slashpos++;
408
+ }
409
+ // Check for .. and . segments
410
+ if (slashpos == 2 && path_[pathpos] == '.' && path_[pathpos + 1] == '.') {
411
+ // Backup a .. segment in the new path_
412
+ // We expect to find a previously added slash at the end or nothing
413
+ RAPIDJSON_ASSERT(newpos == 0 || path_[newpos - 1] == '/');
414
+ size_t lastslashpos = newpos;
415
+ // Make sure we don't go beyond the start segment
416
+ if (lastslashpos > 1) {
417
+ // Find the next to last slash and back up to it
418
+ lastslashpos--;
419
+ while (lastslashpos > 0) {
420
+ if (path_[lastslashpos - 1] == '/') break;
421
+ lastslashpos--;
422
+ }
423
+ // Set the new path_ position
424
+ newpos = lastslashpos;
425
+ }
426
+ } else if (slashpos == 1 && path_[pathpos] == '.') {
427
+ // Discard . segment, leaves new path_ unchanged
428
+ } else {
429
+ // Move any other kind of segment to the new path_
430
+ RAPIDJSON_ASSERT(newpos <= pathpos);
431
+ std::memmove(&path_[newpos], &path_[pathpos], slashpos * sizeof(Ch));
432
+ newpos += slashpos;
433
+ // Add slash if not at end
434
+ if ((pathpos + slashpos) < pathlen) {
435
+ path_[newpos] = '/';
436
+ newpos++;
437
+ }
438
+ }
439
+ // Move to next segment
440
+ pathpos += slashpos + 1;
441
+ }
442
+ path_[newpos] = '\0';
443
+ }
444
+
445
+ Ch* uri_; // Everything
446
+ Ch* base_; // Everything except fragment
447
+ Ch* scheme_; // Includes the :
448
+ Ch* auth_; // Includes the //
449
+ Ch* path_; // Absolute if starts with /
450
+ Ch* query_; // Includes the ?
451
+ Ch* frag_; // Includes the #
452
+
453
+ Allocator* allocator_; //!< The current allocator. It is either user-supplied or equal to ownAllocator_.
454
+ Allocator* ownAllocator_; //!< Allocator owned by this Uri.
455
+ };
456
+
457
+ //! GenericUri for Value (UTF-8, default allocator).
458
+ typedef GenericUri<Value> Uri;
459
+
460
+ RAPIDJSON_NAMESPACE_END
461
+
462
+ #if defined(__clang__)
463
+ RAPIDJSON_DIAG_POP
464
+ #endif
465
+
466
+ #endif // RAPIDJSON_URI_H_
@@ -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
@@ -283,6 +283,8 @@ public:
283
283
  os_->Flush();
284
284
  }
285
285
 
286
+ static const size_t kDefaultLevelDepth = 32;
287
+
286
288
  protected:
287
289
  //! Information for each nested level
288
290
  struct Level {
@@ -291,8 +293,6 @@ protected:
291
293
  bool inArray; //!< true if in array, otherwise in object
292
294
  };
293
295
 
294
- static const size_t kDefaultLevelDepth = 32;
295
-
296
296
  bool WriteNull() {
297
297
  PutReserve(*os_, 4);
298
298
  PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l'); return true;
@@ -6,7 +6,7 @@
6
6
 
7
7
  Tencent is pleased to support the open source community by making RapidJSON available.
8
8
 
9
- Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
9
+ Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
10
10
 
11
11
  * [RapidJSON GitHub](https://github.com/Tencent/rapidjson/)
12
12
  * RapidJSON Documentation
@@ -196,7 +196,7 @@ You can copy and paste the license summary from below.
196
196
  ```
197
197
  Tencent is pleased to support the open source community by making RapidJSON available.
198
198
 
199
- Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
199
+ Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
200
200
 
201
201
  Licensed under the MIT License (the "License"); you may not use this file except
202
202
  in compliance with the License. You may obtain a copy of the License at
@@ -207,4 +207,4 @@ Unless required by applicable law or agreed to in writing, software distributed
207
207
  under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
208
208
  CONDITIONS OF ANY KIND, either express or implied. See the License for the
209
209
  specific language governing permissions and limitations under the License.
210
- ```
210
+ ```
@@ -6,7 +6,7 @@
6
6
 
7
7
  Tencent is pleased to support the open source community by making RapidJSON available.
8
8
 
9
- Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
9
+ Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
10
10
 
11
11
  * [RapidJSON GitHub](https://github.com/Tencent/rapidjson/)
12
12
  * RapidJSON 文档
@@ -149,4 +149,4 @@ int main() {
149
149
  * [prettyauto](https://github.com/Tencent/rapidjson/blob/master/example/prettyauto/prettyauto.cpp): [pretty](https://github.com/Tencent/rapidjson/blob/master/example/pretty/pretty.cpp) 的修改版本,可自动处理任何 UTF 编码的 JSON。
150
150
  * [parsebyparts](https://github.com/Tencent/rapidjson/blob/master/example/parsebyparts/parsebyparts.cpp): 这例子中的 `AsyncDocumentParser` 类使用 C++ 线程来逐段解析 JSON。
151
151
  * [filterkey](https://github.com/Tencent/rapidjson/blob/master/example/filterkey/filterkey.cpp): 移取使用者指定的键值的命令行工具。
152
- * [filterkeydom](https://github.com/Tencent/rapidjson/blob/master/example/filterkey/filterkey.cpp): 如上的工具,但展示如何使用生成器(generator)去填充一个 `Document`。
152
+ * [filterkeydom](https://github.com/Tencent/rapidjson/blob/master/example/filterkey/filterkey.cpp): 如上的工具,但展示如何使用生成器(generator)去填充一个 `Document`。
@@ -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
@@ -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
@@ -130,7 +130,8 @@ public:
130
130
  "integers.json",
131
131
  "mixed.json",
132
132
  "nulls.json",
133
- "paragraphs.json"
133
+ "paragraphs.json",
134
+ "alotofkeys.json"
134
135
  };
135
136
 
136
137
  for (size_t j = 0; j < sizeof(typesfilenames) / sizeof(typesfilenames[0]); j++) {
@@ -158,7 +159,7 @@ public:
158
159
  free(whitespace_);
159
160
  json_ = 0;
160
161
  whitespace_ = 0;
161
- for (size_t i = 0; i < 7; i++) {
162
+ for (size_t i = 0; i < 8; i++) {
162
163
  free(types_[i]);
163
164
  types_[i] = 0;
164
165
  }
@@ -174,8 +175,8 @@ protected:
174
175
  size_t length_;
175
176
  char *whitespace_;
176
177
  size_t whitespace_length_;
177
- char *types_[7];
178
- size_t typesLength_[7];
178
+ char *types_[8];
179
+ size_t typesLength_[8];
179
180
 
180
181
  static const size_t kTrialCount = 1000;
181
182
  };
@@ -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
@@ -26,6 +26,7 @@
26
26
  #include "rapidjson/memorystream.h"
27
27
 
28
28
  #include <fstream>
29
+ #include <vector>
29
30
 
30
31
  #ifdef RAPIDJSON_SSE2
31
32
  #define SIMD_SUFFIX(name) name##_SSE2
@@ -52,7 +53,7 @@ public:
52
53
  // Parse as a document
53
54
  EXPECT_FALSE(doc_.Parse(json_).HasParseError());
54
55
 
55
- for (size_t i = 0; i < 7; i++)
56
+ for (size_t i = 0; i < 8; i++)
56
57
  EXPECT_FALSE(typesDoc_[i].Parse(types_[i]).HasParseError());
57
58
  }
58
59
 
@@ -68,7 +69,7 @@ private:
68
69
  protected:
69
70
  char *temp_;
70
71
  Document doc_;
71
- Document typesDoc_[7];
72
+ Document typesDoc_[8];
72
73
  };
73
74
 
74
75
  TEST_F(RapidJson, SIMD_SUFFIX(ReaderParseInsitu_DummyHandler)) {
@@ -335,6 +336,23 @@ TEST_F(RapidJson, DocumentAccept) {
335
336
  }
336
337
  }
337
338
 
339
+ TEST_F(RapidJson, DocumentFind) {
340
+ typedef Document::ValueType ValueType;
341
+ typedef ValueType::ConstMemberIterator ConstMemberIterator;
342
+ const Document &doc = typesDoc_[7]; // alotofkeys.json
343
+ if (doc.IsObject()) {
344
+ std::vector<const ValueType*> keys;
345
+ for (ConstMemberIterator it = doc.MemberBegin(); it != doc.MemberEnd(); ++it) {
346
+ keys.push_back(&it->name);
347
+ }
348
+ for (size_t i = 0; i < kTrialCount; i++) {
349
+ for (size_t j = 0; j < keys.size(); j++) {
350
+ EXPECT_TRUE(doc.FindMember(*keys[j]) != doc.MemberEnd());
351
+ }
352
+ }
353
+ }
354
+ }
355
+
338
356
  struct NullStream {
339
357
  typedef char Ch;
340
358