15#ifndef RAPIDJSON_POINTER_H_
16#define RAPIDJSON_POINTER_H_
20#include "internal/itoa.h"
25RAPIDJSON_DIAG_OFF(
switch-
enum)
26#elif defined(_MSC_VER)
28RAPIDJSON_DIAG_OFF(4512)
31RAPIDJSON_NAMESPACE_BEGIN
33static const SizeType kPointerInvalidIndex = ~SizeType(0);
67template <
typename ValueType,
typename Allocator = CrtAllocator>
71 typedef typename ValueType::Ch
Ch;
106 Parse(source, internal::StrLen(source));
109#if RAPIDJSON_HAS_STDSTRING
116 explicit GenericPointer(
const std::basic_string<Ch>& source,
Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(
kPointerParseErrorNone) {
117 Parse(source.c_str(), source.size());
129 Parse(source, length);
169 Allocator::Free(tokens_);
178 Allocator::Free(tokens_);
180 tokenCount_ = rhs.tokenCount_;
181 parseErrorOffset_ = rhs.parseErrorOffset_;
182 parseErrorCode_ = rhs.parseErrorCode_;
187 tokens_ = rhs.tokens_;
200 internal::Swap(allocator_, other.allocator_);
201 internal::Swap(ownAllocator_, other.ownAllocator_);
202 internal::Swap(nameBuffer_, other.nameBuffer_);
203 internal::Swap(tokens_, other.tokens_);
204 internal::Swap(tokenCount_, other.tokenCount_);
205 internal::Swap(parseErrorOffset_, other.parseErrorOffset_);
206 internal::Swap(parseErrorCode_, other.parseErrorCode_);
237 r.allocator_ = allocator;
238 Ch *p = r.CopyFromRaw(*
this, 1, token.
length + 1);
239 std::memcpy(p, token.
name, (token.
length + 1) *
sizeof(
Ch));
240 r.tokens_[tokenCount_].
name = p;
254 Token token = { name, length, kPointerInvalidIndex };
255 return Append(token, allocator);
264 template <
typename T>
265 RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<
typename internal::RemoveConst<T>::Type, Ch> >), (
GenericPointer))
267 return Append(name, internal::StrLen(name), allocator);
270#if RAPIDJSON_HAS_STDSTRING
278 return Append(name.c_str(),
static_cast<SizeType>(name.size()), allocator);
290 char* end =
sizeof(
SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer);
292 buffer[length] =
'\0';
294 if (
sizeof(
Ch) == 1) {
295 Token token = {
reinterpret_cast<Ch*
>(buffer), length, index };
296 return Append(token, allocator);
300 for (
size_t i = 0; i <= length; i++)
301 name[i] =
static_cast<Ch>(buffer[i]);
302 Token token = { name, length, index };
303 return Append(token, allocator);
314 if (token.IsString())
315 return Append(token.GetString(), token.GetStringLength(), allocator);
319 return Append(
static_cast<SizeType>(token.GetUint64()), allocator);
359 if (!IsValid() || !rhs.
IsValid() || tokenCount_ != rhs.tokenCount_)
362 for (
size_t i = 0; i < tokenCount_; i++) {
363 if (tokens_[i].index != rhs.tokens_[i].
index ||
364 tokens_[i].length != rhs.tokens_[i].
length ||
365 (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].
name,
sizeof(
Ch)* tokens_[i].length) != 0))
390 if (tokenCount_ != rhs.tokenCount_)
391 return tokenCount_ < rhs.tokenCount_;
393 for (
size_t i = 0; i < tokenCount_; i++) {
394 if (tokens_[i].index != rhs.tokens_[i].
index)
395 return tokens_[i].index < rhs.tokens_[i].
index;
397 if (tokens_[i].length != rhs.tokens_[i].
length)
398 return tokens_[i].length < rhs.tokens_[i].
length;
400 if (
int cmp = std::memcmp(tokens_[i].name, rhs.tokens_[i].
name,
sizeof(
Ch) * tokens_[i].length))
417 template<
typename OutputStream>
419 return Stringify<false, OutputStream>(os);
427 template<
typename OutputStream>
429 return Stringify<true, OutputStream>(os);
452 ValueType&
Create(ValueType& root,
typename ValueType::AllocatorType& allocator,
bool* alreadyExist = 0)
const {
454 ValueType* v = &root;
456 for (
const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
457 if (v->IsArray() && t->name[0] ==
'-' && t->length == 1) {
458 v->PushBack(ValueType().Move(), allocator);
459 v = &((*v)[v->Size() - 1]);
463 if (t->index == kPointerInvalidIndex) {
468 if (!v->IsArray() && !v->IsObject())
473 if (t->index >= v->Size()) {
474 v->Reserve(t->index + 1, allocator);
475 while (t->index >= v->Size())
476 v->PushBack(ValueType().Move(), allocator);
479 v = &((*v)[t->index]);
483 if (m == v->MemberEnd()) {
484 v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
496 *alreadyExist = exist;
507 template <
typename stackAllocator>
509 return Create(document, document.
GetAllocator(), alreadyExist);
535 static const Ch kIdString[] = {
'i',
'd',
'\0' };
536 static const ValueType kIdValue(kIdString, 2);
539 ValueType* v = &root;
540 for (
const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
541 switch (v->GetType()) {
545 typename ValueType::MemberIterator m = v->FindMember(kIdValue);
546 if (m != v->MemberEnd() && (m->value).IsString()) {
551 if (m == v->MemberEnd())
557 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
559 v = &((*v)[t->index]);
566 if (unresolvedTokenIndex)
567 *unresolvedTokenIndex =
static_cast<size_t>(t - tokens_);
573 UriType GetUri(
const ValueType& root,
const UriType& rootUri,
size_t* unresolvedTokenIndex = 0,
Allocator* allocator = 0)
const {
574 return GetUri(
const_cast<ValueType&
>(root), rootUri, unresolvedTokenIndex, allocator);
595 ValueType*
Get(ValueType& root,
size_t* unresolvedTokenIndex = 0)
const {
597 ValueType* v = &root;
598 for (
const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
599 switch (v->GetType()) {
603 if (m == v->MemberEnd())
609 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
611 v = &((*v)[t->index]);
618 if (unresolvedTokenIndex)
619 *unresolvedTokenIndex =
static_cast<size_t>(t - tokens_);
630 const ValueType*
Get(
const ValueType& root,
size_t* unresolvedTokenIndex = 0)
const {
631 return Get(
const_cast<ValueType&
>(root), unresolvedTokenIndex);
649 ValueType&
GetWithDefault(ValueType& root,
const ValueType& defaultValue,
typename ValueType::AllocatorType& allocator)
const {
651 ValueType& v = Create(root, allocator, &alreadyExist);
652 return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
656 ValueType&
GetWithDefault(ValueType& root,
const Ch* defaultValue,
typename ValueType::AllocatorType& allocator)
const {
658 ValueType& v = Create(root, allocator, &alreadyExist);
659 return alreadyExist ? v : v.SetString(defaultValue, allocator);
662#if RAPIDJSON_HAS_STDSTRING
664 ValueType& GetWithDefault(ValueType& root,
const std::basic_string<Ch>& defaultValue,
typename ValueType::AllocatorType& allocator)
const {
666 ValueType& v = Create(root, allocator, &alreadyExist);
667 return alreadyExist ? v : v.SetString(defaultValue, allocator);
675 template <
typename T>
676 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
677 GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator)
const {
678 return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);
682 template <
typename stackAllocator>
684 return GetWithDefault(document, defaultValue, document.
GetAllocator());
688 template <
typename stackAllocator>
690 return GetWithDefault(document, defaultValue, document.
GetAllocator());
693#if RAPIDJSON_HAS_STDSTRING
695 template <
typename stackAllocator>
697 return GetWithDefault(document, defaultValue, document.
GetAllocator());
705 template <
typename T,
typename stackAllocator>
706 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
708 return GetWithDefault(document, defaultValue, document.GetAllocator());
726 ValueType&
Set(ValueType& root, ValueType& value,
typename ValueType::AllocatorType& allocator)
const {
727 return Create(root, allocator) = value;
731 ValueType&
Set(ValueType& root,
const ValueType& value,
typename ValueType::AllocatorType& allocator)
const {
732 return Create(root, allocator).CopyFrom(value, allocator);
736 ValueType&
Set(ValueType& root,
const Ch* value,
typename ValueType::AllocatorType& allocator)
const {
737 return Create(root, allocator) = ValueType(value, allocator).Move();
740#if RAPIDJSON_HAS_STDSTRING
742 ValueType& Set(ValueType& root,
const std::basic_string<Ch>& value,
typename ValueType::AllocatorType& allocator)
const {
743 return Create(root, allocator) = ValueType(value, allocator).Move();
751 template <
typename T>
752 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
753 Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator)
const {
754 return Create(root, allocator) = ValueType(value).Move();
758 template <
typename stackAllocator>
760 return Create(document) = value;
764 template <
typename stackAllocator>
766 return Create(document).CopyFrom(value, document.
GetAllocator());
770 template <
typename stackAllocator>
772 return Create(document) = ValueType(value, document.
GetAllocator()).Move();
775#if RAPIDJSON_HAS_STDSTRING
777 template <
typename stackAllocator>
779 return Create(document) = ValueType(value, document.
GetAllocator()).Move();
787 template <
typename T,
typename stackAllocator>
788 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
790 return Create(document) = value;
808 ValueType&
Swap(ValueType& root, ValueType& value,
typename ValueType::AllocatorType& allocator)
const {
809 return Create(root, allocator).Swap(value);
813 template <
typename stackAllocator>
815 return Create(document).Swap(value);
829 if (tokenCount_ == 0)
832 ValueType* v = &root;
833 const Token* last = tokens_ + (tokenCount_ - 1);
834 for (
const Token *t = tokens_; t != last; ++t) {
835 switch (v->GetType()) {
839 if (m == v->MemberEnd())
845 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
847 v = &((*v)[t->index]);
854 switch (v->GetType()) {
858 if (last->
index == kPointerInvalidIndex || last->
index >= v->Size())
860 v->Erase(v->Begin() + last->
index);
875 Ch* CopyFromRaw(
const GenericPointer& rhs,
size_t extraToken = 0,
size_t extraNameBufferSize = 0) {
879 size_t nameBufferSize = rhs.tokenCount_;
880 for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)
881 nameBufferSize += t->length;
883 tokenCount_ = rhs.tokenCount_ + extraToken;
884 tokens_ =
static_cast<Token *
>(allocator_->Malloc(tokenCount_ *
sizeof(Token) + (nameBufferSize + extraNameBufferSize) *
sizeof(Ch)));
885 nameBuffer_ =
reinterpret_cast<Ch *
>(tokens_ + tokenCount_);
886 if (rhs.tokenCount_ > 0) {
887 std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ *
sizeof(Token));
889 if (nameBufferSize > 0) {
890 std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize *
sizeof(Ch));
896 for (
size_t i = 0; i < rhs.tokenCount_; ++i) {
900 std::ptrdiff_t name_offset = rhs.tokens_[i].
name - rhs.nameBuffer_;
901 tokens_[i].name = nameBuffer_ + name_offset;
904 return nameBuffer_ + nameBufferSize;
912 bool NeedPercentEncode(Ch c)
const {
913 return !((c >=
'0' && c <=
'9') || (c >=
'A' && c <=
'Z') || (c >=
'a' && c <=
'z') || c ==
'-' || c ==
'.' || c ==
'_' || c ==
'~');
924 void Parse(
const Ch* source,
size_t length) {
935 for (
const Ch* s = source; s != source + length; s++)
939 Token* token = tokens_ =
static_cast<Token *
>(allocator_->Malloc(tokenCount_ *
sizeof(Token) + length *
sizeof(Ch)));
940 Ch* name = nameBuffer_ =
reinterpret_cast<Ch *
>(tokens_ + tokenCount_);
944 bool uriFragment =
false;
945 if (source[i] ==
'#') {
950 if (i != length && source[i] !=
'/') {
960 bool isNumber =
true;
962 while (i < length && source[i] !=
'/') {
967 PercentDecodeStream is(&source[i], source + length);
968 GenericInsituStringStream<EncodingType> os(name);
969 Ch* begin = os.PutBegin();
970 if (!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid()) {
974 size_t len = os.PutEnd(begin);
985 else if (NeedPercentEncode(c)) {
997 if (c ==
'0') c =
'~';
998 else if (c ==
'1') c =
'/';
1012 if (c <
'0' || c >
'9')
1017 token->length =
static_cast<SizeType>(name - token->name);
1018 if (token->length == 0)
1023 if (isNumber && token->length > 1 && token->name[0] ==
'0')
1029 for (
size_t j = 0; j < token->length; j++) {
1039 token->index = isNumber ? n : kPointerInvalidIndex;
1048 Allocator::Free(tokens_);
1052 parseErrorOffset_ = i;
1062 template<
bool uriFragment,
typename OutputStream>
1063 bool Stringify(OutputStream& os)
const {
1069 for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
1071 for (
size_t j = 0; j < t->length; j++) {
1077 else if (c ==
'/') {
1081 else if (uriFragment && NeedPercentEncode(c)) {
1083 GenericStringStream<typename ValueType::EncodingType> source(&t->name[j]);
1084 PercentEncodeStream<OutputStream> target(os);
1085 if (!Transcoder<EncodingType, UTF8<> >().Validate(source, target))
1087 j += source.Tell() - 1;
1102 class PercentDecodeStream {
1104 typedef typename ValueType::Ch Ch;
1111 PercentDecodeStream(
const Ch* source,
const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {}
1114 if (*src_ !=
'%' || src_ + 3 > end_) {
1120 for (
int j = 0; j < 2; j++) {
1121 c =
static_cast<Ch
>(c << 4);
1123 if (h >=
'0' && h <=
'9') c =
static_cast<Ch
>(c + h -
'0');
1124 else if (h >=
'A' && h <=
'F') c =
static_cast<Ch
>(c + h -
'A' + 10);
1125 else if (h >=
'a' && h <=
'f') c =
static_cast<Ch
>(c + h -
'a' + 10);
1135 size_t Tell()
const {
return static_cast<size_t>(src_ - head_); }
1136 bool IsValid()
const {
return valid_; }
1146 template <
typename OutputStream>
1147 class PercentEncodeStream {
1149 PercentEncodeStream(OutputStream& os) : os_(os) {}
1151 unsigned char u =
static_cast<unsigned char>(c);
1152 static const char hexDigits[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
1154 os_.Put(
static_cast<typename OutputStream::Ch
>(hexDigits[u >> 4]));
1155 os_.Put(
static_cast<typename OutputStream::Ch
>(hexDigits[u & 15]));
1166 size_t parseErrorOffset_;
1171typedef GenericPointer<Value>
Pointer;
1178template <
typename T>
1179typename T::ValueType& CreateValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
typename T::AllocatorType& a) {
1180 return pointer.Create(root, a);
1183template <
typename T,
typename CharType,
size_t N>
1184typename T::ValueType& CreateValueByPointer(T& root,
const CharType(&source)[N],
typename T::AllocatorType& a) {
1185 return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a);
1190template <
typename DocumentType>
1191typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer) {
1192 return pointer.Create(document);
1195template <
typename DocumentType,
typename CharType,
size_t N>
1196typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document,
const CharType(&source)[N]) {
1197 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document);
1202template <
typename T>
1203typename T::ValueType* GetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
size_t* unresolvedTokenIndex = 0) {
1204 return pointer.Get(root, unresolvedTokenIndex);
1207template <
typename T>
1208const typename T::ValueType* GetValueByPointer(
const T& root,
const GenericPointer<typename T::ValueType>& pointer,
size_t* unresolvedTokenIndex = 0) {
1209 return pointer.Get(root, unresolvedTokenIndex);
1212template <
typename T,
typename CharType,
size_t N>
1213typename T::ValueType* GetValueByPointer(T& root,
const CharType (&source)[N],
size_t* unresolvedTokenIndex = 0) {
1214 return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1217template <
typename T,
typename CharType,
size_t N>
1218const typename T::ValueType* GetValueByPointer(
const T& root,
const CharType(&source)[N],
size_t* unresolvedTokenIndex = 0) {
1219 return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1224template <
typename T>
1225typename T::ValueType& GetValueByPointerWithDefault(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const typename T::ValueType& defaultValue,
typename T::AllocatorType& a) {
1226 return pointer.GetWithDefault(root, defaultValue, a);
1229template <
typename T>
1230typename T::ValueType& GetValueByPointerWithDefault(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const typename T::Ch* defaultValue,
typename T::AllocatorType& a) {
1231 return pointer.GetWithDefault(root, defaultValue, a);
1234#if RAPIDJSON_HAS_STDSTRING
1235template <
typename T>
1236typename T::ValueType& GetValueByPointerWithDefault(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const std::basic_string<typename T::Ch>& defaultValue,
typename T::AllocatorType& a) {
1237 return pointer.GetWithDefault(root, defaultValue, a);
1241template <
typename T,
typename T2>
1242RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename T::ValueType&))
1243GetValueByPointerWithDefault(T& root,
const GenericPointer<typename T::ValueType>& pointer, T2 defaultValue,
typename T::AllocatorType& a) {
1244 return pointer.GetWithDefault(root, defaultValue, a);
1247template <
typename T,
typename CharType,
size_t N>
1248typename T::ValueType& GetValueByPointerWithDefault(T& root,
const CharType(&source)[N],
const typename T::ValueType& defaultValue,
typename T::AllocatorType& a) {
1249 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1252template <
typename T,
typename CharType,
size_t N>
1253typename T::ValueType& GetValueByPointerWithDefault(T& root,
const CharType(&source)[N],
const typename T::Ch* defaultValue,
typename T::AllocatorType& a) {
1254 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1257#if RAPIDJSON_HAS_STDSTRING
1258template <
typename T,
typename CharType,
size_t N>
1259typename T::ValueType& GetValueByPointerWithDefault(T& root,
const CharType(&source)[N],
const std::basic_string<typename T::Ch>& defaultValue,
typename T::AllocatorType& a) {
1260 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1264template <
typename T,
typename CharType,
size_t N,
typename T2>
1265RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename T::ValueType&))
1266GetValueByPointerWithDefault(T& root,
const CharType(&source)[N], T2 defaultValue,
typename T::AllocatorType& a) {
1267 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1272template <
typename DocumentType>
1273typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const typename DocumentType::ValueType& defaultValue) {
1274 return pointer.GetWithDefault(document, defaultValue);
1277template <
typename DocumentType>
1278typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const typename DocumentType::Ch* defaultValue) {
1279 return pointer.GetWithDefault(document, defaultValue);
1282#if RAPIDJSON_HAS_STDSTRING
1283template <
typename DocumentType>
1284typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1285 return pointer.GetWithDefault(document, defaultValue);
1289template <
typename DocumentType,
typename T2>
1290RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename DocumentType::ValueType&))
1291GetValueByPointerWithDefault(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer, T2 defaultValue) {
1292 return pointer.GetWithDefault(document, defaultValue);
1295template <
typename DocumentType,
typename CharType,
size_t N>
1296typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const CharType(&source)[N],
const typename DocumentType::ValueType& defaultValue) {
1297 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1300template <
typename DocumentType,
typename CharType,
size_t N>
1301typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const CharType(&source)[N],
const typename DocumentType::Ch* defaultValue) {
1302 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1305#if RAPIDJSON_HAS_STDSTRING
1306template <
typename DocumentType,
typename CharType,
size_t N>
1307typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const CharType(&source)[N],
const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1308 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1312template <
typename DocumentType,
typename CharType,
size_t N,
typename T2>
1313RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename DocumentType::ValueType&))
1314GetValueByPointerWithDefault(DocumentType& document,
const CharType(&source)[N], T2 defaultValue) {
1315 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1320template <
typename T>
1321typename T::ValueType& SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
typename T::ValueType& value,
typename T::AllocatorType& a) {
1322 return pointer.Set(root, value, a);
1325template <
typename T>
1326typename T::ValueType& SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const typename T::ValueType& value,
typename T::AllocatorType& a) {
1327 return pointer.Set(root, value, a);
1330template <
typename T>
1331typename T::ValueType& SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const typename T::Ch* value,
typename T::AllocatorType& a) {
1332 return pointer.Set(root, value, a);
1335#if RAPIDJSON_HAS_STDSTRING
1336template <
typename T>
1337typename T::ValueType& SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const std::basic_string<typename T::Ch>& value,
typename T::AllocatorType& a) {
1338 return pointer.Set(root, value, a);
1342template <
typename T,
typename T2>
1343RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename T::ValueType&))
1344SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer, T2 value,
typename T::AllocatorType& a) {
1345 return pointer.Set(root, value, a);
1348template <
typename T,
typename CharType,
size_t N>
1349typename T::ValueType& SetValueByPointer(T& root,
const CharType(&source)[N],
typename T::ValueType& value,
typename T::AllocatorType& a) {
1350 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1353template <
typename T,
typename CharType,
size_t N>
1354typename T::ValueType& SetValueByPointer(T& root,
const CharType(&source)[N],
const typename T::ValueType& value,
typename T::AllocatorType& a) {
1355 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1358template <
typename T,
typename CharType,
size_t N>
1359typename T::ValueType& SetValueByPointer(T& root,
const CharType(&source)[N],
const typename T::Ch* value,
typename T::AllocatorType& a) {
1360 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1363#if RAPIDJSON_HAS_STDSTRING
1364template <
typename T,
typename CharType,
size_t N>
1365typename T::ValueType& SetValueByPointer(T& root,
const CharType(&source)[N],
const std::basic_string<typename T::Ch>& value,
typename T::AllocatorType& a) {
1366 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1370template <
typename T,
typename CharType,
size_t N,
typename T2>
1371RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename T::ValueType&))
1372SetValueByPointer(T& root,
const CharType(&source)[N], T2 value,
typename T::AllocatorType& a) {
1373 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1378template <
typename DocumentType>
1379typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
typename DocumentType::ValueType& value) {
1380 return pointer.Set(document, value);
1383template <
typename DocumentType>
1384typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const typename DocumentType::ValueType& value) {
1385 return pointer.Set(document, value);
1388template <
typename DocumentType>
1389typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const typename DocumentType::Ch* value) {
1390 return pointer.Set(document, value);
1393#if RAPIDJSON_HAS_STDSTRING
1394template <
typename DocumentType>
1395typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const std::basic_string<typename DocumentType::Ch>& value) {
1396 return pointer.Set(document, value);
1400template <
typename DocumentType,
typename T2>
1401RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename DocumentType::ValueType&))
1402SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer, T2 value) {
1403 return pointer.Set(document, value);
1406template <
typename DocumentType,
typename CharType,
size_t N>
1407typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const CharType(&source)[N],
typename DocumentType::ValueType& value) {
1408 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1411template <
typename DocumentType,
typename CharType,
size_t N>
1412typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const CharType(&source)[N],
const typename DocumentType::ValueType& value) {
1413 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1416template <
typename DocumentType,
typename CharType,
size_t N>
1417typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const CharType(&source)[N],
const typename DocumentType::Ch* value) {
1418 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1421#if RAPIDJSON_HAS_STDSTRING
1422template <
typename DocumentType,
typename CharType,
size_t N>
1423typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const CharType(&source)[N],
const std::basic_string<typename DocumentType::Ch>& value) {
1424 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1428template <
typename DocumentType,
typename CharType,
size_t N,
typename T2>
1429RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename DocumentType::ValueType&))
1430SetValueByPointer(DocumentType& document,
const CharType(&source)[N], T2 value) {
1431 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1436template <
typename T>
1437typename T::ValueType& SwapValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
typename T::ValueType& value,
typename T::AllocatorType& a) {
1438 return pointer.Swap(root, value, a);
1441template <
typename T,
typename CharType,
size_t N>
1442typename T::ValueType& SwapValueByPointer(T& root,
const CharType(&source)[N],
typename T::ValueType& value,
typename T::AllocatorType& a) {
1443 return GenericPointer<typename T::ValueType>(source, N - 1).Swap(root, value, a);
1446template <
typename DocumentType>
1447typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
typename DocumentType::ValueType& value) {
1448 return pointer.Swap(document, value);
1451template <
typename DocumentType,
typename CharType,
size_t N>
1452typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document,
const CharType(&source)[N],
typename DocumentType::ValueType& value) {
1453 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Swap(document, value);
1458template <
typename T>
1459bool EraseValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer) {
1460 return pointer.Erase(root);
1463template <
typename T,
typename CharType,
size_t N>
1464bool EraseValueByPointer(T& root,
const CharType(&source)[N]) {
1465 return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root);
1470RAPIDJSON_NAMESPACE_END
1472#if defined(__clang__) || defined(_MSC_VER)
Concept for allocating, resizing and freeing memory block.
A document for parsing JSON text as DOM.
Definition fwd.h:119
Allocator & GetAllocator()
Get the allocator of this document.
Definition document.h:2796
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition pointer.h:68
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:128
GenericPointer & operator=(const GenericPointer &rhs)
Assignment operator.
Definition pointer.h:174
~GenericPointer()
Destructor.
Definition pointer.h:167
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:656
friend void swap(GenericPointer &a, GenericPointer &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition pointer.h:222
bool operator<(const GenericPointer &rhs) const
Less than operator.
Definition pointer.h:384
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:253
ValueType & Create(ValueType &root, typename ValueType::AllocatorType &allocator, bool *alreadyExist=0) const
Create a value in a subtree.
Definition pointer.h:452
ValueType::Ch Ch
Character type from Value.
Definition pointer.h:71
ValueType & Set(ValueType &root, const Ch *value, typename ValueType::AllocatorType &allocator) const
Set a null-terminated string in a subtree.
Definition pointer.h:736
bool operator==(const GenericPointer &rhs) const
Equality operator.
Definition pointer.h:358
ValueType & Set(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, const Ch *value) const
Set a null-terminated string in a document.
Definition pointer.h:771
GenericPointer Append(SizeType index, Allocator *allocator=0) const
Append a index token, and return a new Pointer.
Definition pointer.h:288
GenericPointer Append(const ValueType &token, Allocator *allocator=0) const
Append a token by value, and return a new Pointer.
Definition pointer.h:313
Allocator & GetAllocator()
Get the allocator of this pointer.
Definition pointer.h:338
ValueType & Create(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, bool *alreadyExist=0) const
Creates a value in a document.
Definition pointer.h:508
GenericPointer(const Token *tokens, size_t tokenCount)
Constructor with user-supplied tokens.
Definition pointer.h:154
bool Stringify(OutputStream &os) const
Stringify the pointer into string representation.
Definition pointer.h:418
size_t GetParseErrorOffset() const
Get the parsing error offset in code unit.
Definition pointer.h:330
size_t GetTokenCount() const
Get the number of tokens.
Definition pointer.h:347
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
Definition pointer.h:235
ValueType & Set(ValueType &root, const ValueType &value, typename ValueType::AllocatorType &allocator) const
Set a value in a subtree, with copy semantics.
Definition pointer.h:731
ValueType & GetWithDefault(ValueType &root, const ValueType &defaultValue, typename ValueType::AllocatorType &allocator) const
Query a value in a subtree with default value.
Definition pointer.h:649
ValueType * Get(ValueType &root, size_t *unresolvedTokenIndex=0) const
Query a value in a subtree.
Definition pointer.h:595
bool operator!=(const GenericPointer &rhs) const
Inequality operator.
Definition pointer.h:378
GenericPointer(const Ch *source, Allocator *allocator=0)
Constructor that parses a string or URI fragment representation.
Definition pointer.h:105
ValueType & Set(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, ValueType &value) const
Set a value in a document, with move semantics.
Definition pointer.h:759
ValueType & Swap(ValueType &root, ValueType &value, typename ValueType::AllocatorType &allocator) const
Swap a value with a value in a subtree.
Definition pointer.h:808
bool Erase(ValueType &root) const
Erase a value in a subtree.
Definition pointer.h:827
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:765
bool IsValid() const
Check whether this is a valid pointer.
Definition pointer.h:327
GenericPointer(Allocator *allocator=0)
Default constructor.
Definition pointer.h:98
ValueType & Swap(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, ValueType &value) const
Swap a value with a value in a document.
Definition pointer.h:814
ValueType::EncodingType EncodingType
Encoding type from Value.
Definition pointer.h:70
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:683
ValueType & Set(ValueType &root, ValueType &value, typename ValueType::AllocatorType &allocator) const
Set a value in a subtree, with move semantics.
Definition pointer.h:726
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:689
const ValueType * Get(const ValueType &root, size_t *unresolvedTokenIndex=0) const
Query a const value in a const subtree.
Definition pointer.h:630
GenericPointer & Swap(GenericPointer &other) RAPIDJSON_NOEXCEPT
Swap the content of this pointer with an other.
Definition pointer.h:199
GenericPointer(const GenericPointer &rhs)
Copy constructor.
Definition pointer.h:157
bool StringifyUriFragment(OutputStream &os) const
Stringify the pointer into URI fragment representation.
Definition pointer.h:428
UriType GetUri(ValueType &root, const UriType &rootUri, size_t *unresolvedTokenIndex=0, Allocator *allocator=0) const
Compute the in-scope URI for a subtree.
Definition pointer.h:534
const Token * GetTokens() const
Get the token array (const version only).
Definition pointer.h:344
PointerParseErrorCode GetParseErrorCode() const
Get the parsing error code.
Definition pointer.h:333
GenericPointer(const GenericPointer &rhs, Allocator *allocator)
Copy constructor.
Definition pointer.h:162
GenericUri Resolve(const GenericUri &baseuri, Allocator *allocator=0)
Resolve this URI against another (base) URI in accordance with URI resolution rules.
Definition uri.h:156
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition fwd.h:114
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition rapidjson.h:437
PointerParseErrorCode
Error code of JSON pointer parsing.
Definition error.h:257
@ kPointerParseErrorInvalidPercentEncoding
Invalid percent encoding in URI fragment.
Definition error.h:262
@ kPointerParseErrorTokenMustBeginWithSolidus
A token must begin with a '/'.
Definition error.h:260
@ kPointerParseErrorInvalidEscape
Invalid escape.
Definition error.h:261
@ kPointerParseErrorNone
The parse is successful.
Definition error.h:258
@ kPointerParseErrorCharacterMustPercentEncode
A character must percent encoded in URI fragment.
Definition error.h:263
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:415
@ kArrayType
array
Definition rapidjson.h:734
@ kObjectType
object
Definition rapidjson.h:733
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition rapidjson.h:716
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition rapidjson.h:712
A token is the basic units of internal representation.
Definition pointer.h:88
SizeType index
A valid array index, if it is not equal to kPointerInvalidIndex.
Definition pointer.h:91
const Ch * name
Name of the token. It has null character at the end but it can contain null character.
Definition pointer.h:89
SizeType length
Length of the name.
Definition pointer.h:90
Reference to a constant string (not taking a copy)
Definition fwd.h:111