275 {
277 }
278
279#if RAPIDJSON_HAS_STDSTRING
281
288 }
289#endif
290
292
298 char buffer[21];
301 buffer[length] = '\0';
302
303 if (
sizeof(
Ch) == 1) {
304 Token token = {
reinterpret_cast<Ch*
>(buffer), length, index };
306 }
307 else {
309 for (size_t i = 0; i <= length; i++)
310 name[i] =
static_cast<Ch>(buffer[i]);
311 Token token = {
name, length, index };
313 }
314 }
315
317
323 if (token.IsString())
325 else {
329 }
330 }
331
333
334
337
340
343
345
348
350
351
353 const Token* GetTokens()
const {
return tokens_; }
354
356 size_t GetTokenCount()
const {
return tokenCount_; }
357
359
361
362
364
369 return false;
370
375 {
376 return false;
377 }
378 }
379
380 return true;
381 }
382
384
388
390
394 if (!IsValid())
395 return false;
396 if (!rhs.IsValid())
397 return true;
398
401
405
408
411 }
412
413 return false;
414 }
415
417
419
420
422
426 template<typename OutputStream>
427 bool Stringify(OutputStream&
os)
const {
428 return Stringify<false, OutputStream>(
os);
429 }
430
432
436 template<typename OutputStream>
437 bool StringifyUriFragment(OutputStream&
os)
const {
438 return Stringify<true, OutputStream>(
os);
439 }
440
442
444
445
447
461 ValueType& Create(ValueType& root,
typename ValueType::AllocatorType&
allocator,
bool* alreadyExist = 0)
const {
464 bool exist = true;
466 if (v->IsArray() && t->name[0] == '-' && t->length == 1) {
468 v = &((*v)[v->Size() - 1]);
469 exist = false;
470 }
471 else {
472 if (t->index == kPointerInvalidIndex) {
473 if (!v->IsObject())
474 v->SetObject();
475 }
476 else {
477 if (!v->IsArray() && !v->IsObject())
478 v->SetArray();
479 }
480
481 if (v->IsArray()) {
482 if (t->index >= v->Size()) {
484 while (t->index >= v->Size())
486 exist = false;
487 }
488 v = &((*v)[t->index]);
489 }
490 else {
492 if (m == v->MemberEnd()) {
494 v = &(--v->MemberEnd())->value;
495 exist = false;
496 }
497 else
498 v = &m->value;
499 }
500 }
501 }
502
503 if (alreadyExist)
504 *alreadyExist = exist;
505
506 return *v;
507 }
508
510
515 template <typename stackAllocator>
517 return Create(document, document.
GetAllocator(), alreadyExist);
518 }
519
521
523
524
526
539 ValueType* Get(ValueType& root,
size_t* unresolvedTokenIndex = 0)
const {
543 switch (v->GetType()) {
545 {
547 if (m == v->MemberEnd())
548 break;
549 v = &m->value;
550 }
551 continue;
553 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
554 break;
555 v = &((*v)[t->index]);
556 continue;
557 default:
558 break;
559 }
560
561
562 if (unresolvedTokenIndex)
563 *unresolvedTokenIndex =
static_cast<size_t>(t -
tokens_);
564 return 0;
565 }
566 return v;
567 }
568
570
574 const ValueType* Get(
const ValueType& root,
size_t* unresolvedTokenIndex = 0)
const {
575 return Get(
const_cast<ValueType&
>(root), unresolvedTokenIndex);
576 }
577
579
581
582
584
594 bool alreadyExist;
597 }
598
601 bool alreadyExist;
604 }
605
606#if RAPIDJSON_HAS_STDSTRING
609 bool alreadyExist;
612 }
613#endif
614
616
619 template <typename T>
623 }
624
626 template <typename stackAllocator>
629 }
630
632 template <typename stackAllocator>
635 }
636
637#if RAPIDJSON_HAS_STDSTRING
639 template <typename stackAllocator>
642 }
643#endif
644
646
649 template <typename T, typename stackAllocator>
653 }
654
656
658
659
661
672 }
673
677 }
678
682 }
683
684#if RAPIDJSON_HAS_STDSTRING
686 ValueType& Set(ValueType& root,
const std::basic_string<Ch>&
value,
typename ValueType::AllocatorType&
allocator)
const {
688 }
689#endif
690
692
695 template <typename T>
697 Set(ValueType& root,
T value,
typename ValueType::AllocatorType&
allocator)
const {
699 }
700
702 template <typename stackAllocator>
704 return Create(document) =
value;
705 }
706
708 template <typename stackAllocator>
711 }
712
714 template <typename stackAllocator>
717 }
718
719#if RAPIDJSON_HAS_STDSTRING
721 template <typename stackAllocator>
724 }
725#endif
726
728
731 template <typename T, typename stackAllocator>
734 return Create(document) =
value;
735 }
736
738
740
741
743
754 }
755
757 template <typename stackAllocator>
760 }
761
763
765
771 bool Erase(ValueType& root) const {
774 return false;
775
778 for (
const Token *t =
tokens_; t != last; ++t) {
779 switch (v->GetType()) {
781 {
783 if (m == v->MemberEnd())
784 return false;
785 v = &m->value;
786 }
787 break;
789 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
790 return false;
791 v = &((*v)[t->index]);
792 break;
793 default:
794 return false;
795 }
796 }
797
798 switch (v->GetType()) {
802 if (last->index == kPointerInvalidIndex || last->index >= v->Size())
803 return false;
804 v->Erase(v->Begin() + last->index);
805 return true;
806 default:
807 return false;
808 }
809 }
810
811private:
813
819 Ch* CopyFromRaw(
const GenericPointer& rhs,
size_t extraToken = 0,
size_t extraNameBufferSize = 0) {
822
825 nameBufferSize += t->length;
826
832 }
833 if (nameBufferSize > 0) {
835 }
836
837
841
843 }
844
846
850 bool NeedPercentEncode(
Ch c)
const {
851 return !((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~');
852 }
853
855#ifndef __clang__
861#endif
862 void Parse(
const Ch*
source,
size_t length) {
866
867
870
871
876
879 size_t i = 0;
880
881
882 bool uriFragment = false;
884 uriFragment = true;
885 i++;
886 }
887
888 if (i != length &&
source[i] !=
'/') {
890 goto error;
891 }
892
893 while (i < length) {
895 i++;
896
898 bool isNumber = true;
899
900 while (i < length &&
source[i] !=
'/') {
902 if (uriFragment) {
903
904 if (c == '%') {
907 Ch* begin =
os.PutBegin();
910 goto error;
911 }
912 size_t len =
os.PutEnd(begin);
913 i += is.Tell() - 1;
916 else {
918 isNumber = false;
919 i++;
920 continue;
921 }
922 }
923 else if (NeedPercentEncode(c)) {
925 goto error;
926 }
927 }
928
929 i++;
930
931
932 if (c == '~') {
933 if (i < length) {
935 if (c == '0') c = '~';
936 else if (c == '1') c = '/';
937 else {
939 goto error;
940 }
941 i++;
942 }
943 else {
945 goto error;
946 }
947 }
948
949
950 if (c < '0' || c > '9')
951 isNumber = false;
952
954 }
955 token->length =
static_cast<SizeType>(
name - token->name);
956 if (token->length == 0)
957 isNumber = false;
959
960
961 if (isNumber && token->length > 1 && token->name[0] == '0')
962 isNumber = false;
963
964
966 if (isNumber) {
967 for (
size_t j = 0;
j < token->length;
j++) {
969 if (m < n) {
970 isNumber = false;
971 break;
972 }
973 n = m;
974 }
975 }
976
977 token->index = isNumber ? n : kPointerInvalidIndex;
978 token++;
979 }
980
983 return;
984
985 error:
991 return;
992 }
993
995
1000 template<bool uriFragment, typename OutputStream>
1001 bool Stringify(OutputStream&
os)
const {
1003
1004 if (uriFragment)
1006
1009 for (
size_t j = 0;
j < t->length;
j++) {
1011 if (c == '~') {
1014 }
1015 else if (c == '/') {
1018 }
1019 else if (uriFragment && NeedPercentEncode(c)) {
1020
1022 PercentEncodeStream<OutputStream> target(
os);
1024 return false;
1026 }
1027 else
1029 }
1030 }
1031 return true;
1032 }
1033
1035
1040 class PercentDecodeStream {
1041 public:
1042 typedef typename ValueType::Ch
Ch;
1043
1045
1049 PercentDecodeStream(
const Ch*
source,
const Ch* end) : src_(
source), head_(
source), end_(end), valid_(true) {}
1050
1052 if (*src_ != '%' || src_ + 3 > end_) {
1053 valid_ = false;
1054 return 0;
1055 }
1056 src_++;
1058 for (
int j = 0;
j < 2;
j++) {
1059 c =
static_cast<Ch>(c << 4);
1061 if (h >=
'0' && h <=
'9') c =
static_cast<Ch>(c + h -
'0');
1062 else if (h >=
'A' && h <=
'F') c =
static_cast<Ch>(c + h -
'A' + 10);
1063 else if (h >=
'a' && h <=
'f') c =
static_cast<Ch>(c + h -
'a' + 10);
1064 else {
1065 valid_ = false;
1066 return 0;
1067 }
1068 src_++;
1069 }
1070 return c;
1071 }
1072
1073 size_t Tell() const { return static_cast<size_t>(src_ - head_); }
1074 bool IsValid() const { return valid_; }
1075
1076 private:
1080 bool valid_;
1081 };
bool operator<(const CBigNum &a, const CBigNum &b)
A document for parsing JSON text as DOM.
Allocator & GetAllocator()
Get the allocator of this document.
ValueType::EncodingType EncodingType
Encoding type from Value.
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 & Swap(GenericPointer &other) RAPIDJSON_NOEXCEPT
Swap the content of this pointer with an other.
Concept for allocating, resizing and freeing memory block.
bool operator!=(const environment &other)
bool operator==(const environment &other)
#define RAPIDJSON_ASSERT(x)
Assertion.
PointerParseErrorCode
Error code of parsing.
@ kPointerParseErrorInvalidEscape
Invalid escape.
@ kPointerParseErrorTokenMustBeginWithSolidus
A token must begin with a '/'.
@ kPointerParseErrorCharacterMustPercentEncode
A character must percent encoded in URI fragment.
@ kPointerParseErrorInvalidPercentEncoding
Invalid percent encoding in URI fragment.
void diff(const std::string &a, const std::string &b)
char * u64toa(uint64_t value, char *buffer)
char * u32toa(uint32_t value, char *buffer)
const GenericPointer< typename T::ValueType > T2 value
const GenericPointer< typename T::ValueType > T2 defaultValue
#define T(meth, val, expected)
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
A read-write string stream.
SizeType index
A valid array index, if it is not equal to kPointerInvalidIndex.
SizeType length
Length of the name.
const Ch * name
Name of the token. It has null character at the end but it can contain null character.
Reference to a constant string (not taking a copy)
void cmp(const Operand &op, uint32 imm)