rj_schema 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) 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/idandref.json +69 -0
  6. data/ext/rj_schema/rapidjson/doc/stream.md +7 -7
  7. data/ext/rj_schema/rapidjson/doc/stream.zh-cn.md +1 -1
  8. data/ext/rj_schema/rapidjson/doc/tutorial.md +15 -15
  9. data/ext/rj_schema/rapidjson/example/schemavalidator/schemavalidator.cpp +2 -0
  10. data/ext/rj_schema/rapidjson/example/traverseaspointer.cpp +39 -0
  11. data/ext/rj_schema/rapidjson/include/rapidjson/allocators.h +460 -52
  12. data/ext/rj_schema/rapidjson/include/rapidjson/document.h +350 -60
  13. data/ext/rj_schema/rapidjson/include/rapidjson/internal/strfunc.h +14 -0
  14. data/ext/rj_schema/rapidjson/include/rapidjson/pointer.h +68 -1
  15. data/ext/rj_schema/rapidjson/include/rapidjson/rapidjson.h +60 -11
  16. data/ext/rj_schema/rapidjson/include/rapidjson/schema.h +249 -102
  17. data/ext/rj_schema/rapidjson/include/rapidjson/uri.h +466 -0
  18. data/ext/rj_schema/rapidjson/test/perftest/perftest.h +5 -4
  19. data/ext/rj_schema/rapidjson/test/perftest/rapidjsontest.cpp +20 -2
  20. data/ext/rj_schema/rapidjson/test/unittest/CMakeLists.txt +2 -0
  21. data/ext/rj_schema/rapidjson/test/unittest/allocatorstest.cpp +193 -1
  22. data/ext/rj_schema/rapidjson/test/unittest/documenttest.cpp +2 -0
  23. data/ext/rj_schema/rapidjson/test/unittest/platformtest.cpp +40 -0
  24. data/ext/rj_schema/rapidjson/test/unittest/pointertest.cpp +62 -2
  25. data/ext/rj_schema/rapidjson/test/unittest/schematest.cpp +372 -7
  26. data/ext/rj_schema/rapidjson/test/unittest/uritest.cpp +718 -0
  27. data/ext/rj_schema/rapidjson/test/unittest/valuetest.cpp +12 -2
  28. data/ext/rj_schema/rj_schema.cpp +1 -1
  29. data/lib/rj_schema.rb +1 -1
  30. metadata +9 -3
@@ -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_