Arcane  v3.16.8.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
pointer.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2// Tencent is pleased to support the open source community by making RapidJSON available.
3//
4// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
5//
6// Licensed under the MIT License (the "License"); you may not use this file except
7// in compliance with the License. You may obtain a copy of the License at
8//
9// http://opensource.org/licenses/MIT
10//
11// Unless required by applicable law or agreed to in writing, software distributed
12// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
13// CONDITIONS OF ANY KIND, either express or implied. See the License for the
14// specific language governing permissions and limitations under the License.
15
16#ifndef RAPIDJSON_POINTER_H_
17#define RAPIDJSON_POINTER_H_
18
19#include "document.h"
20#include "uri.h"
21#include "internal/itoa.h"
22#include "error/error.h" // PointerParseErrorCode
23
24#ifdef __clang__
25RAPIDJSON_DIAG_PUSH
26RAPIDJSON_DIAG_OFF(switch-enum)
27#elif defined(_MSC_VER)
28RAPIDJSON_DIAG_PUSH
29RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
30#endif
31
32#if defined(RAPIDJSON_CPLUSPLUS) && RAPIDJSON_CPLUSPLUS >= 201703L
33#define RAPIDJSON_IF_CONSTEXPR if constexpr
34#else
35#define RAPIDJSON_IF_CONSTEXPR if
36#endif
37
39
40static const SizeType kPointerInvalidIndex = ~SizeType(0);
41
43// GenericPointer
44
46
74template <typename ValueType, typename Allocator = CrtAllocator>
76public:
77 typedef typename ValueType::EncodingType EncodingType;
78 typedef typename ValueType::Ch Ch;
80
81
83
100
102
103
106
108
113 Parse(source, internal::StrLen(source));
114 }
115
116#if RAPIDJSON_HAS_STDSTRING
118
123 explicit GenericPointer(const std::basic_string<Ch>& source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
124 Parse(source.c_str(), source.size());
125 }
126#endif
127
129
136 Parse(source, length);
137 }
138
140
161 GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
162
167
172
175 if (nameBuffer_) // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and tokens_ are not deallocated.
176 Allocator::Free(tokens_);
178 }
179
182 if (this != &rhs) {
183 // Do not delete ownAllcator
184 if (nameBuffer_)
185 Allocator::Free(tokens_);
186
190
191 if (rhs.nameBuffer_)
192 CopyFromRaw(rhs); // Normally parsed tokens.
193 else {
194 tokens_ = rhs.tokens_; // User supplied const tokens.
195 nameBuffer_ = 0;
196 }
197 }
198 return *this;
199 }
200
202
206 GenericPointer& Swap(GenericPointer& other) RAPIDJSON_NOEXCEPT {
207 internal::Swap(allocator_, other.allocator_);
208 internal::Swap(ownAllocator_, other.ownAllocator_);
209 internal::Swap(nameBuffer_, other.nameBuffer_);
210 internal::Swap(tokens_, other.tokens_);
211 internal::Swap(tokenCount_, other.tokenCount_);
212 internal::Swap(parseErrorOffset_, other.parseErrorOffset_);
213 internal::Swap(parseErrorCode_, other.parseErrorCode_);
214 return *this;
215 }
216
218
229 friend inline void swap(GenericPointer& a, GenericPointer& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
230
232
234
235
237
242 GenericPointer Append(const Token& token, Allocator* allocator = 0) const {
244 r.allocator_ = allocator;
245 Ch *p = r.CopyFromRaw(*this, 1, token.length + 1);
246 std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch));
247 r.tokens_[tokenCount_].name = p;
248 r.tokens_[tokenCount_].length = token.length;
249 r.tokens_[tokenCount_].index = token.index;
250 return r;
251 }
252
254
260 GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const {
261 Token token = { name, length, kPointerInvalidIndex };
262 return Append(token, allocator);
263 }
264
266
271 template <typename T>
272 RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >), (GenericPointer))
273 Append(T* name, Allocator* allocator = 0) const {
274 return Append(name, internal::StrLen(name), allocator);
275 }
276
277#if RAPIDJSON_HAS_STDSTRING
279
284 GenericPointer Append(const std::basic_string<Ch>& name, Allocator* allocator = 0) const {
285 return Append(name.c_str(), static_cast<SizeType>(name.size()), allocator);
286 }
287#endif
288
290
295 GenericPointer Append(SizeType index, Allocator* allocator = 0) const {
296 char buffer[21];
297 char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer);
298 SizeType length = static_cast<SizeType>(end - buffer);
299 buffer[length] = '\0';
300
301 RAPIDJSON_IF_CONSTEXPR (sizeof(Ch) == 1) {
302 Token token = { reinterpret_cast<Ch*>(buffer), length, index };
303 return Append(token, allocator);
304 }
305 else {
306 Ch name[21];
307 for (size_t i = 0; i <= length; i++)
308 name[i] = static_cast<Ch>(buffer[i]);
309 Token token = { name, length, index };
310 return Append(token, allocator);
311 }
312 }
313
315
320 GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const {
321 if (token.IsString())
322 return Append(token.GetString(), token.GetStringLength(), allocator);
323 else {
324 RAPIDJSON_ASSERT(token.IsUint64());
325 RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0));
326 return Append(static_cast<SizeType>(token.GetUint64()), allocator);
327 }
328 }
329
331
332
334 bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; }
335
337 size_t GetParseErrorOffset() const { return parseErrorOffset_; }
338
340 PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; }
341
343
345 Allocator& GetAllocator() { return *allocator_; }
346
348
349
351 const Token* GetTokens() const { return tokens_; }
352
354 size_t GetTokenCount() const { return tokenCount_; }
355
357
359
360
362
365 bool operator==(const GenericPointer& rhs) const {
366 if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_)
367 return false;
368
369 for (size_t i = 0; i < tokenCount_; i++) {
370 if (tokens_[i].index != rhs.tokens_[i].index ||
371 tokens_[i].length != rhs.tokens_[i].length ||
372 (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch)* tokens_[i].length) != 0))
373 {
374 return false;
375 }
376 }
377
378 return true;
379 }
380
382
385 bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }
386
388
391 bool operator<(const GenericPointer& rhs) const {
392 if (!IsValid())
393 return false;
394 if (!rhs.IsValid())
395 return true;
396
397 if (tokenCount_ != rhs.tokenCount_)
398 return tokenCount_ < rhs.tokenCount_;
399
400 for (size_t i = 0; i < tokenCount_; i++) {
401 if (tokens_[i].index != rhs.tokens_[i].index)
402 return tokens_[i].index < rhs.tokens_[i].index;
403
404 if (tokens_[i].length != rhs.tokens_[i].length)
405 return tokens_[i].length < rhs.tokens_[i].length;
406
407 if (int cmp = std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length))
408 return cmp < 0;
409 }
410
411 return false;
412 }
413
415
417
418
420
424 template<typename OutputStream>
425 bool Stringify(OutputStream& os) const {
426 return Stringify<false, OutputStream>(os);
427 }
428
430
434 template<typename OutputStream>
435 bool StringifyUriFragment(OutputStream& os) const {
436 return Stringify<true, OutputStream>(os);
437 }
438
440
442
443
445
459 ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const {
460 RAPIDJSON_ASSERT(IsValid());
461 ValueType* v = &root;
462 bool exist = true;
463 for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
464 if (v->IsArray() && t->name[0] == '-' && t->length == 1) {
465 v->PushBack(ValueType().Move(), allocator);
466 v = &((*v)[v->Size() - 1]);
467 exist = false;
468 }
469 else {
470 if (t->index == kPointerInvalidIndex) { // must be object name
471 if (!v->IsObject())
472 v->SetObject(); // Change to Object
473 }
474 else { // object name or array index
475 if (!v->IsArray() && !v->IsObject())
476 v->SetArray(); // Change to Array
477 }
478
479 if (v->IsArray()) {
480 if (t->index >= v->Size()) {
481 v->Reserve(t->index + 1, allocator);
482 while (t->index >= v->Size())
483 v->PushBack(ValueType().Move(), allocator);
484 exist = false;
485 }
486 v = &((*v)[t->index]);
487 }
488 else {
489 typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
490 if (m == v->MemberEnd()) {
491 v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
492 m = v->MemberEnd();
493 v = &(--m)->value; // Assumes AddMember() appends at the end
494 exist = false;
495 }
496 else
497 v = &m->value;
498 }
499 }
500 }
501
502 if (alreadyExist)
503 *alreadyExist = exist;
504
505 return *v;
506 }
507
509
514 template <typename stackAllocator>
515 ValueType& Create(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, bool* alreadyExist = 0) const {
516 return Create(document, document.GetAllocator(), alreadyExist);
517 }
518
520
522
523
525 // For use with JSON pointers into JSON schema documents.
541 UriType GetUri(ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0, Allocator* allocator = 0) const {
542 static const Ch kIdString[] = { 'i', 'd', '\0' };
543 static const ValueType kIdValue(kIdString, 2);
544 UriType base = UriType(rootUri, allocator);
545 RAPIDJSON_ASSERT(IsValid());
546 ValueType* v = &root;
547 for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
548 switch (v->GetType()) {
549 case kObjectType:
550 {
551 // See if we have an id, and if so resolve with the current base
552 typename ValueType::MemberIterator m = v->FindMember(kIdValue);
553 if (m != v->MemberEnd() && (m->value).IsString()) {
554 UriType here = UriType(m->value, allocator).Resolve(base, allocator);
555 base = here;
556 }
557 m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
558 if (m == v->MemberEnd())
559 break;
560 v = &m->value;
561 }
562 continue;
563 case kArrayType:
564 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
565 break;
566 v = &((*v)[t->index]);
567 continue;
568 default:
569 break;
570 }
571
572 // Error: unresolved token
573 if (unresolvedTokenIndex)
574 *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
575 return UriType(allocator);
576 }
577 return base;
578 }
579
580 UriType GetUri(const ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0, Allocator* allocator = 0) const {
581 return GetUri(const_cast<ValueType&>(root), rootUri, unresolvedTokenIndex, allocator);
582 }
583
584
586
587
589
602 ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const {
603 RAPIDJSON_ASSERT(IsValid());
604 ValueType* v = &root;
605 for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
606 switch (v->GetType()) {
607 case kObjectType:
608 {
609 typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
610 if (m == v->MemberEnd())
611 break;
612 v = &m->value;
613 }
614 continue;
615 case kArrayType:
616 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
617 break;
618 v = &((*v)[t->index]);
619 continue;
620 default:
621 break;
622 }
623
624 // Error: unresolved token
625 if (unresolvedTokenIndex)
626 *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
627 return 0;
628 }
629 return v;
630 }
631
633
637 const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const {
638 return Get(const_cast<ValueType&>(root), unresolvedTokenIndex);
639 }
640
642
644
645
647
656 ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const {
657 bool alreadyExist;
658 ValueType& v = Create(root, allocator, &alreadyExist);
659 return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
660 }
661
663 ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const {
664 bool alreadyExist;
665 ValueType& v = Create(root, allocator, &alreadyExist);
666 return alreadyExist ? v : v.SetString(defaultValue, allocator);
667 }
668
669#if RAPIDJSON_HAS_STDSTRING
671 ValueType& GetWithDefault(ValueType& root, const std::basic_string<Ch>& defaultValue, typename ValueType::AllocatorType& allocator) const {
672 bool alreadyExist;
673 ValueType& v = Create(root, allocator, &alreadyExist);
674 return alreadyExist ? v : v.SetString(defaultValue, allocator);
675 }
676#endif
677
679
682 template <typename T>
683 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
684 GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator) const {
685 return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);
686 }
687
689 template <typename stackAllocator>
690 ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& defaultValue) const {
691 return GetWithDefault(document, defaultValue, document.GetAllocator());
692 }
693
695 template <typename stackAllocator>
696 ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* defaultValue) const {
697 return GetWithDefault(document, defaultValue, document.GetAllocator());
698 }
699
700#if RAPIDJSON_HAS_STDSTRING
702 template <typename stackAllocator>
703 ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& defaultValue) const {
704 return GetWithDefault(document, defaultValue, document.GetAllocator());
705 }
706#endif
707
709
712 template <typename T, typename stackAllocator>
713 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
714 GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T defaultValue) const {
715 return GetWithDefault(document, defaultValue, document.GetAllocator());
716 }
717
719
721
722
724
733 ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
734 return Create(root, allocator) = value;
735 }
736
738 ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const {
739 return Create(root, allocator).CopyFrom(value, allocator);
740 }
741
743 ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const {
744 return Create(root, allocator) = ValueType(value, allocator).Move();
745 }
746
747#if RAPIDJSON_HAS_STDSTRING
749 ValueType& Set(ValueType& root, const std::basic_string<Ch>& value, typename ValueType::AllocatorType& allocator) const {
750 return Create(root, allocator) = ValueType(value, allocator).Move();
751 }
752#endif
753
755
758 template <typename T>
759 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
760 Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const {
761 return Create(root, allocator) = ValueType(value).Move();
762 }
763
765 template <typename stackAllocator>
766 ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const {
767 return Create(document) = value;
768 }
769
771 template <typename stackAllocator>
772 ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& value) const {
773 return Create(document).CopyFrom(value, document.GetAllocator());
774 }
775
777 template <typename stackAllocator>
778 ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* value) const {
779 return Create(document) = ValueType(value, document.GetAllocator()).Move();
780 }
781
782#if RAPIDJSON_HAS_STDSTRING
784 template <typename stackAllocator>
785 ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& value) const {
786 return Create(document) = ValueType(value, document.GetAllocator()).Move();
787 }
788#endif
789
791
794 template <typename T, typename stackAllocator>
795 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
796 Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T value) const {
797 return Create(document) = value;
798 }
799
801
803
804
806
815 ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
816 return Create(root, allocator).Swap(value);
817 }
818
820 template <typename stackAllocator>
821 ValueType& Swap(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const {
822 return Create(document).Swap(value);
823 }
824
826
828
834 bool Erase(ValueType& root) const {
835 RAPIDJSON_ASSERT(IsValid());
836 if (tokenCount_ == 0) // Cannot erase the root
837 return false;
838
839 ValueType* v = &root;
840 const Token* last = tokens_ + (tokenCount_ - 1);
841 for (const Token *t = tokens_; t != last; ++t) {
842 switch (v->GetType()) {
843 case kObjectType:
844 {
845 typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
846 if (m == v->MemberEnd())
847 return false;
848 v = &m->value;
849 }
850 break;
851 case kArrayType:
852 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
853 return false;
854 v = &((*v)[t->index]);
855 break;
856 default:
857 return false;
858 }
859 }
860
861 switch (v->GetType()) {
862 case kObjectType:
863 return v->EraseMember(GenericStringRef<Ch>(last->name, last->length));
864 case kArrayType:
865 if (last->index == kPointerInvalidIndex || last->index >= v->Size())
866 return false;
867 v->Erase(v->Begin() + last->index);
868 return true;
869 default:
870 return false;
871 }
872 }
873
874private:
876
882 Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0) {
883 if (!allocator_) // allocator is independently owned.
884 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
885
886 size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens
887 for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)
888 nameBufferSize += t->length;
889
890 tokenCount_ = rhs.tokenCount_ + extraToken;
891 tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch)));
892 nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
893 if (rhs.tokenCount_ > 0) {
894 std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token));
895 }
896 if (nameBufferSize > 0) {
897 std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
898 }
899
900 // The names of each token point to a string in the nameBuffer_. The
901 // previous memcpy copied over string pointers into the rhs.nameBuffer_,
902 // but they should point to the strings in the new nameBuffer_.
903 for (size_t i = 0; i < rhs.tokenCount_; ++i) {
904 // The offset between the string address and the name buffer should
905 // still be constant, so we can just get this offset and set each new
906 // token name according the new buffer start + the known offset.
907 std::ptrdiff_t name_offset = rhs.tokens_[i].name - rhs.nameBuffer_;
908 tokens_[i].name = nameBuffer_ + name_offset;
909 }
910
911 return nameBuffer_ + nameBufferSize;
912 }
913
915
919 bool NeedPercentEncode(Ch c) const {
920 return !((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~');
921 }
922
924#ifndef __clang__ // -Wdocumentation
930#endif
931 void Parse(const Ch* source, size_t length) {
932 RAPIDJSON_ASSERT(source != NULL);
935
936 // Create own allocator if user did not supply.
937 if (!allocator_)
938 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
939
940 // Count number of '/' as tokenCount
941 tokenCount_ = 0;
942 for (const Ch* s = source; s != source + length; s++)
943 if (*s == '/')
944 tokenCount_++;
945
946 Token* token = tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch)));
947 Ch* name = nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
948 size_t i = 0;
949
950 // Detect if it is a URI fragment
951 bool uriFragment = false;
952 if (source[i] == '#') {
953 uriFragment = true;
954 i++;
955 }
956
957 if (i != length && source[i] != '/') {
959 goto error;
960 }
961
962 while (i < length) {
963 RAPIDJSON_ASSERT(source[i] == '/');
964 i++; // consumes '/'
965
966 token->name = name;
967 bool isNumber = true;
968
969 while (i < length && source[i] != '/') {
970 Ch c = source[i];
971 if (uriFragment) {
972 // Decoding percent-encoding for URI fragment
973 if (c == '%') {
974 PercentDecodeStream is(&source[i], source + length);
975 GenericInsituStringStream<EncodingType> os(name);
976 Ch* begin = os.PutBegin();
977 if (!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid()) {
979 goto error;
980 }
981 size_t len = os.PutEnd(begin);
982 i += is.Tell() - 1;
983 if (len == 1)
984 c = *name;
985 else {
986 name += len;
987 isNumber = false;
988 i++;
989 continue;
990 }
991 }
992 else if (NeedPercentEncode(c)) {
994 goto error;
995 }
996 }
997
998 i++;
999
1000 // Escaping "~0" -> '~', "~1" -> '/'
1001 if (c == '~') {
1002 if (i < length) {
1003 c = source[i];
1004 if (c == '0') c = '~';
1005 else if (c == '1') c = '/';
1006 else {
1008 goto error;
1009 }
1010 i++;
1011 }
1012 else {
1014 goto error;
1015 }
1016 }
1017
1018 // First check for index: all of characters are digit
1019 if (c < '0' || c > '9')
1020 isNumber = false;
1021
1022 *name++ = c;
1023 }
1024 token->length = static_cast<SizeType>(name - token->name);
1025 if (token->length == 0)
1026 isNumber = false;
1027 *name++ = '\0'; // Null terminator
1028
1029 // Second check for index: more than one digit cannot have leading zero
1030 if (isNumber && token->length > 1 && token->name[0] == '0')
1031 isNumber = false;
1032
1033 // String to SizeType conversion
1034 SizeType n = 0;
1035 if (isNumber) {
1036 for (size_t j = 0; j < token->length; j++) {
1037 SizeType m = n * 10 + static_cast<SizeType>(token->name[j] - '0');
1038 if (m < n) { // overflow detection
1039 isNumber = false;
1040 break;
1041 }
1042 n = m;
1043 }
1044 }
1045
1046 token->index = isNumber ? n : kPointerInvalidIndex;
1047 token++;
1048 }
1049
1050 RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer
1052 return;
1053
1054 error:
1055 Allocator::Free(tokens_);
1056 nameBuffer_ = 0;
1057 tokens_ = 0;
1058 tokenCount_ = 0;
1060 return;
1061 }
1062
1064
1069 template<bool uriFragment, typename OutputStream>
1070 bool Stringify(OutputStream& os) const {
1071 RAPIDJSON_ASSERT(IsValid());
1072
1073 if (uriFragment)
1074 os.Put('#');
1075
1076 for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
1077 os.Put('/');
1078 for (size_t j = 0; j < t->length; j++) {
1079 Ch c = t->name[j];
1080 if (c == '~') {
1081 os.Put('~');
1082 os.Put('0');
1083 }
1084 else if (c == '/') {
1085 os.Put('~');
1086 os.Put('1');
1087 }
1088 else if (uriFragment && NeedPercentEncode(c)) {
1089 // Transcode to UTF8 sequence
1090 GenericStringStream<typename ValueType::EncodingType> source(&t->name[j]);
1092 if (!Transcoder<EncodingType, UTF8<> >().Validate(source, target))
1093 return false;
1094 j += source.Tell() - 1;
1095 }
1096 else
1097 os.Put(c);
1098 }
1099 }
1100 return true;
1101 }
1102
1104
1109 class PercentDecodeStream {
1110 public:
1111 typedef typename ValueType::Ch Ch;
1112
1114
1118 PercentDecodeStream(const Ch* source, const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {}
1119
1120 Ch Take() {
1121 if (*src_ != '%' || src_ + 3 > end_) { // %XY triplet
1122 valid_ = false;
1123 return 0;
1124 }
1125 src_++;
1126 Ch c = 0;
1127 for (int j = 0; j < 2; j++) {
1128 c = static_cast<Ch>(c << 4);
1129 Ch h = *src_;
1130 if (h >= '0' && h <= '9') c = static_cast<Ch>(c + h - '0');
1131 else if (h >= 'A' && h <= 'F') c = static_cast<Ch>(c + h - 'A' + 10);
1132 else if (h >= 'a' && h <= 'f') c = static_cast<Ch>(c + h - 'a' + 10);
1133 else {
1134 valid_ = false;
1135 return 0;
1136 }
1137 src_++;
1138 }
1139 return c;
1140 }
1141
1142 size_t Tell() const { return static_cast<size_t>(src_ - head_); }
1143 bool IsValid() const { return valid_; }
1144
1145 private:
1146 const Ch* src_;
1147 const Ch* head_;
1148 const Ch* end_;
1149 bool valid_;
1150 };
1151
1153 template <typename OutputStream>
1154 class PercentEncodeStream {
1155 public:
1156 PercentEncodeStream(OutputStream& os) : os_(os) {}
1157 void Put(char c) { // UTF-8 must be byte
1158 unsigned char u = static_cast<unsigned char>(c);
1159 static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1160 os_.Put('%');
1161 os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u >> 4]));
1162 os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u & 15]));
1163 }
1164 private:
1165 OutputStream& os_;
1166 };
1167
1171 Token* tokens_;
1175};
1176
1178typedef GenericPointer<Value> Pointer;
1179
1181
1182
1184
1185template <typename T>
1186typename T::ValueType& CreateValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::AllocatorType& a) {
1187 return pointer.Create(root, a);
1188}
1189
1190template <typename T, typename CharType, size_t N>
1191typename T::ValueType& CreateValueByPointer(T& root, const CharType(&source)[N], typename T::AllocatorType& a) {
1192 return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a);
1193}
1194
1195// No allocator parameter
1196
1197template <typename DocumentType>
1198typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer) {
1199 return pointer.Create(document);
1200}
1201
1202template <typename DocumentType, typename CharType, size_t N>
1203typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const CharType(&source)[N]) {
1204 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document);
1205}
1206
1208
1209template <typename T>
1210typename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
1211 return pointer.Get(root, unresolvedTokenIndex);
1212}
1213
1214template <typename T>
1215const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
1216 return pointer.Get(root, unresolvedTokenIndex);
1217}
1218
1219template <typename T, typename CharType, size_t N>
1220typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) {
1221 return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1222}
1223
1224template <typename T, typename CharType, size_t N>
1225const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) {
1226 return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1227}
1228
1230
1231template <typename T>
1232typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
1233 return pointer.GetWithDefault(root, defaultValue, a);
1234}
1235
1236template <typename T>
1237typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* defaultValue, typename T::AllocatorType& a) {
1238 return pointer.GetWithDefault(root, defaultValue, a);
1239}
1240
1241#if RAPIDJSON_HAS_STDSTRING
1242template <typename T>
1243typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {
1244 return pointer.GetWithDefault(root, defaultValue, a);
1245}
1246#endif
1247
1248template <typename T, typename T2>
1249RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1250GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 defaultValue, typename T::AllocatorType& a) {
1251 return pointer.GetWithDefault(root, defaultValue, a);
1252}
1253
1254template <typename T, typename CharType, size_t N>
1255typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
1256 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1257}
1258
1259template <typename T, typename CharType, size_t N>
1260typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::Ch* defaultValue, typename T::AllocatorType& a) {
1261 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1262}
1263
1264#if RAPIDJSON_HAS_STDSTRING
1265template <typename T, typename CharType, size_t N>
1266typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {
1267 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1268}
1269#endif
1270
1271template <typename T, typename CharType, size_t N, typename T2>
1272RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1273GetValueByPointerWithDefault(T& root, const CharType(&source)[N], T2 defaultValue, typename T::AllocatorType& a) {
1274 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1275}
1276
1277// No allocator parameter
1278
1279template <typename DocumentType>
1280typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& defaultValue) {
1281 return pointer.GetWithDefault(document, defaultValue);
1282}
1283
1284template <typename DocumentType>
1285typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* defaultValue) {
1286 return pointer.GetWithDefault(document, defaultValue);
1287}
1288
1289#if RAPIDJSON_HAS_STDSTRING
1290template <typename DocumentType>
1291typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1292 return pointer.GetWithDefault(document, defaultValue);
1293}
1294#endif
1295
1296template <typename DocumentType, typename T2>
1297RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1298GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 defaultValue) {
1299 return pointer.GetWithDefault(document, defaultValue);
1300}
1301
1302template <typename DocumentType, typename CharType, size_t N>
1303typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& defaultValue) {
1304 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1305}
1306
1307template <typename DocumentType, typename CharType, size_t N>
1308typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* defaultValue) {
1309 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1310}
1311
1312#if RAPIDJSON_HAS_STDSTRING
1313template <typename DocumentType, typename CharType, size_t N>
1314typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1315 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1316}
1317#endif
1318
1319template <typename DocumentType, typename CharType, size_t N, typename T2>
1320RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1321GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) {
1322 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1323}
1324
1326
1327template <typename T>
1328typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
1329 return pointer.Set(root, value, a);
1330}
1331
1332template <typename T>
1333typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& value, typename T::AllocatorType& a) {
1334 return pointer.Set(root, value, a);
1335}
1336
1337template <typename T>
1338typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* value, typename T::AllocatorType& a) {
1339 return pointer.Set(root, value, a);
1340}
1341
1342#if RAPIDJSON_HAS_STDSTRING
1343template <typename T>
1344typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {
1345 return pointer.Set(root, value, a);
1346}
1347#endif
1348
1349template <typename T, typename T2>
1350RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1351SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 value, typename T::AllocatorType& a) {
1352 return pointer.Set(root, value, a);
1353}
1354
1355template <typename T, typename CharType, size_t N>
1356typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
1357 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1358}
1359
1360template <typename T, typename CharType, size_t N>
1361typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::ValueType& value, typename T::AllocatorType& a) {
1362 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1363}
1364
1365template <typename T, typename CharType, size_t N>
1366typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::Ch* value, typename T::AllocatorType& a) {
1367 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1368}
1369
1370#if RAPIDJSON_HAS_STDSTRING
1371template <typename T, typename CharType, size_t N>
1372typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {
1373 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1374}
1375#endif
1376
1377template <typename T, typename CharType, size_t N, typename T2>
1378RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1379SetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) {
1380 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1381}
1382
1383// No allocator parameter
1384
1385template <typename DocumentType>
1386typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
1387 return pointer.Set(document, value);
1388}
1389
1390template <typename DocumentType>
1391typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& value) {
1392 return pointer.Set(document, value);
1393}
1394
1395template <typename DocumentType>
1396typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* value) {
1397 return pointer.Set(document, value);
1398}
1399
1400#if RAPIDJSON_HAS_STDSTRING
1401template <typename DocumentType>
1402typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& value) {
1403 return pointer.Set(document, value);
1404}
1405#endif
1406
1407template <typename DocumentType, typename T2>
1408RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1409SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 value) {
1410 return pointer.Set(document, value);
1411}
1412
1413template <typename DocumentType, typename CharType, size_t N>
1414typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
1415 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1416}
1417
1418template <typename DocumentType, typename CharType, size_t N>
1419typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& value) {
1420 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1421}
1422
1423template <typename DocumentType, typename CharType, size_t N>
1424typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* value) {
1425 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1426}
1427
1428#if RAPIDJSON_HAS_STDSTRING
1429template <typename DocumentType, typename CharType, size_t N>
1430typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& value) {
1431 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1432}
1433#endif
1434
1435template <typename DocumentType, typename CharType, size_t N, typename T2>
1436RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1437SetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) {
1438 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1439}
1440
1442
1443template <typename T>
1444typename T::ValueType& SwapValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
1445 return pointer.Swap(root, value, a);
1446}
1447
1448template <typename T, typename CharType, size_t N>
1449typename T::ValueType& SwapValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
1450 return GenericPointer<typename T::ValueType>(source, N - 1).Swap(root, value, a);
1451}
1452
1453template <typename DocumentType>
1454typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
1455 return pointer.Swap(document, value);
1456}
1457
1458template <typename DocumentType, typename CharType, size_t N>
1459typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
1460 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Swap(document, value);
1461}
1462
1464
1465template <typename T>
1466bool EraseValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer) {
1467 return pointer.Erase(root);
1468}
1469
1470template <typename T, typename CharType, size_t N>
1471bool EraseValueByPointer(T& root, const CharType(&source)[N]) {
1472 return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root);
1473}
1474
1476
1478
1479#if defined(__clang__) || defined(_MSC_VER)
1480RAPIDJSON_DIAG_POP
1481#endif
1482
1483#endif // RAPIDJSON_POINTER_H_
Allocator & GetAllocator()
Get the allocator of this document.
Definition document.h:2797
A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence.
Definition pointer.h:1154
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition pointer.h:75
friend void swap(GenericPointer &a, GenericPointer &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition pointer.h:229
GenericPointer(const GenericPointer &rhs, Allocator *allocator)
Copy constructor.
Definition pointer.h:169
GenericPointer(const Ch *source, Allocator *allocator=0)
Constructor that parses a string or URI fragment representation.
Definition pointer.h:112
Value::EncodingType EncodingType
Definition pointer.h:77
GenericPointer(const Token *tokens, size_t tokenCount)
Constructor with user-supplied tokens.
Definition pointer.h:161
GenericPointer(Allocator *allocator=0)
Default constructor.
Definition pointer.h:105
GenericPointer(const GenericPointer &rhs)
Copy constructor.
Definition pointer.h:164
PointerParseErrorCode parseErrorCode_
Definition pointer.h:1174
GenericPointer(const Ch *source, size_t length, Allocator *allocator=0)
Constructor that parses a string or URI fragment representation, with length of the source string.
Definition pointer.h:135
GenericPointer Append(const Ch *name, SizeType length, Allocator *allocator=0) const
Append a name token with length, and return a new Pointer.
Definition pointer.h:260
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
Definition pointer.h:242
RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr< internal::IsSame< typename internal::RemoveConst< T >::Type, Ch > >),(GenericPointer)) Append(T *name
Append a name token without length, and return a new Pointer.
~GenericPointer()
Destructor.
Definition pointer.h:174
GenericPointer & operator=(const GenericPointer &rhs)
Assignment operator.
Definition pointer.h:181
GenericPointer & Swap(GenericPointer &other) RAPIDJSON_NOEXCEPT
Swap the content of this pointer with an other.
Definition pointer.h:206
Concept for allocating, resizing and freeing memory block.
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition rapidjson.h:438
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition rapidjson.h:122
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition rapidjson.h:125
PointerParseErrorCode
Error code of JSON pointer parsing.
Definition error.h:258
@ kPointerParseErrorInvalidEscape
Invalid escape.
Definition error.h:262
@ kPointerParseErrorTokenMustBeginWithSolidus
A token must begin with a '/'.
Definition error.h:261
@ kPointerParseErrorNone
The parse is successful.
Definition error.h:259
@ kPointerParseErrorCharacterMustPercentEncode
A character must percent encoded in URI fragment.
Definition error.h:264
@ kPointerParseErrorInvalidPercentEncoding
Invalid percent encoding in URI fragment.
Definition error.h:263
Integer len(const char *s)
Retourne la longueur de la chaîne s.
bool operator<(const Item &item1, const Item &item2)
Compare deux entités.
Definition Item.h:551
@ kObjectType
object
Definition rapidjson.h:734
@ kArrayType
array
Definition rapidjson.h:735
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition rapidjson.h:717
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition rapidjson.h:416
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition rapidjson.h:713
A token is the basic units of internal representation.
Definition pointer.h:95
SizeType index
A valid array index, if it is not equal to kPointerInvalidIndex.
Definition pointer.h:98
SizeType length
Length of the name.
Definition pointer.h:97
const Ch * name
Name of the token. It has null character at the end but it can contain null character.
Definition pointer.h:96