15 #ifndef RAPIDJSON_POINTER_H_
16 #define RAPIDJSON_POINTER_H_
19 #include "internal/itoa.h"
21 RAPIDJSON_NAMESPACE_BEGIN
70 template <
typename ValueType,
typename Allocator = CrtAllocator>
74 typedef typename EncodingType::Ch
Ch;
107 Parse(source, internal::StrLen(source));
110 #if RAPIDJSON_HAS_STDSTRING
118 Parse(source.c_str(), source.size());
130 Parse(source, length);
165 Allocator::Free(tokens_);
174 Allocator::Free(tokens_);
176 tokenCount_ = rhs.tokenCount_;
177 parseErrorOffset_ = rhs.parseErrorOffset_;
178 parseErrorCode_ = rhs.parseErrorCode_;
183 tokens_ = rhs.tokens_;
203 r.allocator_ = allocator;
204 Ch *p = r.CopyFromRaw(*
this, 1, token.
length + 1);
205 std::memcpy(p, token.
name, (token.
length + 1) *
sizeof(
Ch));
206 r.tokens_[tokenCount_].
name = p;
220 Token token = { name, length, kPointerInvalidIndex };
221 return Append(token, allocator);
230 template <
typename T>
233 return Append(name, StrLen(name), allocator);
236 #if RAPIDJSON_HAS_STDSTRING
244 return Append(name.c_str(),
static_cast<SizeType>(name.size()), allocator);
256 SizeType length = (
sizeof(
SizeType) == 4 ? internal::u32toa(index, buffer): internal::u64toa(index, buffer)) - buffer;
257 buffer[length] =
'\0';
259 if (
sizeof(
Ch) == 1) {
260 Token token = { (
Ch*)buffer, length, index };
261 return Append(token, allocator);
265 for (
size_t i = 0; i <= length; i++)
267 Token token = { name, length, index };
268 return Append(token, allocator);
279 if (token.IsString())
280 return Append(token.GetString(), token.GetStringLength(), allocator);
284 return Append(static_cast<SizeType>(token.GetUint64()), allocator);
321 if (!IsValid() || !rhs.
IsValid() || tokenCount_ != rhs.tokenCount_)
324 for (
size_t i = 0; i < tokenCount_; i++) {
325 if (tokens_[i].index != rhs.tokens_[i].
index ||
326 tokens_[i].length != rhs.tokens_[i].
length ||
327 (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].
name,
sizeof(
Ch)* tokens_[i].length) != 0))
352 template<
typename OutputStream>
354 return Stringify<false, OutputStream>(os);
362 template<
typename OutputStream>
364 return Stringify<true, OutputStream>(os);
387 ValueType&
Create(ValueType& root,
typename ValueType::AllocatorType& allocator,
bool* alreadyExist = 0)
const {
389 ValueType* v = &root;
391 for (
const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
392 if (v->IsArray() && t->name[0] ==
'-' && t->length == 1) {
393 v->PushBack(
Value().Move(), allocator);
394 v = &((*v)[v->Size() - 1]);
398 if (t->index == kPointerInvalidIndex) {
403 if (!v->IsArray() && !v->IsObject())
408 if (t->index >= v->Size()) {
409 v->Reserve(t->index + 1, allocator);
410 while (t->index >= v->Size())
411 v->PushBack(
Value().Move(), allocator);
414 v = &((*v)[t->index]);
418 if (m == v->MemberEnd()) {
419 v->AddMember(
Value(t->name, t->length, allocator).Move(),
Value().Move(), allocator);
420 v = &(--v->MemberEnd())->value;
430 *alreadyExist = exist;
442 template <
typename stackAllocator>
444 return Create(document, document.
GetAllocator(), alreadyExist);
457 ValueType*
Get(ValueType& root)
const {
459 ValueType* v = &root;
460 for (
const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
461 switch (v->GetType()) {
465 if (m == v->MemberEnd())
471 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
473 v = &((*v)[t->index]);
487 const ValueType*
Get(
const ValueType& root)
const {
return Get(const_cast<ValueType&>(root)); }
504 ValueType&
GetWithDefault(ValueType& root,
const ValueType& defaultValue,
typename ValueType::AllocatorType& allocator)
const {
506 Value& v = Create(root, allocator, &alreadyExist);
507 return alreadyExist ? v : v.
CopyFrom(defaultValue, allocator);
511 ValueType&
GetWithDefault(ValueType& root,
const Ch* defaultValue,
typename ValueType::AllocatorType& allocator)
const {
513 Value& v = Create(root, allocator, &alreadyExist);
514 return alreadyExist ? v : v.
SetString(defaultValue, allocator);
517 #if RAPIDJSON_HAS_STDSTRING
519 ValueType&
GetWithDefault(ValueType& root,
const std::basic_string<Ch>& defaultValue,
typename ValueType::AllocatorType& allocator)
const {
521 Value& v = Create(root, allocator, &alreadyExist);
522 return alreadyExist ? v : v.
SetString(defaultValue, allocator);
530 template <
typename T>
531 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
532 GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator)
const {
533 return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);
537 template <
typename stackAllocator>
539 return GetWithDefault(document, defaultValue, document.
GetAllocator());
543 template <
typename stackAllocator>
545 return GetWithDefault(document, defaultValue, document.
GetAllocator());
548 #if RAPIDJSON_HAS_STDSTRING
550 template <
typename stackAllocator>
552 return GetWithDefault(document, defaultValue, document.
GetAllocator());
560 template <
typename T,
typename stackAllocator>
561 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
563 return GetWithDefault(document, defaultValue, document.GetAllocator());
581 ValueType&
Set(ValueType& root, ValueType& value,
typename ValueType::AllocatorType& allocator)
const {
582 return Create(root, allocator) = value;
586 ValueType&
Set(ValueType& root,
const ValueType& value,
typename ValueType::AllocatorType& allocator)
const {
587 return Create(root, allocator).CopyFrom(value, allocator);
591 ValueType&
Set(ValueType& root,
const Ch* value,
typename ValueType::AllocatorType& allocator)
const {
592 return Create(root, allocator) = ValueType(value, allocator).Move();
595 #if RAPIDJSON_HAS_STDSTRING
597 ValueType&
Set(ValueType& root,
const std::basic_string<Ch>& value,
typename ValueType::AllocatorType& allocator)
const {
598 return Create(root, allocator) = ValueType(value, allocator).Move();
606 template <
typename T>
607 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
608 Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator)
const {
609 return Create(root, allocator) = ValueType(value).Move();
613 template <
typename stackAllocator>
615 return Create(document) = value;
619 template <
typename stackAllocator>
621 return Create(document).CopyFrom(value, document.
GetAllocator());
625 template <
typename stackAllocator>
627 return Create(document) = ValueType(value, document.
GetAllocator()).Move();
630 #if RAPIDJSON_HAS_STDSTRING
632 template <
typename stackAllocator>
634 return Create(document) = ValueType(value, document.
GetAllocator()).Move();
642 template <
typename T,
typename stackAllocator>
643 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
645 return Create(document) = value;
663 ValueType&
Swap(ValueType& root, ValueType& value,
typename ValueType::AllocatorType& allocator)
const {
664 return Create(root, allocator).Swap(value);
668 template <
typename stackAllocator>
670 return Create(document).Swap(value);
684 if (tokenCount_ == 0)
687 ValueType* v = &root;
688 const Token* last = tokens_ + (tokenCount_ - 1);
689 for (
const Token *t = tokens_; t != last; ++t) {
690 switch (v->GetType()) {
694 if (m == v->MemberEnd())
700 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
702 v = &((*v)[t->index]);
709 switch (v->GetType()) {
713 if (last->
index == kPointerInvalidIndex || last->
index >= v->Size())
715 v->Erase(v->Begin() + last->
index);
730 Ch* CopyFromRaw(
const GenericPointer& rhs,
size_t extraToken = 0,
size_t extraNameBufferSize = 0) {
734 size_t nameBufferSize = rhs.tokenCount_;
735 for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)
736 nameBufferSize += t->length;
738 tokenCount_ = rhs.tokenCount_ + extraToken;
739 tokens_ =
static_cast<Token *
>(allocator_->Malloc(tokenCount_ *
sizeof(Token) + (nameBufferSize + extraNameBufferSize) *
sizeof(Ch)));
740 nameBuffer_ =
reinterpret_cast<Ch *
>(tokens_ + tokenCount_);
741 std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ *
sizeof(Token));
742 std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize *
sizeof(Ch));
745 std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;
746 for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t)
749 return nameBuffer_ + nameBufferSize;
757 bool NeedPercentEncode(Ch c)
const {
758 return !((c >=
'0' && c <= '9') || (c >=
'A' && c <='Z') || (c >=
'a' && c <=
'z') || c ==
'-' || c ==
'.' || c ==
'_' || c ==
'~');
767 void Parse(
const Ch* source,
size_t length) {
778 for (
const Ch* s = source; s != source + length; s++)
782 Token* token = tokens_ =
static_cast<Token *
>(allocator_->Malloc(tokenCount_ *
sizeof(Token) + length *
sizeof(Ch)));
783 Ch* name = nameBuffer_ =
reinterpret_cast<Ch *
>(tokens_ + tokenCount_);
787 bool uriFragment =
false;
788 if (source[i] ==
'#') {
793 if (i != length && source[i] !=
'/') {
803 bool isNumber =
true;
805 while (i < length && source[i] !=
'/') {
810 PercentDecodeStream is(&source[i], source + length);
811 GenericInsituStringStream<EncodingType> os(name);
812 Ch* begin = os.PutBegin();
813 if (!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid()) {
817 size_t len = os.PutEnd(begin);
828 else if (NeedPercentEncode(c)) {
840 if (c ==
'0') c =
'~';
841 else if (c ==
'1') c =
'/';
855 if (c < '0' || c >
'9')
860 token->length = name - token->name;
861 if (token->length == 0)
866 if (isNumber && token->length > 1 && token->name[0] ==
'0')
872 for (
size_t j = 0; j < token->length; j++) {
882 token->index = isNumber ? n : kPointerInvalidIndex;
891 Allocator::Free(tokens_);
895 parseErrorOffset_ = i;
905 template<
bool uriFragment,
typename OutputStream>
906 bool Stringify(OutputStream& os)
const {
912 for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
914 for (
size_t j = 0; j < t->length; j++) {
924 else if (uriFragment && NeedPercentEncode(c)) {
926 GenericStringStream<typename ValueType::EncodingType> source(&t->name[j]);
927 PercentEncodeStream<OutputStream> target(os);
928 if (!Transcoder<EncodingType, UTF8<> >().Validate(source, target))
930 j += source.Tell() - 1;
945 class PercentDecodeStream {
952 PercentDecodeStream(
const Ch* source,
const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {}
955 if (*src_ !=
'%' || src_ + 3 > end_) {
961 for (
int j = 0; j < 2; j++) {
964 if (h >=
'0' && h <=
'9') c += h -
'0';
965 else if (h >=
'A' && h <=
'F') c += h -
'A' + 10;
966 else if (h >=
'a' && h <=
'f') c += h -
'a' + 10;
976 size_t Tell()
const {
return src_ - head_; }
977 bool IsValid()
const {
return valid_; }
987 template <
typename OutputStream>
988 class PercentEncodeStream {
990 PercentEncodeStream(OutputStream& os) : os_(os) {}
992 unsigned char u =
static_cast<unsigned char>(c);
993 static const char hexDigits[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
995 os_.Put(hexDigits[u >> 4]);
996 os_.Put(hexDigits[u & 15]);
1002 Allocator* allocator_;
1003 Allocator* ownAllocator_;
1007 size_t parseErrorOffset_;
1019 template <
typename T>
1021 return pointer.
Create(root, a);
1024 template <
typename T,
typename CharType,
size_t N>
1025 typename T::ValueType& CreateValueByPointer(T& root,
const CharType(&source)[N],
typename T::AllocatorType& a) {
1026 return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a);
1031 template <
typename DocumentType>
1032 typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer) {
1033 return pointer.Create(document);
1036 template <
typename DocumentType,
typename CharType,
size_t N>
1037 typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document,
const CharType(&source)[N]) {
1038 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document);
1043 template <
typename T>
1044 typename T::ValueType* GetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer) {
1045 return pointer.Get(root);
1048 template <
typename T>
1049 const typename T::ValueType* GetValueByPointer(
const T& root,
const GenericPointer<typename T::ValueType>& pointer) {
1050 return pointer.Get(root);
1053 template <
typename T,
typename CharType,
size_t N>
1054 typename T::ValueType* GetValueByPointer(T& root,
const CharType (&source)[N]) {
1055 return GenericPointer<typename T::ValueType>(source, N - 1).Get(root);
1058 template <
typename T,
typename CharType,
size_t N>
1059 const typename T::ValueType* GetValueByPointer(
const T& root,
const CharType(&source)[N]) {
1060 return GenericPointer<typename T::ValueType>(source, N - 1).Get(root);
1065 template <
typename T>
1066 typename T::ValueType& GetValueByPointerWithDefault(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const typename T::ValueType& defaultValue,
typename T::AllocatorType& a) {
1067 return pointer.GetWithDefault(root, defaultValue, a);
1070 template <
typename T>
1071 typename T::ValueType& GetValueByPointerWithDefault(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const typename T::Ch* defaultValue,
typename T::AllocatorType& a) {
1072 return pointer.GetWithDefault(root, defaultValue, a);
1075 #if RAPIDJSON_HAS_STDSTRING
1076 template <
typename T>
1077 typename T::ValueType& GetValueByPointerWithDefault(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const std::basic_string<typename T::Ch>& defaultValue,
typename T::AllocatorType& a) {
1078 return pointer.GetWithDefault(root, defaultValue, a);
1082 template <
typename T,
typename T2>
1083 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename T::ValueType&))
1084 GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 defaultValue, typename T::AllocatorType& a) {
1085 return pointer.GetWithDefault(root, defaultValue, a);
1088 template <
typename T,
typename CharType,
size_t N>
1089 typename T::ValueType& GetValueByPointerWithDefault(T& root,
const CharType(&source)[N],
const typename T::ValueType& defaultValue,
typename T::AllocatorType& a) {
1090 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1093 template <
typename T,
typename CharType,
size_t N>
1094 typename T::ValueType& GetValueByPointerWithDefault(T& root,
const CharType(&source)[N],
const typename T::Ch* defaultValue,
typename T::AllocatorType& a) {
1095 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1098 #if RAPIDJSON_HAS_STDSTRING
1099 template <
typename T,
typename CharType,
size_t N>
1100 typename T::ValueType& GetValueByPointerWithDefault(T& root,
const CharType(&source)[N],
const std::basic_string<typename T::Ch>& defaultValue,
typename T::AllocatorType& a) {
1101 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1105 template <
typename T,
typename CharType,
size_t N,
typename T2>
1106 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename T::ValueType&))
1107 GetValueByPointerWithDefault(T& root, const CharType(&source)[N], T2 defaultValue, typename T::AllocatorType& a) {
1108 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1113 template <
typename DocumentType>
1114 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const typename DocumentType::ValueType& defaultValue) {
1115 return pointer.GetWithDefault(document, defaultValue);
1118 template <
typename DocumentType>
1119 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const typename DocumentType::Ch* defaultValue) {
1120 return pointer.GetWithDefault(document, defaultValue);
1123 #if RAPIDJSON_HAS_STDSTRING
1124 template <
typename DocumentType>
1125 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1126 return pointer.GetWithDefault(document, defaultValue);
1130 template <
typename DocumentType,
typename T2>
1131 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename DocumentType::ValueType&))
1132 GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 defaultValue) {
1133 return pointer.GetWithDefault(document, defaultValue);
1136 template <
typename DocumentType,
typename CharType,
size_t N>
1137 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const CharType(&source)[N],
const typename DocumentType::ValueType& defaultValue) {
1138 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1141 template <
typename DocumentType,
typename CharType,
size_t N>
1142 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const CharType(&source)[N],
const typename DocumentType::Ch* defaultValue) {
1143 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1146 #if RAPIDJSON_HAS_STDSTRING
1147 template <
typename DocumentType,
typename CharType,
size_t N>
1148 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const CharType(&source)[N],
const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1149 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1153 template <
typename DocumentType,
typename CharType,
size_t N,
typename T2>
1154 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename DocumentType::ValueType&))
1155 GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) {
1156 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1161 template <
typename T>
1162 typename T::ValueType& SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
typename T::ValueType& value,
typename T::AllocatorType& a) {
1163 return pointer.Set(root, value, a);
1166 template <
typename T>
1167 typename T::ValueType& SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const typename T::ValueType& value,
typename T::AllocatorType& a) {
1168 return pointer.Set(root, value, a);
1171 template <
typename T>
1172 typename T::ValueType& SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const typename T::Ch* value,
typename T::AllocatorType& a) {
1173 return pointer.Set(root, value, a);
1176 #if RAPIDJSON_HAS_STDSTRING
1177 template <
typename T>
1178 typename T::ValueType& SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const std::basic_string<typename T::Ch>& value,
typename T::AllocatorType& a) {
1179 return pointer.Set(root, value, a);
1183 template <
typename T,
typename T2>
1184 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename T::ValueType&))
1185 SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 value, typename T::AllocatorType& a) {
1186 return pointer.Set(root, value, a);
1189 template <
typename T,
typename CharType,
size_t N>
1190 typename T::ValueType& SetValueByPointer(T& root,
const CharType(&source)[N],
typename T::ValueType& value,
typename T::AllocatorType& a) {
1191 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1194 template <
typename T,
typename CharType,
size_t N>
1195 typename T::ValueType& SetValueByPointer(T& root,
const CharType(&source)[N],
const typename T::ValueType& value,
typename T::AllocatorType& a) {
1196 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1199 template <
typename T,
typename CharType,
size_t N>
1200 typename T::ValueType& SetValueByPointer(T& root,
const CharType(&source)[N],
const typename T::Ch* value,
typename T::AllocatorType& a) {
1201 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1204 #if RAPIDJSON_HAS_STDSTRING
1205 template <
typename T,
typename CharType,
size_t N>
1206 typename T::ValueType& SetValueByPointer(T& root,
const CharType(&source)[N],
const std::basic_string<typename T::Ch>& value,
typename T::AllocatorType& a) {
1207 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1211 template <
typename T,
typename CharType,
size_t N,
typename T2>
1212 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename T::ValueType&))
1213 SetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) {
1214 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1219 template <
typename DocumentType>
1220 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
typename DocumentType::ValueType& value) {
1221 return pointer.Set(document, value);
1224 template <
typename DocumentType>
1225 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const typename DocumentType::ValueType& value) {
1226 return pointer.Set(document, value);
1229 template <
typename DocumentType>
1230 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const typename DocumentType::Ch* value) {
1231 return pointer.Set(document, value);
1234 #if RAPIDJSON_HAS_STDSTRING
1235 template <
typename DocumentType>
1236 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const std::basic_string<typename DocumentType::Ch>& value) {
1237 return pointer.Set(document, value);
1241 template <
typename DocumentType,
typename T2>
1242 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename DocumentType::ValueType&))
1243 SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 value) {
1244 return pointer.Set(document, value);
1247 template <
typename DocumentType,
typename CharType,
size_t N>
1248 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const CharType(&source)[N],
typename DocumentType::ValueType& value) {
1249 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1252 template <
typename DocumentType,
typename CharType,
size_t N>
1253 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const CharType(&source)[N],
const typename DocumentType::ValueType& value) {
1254 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1257 template <
typename DocumentType,
typename CharType,
size_t N>
1258 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const CharType(&source)[N],
const typename DocumentType::Ch* value) {
1259 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1262 #if RAPIDJSON_HAS_STDSTRING
1263 template <
typename DocumentType,
typename CharType,
size_t N>
1264 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const CharType(&source)[N],
const std::basic_string<typename DocumentType::Ch>& value) {
1265 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1269 template <
typename DocumentType,
typename CharType,
size_t N,
typename T2>
1270 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename DocumentType::ValueType&))
1271 SetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) {
1272 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1277 template <
typename T>
1278 typename T::ValueType& SwapValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
typename T::ValueType& value,
typename T::AllocatorType& a) {
1279 return pointer.Swap(root, value, a);
1282 template <
typename T,
typename CharType,
size_t N>
1283 typename T::ValueType& SwapValueByPointer(T& root,
const CharType(&source)[N],
typename T::ValueType& value,
typename T::AllocatorType& a) {
1284 return GenericPointer<typename T::ValueType>(source, N - 1).Swap(root, value, a);
1287 template <
typename DocumentType>
1288 typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
typename DocumentType::ValueType& value) {
1289 return pointer.Swap(document, value);
1292 template <
typename DocumentType,
typename CharType,
size_t N>
1293 typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document,
const CharType(&source)[N],
typename DocumentType::ValueType& value) {
1294 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Swap(document, value);
1299 template <
typename T>
1300 bool EraseValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer) {
1301 return pointer.Erase(root);
1304 template <
typename T,
typename CharType,
size_t N>
1305 bool EraseValueByPointer(T& root,
const CharType(&source)[N]) {
1306 return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root);
1311 RAPIDJSON_NAMESPACE_END
1313 #endif // RAPIDJSON_POINTER_H_
Invalid escape.
Definition: pointer.h:33
ValueType & Set(ValueType &root, ValueType &value, typename ValueType::AllocatorType &allocator) const
Set a value in a subtree, with move semantics.
Definition: pointer.h:581
PointerParseErrorCode
Error code of parsing.
Definition: pointer.h:29
GenericPointer(const Token *tokens, size_t tokenCount)
Constructor with user-supplied tokens.
Definition: pointer.h:155
ValueType & Set(ValueType &root, const ValueType &value, typename ValueType::AllocatorType &allocator) const
Set a value in a subtree, with copy semantics.
Definition: pointer.h:586
const Ch * name
Name of the token. It has null character at the end but it can contain null character.
Definition: pointer.h:90
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:129
size_t GetParseErrorOffset() const
Get the parsing error offset in code unit.
Definition: pointer.h:295
size_t GetTokenCount() const
Get the number of tokens.
Definition: pointer.h:309
ValueType & GetWithDefault(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, const Ch *defaultValue) const
Query a value in a document with default null-terminated string.
Definition: pointer.h:544
GenericPointer Append(SizeType index, Allocator *allocator=0) const
Append a index token, and return a new Pointer.
Definition: pointer.h:254
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:219
ValueType & GetWithDefault(ValueType &root, const std::basic_string< Ch > &defaultValue, typename ValueType::AllocatorType &allocator) const
Query a value in a subtree with default std::basic_string.
Definition: pointer.h:519
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
Definition: pointer.h:201
~GenericPointer()
Destructor.
Definition: pointer.h:163
unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:322
The parse is successful.
Definition: pointer.h:30
A character must percent encoded in URI fragment.
Definition: pointer.h:35
GenericPointer()
Default constructor.
Definition: pointer.h:99
GenericPointer Append(const std::basic_string< Ch > &name, Allocator *allocator=0) const
Append a name token, and return a new Pointer.
Definition: pointer.h:243
SizeType length
Length of the name.
Definition: pointer.h:91
PointerParseErrorCode GetParseErrorCode() const
Get the parsing error code.
Definition: pointer.h:298
A token must begin with a '/'.
Definition: pointer.h:32
ValueType & Create(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, bool *alreadyExist=0) const
Creates a value in a document.
Definition: pointer.h:443
ValueType & Set(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, const Ch *value) const
Set a null-terminated string in a document.
Definition: pointer.h:626
ValueType & Swap(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, ValueType &value) const
Swap a value with a value in a document.
Definition: pointer.h:669
ValueType & Create(ValueType &root, typename ValueType::AllocatorType &allocator, bool *alreadyExist=0) const
Create a value in a subtree.
Definition: pointer.h:387
bool StringifyUriFragment(OutputStream &os) const
Stringify the pointer into URI fragment representation.
Definition: pointer.h:363
GenericValue & SetString(const Ch *s, SizeType length)
Set this value as a string without copying source string.
Definition: document.h:1488
ValueType::EncodingType EncodingType
Encoding type from Value.
Definition: pointer.h:73
ValueType & GetWithDefault(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, const std::basic_string< Ch > &defaultValue) const
Query a value in a document with default std::basic_string.
Definition: pointer.h:551
bool operator!=(const GenericPointer &rhs) const
Inequality operator.
Definition: pointer.h:340
GenericPointer(const Ch *source, Allocator *allocator=0)
Constructor that parses a string or URI fragment representation.
Definition: pointer.h:106
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition: pointer.h:71
bool IsValid() const
Check whether this is a valid pointer.
Definition: pointer.h:292
Type
Type of JSON value.
Definition: rapidjson.h:642
GenericPointer & operator=(const GenericPointer &rhs)
Assignment operator.
Definition: pointer.h:170
ValueType & Set(ValueType &root, const std::basic_string< Ch > &value, typename ValueType::AllocatorType &allocator) const
Set a std::basic_string in a subtree.
Definition: pointer.h:597
ValueType & GetWithDefault(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, const ValueType &defaultValue) const
Query a value in a document with default value.
Definition: pointer.h:538
object
Definition: rapidjson.h:646
const Token * GetTokens() const
Get the token array (const version only).
Definition: pointer.h:306
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:620
GenericPointer Append(const ValueType &token, Allocator *allocator=0) const
Append a token by value, and return a new Pointer.
Definition: pointer.h:278
#define RAPIDJSON_NEW(x)
! customization point for global new
Definition: rapidjson.h:480
ValueType & Set(ValueType &root, const Ch *value, typename ValueType::AllocatorType &allocator) const
Set a null-terminated string in a subtree.
Definition: pointer.h:591
A document for parsing JSON text as DOM.
Definition: document.h:73
array
Definition: rapidjson.h:647
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:484
bool operator==(const GenericPointer &rhs) const
Equality operator.
Definition: pointer.h:320
bool Stringify(OutputStream &os) const
Stringify the pointer into string representation.
Definition: pointer.h:353
ValueType * Get(ValueType &root) const
Query a value in a subtree.
Definition: pointer.h:457
GenericPointer(const GenericPointer &rhs)
Copy constructor.
Definition: pointer.h:158
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:1992
ValueType & Set(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, ValueType &value) const
Set a value in a document, with move semantics.
Definition: pointer.h:614
GenericPointer(const std::basic_string< Ch > &source, Allocator *allocator=0)
Constructor that parses a string or URI fragment representation.
Definition: pointer.h:117
A token is the basic units of internal representation.
Definition: pointer.h:89
ValueType & GetWithDefault(ValueType &root, const Ch *defaultValue, typename ValueType::AllocatorType &allocator) const
Query a value in a subtree with default null-terminated string.
Definition: pointer.h:511
SizeType index
A valid array index, if it is not equal to kPointerInvalidIndex.
Definition: pointer.h:92
bool Erase(ValueType &root) const
Erase a value in a subtree.
Definition: pointer.h:682
Reference to a constant string (not taking a copy)
Definition: document.h:259
Concept for allocating, resizing and freeing memory block.
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:70
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition: document.h:1758
GenericValue & CopyFrom(const GenericValue< Encoding, SourceAllocator > &rhs, Allocator &allocator)
Deep-copy assignment from Value.
Definition: document.h:656
EncodingType::Ch Ch
Character type from Value.
Definition: pointer.h:74
Invalid percent encoding in URI fragment.
Definition: pointer.h:34
const ValueType * Get(const ValueType &root) const
Query a const value in a const subtree.
Definition: pointer.h:487
ValueType & Swap(ValueType &root, ValueType &value, typename ValueType::AllocatorType &allocator) const
Swap a value with a value in a subtree.
Definition: pointer.h:663
ValueType & GetWithDefault(ValueType &root, const ValueType &defaultValue, typename ValueType::AllocatorType &allocator) const
Query a value in a subtree with default value.
Definition: pointer.h:504
ValueType & Set(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, const std::basic_string< Ch > &value) const
Sets a std::basic_string in a document.
Definition: pointer.h:633
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:344