pointer.h
Go to the documentation of this file.
1 // Tencent is pleased to support the open source community by making RapidJSON
2 // available.
3 //
4 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All
5 // rights reserved.
6 //
7 // Licensed under the MIT License (the "License"); you may not use this file
8 // except in compliance with the License. You may obtain a copy of the License
9 // at
10 //
11 // http://opensource.org/licenses/MIT
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16 // License for the specific language governing permissions and limitations under
17 // the License.
18 
19 #ifndef RAPIDJSON_POINTER_H_
20 #define RAPIDJSON_POINTER_H_
21 
22 #include "document.h"
23 #include "internal/itoa.h"
24 
25 #ifdef __clang__
26 RAPIDJSON_DIAG_PUSH
27 RAPIDJSON_DIAG_OFF(switch - enum)
28 #elif defined(_MSC_VER)
29 RAPIDJSON_DIAG_PUSH
30 RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
31 #endif
32 
34 
36  ~SizeType(0);
37 
39 
44 
52 };
54 
56 // GenericPointer
57 
60 
89 template <typename ValueType, typename Allocator = CrtAllocator>
90 class GenericPointer {
91  public:
92  typedef typename ValueType::EncodingType
94  typedef typename ValueType::Ch Ch;
95 
97 
110  struct Token {
111  const Ch
112  *name;
113  SizeType length;
116  };
118 
120 
121 
123  GenericPointer(Allocator *allocator = 0)
125  ownAllocator_(),
126  nameBuffer_(),
127  tokens_(),
128  tokenCount_(),
131 
133 
138  explicit GenericPointer(const Ch *source, Allocator *allocator = 0)
140  ownAllocator_(),
141  nameBuffer_(),
142  tokens_(),
143  tokenCount_(),
146  Parse(source, internal::StrLen(source));
147  }
148 
149 #if RAPIDJSON_HAS_STDSTRING
150 
157  explicit GenericPointer(const std::basic_string<Ch> &source,
158  Allocator *allocator = 0)
160  ownAllocator_(),
161  nameBuffer_(),
162  tokens_(),
163  tokenCount_(),
166  Parse(source.c_str(), source.size());
167  }
168 #endif
169 
172 
179  GenericPointer(const Ch *source, size_t length, Allocator *allocator = 0)
181  ownAllocator_(),
182  nameBuffer_(),
183  tokens_(),
184  tokenCount_(),
187  Parse(source, length);
188  }
189 
191 
212  GenericPointer(const Token *tokens, size_t tokenCount)
213  : allocator_(),
214  ownAllocator_(),
215  nameBuffer_(),
216  tokens_(const_cast<Token *>(tokens)),
217  tokenCount_(tokenCount),
220 
223  : allocator_(rhs.allocator_),
224  ownAllocator_(),
225  nameBuffer_(),
226  tokens_(),
227  tokenCount_(),
230  *this = rhs;
231  }
232 
234  GenericPointer(const GenericPointer &rhs, Allocator *allocator)
235  : allocator_(allocator),
236  ownAllocator_(),
237  nameBuffer_(),
238  tokens_(),
239  tokenCount_(),
242  *this = rhs;
243  }
244 
247  if (nameBuffer_) // If user-supplied tokens constructor is used,
248  // nameBuffer_
249  // is nullptr and tokens_ are not deallocated.
250  Allocator::Free(tokens_);
252  }
253 
256  if (this != &rhs) {
257  // Do not delete ownAllcator
258  if (nameBuffer_) Allocator::Free(tokens_);
259 
260  tokenCount_ = rhs.tokenCount_;
263 
264  if (rhs.nameBuffer_)
265  CopyFromRaw(rhs); // Normally parsed tokens.
266  else {
267  tokens_ = rhs.tokens_; // User supplied const tokens.
268  nameBuffer_ = 0;
269  }
270  }
271  return *this;
272  }
273 
275 
279  GenericPointer &Swap(GenericPointer &other) RAPIDJSON_NOEXCEPT {
280  internal::Swap(allocator_, other.allocator_);
281  internal::Swap(ownAllocator_, other.ownAllocator_);
282  internal::Swap(nameBuffer_, other.nameBuffer_);
283  internal::Swap(tokens_, other.tokens_);
284  internal::Swap(tokenCount_, other.tokenCount_);
285  internal::Swap(parseErrorOffset_, other.parseErrorOffset_);
286  internal::Swap(parseErrorCode_, other.parseErrorCode_);
287  return *this;
288  }
289 
291 
300  friend inline void swap(GenericPointer &a,
301  GenericPointer &b) RAPIDJSON_NOEXCEPT {
302  a.Swap(b);
303  }
304 
306 
308 
309 
311 
316  GenericPointer Append(const Token &token, Allocator *allocator = 0) const {
317  GenericPointer r;
318  r.allocator_ = allocator;
319  Ch *p = r.CopyFromRaw(*this, 1, token.length + 1);
320  std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch));
321  r.tokens_[tokenCount_].name = p;
322  r.tokens_[tokenCount_].length = token.length;
323  r.tokens_[tokenCount_].index = token.index;
324  return r;
325  }
326 
328 
335  Allocator *allocator = 0) const {
336  Token token = {name, length, kPointerInvalidIndex};
337  return Append(token, allocator);
338  }
339 
341 
346  template <typename T>
348  (internal::NotExpr<
349  internal::IsSame<typename internal::RemoveConst<T>::Type, Ch>>),
350  (GenericPointer))
351  Append(T *name, Allocator *allocator = 0) const {
352  return Append(name, internal::StrLen(name), allocator);
353  }
354 
355 #if RAPIDJSON_HAS_STDSTRING
356 
362  GenericPointer Append(const std::basic_string<Ch> &name,
363  Allocator *allocator = 0) const {
364  return Append(name.c_str(), static_cast<SizeType>(name.size()), allocator);
365  }
366 #endif
367 
369 
374  GenericPointer Append(SizeType index, Allocator *allocator = 0) const {
375  char buffer[21];
376  char *end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer)
377  : internal::u64toa(index, buffer);
378  SizeType length = static_cast<SizeType>(end - buffer);
379  buffer[length] = '\0';
380 
381  if (sizeof(Ch) == 1) {
382  Token token = {reinterpret_cast<Ch *>(buffer), length, index};
383  return Append(token, allocator);
384  } else {
385  Ch name[21];
386  for (size_t i = 0; i <= length; i++) name[i] = static_cast<Ch>(buffer[i]);
387  Token token = {name, length, index};
388  return Append(token, allocator);
389  }
390  }
391 
393 
398  GenericPointer Append(const ValueType &token,
399  Allocator *allocator = 0) const {
400  if (token.IsString())
401  return Append(token.GetString(), token.GetStringLength(), allocator);
402  else {
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  if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_)
446  return false;
447 
448  for (size_t i = 0; i < tokenCount_; i++) {
449  if (tokens_[i].index != rhs.tokens_[i].index ||
450  tokens_[i].length != rhs.tokens_[i].length ||
451  (tokens_[i].length != 0 &&
452  std::memcmp(tokens_[i].name, rhs.tokens_[i].name,
453  sizeof(Ch) * tokens_[i].length) != 0)) {
454  return false;
455  }
456  }
457 
458  return true;
459  }
460 
462 
465  bool operator!=(const GenericPointer &rhs) const { return !(*this == rhs); }
466 
468 
471  bool operator<(const GenericPointer &rhs) const {
472  if (!IsValid()) return false;
473  if (!rhs.IsValid()) return true;
474 
475  if (tokenCount_ != rhs.tokenCount_) return tokenCount_ < rhs.tokenCount_;
476 
477  for (size_t i = 0; i < tokenCount_; i++) {
478  if (tokens_[i].index != rhs.tokens_[i].index)
479  return tokens_[i].index < rhs.tokens_[i].index;
480 
481  if (tokens_[i].length != rhs.tokens_[i].length)
482  return tokens_[i].length < rhs.tokens_[i].length;
483 
484  if (int cmp = std::memcmp(tokens_[i].name, rhs.tokens_[i].name,
485  sizeof(Ch) * tokens_[i].length))
486  return cmp < 0;
487  }
488 
489  return false;
490  }
491 
493 
495 
496 
498 
502  template <typename OutputStream>
503  bool Stringify(OutputStream &os) const {
504  return Stringify<false, OutputStream>(os);
505  }
506 
508 
512  template <typename OutputStream>
513  bool StringifyUriFragment(OutputStream &os) const {
514  return Stringify<true, OutputStream>(os);
515  }
516 
518 
520 
521 
523 
539  ValueType &Create(ValueType &root,
540  typename ValueType::AllocatorType &allocator,
541  bool *alreadyExist = 0) const {
542  RAPIDJSON_ASSERT(IsValid());
543  ValueType *v = &root;
544  bool exist = true;
545  for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
546  if (v->IsArray() && t->name[0] == '-' && t->length == 1) {
547  v->PushBack(ValueType().Move(), allocator);
548  v = &((*v)[v->Size() - 1]);
549  exist = false;
550  } else {
551  if (t->index == kPointerInvalidIndex) { // must be object name
552  if (!v->IsObject()) v->SetObject(); // Change to Object
553  } else { // object name or array index
554  if (!v->IsArray() && !v->IsObject())
555  v->SetArray(); // Change to Array
556  }
557 
558  if (v->IsArray()) {
559  if (t->index >= v->Size()) {
560  v->Reserve(t->index + 1, allocator);
561  while (t->index >= v->Size())
562  v->PushBack(ValueType().Move(), allocator);
563  exist = false;
564  }
565  v = &((*v)[t->index]);
566  } else {
567  typename ValueType::MemberIterator m =
568  v->FindMember(GenericValue<EncodingType>(
569  GenericStringRef<Ch>(t->name, t->length)));
570  if (m == v->MemberEnd()) {
571  v->AddMember(ValueType(t->name, t->length, allocator).Move(),
572  ValueType().Move(), allocator);
573  m = v->MemberEnd();
574  v = &(--m)->value; // Assumes AddMember() appends at the end
575  exist = false;
576  } else
577  v = &m->value;
578  }
579  }
580  }
581 
582  if (alreadyExist) *alreadyExist = exist;
583 
584  return *v;
585  }
586 
588 
593  template <typename stackAllocator>
594  ValueType &Create(
595  GenericDocument<EncodingType, typename ValueType::AllocatorType,
596  stackAllocator> &document,
597  bool *alreadyExist = 0) const {
598  return Create(document, document.GetAllocator(), alreadyExist);
599  }
600 
602 
604 
605 
607 
622  ValueType *Get(ValueType &root, size_t *unresolvedTokenIndex = 0) const {
623  RAPIDJSON_ASSERT(IsValid());
624  ValueType *v = &root;
625  for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
626  switch (v->GetType()) {
627  case kObjectType: {
628  typename ValueType::MemberIterator m =
629  v->FindMember(GenericValue<EncodingType>(
630  GenericStringRef<Ch>(t->name, t->length)));
631  if (m == v->MemberEnd()) break;
632  v = &m->value;
633  }
634  continue;
635  case kArrayType:
636  if (t->index == kPointerInvalidIndex || t->index >= v->Size()) break;
637  v = &((*v)[t->index]);
638  continue;
639  default:
640  break;
641  }
642 
643  // Error: unresolved token
644  if (unresolvedTokenIndex)
645  *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
646  return 0;
647  }
648  return v;
649  }
650 
652 
657  const ValueType *Get(const ValueType &root,
658  size_t *unresolvedTokenIndex = 0) const {
659  return Get(const_cast<ValueType &>(root), unresolvedTokenIndex);
660  }
661 
663 
665 
666 
668 
678  ValueType &GetWithDefault(
679  ValueType &root, const ValueType &defaultValue,
680  typename ValueType::AllocatorType &allocator) const {
681  bool alreadyExist;
682  ValueType &v = Create(root, allocator, &alreadyExist);
683  return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
684  }
685 
687  ValueType &GetWithDefault(
688  ValueType &root, const Ch *defaultValue,
689  typename ValueType::AllocatorType &allocator) const {
690  bool alreadyExist;
691  ValueType &v = Create(root, allocator, &alreadyExist);
692  return alreadyExist ? v : v.SetString(defaultValue, allocator);
693  }
694 
695 #if RAPIDJSON_HAS_STDSTRING
696  ValueType &GetWithDefault(
698  ValueType &root, const std::basic_string<Ch> &defaultValue,
699  typename ValueType::AllocatorType &allocator) const {
700  bool alreadyExist;
701  ValueType &v = Create(root, allocator, &alreadyExist);
702  return alreadyExist ? v : v.SetString(defaultValue, allocator);
703  }
704 #endif
705 
707 
711  template <typename T>
713  (internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>),
714  (ValueType &))
715  GetWithDefault(ValueType &root, T defaultValue,
716  typename ValueType::AllocatorType &allocator) const {
717  return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);
718  }
719 
721  template <typename stackAllocator>
722  ValueType &GetWithDefault(
723  GenericDocument<EncodingType, typename ValueType::AllocatorType,
724  stackAllocator> &document,
725  const ValueType &defaultValue) const {
726  return GetWithDefault(document, defaultValue, document.GetAllocator());
727  }
728 
730  template <typename stackAllocator>
731  ValueType &GetWithDefault(
732  GenericDocument<EncodingType, typename ValueType::AllocatorType,
733  stackAllocator> &document,
734  const Ch *defaultValue) const {
735  return GetWithDefault(document, defaultValue, document.GetAllocator());
736  }
737 
738 #if RAPIDJSON_HAS_STDSTRING
739  template <typename stackAllocator>
741  ValueType &GetWithDefault(
742  GenericDocument<EncodingType, typename ValueType::AllocatorType,
743  stackAllocator> &document,
744  const std::basic_string<Ch> &defaultValue) const {
745  return GetWithDefault(document, defaultValue, document.GetAllocator());
746  }
747 #endif
748 
750 
754  template <typename T, typename stackAllocator>
756  (internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>),
757  (ValueType &))
758  GetWithDefault(
759  GenericDocument<EncodingType, typename ValueType::AllocatorType,
760  stackAllocator> &document,
761  T defaultValue) const {
762  return GetWithDefault(document, defaultValue, document.GetAllocator());
763  }
764 
766 
768 
769 
771 
781  ValueType &Set(ValueType &root, ValueType &value,
782  typename ValueType::AllocatorType &allocator) const {
783  return Create(root, allocator) = value;
784  }
785 
787  ValueType &Set(ValueType &root, const ValueType &value,
788  typename ValueType::AllocatorType &allocator) const {
789  return Create(root, allocator).CopyFrom(value, allocator);
790  }
791 
793  ValueType &Set(ValueType &root, const Ch *value,
794  typename ValueType::AllocatorType &allocator) const {
795  return Create(root, allocator) = ValueType(value, allocator).Move();
796  }
797 
798 #if RAPIDJSON_HAS_STDSTRING
799  ValueType &Set(ValueType &root, const std::basic_string<Ch> &value,
801  typename ValueType::AllocatorType &allocator) const {
802  return Create(root, allocator) = ValueType(value, allocator).Move();
803  }
804 #endif
805 
807 
811  template <typename T>
813  (internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>),
814  (ValueType &))
815  Set(ValueType &root, T value,
816  typename ValueType::AllocatorType &allocator) const {
817  return Create(root, allocator) = ValueType(value).Move();
818  }
819 
821  template <typename stackAllocator>
822  ValueType &Set(
823  GenericDocument<EncodingType, typename ValueType::AllocatorType,
824  stackAllocator> &document,
825  ValueType &value) const {
826  return Create(document) = value;
827  }
828 
830  template <typename stackAllocator>
831  ValueType &Set(
832  GenericDocument<EncodingType, typename ValueType::AllocatorType,
833  stackAllocator> &document,
834  const ValueType &value) const {
835  return Create(document).CopyFrom(value, document.GetAllocator());
836  }
837 
839  template <typename stackAllocator>
840  ValueType &Set(
841  GenericDocument<EncodingType, typename ValueType::AllocatorType,
842  stackAllocator> &document,
843  const Ch *value) const {
844  return Create(document) = ValueType(value, document.GetAllocator()).Move();
845  }
846 
847 #if RAPIDJSON_HAS_STDSTRING
848  template <typename stackAllocator>
850  ValueType &Set(
851  GenericDocument<EncodingType, typename ValueType::AllocatorType,
852  stackAllocator> &document,
853  const std::basic_string<Ch> &value) const {
854  return Create(document) = ValueType(value, document.GetAllocator()).Move();
855  }
856 #endif
857 
859 
863  template <typename T, typename stackAllocator>
865  (internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>),
866  (ValueType &))
867  Set(GenericDocument<EncodingType, typename ValueType::AllocatorType,
868  stackAllocator> &document,
869  T value) const {
870  return Create(document) = value;
871  }
872 
874 
876 
877 
879 
889  ValueType &Swap(ValueType &root, ValueType &value,
890  typename ValueType::AllocatorType &allocator) const {
891  return Create(root, allocator).Swap(value);
892  }
893 
895  template <typename stackAllocator>
896  ValueType &Swap(
897  GenericDocument<EncodingType, typename ValueType::AllocatorType,
898  stackAllocator> &document,
899  ValueType &value) const {
900  return Create(document).Swap(value);
901  }
902 
904 
906 
914  bool Erase(ValueType &root) const {
915  RAPIDJSON_ASSERT(IsValid());
916  if (tokenCount_ == 0) // Cannot erase the root
917  return false;
918 
919  ValueType *v = &root;
920  const Token *last = tokens_ + (tokenCount_ - 1);
921  for (const Token *t = tokens_; t != last; ++t) {
922  switch (v->GetType()) {
923  case kObjectType: {
924  typename ValueType::MemberIterator m =
925  v->FindMember(GenericValue<EncodingType>(
926  GenericStringRef<Ch>(t->name, t->length)));
927  if (m == v->MemberEnd()) return false;
928  v = &m->value;
929  } break;
930  case kArrayType:
931  if (t->index == kPointerInvalidIndex || t->index >= v->Size())
932  return false;
933  v = &((*v)[t->index]);
934  break;
935  default:
936  return false;
937  }
938  }
939 
940  switch (v->GetType()) {
941  case kObjectType:
942  return v->EraseMember(GenericStringRef<Ch>(last->name, last->length));
943  case kArrayType:
944  if (last->index == kPointerInvalidIndex || last->index >= v->Size())
945  return false;
946  v->Erase(v->Begin() + last->index);
947  return true;
948  default:
949  return false;
950  }
951  }
952 
953  private:
955 
962  Ch *CopyFromRaw(const GenericPointer &rhs, size_t extraToken = 0,
963  size_t extraNameBufferSize = 0) {
964  if (!allocator_) // allocator is independently owned.
965  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
966 
967  size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens
968  for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)
969  nameBufferSize += t->length;
970 
971  tokenCount_ = rhs.tokenCount_ + extraToken;
972  tokens_ = static_cast<Token *>(allocator_->Malloc(
973  tokenCount_ * sizeof(Token) +
974  (nameBufferSize + extraNameBufferSize) * sizeof(Ch)));
975  nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
976  if (rhs.tokenCount_ > 0) {
977  std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token));
978  }
979  if (nameBufferSize > 0) {
980  std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
981  }
982 
983  // Adjust pointers to name buffer
984  std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;
985  for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t)
986  t->name += diff;
987 
988  return nameBuffer_ + nameBufferSize;
989  }
990 
992 
996  bool NeedPercentEncode(Ch c) const {
997  return !((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') ||
998  (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' ||
999  c == '~');
1000  }
1001 
1003 #ifndef __clang__ // -Wdocumentation
1004 
1012 #endif
1013  void Parse(const Ch *source, size_t length) {
1014  RAPIDJSON_ASSERT(source != NULL);
1016  RAPIDJSON_ASSERT(tokens_ == 0);
1017 
1018  // Create own allocator if user did not supply.
1019  if (!allocator_) ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
1020 
1021  // Count number of '/' as tokenCount
1022  tokenCount_ = 0;
1023  for (const Ch *s = source; s != source + length; s++)
1024  if (*s == '/') tokenCount_++;
1025 
1026  Token *token = tokens_ = static_cast<Token *>(
1027  allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch)));
1028  Ch *name = nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
1029  size_t i = 0;
1030 
1031  // Detect if it is a URI fragment
1032  bool uriFragment = false;
1033  if (source[i] == '#') {
1034  uriFragment = true;
1035  i++;
1036  }
1037 
1038  if (i != length && source[i] != '/') {
1040  goto error;
1041  }
1042 
1043  while (i < length) {
1044  RAPIDJSON_ASSERT(source[i] == '/');
1045  i++; // consumes '/'
1046 
1047  token->name = name;
1048  bool isNumber = true;
1049 
1050  while (i < length && source[i] != '/') {
1051  Ch c = source[i];
1052  if (uriFragment) {
1053  // Decoding percent-encoding for URI fragment
1054  if (c == '%') {
1055  PercentDecodeStream is(&source[i], source + length);
1057  Ch *begin = os.PutBegin();
1058  if (!Transcoder<UTF8<>, EncodingType>().Validate(is, os) ||
1059  !is.IsValid()) {
1061  goto error;
1062  }
1063  size_t len = os.PutEnd(begin);
1064  i += is.Tell() - 1;
1065  if (len == 1)
1066  c = *name;
1067  else {
1068  name += len;
1069  isNumber = false;
1070  i++;
1071  continue;
1072  }
1073  } else if (NeedPercentEncode(c)) {
1075  goto error;
1076  }
1077  }
1078 
1079  i++;
1080 
1081  // Escaping "~0" -> '~', "~1" -> '/'
1082  if (c == '~') {
1083  if (i < length) {
1084  c = source[i];
1085  if (c == '0')
1086  c = '~';
1087  else if (c == '1')
1088  c = '/';
1089  else {
1091  goto error;
1092  }
1093  i++;
1094  } else {
1096  goto error;
1097  }
1098  }
1099 
1100  // First check for index: all of characters are digit
1101  if (c < '0' || c > '9') isNumber = false;
1102 
1103  *name++ = c;
1104  }
1105  token->length = static_cast<SizeType>(name - token->name);
1106  if (token->length == 0) isNumber = false;
1107  *name++ = '\0'; // Null terminator
1108 
1109  // Second check for index: more than one digit cannot have leading zero
1110  if (isNumber && token->length > 1 && token->name[0] == '0')
1111  isNumber = false;
1112 
1113  // String to SizeType conversion
1114  SizeType n = 0;
1115  if (isNumber) {
1116  for (size_t j = 0; j < token->length; j++) {
1117  SizeType m = n * 10 + static_cast<SizeType>(token->name[j] - '0');
1118  if (m < n) { // overflow detection
1119  isNumber = false;
1120  break;
1121  }
1122  n = m;
1123  }
1124  }
1125 
1126  token->index = isNumber ? n : kPointerInvalidIndex;
1127  token++;
1128  }
1129 
1130  RAPIDJSON_ASSERT(name <=
1131  nameBuffer_ + length); // Should not overflow buffer
1133  return;
1134 
1135  error:
1136  Allocator::Free(tokens_);
1137  nameBuffer_ = 0;
1138  tokens_ = 0;
1139  tokenCount_ = 0;
1140  parseErrorOffset_ = i;
1141  return;
1142  }
1143 
1145 
1150  template <bool uriFragment, typename OutputStream>
1151  bool Stringify(OutputStream &os) const {
1152  RAPIDJSON_ASSERT(IsValid());
1153 
1154  if (uriFragment) os.Put('#');
1155 
1156  for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
1157  os.Put('/');
1158  for (size_t j = 0; j < t->length; j++) {
1159  Ch c = t->name[j];
1160  if (c == '~') {
1161  os.Put('~');
1162  os.Put('0');
1163  } else if (c == '/') {
1164  os.Put('~');
1165  os.Put('1');
1166  } else if (uriFragment && NeedPercentEncode(c)) {
1167  // Transcode to UTF8 sequence
1169  &t->name[j]);
1171  if (!Transcoder<EncodingType, UTF8<>>().Validate(source, target))
1172  return false;
1173  j += source.Tell() - 1;
1174  } else
1175  os.Put(c);
1176  }
1177  }
1178  return true;
1179  }
1180 
1182 
1187  class PercentDecodeStream {
1188  public:
1189  typedef typename ValueType::Ch Ch;
1190 
1192 
1196  PercentDecodeStream(const Ch *source, const Ch *end)
1197  : src_(source), head_(source), end_(end), valid_(true) {}
1198 
1199  Ch Take() {
1200  if (*src_ != '%' || src_ + 3 > end_) { // %XY triplet
1201  valid_ = false;
1202  return 0;
1203  }
1204  src_++;
1205  Ch c = 0;
1206  for (int j = 0; j < 2; j++) {
1207  c = static_cast<Ch>(c << 4);
1208  Ch h = *src_;
1209  if (h >= '0' && h <= '9')
1210  c = static_cast<Ch>(c + h - '0');
1211  else if (h >= 'A' && h <= 'F')
1212  c = static_cast<Ch>(c + h - 'A' + 10);
1213  else if (h >= 'a' && h <= 'f')
1214  c = static_cast<Ch>(c + h - 'a' + 10);
1215  else {
1216  valid_ = false;
1217  return 0;
1218  }
1219  src_++;
1220  }
1221  return c;
1222  }
1223 
1224  size_t Tell() const { return static_cast<size_t>(src_ - head_); }
1225  bool IsValid() const { return valid_; }
1226 
1227  private:
1228  const Ch *src_;
1229  const Ch *head_;
1230  const Ch *end_;
1231  bool valid_;
1232  };
1233 
1236  template <typename OutputStream>
1238  public:
1239  PercentEncodeStream(OutputStream &os) : os_(os) {}
1240  void Put(char c) { // UTF-8 must be byte
1241  unsigned char u = static_cast<unsigned char>(c);
1242  static const char hexDigits[16] = {'0', '1', '2', '3', '4', '5',
1243  '6', '7', '8', '9', 'A', 'B',
1244  'C', 'D', 'E', 'F'};
1245  os_.Put('%');
1246  os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u >> 4]));
1247  os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u & 15]));
1248  }
1249 
1250  private:
1251  OutputStream &os_;
1252  };
1253 
1254  Allocator *allocator_;
1255  Allocator *ownAllocator_;
1259  size_t tokenCount_;
1262 };
1263 
1266 
1268 
1269 
1271 
1272 template <typename T>
1273 typename T::ValueType &CreateValueByPointer(
1275  typename T::AllocatorType &a) {
1276  return pointer.Create(root, a);
1277 }
1278 
1279 template <typename T, typename CharType, size_t N>
1280 typename T::ValueType &CreateValueByPointer(T &root,
1281  const CharType (&source)[N],
1282  typename T::AllocatorType &a) {
1283  return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a);
1284 }
1285 
1286 // No allocator parameter
1287 
1288 template <typename DocumentType>
1289 typename DocumentType::ValueType &CreateValueByPointer(
1290  DocumentType &document,
1292  return pointer.Create(document);
1293 }
1294 
1295 template <typename DocumentType, typename CharType, size_t N>
1296 typename DocumentType::ValueType &CreateValueByPointer(
1297  DocumentType &document, const CharType (&source)[N]) {
1299  .Create(document);
1300 }
1301 
1303 
1304 template <typename T>
1305 typename T::ValueType *GetValueByPointer(
1307  size_t *unresolvedTokenIndex = 0) {
1308  return pointer.Get(root, unresolvedTokenIndex);
1309 }
1310 
1311 template <typename T>
1312 const typename T::ValueType *GetValueByPointer(
1313  const T &root, const GenericPointer<typename T::ValueType> &pointer,
1314  size_t *unresolvedTokenIndex = 0) {
1315  return pointer.Get(root, unresolvedTokenIndex);
1316 }
1317 
1318 template <typename T, typename CharType, size_t N>
1319 typename T::ValueType *GetValueByPointer(T &root, const CharType (&source)[N],
1320  size_t *unresolvedTokenIndex = 0) {
1322  .Get(root, unresolvedTokenIndex);
1323 }
1324 
1325 template <typename T, typename CharType, size_t N>
1326 const typename T::ValueType *GetValueByPointer(
1327  const T &root, const CharType (&source)[N],
1328  size_t *unresolvedTokenIndex = 0) {
1330  .Get(root, unresolvedTokenIndex);
1331 }
1332 
1334 
1335 template <typename T>
1336 typename T::ValueType &GetValueByPointerWithDefault(
1338  const typename T::ValueType &defaultValue, typename T::AllocatorType &a) {
1339  return pointer.GetWithDefault(root, defaultValue, a);
1340 }
1341 
1342 template <typename T>
1343 typename T::ValueType &GetValueByPointerWithDefault(
1345  const typename T::Ch *defaultValue, typename T::AllocatorType &a) {
1346  return pointer.GetWithDefault(root, defaultValue, a);
1347 }
1348 
1349 #if RAPIDJSON_HAS_STDSTRING
1350 template <typename T>
1351 typename T::ValueType &GetValueByPointerWithDefault(
1353  const std::basic_string<typename T::Ch> &defaultValue,
1354  typename T::AllocatorType &a) {
1355  return pointer.GetWithDefault(root, defaultValue, a);
1356 }
1357 #endif
1358 
1359 template <typename T, typename T2>
1361  (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1362  (typename T::ValueType &))
1364  T &root, const GenericPointer<typename T::ValueType> &pointer,
1365  T2 defaultValue, typename T::AllocatorType &a) {
1366  return pointer.GetWithDefault(root, defaultValue, a);
1367 }
1368 
1369 template <typename T, typename CharType, size_t N>
1370 typename T::ValueType &GetValueByPointerWithDefault(
1371  T &root, const CharType (&source)[N],
1372  const typename T::ValueType &defaultValue, typename T::AllocatorType &a) {
1374  .GetWithDefault(root, defaultValue, a);
1375 }
1376 
1377 template <typename T, typename CharType, size_t N>
1378 typename T::ValueType &GetValueByPointerWithDefault(
1379  T &root, const CharType (&source)[N], const typename T::Ch *defaultValue,
1380  typename T::AllocatorType &a) {
1382  .GetWithDefault(root, defaultValue, a);
1383 }
1384 
1385 #if RAPIDJSON_HAS_STDSTRING
1386 template <typename T, typename CharType, size_t N>
1387 typename T::ValueType &GetValueByPointerWithDefault(
1388  T &root, const CharType (&source)[N],
1389  const std::basic_string<typename T::Ch> &defaultValue,
1390  typename T::AllocatorType &a) {
1392  .GetWithDefault(root, defaultValue, a);
1393 }
1394 #endif
1395 
1396 template <typename T, typename CharType, size_t N, typename T2>
1398  (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1399  (typename T::ValueType &))
1400 GetValueByPointerWithDefault(T &root, const CharType (&source)[N],
1401  T2 defaultValue, typename T::AllocatorType &a) {
1403  .GetWithDefault(root, defaultValue, a);
1404 }
1405 
1406 // No allocator parameter
1407 
1408 template <typename DocumentType>
1409 typename DocumentType::ValueType &GetValueByPointerWithDefault(
1410  DocumentType &document,
1412  const typename DocumentType::ValueType &defaultValue) {
1413  return pointer.GetWithDefault(document, defaultValue);
1414 }
1415 
1416 template <typename DocumentType>
1417 typename DocumentType::ValueType &GetValueByPointerWithDefault(
1418  DocumentType &document,
1420  const typename DocumentType::Ch *defaultValue) {
1421  return pointer.GetWithDefault(document, defaultValue);
1422 }
1423 
1424 #if RAPIDJSON_HAS_STDSTRING
1425 template <typename DocumentType>
1426 typename DocumentType::ValueType &GetValueByPointerWithDefault(
1427  DocumentType &document,
1429  const std::basic_string<typename DocumentType::Ch> &defaultValue) {
1430  return pointer.GetWithDefault(document, defaultValue);
1431 }
1432 #endif
1433 
1434 template <typename DocumentType, typename T2>
1436  (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1437  (typename DocumentType::ValueType &))
1439  DocumentType &document,
1441  T2 defaultValue) {
1442  return pointer.GetWithDefault(document, defaultValue);
1443 }
1444 
1445 template <typename DocumentType, typename CharType, size_t N>
1446 typename DocumentType::ValueType &GetValueByPointerWithDefault(
1447  DocumentType &document, const CharType (&source)[N],
1448  const typename DocumentType::ValueType &defaultValue) {
1450  .GetWithDefault(document, defaultValue);
1451 }
1452 
1453 template <typename DocumentType, typename CharType, size_t N>
1454 typename DocumentType::ValueType &GetValueByPointerWithDefault(
1455  DocumentType &document, const CharType (&source)[N],
1456  const typename DocumentType::Ch *defaultValue) {
1458  .GetWithDefault(document, defaultValue);
1459 }
1460 
1461 #if RAPIDJSON_HAS_STDSTRING
1462 template <typename DocumentType, typename CharType, size_t N>
1463 typename DocumentType::ValueType &GetValueByPointerWithDefault(
1464  DocumentType &document, const CharType (&source)[N],
1465  const std::basic_string<typename DocumentType::Ch> &defaultValue) {
1467  .GetWithDefault(document, defaultValue);
1468 }
1469 #endif
1470 
1471 template <typename DocumentType, typename CharType, size_t N, typename T2>
1473  (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1474  (typename DocumentType::ValueType &))
1475 GetValueByPointerWithDefault(DocumentType &document,
1476  const CharType (&source)[N], T2 defaultValue) {
1478  .GetWithDefault(document, defaultValue);
1479 }
1480 
1482 
1483 template <typename T>
1484 typename T::ValueType &SetValueByPointer(
1485  T &root, const GenericPointer<typename T::ValueType> &pointer,
1486  typename T::ValueType &value, typename T::AllocatorType &a) {
1487  return pointer.Set(root, value, a);
1488 }
1489 
1490 template <typename T>
1491 typename T::ValueType &SetValueByPointer(
1492  T &root, const GenericPointer<typename T::ValueType> &pointer,
1493  const typename T::ValueType &value, typename T::AllocatorType &a) {
1494  return pointer.Set(root, value, a);
1495 }
1496 
1497 template <typename T>
1498 typename T::ValueType &SetValueByPointer(
1499  T &root, const GenericPointer<typename T::ValueType> &pointer,
1500  const typename T::Ch *value, typename T::AllocatorType &a) {
1501  return pointer.Set(root, value, a);
1502 }
1503 
1504 #if RAPIDJSON_HAS_STDSTRING
1505 template <typename T>
1506 typename T::ValueType &SetValueByPointer(
1507  T &root, const GenericPointer<typename T::ValueType> &pointer,
1508  const std::basic_string<typename T::Ch> &value,
1509  typename T::AllocatorType &a) {
1510  return pointer.Set(root, value, a);
1511 }
1512 #endif
1513 
1514 template <typename T, typename T2>
1516  (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1517  (typename T::ValueType &))
1518 SetValueByPointer(T &root, const GenericPointer<typename T::ValueType> &pointer,
1519  T2 value, typename T::AllocatorType &a) {
1520  return pointer.Set(root, value, a);
1521 }
1522 
1523 template <typename T, typename CharType, size_t N>
1524 typename T::ValueType &SetValueByPointer(T &root, const CharType (&source)[N],
1525  typename T::ValueType &value,
1526  typename T::AllocatorType &a) {
1528  .Set(root, value, a);
1529 }
1530 
1531 template <typename T, typename CharType, size_t N>
1532 typename T::ValueType &SetValueByPointer(T &root, const CharType (&source)[N],
1533  const typename T::ValueType &value,
1534  typename T::AllocatorType &a) {
1536  .Set(root, value, a);
1537 }
1538 
1539 template <typename T, typename CharType, size_t N>
1540 typename T::ValueType &SetValueByPointer(T &root, const CharType (&source)[N],
1541  const typename T::Ch *value,
1542  typename T::AllocatorType &a) {
1544  .Set(root, value, a);
1545 }
1546 
1547 #if RAPIDJSON_HAS_STDSTRING
1548 template <typename T, typename CharType, size_t N>
1549 typename T::ValueType &SetValueByPointer(
1550  T &root, const CharType (&source)[N],
1551  const std::basic_string<typename T::Ch> &value,
1552  typename T::AllocatorType &a) {
1554  .Set(root, value, a);
1555 }
1556 #endif
1557 
1558 template <typename T, typename CharType, size_t N, typename T2>
1560  (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1561  (typename T::ValueType &))
1562 SetValueByPointer(T &root, const CharType (&source)[N], T2 value,
1563  typename T::AllocatorType &a) {
1565  .Set(root, value, a);
1566 }
1567 
1568 // No allocator parameter
1569 
1570 template <typename DocumentType>
1571 typename DocumentType::ValueType &SetValueByPointer(
1572  DocumentType &document,
1574  typename DocumentType::ValueType &value) {
1575  return pointer.Set(document, value);
1576 }
1577 
1578 template <typename DocumentType>
1579 typename DocumentType::ValueType &SetValueByPointer(
1580  DocumentType &document,
1582  const typename DocumentType::ValueType &value) {
1583  return pointer.Set(document, value);
1584 }
1585 
1586 template <typename DocumentType>
1587 typename DocumentType::ValueType &SetValueByPointer(
1588  DocumentType &document,
1590  const typename DocumentType::Ch *value) {
1591  return pointer.Set(document, value);
1592 }
1593 
1594 #if RAPIDJSON_HAS_STDSTRING
1595 template <typename DocumentType>
1596 typename DocumentType::ValueType &SetValueByPointer(
1597  DocumentType &document,
1599  const std::basic_string<typename DocumentType::Ch> &value) {
1600  return pointer.Set(document, value);
1601 }
1602 #endif
1603 
1604 template <typename DocumentType, typename T2>
1606  (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1607  (typename DocumentType::ValueType &))
1609  DocumentType &document,
1610  const GenericPointer<typename DocumentType::ValueType> &pointer, T2 value) {
1611  return pointer.Set(document, value);
1612 }
1613 
1614 template <typename DocumentType, typename CharType, size_t N>
1615 typename DocumentType::ValueType &SetValueByPointer(
1616  DocumentType &document, const CharType (&source)[N],
1617  typename DocumentType::ValueType &value) {
1619  .Set(document, value);
1620 }
1621 
1622 template <typename DocumentType, typename CharType, size_t N>
1623 typename DocumentType::ValueType &SetValueByPointer(
1624  DocumentType &document, const CharType (&source)[N],
1625  const typename DocumentType::ValueType &value) {
1627  .Set(document, value);
1628 }
1629 
1630 template <typename DocumentType, typename CharType, size_t N>
1631 typename DocumentType::ValueType &SetValueByPointer(
1632  DocumentType &document, const CharType (&source)[N],
1633  const typename DocumentType::Ch *value) {
1635  .Set(document, value);
1636 }
1637 
1638 #if RAPIDJSON_HAS_STDSTRING
1639 template <typename DocumentType, typename CharType, size_t N>
1640 typename DocumentType::ValueType &SetValueByPointer(
1641  DocumentType &document, const CharType (&source)[N],
1642  const std::basic_string<typename DocumentType::Ch> &value) {
1644  .Set(document, value);
1645 }
1646 #endif
1647 
1648 template <typename DocumentType, typename CharType, size_t N, typename T2>
1650  (internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2>>),
1651  (typename DocumentType::ValueType &))
1652 SetValueByPointer(DocumentType &document, const CharType (&source)[N],
1653  T2 value) {
1655  .Set(document, value);
1656 }
1657 
1659 
1660 template <typename T>
1661 typename T::ValueType &SwapValueByPointer(
1662  T &root, const GenericPointer<typename T::ValueType> &pointer,
1663  typename T::ValueType &value, typename T::AllocatorType &a) {
1664  return pointer.Swap(root, value, a);
1665 }
1666 
1667 template <typename T, typename CharType, size_t N>
1668 typename T::ValueType &SwapValueByPointer(T &root, const CharType (&source)[N],
1669  typename T::ValueType &value,
1670  typename T::AllocatorType &a) {
1672  .Swap(root, value, a);
1673 }
1674 
1675 template <typename DocumentType>
1676 typename DocumentType::ValueType &SwapValueByPointer(
1677  DocumentType &document,
1679  typename DocumentType::ValueType &value) {
1680  return pointer.Swap(document, value);
1681 }
1682 
1683 template <typename DocumentType, typename CharType, size_t N>
1684 typename DocumentType::ValueType &SwapValueByPointer(
1685  DocumentType &document, const CharType (&source)[N],
1686  typename DocumentType::ValueType &value) {
1688  .Swap(document, value);
1689 }
1690 
1692 
1693 template <typename T>
1694 bool EraseValueByPointer(T &root,
1695  const GenericPointer<typename T::ValueType> &pointer) {
1696  return pointer.Erase(root);
1697 }
1698 
1699 template <typename T, typename CharType, size_t N>
1700 bool EraseValueByPointer(T &root, const CharType (&source)[N]) {
1701  return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root);
1702 }
1703 
1705 
1707 
1708 #if defined(__clang__) || defined(_MSC_VER)
1709 RAPIDJSON_DIAG_POP
1710 #endif
1711 
1712 #endif // RAPIDJSON_POINTER_H_
GenericPointer(const Token *tokens, size_t tokenCount)
Constructor with user-supplied tokens.
Definition: pointer.h:212
T::ValueType & GetValueByPointerWithDefault(T &root, const GenericPointer< typename T::ValueType > &pointer, const typename T::ValueType &defaultValue, typename T::AllocatorType &a)
Definition: pointer.h:1336
char * u64toa(uint64_t value, char *buffer)
Definition: itoa.h:124
Encoding conversion.
Definition: encodings.h:750
const CharType(& source)[N]
Definition: pointer.h:1400
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:411
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:433
object
Definition: rapidjson.h:711
Read-only string stream.
Definition: fwd.h:60
Ch * nameBuffer_
A buffer containing all names in tokens.
Definition: pointer.h:1257
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:131
TFSIMD_FORCE_INLINE bool operator==(const Matrix3x3 &m1, const Matrix3x3 &m2)
array
Definition: rapidjson.h:712
ValueType::EncodingType EncodingType
Encoding type from Value.
Definition: pointer.h:93
GenericPointer(const Ch *source, size_t length, Allocator *allocator=0)
Definition: pointer.h:179
XmlRpcServer s
PointerParseErrorCode parseErrorCode_
Parsing error code.
Definition: pointer.h:1261
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:59
GenericPointer(const GenericPointer &rhs)
Copy constructor.
Definition: pointer.h:222
Token * tokens_
A list of tokens.
Definition: pointer.h:1258
static RAPIDJSON_NAMESPACE_BEGIN const SizeType kPointerInvalidIndex
Represents an invalid index in GenericPointer::Token.
Definition: pointer.h:35
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:334
T::ValueType & SwapValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition: pointer.h:1661
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:128
A token is the basic units of internal representation.
Definition: pointer.h:110
A document for parsing JSON text as DOM.
Definition: document.h:62
A read-write string stream.
Definition: fwd.h:65
SizeType length
Length of the name.
Definition: pointer.h:114
GenericPointer(const Ch *source, Allocator *allocator=0)
Constructor that parses a string or URI fragment representation.
Definition: pointer.h:138
size_t parseErrorOffset_
Offset in code unit when parsing fail.
Definition: pointer.h:1260
UTF-8 encoding.
Definition: encodings.h:102
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition: rapidjson.h:690
friend void swap(GenericPointer &a, GenericPointer &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition: pointer.h:300
GenericPointer & operator=(const GenericPointer &rhs)
Assignment operator.
Definition: pointer.h:255
GenericPointer< Value > Pointer
GenericPointer for Value (UTF-8, default allocator).
Definition: pointer.h:1265
PercentEncodeStream(OutputStream &os)
Definition: pointer.h:1239
size_t tokenCount_
Number of tokens in tokens_.
Definition: pointer.h:1259
TFSIMD_FORCE_INLINE bool operator!=(const Vector3 &other) const
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.
void Swap(T &a, T &b) RAPIDJSON_NOEXCEPT
Custom swap() to avoid dependency on C++ <algorithm> header.
Definition: swap.h:37
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:694
char * u32toa(uint32_t value, char *buffer)
Definition: itoa.h:46
T::ValueType & CreateValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::AllocatorType &a)
Definition: pointer.h:1273
GenericPointer(const GenericPointer &rhs, Allocator *allocator)
Copy constructor.
Definition: pointer.h:234
Allocator * allocator
Definition: pointer.h:351
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1365
ValueType::Ch Ch
Character type from Value.
Definition: pointer.h:94
const Ch * name
Definition: pointer.h:112
PointerParseErrorCode
Error code of parsing.
Definition: pointer.h:42
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1518
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
Definition: pointer.h:316
GenericPointer & Swap(GenericPointer &other) RAPIDJSON_NOEXCEPT
Swap the content of this pointer with an other.
Definition: pointer.h:279
bool EraseValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer)
Definition: pointer.h:1694
const GenericPointer< typename T::ValueType > T2 defaultValue
Definition: pointer.h:1364
SizeType StrLen(const Ch *s)
Custom strlen() which works on different character types.
Definition: strfunc.h:36
Reference to a constant string (not taking a copy)
Definition: document.h:322
The parse is successful.
Definition: pointer.h:43
size_t PutEnd(Ch *begin)
Definition: stream.h:217
Allocator * allocator_
Definition: pointer.h:1254
const GenericPointer< typename T::ValueType > & pointer
Definition: pointer.h:1364
Type
Type of JSON value.
Definition: rapidjson.h:707
size_t Tell() const
Definition: stream.h:167
Allocator * ownAllocator_
Allocator owned by this Pointer.
Definition: pointer.h:1256
T::ValueType & SetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition: pointer.h:1484
GenericPointer(Allocator *allocator=0)
Default constructor.
Definition: pointer.h:123
T::ValueType * GetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, size_t *unresolvedTokenIndex=0)
Definition: pointer.h:1305
~GenericPointer()
Destructor.
Definition: pointer.h:246


livox_ros_driver
Author(s): Livox Dev Team
autogenerated on Mon Mar 15 2021 02:40:46