15 #ifndef RAPIDJSON_POINTER_H_
16 #define RAPIDJSON_POINTER_H_
20 #include "internal/itoa.h"
25 RAPIDJSON_DIAG_OFF(
switch-
enum)
26 #elif defined(_MSC_VER)
28 RAPIDJSON_DIAG_OFF(4512)
31 #if defined(RAPIDJSON_CPLUSPLUS) && RAPIDJSON_CPLUSPLUS >= 201703L
32 #define RAPIDJSON_IF_CONSTEXPR if constexpr
34 #define RAPIDJSON_IF_CONSTEXPR if
37 RAPIDJSON_NAMESPACE_BEGIN
73 template <
typename ValueType,
typename Allocator = CrtAllocator>
74 class GenericPointer {
77 typedef typename ValueType::Ch
Ch;
112 Parse(source, internal::StrLen(source));
115 #if RAPIDJSON_HAS_STDSTRING
123 Parse(source.c_str(), source.size());
135 Parse(source, length);
175 Allocator::Free(tokens_);
184 Allocator::Free(tokens_);
186 tokenCount_ = rhs.tokenCount_;
187 parseErrorOffset_ = rhs.parseErrorOffset_;
188 parseErrorCode_ = rhs.parseErrorCode_;
193 tokens_ = rhs.tokens_;
206 internal::Swap(allocator_, other.allocator_);
207 internal::Swap(ownAllocator_, other.ownAllocator_);
208 internal::Swap(nameBuffer_, other.nameBuffer_);
209 internal::Swap(tokens_, other.tokens_);
210 internal::Swap(tokenCount_, other.tokenCount_);
211 internal::Swap(parseErrorOffset_, other.parseErrorOffset_);
212 internal::Swap(parseErrorCode_, other.parseErrorCode_);
243 r.allocator_ = allocator;
244 Ch *p = r.CopyFromRaw(*
this, 1, token.
length + 1);
245 std::memcpy(p, token.
name, (token.
length + 1) *
sizeof(Ch));
246 r.tokens_[tokenCount_].name = p;
247 r.tokens_[tokenCount_].length = token.
length;
248 r.tokens_[tokenCount_].index = token.
index;
260 Token token = { name, length, kPointerInvalidIndex };
261 return Append(token, allocator);
270 template <
typename T>
273 return Append(name, internal::StrLen(name), allocator);
276 #if RAPIDJSON_HAS_STDSTRING
284 return Append(name.c_str(),
static_cast<SizeType>(name.size()), allocator);
296 char* end =
sizeof(
SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer);
298 buffer[length] =
'\0';
300 RAPIDJSON_IF_CONSTEXPR (
sizeof(Ch) == 1) {
301 Token token = {
reinterpret_cast<Ch*
>(buffer), length, index };
302 return Append(token, allocator);
306 for (
size_t i = 0; i <= length; i++)
307 name[i] = static_cast<Ch>(buffer[i]);
308 Token token = { name, length, index };
309 return Append(token, allocator);
320 if (token.IsString())
321 return Append(token.GetString(), token.GetStringLength(), allocator);
325 return Append(static_cast<SizeType>(token.GetUint64()), allocator);
365 if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_)
368 for (
size_t i = 0; i < tokenCount_; i++) {
369 if (tokens_[i].index != rhs.tokens_[i].index ||
370 tokens_[i].length != rhs.tokens_[i].length ||
371 (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name,
sizeof(Ch)* tokens_[i].length) != 0))
396 if (tokenCount_ != rhs.tokenCount_)
397 return tokenCount_ < rhs.tokenCount_;
399 for (
size_t i = 0; i < tokenCount_; i++) {
400 if (tokens_[i].index != rhs.tokens_[i].index)
401 return tokens_[i].index < rhs.tokens_[i].index;
403 if (tokens_[i].length != rhs.tokens_[i].length)
404 return tokens_[i].length < rhs.tokens_[i].length;
406 if (
int cmp = std::memcmp(tokens_[i].name, rhs.tokens_[i].name,
sizeof(Ch) * tokens_[i].length))
423 template<
typename OutputStream>
425 return Stringify<false, OutputStream>(os);
433 template<
typename OutputStream>
435 return Stringify<true, OutputStream>(os);
458 ValueType&
Create(ValueType& root,
typename ValueType::AllocatorType& allocator,
bool* alreadyExist = 0)
const {
460 ValueType* v = &root;
462 for (
const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
463 if (v->IsArray() && t->name[0] ==
'-' && t->length == 1) {
464 v->PushBack(ValueType().Move(), allocator);
465 v = &((*v)[v->Size() - 1]);
469 if (t->index == kPointerInvalidIndex) {
474 if (!v->IsArray() && !v->IsObject())
479 if (t->index >= v->Size()) {
480 v->Reserve(t->index + 1, allocator);
481 while (t->index >= v->Size())
482 v->PushBack(ValueType().Move(), allocator);
485 v = &((*v)[t->index]);
489 if (m == v->MemberEnd()) {
490 v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
502 *alreadyExist = exist;
513 template <
typename stackAllocator>
515 return Create(document, document.
GetAllocator(), alreadyExist);
540 UriType
GetUri(ValueType& root,
const UriType& rootUri,
size_t* unresolvedTokenIndex = 0,
Allocator* allocator = 0)
const {
541 static const Ch kIdString[] = {
'i',
'd',
'\0' };
542 static const ValueType kIdValue(kIdString, 2);
543 UriType base = UriType(rootUri, allocator);
545 ValueType* v = &root;
546 for (
const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
547 switch (v->GetType()) {
551 typename ValueType::MemberIterator m = v->FindMember(kIdValue);
552 if (m != v->MemberEnd() && (m->value).IsString()) {
553 UriType here = UriType(m->value, allocator).Resolve(base, allocator);
557 if (m == v->MemberEnd())
563 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
565 v = &((*v)[t->index]);
572 if (unresolvedTokenIndex)
573 *unresolvedTokenIndex =
static_cast<size_t>(t - tokens_);
574 return UriType(allocator);
579 UriType GetUri(
const ValueType& root,
const UriType& rootUri,
size_t* unresolvedTokenIndex = 0,
Allocator* allocator = 0)
const {
580 return GetUri(const_cast<ValueType&>(root), rootUri, unresolvedTokenIndex, allocator);
601 ValueType*
Get(ValueType& root,
size_t* unresolvedTokenIndex = 0)
const {
603 ValueType* v = &root;
604 for (
const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
605 switch (v->GetType()) {
609 if (m == v->MemberEnd())
615 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
617 v = &((*v)[t->index]);
624 if (unresolvedTokenIndex)
625 *unresolvedTokenIndex =
static_cast<size_t>(t - tokens_);
636 const ValueType*
Get(
const ValueType& root,
size_t* unresolvedTokenIndex = 0)
const {
637 return Get(const_cast<ValueType&>(root), unresolvedTokenIndex);
655 ValueType&
GetWithDefault(ValueType& root,
const ValueType& defaultValue,
typename ValueType::AllocatorType& allocator)
const {
657 ValueType& v = Create(root, allocator, &alreadyExist);
658 return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
662 ValueType&
GetWithDefault(ValueType& root,
const Ch* defaultValue,
typename ValueType::AllocatorType& allocator)
const {
664 ValueType& v = Create(root, allocator, &alreadyExist);
665 return alreadyExist ? v : v.SetString(defaultValue, allocator);
668 #if RAPIDJSON_HAS_STDSTRING
670 ValueType&
GetWithDefault(ValueType& root,
const std::basic_string<Ch>& defaultValue,
typename ValueType::AllocatorType& allocator)
const {
672 ValueType& v = Create(root, allocator, &alreadyExist);
673 return alreadyExist ? v : v.SetString(defaultValue, allocator);
681 template <
typename T>
682 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
683 GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator)
const {
684 return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);
688 template <
typename stackAllocator>
690 return GetWithDefault(document, defaultValue, document.
GetAllocator());
694 template <
typename stackAllocator>
696 return GetWithDefault(document, defaultValue, document.
GetAllocator());
699 #if RAPIDJSON_HAS_STDSTRING
701 template <
typename stackAllocator>
703 return GetWithDefault(document, defaultValue, document.
GetAllocator());
711 template <
typename T,
typename stackAllocator>
712 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
713 GetWithDefault(
GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T defaultValue)
const {
714 return GetWithDefault(document, defaultValue, document.GetAllocator());
732 ValueType&
Set(ValueType& root, ValueType& value,
typename ValueType::AllocatorType& allocator)
const {
733 return Create(root, allocator) = value;
737 ValueType&
Set(ValueType& root,
const ValueType& value,
typename ValueType::AllocatorType& allocator)
const {
738 return Create(root, allocator).CopyFrom(value, allocator);
742 ValueType&
Set(ValueType& root,
const Ch* value,
typename ValueType::AllocatorType& allocator)
const {
743 return Create(root, allocator) = ValueType(value, allocator).Move();
746 #if RAPIDJSON_HAS_STDSTRING
748 ValueType&
Set(ValueType& root,
const std::basic_string<Ch>& value,
typename ValueType::AllocatorType& allocator)
const {
749 return Create(root, allocator) = ValueType(value, allocator).Move();
757 template <
typename T>
758 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
759 Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator)
const {
760 return Create(root, allocator) = ValueType(value).Move();
764 template <
typename stackAllocator>
766 return Create(document) = value;
770 template <
typename stackAllocator>
772 return Create(document).CopyFrom(value, document.
GetAllocator());
776 template <
typename stackAllocator>
778 return Create(document) = ValueType(value, document.
GetAllocator()).Move();
781 #if RAPIDJSON_HAS_STDSTRING
783 template <
typename stackAllocator>
785 return Create(document) = ValueType(value, document.
GetAllocator()).Move();
793 template <
typename T,
typename stackAllocator>
794 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
795 Set(
GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T value)
const {
796 return Create(document) = value;
814 ValueType&
Swap(ValueType& root, ValueType& value,
typename ValueType::AllocatorType& allocator)
const {
815 return Create(root, allocator).Swap(value);
819 template <
typename stackAllocator>
821 return Create(document).Swap(value);
835 if (tokenCount_ == 0)
838 ValueType* v = &root;
839 const Token* last = tokens_ + (tokenCount_ - 1);
840 for (
const Token *t = tokens_; t != last; ++t) {
841 switch (v->GetType()) {
845 if (m == v->MemberEnd())
851 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
853 v = &((*v)[t->index]);
860 switch (v->GetType()) {
864 if (last->
index == kPointerInvalidIndex || last->
index >= v->Size())
866 v->Erase(v->Begin() + last->
index);
881 Ch* CopyFromRaw(
const GenericPointer& rhs,
size_t extraToken = 0,
size_t extraNameBufferSize = 0) {
885 size_t nameBufferSize = rhs.tokenCount_;
886 for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)
887 nameBufferSize += t->length;
889 tokenCount_ = rhs.tokenCount_ + extraToken;
890 tokens_ =
static_cast<Token *
>(allocator_->Malloc(tokenCount_ *
sizeof(Token) + (nameBufferSize + extraNameBufferSize) *
sizeof(Ch)));
891 nameBuffer_ =
reinterpret_cast<Ch *
>(tokens_ + tokenCount_);
892 if (rhs.tokenCount_ > 0) {
893 std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ *
sizeof(Token));
895 if (nameBufferSize > 0) {
896 std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize *
sizeof(Ch));
902 for (
size_t i = 0; i < rhs.tokenCount_; ++i) {
906 std::ptrdiff_t name_offset = rhs.tokens_[i].name - rhs.nameBuffer_;
907 tokens_[i].name = nameBuffer_ + name_offset;
910 return nameBuffer_ + nameBufferSize;
918 bool NeedPercentEncode(Ch c)
const {
919 return !((c >=
'0' && c <= '9') || (c >=
'A' && c <='Z') || (c >=
'a' && c <=
'z') || c ==
'-' || c ==
'.' || c ==
'_' || c ==
'~');
923 #ifndef __clang__ // -Wdocumentation
930 void Parse(
const Ch* source,
size_t length) {
941 for (
const Ch* s = source; s != source + length; s++)
945 Token* token = tokens_ =
static_cast<Token *
>(allocator_->Malloc(tokenCount_ *
sizeof(Token) + length *
sizeof(Ch)));
946 Ch* name = nameBuffer_ =
reinterpret_cast<Ch *
>(tokens_ + tokenCount_);
950 bool uriFragment =
false;
951 if (source[i] ==
'#') {
956 if (i != length && source[i] !=
'/') {
966 bool isNumber =
true;
968 while (i < length && source[i] !=
'/') {
973 PercentDecodeStream is(&source[i], source + length);
974 GenericInsituStringStream<EncodingType> os(name);
975 Ch* begin = os.PutBegin();
976 if (!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid()) {
980 size_t len = os.PutEnd(begin);
991 else if (NeedPercentEncode(c)) {
1003 if (c ==
'0') c =
'~';
1004 else if (c ==
'1') c =
'/';
1018 if (c < '0' || c >
'9')
1023 token->length =
static_cast<SizeType>(name - token->name);
1024 if (token->length == 0)
1029 if (isNumber && token->length > 1 && token->name[0] ==
'0')
1035 for (
size_t j = 0; j < token->length; j++) {
1045 token->index = isNumber ? n : kPointerInvalidIndex;
1054 Allocator::Free(tokens_);
1058 parseErrorOffset_ = i;
1068 template<
bool uriFragment,
typename OutputStream>
1069 bool Stringify(OutputStream& os)
const {
1075 for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
1077 for (
size_t j = 0; j < t->length; j++) {
1083 else if (c ==
'/') {
1087 else if (uriFragment && NeedPercentEncode(c)) {
1089 GenericStringStream<typename ValueType::EncodingType> source(&t->name[j]);
1090 PercentEncodeStream<OutputStream> target(os);
1091 if (!Transcoder<EncodingType, UTF8<> >().Validate(source, target))
1093 j += source.Tell() - 1;
1108 class PercentDecodeStream {
1110 typedef typename ValueType::Ch Ch;
1117 PercentDecodeStream(
const Ch* source,
const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {}
1120 if (*src_ !=
'%' || src_ + 3 > end_) {
1126 for (
int j = 0; j < 2; j++) {
1127 c =
static_cast<Ch
>(c << 4);
1129 if (h >=
'0' && h <=
'9') c =
static_cast<Ch
>(c + h -
'0');
1130 else if (h >=
'A' && h <=
'F') c =
static_cast<Ch
>(c + h -
'A' + 10);
1131 else if (h >=
'a' && h <=
'f') c =
static_cast<Ch
>(c + h -
'a' + 10);
1141 size_t Tell()
const {
return static_cast<size_t>(src_ - head_); }
1142 bool IsValid()
const {
return valid_; }
1152 template <
typename OutputStream>
1153 class PercentEncodeStream {
1155 PercentEncodeStream(OutputStream& os) : os_(os) {}
1157 unsigned char u =
static_cast<unsigned char>(c);
1158 static const char hexDigits[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
1160 os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u >> 4]));
1161 os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u & 15]));
1167 Allocator* allocator_;
1168 Allocator* ownAllocator_;
1172 size_t parseErrorOffset_;
1177 typedef GenericPointer<Value>
Pointer;
1184 template <
typename T>
1185 typename T::ValueType& CreateValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
typename T::AllocatorType& a) {
1186 return pointer.Create(root, a);
1189 template <
typename T,
typename CharType,
size_t N>
1190 typename T::ValueType& CreateValueByPointer(T& root,
const CharType(&source)[N],
typename T::AllocatorType& a) {
1191 return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a);
1196 template <
typename DocumentType>
1197 typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer) {
1198 return pointer.Create(document);
1201 template <
typename DocumentType,
typename CharType,
size_t N>
1202 typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document,
const CharType(&source)[N]) {
1203 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document);
1208 template <
typename T>
1209 typename T::ValueType* GetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
size_t* unresolvedTokenIndex = 0) {
1210 return pointer.Get(root, unresolvedTokenIndex);
1213 template <
typename T>
1214 const typename T::ValueType* GetValueByPointer(
const T& root,
const GenericPointer<typename T::ValueType>& pointer,
size_t* unresolvedTokenIndex = 0) {
1215 return pointer.Get(root, unresolvedTokenIndex);
1218 template <
typename T,
typename CharType,
size_t N>
1219 typename T::ValueType* GetValueByPointer(T& root,
const CharType (&source)[N],
size_t* unresolvedTokenIndex = 0) {
1220 return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1223 template <
typename T,
typename CharType,
size_t N>
1224 const typename T::ValueType* GetValueByPointer(
const T& root,
const CharType(&source)[N],
size_t* unresolvedTokenIndex = 0) {
1225 return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1230 template <
typename T>
1231 typename T::ValueType& GetValueByPointerWithDefault(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const typename T::ValueType& defaultValue,
typename T::AllocatorType& a) {
1232 return pointer.GetWithDefault(root, defaultValue, a);
1235 template <
typename T>
1236 typename T::ValueType& GetValueByPointerWithDefault(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const typename T::Ch* defaultValue,
typename T::AllocatorType& a) {
1237 return pointer.GetWithDefault(root, defaultValue, a);
1240 #if RAPIDJSON_HAS_STDSTRING
1241 template <
typename T>
1242 typename T::ValueType& GetValueByPointerWithDefault(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const std::basic_string<typename T::Ch>& defaultValue,
typename T::AllocatorType& a) {
1243 return pointer.GetWithDefault(root, defaultValue, a);
1247 template <
typename T,
typename T2>
1248 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename T::ValueType&))
1249 GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 defaultValue, typename T::AllocatorType& a) {
1250 return pointer.GetWithDefault(root, defaultValue, a);
1253 template <
typename T,
typename CharType,
size_t N>
1254 typename T::ValueType& GetValueByPointerWithDefault(T& root,
const CharType(&source)[N],
const typename T::ValueType& defaultValue,
typename T::AllocatorType& a) {
1255 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1258 template <
typename T,
typename CharType,
size_t N>
1259 typename T::ValueType& GetValueByPointerWithDefault(T& root,
const CharType(&source)[N],
const typename T::Ch* defaultValue,
typename T::AllocatorType& a) {
1260 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1263 #if RAPIDJSON_HAS_STDSTRING
1264 template <
typename T,
typename CharType,
size_t N>
1265 typename T::ValueType& GetValueByPointerWithDefault(T& root,
const CharType(&source)[N],
const std::basic_string<typename T::Ch>& defaultValue,
typename T::AllocatorType& a) {
1266 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1270 template <
typename T,
typename CharType,
size_t N,
typename T2>
1271 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename T::ValueType&))
1272 GetValueByPointerWithDefault(T& root, const CharType(&source)[N], T2 defaultValue, typename T::AllocatorType& a) {
1273 return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1278 template <
typename DocumentType>
1279 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const typename DocumentType::ValueType& defaultValue) {
1280 return pointer.GetWithDefault(document, defaultValue);
1283 template <
typename DocumentType>
1284 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const typename DocumentType::Ch* defaultValue) {
1285 return pointer.GetWithDefault(document, defaultValue);
1288 #if RAPIDJSON_HAS_STDSTRING
1289 template <
typename DocumentType>
1290 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1291 return pointer.GetWithDefault(document, defaultValue);
1295 template <
typename DocumentType,
typename T2>
1296 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename DocumentType::ValueType&))
1297 GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 defaultValue) {
1298 return pointer.GetWithDefault(document, defaultValue);
1301 template <
typename DocumentType,
typename CharType,
size_t N>
1302 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const CharType(&source)[N],
const typename DocumentType::ValueType& defaultValue) {
1303 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1306 template <
typename DocumentType,
typename CharType,
size_t N>
1307 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const CharType(&source)[N],
const typename DocumentType::Ch* defaultValue) {
1308 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1311 #if RAPIDJSON_HAS_STDSTRING
1312 template <
typename DocumentType,
typename CharType,
size_t N>
1313 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document,
const CharType(&source)[N],
const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1314 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1318 template <
typename DocumentType,
typename CharType,
size_t N,
typename T2>
1319 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename DocumentType::ValueType&))
1320 GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) {
1321 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1326 template <
typename T>
1327 typename T::ValueType& SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
typename T::ValueType& value,
typename T::AllocatorType& a) {
1328 return pointer.Set(root, value, a);
1331 template <
typename T>
1332 typename T::ValueType& SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const typename T::ValueType& value,
typename T::AllocatorType& a) {
1333 return pointer.Set(root, value, a);
1336 template <
typename T>
1337 typename T::ValueType& SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const typename T::Ch* value,
typename T::AllocatorType& a) {
1338 return pointer.Set(root, value, a);
1341 #if RAPIDJSON_HAS_STDSTRING
1342 template <
typename T>
1343 typename T::ValueType& SetValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
const std::basic_string<typename T::Ch>& value,
typename T::AllocatorType& a) {
1344 return pointer.Set(root, value, a);
1348 template <
typename T,
typename T2>
1349 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename T::ValueType&))
1350 SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 value, typename T::AllocatorType& a) {
1351 return pointer.Set(root, value, a);
1354 template <
typename T,
typename CharType,
size_t N>
1355 typename T::ValueType& SetValueByPointer(T& root,
const CharType(&source)[N],
typename T::ValueType& value,
typename T::AllocatorType& a) {
1356 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1359 template <
typename T,
typename CharType,
size_t N>
1360 typename T::ValueType& SetValueByPointer(T& root,
const CharType(&source)[N],
const typename T::ValueType& value,
typename T::AllocatorType& a) {
1361 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1364 template <
typename T,
typename CharType,
size_t N>
1365 typename T::ValueType& SetValueByPointer(T& root,
const CharType(&source)[N],
const typename T::Ch* value,
typename T::AllocatorType& a) {
1366 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1369 #if RAPIDJSON_HAS_STDSTRING
1370 template <
typename T,
typename CharType,
size_t N>
1371 typename T::ValueType& SetValueByPointer(T& root,
const CharType(&source)[N],
const std::basic_string<typename T::Ch>& value,
typename T::AllocatorType& a) {
1372 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1376 template <
typename T,
typename CharType,
size_t N,
typename T2>
1377 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename T::ValueType&))
1378 SetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) {
1379 return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1384 template <
typename DocumentType>
1385 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
typename DocumentType::ValueType& value) {
1386 return pointer.Set(document, value);
1389 template <
typename DocumentType>
1390 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const typename DocumentType::ValueType& value) {
1391 return pointer.Set(document, value);
1394 template <
typename DocumentType>
1395 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const typename DocumentType::Ch* value) {
1396 return pointer.Set(document, value);
1399 #if RAPIDJSON_HAS_STDSTRING
1400 template <
typename DocumentType>
1401 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
const std::basic_string<typename DocumentType::Ch>& value) {
1402 return pointer.Set(document, value);
1406 template <
typename DocumentType,
typename T2>
1407 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename DocumentType::ValueType&))
1408 SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 value) {
1409 return pointer.Set(document, value);
1412 template <
typename DocumentType,
typename CharType,
size_t N>
1413 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const CharType(&source)[N],
typename DocumentType::ValueType& value) {
1414 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1417 template <
typename DocumentType,
typename CharType,
size_t N>
1418 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const CharType(&source)[N],
const typename DocumentType::ValueType& value) {
1419 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1422 template <
typename DocumentType,
typename CharType,
size_t N>
1423 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const CharType(&source)[N],
const typename DocumentType::Ch* value) {
1424 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1427 #if RAPIDJSON_HAS_STDSTRING
1428 template <
typename DocumentType,
typename CharType,
size_t N>
1429 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
const CharType(&source)[N],
const std::basic_string<typename DocumentType::Ch>& value) {
1430 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1434 template <
typename DocumentType,
typename CharType,
size_t N,
typename T2>
1435 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (
typename DocumentType::ValueType&))
1436 SetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) {
1437 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1442 template <
typename T>
1443 typename T::ValueType& SwapValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer,
typename T::ValueType& value,
typename T::AllocatorType& a) {
1444 return pointer.Swap(root, value, a);
1447 template <
typename T,
typename CharType,
size_t N>
1448 typename T::ValueType& SwapValueByPointer(T& root,
const CharType(&source)[N],
typename T::ValueType& value,
typename T::AllocatorType& a) {
1449 return GenericPointer<typename T::ValueType>(source, N - 1).Swap(root, value, a);
1452 template <
typename DocumentType>
1453 typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document,
const GenericPointer<typename DocumentType::ValueType>& pointer,
typename DocumentType::ValueType& value) {
1454 return pointer.Swap(document, value);
1457 template <
typename DocumentType,
typename CharType,
size_t N>
1458 typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document,
const CharType(&source)[N],
typename DocumentType::ValueType& value) {
1459 return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Swap(document, value);
1464 template <
typename T>
1465 bool EraseValueByPointer(T& root,
const GenericPointer<typename T::ValueType>& pointer) {
1466 return pointer.Erase(root);
1469 template <
typename T,
typename CharType,
size_t N>
1470 bool EraseValueByPointer(T& root,
const CharType(&source)[N]) {
1471 return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root);
1476 RAPIDJSON_NAMESPACE_END
1478 #if defined(__clang__) || defined(_MSC_VER)
1482 #endif // RAPIDJSON_POINTER_H_
GenericPointer(const GenericPointer &rhs, Allocator *allocator)
Copy constructor.
Definition: pointer.h:168
Invalid escape.
Definition: error.h:261
ValueType * Get(ValueType &root, size_t *unresolvedTokenIndex=0) const
Query a value in a subtree.
Definition: pointer.h:601
ValueType & Set(ValueType &root, ValueType &value, typename ValueType::AllocatorType &allocator) const
Set a value in a subtree, with move semantics.
Definition: pointer.h:732
PointerParseErrorCode
Error code of JSON pointer parsing.
Definition: error.h:257
GenericPointer(const Token *tokens, size_t tokenCount)
Constructor with user-supplied tokens.
Definition: pointer.h:160
ValueType & Set(ValueType &root, const ValueType &value, typename ValueType::AllocatorType &allocator) const
Set a value in a subtree, with copy semantics.
Definition: pointer.h:737
const Ch * name
Name of the token. It has null character at the end but it can contain null character.
Definition: pointer.h:95
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:134
size_t GetParseErrorOffset() const
Get the parsing error offset in code unit.
Definition: pointer.h:336
size_t GetTokenCount() const
Get the number of tokens.
Definition: pointer.h:353
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:695
GenericPointer Append(SizeType index, Allocator *allocator=0) const
Append a index token, and return a new Pointer.
Definition: pointer.h:294
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:259
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:670
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
Definition: pointer.h:241
~GenericPointer()
Destructor.
Definition: pointer.h:173
bool operator<(const GenericPointer &rhs) const
Less than operator.
Definition: pointer.h:390
GenericPointer< Value, CrtAllocator > Pointer
GenericPointer for Value (UTF-8, default allocator).
Definition: fwd.h:126
Allocator & GetAllocator()
Get the allocator of this pointer.
Definition: pointer.h:344
unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:415
The parse is successful.
Definition: error.h:258
A character must percent encoded in URI fragment.
Definition: error.h:263
GenericPointer Append(const std::basic_string< Ch > &name, Allocator *allocator=0) const
Append a name token, and return a new Pointer.
Definition: pointer.h:283
SizeType length
Length of the name.
Definition: pointer.h:96
PointerParseErrorCode GetParseErrorCode() const
Get the parsing error code.
Definition: pointer.h:339
ValueType::Ch Ch
Character type from Value.
Definition: pointer.h:77
A token must begin with a '/'.
Definition: error.h:260
ValueType & Create(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, bool *alreadyExist=0) const
Creates a value in a document.
Definition: pointer.h:514
ValueType & Set(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, const Ch *value) const
Set a null-terminated string in a document.
Definition: pointer.h:777
ValueType & Swap(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, ValueType &value) const
Swap a value with a value in a document.
Definition: pointer.h:820
ValueType & Create(ValueType &root, typename ValueType::AllocatorType &allocator, bool *alreadyExist=0) const
Create a value in a subtree.
Definition: pointer.h:458
bool StringifyUriFragment(OutputStream &os) const
Stringify the pointer into URI fragment representation.
Definition: pointer.h:434
ValueType::EncodingType EncodingType
Encoding type from Value.
Definition: pointer.h:76
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition: rapidjson.h:712
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:702
bool operator!=(const GenericPointer &rhs) const
Inequality operator.
Definition: pointer.h:384
GenericPointer(const Ch *source, Allocator *allocator=0)
Constructor that parses a string or URI fragment representation.
Definition: pointer.h:111
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition: fwd.h:126
bool IsValid() const
Check whether this is a valid pointer.
Definition: pointer.h:333
Type
Type of JSON value.
Definition: rapidjson.h:729
GenericPointer & operator=(const GenericPointer &rhs)
Assignment operator.
Definition: pointer.h:180
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:748
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:689
object
Definition: rapidjson.h:733
const Token * GetTokens() const
Get the token array (const version only).
Definition: pointer.h:350
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:771
GenericPointer Append(const ValueType &token, Allocator *allocator=0) const
Append a token by value, and return a new Pointer.
Definition: pointer.h:319
GenericPointer(Allocator *allocator=0)
Default constructor.
Definition: pointer.h:104
ValueType & Set(ValueType &root, const Ch *value, typename ValueType::AllocatorType &allocator) const
Set a null-terminated string in a subtree.
Definition: pointer.h:742
friend void swap(GenericPointer &a, GenericPointer &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition: pointer.h:228
A document for parsing JSON text as DOM.
Definition: document.h:69
array
Definition: rapidjson.h:734
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:716
bool operator==(const GenericPointer &rhs) const
Equality operator.
Definition: pointer.h:364
bool Stringify(OutputStream &os) const
Stringify the pointer into string representation.
Definition: pointer.h:424
GenericPointer(const GenericPointer &rhs)
Copy constructor.
Definition: pointer.h:163
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:2796
ValueType & Set(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, ValueType &value) const
Set a value in a document, with move semantics.
Definition: pointer.h:765
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:540
GenericPointer(const std::basic_string< Ch > &source, Allocator *allocator=0)
Constructor that parses a string or URI fragment representation.
Definition: pointer.h:122
A token is the basic units of internal representation.
Definition: pointer.h:94
GenericPointer & Swap(GenericPointer &other) RAPIDJSON_NOEXCEPT
Swap the content of this pointer with an other.
Definition: pointer.h:205
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:662
const ValueType * Get(const ValueType &root, size_t *unresolvedTokenIndex=0) const
Query a const value in a const subtree.
Definition: pointer.h:636
SizeType index
A valid array index, if it is not equal to kPointerInvalidIndex.
Definition: pointer.h:97
bool Erase(ValueType &root) const
Erase a value in a subtree.
Definition: pointer.h:833
Reference to a constant string (not taking a copy)
Definition: document.h:346
Concept for allocating, resizing and freeing memory block.
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:66
Invalid percent encoding in URI fragment.
Definition: error.h:262
ValueType & Swap(ValueType &root, ValueType &value, typename ValueType::AllocatorType &allocator) const
Swap a value with a value in a subtree.
Definition: pointer.h:814
ValueType & GetWithDefault(ValueType &root, const ValueType &defaultValue, typename ValueType::AllocatorType &allocator) const
Query a value in a subtree with default value.
Definition: pointer.h:655
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:784
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:437