Monero
Loading...
Searching...
No Matches
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. All rights reserved.
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 "internal/itoa.h"
20
21#ifdef __clang__
22RAPIDJSON_DIAG_PUSH
23RAPIDJSON_DIAG_OFF(switch-enum)
24#elif defined(_MSC_VER)
25RAPIDJSON_DIAG_PUSH
26RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
27#endif
28
30
32
34
45
47// GenericPointer
48
50
78template <typename ValueType, typename Allocator = CrtAllocator>
80public:
81 typedef typename ValueType::EncodingType EncodingType;
82 typedef typename ValueType::Ch Ch;
83
85
97 struct Token {
98 const Ch* name;
101 };
102
104
105
108
110
117
118#if RAPIDJSON_HAS_STDSTRING
120
126 Parse(source.c_str(), source.size());
127 }
128#endif
129
131
140
142
163 GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
164
169
174
177 if (nameBuffer_) // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and tokens_ are not deallocated.
178 Allocator::Free(tokens_);
180 }
181
184 if (this != &rhs) {
185 // Do not delete ownAllcator
186 if (nameBuffer_)
187 Allocator::Free(tokens_);
188
192
193 if (rhs.nameBuffer_)
194 CopyFromRaw(rhs); // Normally parsed tokens.
195 else {
196 tokens_ = rhs.tokens_; // User supplied const tokens.
197 nameBuffer_ = 0;
198 }
199 }
200 return *this;
201 }
202
204
206
207
209
214 GenericPointer Append(const Token& token, Allocator* allocator = 0) const {
216 r.allocator_ = allocator;
217 Ch *p = r.CopyFromRaw(*this, 1, token.length + 1);
218 std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch));
219 r.tokens_[tokenCount_].name = p;
220 r.tokens_[tokenCount_].length = token.length;
221 r.tokens_[tokenCount_].index = token.index;
222 return r;
223 }
224
226
233 Token token = { name, length, kPointerInvalidIndex };
234 return Append(token, allocator);
235 }
236
238
243 template <typename T>
244 RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >), (GenericPointer))
247 }
248
249#if RAPIDJSON_HAS_STDSTRING
251
256 GenericPointer Append(const std::basic_string<Ch>& name, Allocator* allocator = 0) const {
257 return Append(name.c_str(), static_cast<SizeType>(name.size()), allocator);
258 }
259#endif
260
262
267 GenericPointer Append(SizeType index, Allocator* allocator = 0) const {
268 char buffer[21];
269 char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer);
270 SizeType length = static_cast<SizeType>(end - buffer);
271 buffer[length] = '\0';
272
273 if (sizeof(Ch) == 1) {
274 Token token = { reinterpret_cast<Ch*>(buffer), length, index };
275 return Append(token, allocator);
276 }
277 else {
278 Ch name[21];
279 for (size_t i = 0; i <= length; i++)
280 name[i] = static_cast<Ch>(buffer[i]);
281 Token token = { name, length, index };
282 return Append(token, allocator);
283 }
284 }
285
287
292 GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const {
293 if (token.IsString())
294 return Append(token.GetString(), token.GetStringLength(), allocator);
295 else {
296 RAPIDJSON_ASSERT(token.IsUint64());
297 RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0));
298 return Append(static_cast<SizeType>(token.GetUint64()), allocator);
299 }
300 }
301
303
304
306 bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; }
307
309 size_t GetParseErrorOffset() const { return parseErrorOffset_; }
310
312 PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; }
313
315
317 Allocator& GetAllocator() { return *allocator_; }
318
320
321
323 const Token* GetTokens() const { return tokens_; }
324
326 size_t GetTokenCount() const { return tokenCount_; }
327
329
331
332
334
337 bool operator==(const GenericPointer& rhs) const {
338 if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_)
339 return false;
340
341 for (size_t i = 0; i < tokenCount_; i++) {
342 if (tokens_[i].index != rhs.tokens_[i].index ||
343 tokens_[i].length != rhs.tokens_[i].length ||
344 (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch)* tokens_[i].length) != 0))
345 {
346 return false;
347 }
348 }
349
350 return true;
351 }
352
354
357 bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }
358
360
362
363
365
369 template<typename OutputStream>
370 bool Stringify(OutputStream& os) const {
372 }
373
375
379 template<typename OutputStream>
380 bool StringifyUriFragment(OutputStream& os) const {
382 }
383
385
387
388
390
404 ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const {
405 RAPIDJSON_ASSERT(IsValid());
406 ValueType* v = &root;
407 bool exist = true;
408 for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
409 if (v->IsArray() && t->name[0] == '-' && t->length == 1) {
410 v->PushBack(ValueType().Move(), allocator);
411 v = &((*v)[v->Size() - 1]);
412 exist = false;
413 }
414 else {
415 if (t->index == kPointerInvalidIndex) { // must be object name
416 if (!v->IsObject())
417 v->SetObject(); // Change to Object
418 }
419 else { // object name or array index
420 if (!v->IsArray() && !v->IsObject())
421 v->SetArray(); // Change to Array
422 }
423
424 if (v->IsArray()) {
425 if (t->index >= v->Size()) {
426 v->Reserve(t->index + 1, allocator);
427 while (t->index >= v->Size())
428 v->PushBack(ValueType().Move(), allocator);
429 exist = false;
430 }
431 v = &((*v)[t->index]);
432 }
433 else {
434 typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
435 if (m == v->MemberEnd()) {
436 v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
437 v = &(--v->MemberEnd())->value; // Assumes AddMember() appends at the end
438 exist = false;
439 }
440 else
441 v = &m->value;
442 }
443 }
444 }
445
446 if (alreadyExist)
447 *alreadyExist = exist;
448
449 return *v;
450 }
451
453
458 template <typename stackAllocator>
459 ValueType& Create(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, bool* alreadyExist = 0) const {
460 return Create(document, document.GetAllocator(), alreadyExist);
461 }
462
464
466
467
469
482 ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const {
483 RAPIDJSON_ASSERT(IsValid());
484 ValueType* v = &root;
485 for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
486 switch (v->GetType()) {
487 case kObjectType:
488 {
489 typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
490 if (m == v->MemberEnd())
491 break;
492 v = &m->value;
493 }
494 continue;
495 case kArrayType:
496 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
497 break;
498 v = &((*v)[t->index]);
499 continue;
500 default:
501 break;
502 }
503
504 // Error: unresolved token
505 if (unresolvedTokenIndex)
506 *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
507 return 0;
508 }
509 return v;
510 }
511
513
517 const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const {
518 return Get(const_cast<ValueType&>(root), unresolvedTokenIndex);
519 }
520
522
524
525
527
536 ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const {
537 bool alreadyExist;
538 ValueType& v = Create(root, allocator, &alreadyExist);
539 return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
540 }
541
543 ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const {
544 bool alreadyExist;
545 ValueType& v = Create(root, allocator, &alreadyExist);
546 return alreadyExist ? v : v.SetString(defaultValue, allocator);
547 }
548
549#if RAPIDJSON_HAS_STDSTRING
551 ValueType& GetWithDefault(ValueType& root, const std::basic_string<Ch>& defaultValue, typename ValueType::AllocatorType& allocator) const {
552 bool alreadyExist;
553 ValueType& v = Create(root, allocator, &alreadyExist);
554 return alreadyExist ? v : v.SetString(defaultValue, allocator);
555 }
556#endif
557
559
562 template <typename T>
563 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
564 GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator) const {
565 return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);
566 }
567
569 template <typename stackAllocator>
570 ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& defaultValue) const {
571 return GetWithDefault(document, defaultValue, document.GetAllocator());
572 }
573
575 template <typename stackAllocator>
576 ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* defaultValue) const {
577 return GetWithDefault(document, defaultValue, document.GetAllocator());
578 }
579
580#if RAPIDJSON_HAS_STDSTRING
582 template <typename stackAllocator>
583 ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& defaultValue) const {
584 return GetWithDefault(document, defaultValue, document.GetAllocator());
585 }
586#endif
587
589
592 template <typename T, typename stackAllocator>
593 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
594 GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T defaultValue) const {
595 return GetWithDefault(document, defaultValue, document.GetAllocator());
596 }
597
599
601
602
604
613 ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
614 return Create(root, allocator) = value;
615 }
616
618 ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const {
619 return Create(root, allocator).CopyFrom(value, allocator);
620 }
621
623 ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const {
624 return Create(root, allocator) = ValueType(value, allocator).Move();
625 }
626
627#if RAPIDJSON_HAS_STDSTRING
629 ValueType& Set(ValueType& root, const std::basic_string<Ch>& value, typename ValueType::AllocatorType& allocator) const {
630 return Create(root, allocator) = ValueType(value, allocator).Move();
631 }
632#endif
633
635
638 template <typename T>
639 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
640 Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const {
641 return Create(root, allocator) = ValueType(value).Move();
642 }
643
645 template <typename stackAllocator>
649
651 template <typename stackAllocator>
653 return Create(document).CopyFrom(value, document.GetAllocator());
654 }
655
657 template <typename stackAllocator>
659 return Create(document) = ValueType(value, document.GetAllocator()).Move();
660 }
661
662#if RAPIDJSON_HAS_STDSTRING
664 template <typename stackAllocator>
666 return Create(document) = ValueType(value, document.GetAllocator()).Move();
667 }
668#endif
669
671
674 template <typename T, typename stackAllocator>
675 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
676 Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T value) const {
677 return Create(document) = value;
678 }
679
681
683
684
686
695 ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
696 return Create(root, allocator).Swap(value);
697 }
698
700 template <typename stackAllocator>
704
706
708
714 bool Erase(ValueType& root) const {
715 RAPIDJSON_ASSERT(IsValid());
716 if (tokenCount_ == 0) // Cannot erase the root
717 return false;
718
719 ValueType* v = &root;
720 const Token* last = tokens_ + (tokenCount_ - 1);
721 for (const Token *t = tokens_; t != last; ++t) {
722 switch (v->GetType()) {
723 case kObjectType:
724 {
725 typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
726 if (m == v->MemberEnd())
727 return false;
728 v = &m->value;
729 }
730 break;
731 case kArrayType:
732 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
733 return false;
734 v = &((*v)[t->index]);
735 break;
736 default:
737 return false;
738 }
739 }
740
741 switch (v->GetType()) {
742 case kObjectType:
743 return v->EraseMember(GenericStringRef<Ch>(last->name, last->length));
744 case kArrayType:
745 if (last->index == kPointerInvalidIndex || last->index >= v->Size())
746 return false;
747 v->Erase(v->Begin() + last->index);
748 return true;
749 default:
750 return false;
751 }
752 }
753
754private:
756
762 Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0) {
763 if (!allocator_) // allocator is independently owned.
765
766 size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens
767 for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)
768 nameBufferSize += t->length;
769
770 tokenCount_ = rhs.tokenCount_ + extraToken;
771 tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch)));
772 nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
773 if (rhs.tokenCount_ > 0) {
774 std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token));
775 }
776 if (nameBufferSize > 0) {
777 std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
778 }
779
780 // Adjust pointers to name buffer
781 std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;
782 for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t)
783 t->name += diff;
784
785 return nameBuffer_ + nameBufferSize;
786 }
787
789
793 bool NeedPercentEncode(Ch c) const {
794 return !((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~');
795 }
796
798#ifndef __clang__ // -Wdocumentation
804#endif
805 void Parse(const Ch* source, size_t length) {
806 RAPIDJSON_ASSERT(source != NULL);
809
810 // Create own allocator if user did not supply.
811 if (!allocator_)
813
814 // Count number of '/' as tokenCount
815 tokenCount_ = 0;
816 for (const Ch* s = source; s != source + length; s++)
817 if (*s == '/')
818 tokenCount_++;
819
820 Token* token = tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch)));
821 Ch* name = nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
822 size_t i = 0;
823
824 // Detect if it is a URI fragment
825 bool uriFragment = false;
826 if (source[i] == '#') {
827 uriFragment = true;
828 i++;
829 }
830
831 if (i != length && source[i] != '/') {
833 goto error;
834 }
835
836 while (i < length) {
837 RAPIDJSON_ASSERT(source[i] == '/');
838 i++; // consumes '/'
839
840 token->name = name;
841 bool isNumber = true;
842
843 while (i < length && source[i] != '/') {
844 Ch c = source[i];
845 if (uriFragment) {
846 // Decoding percent-encoding for URI fragment
847 if (c == '%') {
848 PercentDecodeStream is(&source[i], source + length);
850 Ch* begin = os.PutBegin();
851 if (!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid()) {
853 goto error;
854 }
855 size_t len = os.PutEnd(begin);
856 i += is.Tell() - 1;
857 if (len == 1)
858 c = *name;
859 else {
860 name += len;
861 isNumber = false;
862 i++;
863 continue;
864 }
865 }
866 else if (NeedPercentEncode(c)) {
868 goto error;
869 }
870 }
871
872 i++;
873
874 // Escaping "~0" -> '~', "~1" -> '/'
875 if (c == '~') {
876 if (i < length) {
877 c = source[i];
878 if (c == '0') c = '~';
879 else if (c == '1') c = '/';
880 else {
882 goto error;
883 }
884 i++;
885 }
886 else {
888 goto error;
889 }
890 }
891
892 // First check for index: all of characters are digit
893 if (c < '0' || c > '9')
894 isNumber = false;
895
896 *name++ = c;
897 }
898 token->length = static_cast<SizeType>(name - token->name);
899 if (token->length == 0)
900 isNumber = false;
901 *name++ = '\0'; // Null terminator
902
903 // Second check for index: more than one digit cannot have leading zero
904 if (isNumber && token->length > 1 && token->name[0] == '0')
905 isNumber = false;
906
907 // String to SizeType conversion
908 SizeType n = 0;
909 if (isNumber) {
910 for (size_t j = 0; j < token->length; j++) {
911 SizeType m = n * 10 + static_cast<SizeType>(token->name[j] - '0');
912 if (m < n) { // overflow detection
913 isNumber = false;
914 break;
915 }
916 n = m;
917 }
918 }
919
920 token->index = isNumber ? n : kPointerInvalidIndex;
921 token++;
922 }
923
924 RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer
926 return;
927
928 error:
929 Allocator::Free(tokens_);
930 nameBuffer_ = 0;
931 tokens_ = 0;
932 tokenCount_ = 0;
934 return;
935 }
936
938
943 template<bool uriFragment, typename OutputStream>
944 bool Stringify(OutputStream& os) const {
945 RAPIDJSON_ASSERT(IsValid());
946
947 if (uriFragment)
948 os.Put('#');
949
950 for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
951 os.Put('/');
952 for (size_t j = 0; j < t->length; j++) {
953 Ch c = t->name[j];
954 if (c == '~') {
955 os.Put('~');
956 os.Put('0');
957 }
958 else if (c == '/') {
959 os.Put('~');
960 os.Put('1');
961 }
962 else if (uriFragment && NeedPercentEncode(c)) {
963 // Transcode to UTF8 sequence
965 PercentEncodeStream<OutputStream> target(os);
966 if (!Transcoder<EncodingType, UTF8<> >().Validate(source, target))
967 return false;
968 j += source.Tell() - 1;
969 }
970 else
971 os.Put(c);
972 }
973 }
974 return true;
975 }
976
978
984 public:
985 typedef typename ValueType::Ch Ch;
986
988
992 PercentDecodeStream(const Ch* source, const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {}
993
995 if (*src_ != '%' || src_ + 3 > end_) { // %XY triplet
996 valid_ = false;
997 return 0;
998 }
999 src_++;
1000 Ch c = 0;
1001 for (int j = 0; j < 2; j++) {
1002 c = static_cast<Ch>(c << 4);
1003 Ch h = *src_;
1004 if (h >= '0' && h <= '9') c = static_cast<Ch>(c + h - '0');
1005 else if (h >= 'A' && h <= 'F') c = static_cast<Ch>(c + h - 'A' + 10);
1006 else if (h >= 'a' && h <= 'f') c = static_cast<Ch>(c + h - 'a' + 10);
1007 else {
1008 valid_ = false;
1009 return 0;
1010 }
1011 src_++;
1012 }
1013 return c;
1014 }
1015
1016 size_t Tell() const { return static_cast<size_t>(src_ - head_); }
1017 bool IsValid() const { return valid_; }
1018
1019 private:
1020 const Ch* src_;
1021 const Ch* head_;
1022 const Ch* end_;
1023 bool valid_;
1024 };
1025
1027 template <typename OutputStream>
1029 public:
1030 PercentEncodeStream(OutputStream& os) : os_(os) {}
1031 void Put(char c) { // UTF-8 must be byte
1032 unsigned char u = static_cast<unsigned char>(c);
1033 static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1034 os_.Put('%');
1035 os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u >> 4]));
1036 os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u & 15]));
1037 }
1038 private:
1039 OutputStream& os_;
1040 };
1041
1045 Token* tokens_;
1049};
1050
1053
1055
1056
1058
1059template <typename T>
1060typename T::ValueType& CreateValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::AllocatorType& a) {
1061 return pointer.Create(root, a);
1062}
1063
1064template <typename T, typename CharType, size_t N>
1065typename T::ValueType& CreateValueByPointer(T& root, const CharType(&source)[N], typename T::AllocatorType& a) {
1066 return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a);
1067}
1068
1069// No allocator parameter
1070
1071template <typename DocumentType>
1072typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer) {
1073 return pointer.Create(document);
1074}
1075
1076template <typename DocumentType, typename CharType, size_t N>
1077typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const CharType(&source)[N]) {
1078 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document);
1079}
1080
1082
1083template <typename T>
1084typename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
1085 return pointer.Get(root, unresolvedTokenIndex);
1086}
1087
1088template <typename T>
1089const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
1090 return pointer.Get(root, unresolvedTokenIndex);
1091}
1092
1093template <typename T, typename CharType, size_t N>
1094typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) {
1095 return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1096}
1097
1098template <typename T, typename CharType, size_t N>
1099const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) {
1100 return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1101}
1102
1104
1105template <typename T>
1106typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
1107 return pointer.GetWithDefault(root, defaultValue, a);
1108}
1109
1110template <typename T>
1111typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* defaultValue, typename T::AllocatorType& a) {
1112 return pointer.GetWithDefault(root, defaultValue, a);
1113}
1114
1115#if RAPIDJSON_HAS_STDSTRING
1116template <typename T>
1117typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {
1118 return pointer.GetWithDefault(root, defaultValue, a);
1119}
1120#endif
1121
1122template <typename T, typename T2>
1123RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1124GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 defaultValue, typename T::AllocatorType& a) {
1125 return pointer.GetWithDefault(root, defaultValue, a);
1126}
1127
1128template <typename T, typename CharType, size_t N>
1129typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
1130 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1131}
1132
1133template <typename T, typename CharType, size_t N>
1134typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::Ch* defaultValue, typename T::AllocatorType& a) {
1135 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1136}
1137
1138#if RAPIDJSON_HAS_STDSTRING
1139template <typename T, typename CharType, size_t N>
1140typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {
1141 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1142}
1143#endif
1144
1145template <typename T, typename CharType, size_t N, typename T2>
1146RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1147GetValueByPointerWithDefault(T& root, const CharType(&source)[N], T2 defaultValue, typename T::AllocatorType& a) {
1148 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1149}
1150
1151// No allocator parameter
1152
1153template <typename DocumentType>
1154typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& defaultValue) {
1155 return pointer.GetWithDefault(document, defaultValue);
1156}
1157
1158template <typename DocumentType>
1159typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* defaultValue) {
1160 return pointer.GetWithDefault(document, defaultValue);
1161}
1162
1163#if RAPIDJSON_HAS_STDSTRING
1164template <typename DocumentType>
1165typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1166 return pointer.GetWithDefault(document, defaultValue);
1167}
1168#endif
1169
1170template <typename DocumentType, typename T2>
1171RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1173 return pointer.GetWithDefault(document, defaultValue);
1174}
1175
1176template <typename DocumentType, typename CharType, size_t N>
1177typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& defaultValue) {
1178 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1179}
1180
1181template <typename DocumentType, typename CharType, size_t N>
1182typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* defaultValue) {
1183 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1184}
1185
1186#if RAPIDJSON_HAS_STDSTRING
1187template <typename DocumentType, typename CharType, size_t N>
1188typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1189 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1190}
1191#endif
1192
1193template <typename DocumentType, typename CharType, size_t N, typename T2>
1194RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1195GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) {
1196 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1197}
1198
1200
1201template <typename T>
1202typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
1203 return pointer.Set(root, value, a);
1204}
1205
1206template <typename T>
1207typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& value, typename T::AllocatorType& a) {
1208 return pointer.Set(root, value, a);
1209}
1210
1211template <typename T>
1212typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* value, typename T::AllocatorType& a) {
1213 return pointer.Set(root, value, a);
1214}
1215
1216#if RAPIDJSON_HAS_STDSTRING
1217template <typename T>
1218typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {
1219 return pointer.Set(root, value, a);
1220}
1221#endif
1222
1223template <typename T, typename T2>
1224RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1225SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 value, typename T::AllocatorType& a) {
1226 return pointer.Set(root, value, a);
1227}
1228
1229template <typename T, typename CharType, size_t N>
1230typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
1232}
1233
1234template <typename T, typename CharType, size_t N>
1235typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::ValueType& value, typename T::AllocatorType& a) {
1237}
1238
1239template <typename T, typename CharType, size_t N>
1240typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::Ch* value, typename T::AllocatorType& a) {
1242}
1243
1244#if RAPIDJSON_HAS_STDSTRING
1245template <typename T, typename CharType, size_t N>
1246typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {
1248}
1249#endif
1250
1251template <typename T, typename CharType, size_t N, typename T2>
1252RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1253SetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) {
1255}
1256
1257// No allocator parameter
1258
1259template <typename DocumentType>
1260typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
1261 return pointer.Set(document, value);
1262}
1263
1264template <typename DocumentType>
1265typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& value) {
1266 return pointer.Set(document, value);
1267}
1268
1269template <typename DocumentType>
1270typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* value) {
1271 return pointer.Set(document, value);
1272}
1273
1274#if RAPIDJSON_HAS_STDSTRING
1275template <typename DocumentType>
1276typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& value) {
1277 return pointer.Set(document, value);
1278}
1279#endif
1280
1281template <typename DocumentType, typename T2>
1282RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1284 return pointer.Set(document, value);
1285}
1286
1287template <typename DocumentType, typename CharType, size_t N>
1288typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
1290}
1291
1292template <typename DocumentType, typename CharType, size_t N>
1293typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& value) {
1295}
1296
1297template <typename DocumentType, typename CharType, size_t N>
1298typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* value) {
1300}
1301
1302#if RAPIDJSON_HAS_STDSTRING
1303template <typename DocumentType, typename CharType, size_t N>
1304typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& value) {
1306}
1307#endif
1308
1309template <typename DocumentType, typename CharType, size_t N, typename T2>
1310RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1311SetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) {
1313}
1314
1316
1317template <typename T>
1318typename T::ValueType& SwapValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
1319 return pointer.Swap(root, value, a);
1320}
1321
1322template <typename T, typename CharType, size_t N>
1323typename T::ValueType& SwapValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
1325}
1326
1327template <typename DocumentType>
1328typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
1329 return pointer.Swap(document, value);
1330}
1331
1332template <typename DocumentType, typename CharType, size_t N>
1333typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
1335}
1336
1338
1339template <typename T>
1341 return pointer.Erase(root);
1342}
1343
1344template <typename T, typename CharType, size_t N>
1345bool EraseValueByPointer(T& root, const CharType(&source)[N]) {
1347}
1348
1350
1352
1353#if defined(__clang__) || defined(_MSC_VER)
1354RAPIDJSON_DIAG_POP
1355#endif
1356
1357#endif // RAPIDJSON_POINTER_H_
#define s(x, c)
Definition aesb.c:47
static uint64_t h
Definition blockchain_stats.cpp:55
A document for parsing JSON text as DOM.
Definition document.h:2130
Ch Take()
Definition pointer.h:994
size_t Tell() const
Definition pointer.h:1016
PercentDecodeStream(const Ch *source, const Ch *end)
Constructor.
Definition pointer.h:992
bool IsValid() const
Definition pointer.h:1017
const Ch * src_
Current read position.
Definition pointer.h:1020
ValueType::Ch Ch
Definition pointer.h:985
bool valid_
Whether the parsing is valid.
Definition pointer.h:1023
const Ch * end_
Past-the-end position.
Definition pointer.h:1022
const Ch * head_
Original head of the string.
Definition pointer.h:1021
PercentEncodeStream(OutputStream &os)
Definition pointer.h:1030
OutputStream & os_
Definition pointer.h:1039
void Put(char c)
Definition pointer.h:1031
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition pointer.h:79
ValueType & Swap(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, ValueType &value) const
Swap a value with a value in a document.
Definition pointer.h:701
Ch * CopyFromRaw(const GenericPointer &rhs, size_t extraToken=0, size_t extraNameBufferSize=0)
Clone the content from rhs to this.
Definition pointer.h:762
T value
Definition pointer.h:640
bool Stringify(OutputStream &os) const
Stringify to string or URI fragment representation.
Definition pointer.h:944
ValueType & Set(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, const Ch *value) const
Set a null-terminated string in a document.
Definition pointer.h:658
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T >, internal::IsGenericValue< T > >),(ValueType &)) Set(GenericDocument< EncodingType
Set a primitive value in a document.
ValueType & Set(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, const ValueType &value) const
Set a value in a document, with copy semantics.
Definition pointer.h:652
Ch * nameBuffer_
Definition pointer.h:1044
CrtAllocator * allocator_
Definition pointer.h:1042
GenericPointer(const GenericPointer &rhs, Allocator *allocator)
Copy constructor.
Definition pointer.h:171
GenericPointer(const Ch *source, Allocator *allocator=0)
Constructor that parses a string or URI fragment representation.
Definition pointer.h:114
Value::EncodingType EncodingType
Definition pointer.h:81
GenericPointer(const Token *tokens, size_t tokenCount)
Constructor with user-supplied tokens.
Definition pointer.h:163
void Parse(const Ch *source, size_t length)
Parse a JSON String or its URI fragment representation into tokens.
Definition pointer.h:805
ValueType & Set(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, ValueType &value) const
Set a value in a document, with move semantics.
Definition pointer.h:646
GenericPointer(Allocator *allocator=0)
Default constructor.
Definition pointer.h:107
Allocator stackAllocator stackAllocator & document
Definition pointer.h:594
ValueType & Swap(ValueType &root, ValueType &value, typename ValueType::AllocatorType &allocator) const
Swap a value with a value in a subtree.
Definition pointer.h:695
size_t tokenCount_
Definition pointer.h:1046
bool Erase(ValueType &root) const
Erase a value in a subtree.
Definition pointer.h:714
GenericPointer(const GenericPointer &rhs)
Copy constructor.
Definition pointer.h:166
bool NeedPercentEncode(Ch c) const
Check whether a character should be percent-encoded.
Definition pointer.h:793
ValueType & Set(ValueType &root, ValueType &value, typename ValueType::AllocatorType &allocator) const
Set a value in a subtree, with move semantics.
Definition pointer.h:613
PointerParseErrorCode parseErrorCode_
Definition pointer.h:1048
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T >, internal::IsGenericValue< T > >),(ValueType &)) Set(ValueType &root
Set a primitive value in a subtree.
ValueType & Set(ValueType &root, const ValueType &value, typename ValueType::AllocatorType &allocator) const
Set a value in a subtree, with copy semantics.
Definition pointer.h:618
Token * tokens_
Definition pointer.h:1045
CrtAllocator * ownAllocator_
Definition pointer.h:1043
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:137
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:232
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
Definition pointer.h:214
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:82
~GenericPointer()
Destructor.
Definition pointer.h:176
size_t parseErrorOffset_
Definition pointer.h:1047
ValueType & Set(ValueType &root, const Ch *value, typename ValueType::AllocatorType &allocator) const
Set a null-terminated string in a subtree.
Definition pointer.h:623
GenericPointer & operator=(const GenericPointer &rhs)
Assignment operator.
Definition pointer.h:183
CrtAllocator * allocator
Definition pointer.h:245
Allocator stackAllocator RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T >, internal::IsGenericValue< T > >),(ValueType &)) GetWithDefault(GenericDocument< EncodingType
Concept for allocating, resizing and freeing memory block.
bool operator!=(expect< T > const &lhs, expect< U > const &rhs) noexcept(noexcept(lhs.equal(rhs)))
Definition expect.h:423
bool operator==(expect< T > const &lhs, expect< U > const &rhs) noexcept(noexcept(lhs.equal(rhs)))
Definition expect.h:402
GenericPointer< Value, CrtAllocator > Pointer
Definition fwd.h:128
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition rapidjson.h:411
#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 parsing.
Definition pointer.h:37
@ kPointerParseErrorInvalidEscape
Invalid escape.
Definition pointer.h:41
@ kPointerParseErrorTokenMustBeginWithSolidus
A token must begin with a '/'.
Definition pointer.h:40
@ kPointerParseErrorNone
The parse is successful.
Definition pointer.h:38
@ kPointerParseErrorCharacterMustPercentEncode
A character must percent encoded in URI fragment.
Definition pointer.h:43
@ kPointerParseErrorInvalidPercentEncoding
Invalid percent encoding in URI fragment.
Definition pointer.h:42
#define true
#define const
Definition ipfrdr.c:80
t
Definition console.py:33
GetTokens(source)
Definition tokenize.py:119
char * u64toa(uint64_t value, char *buffer)
Definition itoa.h:126
SizeType StrLen(const Ch *s)
Custom strlen() which works on different character types.
Definition strfunc.h:31
char * u32toa(uint32_t value, char *buffer)
Definition itoa.h:39
int i
Definition pymoduletest.py:23
const char * name
Definition options.c:30
const GenericPointer< typename T::ValueType > T2 value
Definition pointer.h:1225
const GenericPointer< typename T::ValueType > T2 defaultValue
Definition pointer.h:1124
T::ValueType & SwapValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition pointer.h:1318
T::ValueType & SetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition pointer.h:1202
T::ValueType * GetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, size_t *unresolvedTokenIndex=0)
Definition pointer.h:1084
bool EraseValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer)
Definition pointer.h:1340
T::ValueType & CreateValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::AllocatorType &a)
Definition pointer.h:1060
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:1124
T::ValueType & GetValueByPointerWithDefault(T &root, const GenericPointer< typename T::ValueType > &pointer, const typename T::ValueType &defaultValue, typename T::AllocatorType &a)
Definition pointer.h:1106
const CharType(& source)[N]
Definition pointer.h:1147
static RAPIDJSON_NAMESPACE_BEGIN const SizeType kPointerInvalidIndex
Represents an invalid index in GenericPointer::Token.
Definition pointer.h:31
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1124
@ kObjectType
object
Definition rapidjson.h:627
@ kArrayType
array
Definition rapidjson.h:628
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition rapidjson.h:610
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.).
Definition rapidjson.h:389
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition rapidjson.h:606
A read-write string stream.
Definition stream.h:188
Ch * PutBegin()
Definition stream.h:201
size_t PutEnd(Ch *begin)
Definition stream.h:202
A token is the basic units of internal representation.
Definition pointer.h:97
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
Name of the token. It has null character at the end but it can contain null character.
Definition pointer.h:98
Reference to a constant string (not taking a copy).
Definition document.h:253
Read-only string stream.
Definition stream.h:154
Encoding conversion.
Definition encodings.h:658
UTF-8 encoding.
Definition encodings.h:96
Definition document.h:416
#define T(x)