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 #ifdef __clang__
22 RAPIDJSON_DIAG_PUSH
23 RAPIDJSON_DIAG_OFF(switch-enum)
24 #endif
25 
26 #ifdef _MSC_VER
27 RAPIDJSON_DIAG_PUSH
28 RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
29 #endif
30 
32 
34 
36 
41 
46 };
47 
49 // GenericPointer
50 
52 
80 template <typename ValueType, typename Allocator = CrtAllocator>
81 class GenericPointer {
82 public:
83  typedef typename ValueType::EncodingType EncodingType;
84  typedef typename ValueType::Ch Ch;
85 
87 
99  struct Token {
100  const Ch* name;
103  };
104 
106 
107 
110 
112 
117  Parse(source, internal::StrLen(source));
118  }
119 
120 #if RAPIDJSON_HAS_STDSTRING
121 
128  Parse(source.c_str(), source.size());
129  }
130 #endif
131 
133 
140  Parse(source, length);
141  }
142 
144 
165  GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
166 
169  *this = rhs;
170  }
171 
174  if (nameBuffer_) // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and tokens_ are not deallocated.
175  Allocator::Free(tokens_);
177  }
178 
181  if (this != &rhs) {
182  // Do not delete ownAllcator
183  if (nameBuffer_)
184  Allocator::Free(tokens_);
185 
186  tokenCount_ = rhs.tokenCount_;
189 
190  if (rhs.nameBuffer_)
191  CopyFromRaw(rhs); // Normally parsed tokens.
192  else {
193  tokens_ = rhs.tokens_; // User supplied const tokens.
194  nameBuffer_ = 0;
195  }
196  }
197  return *this;
198  }
199 
201 
203 
204 
206 
211  GenericPointer Append(const Token& token, Allocator* allocator = 0) const {
212  GenericPointer r;
213  r.allocator_ = allocator;
214  Ch *p = r.CopyFromRaw(*this, 1, token.length + 1);
215  std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch));
216  r.tokens_[tokenCount_].name = p;
217  r.tokens_[tokenCount_].length = token.length;
218  r.tokens_[tokenCount_].index = token.index;
219  return r;
220  }
221 
223 
229  GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const {
230  Token token = { name, length, kPointerInvalidIndex };
231  return Append(token, allocator);
232  }
233 
235 
240  template <typename T>
241  RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >), (GenericPointer))
242  Append(T* name, Allocator* allocator = 0) const {
243  return Append(name, internal::StrLen(name), allocator);
244  }
245 
246 #if RAPIDJSON_HAS_STDSTRING
247 
253  GenericPointer Append(const std::basic_string<Ch>& name, Allocator* allocator = 0) const {
254  return Append(name.c_str(), static_cast<SizeType>(name.size()), allocator);
255  }
256 #endif
257 
259 
264  GenericPointer Append(SizeType index, Allocator* allocator = 0) const {
265  char buffer[21];
266  char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer);
267  SizeType length = static_cast<SizeType>(end - buffer);
268  buffer[length] = '\0';
269 
270  if (sizeof(Ch) == 1) {
271  Token token = { reinterpret_cast<Ch*>(buffer), length, index };
272  return Append(token, allocator);
273  }
274  else {
275  Ch name[21];
276  for (size_t i = 0; i <= length; i++)
277  name[i] = static_cast<Ch>(buffer[i]);
278  Token token = { name, length, index };
279  return Append(token, allocator);
280  }
281  }
282 
284 
289  GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const {
290  if (token.IsString())
291  return Append(token.GetString(), token.GetStringLength(), allocator);
292  else {
293  RAPIDJSON_ASSERT(token.IsUint64());
294  RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0));
295  return Append(static_cast<SizeType>(token.GetUint64()), allocator);
296  }
297  }
298 
300 
301 
303  bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; }
304 
306  size_t GetParseErrorOffset() const { return parseErrorOffset_; }
307 
309  PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; }
310 
312 
314  Allocator& GetAllocator() { return *allocator_; }
315 
317 
318 
320  const Token* GetTokens() const { return tokens_; }
321 
323  size_t GetTokenCount() const { return tokenCount_; }
324 
326 
328 
329 
331 
334  bool operator==(const GenericPointer& rhs) const {
335  if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_)
336  return false;
337 
338  for (size_t i = 0; i < tokenCount_; i++) {
339  if (tokens_[i].index != rhs.tokens_[i].index ||
340  tokens_[i].length != rhs.tokens_[i].length ||
341  (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch)* tokens_[i].length) != 0))
342  {
343  return false;
344  }
345  }
346 
347  return true;
348  }
349 
351 
354  bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }
355 
357 
359 
360 
362 
366  template<typename OutputStream>
367  bool Stringify(OutputStream& os) const {
368  return Stringify<false, OutputStream>(os);
369  }
370 
372 
376  template<typename OutputStream>
377  bool StringifyUriFragment(OutputStream& os) const {
378  return Stringify<true, OutputStream>(os);
379  }
380 
382 
384 
385 
387 
401  ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const {
402  RAPIDJSON_ASSERT(IsValid());
403  ValueType* v = &root;
404  bool exist = true;
405  for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
406  if (v->IsArray() && t->name[0] == '-' && t->length == 1) {
407  v->PushBack(ValueType().Move(), allocator);
408  v = &((*v)[v->Size() - 1]);
409  exist = false;
410  }
411  else {
412  if (t->index == kPointerInvalidIndex) { // must be object name
413  if (!v->IsObject())
414  v->SetObject(); // Change to Object
415  }
416  else { // object name or array index
417  if (!v->IsArray() && !v->IsObject())
418  v->SetArray(); // Change to Array
419  }
420 
421  if (v->IsArray()) {
422  if (t->index >= v->Size()) {
423  v->Reserve(t->index + 1, allocator);
424  while (t->index >= v->Size())
425  v->PushBack(ValueType().Move(), allocator);
426  exist = false;
427  }
428  v = &((*v)[t->index]);
429  }
430  else {
431  typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
432  if (m == v->MemberEnd()) {
433  v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
434  v = &(--v->MemberEnd())->value; // Assumes AddMember() appends at the end
435  exist = false;
436  }
437  else
438  v = &m->value;
439  }
440  }
441  }
442 
443  if (alreadyExist)
444  *alreadyExist = exist;
445 
446  return *v;
447  }
448 
450 
455  template <typename stackAllocator>
456  ValueType& Create(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, bool* alreadyExist = 0) const {
457  return Create(document, document.GetAllocator(), alreadyExist);
458  }
459 
461 
463 
464 
466 
479  ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const {
480  RAPIDJSON_ASSERT(IsValid());
481  ValueType* v = &root;
482  for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
483  switch (v->GetType()) {
484  case kObjectType:
485  {
486  typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
487  if (m == v->MemberEnd())
488  break;
489  v = &m->value;
490  }
491  continue;
492  case kArrayType:
493  if (t->index == kPointerInvalidIndex || t->index >= v->Size())
494  break;
495  v = &((*v)[t->index]);
496  continue;
497  default:
498  break;
499  }
500 
501  // Error: unresolved token
502  if (unresolvedTokenIndex)
503  *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
504  return 0;
505  }
506  return v;
507  }
508 
510 
514  const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const {
515  return Get(const_cast<ValueType&>(root), unresolvedTokenIndex);
516  }
517 
519 
521 
522 
524 
533  ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const {
534  bool alreadyExist;
535  Value& v = Create(root, allocator, &alreadyExist);
536  return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
537  }
538 
540  ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const {
541  bool alreadyExist;
542  Value& v = Create(root, allocator, &alreadyExist);
543  return alreadyExist ? v : v.SetString(defaultValue, allocator);
544  }
545 
546 #if RAPIDJSON_HAS_STDSTRING
547  ValueType& GetWithDefault(ValueType& root, const std::basic_string<Ch>& defaultValue, typename ValueType::AllocatorType& allocator) const {
549  bool alreadyExist;
550  Value& v = Create(root, allocator, &alreadyExist);
551  return alreadyExist ? v : v.SetString(defaultValue, allocator);
552  }
553 #endif
554 
556 
559  template <typename T>
560  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
561  GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator) const {
562  return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);
563  }
564 
566  template <typename stackAllocator>
567  ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& defaultValue) const {
568  return GetWithDefault(document, defaultValue, document.GetAllocator());
569  }
570 
572  template <typename stackAllocator>
573  ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* defaultValue) const {
574  return GetWithDefault(document, defaultValue, document.GetAllocator());
575  }
576 
577 #if RAPIDJSON_HAS_STDSTRING
578  template <typename stackAllocator>
580  ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& defaultValue) const {
581  return GetWithDefault(document, defaultValue, document.GetAllocator());
582  }
583 #endif
584 
586 
589  template <typename T, typename stackAllocator>
590  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
591  GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T defaultValue) const {
592  return GetWithDefault(document, defaultValue, document.GetAllocator());
593  }
594 
596 
598 
599 
601 
610  ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
611  return Create(root, allocator) = value;
612  }
613 
615  ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const {
616  return Create(root, allocator).CopyFrom(value, allocator);
617  }
618 
620  ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const {
621  return Create(root, allocator) = ValueType(value, allocator).Move();
622  }
623 
624 #if RAPIDJSON_HAS_STDSTRING
625  ValueType& Set(ValueType& root, const std::basic_string<Ch>& value, typename ValueType::AllocatorType& allocator) const {
627  return Create(root, allocator) = ValueType(value, allocator).Move();
628  }
629 #endif
630 
632 
635  template <typename T>
636  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
637  Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const {
638  return Create(root, allocator) = ValueType(value).Move();
639  }
640 
642  template <typename stackAllocator>
644  return Create(document) = value;
645  }
646 
648  template <typename stackAllocator>
650  return Create(document).CopyFrom(value, document.GetAllocator());
651  }
652 
654  template <typename stackAllocator>
656  return Create(document) = ValueType(value, document.GetAllocator()).Move();
657  }
658 
659 #if RAPIDJSON_HAS_STDSTRING
660  template <typename stackAllocator>
663  return Create(document) = ValueType(value, document.GetAllocator()).Move();
664  }
665 #endif
666 
668 
671  template <typename T, typename stackAllocator>
672  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
673  Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T value) const {
674  return Create(document) = value;
675  }
676 
678 
680 
681 
683 
692  ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
693  return Create(root, allocator).Swap(value);
694  }
695 
697  template <typename stackAllocator>
699  return Create(document).Swap(value);
700  }
701 
703 
705 
711  bool Erase(ValueType& root) const {
712  RAPIDJSON_ASSERT(IsValid());
713  if (tokenCount_ == 0) // Cannot erase the root
714  return false;
715 
716  ValueType* v = &root;
717  const Token* last = tokens_ + (tokenCount_ - 1);
718  for (const Token *t = tokens_; t != last; ++t) {
719  switch (v->GetType()) {
720  case kObjectType:
721  {
722  typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
723  if (m == v->MemberEnd())
724  return false;
725  v = &m->value;
726  }
727  break;
728  case kArrayType:
729  if (t->index == kPointerInvalidIndex || t->index >= v->Size())
730  return false;
731  v = &((*v)[t->index]);
732  break;
733  default:
734  return false;
735  }
736  }
737 
738  switch (v->GetType()) {
739  case kObjectType:
740  return v->EraseMember(GenericStringRef<Ch>(last->name, last->length));
741  case kArrayType:
742  if (last->index == kPointerInvalidIndex || last->index >= v->Size())
743  return false;
744  v->Erase(v->Begin() + last->index);
745  return true;
746  default:
747  return false;
748  }
749  }
750 
751 private:
753 
759  Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0) {
760  if (!allocator_) // allocator is independently owned.
761  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
762 
763  size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens
764  for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)
765  nameBufferSize += t->length;
766 
767  tokenCount_ = rhs.tokenCount_ + extraToken;
768  tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch)));
769  nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
770  if (rhs.tokenCount_ > 0) {
771  std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token));
772  }
773  if (nameBufferSize > 0) {
774  std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
775  }
776 
777  // Adjust pointers to name buffer
778  std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;
779  for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t)
780  t->name += diff;
781 
782  return nameBuffer_ + nameBufferSize;
783  }
784 
786 
790  bool NeedPercentEncode(Ch c) const {
791  return !((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~');
792  }
793 
795 #ifndef __clang__ // -Wdocumentation
796 
801 #endif
802  void Parse(const Ch* source, size_t length) {
803  RAPIDJSON_ASSERT(source != NULL);
806 
807  // Create own allocator if user did not supply.
808  if (!allocator_)
809  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
810 
811  // Count number of '/' as tokenCount
812  tokenCount_ = 0;
813  for (const Ch* s = source; s != source + length; s++)
814  if (*s == '/')
815  tokenCount_++;
816 
817  Token* token = tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch)));
818  Ch* name = nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
819  size_t i = 0;
820 
821  // Detect if it is a URI fragment
822  bool uriFragment = false;
823  if (source[i] == '#') {
824  uriFragment = true;
825  i++;
826  }
827 
828  if (i != length && source[i] != '/') {
830  goto error;
831  }
832 
833  while (i < length) {
834  RAPIDJSON_ASSERT(source[i] == '/');
835  i++; // consumes '/'
836 
837  token->name = name;
838  bool isNumber = true;
839 
840  while (i < length && source[i] != '/') {
841  Ch c = source[i];
842  if (uriFragment) {
843  // Decoding percent-encoding for URI fragment
844  if (c == '%') {
845  PercentDecodeStream is(&source[i], source + length);
847  Ch* begin = os.PutBegin();
848  if (!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid()) {
850  goto error;
851  }
852  size_t len = os.PutEnd(begin);
853  i += is.Tell() - 1;
854  if (len == 1)
855  c = *name;
856  else {
857  name += len;
858  isNumber = false;
859  i++;
860  continue;
861  }
862  }
863  else if (NeedPercentEncode(c)) {
865  goto error;
866  }
867  }
868 
869  i++;
870 
871  // Escaping "~0" -> '~', "~1" -> '/'
872  if (c == '~') {
873  if (i < length) {
874  c = source[i];
875  if (c == '0') c = '~';
876  else if (c == '1') c = '/';
877  else {
879  goto error;
880  }
881  i++;
882  }
883  else {
885  goto error;
886  }
887  }
888 
889  // First check for index: all of characters are digit
890  if (c < '0' || c > '9')
891  isNumber = false;
892 
893  *name++ = c;
894  }
895  token->length = static_cast<SizeType>(name - token->name);
896  if (token->length == 0)
897  isNumber = false;
898  *name++ = '\0'; // Null terminator
899 
900  // Second check for index: more than one digit cannot have leading zero
901  if (isNumber && token->length > 1 && token->name[0] == '0')
902  isNumber = false;
903 
904  // String to SizeType conversion
905  SizeType n = 0;
906  if (isNumber) {
907  for (size_t j = 0; j < token->length; j++) {
908  SizeType m = n * 10 + static_cast<SizeType>(token->name[j] - '0');
909  if (m < n) { // overflow detection
910  isNumber = false;
911  break;
912  }
913  n = m;
914  }
915  }
916 
917  token->index = isNumber ? n : kPointerInvalidIndex;
918  token++;
919  }
920 
921  RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer
923  return;
924 
925  error:
926  Allocator::Free(tokens_);
927  nameBuffer_ = 0;
928  tokens_ = 0;
929  tokenCount_ = 0;
930  parseErrorOffset_ = i;
931  return;
932  }
933 
935 
940  template<bool uriFragment, typename OutputStream>
941  bool Stringify(OutputStream& os) const {
942  RAPIDJSON_ASSERT(IsValid());
943 
944  if (uriFragment)
945  os.Put('#');
946 
947  for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
948  os.Put('/');
949  for (size_t j = 0; j < t->length; j++) {
950  Ch c = t->name[j];
951  if (c == '~') {
952  os.Put('~');
953  os.Put('0');
954  }
955  else if (c == '/') {
956  os.Put('~');
957  os.Put('1');
958  }
959  else if (uriFragment && NeedPercentEncode(c)) {
960  // Transcode to UTF8 sequence
963  if (!Transcoder<EncodingType, UTF8<> >().Validate(source, target))
964  return false;
965  j += source.Tell() - 1;
966  }
967  else
968  os.Put(c);
969  }
970  }
971  return true;
972  }
973 
975 
981  public:
982  typedef typename ValueType::Ch Ch;
983 
985 
989  PercentDecodeStream(const Ch* source, const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {}
990 
991  Ch Take() {
992  if (*src_ != '%' || src_ + 3 > end_) { // %XY triplet
993  valid_ = false;
994  return 0;
995  }
996  src_++;
997  Ch c = 0;
998  for (int j = 0; j < 2; j++) {
999  c = static_cast<Ch>(c << 4);
1000  Ch h = *src_;
1001  if (h >= '0' && h <= '9') c = static_cast<Ch>(c + h - '0');
1002  else if (h >= 'A' && h <= 'F') c = static_cast<Ch>(c + h - 'A' + 10);
1003  else if (h >= 'a' && h <= 'f') c = static_cast<Ch>(c + h - 'a' + 10);
1004  else {
1005  valid_ = false;
1006  return 0;
1007  }
1008  src_++;
1009  }
1010  return c;
1011  }
1012 
1013  size_t Tell() const { return static_cast<size_t>(src_ - head_); }
1014  bool IsValid() const { return valid_; }
1015 
1016  private:
1017  const Ch* src_;
1018  const Ch* head_;
1019  const Ch* end_;
1020  bool valid_;
1021  };
1022 
1024  template <typename OutputStream>
1026  public:
1027  PercentEncodeStream(OutputStream& os) : os_(os) {}
1028  void Put(char c) { // UTF-8 must be byte
1029  unsigned char u = static_cast<unsigned char>(c);
1030  static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1031  os_.Put('%');
1032  os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u >> 4]));
1033  os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u & 15]));
1034  }
1035  private:
1036  OutputStream& os_;
1037  };
1038 
1039  Allocator* allocator_;
1040  Allocator* ownAllocator_;
1043  size_t tokenCount_;
1046 };
1047 
1050 
1052 
1053 
1055 
1056 template <typename T>
1057 typename T::ValueType& CreateValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::AllocatorType& a) {
1058  return pointer.Create(root, a);
1059 }
1060 
1061 template <typename T, typename CharType, size_t N>
1062 typename T::ValueType& CreateValueByPointer(T& root, const CharType(&source)[N], typename T::AllocatorType& a) {
1063  return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a);
1064 }
1065 
1066 // No allocator parameter
1067 
1068 template <typename DocumentType>
1069 typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer) {
1070  return pointer.Create(document);
1071 }
1072 
1073 template <typename DocumentType, typename CharType, size_t N>
1074 typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const CharType(&source)[N]) {
1075  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document);
1076 }
1077 
1079 
1080 template <typename T>
1081 typename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
1082  return pointer.Get(root, unresolvedTokenIndex);
1083 }
1084 
1085 template <typename T>
1086 const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
1087  return pointer.Get(root, unresolvedTokenIndex);
1088 }
1089 
1090 template <typename T, typename CharType, size_t N>
1091 typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) {
1092  return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1093 }
1094 
1095 template <typename T, typename CharType, size_t N>
1096 const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) {
1097  return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1098 }
1099 
1101 
1102 template <typename T>
1103 typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
1104  return pointer.GetWithDefault(root, defaultValue, a);
1105 }
1106 
1107 template <typename T>
1108 typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* defaultValue, typename T::AllocatorType& a) {
1109  return pointer.GetWithDefault(root, defaultValue, a);
1110 }
1111 
1112 #if RAPIDJSON_HAS_STDSTRING
1113 template <typename T>
1114 typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {
1115  return pointer.GetWithDefault(root, defaultValue, a);
1116 }
1117 #endif
1118 
1119 template <typename T, typename T2>
1120 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1121 GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 defaultValue, typename T::AllocatorType& a) {
1122  return pointer.GetWithDefault(root, defaultValue, a);
1123 }
1124 
1125 template <typename T, typename CharType, size_t N>
1126 typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
1127  return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1128 }
1129 
1130 template <typename T, typename CharType, size_t N>
1131 typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::Ch* defaultValue, typename T::AllocatorType& a) {
1132  return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1133 }
1134 
1135 #if RAPIDJSON_HAS_STDSTRING
1136 template <typename T, typename CharType, size_t N>
1137 typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {
1138  return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1139 }
1140 #endif
1141 
1142 template <typename T, typename CharType, size_t N, typename T2>
1143 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1144 GetValueByPointerWithDefault(T& root, const CharType(&source)[N], T2 defaultValue, typename T::AllocatorType& a) {
1145  return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1146 }
1147 
1148 // No allocator parameter
1149 
1150 template <typename DocumentType>
1151 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& defaultValue) {
1152  return pointer.GetWithDefault(document, defaultValue);
1153 }
1154 
1155 template <typename DocumentType>
1156 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* defaultValue) {
1157  return pointer.GetWithDefault(document, defaultValue);
1158 }
1159 
1160 #if RAPIDJSON_HAS_STDSTRING
1161 template <typename DocumentType>
1162 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1163  return pointer.GetWithDefault(document, defaultValue);
1164 }
1165 #endif
1166 
1167 template <typename DocumentType, typename T2>
1168 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1169 GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 defaultValue) {
1170  return pointer.GetWithDefault(document, defaultValue);
1171 }
1172 
1173 template <typename DocumentType, typename CharType, size_t N>
1174 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& defaultValue) {
1175  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1176 }
1177 
1178 template <typename DocumentType, typename CharType, size_t N>
1179 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* defaultValue) {
1180  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1181 }
1182 
1183 #if RAPIDJSON_HAS_STDSTRING
1184 template <typename DocumentType, typename CharType, size_t N>
1185 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1186  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1187 }
1188 #endif
1189 
1190 template <typename DocumentType, typename CharType, size_t N, typename T2>
1191 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1192 GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) {
1193  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1194 }
1195 
1197 
1198 template <typename T>
1199 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
1200  return pointer.Set(root, value, a);
1201 }
1202 
1203 template <typename T>
1204 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& value, typename T::AllocatorType& a) {
1205  return pointer.Set(root, value, a);
1206 }
1207 
1208 template <typename T>
1209 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* value, typename T::AllocatorType& a) {
1210  return pointer.Set(root, value, a);
1211 }
1212 
1213 #if RAPIDJSON_HAS_STDSTRING
1214 template <typename T>
1215 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {
1216  return pointer.Set(root, value, a);
1217 }
1218 #endif
1219 
1220 template <typename T, typename T2>
1221 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1222 SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 value, typename T::AllocatorType& a) {
1223  return pointer.Set(root, value, a);
1224 }
1225 
1226 template <typename T, typename CharType, size_t N>
1227 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
1228  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1229 }
1230 
1231 template <typename T, typename CharType, size_t N>
1232 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::ValueType& value, typename T::AllocatorType& a) {
1233  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1234 }
1235 
1236 template <typename T, typename CharType, size_t N>
1237 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::Ch* value, typename T::AllocatorType& a) {
1238  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1239 }
1240 
1241 #if RAPIDJSON_HAS_STDSTRING
1242 template <typename T, typename CharType, size_t N>
1243 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {
1244  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1245 }
1246 #endif
1247 
1248 template <typename T, typename CharType, size_t N, typename T2>
1249 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1250 SetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) {
1251  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1252 }
1253 
1254 // No allocator parameter
1255 
1256 template <typename DocumentType>
1257 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
1258  return pointer.Set(document, value);
1259 }
1260 
1261 template <typename DocumentType>
1262 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& value) {
1263  return pointer.Set(document, value);
1264 }
1265 
1266 template <typename DocumentType>
1267 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* value) {
1268  return pointer.Set(document, value);
1269 }
1270 
1271 #if RAPIDJSON_HAS_STDSTRING
1272 template <typename DocumentType>
1273 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& value) {
1274  return pointer.Set(document, value);
1275 }
1276 #endif
1277 
1278 template <typename DocumentType, typename T2>
1279 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1280 SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 value) {
1281  return pointer.Set(document, value);
1282 }
1283 
1284 template <typename DocumentType, typename CharType, size_t N>
1285 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
1286  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1287 }
1288 
1289 template <typename DocumentType, typename CharType, size_t N>
1290 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& value) {
1291  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1292 }
1293 
1294 template <typename DocumentType, typename CharType, size_t N>
1295 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* value) {
1296  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1297 }
1298 
1299 #if RAPIDJSON_HAS_STDSTRING
1300 template <typename DocumentType, typename CharType, size_t N>
1301 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& value) {
1302  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1303 }
1304 #endif
1305 
1306 template <typename DocumentType, typename CharType, size_t N, typename T2>
1307 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1308 SetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) {
1309  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1310 }
1311 
1313 
1314 template <typename T>
1315 typename T::ValueType& SwapValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
1316  return pointer.Swap(root, value, a);
1317 }
1318 
1319 template <typename T, typename CharType, size_t N>
1320 typename T::ValueType& SwapValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
1321  return GenericPointer<typename T::ValueType>(source, N - 1).Swap(root, value, a);
1322 }
1323 
1324 template <typename DocumentType>
1325 typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
1326  return pointer.Swap(document, value);
1327 }
1328 
1329 template <typename DocumentType, typename CharType, size_t N>
1330 typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
1331  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Swap(document, value);
1332 }
1333 
1335 
1336 template <typename T>
1338  return pointer.Erase(root);
1339 }
1340 
1341 template <typename T, typename CharType, size_t N>
1342 bool EraseValueByPointer(T& root, const CharType(&source)[N]) {
1343  return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root);
1344 }
1345 
1347 
1349 
1350 #ifdef __clang__
1351 RAPIDJSON_DIAG_POP
1352 #endif
1353 
1354 #ifdef _MSC_VER
1355 RAPIDJSON_DIAG_POP
1356 #endif
1357 
1358 #endif // RAPIDJSON_POINTER_H_
GenericPointer(const Token *tokens, size_t tokenCount)
Constructor with user-supplied tokens.
Definition: pointer.h:165
ValueType & Set(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, const ValueType &value) const
Set a value in a document, with copy semantics.
Definition: pointer.h:649
T::ValueType & GetValueByPointerWithDefault(T &root, const GenericPointer< typename T::ValueType > &pointer, const typename T::ValueType &defaultValue, typename T::AllocatorType &a)
Definition: pointer.h:1103
char * u64toa(uint64_t value, char *buffer)
Definition: itoa.h:123
ValueType & Set(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, const Ch *value) const
Set a null-terminated string in a document.
Definition: pointer.h:655
Encoding conversion.
Definition: encodings.h:658
const CharType(& source)[N]
Definition: pointer.h:1144
ValueType & Set(ValueType &root, const Ch *value, typename ValueType::AllocatorType &allocator) const
Set a null-terminated string in a subtree.
Definition: pointer.h:620
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:389
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:411
void Parse(const Ch *source, size_t length)
Parse a JSON String or its URI fragment representation into tokens.
Definition: pointer.h:802
object
Definition: rapidjson.h:620
Ch * CopyFromRaw(const GenericPointer &rhs, size_t extraToken=0, size_t extraNameBufferSize=0)
Clone the content from rhs to this.
Definition: pointer.h:759
Read-only string stream.
Definition: fwd.h:47
Ch * nameBuffer_
A buffer containing all names in tokens.
Definition: pointer.h:1041
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:124
array
Definition: rapidjson.h:621
ValueType & Set(ValueType &root, ValueType &value, typename ValueType::AllocatorType &allocator) const
Set a value in a subtree, with move semantics.
Definition: pointer.h:610
ValueType::EncodingType EncodingType
Encoding type from Value.
Definition: pointer.h:83
Invalid percent encoding in URI fragment.
Definition: pointer.h:44
ValueType & Set(ValueType &root, const ValueType &value, typename ValueType::AllocatorType &allocator) const
Set a value in a subtree, with copy semantics.
Definition: pointer.h:615
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:139
XmlRpcServer s
PointerParseErrorCode parseErrorCode_
Parsing error code.
Definition: pointer.h:1045
const Ch * head_
Original head of the string.
Definition: pointer.h:1018
PercentDecodeStream(const Ch *source, const Ch *end)
Constructor.
Definition: pointer.h:989
Token * tokens_
A list of tokens.
Definition: pointer.h:1042
static RAPIDJSON_NAMESPACE_BEGIN const SizeType kPointerInvalidIndex
Represents an invalid index in GenericPointer::Token.
Definition: pointer.h:33
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:229
A helper stream for decoding a percent-encoded sequence into code unit.
Definition: pointer.h:980
SizeType index
A valid array index, if it is not equal to kPointerInvalidIndex.
Definition: pointer.h:102
T::ValueType & SwapValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition: pointer.h:1315
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:121
A token is the basic units of internal representation.
Definition: pointer.h:99
A document for parsing JSON text as DOM.
Definition: document.h:70
A token must begin with a &#39;/&#39;.
Definition: pointer.h:42
A read-write string stream.
Definition: fwd.h:52
SizeType length
Length of the name.
Definition: pointer.h:101
bool valid_
Whether the parsing is valid.
Definition: pointer.h:1020
GenericPointer(const Ch *source, Allocator *allocator=0)
Constructor that parses a string or URI fragment representation.
Definition: pointer.h:116
size_t parseErrorOffset_
Offset in code unit when parsing fail.
Definition: pointer.h:1044
UTF-8 encoding.
Definition: encodings.h:96
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition: rapidjson.h:599
ValueType & Swap(ValueType &root, ValueType &value, typename ValueType::AllocatorType &allocator) const
Swap a value with a value in a subtree.
Definition: pointer.h:692
Allocator stackAllocator stackAllocator & document
Definition: pointer.h:591
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition: fwd.h:126
GenericPointer & operator=(const GenericPointer &rhs)
Assignment operator.
Definition: pointer.h:180
const Ch * end_
Past-the-end position.
Definition: pointer.h:1019
A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence.
Definition: pointer.h:1025
GenericPointer< Value > Pointer
GenericPointer for Value (UTF-8, default allocator).
Definition: pointer.h:1049
PercentEncodeStream(OutputStream &os)
Definition: pointer.h:1027
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:2383
size_t tokenCount_
Number of tokens in tokens_.
Definition: pointer.h:1043
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:603
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:1057
Allocator * allocator
Definition: pointer.h:242
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1121
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:100
PointerParseErrorCode
Error code of parsing.
Definition: pointer.h:39
GenericPointer(const GenericPointer &rhs, Allocator *allocator=0)
Copy constructor.
Definition: pointer.h:168
bool NeedPercentEncode(Ch c) const
Check whether a character should be percent-encoded.
Definition: pointer.h:790
#define T(x)
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
Definition: pointer.h:211
bool Erase(ValueType &root) const
Erase a value in a subtree.
Definition: pointer.h:711
bool EraseValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer)
Definition: pointer.h:1337
Allocator stackAllocator stackAllocator T defaultValue const
Definition: pointer.h:591
ValueType & Set(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, ValueType &value) const
Set a value in a document, with move semantics.
Definition: pointer.h:643
bool Stringify(OutputStream &os) const
Stringify to string or URI fragment representation.
Definition: pointer.h:941
const GenericPointer< typename T::ValueType > T2 defaultValue
Definition: pointer.h:1121
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:257
The parse is successful.
Definition: pointer.h:40
size_t PutEnd(Ch *begin)
Definition: stream.h:158
Allocator * allocator_
The current allocator. It is either user-supplied or equal to ownAllocator_.
Definition: pointer.h:1039
const GenericPointer< typename T::ValueType > & pointer
Definition: pointer.h:1121
Type
Type of JSON value.
Definition: rapidjson.h:616
size_t Tell() const
Definition: stream.h:117
A character must percent encoded in URI fragment.
Definition: pointer.h:45
Allocator * ownAllocator_
Allocator owned by this Pointer.
Definition: pointer.h:1040
T::ValueType & SetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition: pointer.h:1199
GenericPointer(Allocator *allocator=0)
Default constructor.
Definition: pointer.h:109
const Ch * src_
Current read position.
Definition: pointer.h:1017
T::ValueType * GetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, size_t *unresolvedTokenIndex=0)
Definition: pointer.h:1081
ValueType & Swap(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, ValueType &value) const
Swap a value with a value in a document.
Definition: pointer.h:698
~GenericPointer()
Destructor.
Definition: pointer.h:173


choreo_rapidjson
Author(s):
autogenerated on Thu Jul 18 2019 03:59:09