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. All rights reserved.
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 "internal/itoa.h"
20 
21 #if __clang__
22 RAPIDJSON_DIAG_PUSH
23 RAPIDJSON_DIAG_OFF(switch - enum)
24 #elif defined(_MSC_VER)
25 RAPIDJSON_DIAG_PUSH
26 RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
27 #endif
28 
30 
32 
34 
38 {
40 
45 };
46 
48 // GenericPointer
49 
51 
79 template <typename ValueType, typename Allocator = CrtAllocator>
80 class GenericPointer
81 {
82 public:
83  typedef typename ValueType::EncodingType EncodingType;
84  typedef typename ValueType::Ch Ch;
85 
87 
99  struct Token
100  {
101  const Ch* name;
104  };
105 
107 
108 
110  GenericPointer(Allocator* allocator = 0)
112  , ownAllocator_()
113  , nameBuffer_()
114  , tokens_()
115  , tokenCount_()
118  {
119  }
120 
122 
127  explicit GenericPointer(const Ch* source, Allocator* allocator = 0)
129  , ownAllocator_()
130  , nameBuffer_()
131  , tokens_()
132  , tokenCount_()
135  {
136  Parse(source, internal::StrLen(source));
137  }
138 
139 #if RAPIDJSON_HAS_STDSTRING
140 
147  explicit GenericPointer(const std::basic_string<Ch>& source, Allocator* allocator = 0)
149  , ownAllocator_()
150  , nameBuffer_()
151  , tokens_()
152  , tokenCount_()
155  {
156  Parse(source.c_str(), source.size());
157  }
158 #endif
159 
161 
168  GenericPointer(const Ch* source, size_t length, Allocator* allocator = 0)
170  , ownAllocator_()
171  , nameBuffer_()
172  , tokens_()
173  , tokenCount_()
176  {
177  Parse(source, length);
178  }
179 
181 
202  GenericPointer(const Token* tokens, size_t tokenCount)
203  : allocator_()
204  , ownAllocator_()
205  , nameBuffer_()
206  , tokens_(const_cast<Token*>(tokens))
207  , tokenCount_(tokenCount)
210  {
211  }
212 
215  : allocator_(rhs.allocator_)
216  , ownAllocator_()
217  , nameBuffer_()
218  , tokens_()
219  , tokenCount_()
222  {
223  *this = rhs;
224  }
225 
227  GenericPointer(const GenericPointer& rhs, Allocator* allocator)
228  : allocator_(allocator)
229  , ownAllocator_()
230  , nameBuffer_()
231  , tokens_()
232  , tokenCount_()
235  {
236  *this = rhs;
237  }
238 
241  {
242  if (nameBuffer_) // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and tokens_ are not
243  // deallocated.
244  Allocator::Free(tokens_);
246  }
247 
250  {
251  if (this != &rhs)
252  {
253  // Do not delete ownAllcator
254  if (nameBuffer_)
255  Allocator::Free(tokens_);
256 
257  tokenCount_ = rhs.tokenCount_;
260 
261  if (rhs.nameBuffer_)
262  CopyFromRaw(rhs); // Normally parsed tokens.
263  else
264  {
265  tokens_ = rhs.tokens_; // User supplied const tokens.
266  nameBuffer_ = 0;
267  }
268  }
269  return *this;
270  }
271 
273 
277  GenericPointer& Swap(GenericPointer& other) RAPIDJSON_NOEXCEPT
278  {
279  internal::Swap(allocator_, other.allocator_);
280  internal::Swap(ownAllocator_, other.ownAllocator_);
281  internal::Swap(nameBuffer_, other.nameBuffer_);
282  internal::Swap(tokens_, other.tokens_);
283  internal::Swap(tokenCount_, other.tokenCount_);
284  internal::Swap(parseErrorOffset_, other.parseErrorOffset_);
285  internal::Swap(parseErrorCode_, other.parseErrorCode_);
286  return *this;
287  }
288 
290 
301  friend inline void swap(GenericPointer& a, GenericPointer& b) RAPIDJSON_NOEXCEPT
302  {
303  a.Swap(b);
304  }
305 
307 
309 
310 
312 
317  GenericPointer Append(const Token& token, Allocator* allocator = 0) const
318  {
319  GenericPointer r;
320  r.allocator_ = allocator;
321  Ch* p = r.CopyFromRaw(*this, 1, token.length + 1);
322  std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch));
323  r.tokens_[tokenCount_].name = p;
324  r.tokens_[tokenCount_].length = token.length;
325  r.tokens_[tokenCount_].index = token.index;
326  return r;
327  }
328 
330 
336  GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const
337  {
338  Token token = { name, length, kPointerInvalidIndex };
339  return Append(token, allocator);
340  }
341 
343 
348  template <typename T>
349  RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),
350  (GenericPointer))
351  Append(T* name, Allocator* allocator = 0) const
352  {
353  return Append(name, internal::StrLen(name), allocator);
354  }
355 
356 #if RAPIDJSON_HAS_STDSTRING
357 
363  GenericPointer Append(const std::basic_string<Ch>& name, Allocator* allocator = 0) const
364  {
365  return Append(name.c_str(), static_cast<SizeType>(name.size()), allocator);
366  }
367 #endif
368 
370 
375  GenericPointer Append(SizeType index, Allocator* allocator = 0) const
376  {
377  char buffer[21];
378  char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer);
379  SizeType length = static_cast<SizeType>(end - buffer);
380  buffer[length] = '\0';
381 
382  if (sizeof(Ch) == 1)
383  {
384  Token token = { reinterpret_cast<Ch*>(buffer), length, index };
385  return Append(token, allocator);
386  }
387  else
388  {
389  Ch name[21];
390  for (size_t i = 0; i <= length; i++)
391  name[i] = static_cast<Ch>(buffer[i]);
392  Token token = { name, length, index };
393  return Append(token, allocator);
394  }
395  }
396 
398 
403  GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const
404  {
405  if (token.IsString())
406  return Append(token.GetString(), token.GetStringLength(), allocator);
407  else
408  {
409  RAPIDJSON_ASSERT(token.IsUint64());
410  RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0));
411  return Append(static_cast<SizeType>(token.GetUint64()), allocator);
412  }
413  }
414 
416 
417 
419  bool IsValid() const
420  {
422  }
423 
425  size_t GetParseErrorOffset() const
426  {
427  return parseErrorOffset_;
428  }
429 
431  PointerParseErrorCode GetParseErrorCode() const
432  {
433  return parseErrorCode_;
434  }
435 
437 
439  Allocator& GetAllocator()
440  {
441  return *allocator_;
442  }
443 
445 
446 
448  const Token* GetTokens() const
449  {
450  return tokens_;
451  }
452 
454  size_t GetTokenCount() const
455  {
456  return tokenCount_;
457  }
458 
460 
462 
463 
465 
468  bool operator==(const GenericPointer& rhs) const
469  {
470  if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_)
471  return false;
472 
473  for (size_t i = 0; i < tokenCount_; i++)
474  {
475  if (tokens_[i].index != rhs.tokens_[i].index || tokens_[i].length != rhs.tokens_[i].length ||
476  (tokens_[i].length != 0 &&
477  std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length) != 0))
478  {
479  return false;
480  }
481  }
482 
483  return true;
484  }
485 
487 
490  bool operator!=(const GenericPointer& rhs) const
491  {
492  return !(*this == rhs);
493  }
494 
496 
499  bool operator<(const GenericPointer& rhs) const
500  {
501  if (!IsValid())
502  return false;
503  if (!rhs.IsValid())
504  return true;
505 
506  if (tokenCount_ != rhs.tokenCount_)
507  return tokenCount_ < rhs.tokenCount_;
508 
509  for (size_t i = 0; i < tokenCount_; i++)
510  {
511  if (tokens_[i].index != rhs.tokens_[i].index)
512  return tokens_[i].index < rhs.tokens_[i].index;
513 
514  if (tokens_[i].length != rhs.tokens_[i].length)
515  return tokens_[i].length < rhs.tokens_[i].length;
516 
517  if (int cmp = std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length))
518  return cmp < 0;
519  }
520 
521  return false;
522  }
523 
525 
527 
528 
530 
534  template <typename OutputStream>
535  bool Stringify(OutputStream& os) const
536  {
537  return Stringify<false, OutputStream>(os);
538  }
539 
541 
545  template <typename OutputStream>
546  bool StringifyUriFragment(OutputStream& os) const
547  {
548  return Stringify<true, OutputStream>(os);
549  }
550 
552 
554 
555 
557 
571  ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const
572  {
573  RAPIDJSON_ASSERT(IsValid());
574  ValueType* v = &root;
575  bool exist = true;
576  for (const Token* t = tokens_; t != tokens_ + tokenCount_; ++t)
577  {
578  if (v->IsArray() && t->name[0] == '-' && t->length == 1)
579  {
580  v->PushBack(ValueType().Move(), allocator);
581  v = &((*v)[v->Size() - 1]);
582  exist = false;
583  }
584  else
585  {
586  if (t->index == kPointerInvalidIndex)
587  { // must be object name
588  if (!v->IsObject())
589  v->SetObject(); // Change to Object
590  }
591  else
592  { // object name or array index
593  if (!v->IsArray() && !v->IsObject())
594  v->SetArray(); // Change to Array
595  }
596 
597  if (v->IsArray())
598  {
599  if (t->index >= v->Size())
600  {
601  v->Reserve(t->index + 1, allocator);
602  while (t->index >= v->Size())
603  v->PushBack(ValueType().Move(), allocator);
604  exist = false;
605  }
606  v = &((*v)[t->index]);
607  }
608  else
609  {
610  typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
611  if (m == v->MemberEnd())
612  {
613  v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
614  v = &(--v->MemberEnd())->value; // Assumes AddMember() appends at the end
615  exist = false;
616  }
617  else
618  v = &m->value;
619  }
620  }
621  }
622 
623  if (alreadyExist)
624  *alreadyExist = exist;
625 
626  return *v;
627  }
628 
630 
635  template <typename stackAllocator>
637  bool* alreadyExist = 0) const
638  {
639  return Create(document, document.GetAllocator(), alreadyExist);
640  }
641 
643 
645 
646 
648 
662  ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const
663  {
664  RAPIDJSON_ASSERT(IsValid());
665  ValueType* v = &root;
666  for (const Token* t = tokens_; t != tokens_ + tokenCount_; ++t)
667  {
668  switch (v->GetType())
669  {
670  case kObjectType:
671  {
672  typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
673  if (m == v->MemberEnd())
674  break;
675  v = &m->value;
676  }
677  continue;
678  case kArrayType:
679  if (t->index == kPointerInvalidIndex || t->index >= v->Size())
680  break;
681  v = &((*v)[t->index]);
682  continue;
683  default:
684  break;
685  }
686 
687  // Error: unresolved token
688  if (unresolvedTokenIndex)
689  *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
690  return 0;
691  }
692  return v;
693  }
694 
696 
700  const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const
701  {
702  return Get(const_cast<ValueType&>(root), unresolvedTokenIndex);
703  }
704 
706 
708 
709 
711 
720  ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue,
721  typename ValueType::AllocatorType& allocator) const
722  {
723  bool alreadyExist;
724  ValueType& v = Create(root, allocator, &alreadyExist);
725  return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
726  }
727 
729  ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const
730  {
731  bool alreadyExist;
732  ValueType& v = Create(root, allocator, &alreadyExist);
733  return alreadyExist ? v : v.SetString(defaultValue, allocator);
734  }
735 
736 #if RAPIDJSON_HAS_STDSTRING
737  ValueType& GetWithDefault(ValueType& root, const std::basic_string<Ch>& defaultValue,
739  typename ValueType::AllocatorType& allocator) const
740  {
741  bool alreadyExist;
742  ValueType& v = Create(root, allocator, &alreadyExist);
743  return alreadyExist ? v : v.SetString(defaultValue, allocator);
744  }
745 #endif
746 
748 
751  template <typename T>
752  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
753  GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator) const
754  {
755  return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);
756  }
757 
759  template <typename stackAllocator>
761  const ValueType& defaultValue) const
762  {
763  return GetWithDefault(document, defaultValue, document.GetAllocator());
764  }
765 
767  template <typename stackAllocator>
769  const Ch* defaultValue) const
770  {
771  return GetWithDefault(document, defaultValue, document.GetAllocator());
772  }
773 
774 #if RAPIDJSON_HAS_STDSTRING
775  template <typename stackAllocator>
778  const std::basic_string<Ch>& defaultValue) const
779  {
780  return GetWithDefault(document, defaultValue, document.GetAllocator());
781  }
782 #endif
783 
785 
788  template <typename T, typename stackAllocator>
789  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
791  T defaultValue) const
792  {
793  return GetWithDefault(document, defaultValue, document.GetAllocator());
794  }
795 
797 
799 
800 
802 
811  ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const
812  {
813  return Create(root, allocator) = value;
814  }
815 
817  ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const
818  {
819  return Create(root, allocator).CopyFrom(value, allocator);
820  }
821 
823  ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const
824  {
825  return Create(root, allocator) = ValueType(value, allocator).Move();
826  }
827 
828 #if RAPIDJSON_HAS_STDSTRING
829  ValueType& Set(ValueType& root, const std::basic_string<Ch>& value,
831  typename ValueType::AllocatorType& allocator) const
832  {
833  return Create(root, allocator) = ValueType(value, allocator).Move();
834  }
835 #endif
836 
838 
841  template <typename T>
842  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
843  Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const
844  {
845  return Create(root, allocator) = ValueType(value).Move();
846  }
847 
849  template <typename stackAllocator>
851  ValueType& value) const
852  {
853  return Create(document) = value;
854  }
855 
857  template <typename stackAllocator>
859  const ValueType& value) const
860  {
861  return Create(document).CopyFrom(value, document.GetAllocator());
862  }
863 
865  template <typename stackAllocator>
867  const Ch* value) const
868  {
869  return Create(document) = ValueType(value, document.GetAllocator()).Move();
870  }
871 
872 #if RAPIDJSON_HAS_STDSTRING
873  template <typename stackAllocator>
876  const std::basic_string<Ch>& value) const
877  {
878  return Create(document) = ValueType(value, document.GetAllocator()).Move();
879  }
880 #endif
881 
883 
886  template <typename T, typename stackAllocator>
887  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
889  {
890  return Create(document) = value;
891  }
892 
894 
896 
897 
899 
908  ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const
909  {
910  return Create(root, allocator).Swap(value);
911  }
912 
914  template <typename stackAllocator>
916  ValueType& value) const
917  {
918  return Create(document).Swap(value);
919  }
920 
922 
924 
930  bool Erase(ValueType& root) const
931  {
932  RAPIDJSON_ASSERT(IsValid());
933  if (tokenCount_ == 0) // Cannot erase the root
934  return false;
935 
936  ValueType* v = &root;
937  const Token* last = tokens_ + (tokenCount_ - 1);
938  for (const Token* t = tokens_; t != last; ++t)
939  {
940  switch (v->GetType())
941  {
942  case kObjectType:
943  {
944  typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
945  if (m == v->MemberEnd())
946  return false;
947  v = &m->value;
948  }
949  break;
950  case kArrayType:
951  if (t->index == kPointerInvalidIndex || t->index >= v->Size())
952  return false;
953  v = &((*v)[t->index]);
954  break;
955  default:
956  return false;
957  }
958  }
959 
960  switch (v->GetType())
961  {
962  case kObjectType:
963  return v->EraseMember(GenericStringRef<Ch>(last->name, last->length));
964  case kArrayType:
965  if (last->index == kPointerInvalidIndex || last->index >= v->Size())
966  return false;
967  v->Erase(v->Begin() + last->index);
968  return true;
969  default:
970  return false;
971  }
972  }
973 
974 private:
976 
982  Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0)
983  {
984  if (!allocator_) // allocator is independently owned.
985  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
986 
987  size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens
988  for (Token* t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)
989  nameBufferSize += t->length;
990 
991  tokenCount_ = rhs.tokenCount_ + extraToken;
992  tokens_ = static_cast<Token*>(
993  allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch)));
994  nameBuffer_ = reinterpret_cast<Ch*>(tokens_ + tokenCount_);
995  if (rhs.tokenCount_ > 0)
996  {
997  std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token));
998  }
999  if (nameBufferSize > 0)
1000  {
1001  std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
1002  }
1003 
1004  // Adjust pointers to name buffer
1005  std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;
1006  for (Token* t = tokens_; t != tokens_ + rhs.tokenCount_; ++t)
1007  t->name += diff;
1008 
1009  return nameBuffer_ + nameBufferSize;
1010  }
1011 
1013 
1017  bool NeedPercentEncode(Ch c) const
1018  {
1019  return !((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' ||
1020  c == '_' || c == '~');
1021  }
1022 
1024 #ifndef __clang__ // -Wdocumentation
1025 
1030 #endif
1031  void Parse(const Ch* source, size_t length)
1032  {
1033  RAPIDJSON_ASSERT(source != NULL);
1035  RAPIDJSON_ASSERT(tokens_ == 0);
1036 
1037  // Create own allocator if user did not supply.
1038  if (!allocator_)
1039  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
1040 
1041  // Count number of '/' as tokenCount
1042  tokenCount_ = 0;
1043  for (const Ch* s = source; s != source + length; s++)
1044  if (*s == '/')
1045  tokenCount_++;
1046 
1047  Token* token = tokens_ = static_cast<Token*>(allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch)));
1048  Ch* name = nameBuffer_ = reinterpret_cast<Ch*>(tokens_ + tokenCount_);
1049  size_t i = 0;
1050 
1051  // Detect if it is a URI fragment
1052  bool uriFragment = false;
1053  if (source[i] == '#')
1054  {
1055  uriFragment = true;
1056  i++;
1057  }
1058 
1059  if (i != length && source[i] != '/')
1060  {
1062  goto error;
1063  }
1064 
1065  while (i < length)
1066  {
1067  RAPIDJSON_ASSERT(source[i] == '/');
1068  i++; // consumes '/'
1069 
1070  token->name = name;
1071  bool isNumber = true;
1072 
1073  while (i < length && source[i] != '/')
1074  {
1075  Ch c = source[i];
1076  if (uriFragment)
1077  {
1078  // Decoding percent-encoding for URI fragment
1079  if (c == '%')
1080  {
1081  PercentDecodeStream is(&source[i], source + length);
1083  Ch* begin = os.PutBegin();
1084  if (!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid())
1085  {
1087  goto error;
1088  }
1089  size_t len = os.PutEnd(begin);
1090  i += is.Tell() - 1;
1091  if (len == 1)
1092  c = *name;
1093  else
1094  {
1095  name += len;
1096  isNumber = false;
1097  i++;
1098  continue;
1099  }
1100  }
1101  else if (NeedPercentEncode(c))
1102  {
1104  goto error;
1105  }
1106  }
1107 
1108  i++;
1109 
1110  // Escaping "~0" -> '~', "~1" -> '/'
1111  if (c == '~')
1112  {
1113  if (i < length)
1114  {
1115  c = source[i];
1116  if (c == '0')
1117  c = '~';
1118  else if (c == '1')
1119  c = '/';
1120  else
1121  {
1123  goto error;
1124  }
1125  i++;
1126  }
1127  else
1128  {
1130  goto error;
1131  }
1132  }
1133 
1134  // First check for index: all of characters are digit
1135  if (c < '0' || c > '9')
1136  isNumber = false;
1137 
1138  *name++ = c;
1139  }
1140  token->length = static_cast<SizeType>(name - token->name);
1141  if (token->length == 0)
1142  isNumber = false;
1143  *name++ = '\0'; // Null terminator
1144 
1145  // Second check for index: more than one digit cannot have leading zero
1146  if (isNumber && token->length > 1 && token->name[0] == '0')
1147  isNumber = false;
1148 
1149  // String to SizeType conversion
1150  SizeType n = 0;
1151  if (isNumber)
1152  {
1153  for (size_t j = 0; j < token->length; j++)
1154  {
1155  SizeType m = n * 10 + static_cast<SizeType>(token->name[j] - '0');
1156  if (m < n)
1157  { // overflow detection
1158  isNumber = false;
1159  break;
1160  }
1161  n = m;
1162  }
1163  }
1164 
1165  token->index = isNumber ? n : kPointerInvalidIndex;
1166  token++;
1167  }
1168 
1169  RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer
1171  return;
1172 
1173  error:
1174  Allocator::Free(tokens_);
1175  nameBuffer_ = 0;
1176  tokens_ = 0;
1177  tokenCount_ = 0;
1178  parseErrorOffset_ = i;
1179  return;
1180  }
1181 
1183 
1188  template <bool uriFragment, typename OutputStream>
1189  bool Stringify(OutputStream& os) const
1190  {
1191  RAPIDJSON_ASSERT(IsValid());
1192 
1193  if (uriFragment)
1194  os.Put('#');
1195 
1196  for (Token* t = tokens_; t != tokens_ + tokenCount_; ++t)
1197  {
1198  os.Put('/');
1199  for (size_t j = 0; j < t->length; j++)
1200  {
1201  Ch c = t->name[j];
1202  if (c == '~')
1203  {
1204  os.Put('~');
1205  os.Put('0');
1206  }
1207  else if (c == '/')
1208  {
1209  os.Put('~');
1210  os.Put('1');
1211  }
1212  else if (uriFragment && NeedPercentEncode(c))
1213  {
1214  // Transcode to UTF8 sequence
1217  if (!Transcoder<EncodingType, UTF8<> >().Validate(source, target))
1218  return false;
1219  j += source.Tell() - 1;
1220  }
1221  else
1222  os.Put(c);
1223  }
1224  }
1225  return true;
1226  }
1227 
1229 
1234  class PercentDecodeStream
1235  {
1236  public:
1237  typedef typename ValueType::Ch Ch;
1238 
1240 
1244  PercentDecodeStream(const Ch* source, const Ch* end) : src_(source), head_(source), end_(end), valid_(true)
1245  {
1246  }
1247 
1248  Ch Take()
1249  {
1250  if (*src_ != '%' || src_ + 3 > end_)
1251  { // %XY triplet
1252  valid_ = false;
1253  return 0;
1254  }
1255  src_++;
1256  Ch c = 0;
1257  for (int j = 0; j < 2; j++)
1258  {
1259  c = static_cast<Ch>(c << 4);
1260  Ch h = *src_;
1261  if (h >= '0' && h <= '9')
1262  c = static_cast<Ch>(c + h - '0');
1263  else if (h >= 'A' && h <= 'F')
1264  c = static_cast<Ch>(c + h - 'A' + 10);
1265  else if (h >= 'a' && h <= 'f')
1266  c = static_cast<Ch>(c + h - 'a' + 10);
1267  else
1268  {
1269  valid_ = false;
1270  return 0;
1271  }
1272  src_++;
1273  }
1274  return c;
1275  }
1276 
1277  size_t Tell() const
1278  {
1279  return static_cast<size_t>(src_ - head_);
1280  }
1281  bool IsValid() const
1282  {
1283  return valid_;
1284  }
1285 
1286  private:
1287  const Ch* src_;
1288  const Ch* head_;
1289  const Ch* end_;
1290  bool valid_;
1291  };
1292 
1294  template <typename OutputStream>
1296  {
1297  public:
1298  PercentEncodeStream(OutputStream& os) : os_(os)
1299  {
1300  }
1301  void Put(char c)
1302  { // UTF-8 must be byte
1303  unsigned char u = static_cast<unsigned char>(c);
1304  static const char hexDigits[16] = {
1305  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
1306  };
1307  os_.Put('%');
1308  os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u >> 4]));
1309  os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u & 15]));
1310  }
1311 
1312  private:
1313  OutputStream& os_;
1314  };
1315 
1316  Allocator* allocator_;
1317  Allocator* ownAllocator_;
1320  size_t tokenCount_;
1323 };
1324 
1327 
1329 
1330 
1332 
1333 template <typename T>
1335  typename T::AllocatorType& a)
1336 {
1337  return pointer.Create(root, a);
1338 }
1339 
1340 template <typename T, typename CharType, size_t N>
1341 typename T::ValueType& CreateValueByPointer(T& root, const CharType (&source)[N], typename T::AllocatorType& a)
1342 {
1343  return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a);
1344 }
1345 
1346 // No allocator parameter
1347 
1348 template <typename DocumentType>
1349 typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document,
1351 {
1352  return pointer.Create(document);
1353 }
1354 
1355 template <typename DocumentType, typename CharType, size_t N>
1356 typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const CharType (&source)[N])
1357 {
1358  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document);
1359 }
1360 
1362 
1363 template <typename T>
1364 typename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer,
1365  size_t* unresolvedTokenIndex = 0)
1366 {
1367  return pointer.Get(root, unresolvedTokenIndex);
1368 }
1369 
1370 template <typename T>
1371 const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer<typename T::ValueType>& pointer,
1372  size_t* unresolvedTokenIndex = 0)
1373 {
1374  return pointer.Get(root, unresolvedTokenIndex);
1375 }
1376 
1377 template <typename T, typename CharType, size_t N>
1378 typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0)
1379 {
1380  return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1381 }
1382 
1383 template <typename T, typename CharType, size_t N>
1384 const typename T::ValueType* GetValueByPointer(const T& root, const CharType (&source)[N],
1385  size_t* unresolvedTokenIndex = 0)
1386 {
1387  return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1388 }
1389 
1391 
1392 template <typename T>
1394  const typename T::ValueType& defaultValue,
1395  typename T::AllocatorType& a)
1396 {
1397  return pointer.GetWithDefault(root, defaultValue, a);
1398 }
1399 
1400 template <typename T>
1402  const typename T::Ch* defaultValue, typename T::AllocatorType& a)
1403 {
1404  return pointer.GetWithDefault(root, defaultValue, a);
1405 }
1406 
1407 #if RAPIDJSON_HAS_STDSTRING
1408 template <typename T>
1409 typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer,
1410  const std::basic_string<typename T::Ch>& defaultValue,
1411  typename T::AllocatorType& a)
1412 {
1413  return pointer.GetWithDefault(root, defaultValue, a);
1414 }
1415 #endif
1416 
1417 template <typename T, typename T2>
1418 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >),
1419  (typename T::ValueType&))
1420 GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 defaultValue,
1421  typename T::AllocatorType& a)
1423  return pointer.GetWithDefault(root, defaultValue, a);
1424 }
1425 
1426 template <typename T, typename CharType, size_t N>
1427 typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType (&source)[N],
1428  const typename T::ValueType& defaultValue,
1429  typename T::AllocatorType& a)
1430 {
1431  return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1432 }
1433 
1434 template <typename T, typename CharType, size_t N>
1435 typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType (&source)[N],
1436  const typename T::Ch* defaultValue, typename T::AllocatorType& a)
1437 {
1438  return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1439 }
1440 
1441 #if RAPIDJSON_HAS_STDSTRING
1442 template <typename T, typename CharType, size_t N>
1443 typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType (&source)[N],
1444  const std::basic_string<typename T::Ch>& defaultValue,
1445  typename T::AllocatorType& a)
1446 {
1447  return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1448 }
1449 #endif
1450 
1451 template <typename T, typename CharType, size_t N, typename T2>
1452 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >),
1453  (typename T::ValueType&))
1454 GetValueByPointerWithDefault(T& root, const CharType (&source)[N], T2 defaultValue, typename T::AllocatorType& a)
1455 {
1456  return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1457 }
1458 
1459 // No allocator parameter
1460 
1461 template <typename DocumentType>
1462 typename DocumentType::ValueType&
1464  const typename DocumentType::ValueType& defaultValue)
1465 {
1466  return pointer.GetWithDefault(document, defaultValue);
1467 }
1468 
1469 template <typename DocumentType>
1470 typename DocumentType::ValueType&
1472  const typename DocumentType::Ch* defaultValue)
1473 {
1474  return pointer.GetWithDefault(document, defaultValue);
1475 }
1476 
1477 #if RAPIDJSON_HAS_STDSTRING
1478 template <typename DocumentType>
1479 typename DocumentType::ValueType&
1481  const std::basic_string<typename DocumentType::Ch>& defaultValue)
1482 {
1483  return pointer.GetWithDefault(document, defaultValue);
1484 }
1485 #endif
1486 
1487 template <typename DocumentType, typename T2>
1488 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >),
1489  (typename DocumentType::ValueType&))
1491  T2 defaultValue)
1492 {
1493  return pointer.GetWithDefault(document, defaultValue);
1494 }
1495 
1496 template <typename DocumentType, typename CharType, size_t N>
1497 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType (&source)[N],
1498  const typename DocumentType::ValueType& defaultValue)
1499 {
1500  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1501 }
1502 
1503 template <typename DocumentType, typename CharType, size_t N>
1504 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType (&source)[N],
1505  const typename DocumentType::Ch* defaultValue)
1506 {
1507  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1508 }
1509 
1510 #if RAPIDJSON_HAS_STDSTRING
1511 template <typename DocumentType, typename CharType, size_t N>
1512 typename DocumentType::ValueType&
1513 GetValueByPointerWithDefault(DocumentType& document, const CharType (&source)[N],
1514  const std::basic_string<typename DocumentType::Ch>& defaultValue)
1515 {
1516  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1517 }
1518 #endif
1519 
1520 template <typename DocumentType, typename CharType, size_t N, typename T2>
1521 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >),
1522  (typename DocumentType::ValueType&))
1523 GetValueByPointerWithDefault(DocumentType& document, const CharType (&source)[N], T2 defaultValue)
1524 {
1525  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1526 }
1527 
1529 
1530 template <typename T>
1531 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer,
1532  typename T::ValueType& value, typename T::AllocatorType& a)
1533 {
1534  return pointer.Set(root, value, a);
1535 }
1536 
1537 template <typename T>
1538 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer,
1539  const typename T::ValueType& value, typename T::AllocatorType& a)
1540 {
1541  return pointer.Set(root, value, a);
1542 }
1543 
1544 template <typename T>
1545 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer,
1546  const typename T::Ch* value, typename T::AllocatorType& a)
1547 {
1548  return pointer.Set(root, value, a);
1549 }
1550 
1551 #if RAPIDJSON_HAS_STDSTRING
1552 template <typename T>
1553 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer,
1554  const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a)
1555 {
1556  return pointer.Set(root, value, a);
1557 }
1558 #endif
1559 
1560 template <typename T, typename T2>
1561 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >),
1562  (typename T::ValueType&))
1563 SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 value, typename T::AllocatorType& a)
1564 {
1565  return pointer.Set(root, value, a);
1566 }
1567 
1568 template <typename T, typename CharType, size_t N>
1569 typename T::ValueType& SetValueByPointer(T& root, const CharType (&source)[N], typename T::ValueType& value,
1570  typename T::AllocatorType& a)
1571 {
1572  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1573 }
1574 
1575 template <typename T, typename CharType, size_t N>
1576 typename T::ValueType& SetValueByPointer(T& root, const CharType (&source)[N], const typename T::ValueType& value,
1577  typename T::AllocatorType& a)
1578 {
1579  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1580 }
1581 
1582 template <typename T, typename CharType, size_t N>
1583 typename T::ValueType& SetValueByPointer(T& root, const CharType (&source)[N], const typename T::Ch* value,
1584  typename T::AllocatorType& a)
1585 {
1586  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1587 }
1588 
1589 #if RAPIDJSON_HAS_STDSTRING
1590 template <typename T, typename CharType, size_t N>
1591 typename T::ValueType& SetValueByPointer(T& root, const CharType (&source)[N],
1592  const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a)
1593 {
1594  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1595 }
1596 #endif
1597 
1598 template <typename T, typename CharType, size_t N, typename T2>
1599 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >),
1600  (typename T::ValueType&))
1601 SetValueByPointer(T& root, const CharType (&source)[N], T2 value, typename T::AllocatorType& a)
1602 {
1603  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1604 }
1605 
1606 // No allocator parameter
1607 
1608 template <typename DocumentType>
1609 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
1611  typename DocumentType::ValueType& value)
1612 {
1613  return pointer.Set(document, value);
1614 }
1615 
1616 template <typename DocumentType>
1617 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
1619  const typename DocumentType::ValueType& value)
1620 {
1621  return pointer.Set(document, value);
1622 }
1623 
1624 template <typename DocumentType>
1625 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
1627  const typename DocumentType::Ch* value)
1628 {
1629  return pointer.Set(document, value);
1630 }
1631 
1632 #if RAPIDJSON_HAS_STDSTRING
1633 template <typename DocumentType>
1634 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document,
1636  const std::basic_string<typename DocumentType::Ch>& value)
1637 {
1638  return pointer.Set(document, value);
1639 }
1640 #endif
1641 
1642 template <typename DocumentType, typename T2>
1643 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >),
1644  (typename DocumentType::ValueType&))
1645 SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 value)
1646 {
1647  return pointer.Set(document, value);
1648 }
1649 
1650 template <typename DocumentType, typename CharType, size_t N>
1651 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType (&source)[N],
1652  typename DocumentType::ValueType& value)
1653 {
1654  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1655 }
1656 
1657 template <typename DocumentType, typename CharType, size_t N>
1658 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType (&source)[N],
1659  const typename DocumentType::ValueType& value)
1660 {
1661  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1662 }
1663 
1664 template <typename DocumentType, typename CharType, size_t N>
1665 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType (&source)[N],
1666  const typename DocumentType::Ch* value)
1667 {
1668  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1669 }
1670 
1671 #if RAPIDJSON_HAS_STDSTRING
1672 template <typename DocumentType, typename CharType, size_t N>
1673 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType (&source)[N],
1674  const std::basic_string<typename DocumentType::Ch>& value)
1675 {
1676  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1677 }
1678 #endif
1679 
1680 template <typename DocumentType, typename CharType, size_t N, typename T2>
1681 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >),
1682  (typename DocumentType::ValueType&))
1683 SetValueByPointer(DocumentType& document, const CharType (&source)[N], T2 value)
1684 {
1685  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1686 }
1687 
1689 
1690 template <typename T>
1691 typename T::ValueType& swapValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer,
1692  typename T::ValueType& value, typename T::AllocatorType& a)
1693 {
1694  return pointer.Swap(root, value, a);
1695 }
1696 
1697 template <typename T, typename CharType, size_t N>
1698 typename T::ValueType& swapValueByPointer(T& root, const CharType (&source)[N], typename T::ValueType& value,
1699  typename T::AllocatorType& a)
1700 {
1701  return GenericPointer<typename T::ValueType>(source, N - 1).Swap(root, value, a);
1702 }
1703 
1704 template <typename DocumentType>
1705 typename DocumentType::ValueType& swapValueByPointer(DocumentType& document,
1707  typename DocumentType::ValueType& value)
1708 {
1709  return pointer.Swap(document, value);
1710 }
1711 
1712 template <typename DocumentType, typename CharType, size_t N>
1713 typename DocumentType::ValueType& swapValueByPointer(DocumentType& document, const CharType (&source)[N],
1714  typename DocumentType::ValueType& value)
1715 {
1716  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Swap(document, value);
1717 }
1718 
1720 
1721 template <typename T>
1723 {
1724  return pointer.Erase(root);
1725 }
1726 
1727 template <typename T, typename CharType, size_t N>
1728 bool EraseValueByPointer(T& root, const CharType (&source)[N])
1729 {
1730  return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root);
1731 }
1732 
1734 
1736 
1737 #if defined(__clang__) || defined(_MSC_VER)
1738 RAPIDJSON_DIAG_POP
1739 #endif
1740 
1741 #endif // RAPIDJSON_POINTER_H_
GenericPointer(const Token *tokens, size_t tokenCount)
Constructor with user-supplied tokens.
Definition: pointer.h:202
T::ValueType & GetValueByPointerWithDefault(T &root, const GenericPointer< typename T::ValueType > &pointer, const typename T::ValueType &defaultValue, typename T::AllocatorType &a)
Definition: pointer.h:1393
char * u64toa(uint64_t value, char *buffer)
Definition: itoa.h:133
Encoding conversion.
Definition: encodings.h:817
const CharType(& source)[N]
Definition: pointer.h:1454
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:394
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:416
object
Definition: rapidjson.h:671
Read-only string stream.
Definition: fwd.h:56
Ch * nameBuffer_
A buffer containing all names in tokens.
Definition: pointer.h:1318
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:126
array
Definition: rapidjson.h:672
ValueType::EncodingType EncodingType
Encoding type from Value.
Definition: pointer.h:83
Invalid percent encoding in URI fragment.
Definition: pointer.h:43
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:168
XmlRpcServer s
PointerParseErrorCode parseErrorCode_
Parsing error code.
Definition: pointer.h:1322
GenericPointer(const GenericPointer &rhs)
Copy constructor.
Definition: pointer.h:214
Token * tokens_
A list of tokens.
Definition: pointer.h:1319
static RAPIDJSON_NAMESPACE_BEGIN const SizeType kPointerInvalidIndex
Represents an invalid index in GenericPointer::Token.
Definition: pointer.h:31
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:336
SizeType index
A valid array index, if it is not equal to kPointerInvalidIndex.
Definition: pointer.h:103
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:121
T::ValueType & swapValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition: pointer.h:1691
A token is the basic units of internal representation.
Definition: pointer.h:99
A document for parsing JSON text as DOM.
Definition: document.h:57
A token must begin with a &#39;/&#39;.
Definition: pointer.h:41
A read-write string stream.
Definition: fwd.h:61
SizeType length
Length of the name.
Definition: pointer.h:102
GenericPointer(const Ch *source, Allocator *allocator=0)
Constructor that parses a string or URI fragment representation.
Definition: pointer.h:127
size_t parseErrorOffset_
Offset in code unit when parsing fail.
Definition: pointer.h:1321
UTF-8 encoding.
Definition: encodings.h:96
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition: rapidjson.h:649
friend void swap(GenericPointer &a, GenericPointer &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition: pointer.h:301
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition: fwd.h:137
GenericPointer & operator=(const GenericPointer &rhs)
Assignment operator.
Definition: pointer.h:249
A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence.
Definition: pointer.h:1295
GenericPointer< Value > Pointer
GenericPointer for Value (UTF-8, default allocator).
Definition: pointer.h:1326
PercentEncodeStream(OutputStream &os)
Definition: pointer.h:1298
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.
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:3259
size_t tokenCount_
Number of tokens in tokens_.
Definition: pointer.h:1320
void Swap(T &a, T &b) RAPIDJSON_NOEXCEPT
Custom swap() to avoid dependency on C++ <algorithm> header.
Definition: swap.h:33
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:653
char * u32toa(uint32_t value, char *buffer)
Definition: itoa.h:39
T::ValueType & CreateValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::AllocatorType &a)
Definition: pointer.h:1334
GenericPointer(const GenericPointer &rhs, Allocator *allocator)
Copy constructor.
Definition: pointer.h:227
Allocator * allocator
Definition: pointer.h:351
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1422
ValueType::Ch Ch
Character type from Value.
Definition: pointer.h:84
const Ch * name
Name of the token. It has null character at the end but it can contain null character.
Definition: pointer.h:101
PointerParseErrorCode
Error code of parsing.
Definition: pointer.h:37
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1563
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
Definition: pointer.h:317
GenericPointer & Swap(GenericPointer &other) RAPIDJSON_NOEXCEPT
Swap the content of this pointer with an other.
Definition: pointer.h:277
bool EraseValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer)
Definition: pointer.h:1722
const GenericPointer< typename T::ValueType > T2 defaultValue
Definition: pointer.h:1420
SizeType StrLen(const Ch *s)
Custom strlen() which works on different character types.
Definition: strfunc.h:31
Reference to a constant string (not taking a copy)
Definition: document.h:334
The parse is successful.
Definition: pointer.h:39
size_t PutEnd(Ch *begin)
Definition: stream.h:291
Allocator * allocator_
The current allocator. It is either user-supplied or equal to ownAllocator_.
Definition: pointer.h:1316
const GenericPointer< typename T::ValueType > & pointer
Definition: pointer.h:1420
Type
Type of JSON value.
Definition: rapidjson.h:666
size_t Tell() const
Definition: stream.h:210
A character must percent encoded in URI fragment.
Definition: pointer.h:44
Allocator * ownAllocator_
Allocator owned by this Pointer.
Definition: pointer.h:1317
T::ValueType & SetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition: pointer.h:1531
GenericPointer(Allocator *allocator=0)
Default constructor.
Definition: pointer.h:110
T::ValueType * GetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, size_t *unresolvedTokenIndex=0)
Definition: pointer.h:1364
~GenericPointer()
Destructor.
Definition: pointer.h:240


xbot_talker
Author(s): wangxiaoyun
autogenerated on Sat Oct 10 2020 03:27:53