pointer.h Source File

pointer.h Source File#

Composable Kernel: pointer.h Source File
pointer.h
Go to the documentation of this file.
1// Tencent is pleased to support the open source community by making RapidJSON available.
2//
3// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
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_POINTER_H_
16#define RAPIDJSON_POINTER_H_
17
18#include "document.h"
19#include "uri.h"
20#include "internal/itoa.h"
21#include "error/error.h" // PointerParseErrorCode
22
23#ifdef __clang__
24RAPIDJSON_DIAG_PUSH
25RAPIDJSON_DIAG_OFF(switch - enum)
26#elif defined(_MSC_VER)
27RAPIDJSON_DIAG_PUSH
28RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
29#endif
30
31#if defined(RAPIDJSON_CPLUSPLUS) && RAPIDJSON_CPLUSPLUS >= 201703L
32#define RAPIDJSON_IF_CONSTEXPR if constexpr
33#else
34#define RAPIDJSON_IF_CONSTEXPR if
35#endif
36
38
39static const SizeType kPointerInvalidIndex =
40 ~SizeType(0);
41
43// GenericPointer
44
46
74template <typename ValueType, typename Allocator = CrtAllocator>
76{
77 public:
78 typedef typename ValueType::EncodingType EncodingType;
79 typedef typename ValueType::Ch Ch;
81
83
95 struct Token
96 {
97 const Ch* name;
101 };
102
104
105
117
119
135
136#if RAPIDJSON_HAS_STDSTRING
138
144 explicit GenericPointer(const std::basic_string<Ch>& source, Allocator* allocator = 0)
147 nameBuffer_(),
148 tokens_(),
149 tokenCount_(),
152 {
153 Parse(source.c_str(), source.size());
154 }
155#endif
156
159
165 GenericPointer(const Ch* source, size_t length, Allocator* allocator = 0)
168 nameBuffer_(),
169 tokens_(),
170 tokenCount_(),
173 {
174 Parse(source, length);
175 }
176
178
199 GenericPointer(const Token* tokens, size_t tokenCount)
200 : allocator_(),
202 nameBuffer_(),
203 tokens_(const_cast<Token*>(tokens)),
204 tokenCount_(tokenCount),
207 {
208 }
209
212 : allocator_(),
214 nameBuffer_(),
215 tokens_(),
216 tokenCount_(),
219 {
220 *this = rhs;
221 }
222
235
238 {
239 if(nameBuffer_) // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and
240 // tokens_ are not deallocated.
241 Allocator::Free(tokens_);
243 }
244
247 {
248 if(this != &rhs)
249 {
250 // Do not delete ownAllcator
251 if(nameBuffer_)
252 Allocator::Free(tokens_);
253
257
258 if(rhs.nameBuffer_)
259 CopyFromRaw(rhs); // Normally parsed tokens.
260 else
261 {
262 tokens_ = rhs.tokens_; // User supplied const tokens.
263 nameBuffer_ = 0;
264 }
265 }
266 return *this;
267 }
268
270
274 GenericPointer& Swap(GenericPointer& other) RAPIDJSON_NOEXCEPT
275 {
276 internal::Swap(allocator_, other.allocator_);
277 internal::Swap(ownAllocator_, other.ownAllocator_);
278 internal::Swap(nameBuffer_, other.nameBuffer_);
279 internal::Swap(tokens_, other.tokens_);
280 internal::Swap(tokenCount_, other.tokenCount_);
281 internal::Swap(parseErrorOffset_, other.parseErrorOffset_);
282 internal::Swap(parseErrorCode_, other.parseErrorCode_);
283 return *this;
284 }
285
287
296 friend inline void swap(GenericPointer& a, GenericPointer& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
297
299
301
302
304
309 GenericPointer Append(const Token& token, Allocator* allocator = 0) const
310 {
313 Ch* p = r.CopyFromRaw(*this, 1, token.length + 1);
314 std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch));
315 r.tokens_[tokenCount_].name = p;
316 r.tokens_[tokenCount_].length = token.length;
317 r.tokens_[tokenCount_].index = token.index;
318 return r;
319 }
320
322
328 GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const
329 {
330 Token token = {name, length, kPointerInvalidIndex};
331 return Append(token, allocator);
332 }
333
335
340 template <typename T>
342 (internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch>>),
344 Append(T* name, Allocator* allocator = 0) const
345 {
346 return Append(name, internal::StrLen(name), allocator);
347 }
348
349#if RAPIDJSON_HAS_STDSTRING
351
356 GenericPointer Append(const std::basic_string<Ch>& name, Allocator* allocator = 0) const
357 {
358 return Append(name.c_str(), static_cast<SizeType>(name.size()), allocator);
359 }
360#endif
361
363
368 GenericPointer Append(SizeType index, Allocator* allocator = 0) const
369 {
370 char buffer[21];
371 char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer)
372 : internal::u64toa(index, buffer);
373 SizeType length = static_cast<SizeType>(end - buffer);
374 buffer[length] = '\0';
375
376 RAPIDJSON_IF_CONSTEXPR(sizeof(Ch) == 1)
377 {
378 Token token = {reinterpret_cast<Ch*>(buffer), length, index};
379 return Append(token, allocator);
380 }
381 else
382 {
383 Ch name[21];
384 for(size_t i = 0; i <= length; i++)
385 name[i] = static_cast<Ch>(buffer[i]);
386 Token token = {name, length, index};
387 return Append(token, allocator);
388 }
389 }
390
392
397 GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const
398 {
399 if(token.IsString())
400 return Append(token.GetString(), token.GetStringLength(), allocator);
401 else
402 {
403 RAPIDJSON_ASSERT(token.IsUint64());
404 RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0));
405 return Append(static_cast<SizeType>(token.GetUint64()), allocator);
406 }
407 }
408
410
411
413 bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; }
414
416 size_t GetParseErrorOffset() const { return parseErrorOffset_; }
417
419 PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; }
420
422
424 Allocator& GetAllocator() { return *allocator_; }
425
427
428
430 const Token* GetTokens() const { return tokens_; }
431
433 size_t GetTokenCount() const { return tokenCount_; }
434
436
438
439
441
444 bool operator==(const GenericPointer& rhs) const
445 {
446 if(!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_)
447 return false;
448
449 for(size_t i = 0; i < tokenCount_; i++)
450 {
451 if(tokens_[i].index != rhs.tokens_[i].index ||
452 tokens_[i].length != rhs.tokens_[i].length ||
453 (tokens_[i].length != 0 &&
454 std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length) !=
455 0))
456 {
457 return false;
458 }
459 }
460
461 return true;
462 }
463
465
468 bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }
469
471
474 bool operator<(const GenericPointer& rhs) const
475 {
476 if(!IsValid())
477 return false;
478 if(!rhs.IsValid())
479 return true;
480
481 if(tokenCount_ != rhs.tokenCount_)
482 return tokenCount_ < rhs.tokenCount_;
483
484 for(size_t i = 0; i < tokenCount_; i++)
485 {
486 if(tokens_[i].index != rhs.tokens_[i].index)
487 return tokens_[i].index < rhs.tokens_[i].index;
488
489 if(tokens_[i].length != rhs.tokens_[i].length)
490 return tokens_[i].length < rhs.tokens_[i].length;
491
492 if(int cmp = std::memcmp(
493 tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length))
494 return cmp < 0;
495 }
496
497 return false;
498 }
499
501
503
504
506
510 template <typename OutputStream>
511 bool Stringify(OutputStream& os) const
512 {
513 return Stringify<false, OutputStream>(os);
514 }
515
517
521 template <typename OutputStream>
522 bool StringifyUriFragment(OutputStream& os) const
523 {
524 return Stringify<true, OutputStream>(os);
525 }
526
528
530
531
533
548 ValueType& Create(ValueType& root,
549 typename ValueType::AllocatorType& allocator,
550 bool* alreadyExist = 0) const
551 {
552 RAPIDJSON_ASSERT(IsValid());
553 ValueType* v = &root;
554 bool exist = true;
555 for(const Token* t = tokens_; t != tokens_ + tokenCount_; ++t)
556 {
557 if(v->IsArray() && t->name[0] == '-' && t->length == 1)
558 {
559 v->PushBack(ValueType().Move(), allocator);
560 v = &((*v)[v->Size() - 1]);
561 exist = false;
562 }
563 else
564 {
565 if(t->index == kPointerInvalidIndex)
566 { // must be object name
567 if(!v->IsObject())
568 v->SetObject(); // Change to Object
569 }
570 else
571 { // object name or array index
572 if(!v->IsArray() && !v->IsObject())
573 v->SetArray(); // Change to Array
574 }
575
576 if(v->IsArray())
577 {
578 if(t->index >= v->Size())
579 {
580 v->Reserve(t->index + 1, allocator);
581 while(t->index >= v->Size())
582 v->PushBack(ValueType().Move(), allocator);
583 exist = false;
584 }
585 v = &((*v)[t->index]);
586 }
587 else
588 {
589 typename ValueType::MemberIterator m = v->FindMember(
590 GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
591 if(m == v->MemberEnd())
592 {
593 v->AddMember(ValueType(t->name, t->length, allocator).Move(),
594 ValueType().Move(),
595 allocator);
596 m = v->MemberEnd();
597 v = &(--m)->value; // Assumes AddMember() appends at the end
598 exist = false;
599 }
600 else
601 v = &m->value;
602 }
603 }
604 }
605
606 if(alreadyExist)
607 *alreadyExist = exist;
608
609 return *v;
610 }
611
613
618 template <typename stackAllocator>
619 ValueType& Create(
620 GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document,
621 bool* alreadyExist = 0) const
622 {
623 return Create(document, document.GetAllocator(), alreadyExist);
624 }
625
627
629
630
632 // For use with JSON pointers into JSON schema documents.
648 UriType GetUri(ValueType& root,
649 const UriType& rootUri,
650 size_t* unresolvedTokenIndex = 0,
651 Allocator* allocator = 0) const
652 {
653 static const Ch kIdString[] = {'i', 'd', '\0'};
654 static const ValueType kIdValue(kIdString, 2);
655 UriType base = UriType(rootUri, allocator);
656 RAPIDJSON_ASSERT(IsValid());
657 ValueType* v = &root;
658 for(const Token* t = tokens_; t != tokens_ + tokenCount_; ++t)
659 {
660 switch(v->GetType())
661 {
662 case kObjectType: {
663 // See if we have an id, and if so resolve with the current base
664 typename ValueType::MemberIterator m = v->FindMember(kIdValue);
665 if(m != v->MemberEnd() && (m->value).IsString())
666 {
667 UriType here = UriType(m->value, allocator).Resolve(base, allocator);
668 base = here;
669 }
670 m = v->FindMember(
671 GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
672 if(m == v->MemberEnd())
673 break;
674 v = &m->value;
675 }
676 continue;
677 case kArrayType:
678 if(t->index == kPointerInvalidIndex || t->index >= v->Size())
679 break;
680 v = &((*v)[t->index]);
681 continue;
682 default: break;
683 }
684
685 // Error: unresolved token
686 if(unresolvedTokenIndex)
687 *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
688 return UriType(allocator);
689 }
690 return base;
691 }
692
693 UriType GetUri(const ValueType& root,
694 const UriType& rootUri,
695 size_t* unresolvedTokenIndex = 0,
696 Allocator* allocator = 0) const
697 {
698 return GetUri(const_cast<ValueType&>(root), rootUri, unresolvedTokenIndex, allocator);
699 }
700
702
703
705
719 ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const
720 {
721 RAPIDJSON_ASSERT(IsValid());
722 ValueType* v = &root;
723 for(const Token* t = tokens_; t != tokens_ + tokenCount_; ++t)
724 {
725 switch(v->GetType())
726 {
727 case kObjectType: {
728 typename ValueType::MemberIterator m = v->FindMember(
729 GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
730 if(m == v->MemberEnd())
731 break;
732 v = &m->value;
733 }
734 continue;
735 case kArrayType:
736 if(t->index == kPointerInvalidIndex || t->index >= v->Size())
737 break;
738 v = &((*v)[t->index]);
739 continue;
740 default: break;
741 }
742
743 // Error: unresolved token
744 if(unresolvedTokenIndex)
745 *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
746 return 0;
747 }
748 return v;
749 }
750
752
756 const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const
757 {
758 return Get(const_cast<ValueType&>(root), unresolvedTokenIndex);
759 }
760
762
764
765
767
776 ValueType& GetWithDefault(ValueType& root,
777 const ValueType& defaultValue,
778 typename ValueType::AllocatorType& allocator) const
779 {
780 bool alreadyExist;
781 ValueType& v = Create(root, allocator, &alreadyExist);
782 return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
783 }
784
786 ValueType& GetWithDefault(ValueType& root,
787 const Ch* defaultValue,
788 typename ValueType::AllocatorType& allocator) const
789 {
790 bool alreadyExist;
791 ValueType& v = Create(root, allocator, &alreadyExist);
792 return alreadyExist ? v : v.SetString(defaultValue, allocator);
793 }
794
795#if RAPIDJSON_HAS_STDSTRING
797 ValueType& GetWithDefault(ValueType& root,
798 const std::basic_string<Ch>& defaultValue,
799 typename ValueType::AllocatorType& allocator) const
800 {
801 bool alreadyExist;
802 ValueType& v = Create(root, allocator, &alreadyExist);
803 return alreadyExist ? v : v.SetString(defaultValue, allocator);
804 }
805#endif
806
808
811 template <typename T>
813 (internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>), (ValueType&))
814 GetWithDefault(ValueType& root,
815 T defaultValue,
816 typename ValueType::AllocatorType& allocator) const
817 {
818 return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);
819 }
820
822 template <typename stackAllocator>
823 ValueType& GetWithDefault(
824 GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document,
825 const ValueType& defaultValue) const
826 {
827 return GetWithDefault(document, defaultValue, document.GetAllocator());
828 }
829
831 template <typename stackAllocator>
832 ValueType& GetWithDefault(
833 GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document,
834 const Ch* defaultValue) const
835 {
836 return GetWithDefault(document, defaultValue, document.GetAllocator());
837 }
838
839#if RAPIDJSON_HAS_STDSTRING
841 template <typename stackAllocator>
842 ValueType& GetWithDefault(
843 GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document,
844 const std::basic_string<Ch>& defaultValue) const
845 {
846 return GetWithDefault(document, defaultValue, document.GetAllocator());
847 }
848#endif
849
851
854 template <typename T, typename stackAllocator>
856 (internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>), (ValueType&))
857 GetWithDefault(
858 GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document,
859 T defaultValue) const
860 {
861 return GetWithDefault(document, defaultValue, document.GetAllocator());
862 }
863
865
867
868
870
878 ValueType&
879 Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const
880 {
881 return Create(root, allocator) = value;
882 }
883
885 ValueType&
886 Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const
887 {
888 return Create(root, allocator).CopyFrom(value, allocator);
889 }
890
892 ValueType&
893 Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const
894 {
895 return Create(root, allocator) = ValueType(value, allocator).Move();
896 }
897
898#if RAPIDJSON_HAS_STDSTRING
900 ValueType& Set(ValueType& root,
901 const std::basic_string<Ch>& value,
902 typename ValueType::AllocatorType& allocator) const
903 {
904 return Create(root, allocator) = ValueType(value, allocator).Move();
905 }
906#endif
907
909
912 template <typename T>
914 (internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>), (ValueType&))
915 Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const
916 {
917 return Create(root, allocator) = ValueType(value).Move();
918 }
919
921 template <typename stackAllocator>
922 ValueType&
923 Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document,
924 ValueType& value) const
925 {
926 return Create(document) = value;
927 }
928
930 template <typename stackAllocator>
931 ValueType&
932 Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document,
933 const ValueType& value) const
934 {
935 return Create(document).CopyFrom(value, document.GetAllocator());
936 }
937
939 template <typename stackAllocator>
940 ValueType&
941 Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document,
942 const Ch* value) const
943 {
944 return Create(document) = ValueType(value, document.GetAllocator()).Move();
945 }
946
947#if RAPIDJSON_HAS_STDSTRING
949 template <typename stackAllocator>
950 ValueType&
951 Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document,
952 const std::basic_string<Ch>& value) const
953 {
954 return Create(document) = ValueType(value, document.GetAllocator()).Move();
955 }
956#endif
957
959
962 template <typename T, typename stackAllocator>
964 (internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>), (ValueType&))
965 Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document,
966 T value) const
967 {
968 return Create(document) = value;
969 }
970
972
974
975
977
985 ValueType&
986 Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const
987 {
988 return Create(root, allocator).Swap(value);
989 }
990
992 template <typename stackAllocator>
993 ValueType&
994 Swap(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document,
995 ValueType& value) const
996 {
997 return Create(document).Swap(value);
998 }
999
1001
1003
1010 bool Erase(ValueType& root) const
1011 {
1012 RAPIDJSON_ASSERT(IsValid());
1013 if(tokenCount_ == 0) // Cannot erase the root
1014 return false;
1015
1016 ValueType* v = &root;
1017 const Token* last = tokens_ + (tokenCount_ - 1);
1018 for(const Token* t = tokens_; t != last; ++t)
1019 {
1020 switch(v->GetType())
1021 {
1022 case kObjectType: {
1023 typename ValueType::MemberIterator m = v->FindMember(
1024 GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
1025 if(m == v->MemberEnd())
1026 return false;
1027 v = &m->value;
1028 }
1029 break;
1030 case kArrayType:
1031 if(t->index == kPointerInvalidIndex || t->index >= v->Size())
1032 return false;
1033 v = &((*v)[t->index]);
1034 break;
1035 default: return false;
1036 }
1037 }
1038
1039 switch(v->GetType())
1040 {
1041 case kObjectType: return v->EraseMember(GenericStringRef<Ch>(last->name, last->length));
1042 case kArrayType:
1043 if(last->index == kPointerInvalidIndex || last->index >= v->Size())
1044 return false;
1045 v->Erase(v->Begin() + last->index);
1046 return true;
1047 default: return false;
1048 }
1049 }
1050
1051 private:
1053
1059 Ch*
1060 CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0)
1061 {
1062 if(!allocator_) // allocator is independently owned.
1063 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
1064
1065 size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens
1066 for(Token* t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)
1067 nameBufferSize += t->length;
1068
1069 tokenCount_ = rhs.tokenCount_ + extraToken;
1070 tokens_ = static_cast<Token*>(allocator_->Malloc(
1071 tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch)));
1072 nameBuffer_ = reinterpret_cast<Ch*>(tokens_ + tokenCount_);
1073 if(rhs.tokenCount_ > 0)
1074 {
1075 std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token));
1076 }
1077 if(nameBufferSize > 0)
1078 {
1079 std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
1080 }
1081
1082 // The names of each token point to a string in the nameBuffer_. The
1083 // previous memcpy copied over string pointers into the rhs.nameBuffer_,
1084 // but they should point to the strings in the new nameBuffer_.
1085 for(size_t i = 0; i < rhs.tokenCount_; ++i)
1086 {
1087 // The offset between the string address and the name buffer should
1088 // still be constant, so we can just get this offset and set each new
1089 // token name according the new buffer start + the known offset.
1090 std::ptrdiff_t name_offset = rhs.tokens_[i].name - rhs.nameBuffer_;
1091 tokens_[i].name = nameBuffer_ + name_offset;
1092 }
1093
1094 return nameBuffer_ + nameBufferSize;
1095 }
1096
1098
1102 bool NeedPercentEncode(Ch c) const
1103 {
1104 return !((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
1105 c == '-' || c == '.' || c == '_' || c == '~');
1106 }
1107
1109#ifndef __clang__ // -Wdocumentation
1115#endif
1116 void Parse(const Ch* source, size_t length)
1117 {
1118 RAPIDJSON_ASSERT(source != NULL);
1121
1122 // Create own allocator if user did not supply.
1123 if(!allocator_)
1124 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
1125
1126 // Count number of '/' as tokenCount
1127 tokenCount_ = 0;
1128 for(const Ch* s = source; s != source + length; s++)
1129 if(*s == '/')
1130 tokenCount_++;
1131
1132 Token* token = tokens_ = static_cast<Token*>(
1133 allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch)));
1134 Ch* name = nameBuffer_ = reinterpret_cast<Ch*>(tokens_ + tokenCount_);
1135 size_t i = 0;
1136
1137 // Detect if it is a URI fragment
1138 bool uriFragment = false;
1139 if(source[i] == '#')
1140 {
1141 uriFragment = true;
1142 i++;
1143 }
1144
1145 if(i != length && source[i] != '/')
1146 {
1148 goto error;
1149 }
1150
1151 while(i < length)
1152 {
1153 RAPIDJSON_ASSERT(source[i] == '/');
1154 i++; // consumes '/'
1155
1156 token->name = name;
1157 bool isNumber = true;
1158
1159 while(i < length && source[i] != '/')
1160 {
1161 Ch c = source[i];
1162 if(uriFragment)
1163 {
1164 // Decoding percent-encoding for URI fragment
1165 if(c == '%')
1166 {
1167 PercentDecodeStream is(&source[i], source + length);
1168 GenericInsituStringStream<EncodingType> os(name);
1169 Ch* begin = os.PutBegin();
1170 if(!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid())
1171 {
1173 goto error;
1174 }
1175 size_t len = os.PutEnd(begin);
1176 i += is.Tell() - 1;
1177 if(len == 1)
1178 c = *name;
1179 else
1180 {
1181 name += len;
1182 isNumber = false;
1183 i++;
1184 continue;
1185 }
1186 }
1187 else if(NeedPercentEncode(c))
1188 {
1190 goto error;
1191 }
1192 }
1193
1194 i++;
1195
1196 // Escaping "~0" -> '~', "~1" -> '/'
1197 if(c == '~')
1198 {
1199 if(i < length)
1200 {
1201 c = source[i];
1202 if(c == '0')
1203 c = '~';
1204 else if(c == '1')
1205 c = '/';
1206 else
1207 {
1209 goto error;
1210 }
1211 i++;
1212 }
1213 else
1214 {
1216 goto error;
1217 }
1218 }
1219
1220 // First check for index: all of characters are digit
1221 if(c < '0' || c > '9')
1222 isNumber = false;
1223
1224 *name++ = c;
1225 }
1226 token->length = static_cast<SizeType>(name - token->name);
1227 if(token->length == 0)
1228 isNumber = false;
1229 *name++ = '\0'; // Null terminator
1230
1231 // Second check for index: more than one digit cannot have leading zero
1232 if(isNumber && token->length > 1 && token->name[0] == '0')
1233 isNumber = false;
1234
1235 // String to SizeType conversion
1236 SizeType n = 0;
1237 if(isNumber)
1238 {
1239 for(size_t j = 0; j < token->length; j++)
1240 {
1241 SizeType m = n * 10 + static_cast<SizeType>(token->name[j] - '0');
1242 if(m < n)
1243 { // overflow detection
1244 isNumber = false;
1245 break;
1246 }
1247 n = m;
1248 }
1249 }
1250
1251 token->index = isNumber ? n : kPointerInvalidIndex;
1252 token++;
1253 }
1254
1255 RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer
1257 return;
1258
1259 error:
1260 Allocator::Free(tokens_);
1261 nameBuffer_ = 0;
1262 tokens_ = 0;
1263 tokenCount_ = 0;
1265 return;
1266 }
1267
1269
1273 template <bool uriFragment, typename OutputStream>
1274 bool Stringify(OutputStream& os) const
1275 {
1276 RAPIDJSON_ASSERT(IsValid());
1277
1278 if(uriFragment)
1279 os.Put('#');
1280
1281 for(Token* t = tokens_; t != tokens_ + tokenCount_; ++t)
1282 {
1283 os.Put('/');
1284 for(size_t j = 0; j < t->length; j++)
1285 {
1286 Ch c = t->name[j];
1287 if(c == '~')
1288 {
1289 os.Put('~');
1290 os.Put('0');
1291 }
1292 else if(c == '/')
1293 {
1294 os.Put('~');
1295 os.Put('1');
1296 }
1297 else if(uriFragment && NeedPercentEncode(c))
1298 {
1299 // Transcode to UTF8 sequence
1300 GenericStringStream<typename ValueType::EncodingType> source(&t->name[j]);
1302 if(!Transcoder<EncodingType, UTF8<>>().Validate(source, target))
1303 return false;
1304 j += source.Tell() - 1;
1305 }
1306 else
1307 os.Put(c);
1308 }
1309 }
1310 return true;
1311 }
1312
1314
1319 class PercentDecodeStream
1320 {
1321 public:
1322 typedef typename ValueType::Ch Ch;
1323
1325
1329 PercentDecodeStream(const Ch* source, const Ch* end)
1330 : src_(source), head_(source), end_(end), valid_(true)
1331 {
1332 }
1333
1334 Ch Take()
1335 {
1336 if(*src_ != '%' || src_ + 3 > end_)
1337 { // %XY triplet
1338 valid_ = false;
1339 return 0;
1340 }
1341 src_++;
1342 Ch c = 0;
1343 for(int j = 0; j < 2; j++)
1344 {
1345 c = static_cast<Ch>(c << 4);
1346 Ch h = *src_;
1347 if(h >= '0' && h <= '9')
1348 c = static_cast<Ch>(c + h - '0');
1349 else if(h >= 'A' && h <= 'F')
1350 c = static_cast<Ch>(c + h - 'A' + 10);
1351 else if(h >= 'a' && h <= 'f')
1352 c = static_cast<Ch>(c + h - 'a' + 10);
1353 else
1354 {
1355 valid_ = false;
1356 return 0;
1357 }
1358 src_++;
1359 }
1360 return c;
1361 }
1362
1363 size_t Tell() const { return static_cast<size_t>(src_ - head_); }
1364 bool IsValid() const { return valid_; }
1365
1366 private:
1367 const Ch* src_;
1368 const Ch* head_;
1369 const Ch* end_;
1370 bool valid_;
1371 };
1372
1374 template <typename OutputStream>
1376 {
1377 public:
1378 PercentEncodeStream(OutputStream& os) : os_(os) {}
1379 void Put(char c)
1380 { // UTF-8 must be byte
1381 unsigned char u = static_cast<unsigned char>(c);
1382 static const char hexDigits[16] = {
1383 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
1384 os_.Put('%');
1385 os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u >> 4]));
1386 os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u & 15]));
1387 }
1388
1389 private:
1390 OutputStream& os_;
1391 };
1392
1397 Token* tokens_;
1401};
1402
1405
1407
1408
1410
1411template <typename T>
1412typename T::ValueType& CreateValueByPointer(T& root,
1414 typename T::AllocatorType& a)
1415{
1416 return pointer.Create(root, a);
1417}
1418
1419template <typename T, typename CharType, size_t N>
1420typename T::ValueType&
1421CreateValueByPointer(T& root, const CharType (&source)[N], typename T::AllocatorType& a)
1422{
1423 return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a);
1424}
1425
1426// No allocator parameter
1427
1428template <typename DocumentType>
1429typename DocumentType::ValueType&
1430CreateValueByPointer(DocumentType& document,
1432{
1433 return pointer.Create(document);
1434}
1435
1436template <typename DocumentType, typename CharType, size_t N>
1437typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document,
1438 const CharType (&source)[N])
1439{
1440 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document);
1441}
1442
1444
1445template <typename T>
1446typename T::ValueType* GetValueByPointer(T& root,
1448 size_t* unresolvedTokenIndex = 0)
1449{
1450 return pointer.Get(root, unresolvedTokenIndex);
1451}
1452
1453template <typename T>
1454const typename T::ValueType* GetValueByPointer(const T& root,
1456 size_t* unresolvedTokenIndex = 0)
1457{
1458 return pointer.Get(root, unresolvedTokenIndex);
1459}
1460
1461template <typename T, typename CharType, size_t N>
1462typename T::ValueType*
1463GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0)
1464{
1465 return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1466}
1467
1468template <typename T, typename CharType, size_t N>
1469const typename T::ValueType*
1470GetValueByPointer(const T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0)
1471{
1472 return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1473}
1474
1476
1477template <typename T>
1478typename T::ValueType&
1481 const typename T::ValueType& defaultValue,
1482 typename T::AllocatorType& a)
1483{
1484 return pointer.GetWithDefault(root, defaultValue, a);
1485}
1486
1487template <typename T>
1488typename T::ValueType&
1491 const typename T::Ch* defaultValue,
1492 typename T::AllocatorType& a)
1493{
1494 return pointer.GetWithDefault(root, defaultValue, a);
1495}
1496
1497#if RAPIDJSON_HAS_STDSTRING
1498template <typename T>
1499typename T::ValueType&
1502 const std::basic_string<typename T::Ch>& defaultValue,
1503 typename T::AllocatorType& a)
1504{
1505 return pointer.GetWithDefault(root, defaultValue, a);
1506}
1507#endif
1508
1509template <typename T, typename T2>
1511 (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1512 (typename T::ValueType&))
1516 typename T::AllocatorType& a)
1517{
1518 return pointer.GetWithDefault(root, defaultValue, a);
1519}
1520
1521template <typename T, typename CharType, size_t N>
1522typename T::ValueType& GetValueByPointerWithDefault(T& root,
1523 const CharType (&source)[N],
1524 const typename T::ValueType& defaultValue,
1525 typename T::AllocatorType& a)
1526{
1528 .GetWithDefault(root, defaultValue, a);
1529}
1530
1531template <typename T, typename CharType, size_t N>
1532typename T::ValueType& GetValueByPointerWithDefault(T& root,
1533 const CharType (&source)[N],
1534 const typename T::Ch* defaultValue,
1535 typename T::AllocatorType& a)
1536{
1538 .GetWithDefault(root, defaultValue, a);
1539}
1540
1541#if RAPIDJSON_HAS_STDSTRING
1542template <typename T, typename CharType, size_t N>
1543typename T::ValueType&
1545 const CharType (&source)[N],
1546 const std::basic_string<typename T::Ch>& defaultValue,
1547 typename T::AllocatorType& a)
1548{
1550 .GetWithDefault(root, defaultValue, a);
1551}
1552#endif
1553
1554template <typename T, typename CharType, size_t N, typename T2>
1556 (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1557 (typename T::ValueType&))
1559 const CharType (&source)[N],
1560 T2 defaultValue,
1561 typename T::AllocatorType& a)
1562{
1564 .GetWithDefault(root, defaultValue, a);
1565}
1566
1567// No allocator parameter
1568
1569template <typename DocumentType>
1570typename DocumentType::ValueType&
1571GetValueByPointerWithDefault(DocumentType& document,
1573 const typename DocumentType::ValueType& defaultValue)
1574{
1575 return pointer.GetWithDefault(document, defaultValue);
1576}
1577
1578template <typename DocumentType>
1579typename DocumentType::ValueType&
1580GetValueByPointerWithDefault(DocumentType& document,
1582 const typename DocumentType::Ch* defaultValue)
1583{
1584 return pointer.GetWithDefault(document, defaultValue);
1585}
1586
1587#if RAPIDJSON_HAS_STDSTRING
1588template <typename DocumentType>
1589typename DocumentType::ValueType&
1590GetValueByPointerWithDefault(DocumentType& document,
1592 const std::basic_string<typename DocumentType::Ch>& defaultValue)
1593{
1594 return pointer.GetWithDefault(document, defaultValue);
1595}
1596#endif
1597
1598template <typename DocumentType, typename T2>
1600 (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1601 (typename DocumentType::ValueType&))
1602GetValueByPointerWithDefault(DocumentType& document,
1604 T2 defaultValue)
1605{
1606 return pointer.GetWithDefault(document, defaultValue);
1607}
1608
1609template <typename DocumentType, typename CharType, size_t N>
1610typename DocumentType::ValueType&
1611GetValueByPointerWithDefault(DocumentType& document,
1612 const CharType (&source)[N],
1613 const typename DocumentType::ValueType& defaultValue)
1614{
1616 .GetWithDefault(document, defaultValue);
1617}
1618
1619template <typename DocumentType, typename CharType, size_t N>
1620typename DocumentType::ValueType&
1621GetValueByPointerWithDefault(DocumentType& document,
1622 const CharType (&source)[N],
1623 const typename DocumentType::Ch* defaultValue)
1624{
1626 .GetWithDefault(document, defaultValue);
1627}
1628
1629#if RAPIDJSON_HAS_STDSTRING
1630template <typename DocumentType, typename CharType, size_t N>
1631typename DocumentType::ValueType&
1632GetValueByPointerWithDefault(DocumentType& document,
1633 const CharType (&source)[N],
1634 const std::basic_string<typename DocumentType::Ch>& defaultValue)
1635{
1637 .GetWithDefault(document, defaultValue);
1638}
1639#endif
1640
1641template <typename DocumentType, typename CharType, size_t N, typename T2>
1643 (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1644 (typename DocumentType::ValueType&))
1645GetValueByPointerWithDefault(DocumentType& document, const CharType (&source)[N], T2 defaultValue)
1646{
1648 .GetWithDefault(document, defaultValue);
1649}
1650
1652
1653template <typename T>
1654typename T::ValueType& SetValueByPointer(T& root,
1656 typename T::ValueType& value,
1657 typename T::AllocatorType& a)
1658{
1659 return pointer.Set(root, value, a);
1660}
1661
1662template <typename T>
1663typename T::ValueType& SetValueByPointer(T& root,
1665 const typename T::ValueType& value,
1666 typename T::AllocatorType& a)
1667{
1668 return pointer.Set(root, value, a);
1669}
1670
1671template <typename T>
1672typename T::ValueType& SetValueByPointer(T& root,
1674 const typename T::Ch* value,
1675 typename T::AllocatorType& a)
1676{
1677 return pointer.Set(root, value, a);
1678}
1679
1680#if RAPIDJSON_HAS_STDSTRING
1681template <typename T>
1682typename T::ValueType& SetValueByPointer(T& root,
1684 const std::basic_string<typename T::Ch>& value,
1685 typename T::AllocatorType& a)
1686{
1687 return pointer.Set(root, value, a);
1688}
1689#endif
1690
1691template <typename T, typename T2>
1693 (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1694 (typename T::ValueType&))
1695SetValueByPointer(T& root,
1698 typename T::AllocatorType& a)
1699{
1700 return pointer.Set(root, value, a);
1701}
1702
1703template <typename T, typename CharType, size_t N>
1704typename T::ValueType& SetValueByPointer(T& root,
1705 const CharType (&source)[N],
1706 typename T::ValueType& value,
1707 typename T::AllocatorType& a)
1708{
1709 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1710}
1711
1712template <typename T, typename CharType, size_t N>
1713typename T::ValueType& SetValueByPointer(T& root,
1714 const CharType (&source)[N],
1715 const typename T::ValueType& value,
1716 typename T::AllocatorType& a)
1717{
1718 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1719}
1720
1721template <typename T, typename CharType, size_t N>
1722typename T::ValueType& SetValueByPointer(T& root,
1723 const CharType (&source)[N],
1724 const typename T::Ch* value,
1725 typename T::AllocatorType& a)
1726{
1727 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1728}
1729
1730#if RAPIDJSON_HAS_STDSTRING
1731template <typename T, typename CharType, size_t N>
1732typename T::ValueType& SetValueByPointer(T& root,
1733 const CharType (&source)[N],
1734 const std::basic_string<typename T::Ch>& value,
1735 typename T::AllocatorType& a)
1736{
1737 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1738}
1739#endif
1740
1741template <typename T, typename CharType, size_t N, typename T2>
1743 (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1744 (typename T::ValueType&))
1745SetValueByPointer(T& root, const CharType (&source)[N], T2 value, typename T::AllocatorType& a)
1746{
1747 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1748}
1749
1750// No allocator parameter
1751
1752template <typename DocumentType>
1753typename DocumentType::ValueType&
1754SetValueByPointer(DocumentType& document,
1756 typename DocumentType::ValueType& value)
1757{
1758 return pointer.Set(document, value);
1759}
1760
1761template <typename DocumentType>
1762typename DocumentType::ValueType&
1763SetValueByPointer(DocumentType& document,
1765 const typename DocumentType::ValueType& value)
1766{
1767 return pointer.Set(document, value);
1768}
1769
1770template <typename DocumentType>
1771typename DocumentType::ValueType&
1772SetValueByPointer(DocumentType& document,
1774 const typename DocumentType::Ch* value)
1775{
1776 return pointer.Set(document, value);
1777}
1778
1779#if RAPIDJSON_HAS_STDSTRING
1780template <typename DocumentType>
1781typename DocumentType::ValueType&
1782SetValueByPointer(DocumentType& document,
1784 const std::basic_string<typename DocumentType::Ch>& value)
1785{
1786 return pointer.Set(document, value);
1787}
1788#endif
1789
1790template <typename DocumentType, typename T2>
1792 (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1793 (typename DocumentType::ValueType&))
1794SetValueByPointer(DocumentType& document,
1796 T2 value)
1797{
1798 return pointer.Set(document, value);
1799}
1800
1801template <typename DocumentType, typename CharType, size_t N>
1802typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
1803 const CharType (&source)[N],
1804 typename DocumentType::ValueType& value)
1805{
1807}
1808
1809template <typename DocumentType, typename CharType, size_t N>
1810typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
1811 const CharType (&source)[N],
1812 const typename DocumentType::ValueType& value)
1813{
1815}
1816
1817template <typename DocumentType, typename CharType, size_t N>
1818typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
1819 const CharType (&source)[N],
1820 const typename DocumentType::Ch* value)
1821{
1823}
1824
1825#if RAPIDJSON_HAS_STDSTRING
1826template <typename DocumentType, typename CharType, size_t N>
1827typename DocumentType::ValueType&
1828SetValueByPointer(DocumentType& document,
1829 const CharType (&source)[N],
1830 const std::basic_string<typename DocumentType::Ch>& value)
1831{
1833}
1834#endif
1835
1836template <typename DocumentType, typename CharType, size_t N, typename T2>
1838 (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1839 (typename DocumentType::ValueType&))
1840SetValueByPointer(DocumentType& document, const CharType (&source)[N], T2 value)
1841{
1843}
1844
1846
1847template <typename T>
1848typename T::ValueType& SwapValueByPointer(T& root,
1850 typename T::ValueType& value,
1851 typename T::AllocatorType& a)
1852{
1853 return pointer.Swap(root, value, a);
1854}
1855
1856template <typename T, typename CharType, size_t N>
1857typename T::ValueType& SwapValueByPointer(T& root,
1858 const CharType (&source)[N],
1859 typename T::ValueType& value,
1860 typename T::AllocatorType& a)
1861{
1863}
1864
1865template <typename DocumentType>
1866typename DocumentType::ValueType&
1867SwapValueByPointer(DocumentType& document,
1869 typename DocumentType::ValueType& value)
1870{
1871 return pointer.Swap(document, value);
1872}
1873
1874template <typename DocumentType, typename CharType, size_t N>
1875typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document,
1876 const CharType (&source)[N],
1877 typename DocumentType::ValueType& value)
1878{
1880}
1881
1883
1884template <typename T>
1886{
1887 return pointer.Erase(root);
1888}
1889
1890template <typename T, typename CharType, size_t N>
1891bool EraseValueByPointer(T& root, const CharType (&source)[N])
1892{
1893 return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root);
1894}
1895
1897
1899
1900#if defined(__clang__) || defined(_MSC_VER)
1901RAPIDJSON_DIAG_POP
1902#endif
1903
1904#endif // RAPIDJSON_POINTER_H_
Allocator & GetAllocator()
Get the allocator of this document.
Definition document.h:3472
A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence.
Definition pointer.h:1376
PercentEncodeStream(OutputStream &os)
Definition pointer.h:1378
void Put(char c)
Definition pointer.h:1379
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition pointer.h:76
friend void swap(GenericPointer &a, GenericPointer &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition pointer.h:296
Ch * nameBuffer_
Definition pointer.h:1396
CrtAllocator * allocator_
Definition pointer.h:1393
GenericPointer(const GenericPointer &rhs, Allocator *allocator)
Copy constructor.
Definition pointer.h:224
GenericPointer(const Ch *source, Allocator *allocator=0)
Constructor that parses a string or URI fragment representation.
Definition pointer.h:124
Value::EncodingType EncodingType
Definition pointer.h:78
GenericPointer(const Token *tokens, size_t tokenCount)
Constructor with user-supplied tokens.
Definition pointer.h:199
GenericPointer(Allocator *allocator=0)
Default constructor.
Definition pointer.h:107
size_t tokenCount_
Definition pointer.h:1398
GenericPointer(const GenericPointer &rhs)
Copy constructor.
Definition pointer.h:211
PointerParseErrorCode parseErrorCode_
Definition pointer.h:1400
Token * tokens_
Definition pointer.h:1397
CrtAllocator * ownAllocator_
Definition pointer.h:1395
GenericPointer(const Ch *source, size_t length, Allocator *allocator=0)
Definition pointer.h:165
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:328
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
Definition pointer.h:309
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.
Value::Ch Ch
Definition pointer.h:79
GenericUri< Value, CrtAllocator > UriType
Definition pointer.h:80
~GenericPointer()
Destructor.
Definition pointer.h:237
size_t parseErrorOffset_
Definition pointer.h:1399
GenericPointer & operator=(const GenericPointer &rhs)
Assignment operator.
Definition pointer.h:246
CrtAllocator * allocator
Definition pointer.h:344
GenericPointer & Swap(GenericPointer &other) RAPIDJSON_NOEXCEPT
Swap the content of this pointer with an other.
Definition pointer.h:274
Definition uri.h:34
GenericUri Resolve(const GenericUri &baseuri, Allocator *allocator=0)
Resolve this URI against another (base) URI in accordance with URI resolution rules.
Definition uri.h:259
Concept for allocating, resizing and freeing memory block.
GenericPointer< Value, CrtAllocator > Pointer
Definition fwd.h:145
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition rapidjson.h:451
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition rapidjson.h:121
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition rapidjson.h:124
PointerParseErrorCode
Error code of JSON pointer parsing.
Definition error.h:277
@ kPointerParseErrorInvalidEscape
Invalid escape.
Definition error.h:281
@ kPointerParseErrorTokenMustBeginWithSolidus
A token must begin with a '/'.
Definition error.h:280
@ kPointerParseErrorNone
The parse is successful.
Definition error.h:278
@ kPointerParseErrorCharacterMustPercentEncode
Definition error.h:283
@ kPointerParseErrorInvalidPercentEncoding
Invalid percent encoding in URI fragment.
Definition error.h:282
CK_TILE_HOST_DEVICE constexpr bool operator!=(const array< T, Size > &a, const array< T, Size > &b)
Definition tile/core/container/array.hpp:280
@ Set
Definition ck.hpp:278
__host__ __device__ constexpr bool operator==(Sequence< Xs... >, Sequence< Ys... >)
Definition utility/sequence.hpp:649
char * u64toa(uint64_t value, char *buffer)
Definition itoa.h:135
void Swap(T &a, T &b) RAPIDJSON_NOEXCEPT
Custom swap() to avoid dependency on C++ <algorithm> header.
Definition swap.h:33
SizeType StrLen(const Ch *s)
Custom strlen() which works on different character types.
Definition strfunc.h:32
char * u32toa(uint32_t value, char *buffer)
Definition itoa.h:41
const GenericPointer< typename T::ValueType > T2 value
Definition pointer.h:1697
const GenericPointer< typename T::ValueType > T2 defaultValue
Definition pointer.h:1515
T::ValueType & SwapValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition pointer.h:1848
T::ValueType & SetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition pointer.h:1654
T::ValueType * GetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, size_t *unresolvedTokenIndex=0)
Definition pointer.h:1446
#define RAPIDJSON_IF_CONSTEXPR
Definition pointer.h:34
bool EraseValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer)
Definition pointer.h:1885
T::ValueType & CreateValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::AllocatorType &a)
Definition pointer.h:1412
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T2 >, internal::IsGenericValue< T2 > >),(typename T::ValueType &)) GetValueByPointerWithDefault(T &root
const GenericPointer< typename T::ValueType > & pointer
Definition pointer.h:1514
T::ValueType & GetValueByPointerWithDefault(T &root, const GenericPointer< typename T::ValueType > &pointer, const typename T::ValueType &defaultValue, typename T::AllocatorType &a)
Definition pointer.h:1479
const CharType(& source)[N]
Definition pointer.h:1559
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1517
@ kObjectType
object
Definition rapidjson.h:764
@ kArrayType
array
Definition rapidjson.h:765
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition rapidjson.h:746
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.).
Definition rapidjson.h:429
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition rapidjson.h:742
A token is the basic units of internal representation.
Definition pointer.h:96
SizeType index
A valid array index, if it is not equal to kPointerInvalidIndex.
Definition pointer.h:100
SizeType length
Length of the name.
Definition pointer.h:99
const Ch * name
Definition pointer.h:97
Definition document.h:595