15#ifndef RAPIDJSON_POINTER_H_
16#define RAPIDJSON_POINTER_H_
19#include "internal/itoa.h"
23RAPIDJSON_DIAG_OFF(
switch-
enum)
24#elif defined(_MSC_VER)
26RAPIDJSON_DIAG_OFF(4512)
29RAPIDJSON_NAMESPACE_BEGIN
31static const SizeType kPointerInvalidIndex = ~SizeType(0);
78template <
typename ValueType,
typename Allocator = CrtAllocator>
82 typedef typename ValueType::Ch
Ch;
115 Parse(source, internal::StrLen(source));
118#if RAPIDJSON_HAS_STDSTRING
126 Parse(source.c_str(), source.size());
138 Parse(source, length);
178 Allocator::Free(tokens_);
187 Allocator::Free(tokens_);
189 tokenCount_ = rhs.tokenCount_;
190 parseErrorOffset_ = rhs.parseErrorOffset_;
191 parseErrorCode_ = rhs.parseErrorCode_;
196 tokens_ = rhs.tokens_;
209 internal::Swap(allocator_, other.allocator_);
210 internal::Swap(ownAllocator_, other.ownAllocator_);
211 internal::Swap(nameBuffer_, other.nameBuffer_);
212 internal::Swap(tokens_, other.tokens_);
213 internal::Swap(tokenCount_, other.tokenCount_);
214 internal::Swap(parseErrorOffset_, other.parseErrorOffset_);
215 internal::Swap(parseErrorCode_, other.parseErrorCode_);
246 r.allocator_ = allocator;
247 Ch *p = r.CopyFromRaw(*
this, 1, token.
length + 1);
248 std::memcpy(p, token.
name, (token.
length + 1) *
sizeof(
Ch));
249 r.tokens_[tokenCount_].
name = p;
263 Token token = { name, length, kPointerInvalidIndex };
264 return Append(token, allocator);
273 template <
typename T>
276 return Append(name, internal::StrLen(name), allocator);
279#if RAPIDJSON_HAS_STDSTRING
287 return Append(name.c_str(),
static_cast<SizeType>(name.size()), allocator);
299 char* end =
sizeof(
SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer);
301 buffer[length] =
'\0';
303 if (
sizeof(
Ch) == 1) {
304 Token token = {
reinterpret_cast<Ch*
>(buffer), length, index };
305 return Append(token, allocator);
309 for (
size_t i = 0; i <= length; i++)
310 name[i] =
static_cast<Ch>(buffer[i]);
311 Token token = { name, length, index };
312 return Append(token, allocator);
323 if (token.IsString())
324 return Append(token.GetString(), token.GetStringLength(), allocator);
328 return Append(
static_cast<SizeType>(token.GetUint64()), allocator);
368 if (!IsValid() || !rhs.
IsValid() || tokenCount_ != rhs.tokenCount_)
371 for (
size_t i = 0; i < tokenCount_; i++) {
372 if (tokens_[i].index != rhs.tokens_[i].
index ||
373 tokens_[i].length != rhs.tokens_[i].
length ||
374 (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].
name,
sizeof(
Ch)* tokens_[i].length) != 0))
399 if (tokenCount_ != rhs.tokenCount_)
400 return tokenCount_ < rhs.tokenCount_;
402 for (
size_t i = 0; i < tokenCount_; i++) {
403 if (tokens_[i].index != rhs.tokens_[i].
index)
404 return tokens_[i].index < rhs.tokens_[i].
index;
406 if (tokens_[i].length != rhs.tokens_[i].
length)
407 return tokens_[i].length < rhs.tokens_[i].
length;
409 if (
int cmp = std::memcmp(tokens_[i].name, rhs.tokens_[i].
name,
sizeof(
Ch) * tokens_[i].length))
426 template<
typename OutputStream>
428 return Stringify<false, OutputStream>(os);
436 template<
typename OutputStream>
438 return Stringify<true, OutputStream>(os);
461 ValueType&
Create(ValueType& root,
typename ValueType::AllocatorType& allocator,
bool* alreadyExist = 0)
const {
463 ValueType* v = &root;
465 for (
const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
466 if (v->IsArray() && t->name[0] ==
'-' && t->length == 1) {
467 v->PushBack(ValueType().Move(), allocator);
468 v = &((*v)[v->Size() - 1]);
472 if (t->index == kPointerInvalidIndex) {
477 if (!v->IsArray() && !v->IsObject())
482 if (t->index >= v->Size()) {
483 v->Reserve(t->index + 1, allocator);
484 while (t->index >= v->Size())
485 v->PushBack(ValueType().Move(), allocator);
488 v = &((*v)[t->index]);
492 if (m == v->MemberEnd()) {
493 v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
505 *alreadyExist = exist;
516 template <
typename stackAllocator>
518 return Create(document, document.
GetAllocator(), alreadyExist);
540 ValueType*
Get(ValueType& root,
size_t* unresolvedTokenIndex = 0)
const {
542 ValueType* v = &root;
543 for (
const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
544 switch (v->GetType()) {
548 if (m == v->MemberEnd())
554 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
556 v = &((*v)[t->index]);
563 if (unresolvedTokenIndex)
564 *unresolvedTokenIndex =
static_cast<size_t>(t - tokens_);
575 const ValueType*
Get(
const ValueType& root,
size_t* unresolvedTokenIndex = 0)
const {
576 return Get(
const_cast<ValueType&
>(root), unresolvedTokenIndex);
594 ValueType&
GetWithDefault(ValueType& root,
const ValueType& defaultValue,
typename ValueType::AllocatorType& allocator)
const {
596 ValueType& v = Create(root, allocator, &alreadyExist);
597 return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
601 ValueType&
GetWithDefault(ValueType& root,
const Ch* defaultValue,
typename ValueType::AllocatorType& allocator)
const {
603 ValueType& v = Create(root, allocator, &alreadyExist);
604 return alreadyExist ? v : v.SetString(defaultValue, allocator);
607#if RAPIDJSON_HAS_STDSTRING
609 ValueType&
GetWithDefault(ValueType& root,
const std::basic_string<Ch>& defaultValue,
typename ValueType::AllocatorType& allocator)
const {
611 ValueType& v = Create(root, allocator, &alreadyExist);
612 return alreadyExist ? v : v.SetString(defaultValue, allocator);
620 template <
typename T>
621 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
622 GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator)
const {
623 return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);
627 template <
typename stackAllocator>
629 return GetWithDefault(document, defaultValue, document.
GetAllocator());
633 template <
typename stackAllocator>
635 return GetWithDefault(document, defaultValue, document.
GetAllocator());
638#if RAPIDJSON_HAS_STDSTRING
640 template <
typename stackAllocator>
642 return GetWithDefault(document, defaultValue, document.
GetAllocator());
650 template <
typename T,
typename stackAllocator>
651 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
653 return GetWithDefault(document, defaultValue, document.GetAllocator());
671 ValueType&
Set(ValueType& root, ValueType& value,
typename ValueType::AllocatorType& allocator)
const {
672 return Create(root, allocator) = value;
676 ValueType&
Set(ValueType& root,
const ValueType& value,
typename ValueType::AllocatorType& allocator)
const {
677 return Create(root, allocator).CopyFrom(value, allocator);
681 ValueType&
Set(ValueType& root,
const Ch* value,
typename ValueType::AllocatorType& allocator)
const {
682 return Create(root, allocator) = ValueType(value, allocator).Move();
685#if RAPIDJSON_HAS_STDSTRING
687 ValueType&
Set(ValueType& root,
const std::basic_string<Ch>& value,
typename ValueType::AllocatorType& allocator)
const {
688 return Create(root, allocator) = ValueType(value, allocator).Move();
696 template <
typename T>
697 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
698 Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator)
const {
699 return Create(root, allocator) = ValueType(value).Move();
703 template <
typename stackAllocator>
705 return Create(document) = value;
709 template <
typename stackAllocator>
711 return Create(document).CopyFrom(value, document.
GetAllocator());
715 template <
typename stackAllocator>
717 return Create(document) = ValueType(value, document.
GetAllocator()).Move();
720#if RAPIDJSON_HAS_STDSTRING
722 template <
typename stackAllocator>
724 return Create(document) = ValueType(value, document.
GetAllocator()).Move();
732 template <
typename T,
typename stackAllocator>
733 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
735 return Create(document) = value;
753 ValueType&
Swap(ValueType& root, ValueType& value,
typename ValueType::AllocatorType& allocator)
const {
754 return Create(root, allocator).Swap(value);
758 template <
typename stackAllocator>
760 return Create(document).Swap(value);
774 if (tokenCount_ == 0)
777 ValueType* v = &root;
778 const Token* last = tokens_ + (tokenCount_ - 1);
779 for (
const Token *t = tokens_; t != last; ++t) {
780 switch (v->GetType()) {
784 if (m == v->MemberEnd())
790 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
792 v = &((*v)[t->index]);
799 switch (v->GetType()) {
803 if (last->
index == kPointerInvalidIndex || last->
index >= v->Size())
805 v->Erase(v->Begin() + last->
index);
820 Ch* CopyFromRaw(
const GenericPointer& rhs,
size_t extraToken = 0,
size_t extraNameBufferSize = 0) {
824 size_t nameBufferSize = rhs.tokenCount_;
825 for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)
826 nameBufferSize += t->length;
828 tokenCount_ = rhs.tokenCount_ + extraToken;
829 tokens_ =
static_cast<Token *
>(allocator_->Malloc(tokenCount_ *
sizeof(Token) + (nameBufferSize + extraNameBufferSize) *
sizeof(Ch)));
830 nameBuffer_ =
reinterpret_cast<Ch *
>(tokens_ + tokenCount_);
831 if (rhs.tokenCount_ > 0) {
832 std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ *
sizeof(Token));
834 if (nameBufferSize > 0) {
835 std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize *
sizeof(Ch));
839 std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;
840 for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t)
843 return nameBuffer_ + nameBufferSize;
851 bool NeedPercentEncode(Ch c)
const {
852 return !((c >=
'0' && c <=
'9') || (c >=
'A' && c <=
'Z') || (c >=
'a' && c <=
'z') || c ==
'-' || c ==
'.' || c ==
'_' || c ==
'~');
863 void Parse(
const Ch* source,
size_t length) {
874 for (
const Ch* s = source; s != source + length; s++)
878 Token* token = tokens_ =
static_cast<Token *
>(allocator_->Malloc(tokenCount_ *
sizeof(Token) + length *
sizeof(Ch)));
879 Ch* name = nameBuffer_ =
reinterpret_cast<Ch *
>(tokens_ + tokenCount_);
883 bool uriFragment =
false;
884 if (source[i] ==
'#') {
889 if (i != length && source[i] !=
'/') {
899 bool isNumber =
true;
901 while (i < length && source[i] !=
'/') {
906 PercentDecodeStream is(&source[i], source + length);
907 GenericInsituStringStream<EncodingType> os(name);
908 Ch* begin = os.PutBegin();
909 if (!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid()) {
913 size_t len = os.PutEnd(begin);
924 else if (NeedPercentEncode(c)) {
936 if (c ==
'0') c =
'~';
937 else if (c ==
'1') c =
'/';
951 if (c < '0' || c >
'9')
956 token->length =
static_cast<SizeType>(name - token->name);
957 if (token->length == 0)
962 if (isNumber && token->length > 1 && token->name[0] ==
'0')
968 for (
size_t j = 0; j < token->length; j++) {
978 token->index = isNumber ? n : kPointerInvalidIndex;
987 Allocator::Free(tokens_);
991 parseErrorOffset_ = i;
1001 template<
bool uriFragment,
typename OutputStream>
1002 bool Stringify(OutputStream& os)
const {
1008 for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
1010 for (
size_t j = 0; j < t->length; j++) {
1016 else if (c ==
'/') {
1020 else if (uriFragment && NeedPercentEncode(c)) {
1022 GenericStringStream<typename ValueType::EncodingType> source(&t->name[j]);
1023 PercentEncodeStream<OutputStream> target(os);
1024 if (!Transcoder<EncodingType, UTF8<> >().Validate(source, target))
1026 j += source.Tell() - 1;
1041 class PercentDecodeStream {
1043 typedef typename ValueType::Ch Ch;
1050 PercentDecodeStream(
const Ch* source,
const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {}
1053 if (*src_ !=
'%' || src_ + 3 > end_) {
1059 for (
int j = 0; j < 2; j++) {
1060 c =
static_cast<Ch
>(c << 4);
1062 if (h >=
'0' && h <=
'9') c =
static_cast<Ch
>(c + h -
'0');
1063 else if (h >=
'A' && h <=
'F') c =
static_cast<Ch
>(c + h -
'A' + 10);
1064 else if (h >=
'a' && h <=
'f') c =
static_cast<Ch
>(c + h -
'a' + 10);
1074 size_t Tell()
const {
return static_cast<size_t>(src_ - head_); }
1075 bool IsValid()
const {
return valid_; }
1085 template <
typename OutputStream>
1086 class PercentEncodeStream {
1088 PercentEncodeStream(OutputStream& os) : os_(os) {}
1090 unsigned char u =
static_cast<unsigned char>(c);
1091 static const char hexDigits[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
1093 os_.Put(
static_cast<typename OutputStream::Ch
>(hexDigits[u >> 4]));
1094 os_.Put(
static_cast<typename OutputStream::Ch
>(hexDigits[u & 15]));
1105 size_t parseErrorOffset_;
1110typedef GenericPointer<Value>
Pointer;
1117template <
typename T>
1118typename T::ValueType& CreateValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
typename T::AllocatorType& a) {
1119 return pointer.Create(root, a);
1122template <
typename T,
typename CharType,
size_t N>
1123typename T::ValueType& CreateValueByPointer(T& root,
const CharType(&source)[N],
typename T::AllocatorType& a) {
1124 return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a);
1129template <
typename DocumentType>
1130typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer) {
1131 return pointer.Create(document);
1134template <
typename DocumentType,
typename CharType,
size_t N>
1135typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document,
const CharType(&source)[N]) {
1136 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document);
1141template <
typename T>
1142typename T::ValueType* GetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
size_t* unresolvedTokenIndex = 0) {
1143 return pointer.Get(root, unresolvedTokenIndex);
1146template <
typename T>
1147const typename T::ValueType* GetValueByPointer(
const T& root,
const GenericPointer<typename T::ValueType>& pointer,
size_t* unresolvedTokenIndex = 0) {
1148 return pointer.Get(root, unresolvedTokenIndex);
1151template <
typename T,
typename CharType,
size_t N>
1152typename T::ValueType* GetValueByPointer(T& root,
const CharType (&source)[N],
size_t* unresolvedTokenIndex = 0) {
1153 return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1156template <
typename T,
typename CharType,
size_t N>
1157const typename T::ValueType* GetValueByPointer(
const T& root,
const CharType(&source)[N],
size_t* unresolvedTokenIndex = 0) {
1158 return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1163template <
typename T>
1164typename T::ValueType& GetValueByPointerWithDefault(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const typename T::ValueType& defaultValue,
typename T::AllocatorType& a) {
1165 return pointer.GetWithDefault(root, defaultValue, a);
1168template <
typename T>
1169typename T::ValueType& GetValueByPointerWithDefault(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const typename T::Ch* defaultValue,
typename T::AllocatorType& a) {
1170 return pointer.GetWithDefault(root, defaultValue, a);
1173#if RAPIDJSON_HAS_STDSTRING
1174template <
typename T>
1175typename T::ValueType& GetValueByPointerWithDefault(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const std::basic_string<typename T::Ch>& defaultValue,
typename T::AllocatorType& a) {
1176 return pointer.GetWithDefault(root, defaultValue, a);
1180template <
typename T,
typename T2>
1181RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename T::ValueType&))
1182GetValueByPointerWithDefault(T& root,
const GenericPointer<typename T::ValueType>& pointer, T2 defaultValue,
typename T::AllocatorType& a) {
1183 return pointer.GetWithDefault(root, defaultValue, a);
1186template <
typename T,
typename CharType,
size_t N>
1187typename T::ValueType& GetValueByPointerWithDefault(T& root,
const CharType(&source)[N],
const typename T::ValueType& defaultValue,
typename T::AllocatorType& a) {
1188 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1191template <
typename T,
typename CharType,
size_t N>
1192typename T::ValueType& GetValueByPointerWithDefault(T& root,
const CharType(&source)[N],
const typename T::Ch* defaultValue,
typename T::AllocatorType& a) {
1193 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1196#if RAPIDJSON_HAS_STDSTRING
1197template <
typename T,
typename CharType,
size_t N>
1198typename T::ValueType& GetValueByPointerWithDefault(T& root,
const CharType(&source)[N],
const std::basic_string<typename T::Ch>& defaultValue,
typename T::AllocatorType& a) {
1199 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1203template <
typename T,
typename CharType,
size_t N,
typename T2>
1204RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename T::ValueType&))
1205GetValueByPointerWithDefault(T& root,
const CharType(&source)[N], T2 defaultValue,
typename T::AllocatorType& a) {
1206 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1211template <
typename DocumentType>
1212typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const typename DocumentType::ValueType& defaultValue) {
1213 return pointer.GetWithDefault(document, defaultValue);
1216template <
typename DocumentType>
1217typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const typename DocumentType::Ch* defaultValue) {
1218 return pointer.GetWithDefault(document, defaultValue);
1221#if RAPIDJSON_HAS_STDSTRING
1222template <
typename DocumentType>
1223typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1224 return pointer.GetWithDefault(document, defaultValue);
1228template <
typename DocumentType,
typename T2>
1229RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename DocumentType::ValueType&))
1230GetValueByPointerWithDefault(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer, T2 defaultValue) {
1231 return pointer.GetWithDefault(document, defaultValue);
1234template <
typename DocumentType,
typename CharType,
size_t N>
1235typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const CharType(&source)[N],
const typename DocumentType::ValueType& defaultValue) {
1236 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1239template <
typename DocumentType,
typename CharType,
size_t N>
1240typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const CharType(&source)[N],
const typename DocumentType::Ch* defaultValue) {
1241 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1244#if RAPIDJSON_HAS_STDSTRING
1245template <
typename DocumentType,
typename CharType,
size_t N>
1246typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const CharType(&source)[N],
const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1247 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1251template <
typename DocumentType,
typename CharType,
size_t N,
typename T2>
1252RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename DocumentType::ValueType&))
1253GetValueByPointerWithDefault(DocumentType& document,
const CharType(&source)[N], T2 defaultValue) {
1254 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1259template <
typename T>
1260typename T::ValueType& SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
typename T::ValueType& value,
typename T::AllocatorType& a) {
1261 return pointer.Set(root, value, a);
1264template <
typename T>
1265typename T::ValueType& SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const typename T::ValueType& value,
typename T::AllocatorType& a) {
1266 return pointer.Set(root, value, a);
1269template <
typename T>
1270typename T::ValueType& SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const typename T::Ch* value,
typename T::AllocatorType& a) {
1271 return pointer.Set(root, value, a);
1274#if RAPIDJSON_HAS_STDSTRING
1275template <
typename T>
1276typename T::ValueType& SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const std::basic_string<typename T::Ch>& value,
typename T::AllocatorType& a) {
1277 return pointer.Set(root, value, a);
1281template <
typename T,
typename T2>
1282RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename T::ValueType&))
1283SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer, T2 value,
typename T::AllocatorType& a) {
1284 return pointer.Set(root, value, a);
1287template <
typename T,
typename CharType,
size_t N>
1288typename T::ValueType& SetValueByPointer(T& root,
const CharType(&source)[N],
typename T::ValueType& value,
typename T::AllocatorType& a) {
1289 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1292template <
typename T,
typename CharType,
size_t N>
1293typename T::ValueType& SetValueByPointer(T& root,
const CharType(&source)[N],
const typename T::ValueType& value,
typename T::AllocatorType& a) {
1294 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1297template <
typename T,
typename CharType,
size_t N>
1298typename T::ValueType& SetValueByPointer(T& root,
const CharType(&source)[N],
const typename T::Ch* value,
typename T::AllocatorType& a) {
1299 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1302#if RAPIDJSON_HAS_STDSTRING
1303template <
typename T,
typename CharType,
size_t N>
1304typename T::ValueType& SetValueByPointer(T& root,
const CharType(&source)[N],
const std::basic_string<typename T::Ch>& value,
typename T::AllocatorType& a) {
1305 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1309template <
typename T,
typename CharType,
size_t N,
typename T2>
1310RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename T::ValueType&))
1311SetValueByPointer(T& root,
const CharType(&source)[N], T2 value,
typename T::AllocatorType& a) {
1312 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1317template <
typename DocumentType>
1318typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
typename DocumentType::ValueType& value) {
1319 return pointer.Set(document, value);
1322template <
typename DocumentType>
1323typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const typename DocumentType::ValueType& value) {
1324 return pointer.Set(document, value);
1327template <
typename DocumentType>
1328typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const typename DocumentType::Ch* value) {
1329 return pointer.Set(document, value);
1332#if RAPIDJSON_HAS_STDSTRING
1333template <
typename DocumentType>
1334typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const std::basic_string<typename DocumentType::Ch>& value) {
1335 return pointer.Set(document, value);
1339template <
typename DocumentType,
typename T2>
1340RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename DocumentType::ValueType&))
1341SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer, T2 value) {
1342 return pointer.Set(document, value);
1345template <
typename DocumentType,
typename CharType,
size_t N>
1346typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const CharType(&source)[N],
typename DocumentType::ValueType& value) {
1347 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1350template <
typename DocumentType,
typename CharType,
size_t N>
1351typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const CharType(&source)[N],
const typename DocumentType::ValueType& value) {
1352 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1355template <
typename DocumentType,
typename CharType,
size_t N>
1356typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const CharType(&source)[N],
const typename DocumentType::Ch* value) {
1357 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1360#if RAPIDJSON_HAS_STDSTRING
1361template <
typename DocumentType,
typename CharType,
size_t N>
1362typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const CharType(&source)[N],
const std::basic_string<typename DocumentType::Ch>& value) {
1363 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1367template <
typename DocumentType,
typename CharType,
size_t N,
typename T2>
1368RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename DocumentType::ValueType&))
1369SetValueByPointer(DocumentType& document,
const CharType(&source)[N], T2 value) {
1370 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1375template <
typename T>
1376typename T::ValueType& SwapValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
typename T::ValueType& value,
typename T::AllocatorType& a) {
1377 return pointer.Swap(root, value, a);
1380template <
typename T,
typename CharType,
size_t N>
1381typename T::ValueType& SwapValueByPointer(T& root,
const CharType(&source)[N],
typename T::ValueType& value,
typename T::AllocatorType& a) {
1382 return GenericPointer<typename T::ValueType>(source, N - 1).Swap(root, value, a);
1385template <
typename DocumentType>
1386typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
typename DocumentType::ValueType& value) {
1387 return pointer.Swap(document, value);
1390template <
typename DocumentType,
typename CharType,
size_t N>
1391typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document,
const CharType(&source)[N],
typename DocumentType::ValueType& value) {
1392 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Swap(document, value);
1397template <
typename T>
1398bool EraseValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer) {
1399 return pointer.Erase(root);
1402template <
typename T,
typename CharType,
size_t N>
1403bool EraseValueByPointer(T& root,
const CharType(&source)[N]) {
1404 return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root);
1409RAPIDJSON_NAMESPACE_END
1411#if defined(__clang__) || defined(_MSC_VER)
Concept for allocating, resizing and freeing memory block.
A document for parsing JSON text as DOM.
Definition: document.h:2154
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:2442
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition: pointer.h:79
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 & operator=(const GenericPointer &rhs)
Assignment operator.
Definition: pointer.h:183
~GenericPointer()
Destructor.
Definition: pointer.h:176
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:601
GenericPointer Append(const std::basic_string< Ch > &name, Allocator *allocator=0) const
Append a name token, and return a new Pointer.
Definition: pointer.h:286
friend void swap(GenericPointer &a, GenericPointer &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition: pointer.h:231
bool operator<(const GenericPointer &rhs) const
Less than operator.
Definition: pointer.h:393
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:262
ValueType & Create(ValueType &root, typename ValueType::AllocatorType &allocator, bool *alreadyExist=0) const
Create a value in a subtree.
Definition: pointer.h:461
ValueType::EncodingType EncodingType
Encoding type from Value.
Definition: pointer.h:81
ValueType & Set(ValueType &root, const Ch *value, typename ValueType::AllocatorType &allocator) const
Set a null-terminated string in a subtree.
Definition: pointer.h:681
bool operator==(const GenericPointer &rhs) const
Equality operator.
Definition: pointer.h:367
ValueType & Set(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, const Ch *value) const
Set a null-terminated string in a document.
Definition: pointer.h:716
GenericPointer Append(SizeType index, Allocator *allocator=0) const
Append a index token, and return a new Pointer.
Definition: pointer.h:297
GenericPointer Append(const ValueType &token, Allocator *allocator=0) const
Append a token by value, and return a new Pointer.
Definition: pointer.h:322
Allocator & GetAllocator()
Get the allocator of this pointer.
Definition: pointer.h:347
ValueType & Create(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, bool *alreadyExist=0) const
Creates a value in a document.
Definition: pointer.h:517
GenericPointer(const Token *tokens, size_t tokenCount)
Constructor with user-supplied tokens.
Definition: pointer.h:163
bool Stringify(OutputStream &os) const
Stringify the pointer into string representation.
Definition: pointer.h:427
size_t GetParseErrorOffset() const
Get the parsing error offset in code unit.
Definition: pointer.h:339
size_t GetTokenCount() const
Get the number of tokens.
Definition: pointer.h:356
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
Definition: pointer.h:244
ValueType & Set(ValueType &root, const ValueType &value, typename ValueType::AllocatorType &allocator) const
Set a value in a subtree, with copy semantics.
Definition: pointer.h:676
ValueType & GetWithDefault(ValueType &root, const ValueType &defaultValue, typename ValueType::AllocatorType &allocator) const
Query a value in a subtree with default value.
Definition: pointer.h:594
ValueType::Ch Ch
Character type from Value.
Definition: pointer.h:82
ValueType * Get(ValueType &root, size_t *unresolvedTokenIndex=0) const
Query a value in a subtree.
Definition: pointer.h:540
bool operator!=(const GenericPointer &rhs) const
Inequality operator.
Definition: pointer.h:387
GenericPointer(const Ch *source, Allocator *allocator=0)
Constructor that parses a string or URI fragment representation.
Definition: pointer.h:114
ValueType & Set(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, ValueType &value) const
Set a value in a document, with move semantics.
Definition: pointer.h:704
ValueType & Swap(ValueType &root, ValueType &value, typename ValueType::AllocatorType &allocator) const
Swap a value with a value in a subtree.
Definition: pointer.h:753
bool Erase(ValueType &root) const
Erase a value in a subtree.
Definition: pointer.h:772
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:710
bool IsValid() const
Check whether this is a valid pointer.
Definition: pointer.h:336
GenericPointer(Allocator *allocator=0)
Default constructor.
Definition: pointer.h:107
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:723
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:641
ValueType & Swap(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, ValueType &value) const
Swap a value with a value in a document.
Definition: pointer.h:759
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:687
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:609
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:628
ValueType & Set(ValueType &root, ValueType &value, typename ValueType::AllocatorType &allocator) const
Set a value in a subtree, with move semantics.
Definition: pointer.h:671
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:634
const ValueType * Get(const ValueType &root, size_t *unresolvedTokenIndex=0) const
Query a const value in a const subtree.
Definition: pointer.h:575
GenericPointer & Swap(GenericPointer &other) RAPIDJSON_NOEXCEPT
Swap the content of this pointer with an other.
Definition: pointer.h:208
GenericPointer(const GenericPointer &rhs)
Copy constructor.
Definition: pointer.h:166
bool StringifyUriFragment(OutputStream &os) const
Stringify the pointer into URI fragment representation.
Definition: pointer.h:437
GenericPointer(const std::basic_string< Ch > &source, Allocator *allocator=0)
Constructor that parses a string or URI fragment representation.
Definition: pointer.h:125
const Token * GetTokens() const
Get the token array (const version only).
Definition: pointer.h:353
PointerParseErrorCode GetParseErrorCode() const
Get the parsing error code.
Definition: pointer.h:342
GenericPointer(const GenericPointer &rhs, Allocator *allocator)
Copy constructor.
Definition: pointer.h:171
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:608
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:406
PointerParseErrorCode
Error code of parsing.
Definition: pointer.h:37
@ kPointerParseErrorInvalidPercentEncoding
Invalid percent encoding in URI fragment.
Definition: pointer.h:42
@ kPointerParseErrorTokenMustBeginWithSolidus
A token must begin with a '/'.
Definition: pointer.h:40
@ kPointerParseErrorInvalidEscape
Invalid escape.
Definition: pointer.h:41
@ kPointerParseErrorNone
The parse is successful.
Definition: pointer.h:38
@ kPointerParseErrorCharacterMustPercentEncode
A character must percent encoded in URI fragment.
Definition: pointer.h:43
GenericPointer< Value, CrtAllocator > Pointer
GenericPointer for Value (UTF-8, default allocator).
Definition: fwd.h:128
unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:384
Type
Type of JSON value.
Definition: rapidjson.h:663
@ kArrayType
array
Definition: rapidjson.h:668
@ kObjectType
object
Definition: rapidjson.h:667
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:650
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition: rapidjson.h:646
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
const Ch * name
Name of the token. It has null character at the end but it can contain null character.
Definition: pointer.h:98
SizeType length
Length of the name.
Definition: pointer.h:99
Reference to a constant string (not taking a copy)
Definition: document.h:286