/home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-composable-kernel/checkouts/develop/include/rapidjson/pointer.h Source File

/home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-composable-kernel/checkouts/develop/include/rapidjson/pointer.h Source File#

Composable Kernel: /home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-composable-kernel/checkouts/develop/include/rapidjson/pointer.h Source File
pointer.h
Go to the documentation of this file.
1 // Tencent is pleased to support the open source community by making RapidJSON available.
2 //
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
4 //
5 // Licensed under the MIT License (the "License"); you may not use this file except
6 // in compliance with the License. You may obtain a copy of the License at
7 //
8 // http://opensource.org/licenses/MIT
9 //
10 // Unless required by applicable law or agreed to in writing, software distributed
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 // specific language governing permissions and limitations under the License.
14 
15 #ifndef RAPIDJSON_POINTER_H_
16 #define RAPIDJSON_POINTER_H_
17 
18 #include "document.h"
19 #include "uri.h"
20 #include "internal/itoa.h"
21 #include "error/error.h" // PointerParseErrorCode
22 
23 #ifdef __clang__
24 RAPIDJSON_DIAG_PUSH
25 RAPIDJSON_DIAG_OFF(switch-enum)
26 #elif defined(_MSC_VER)
27 RAPIDJSON_DIAG_PUSH
28 RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
29 #endif
30 
31 #if defined(RAPIDJSON_CPLUSPLUS) && RAPIDJSON_CPLUSPLUS >= 201703L
32 #define RAPIDJSON_IF_CONSTEXPR if constexpr
33 #else
34 #define RAPIDJSON_IF_CONSTEXPR if
35 #endif
36 
38 
39 static const SizeType kPointerInvalidIndex = ~SizeType(0);
40 
42 // GenericPointer
43 
45 
73 template <typename ValueType, typename Allocator = CrtAllocator>
75 public:
76  typedef typename ValueType::EncodingType EncodingType;
77  typedef typename ValueType::Ch Ch;
79 
80 
82 
94  struct Token {
95  const Ch* name;
98  };
99 
101 
102 
105 
107 
112  Parse(source, internal::StrLen(source));
113  }
114 
115 #if RAPIDJSON_HAS_STDSTRING
117 
123  Parse(source.c_str(), source.size());
124  }
125 #endif
126 
128 
135  Parse(source, length);
136  }
137 
139 
160  GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
161 
164  *this = rhs;
165  }
166 
169  *this = rhs;
170  }
171 
174  if (nameBuffer_) // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and tokens_ are not deallocated.
177  }
178 
181  if (this != &rhs) {
182  // Do not delete ownAllcator
183  if (nameBuffer_)
185 
186  tokenCount_ = rhs.tokenCount_;
189 
190  if (rhs.nameBuffer_)
191  CopyFromRaw(rhs); // Normally parsed tokens.
192  else {
193  tokens_ = rhs.tokens_; // User supplied const tokens.
194  nameBuffer_ = 0;
195  }
196  }
197  return *this;
198  }
199 
201 
205  GenericPointer& Swap(GenericPointer& other) RAPIDJSON_NOEXCEPT {
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_);
213  return *this;
214  }
215 
217 
228  friend inline void swap(GenericPointer& a, GenericPointer& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
229 
231 
233 
234 
236 
241  GenericPointer Append(const Token& token, Allocator* allocator = 0) const {
242  GenericPointer r;
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;
249  return r;
250  }
251 
253 
259  GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const {
260  Token token = { name, length, kPointerInvalidIndex };
261  return Append(token, allocator);
262  }
263 
265 
270  template <typename T>
271  RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >), (GenericPointer))
272  Append(T* name, Allocator* allocator = 0) const {
273  return Append(name, internal::StrLen(name), allocator);
274  }
275 
276 #if RAPIDJSON_HAS_STDSTRING
278 
283  GenericPointer Append(const std::basic_string<Ch>& name, Allocator* allocator = 0) const {
284  return Append(name.c_str(), static_cast<SizeType>(name.size()), allocator);
285  }
286 #endif
287 
289 
294  GenericPointer Append(SizeType index, Allocator* allocator = 0) const {
295  char buffer[21];
296  char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer);
297  SizeType length = static_cast<SizeType>(end - buffer);
298  buffer[length] = '\0';
299 
300  RAPIDJSON_IF_CONSTEXPR (sizeof(Ch) == 1) {
301  Token token = { reinterpret_cast<Ch*>(buffer), length, index };
302  return Append(token, allocator);
303  }
304  else {
305  Ch name[21];
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);
310  }
311  }
312 
314 
319  GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const {
320  if (token.IsString())
321  return Append(token.GetString(), token.GetStringLength(), allocator);
322  else {
323  RAPIDJSON_ASSERT(token.IsUint64());
324  RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0));
325  return Append(static_cast<SizeType>(token.GetUint64()), allocator);
326  }
327  }
328 
330 
331 
333  bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; }
334 
336  size_t GetParseErrorOffset() const { return parseErrorOffset_; }
337 
339  PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; }
340 
342 
344  Allocator& GetAllocator() { return *allocator_; }
345 
347 
348 
350  const Token* GetTokens() const { return tokens_; }
351 
353  size_t GetTokenCount() const { return tokenCount_; }
354 
356 
358 
359 
361 
364  bool operator==(const GenericPointer& rhs) const {
365  if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_)
366  return false;
367 
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))
372  {
373  return false;
374  }
375  }
376 
377  return true;
378  }
379 
381 
384  bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }
385 
387 
390  bool operator<(const GenericPointer& rhs) const {
391  if (!IsValid())
392  return false;
393  if (!rhs.IsValid())
394  return true;
395 
396  if (tokenCount_ != rhs.tokenCount_)
397  return tokenCount_ < rhs.tokenCount_;
398 
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;
402 
403  if (tokens_[i].length != rhs.tokens_[i].length)
404  return tokens_[i].length < rhs.tokens_[i].length;
405 
406  if (int cmp = std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length))
407  return cmp < 0;
408  }
409 
410  return false;
411  }
412 
414 
416 
417 
419 
423  template<typename OutputStream>
424  bool Stringify(OutputStream& os) const {
425  return Stringify<false, OutputStream>(os);
426  }
427 
429 
433  template<typename OutputStream>
434  bool StringifyUriFragment(OutputStream& os) const {
435  return Stringify<true, OutputStream>(os);
436  }
437 
439 
441 
442 
444 
458  ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const {
459  RAPIDJSON_ASSERT(IsValid());
460  ValueType* v = &root;
461  bool exist = true;
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]);
466  exist = false;
467  }
468  else {
469  if (t->index == kPointerInvalidIndex) { // must be object name
470  if (!v->IsObject())
471  v->SetObject(); // Change to Object
472  }
473  else { // object name or array index
474  if (!v->IsArray() && !v->IsObject())
475  v->SetArray(); // Change to Array
476  }
477 
478  if (v->IsArray()) {
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);
483  exist = false;
484  }
485  v = &((*v)[t->index]);
486  }
487  else {
488  typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
489  if (m == v->MemberEnd()) {
490  v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
491  m = v->MemberEnd();
492  v = &(--m)->value; // Assumes AddMember() appends at the end
493  exist = false;
494  }
495  else
496  v = &m->value;
497  }
498  }
499  }
500 
501  if (alreadyExist)
502  *alreadyExist = exist;
503 
504  return *v;
505  }
506 
508 
513  template <typename stackAllocator>
514  ValueType& Create(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, bool* alreadyExist = 0) const {
515  return Create(document, document.GetAllocator(), alreadyExist);
516  }
517 
519 
521 
522 
524  // For use with JSON pointers into JSON schema documents.
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);
544  RAPIDJSON_ASSERT(IsValid());
545  ValueType* v = &root;
546  for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
547  switch (v->GetType()) {
548  case kObjectType:
549  {
550  // See if we have an id, and if so resolve with the current base
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);
554  base = here;
555  }
556  m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
557  if (m == v->MemberEnd())
558  break;
559  v = &m->value;
560  }
561  continue;
562  case kArrayType:
563  if (t->index == kPointerInvalidIndex || t->index >= v->Size())
564  break;
565  v = &((*v)[t->index]);
566  continue;
567  default:
568  break;
569  }
570 
571  // Error: unresolved token
572  if (unresolvedTokenIndex)
573  *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
574  return UriType(allocator);
575  }
576  return base;
577  }
578 
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);
581  }
582 
583 
585 
586 
588 
601  ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const {
602  RAPIDJSON_ASSERT(IsValid());
603  ValueType* v = &root;
604  for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
605  switch (v->GetType()) {
606  case kObjectType:
607  {
608  typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
609  if (m == v->MemberEnd())
610  break;
611  v = &m->value;
612  }
613  continue;
614  case kArrayType:
615  if (t->index == kPointerInvalidIndex || t->index >= v->Size())
616  break;
617  v = &((*v)[t->index]);
618  continue;
619  default:
620  break;
621  }
622 
623  // Error: unresolved token
624  if (unresolvedTokenIndex)
625  *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
626  return 0;
627  }
628  return v;
629  }
630 
632 
636  const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const {
637  return Get(const_cast<ValueType&>(root), unresolvedTokenIndex);
638  }
639 
641 
643 
644 
646 
655  ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const {
656  bool alreadyExist;
657  ValueType& v = Create(root, allocator, &alreadyExist);
658  return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
659  }
660 
662  ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const {
663  bool alreadyExist;
664  ValueType& v = Create(root, allocator, &alreadyExist);
665  return alreadyExist ? v : v.SetString(defaultValue, allocator);
666  }
667 
668 #if RAPIDJSON_HAS_STDSTRING
670  ValueType& GetWithDefault(ValueType& root, const std::basic_string<Ch>& defaultValue, typename ValueType::AllocatorType& allocator) const {
671  bool alreadyExist;
672  ValueType& v = Create(root, allocator, &alreadyExist);
673  return alreadyExist ? v : v.SetString(defaultValue, allocator);
674  }
675 #endif
676 
678 
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);
685  }
686 
688  template <typename stackAllocator>
689  ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& defaultValue) const {
690  return GetWithDefault(document, defaultValue, document.GetAllocator());
691  }
692 
694  template <typename stackAllocator>
696  return GetWithDefault(document, defaultValue, document.GetAllocator());
697  }
698 
699 #if RAPIDJSON_HAS_STDSTRING
701  template <typename stackAllocator>
702  ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& defaultValue) const {
703  return GetWithDefault(document, defaultValue, document.GetAllocator());
704  }
705 #endif
706 
708 
711  template <typename T, typename stackAllocator>
712  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
714  return GetWithDefault(document, defaultValue, document.GetAllocator());
715  }
716 
718 
720 
721 
723 
732  ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
733  return Create(root, allocator) = value;
734  }
735 
737  ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const {
738  return Create(root, allocator).CopyFrom(value, allocator);
739  }
740 
742  ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const {
743  return Create(root, allocator) = ValueType(value, allocator).Move();
744  }
745 
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();
750  }
751 #endif
752 
754 
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();
761  }
762 
764  template <typename stackAllocator>
766  return Create(document) = value;
767  }
768 
770  template <typename stackAllocator>
772  return Create(document).CopyFrom(value, document.GetAllocator());
773  }
774 
776  template <typename stackAllocator>
778  return Create(document) = ValueType(value, document.GetAllocator()).Move();
779  }
780 
781 #if RAPIDJSON_HAS_STDSTRING
783  template <typename stackAllocator>
784  ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& value) const {
785  return Create(document) = ValueType(value, document.GetAllocator()).Move();
786  }
787 #endif
788 
790 
793  template <typename T, typename stackAllocator>
794  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
796  return Create(document) = value;
797  }
798 
800 
802 
803 
805 
814  ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
815  return Create(root, allocator).Swap(value);
816  }
817 
819  template <typename stackAllocator>
821  return Create(document).Swap(value);
822  }
823 
825 
827 
833  bool Erase(ValueType& root) const {
834  RAPIDJSON_ASSERT(IsValid());
835  if (tokenCount_ == 0) // Cannot erase the root
836  return false;
837 
838  ValueType* v = &root;
839  const Token* last = tokens_ + (tokenCount_ - 1);
840  for (const Token *t = tokens_; t != last; ++t) {
841  switch (v->GetType()) {
842  case kObjectType:
843  {
844  typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
845  if (m == v->MemberEnd())
846  return false;
847  v = &m->value;
848  }
849  break;
850  case kArrayType:
851  if (t->index == kPointerInvalidIndex || t->index >= v->Size())
852  return false;
853  v = &((*v)[t->index]);
854  break;
855  default:
856  return false;
857  }
858  }
859 
860  switch (v->GetType()) {
861  case kObjectType:
862  return v->EraseMember(GenericStringRef<Ch>(last->name, last->length));
863  case kArrayType:
864  if (last->index == kPointerInvalidIndex || last->index >= v->Size())
865  return false;
866  v->Erase(v->Begin() + last->index);
867  return true;
868  default:
869  return false;
870  }
871  }
872 
873 private:
875 
881  Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0) {
882  if (!allocator_) // allocator is independently owned.
884 
885  size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens
886  for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)
887  nameBufferSize += t->length;
888 
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));
894  }
895  if (nameBufferSize > 0) {
896  std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
897  }
898 
899  // The names of each token point to a string in the nameBuffer_. The
900  // previous memcpy copied over string pointers into the rhs.nameBuffer_,
901  // but they should point to the strings in the new nameBuffer_.
902  for (size_t i = 0; i < rhs.tokenCount_; ++i) {
903  // The offset between the string address and the name buffer should
904  // still be constant, so we can just get this offset and set each new
905  // token name according the new buffer start + the known offset.
906  std::ptrdiff_t name_offset = rhs.tokens_[i].name - rhs.nameBuffer_;
907  tokens_[i].name = nameBuffer_ + name_offset;
908  }
909 
910  return nameBuffer_ + nameBufferSize;
911  }
912 
914 
918  bool NeedPercentEncode(Ch c) const {
919  return !((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~');
920  }
921 
923 #ifndef __clang__ // -Wdocumentation
929 #endif
930  void Parse(const Ch* source, size_t length) {
931  RAPIDJSON_ASSERT(source != NULL);
934 
935  // Create own allocator if user did not supply.
936  if (!allocator_)
938 
939  // Count number of '/' as tokenCount
940  tokenCount_ = 0;
941  for (const Ch* s = source; s != source + length; s++)
942  if (*s == '/')
943  tokenCount_++;
944 
945  Token* token = tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch)));
946  Ch* name = nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
947  size_t i = 0;
948 
949  // Detect if it is a URI fragment
950  bool uriFragment = false;
951  if (source[i] == '#') {
952  uriFragment = true;
953  i++;
954  }
955 
956  if (i != length && source[i] != '/') {
958  goto error;
959  }
960 
961  while (i < length) {
962  RAPIDJSON_ASSERT(source[i] == '/');
963  i++; // consumes '/'
964 
965  token->name = name;
966  bool isNumber = true;
967 
968  while (i < length && source[i] != '/') {
969  Ch c = source[i];
970  if (uriFragment) {
971  // Decoding percent-encoding for URI fragment
972  if (c == '%') {
973  PercentDecodeStream is(&source[i], source + length);
975  Ch* begin = os.PutBegin();
976  if (!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid()) {
978  goto error;
979  }
980  size_t len = os.PutEnd(begin);
981  i += is.Tell() - 1;
982  if (len == 1)
983  c = *name;
984  else {
985  name += len;
986  isNumber = false;
987  i++;
988  continue;
989  }
990  }
991  else if (NeedPercentEncode(c)) {
993  goto error;
994  }
995  }
996 
997  i++;
998 
999  // Escaping "~0" -> '~', "~1" -> '/'
1000  if (c == '~') {
1001  if (i < length) {
1002  c = source[i];
1003  if (c == '0') c = '~';
1004  else if (c == '1') c = '/';
1005  else {
1007  goto error;
1008  }
1009  i++;
1010  }
1011  else {
1013  goto error;
1014  }
1015  }
1016 
1017  // First check for index: all of characters are digit
1018  if (c < '0' || c > '9')
1019  isNumber = false;
1020 
1021  *name++ = c;
1022  }
1023  token->length = static_cast<SizeType>(name - token->name);
1024  if (token->length == 0)
1025  isNumber = false;
1026  *name++ = '\0'; // Null terminator
1027 
1028  // Second check for index: more than one digit cannot have leading zero
1029  if (isNumber && token->length > 1 && token->name[0] == '0')
1030  isNumber = false;
1031 
1032  // String to SizeType conversion
1033  SizeType n = 0;
1034  if (isNumber) {
1035  for (size_t j = 0; j < token->length; j++) {
1036  SizeType m = n * 10 + static_cast<SizeType>(token->name[j] - '0');
1037  if (m < n) { // overflow detection
1038  isNumber = false;
1039  break;
1040  }
1041  n = m;
1042  }
1043  }
1044 
1045  token->index = isNumber ? n : kPointerInvalidIndex;
1046  token++;
1047  }
1048 
1049  RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer
1051  return;
1052 
1053  error:
1055  nameBuffer_ = 0;
1056  tokens_ = 0;
1057  tokenCount_ = 0;
1058  parseErrorOffset_ = i;
1059  return;
1060  }
1061 
1063 
1068  template<bool uriFragment, typename OutputStream>
1069  bool Stringify(OutputStream& os) const {
1070  RAPIDJSON_ASSERT(IsValid());
1071 
1072  if (uriFragment)
1073  os.Put('#');
1074 
1075  for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
1076  os.Put('/');
1077  for (size_t j = 0; j < t->length; j++) {
1078  Ch c = t->name[j];
1079  if (c == '~') {
1080  os.Put('~');
1081  os.Put('0');
1082  }
1083  else if (c == '/') {
1084  os.Put('~');
1085  os.Put('1');
1086  }
1087  else if (uriFragment && NeedPercentEncode(c)) {
1088  // Transcode to UTF8 sequence
1090  PercentEncodeStream<OutputStream> target(os);
1091  if (!Transcoder<EncodingType, UTF8<> >().Validate(source, target))
1092  return false;
1093  j += source.Tell() - 1;
1094  }
1095  else
1096  os.Put(c);
1097  }
1098  }
1099  return true;
1100  }
1101 
1103 
1108  class PercentDecodeStream {
1109  public:
1110  typedef typename ValueType::Ch Ch;
1111 
1113 
1117  PercentDecodeStream(const Ch* source, const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {}
1118 
1119  Ch Take() {
1120  if (*src_ != '%' || src_ + 3 > end_) { // %XY triplet
1121  valid_ = false;
1122  return 0;
1123  }
1124  src_++;
1125  Ch c = 0;
1126  for (int j = 0; j < 2; j++) {
1127  c = static_cast<Ch>(c << 4);
1128  Ch h = *src_;
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);
1132  else {
1133  valid_ = false;
1134  return 0;
1135  }
1136  src_++;
1137  }
1138  return c;
1139  }
1140 
1141  size_t Tell() const { return static_cast<size_t>(src_ - head_); }
1142  bool IsValid() const { return valid_; }
1143 
1144  private:
1145  const Ch* src_;
1146  const Ch* head_;
1147  const Ch* end_;
1148  bool valid_;
1149  };
1150 
1152  template <typename OutputStream>
1154  public:
1155  PercentEncodeStream(OutputStream& os) : os_(os) {}
1156  void Put(char c) { // UTF-8 must be byte
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' };
1159  os_.Put('%');
1160  os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u >> 4]));
1161  os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u & 15]));
1162  }
1163  private:
1164  OutputStream& os_;
1165  };
1166 
1171  size_t tokenCount_;
1174 };
1175 
1178 
1180 
1181 
1183 
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);
1187 }
1188 
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);
1192 }
1193 
1194 // No allocator parameter
1195 
1196 template <typename DocumentType>
1197 typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer) {
1198  return pointer.Create(document);
1199 }
1200 
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);
1204 }
1205 
1207 
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);
1211 }
1212 
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);
1216 }
1217 
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);
1221 }
1222 
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);
1226 }
1227 
1229 
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);
1233 }
1234 
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);
1238 }
1239 
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);
1244 }
1245 #endif
1246 
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);
1251 }
1252 
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);
1256 }
1257 
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);
1261 }
1262 
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);
1267 }
1268 #endif
1269 
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);
1274 }
1275 
1276 // No allocator parameter
1277 
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);
1281 }
1282 
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);
1286 }
1287 
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);
1292 }
1293 #endif
1294 
1295 template <typename DocumentType, typename T2>
1296 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1298  return pointer.GetWithDefault(document, defaultValue);
1299 }
1300 
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);
1304 }
1305 
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);
1309 }
1310 
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);
1315 }
1316 #endif
1317 
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);
1322 }
1323 
1325 
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);
1329 }
1330 
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);
1334 }
1335 
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);
1339 }
1340 
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);
1345 }
1346 #endif
1347 
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);
1352 }
1353 
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);
1357 }
1358 
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);
1362 }
1363 
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);
1367 }
1368 
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);
1373 }
1374 #endif
1375 
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);
1380 }
1381 
1382 // No allocator parameter
1383 
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);
1387 }
1388 
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);
1392 }
1393 
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);
1397 }
1398 
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);
1403 }
1404 #endif
1405 
1406 template <typename DocumentType, typename T2>
1407 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1409  return pointer.Set(document, value);
1410 }
1411 
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);
1415 }
1416 
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);
1420 }
1421 
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);
1425 }
1426 
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);
1431 }
1432 #endif
1433 
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);
1438 }
1439 
1441 
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);
1445 }
1446 
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);
1450 }
1451 
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);
1455 }
1456 
1457 template <typename DocumentType, typename CharType, size_t N>
1458 typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
1460 }
1461 
1463 
1464 template <typename T>
1466  return pointer.Erase(root);
1467 }
1468 
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);
1472 }
1473 
1475 
1477 
1478 #if defined(__clang__) || defined(_MSC_VER)
1479 RAPIDJSON_DIAG_POP
1480 #endif
1481 
1482 #endif // RAPIDJSON_POINTER_H_
void Free(A &a, T *p, size_t n=1)
Definition: allocators.h:448
A document for parsing JSON text as DOM.
Definition: document.h:2500
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:2796
A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence.
Definition: pointer.h:1153
PercentEncodeStream(OutputStream &os)
Definition: pointer.h:1155
void Put(char c)
Definition: pointer.h:1156
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition: pointer.h:74
GenericPointer & operator=(const GenericPointer &rhs)
Assignment operator.
Definition: pointer.h:180
friend void swap(GenericPointer &a, GenericPointer &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition: pointer.h:228
Ch * nameBuffer_
A buffer containing all names in tokens.
Definition: pointer.h:1169
Allocator * allocator_
The current allocator. It is either user-supplied or equal to ownAllocator_.
Definition: pointer.h:1167
GenericPointer(const GenericPointer &rhs, Allocator *allocator)
Copy constructor.
Definition: pointer.h:168
GenericPointer(const Ch *source, Allocator *allocator=0)
Constructor that parses a string or URI fragment representation.
Definition: pointer.h:111
ValueType::EncodingType EncodingType
Encoding type from Value.
Definition: pointer.h:76
GenericPointer(const Token *tokens, size_t tokenCount)
Constructor with user-supplied tokens.
Definition: pointer.h:160
GenericPointer(Allocator *allocator=0)
Default constructor.
Definition: pointer.h:104
GenericPointer & Swap(GenericPointer &other) RAPIDJSON_NOEXCEPT
Swap the content of this pointer with an other.
Definition: pointer.h:205
size_t tokenCount_
Number of tokens in tokens_.
Definition: pointer.h:1171
GenericPointer(const GenericPointer &rhs)
Copy constructor.
Definition: pointer.h:163
PointerParseErrorCode parseErrorCode_
Parsing error code.
Definition: pointer.h:1173
Token * tokens_
A list of tokens.
Definition: pointer.h:1170
Allocator * ownAllocator_
Allocator owned by this Pointer.
Definition: pointer.h:1168
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
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
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
Definition: pointer.h:241
RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr< internal::IsSame< typename internal::RemoveConst< T >::Type, Ch > >),(GenericPointer)) Append(T *name
Append a name token without length, and return a new Pointer.
ValueType::Ch Ch
Character type from Value.
Definition: pointer.h:77
GenericUri< ValueType, Allocator > UriType
Definition: pointer.h:78
~GenericPointer()
Destructor.
Definition: pointer.h:173
size_t parseErrorOffset_
Offset in code unit when parsing fail.
Definition: pointer.h:1172
Allocator * allocator
The current allocator. It is either user-supplied or equal to ownAllocator_.
Definition: pointer.h:272
Definition: uri.h:33
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:668
Concept for allocating, resizing and freeing memory block.
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:437
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:121
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:124
PointerParseErrorCode
Error code of JSON pointer parsing.
Definition: error.h:257
@ kPointerParseErrorInvalidEscape
Invalid escape.
Definition: error.h:261
@ kPointerParseErrorTokenMustBeginWithSolidus
A token must begin with a '/'.
Definition: error.h:260
@ kPointerParseErrorNone
The parse is successful.
Definition: error.h:258
@ kPointerParseErrorCharacterMustPercentEncode
A character must percent encoded in URI fragment.
Definition: error.h:263
@ kPointerParseErrorInvalidPercentEncoding
Invalid percent encoding in URI fragment.
Definition: error.h:262
constexpr CK_TILE_HOST_DEVICE bool operator!=(const array< T, Size > &a, const array< T, Size > &b)
Definition: array.hpp:280
__host__ constexpr __device__ bool operator==(Sequence< Xs... >, Sequence< Ys... >)
Definition: sequence.hpp:649
void Swap(T &a, T &b) RAPIDJSON_NOEXCEPT
Custom swap() to avoid dependency on C++ <algorithm> header.
Definition: swap.h:33
char * u32toa(uint32_t value, char *buffer)
Definition: itoa.h:39
SizeType StrLen(const Ch *s)
Custom strlen() which works on different character types.
Definition: strfunc.h:31
char * u64toa(uint64_t value, char *buffer)
Definition: itoa.h:126
T::ValueType * GetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, size_t *unresolvedTokenIndex=0)
Definition: pointer.h:1209
T::ValueType & GetValueByPointerWithDefault(T &root, const GenericPointer< typename T::ValueType > &pointer, const typename T::ValueType &defaultValue, typename T::AllocatorType &a)
Definition: pointer.h:1231
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1350
const GenericPointer< typename T::ValueType > T2 defaultValue
Definition: pointer.h:1249
#define RAPIDJSON_IF_CONSTEXPR
Definition: pointer.h:34
bool EraseValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer)
Definition: pointer.h:1465
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T2 >, internal::IsGenericValue< T2 > >),(typename T::ValueType &)) GetValueByPointerWithDefault(T &root
GenericPointer< Value > Pointer
GenericPointer for Value (UTF-8, default allocator).
Definition: pointer.h:1177
T::ValueType & SetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition: pointer.h:1327
const GenericPointer< typename T::ValueType > & pointer
Definition: pointer.h:1249
T::ValueType & SwapValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition: pointer.h:1443
const CharType(& source)[N]
Definition: pointer.h:1272
T::ValueType & CreateValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::AllocatorType &a)
Definition: pointer.h:1185
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1249
Type
Type of JSON value.
Definition: rapidjson.h:729
@ kObjectType
object
Definition: rapidjson.h:733
@ kArrayType
array
Definition: rapidjson.h:734
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:716
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:415
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition: rapidjson.h:712
A read-write string stream.
Definition: stream.h:188
A token is the basic units of internal representation.
Definition: pointer.h:94
SizeType index
A valid array index, if it is not equal to kPointerInvalidIndex.
Definition: pointer.h:97
SizeType length
Length of the name.
Definition: pointer.h:96
const Ch * name
Name of the token. It has null character at the end but it can contain null character.
Definition: pointer.h:95
Reference to a constant string (not taking a copy)
Definition: document.h:346
Read-only string stream.
Definition: stream.h:154
Encoding conversion.
Definition: encodings.h:658
UTF-8 encoding.
Definition: encodings.h:96
Definition: document.h:509