/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 =
40  ~SizeType(0);
41 
43 // GenericPointer
44 
46 
74 template <typename ValueType, typename Allocator = CrtAllocator>
76 {
77  public:
78  typedef typename ValueType::EncodingType EncodingType;
79  typedef typename ValueType::Ch Ch;
81 
83 
95  struct Token
96  {
97  const Ch* name;
101  };
102 
104 
105 
109  ownAllocator_(),
110  nameBuffer_(),
111  tokens_(),
112  tokenCount_(),
115  {
116  }
117 
119 
124  explicit GenericPointer(const Ch* source, Allocator* allocator = 0)
126  ownAllocator_(),
127  nameBuffer_(),
128  tokens_(),
129  tokenCount_(),
132  {
133  Parse(source, internal::StrLen(source));
134  }
135 
136 #if RAPIDJSON_HAS_STDSTRING
138 
144  explicit GenericPointer(const std::basic_string<Ch>& source, Allocator* allocator = 0)
146  ownAllocator_(),
147  nameBuffer_(),
148  tokens_(),
149  tokenCount_(),
152  {
153  Parse(source.c_str(), source.size());
154  }
155 #endif
156 
159 
165  GenericPointer(const Ch* source, size_t length, Allocator* allocator = 0)
167  ownAllocator_(),
168  nameBuffer_(),
169  tokens_(),
170  tokenCount_(),
173  {
174  Parse(source, length);
175  }
176 
178 
199  GenericPointer(const Token* tokens, size_t tokenCount)
200  : allocator_(),
201  ownAllocator_(),
202  nameBuffer_(),
203  tokens_(const_cast<Token*>(tokens)),
204  tokenCount_(tokenCount),
207  {
208  }
209 
212  : allocator_(),
213  ownAllocator_(),
214  nameBuffer_(),
215  tokens_(),
216  tokenCount_(),
219  {
220  *this = rhs;
221  }
222 
226  ownAllocator_(),
227  nameBuffer_(),
228  tokens_(),
229  tokenCount_(),
232  {
233  *this = rhs;
234  }
235 
238  {
239  if(nameBuffer_) // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and
240  // tokens_ are not deallocated.
243  }
244 
247  {
248  if(this != &rhs)
249  {
250  // Do not delete ownAllcator
251  if(nameBuffer_)
253 
254  tokenCount_ = rhs.tokenCount_;
257 
258  if(rhs.nameBuffer_)
259  CopyFromRaw(rhs); // Normally parsed tokens.
260  else
261  {
262  tokens_ = rhs.tokens_; // User supplied const tokens.
263  nameBuffer_ = 0;
264  }
265  }
266  return *this;
267  }
268 
270 
274  GenericPointer& Swap(GenericPointer& other) RAPIDJSON_NOEXCEPT
275  {
276  internal::Swap(allocator_, other.allocator_);
277  internal::Swap(ownAllocator_, other.ownAllocator_);
278  internal::Swap(nameBuffer_, other.nameBuffer_);
279  internal::Swap(tokens_, other.tokens_);
280  internal::Swap(tokenCount_, other.tokenCount_);
281  internal::Swap(parseErrorOffset_, other.parseErrorOffset_);
282  internal::Swap(parseErrorCode_, other.parseErrorCode_);
283  return *this;
284  }
285 
287 
296  friend inline void swap(GenericPointer& a, GenericPointer& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
297 
299 
301 
302 
304 
309  GenericPointer Append(const Token& token, Allocator* allocator = 0) const
310  {
311  GenericPointer r;
312  r.allocator_ = allocator;
313  Ch* p = r.CopyFromRaw(*this, 1, token.length + 1);
314  std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch));
315  r.tokens_[tokenCount_].name = p;
316  r.tokens_[tokenCount_].length = token.length;
317  r.tokens_[tokenCount_].index = token.index;
318  return r;
319  }
320 
322 
328  GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const
329  {
330  Token token = {name, length, kPointerInvalidIndex};
331  return Append(token, allocator);
332  }
333 
335 
340  template <typename T>
342  (internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch>>),
343  (GenericPointer))
344  Append(T* name, Allocator* allocator = 0) const
345  {
346  return Append(name, internal::StrLen(name), allocator);
347  }
348 
349 #if RAPIDJSON_HAS_STDSTRING
351 
356  GenericPointer Append(const std::basic_string<Ch>& name, Allocator* allocator = 0) const
357  {
358  return Append(name.c_str(), static_cast<SizeType>(name.size()), allocator);
359  }
360 #endif
361 
363 
369  {
370  char buffer[21];
371  char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer)
372  : internal::u64toa(index, buffer);
373  SizeType length = static_cast<SizeType>(end - buffer);
374  buffer[length] = '\0';
375 
376  RAPIDJSON_IF_CONSTEXPR(sizeof(Ch) == 1)
377  {
378  Token token = {reinterpret_cast<Ch*>(buffer), length, index};
379  return Append(token, allocator);
380  }
381  else
382  {
383  Ch name[21];
384  for(size_t i = 0; i <= length; i++)
385  name[i] = static_cast<Ch>(buffer[i]);
386  Token token = {name, length, index};
387  return Append(token, allocator);
388  }
389  }
390 
392 
397  GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const
398  {
399  if(token.IsString())
400  return Append(token.GetString(), token.GetStringLength(), allocator);
401  else
402  {
403  RAPIDJSON_ASSERT(token.IsUint64());
404  RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0));
405  return Append(static_cast<SizeType>(token.GetUint64()), allocator);
406  }
407  }
408 
410 
411 
413  bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; }
414 
416  size_t GetParseErrorOffset() const { return parseErrorOffset_; }
417 
419  PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; }
420 
422 
424  Allocator& GetAllocator() { return *allocator_; }
425 
427 
428 
430  const Token* GetTokens() const { return tokens_; }
431 
433  size_t GetTokenCount() const { return tokenCount_; }
434 
436 
438 
439 
441 
444  bool operator==(const GenericPointer& rhs) const
445  {
446  if(!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_)
447  return false;
448 
449  for(size_t i = 0; i < tokenCount_; i++)
450  {
451  if(tokens_[i].index != rhs.tokens_[i].index ||
452  tokens_[i].length != rhs.tokens_[i].length ||
453  (tokens_[i].length != 0 &&
454  std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length) !=
455  0))
456  {
457  return false;
458  }
459  }
460 
461  return true;
462  }
463 
465 
468  bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }
469 
471 
474  bool operator<(const GenericPointer& rhs) const
475  {
476  if(!IsValid())
477  return false;
478  if(!rhs.IsValid())
479  return true;
480 
481  if(tokenCount_ != rhs.tokenCount_)
482  return tokenCount_ < rhs.tokenCount_;
483 
484  for(size_t i = 0; i < tokenCount_; i++)
485  {
486  if(tokens_[i].index != rhs.tokens_[i].index)
487  return tokens_[i].index < rhs.tokens_[i].index;
488 
489  if(tokens_[i].length != rhs.tokens_[i].length)
490  return tokens_[i].length < rhs.tokens_[i].length;
491 
492  if(int cmp = std::memcmp(
493  tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length))
494  return cmp < 0;
495  }
496 
497  return false;
498  }
499 
501 
503 
504 
506 
510  template <typename OutputStream>
511  bool Stringify(OutputStream& os) const
512  {
513  return Stringify<false, OutputStream>(os);
514  }
515 
517 
521  template <typename OutputStream>
522  bool StringifyUriFragment(OutputStream& os) const
523  {
524  return Stringify<true, OutputStream>(os);
525  }
526 
528 
530 
531 
533 
548  ValueType& Create(ValueType& root,
549  typename ValueType::AllocatorType& allocator,
550  bool* alreadyExist = 0) const
551  {
552  RAPIDJSON_ASSERT(IsValid());
553  ValueType* v = &root;
554  bool exist = true;
555  for(const Token* t = tokens_; t != tokens_ + tokenCount_; ++t)
556  {
557  if(v->IsArray() && t->name[0] == '-' && t->length == 1)
558  {
559  v->PushBack(ValueType().Move(), allocator);
560  v = &((*v)[v->Size() - 1]);
561  exist = false;
562  }
563  else
564  {
565  if(t->index == kPointerInvalidIndex)
566  { // must be object name
567  if(!v->IsObject())
568  v->SetObject(); // Change to Object
569  }
570  else
571  { // object name or array index
572  if(!v->IsArray() && !v->IsObject())
573  v->SetArray(); // Change to Array
574  }
575 
576  if(v->IsArray())
577  {
578  if(t->index >= v->Size())
579  {
580  v->Reserve(t->index + 1, allocator);
581  while(t->index >= v->Size())
582  v->PushBack(ValueType().Move(), allocator);
583  exist = false;
584  }
585  v = &((*v)[t->index]);
586  }
587  else
588  {
589  typename ValueType::MemberIterator m = v->FindMember(
590  GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
591  if(m == v->MemberEnd())
592  {
593  v->AddMember(ValueType(t->name, t->length, allocator).Move(),
594  ValueType().Move(),
595  allocator);
596  m = v->MemberEnd();
597  v = &(--m)->value; // Assumes AddMember() appends at the end
598  exist = false;
599  }
600  else
601  v = &m->value;
602  }
603  }
604  }
605 
606  if(alreadyExist)
607  *alreadyExist = exist;
608 
609  return *v;
610  }
611 
613 
618  template <typename stackAllocator>
619  ValueType& Create(
621  bool* alreadyExist = 0) const
622  {
623  return Create(document, document.GetAllocator(), alreadyExist);
624  }
625 
627 
629 
630 
632  // For use with JSON pointers into JSON schema documents.
648  UriType GetUri(ValueType& root,
649  const UriType& rootUri,
650  size_t* unresolvedTokenIndex = 0,
651  Allocator* allocator = 0) const
652  {
653  static const Ch kIdString[] = {'i', 'd', '\0'};
654  static const ValueType kIdValue(kIdString, 2);
655  UriType base = UriType(rootUri, allocator);
656  RAPIDJSON_ASSERT(IsValid());
657  ValueType* v = &root;
658  for(const Token* t = tokens_; t != tokens_ + tokenCount_; ++t)
659  {
660  switch(v->GetType())
661  {
662  case kObjectType: {
663  // See if we have an id, and if so resolve with the current base
664  typename ValueType::MemberIterator m = v->FindMember(kIdValue);
665  if(m != v->MemberEnd() && (m->value).IsString())
666  {
667  UriType here = UriType(m->value, allocator).Resolve(base, allocator);
668  base = here;
669  }
670  m = v->FindMember(
671  GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
672  if(m == v->MemberEnd())
673  break;
674  v = &m->value;
675  }
676  continue;
677  case kArrayType:
678  if(t->index == kPointerInvalidIndex || t->index >= v->Size())
679  break;
680  v = &((*v)[t->index]);
681  continue;
682  default: break;
683  }
684 
685  // Error: unresolved token
686  if(unresolvedTokenIndex)
687  *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
688  return UriType(allocator);
689  }
690  return base;
691  }
692 
693  UriType GetUri(const ValueType& root,
694  const UriType& rootUri,
695  size_t* unresolvedTokenIndex = 0,
696  Allocator* allocator = 0) const
697  {
698  return GetUri(const_cast<ValueType&>(root), rootUri, unresolvedTokenIndex, allocator);
699  }
700 
702 
703 
705 
719  ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const
720  {
721  RAPIDJSON_ASSERT(IsValid());
722  ValueType* v = &root;
723  for(const Token* t = tokens_; t != tokens_ + tokenCount_; ++t)
724  {
725  switch(v->GetType())
726  {
727  case kObjectType: {
728  typename ValueType::MemberIterator m = v->FindMember(
729  GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
730  if(m == v->MemberEnd())
731  break;
732  v = &m->value;
733  }
734  continue;
735  case kArrayType:
736  if(t->index == kPointerInvalidIndex || t->index >= v->Size())
737  break;
738  v = &((*v)[t->index]);
739  continue;
740  default: break;
741  }
742 
743  // Error: unresolved token
744  if(unresolvedTokenIndex)
745  *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
746  return 0;
747  }
748  return v;
749  }
750 
752 
756  const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const
757  {
758  return Get(const_cast<ValueType&>(root), unresolvedTokenIndex);
759  }
760 
762 
764 
765 
767 
776  ValueType& GetWithDefault(ValueType& root,
777  const ValueType& defaultValue,
778  typename ValueType::AllocatorType& allocator) const
779  {
780  bool alreadyExist;
781  ValueType& v = Create(root, allocator, &alreadyExist);
782  return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
783  }
784 
786  ValueType& GetWithDefault(ValueType& root,
787  const Ch* defaultValue,
788  typename ValueType::AllocatorType& allocator) const
789  {
790  bool alreadyExist;
791  ValueType& v = Create(root, allocator, &alreadyExist);
792  return alreadyExist ? v : v.SetString(defaultValue, allocator);
793  }
794 
795 #if RAPIDJSON_HAS_STDSTRING
797  ValueType& GetWithDefault(ValueType& root,
798  const std::basic_string<Ch>& defaultValue,
799  typename ValueType::AllocatorType& allocator) const
800  {
801  bool alreadyExist;
802  ValueType& v = Create(root, allocator, &alreadyExist);
803  return alreadyExist ? v : v.SetString(defaultValue, allocator);
804  }
805 #endif
806 
808 
811  template <typename T>
813  (internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>), (ValueType&))
814  GetWithDefault(ValueType& root,
815  T defaultValue,
816  typename ValueType::AllocatorType& allocator) const
817  {
818  return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);
819  }
820 
822  template <typename stackAllocator>
823  ValueType& GetWithDefault(
825  const ValueType& defaultValue) const
826  {
827  return GetWithDefault(document, defaultValue, document.GetAllocator());
828  }
829 
831  template <typename stackAllocator>
832  ValueType& GetWithDefault(
834  const Ch* defaultValue) const
835  {
836  return GetWithDefault(document, defaultValue, document.GetAllocator());
837  }
838 
839 #if RAPIDJSON_HAS_STDSTRING
841  template <typename stackAllocator>
842  ValueType& GetWithDefault(
844  const std::basic_string<Ch>& defaultValue) const
845  {
846  return GetWithDefault(document, defaultValue, document.GetAllocator());
847  }
848 #endif
849 
851 
854  template <typename T, typename stackAllocator>
856  (internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>), (ValueType&))
857  GetWithDefault(
859  T defaultValue) const
860  {
861  return GetWithDefault(document, defaultValue, document.GetAllocator());
862  }
863 
865 
867 
868 
870 
878  ValueType&
879  Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const
880  {
881  return Create(root, allocator) = value;
882  }
883 
885  ValueType&
886  Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const
887  {
888  return Create(root, allocator).CopyFrom(value, allocator);
889  }
890 
892  ValueType&
893  Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const
894  {
895  return Create(root, allocator) = ValueType(value, allocator).Move();
896  }
897 
898 #if RAPIDJSON_HAS_STDSTRING
900  ValueType& Set(ValueType& root,
901  const std::basic_string<Ch>& value,
902  typename ValueType::AllocatorType& allocator) const
903  {
904  return Create(root, allocator) = ValueType(value, allocator).Move();
905  }
906 #endif
907 
909 
912  template <typename T>
914  (internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>), (ValueType&))
915  Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const
916  {
917  return Create(root, allocator) = ValueType(value).Move();
918  }
919 
921  template <typename stackAllocator>
922  ValueType&
924  ValueType& value) const
925  {
926  return Create(document) = value;
927  }
928 
930  template <typename stackAllocator>
931  ValueType&
933  const ValueType& value) const
934  {
935  return Create(document).CopyFrom(value, document.GetAllocator());
936  }
937 
939  template <typename stackAllocator>
940  ValueType&
942  const Ch* value) const
943  {
944  return Create(document) = ValueType(value, document.GetAllocator()).Move();
945  }
946 
947 #if RAPIDJSON_HAS_STDSTRING
949  template <typename stackAllocator>
950  ValueType&
952  const std::basic_string<Ch>& value) const
953  {
954  return Create(document) = ValueType(value, document.GetAllocator()).Move();
955  }
956 #endif
957 
959 
962  template <typename T, typename stackAllocator>
964  (internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>), (ValueType&))
966  T value) const
967  {
968  return Create(document) = value;
969  }
970 
972 
974 
975 
977 
985  ValueType&
986  Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const
987  {
988  return Create(root, allocator).Swap(value);
989  }
990 
992  template <typename stackAllocator>
993  ValueType&
995  ValueType& value) const
996  {
997  return Create(document).Swap(value);
998  }
999 
1001 
1003 
1010  bool Erase(ValueType& root) const
1011  {
1012  RAPIDJSON_ASSERT(IsValid());
1013  if(tokenCount_ == 0) // Cannot erase the root
1014  return false;
1015 
1016  ValueType* v = &root;
1017  const Token* last = tokens_ + (tokenCount_ - 1);
1018  for(const Token* t = tokens_; t != last; ++t)
1019  {
1020  switch(v->GetType())
1021  {
1022  case kObjectType: {
1023  typename ValueType::MemberIterator m = v->FindMember(
1024  GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
1025  if(m == v->MemberEnd())
1026  return false;
1027  v = &m->value;
1028  }
1029  break;
1030  case kArrayType:
1031  if(t->index == kPointerInvalidIndex || t->index >= v->Size())
1032  return false;
1033  v = &((*v)[t->index]);
1034  break;
1035  default: return false;
1036  }
1037  }
1038 
1039  switch(v->GetType())
1040  {
1041  case kObjectType: return v->EraseMember(GenericStringRef<Ch>(last->name, last->length));
1042  case kArrayType:
1043  if(last->index == kPointerInvalidIndex || last->index >= v->Size())
1044  return false;
1045  v->Erase(v->Begin() + last->index);
1046  return true;
1047  default: return false;
1048  }
1049  }
1050 
1051  private:
1053 
1059  Ch*
1060  CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0)
1061  {
1062  if(!allocator_) // allocator is independently owned.
1064 
1065  size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens
1066  for(Token* t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)
1067  nameBufferSize += t->length;
1068 
1069  tokenCount_ = rhs.tokenCount_ + extraToken;
1070  tokens_ = static_cast<Token*>(allocator_->Malloc(
1071  tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch)));
1072  nameBuffer_ = reinterpret_cast<Ch*>(tokens_ + tokenCount_);
1073  if(rhs.tokenCount_ > 0)
1074  {
1075  std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token));
1076  }
1077  if(nameBufferSize > 0)
1078  {
1079  std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
1080  }
1081 
1082  // The names of each token point to a string in the nameBuffer_. The
1083  // previous memcpy copied over string pointers into the rhs.nameBuffer_,
1084  // but they should point to the strings in the new nameBuffer_.
1085  for(size_t i = 0; i < rhs.tokenCount_; ++i)
1086  {
1087  // The offset between the string address and the name buffer should
1088  // still be constant, so we can just get this offset and set each new
1089  // token name according the new buffer start + the known offset.
1090  std::ptrdiff_t name_offset = rhs.tokens_[i].name - rhs.nameBuffer_;
1091  tokens_[i].name = nameBuffer_ + name_offset;
1092  }
1093 
1094  return nameBuffer_ + nameBufferSize;
1095  }
1096 
1098 
1102  bool NeedPercentEncode(Ch c) const
1103  {
1104  return !((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
1105  c == '-' || c == '.' || c == '_' || c == '~');
1106  }
1107 
1109 #ifndef __clang__ // -Wdocumentation
1115 #endif
1116  void Parse(const Ch* source, size_t length)
1117  {
1118  RAPIDJSON_ASSERT(source != NULL);
1120  RAPIDJSON_ASSERT(tokens_ == 0);
1121 
1122  // Create own allocator if user did not supply.
1123  if(!allocator_)
1125 
1126  // Count number of '/' as tokenCount
1127  tokenCount_ = 0;
1128  for(const Ch* s = source; s != source + length; s++)
1129  if(*s == '/')
1130  tokenCount_++;
1131 
1132  Token* token = tokens_ = static_cast<Token*>(
1133  allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch)));
1134  Ch* name = nameBuffer_ = reinterpret_cast<Ch*>(tokens_ + tokenCount_);
1135  size_t i = 0;
1136 
1137  // Detect if it is a URI fragment
1138  bool uriFragment = false;
1139  if(source[i] == '#')
1140  {
1141  uriFragment = true;
1142  i++;
1143  }
1144 
1145  if(i != length && source[i] != '/')
1146  {
1148  goto error;
1149  }
1150 
1151  while(i < length)
1152  {
1153  RAPIDJSON_ASSERT(source[i] == '/');
1154  i++; // consumes '/'
1155 
1156  token->name = name;
1157  bool isNumber = true;
1158 
1159  while(i < length && source[i] != '/')
1160  {
1161  Ch c = source[i];
1162  if(uriFragment)
1163  {
1164  // Decoding percent-encoding for URI fragment
1165  if(c == '%')
1166  {
1167  PercentDecodeStream is(&source[i], source + length);
1169  Ch* begin = os.PutBegin();
1170  if(!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid())
1171  {
1173  goto error;
1174  }
1175  size_t len = os.PutEnd(begin);
1176  i += is.Tell() - 1;
1177  if(len == 1)
1178  c = *name;
1179  else
1180  {
1181  name += len;
1182  isNumber = false;
1183  i++;
1184  continue;
1185  }
1186  }
1187  else if(NeedPercentEncode(c))
1188  {
1190  goto error;
1191  }
1192  }
1193 
1194  i++;
1195 
1196  // Escaping "~0" -> '~', "~1" -> '/'
1197  if(c == '~')
1198  {
1199  if(i < length)
1200  {
1201  c = source[i];
1202  if(c == '0')
1203  c = '~';
1204  else if(c == '1')
1205  c = '/';
1206  else
1207  {
1209  goto error;
1210  }
1211  i++;
1212  }
1213  else
1214  {
1216  goto error;
1217  }
1218  }
1219 
1220  // First check for index: all of characters are digit
1221  if(c < '0' || c > '9')
1222  isNumber = false;
1223 
1224  *name++ = c;
1225  }
1226  token->length = static_cast<SizeType>(name - token->name);
1227  if(token->length == 0)
1228  isNumber = false;
1229  *name++ = '\0'; // Null terminator
1230 
1231  // Second check for index: more than one digit cannot have leading zero
1232  if(isNumber && token->length > 1 && token->name[0] == '0')
1233  isNumber = false;
1234 
1235  // String to SizeType conversion
1236  SizeType n = 0;
1237  if(isNumber)
1238  {
1239  for(size_t j = 0; j < token->length; j++)
1240  {
1241  SizeType m = n * 10 + static_cast<SizeType>(token->name[j] - '0');
1242  if(m < n)
1243  { // overflow detection
1244  isNumber = false;
1245  break;
1246  }
1247  n = m;
1248  }
1249  }
1250 
1251  token->index = isNumber ? n : kPointerInvalidIndex;
1252  token++;
1253  }
1254 
1255  RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer
1257  return;
1258 
1259  error:
1261  nameBuffer_ = 0;
1262  tokens_ = 0;
1263  tokenCount_ = 0;
1264  parseErrorOffset_ = i;
1265  return;
1266  }
1267 
1269 
1273  template <bool uriFragment, typename OutputStream>
1274  bool Stringify(OutputStream& os) const
1275  {
1276  RAPIDJSON_ASSERT(IsValid());
1277 
1278  if(uriFragment)
1279  os.Put('#');
1280 
1281  for(Token* t = tokens_; t != tokens_ + tokenCount_; ++t)
1282  {
1283  os.Put('/');
1284  for(size_t j = 0; j < t->length; j++)
1285  {
1286  Ch c = t->name[j];
1287  if(c == '~')
1288  {
1289  os.Put('~');
1290  os.Put('0');
1291  }
1292  else if(c == '/')
1293  {
1294  os.Put('~');
1295  os.Put('1');
1296  }
1297  else if(uriFragment && NeedPercentEncode(c))
1298  {
1299  // Transcode to UTF8 sequence
1301  PercentEncodeStream<OutputStream> target(os);
1302  if(!Transcoder<EncodingType, UTF8<>>().Validate(source, target))
1303  return false;
1304  j += source.Tell() - 1;
1305  }
1306  else
1307  os.Put(c);
1308  }
1309  }
1310  return true;
1311  }
1312 
1314 
1319  class PercentDecodeStream
1320  {
1321  public:
1322  typedef typename ValueType::Ch Ch;
1323 
1325 
1329  PercentDecodeStream(const Ch* source, const Ch* end)
1330  : src_(source), head_(source), end_(end), valid_(true)
1331  {
1332  }
1333 
1334  Ch Take()
1335  {
1336  if(*src_ != '%' || src_ + 3 > end_)
1337  { // %XY triplet
1338  valid_ = false;
1339  return 0;
1340  }
1341  src_++;
1342  Ch c = 0;
1343  for(int j = 0; j < 2; j++)
1344  {
1345  c = static_cast<Ch>(c << 4);
1346  Ch h = *src_;
1347  if(h >= '0' && h <= '9')
1348  c = static_cast<Ch>(c + h - '0');
1349  else if(h >= 'A' && h <= 'F')
1350  c = static_cast<Ch>(c + h - 'A' + 10);
1351  else if(h >= 'a' && h <= 'f')
1352  c = static_cast<Ch>(c + h - 'a' + 10);
1353  else
1354  {
1355  valid_ = false;
1356  return 0;
1357  }
1358  src_++;
1359  }
1360  return c;
1361  }
1362 
1363  size_t Tell() const { return static_cast<size_t>(src_ - head_); }
1364  bool IsValid() const { return valid_; }
1365 
1366  private:
1367  const Ch* src_;
1368  const Ch* head_;
1369  const Ch* end_;
1370  bool valid_;
1371  };
1372 
1374  template <typename OutputStream>
1376  {
1377  public:
1378  PercentEncodeStream(OutputStream& os) : os_(os) {}
1379  void Put(char c)
1380  { // UTF-8 must be byte
1381  unsigned char u = static_cast<unsigned char>(c);
1382  static const char hexDigits[16] = {
1383  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
1384  os_.Put('%');
1385  os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u >> 4]));
1386  os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u & 15]));
1387  }
1388 
1389  private:
1390  OutputStream& os_;
1391  };
1392 
1398  size_t tokenCount_;
1401 };
1402 
1405 
1407 
1408 
1410 
1411 template <typename T>
1412 typename T::ValueType& CreateValueByPointer(T& root,
1414  typename T::AllocatorType& a)
1415 {
1416  return pointer.Create(root, a);
1417 }
1418 
1419 template <typename T, typename CharType, size_t N>
1420 typename T::ValueType&
1421 CreateValueByPointer(T& root, const CharType (&source)[N], typename T::AllocatorType& a)
1422 {
1423  return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a);
1424 }
1425 
1426 // No allocator parameter
1427 
1428 template <typename DocumentType>
1429 typename DocumentType::ValueType&
1430 CreateValueByPointer(DocumentType& document,
1432 {
1433  return pointer.Create(document);
1434 }
1435 
1436 template <typename DocumentType, typename CharType, size_t N>
1437 typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document,
1438  const CharType (&source)[N])
1439 {
1440  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document);
1441 }
1442 
1444 
1445 template <typename T>
1446 typename T::ValueType* GetValueByPointer(T& root,
1448  size_t* unresolvedTokenIndex = 0)
1449 {
1450  return pointer.Get(root, unresolvedTokenIndex);
1451 }
1452 
1453 template <typename T>
1454 const typename T::ValueType* GetValueByPointer(const T& root,
1456  size_t* unresolvedTokenIndex = 0)
1457 {
1458  return pointer.Get(root, unresolvedTokenIndex);
1459 }
1460 
1461 template <typename T, typename CharType, size_t N>
1462 typename T::ValueType*
1463 GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0)
1464 {
1465  return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1466 }
1467 
1468 template <typename T, typename CharType, size_t N>
1469 const typename T::ValueType*
1470 GetValueByPointer(const T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0)
1471 {
1472  return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1473 }
1474 
1476 
1477 template <typename T>
1478 typename T::ValueType&
1481  const typename T::ValueType& defaultValue,
1482  typename T::AllocatorType& a)
1483 {
1484  return pointer.GetWithDefault(root, defaultValue, a);
1485 }
1486 
1487 template <typename T>
1488 typename T::ValueType&
1491  const typename T::Ch* defaultValue,
1492  typename T::AllocatorType& a)
1493 {
1494  return pointer.GetWithDefault(root, defaultValue, a);
1495 }
1496 
1497 #if RAPIDJSON_HAS_STDSTRING
1498 template <typename T>
1499 typename T::ValueType&
1502  const std::basic_string<typename T::Ch>& defaultValue,
1503  typename T::AllocatorType& a)
1504 {
1505  return pointer.GetWithDefault(root, defaultValue, a);
1506 }
1507 #endif
1508 
1509 template <typename T, typename T2>
1511  (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1512  (typename T::ValueType&))
1516  typename T::AllocatorType& a)
1517 {
1518  return pointer.GetWithDefault(root, defaultValue, a);
1519 }
1520 
1521 template <typename T, typename CharType, size_t N>
1522 typename T::ValueType& GetValueByPointerWithDefault(T& root,
1523  const CharType (&source)[N],
1524  const typename T::ValueType& defaultValue,
1525  typename T::AllocatorType& a)
1526 {
1528  .GetWithDefault(root, defaultValue, a);
1529 }
1530 
1531 template <typename T, typename CharType, size_t N>
1532 typename T::ValueType& GetValueByPointerWithDefault(T& root,
1533  const CharType (&source)[N],
1534  const typename T::Ch* defaultValue,
1535  typename T::AllocatorType& a)
1536 {
1538  .GetWithDefault(root, defaultValue, a);
1539 }
1540 
1541 #if RAPIDJSON_HAS_STDSTRING
1542 template <typename T, typename CharType, size_t N>
1543 typename T::ValueType&
1545  const CharType (&source)[N],
1546  const std::basic_string<typename T::Ch>& defaultValue,
1547  typename T::AllocatorType& a)
1548 {
1550  .GetWithDefault(root, defaultValue, a);
1551 }
1552 #endif
1553 
1554 template <typename T, typename CharType, size_t N, typename T2>
1556  (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1557  (typename T::ValueType&))
1559  const CharType (&source)[N],
1560  T2 defaultValue,
1561  typename T::AllocatorType& a)
1562 {
1564  .GetWithDefault(root, defaultValue, a);
1565 }
1566 
1567 // No allocator parameter
1568 
1569 template <typename DocumentType>
1570 typename DocumentType::ValueType&
1571 GetValueByPointerWithDefault(DocumentType& document,
1573  const typename DocumentType::ValueType& defaultValue)
1574 {
1575  return pointer.GetWithDefault(document, defaultValue);
1576 }
1577 
1578 template <typename DocumentType>
1579 typename DocumentType::ValueType&
1580 GetValueByPointerWithDefault(DocumentType& document,
1582  const typename DocumentType::Ch* defaultValue)
1583 {
1584  return pointer.GetWithDefault(document, defaultValue);
1585 }
1586 
1587 #if RAPIDJSON_HAS_STDSTRING
1588 template <typename DocumentType>
1589 typename DocumentType::ValueType&
1590 GetValueByPointerWithDefault(DocumentType& document,
1592  const std::basic_string<typename DocumentType::Ch>& defaultValue)
1593 {
1594  return pointer.GetWithDefault(document, defaultValue);
1595 }
1596 #endif
1597 
1598 template <typename DocumentType, typename T2>
1600  (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1601  (typename DocumentType::ValueType&))
1602 GetValueByPointerWithDefault(DocumentType& document,
1604  T2 defaultValue)
1605 {
1606  return pointer.GetWithDefault(document, defaultValue);
1607 }
1608 
1609 template <typename DocumentType, typename CharType, size_t N>
1610 typename DocumentType::ValueType&
1611 GetValueByPointerWithDefault(DocumentType& document,
1612  const CharType (&source)[N],
1613  const typename DocumentType::ValueType& defaultValue)
1614 {
1616  .GetWithDefault(document, defaultValue);
1617 }
1618 
1619 template <typename DocumentType, typename CharType, size_t N>
1620 typename DocumentType::ValueType&
1621 GetValueByPointerWithDefault(DocumentType& document,
1622  const CharType (&source)[N],
1623  const typename DocumentType::Ch* defaultValue)
1624 {
1626  .GetWithDefault(document, defaultValue);
1627 }
1628 
1629 #if RAPIDJSON_HAS_STDSTRING
1630 template <typename DocumentType, typename CharType, size_t N>
1631 typename DocumentType::ValueType&
1632 GetValueByPointerWithDefault(DocumentType& document,
1633  const CharType (&source)[N],
1634  const std::basic_string<typename DocumentType::Ch>& defaultValue)
1635 {
1637  .GetWithDefault(document, defaultValue);
1638 }
1639 #endif
1640 
1641 template <typename DocumentType, typename CharType, size_t N, typename T2>
1643  (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1644  (typename DocumentType::ValueType&))
1645 GetValueByPointerWithDefault(DocumentType& document, const CharType (&source)[N], T2 defaultValue)
1646 {
1648  .GetWithDefault(document, defaultValue);
1649 }
1650 
1652 
1653 template <typename T>
1654 typename T::ValueType& SetValueByPointer(T& root,
1656  typename T::ValueType& value,
1657  typename T::AllocatorType& a)
1658 {
1659  return pointer.Set(root, value, a);
1660 }
1661 
1662 template <typename T>
1663 typename T::ValueType& SetValueByPointer(T& root,
1665  const typename T::ValueType& value,
1666  typename T::AllocatorType& a)
1667 {
1668  return pointer.Set(root, value, a);
1669 }
1670 
1671 template <typename T>
1672 typename T::ValueType& SetValueByPointer(T& root,
1674  const typename T::Ch* value,
1675  typename T::AllocatorType& a)
1676 {
1677  return pointer.Set(root, value, a);
1678 }
1679 
1680 #if RAPIDJSON_HAS_STDSTRING
1681 template <typename T>
1682 typename T::ValueType& SetValueByPointer(T& root,
1684  const std::basic_string<typename T::Ch>& value,
1685  typename T::AllocatorType& a)
1686 {
1687  return pointer.Set(root, value, a);
1688 }
1689 #endif
1690 
1691 template <typename T, typename T2>
1693  (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1694  (typename T::ValueType&))
1695 SetValueByPointer(T& root,
1697  T2 value,
1698  typename T::AllocatorType& a)
1699 {
1700  return pointer.Set(root, value, a);
1701 }
1702 
1703 template <typename T, typename CharType, size_t N>
1704 typename T::ValueType& SetValueByPointer(T& root,
1705  const CharType (&source)[N],
1706  typename T::ValueType& value,
1707  typename T::AllocatorType& a)
1708 {
1709  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1710 }
1711 
1712 template <typename T, typename CharType, size_t N>
1713 typename T::ValueType& SetValueByPointer(T& root,
1714  const CharType (&source)[N],
1715  const typename T::ValueType& value,
1716  typename T::AllocatorType& a)
1717 {
1718  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1719 }
1720 
1721 template <typename T, typename CharType, size_t N>
1722 typename T::ValueType& SetValueByPointer(T& root,
1723  const CharType (&source)[N],
1724  const typename T::Ch* value,
1725  typename T::AllocatorType& a)
1726 {
1727  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1728 }
1729 
1730 #if RAPIDJSON_HAS_STDSTRING
1731 template <typename T, typename CharType, size_t N>
1732 typename T::ValueType& SetValueByPointer(T& root,
1733  const CharType (&source)[N],
1734  const std::basic_string<typename T::Ch>& value,
1735  typename T::AllocatorType& a)
1736 {
1737  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1738 }
1739 #endif
1740 
1741 template <typename T, typename CharType, size_t N, typename T2>
1743  (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1744  (typename T::ValueType&))
1745 SetValueByPointer(T& root, const CharType (&source)[N], T2 value, typename T::AllocatorType& a)
1746 {
1747  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1748 }
1749 
1750 // No allocator parameter
1751 
1752 template <typename DocumentType>
1753 typename DocumentType::ValueType&
1754 SetValueByPointer(DocumentType& document,
1756  typename DocumentType::ValueType& value)
1757 {
1758  return pointer.Set(document, value);
1759 }
1760 
1761 template <typename DocumentType>
1762 typename DocumentType::ValueType&
1763 SetValueByPointer(DocumentType& document,
1765  const typename DocumentType::ValueType& value)
1766 {
1767  return pointer.Set(document, value);
1768 }
1769 
1770 template <typename DocumentType>
1771 typename DocumentType::ValueType&
1772 SetValueByPointer(DocumentType& document,
1774  const typename DocumentType::Ch* value)
1775 {
1776  return pointer.Set(document, value);
1777 }
1778 
1779 #if RAPIDJSON_HAS_STDSTRING
1780 template <typename DocumentType>
1781 typename DocumentType::ValueType&
1782 SetValueByPointer(DocumentType& document,
1784  const std::basic_string<typename DocumentType::Ch>& value)
1785 {
1786  return pointer.Set(document, value);
1787 }
1788 #endif
1789 
1790 template <typename DocumentType, typename T2>
1792  (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1793  (typename DocumentType::ValueType&))
1794 SetValueByPointer(DocumentType& document,
1796  T2 value)
1797 {
1798  return pointer.Set(document, value);
1799 }
1800 
1801 template <typename DocumentType, typename CharType, size_t N>
1802 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
1803  const CharType (&source)[N],
1804  typename DocumentType::ValueType& value)
1805 {
1806  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1807 }
1808 
1809 template <typename DocumentType, typename CharType, size_t N>
1810 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
1811  const CharType (&source)[N],
1812  const typename DocumentType::ValueType& value)
1813 {
1814  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1815 }
1816 
1817 template <typename DocumentType, typename CharType, size_t N>
1818 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
1819  const CharType (&source)[N],
1820  const typename DocumentType::Ch* value)
1821 {
1822  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1823 }
1824 
1825 #if RAPIDJSON_HAS_STDSTRING
1826 template <typename DocumentType, typename CharType, size_t N>
1827 typename DocumentType::ValueType&
1828 SetValueByPointer(DocumentType& document,
1829  const CharType (&source)[N],
1830  const std::basic_string<typename DocumentType::Ch>& value)
1831 {
1832  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1833 }
1834 #endif
1835 
1836 template <typename DocumentType, typename CharType, size_t N, typename T2>
1838  (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1839  (typename DocumentType::ValueType&))
1840 SetValueByPointer(DocumentType& document, const CharType (&source)[N], T2 value)
1841 {
1842  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1843 }
1844 
1846 
1847 template <typename T>
1848 typename T::ValueType& SwapValueByPointer(T& root,
1850  typename T::ValueType& value,
1851  typename T::AllocatorType& a)
1852 {
1853  return pointer.Swap(root, value, a);
1854 }
1855 
1856 template <typename T, typename CharType, size_t N>
1857 typename T::ValueType& SwapValueByPointer(T& root,
1858  const CharType (&source)[N],
1859  typename T::ValueType& value,
1860  typename T::AllocatorType& a)
1861 {
1862  return GenericPointer<typename T::ValueType>(source, N - 1).Swap(root, value, a);
1863 }
1864 
1865 template <typename DocumentType>
1866 typename DocumentType::ValueType&
1867 SwapValueByPointer(DocumentType& document,
1869  typename DocumentType::ValueType& value)
1870 {
1871  return pointer.Swap(document, value);
1872 }
1873 
1874 template <typename DocumentType, typename CharType, size_t N>
1875 typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document,
1876  const CharType (&source)[N],
1877  typename DocumentType::ValueType& value)
1878 {
1880 }
1881 
1883 
1884 template <typename T>
1886 {
1887  return pointer.Erase(root);
1888 }
1889 
1890 template <typename T, typename CharType, size_t N>
1891 bool EraseValueByPointer(T& root, const CharType (&source)[N])
1892 {
1893  return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root);
1894 }
1895 
1897 
1899 
1900 #if defined(__clang__) || defined(_MSC_VER)
1901 RAPIDJSON_DIAG_POP
1902 #endif
1903 
1904 #endif // RAPIDJSON_POINTER_H_
void Free(A &a, T *p, size_t n=1)
Definition: allocators.h:485
A document for parsing JSON text as DOM.
Definition: document.h:3143
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:3472
A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence.
Definition: pointer.h:1376
PercentEncodeStream(OutputStream &os)
Definition: pointer.h:1378
void Put(char c)
Definition: pointer.h:1379
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition: pointer.h:76
GenericPointer & operator=(const GenericPointer &rhs)
Assignment operator.
Definition: pointer.h:246
friend void swap(GenericPointer &a, GenericPointer &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition: pointer.h:296
Ch * nameBuffer_
A buffer containing all names in tokens.
Definition: pointer.h:1396
Allocator * allocator_
Definition: pointer.h:1393
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.
GenericPointer(const GenericPointer &rhs, Allocator *allocator)
Copy constructor.
Definition: pointer.h:224
GenericPointer(const Ch *source, Allocator *allocator=0)
Constructor that parses a string or URI fragment representation.
Definition: pointer.h:124
ValueType::EncodingType EncodingType
Encoding type from Value.
Definition: pointer.h:78
GenericPointer(const Token *tokens, size_t tokenCount)
Constructor with user-supplied tokens.
Definition: pointer.h:199
GenericPointer(Allocator *allocator=0)
Default constructor.
Definition: pointer.h:107
GenericPointer & Swap(GenericPointer &other) RAPIDJSON_NOEXCEPT
Swap the content of this pointer with an other.
Definition: pointer.h:274
size_t tokenCount_
Number of tokens in tokens_.
Definition: pointer.h:1398
GenericPointer(const GenericPointer &rhs)
Copy constructor.
Definition: pointer.h:211
PointerParseErrorCode parseErrorCode_
Parsing error code.
Definition: pointer.h:1400
Token * tokens_
A list of tokens.
Definition: pointer.h:1397
Allocator * ownAllocator_
Allocator owned by this Pointer.
Definition: pointer.h:1395
GenericPointer(const Ch *source, size_t length, Allocator *allocator=0)
Definition: pointer.h:165
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:328
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
Definition: pointer.h:309
ValueType::Ch Ch
Character type from Value.
Definition: pointer.h:79
GenericUri< ValueType, Allocator > UriType
Definition: pointer.h:80
~GenericPointer()
Destructor.
Definition: pointer.h:237
size_t parseErrorOffset_
Offset in code unit when parsing fail.
Definition: pointer.h:1399
Allocator * allocator
Definition: pointer.h:344
Definition: uri.h:34
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:822
Concept for allocating, resizing and freeing memory block.
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:451
#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:277
@ kPointerParseErrorInvalidEscape
Invalid escape.
Definition: error.h:281
@ kPointerParseErrorTokenMustBeginWithSolidus
A token must begin with a '/'.
Definition: error.h:280
@ kPointerParseErrorNone
The parse is successful.
Definition: error.h:278
@ kPointerParseErrorCharacterMustPercentEncode
Definition: error.h:283
@ kPointerParseErrorInvalidPercentEncoding
Invalid percent encoding in URI fragment.
Definition: error.h:282
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:41
SizeType StrLen(const Ch *s)
Custom strlen() which works on different character types.
Definition: strfunc.h:32
char * u64toa(uint64_t value, char *buffer)
Definition: itoa.h:135
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T2 >, internal::IsGenericValue< T2 >>),(typename T::ValueType &)) GetValueByPointerWithDefault(T &root
T::ValueType * GetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, size_t *unresolvedTokenIndex=0)
Definition: pointer.h:1446
T::ValueType & GetValueByPointerWithDefault(T &root, const GenericPointer< typename T::ValueType > &pointer, const typename T::ValueType &defaultValue, typename T::AllocatorType &a)
Definition: pointer.h:1479
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1697
const GenericPointer< typename T::ValueType > T2 defaultValue
Definition: pointer.h:1515
#define RAPIDJSON_IF_CONSTEXPR
Definition: pointer.h:34
bool EraseValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer)
Definition: pointer.h:1885
GenericPointer< Value > Pointer
GenericPointer for Value (UTF-8, default allocator).
Definition: pointer.h:1404
T::ValueType & SetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition: pointer.h:1654
const GenericPointer< typename T::ValueType > & pointer
Definition: pointer.h:1514
T::ValueType & SwapValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition: pointer.h:1848
const CharType(& source)[N]
Definition: pointer.h:1559
T::ValueType & CreateValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::AllocatorType &a)
Definition: pointer.h:1412
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1517
Type
Type of JSON value.
Definition: rapidjson.h:760
@ kObjectType
object
Definition: rapidjson.h:764
@ kArrayType
array
Definition: rapidjson.h:765
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:746
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:429
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition: rapidjson.h:742
A read-write string stream.
Definition: stream.h:210
A token is the basic units of internal representation.
Definition: pointer.h:96
SizeType index
A valid array index, if it is not equal to kPointerInvalidIndex.
Definition: pointer.h:100
SizeType length
Length of the name.
Definition: pointer.h:99
const Ch * name
Definition: pointer.h:97
Reference to a constant string (not taking a copy)
Definition: document.h:417
Read-only string stream.
Definition: stream.h:163
Encoding conversion.
Definition: encodings.h:823
UTF-8 encoding.
Definition: encodings.h:98
Definition: document.h:595