IN2OSM  1.0.1
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 #elif defined(_MSC_VER)
25 RAPIDJSON_DIAG_PUSH
26 RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
27 #endif
28 
30 
32 
34 
39 
44 };
45 
47 // GenericPointer
48 
50 
78 template <typename ValueType, typename Allocator = CrtAllocator>
79 class GenericPointer {
80 public:
81  typedef typename ValueType::EncodingType EncodingType;
82  typedef typename ValueType::Ch Ch;
83 
85 
97  struct Token {
98  const Ch* name;
101  };
102 
104 
105 
108 
110 
115  Parse(source, internal::StrLen(source));
116  }
117 
118 #if RAPIDJSON_HAS_STDSTRING
119 
126  Parse(source.c_str(), source.size());
127  }
128 #endif
129 
131 
138  Parse(source, length);
139  }
140 
142 
163  GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
164 
167  *this = rhs;
168  }
169 
172  *this = rhs;
173  }
174 
177  if (nameBuffer_) // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and tokens_ are not deallocated.
178  Allocator::Free(tokens_);
180  }
181 
184  if (this != &rhs) {
185  // Do not delete ownAllcator
186  if (nameBuffer_)
187  Allocator::Free(tokens_);
188 
189  tokenCount_ = rhs.tokenCount_;
192 
193  if (rhs.nameBuffer_)
194  CopyFromRaw(rhs); // Normally parsed tokens.
195  else {
196  tokens_ = rhs.tokens_; // User supplied const tokens.
197  nameBuffer_ = 0;
198  }
199  }
200  return *this;
201  }
202 
204 
208  GenericPointer& Swap(GenericPointer& other) RAPIDJSON_NOEXCEPT {
209  internal::Swap(allocator_, other.allocator_);
210  internal::Swap(ownAllocator_, other.ownAllocator_);
211  internal::Swap(nameBuffer_, other.nameBuffer_);
212  internal::Swap(tokens_, other.tokens_);
213  internal::Swap(tokenCount_, other.tokenCount_);
214  internal::Swap(parseErrorOffset_, other.parseErrorOffset_);
215  internal::Swap(parseErrorCode_, other.parseErrorCode_);
216  return *this;
217  }
218 
220 
231  friend inline void swap(GenericPointer& a, GenericPointer& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
232 
234 
236 
237 
239 
244  GenericPointer Append(const Token& token, Allocator* allocator = 0) const {
245  GenericPointer r;
246  r.allocator_ = allocator;
247  Ch *p = r.CopyFromRaw(*this, 1, token.length + 1);
248  std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch));
249  r.tokens_[tokenCount_].name = p;
250  r.tokens_[tokenCount_].length = token.length;
251  r.tokens_[tokenCount_].index = token.index;
252  return r;
253  }
254 
256 
262  GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const {
263  Token token = { name, length, kPointerInvalidIndex };
264  return Append(token, allocator);
265  }
266 
268 
273  template <typename T>
274  RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >), (GenericPointer))
275  Append(T* name, Allocator* allocator = 0) const {
276  return Append(name, internal::StrLen(name), allocator);
277  }
278 
279 #if RAPIDJSON_HAS_STDSTRING
280 
286  GenericPointer Append(const std::basic_string<Ch>& name, Allocator* allocator = 0) const {
287  return Append(name.c_str(), static_cast<SizeType>(name.size()), allocator);
288  }
289 #endif
290 
292 
297  GenericPointer Append(SizeType index, Allocator* allocator = 0) const {
298  char buffer[21];
299  char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer);
300  SizeType length = static_cast<SizeType>(end - buffer);
301  buffer[length] = '\0';
302 
303  if (sizeof(Ch) == 1) {
304  Token token = { reinterpret_cast<Ch*>(buffer), length, index };
305  return Append(token, allocator);
306  }
307  else {
308  Ch name[21];
309  for (size_t i = 0; i <= length; i++)
310  name[i] = static_cast<Ch>(buffer[i]);
311  Token token = { name, length, index };
312  return Append(token, allocator);
313  }
314  }
315 
317 
322  GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const {
323  if (token.IsString())
324  return Append(token.GetString(), token.GetStringLength(), allocator);
325  else {
326  RAPIDJSON_ASSERT(token.IsUint64());
327  RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0));
328  return Append(static_cast<SizeType>(token.GetUint64()), allocator);
329  }
330  }
331 
333 
334 
336  bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; }
337 
339  size_t GetParseErrorOffset() const { return parseErrorOffset_; }
340 
342  PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; }
343 
345 
347  Allocator& GetAllocator() { return *allocator_; }
348 
350 
351 
353  const Token* GetTokens() const { return tokens_; }
354 
356  size_t GetTokenCount() const { return tokenCount_; }
357 
359 
361 
362 
364 
367  bool operator==(const GenericPointer& rhs) const {
368  if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_)
369  return false;
370 
371  for (size_t i = 0; i < tokenCount_; i++) {
372  if (tokens_[i].index != rhs.tokens_[i].index ||
373  tokens_[i].length != rhs.tokens_[i].length ||
374  (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch)* tokens_[i].length) != 0))
375  {
376  return false;
377  }
378  }
379 
380  return true;
381  }
382 
384 
387  bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }
388 
390 
393  bool operator<(const GenericPointer& rhs) const {
394  if (!IsValid())
395  return false;
396  if (!rhs.IsValid())
397  return true;
398 
399  if (tokenCount_ != rhs.tokenCount_)
400  return tokenCount_ < rhs.tokenCount_;
401 
402  for (size_t i = 0; i < tokenCount_; i++) {
403  if (tokens_[i].index != rhs.tokens_[i].index)
404  return tokens_[i].index < rhs.tokens_[i].index;
405 
406  if (tokens_[i].length != rhs.tokens_[i].length)
407  return tokens_[i].length < rhs.tokens_[i].length;
408 
409  if (int cmp = std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length))
410  return cmp < 0;
411  }
412 
413  return false;
414  }
415 
417 
419 
420 
422 
426  template<typename OutputStream>
427  bool Stringify(OutputStream& os) const {
428  return Stringify<false, OutputStream>(os);
429  }
430 
432 
436  template<typename OutputStream>
437  bool StringifyUriFragment(OutputStream& os) const {
438  return Stringify<true, OutputStream>(os);
439  }
440 
442 
444 
445 
447 
461  ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const {
462  RAPIDJSON_ASSERT(IsValid());
463  ValueType* v = &root;
464  bool exist = true;
465  for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
466  if (v->IsArray() && t->name[0] == '-' && t->length == 1) {
467  v->PushBack(ValueType().Move(), allocator);
468  v = &((*v)[v->Size() - 1]);
469  exist = false;
470  }
471  else {
472  if (t->index == kPointerInvalidIndex) { // must be object name
473  if (!v->IsObject())
474  v->SetObject(); // Change to Object
475  }
476  else { // object name or array index
477  if (!v->IsArray() && !v->IsObject())
478  v->SetArray(); // Change to Array
479  }
480 
481  if (v->IsArray()) {
482  if (t->index >= v->Size()) {
483  v->Reserve(t->index + 1, allocator);
484  while (t->index >= v->Size())
485  v->PushBack(ValueType().Move(), allocator);
486  exist = false;
487  }
488  v = &((*v)[t->index]);
489  }
490  else {
491  typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
492  if (m == v->MemberEnd()) {
493  v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
494  v = &(--v->MemberEnd())->value; // Assumes AddMember() appends at the end
495  exist = false;
496  }
497  else
498  v = &m->value;
499  }
500  }
501  }
502 
503  if (alreadyExist)
504  *alreadyExist = exist;
505 
506  return *v;
507  }
508 
510 
515  template <typename stackAllocator>
516  ValueType& Create(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, bool* alreadyExist = 0) const {
517  return Create(document, document.GetAllocator(), alreadyExist);
518  }
519 
521 
523 
524 
526 
539  ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const {
540  RAPIDJSON_ASSERT(IsValid());
541  ValueType* v = &root;
542  for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
543  switch (v->GetType()) {
544  case kObjectType:
545  {
546  typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
547  if (m == v->MemberEnd())
548  break;
549  v = &m->value;
550  }
551  continue;
552  case kArrayType:
553  if (t->index == kPointerInvalidIndex || t->index >= v->Size())
554  break;
555  v = &((*v)[t->index]);
556  continue;
557  default:
558  break;
559  }
560 
561  // Error: unresolved token
562  if (unresolvedTokenIndex)
563  *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
564  return 0;
565  }
566  return v;
567  }
568 
570 
574  const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const {
575  return Get(const_cast<ValueType&>(root), unresolvedTokenIndex);
576  }
577 
579 
581 
582 
584 
593  ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const {
594  bool alreadyExist;
595  ValueType& v = Create(root, allocator, &alreadyExist);
596  return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
597  }
598 
600  ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const {
601  bool alreadyExist;
602  ValueType& v = Create(root, allocator, &alreadyExist);
603  return alreadyExist ? v : v.SetString(defaultValue, allocator);
604  }
605 
606 #if RAPIDJSON_HAS_STDSTRING
607  ValueType& GetWithDefault(ValueType& root, const std::basic_string<Ch>& defaultValue, typename ValueType::AllocatorType& allocator) const {
609  bool alreadyExist;
610  ValueType& v = Create(root, allocator, &alreadyExist);
611  return alreadyExist ? v : v.SetString(defaultValue, allocator);
612  }
613 #endif
614 
616 
619  template <typename T>
620  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
621  GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator) const {
622  return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);
623  }
624 
626  template <typename stackAllocator>
627  ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& defaultValue) const {
628  return GetWithDefault(document, defaultValue, document.GetAllocator());
629  }
630 
632  template <typename stackAllocator>
633  ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* defaultValue) const {
634  return GetWithDefault(document, defaultValue, document.GetAllocator());
635  }
636 
637 #if RAPIDJSON_HAS_STDSTRING
638  template <typename stackAllocator>
640  ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& defaultValue) const {
641  return GetWithDefault(document, defaultValue, document.GetAllocator());
642  }
643 #endif
644 
646 
649  template <typename T, typename stackAllocator>
650  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
651  GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T defaultValue) const {
652  return GetWithDefault(document, defaultValue, document.GetAllocator());
653  }
654 
656 
658 
659 
661 
670  ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
671  return Create(root, allocator) = value;
672  }
673 
675  ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const {
676  return Create(root, allocator).CopyFrom(value, allocator);
677  }
678 
680  ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const {
681  return Create(root, allocator) = ValueType(value, allocator).Move();
682  }
683 
684 #if RAPIDJSON_HAS_STDSTRING
685  ValueType& Set(ValueType& root, const std::basic_string<Ch>& value, typename ValueType::AllocatorType& allocator) const {
687  return Create(root, allocator) = ValueType(value, allocator).Move();
688  }
689 #endif
690 
692 
695  template <typename T>
696  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
697  Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const {
698  return Create(root, allocator) = ValueType(value).Move();
699  }
700 
702  template <typename stackAllocator>
703  ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const {
704  return Create(document) = value;
705  }
706 
708  template <typename stackAllocator>
709  ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& value) const {
710  return Create(document).CopyFrom(value, document.GetAllocator());
711  }
712 
714  template <typename stackAllocator>
715  ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* value) const {
716  return Create(document) = ValueType(value, document.GetAllocator()).Move();
717  }
718 
719 #if RAPIDJSON_HAS_STDSTRING
720  template <typename stackAllocator>
722  ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& value) const {
723  return Create(document) = ValueType(value, document.GetAllocator()).Move();
724  }
725 #endif
726 
728 
731  template <typename T, typename stackAllocator>
732  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
734  return Create(document) = value;
735  }
736 
738 
740 
741 
743 
752  ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
753  return Create(root, allocator).Swap(value);
754  }
755 
757  template <typename stackAllocator>
758  ValueType& Swap(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const {
759  return Create(document).Swap(value);
760  }
761 
763 
765 
771  bool Erase(ValueType& root) const {
772  RAPIDJSON_ASSERT(IsValid());
773  if (tokenCount_ == 0) // Cannot erase the root
774  return false;
775 
776  ValueType* v = &root;
777  const Token* last = tokens_ + (tokenCount_ - 1);
778  for (const Token *t = tokens_; t != last; ++t) {
779  switch (v->GetType()) {
780  case kObjectType:
781  {
782  typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
783  if (m == v->MemberEnd())
784  return false;
785  v = &m->value;
786  }
787  break;
788  case kArrayType:
789  if (t->index == kPointerInvalidIndex || t->index >= v->Size())
790  return false;
791  v = &((*v)[t->index]);
792  break;
793  default:
794  return false;
795  }
796  }
797 
798  switch (v->GetType()) {
799  case kObjectType:
800  return v->EraseMember(GenericStringRef<Ch>(last->name, last->length));
801  case kArrayType:
802  if (last->index == kPointerInvalidIndex || last->index >= v->Size())
803  return false;
804  v->Erase(v->Begin() + last->index);
805  return true;
806  default:
807  return false;
808  }
809  }
810 
811 private:
813 
819  Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0) {
820  if (!allocator_) // allocator is independently owned.
821  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
822 
823  size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens
824  for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)
825  nameBufferSize += t->length;
826 
827  tokenCount_ = rhs.tokenCount_ + extraToken;
828  tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch)));
829  nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
830  if (rhs.tokenCount_ > 0) {
831  std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token));
832  }
833  if (nameBufferSize > 0) {
834  std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
835  }
836 
837  // Adjust pointers to name buffer
838  std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;
839  for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t)
840  t->name += diff;
841 
842  return nameBuffer_ + nameBufferSize;
843  }
844 
846 
850  bool NeedPercentEncode(Ch c) const {
851  return !((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~');
852  }
853 
855 #ifndef __clang__ // -Wdocumentation
856 
861 #endif
862  void Parse(const Ch* source, size_t length) {
863  RAPIDJSON_ASSERT(source != NULL);
866 
867  // Create own allocator if user did not supply.
868  if (!allocator_)
869  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
870 
871  // Count number of '/' as tokenCount
872  tokenCount_ = 0;
873  for (const Ch* s = source; s != source + length; s++)
874  if (*s == '/')
875  tokenCount_++;
876 
877  Token* token = tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch)));
878  Ch* name = nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
879  size_t i = 0;
880 
881  // Detect if it is a URI fragment
882  bool uriFragment = false;
883  if (source[i] == '#') {
884  uriFragment = true;
885  i++;
886  }
887 
888  if (i != length && source[i] != '/') {
890  goto error;
891  }
892 
893  while (i < length) {
894  RAPIDJSON_ASSERT(source[i] == '/');
895  i++; // consumes '/'
896 
897  token->name = name;
898  bool isNumber = true;
899 
900  while (i < length && source[i] != '/') {
901  Ch c = source[i];
902  if (uriFragment) {
903  // Decoding percent-encoding for URI fragment
904  if (c == '%') {
905  PercentDecodeStream is(&source[i], source + length);
907  Ch* begin = os.PutBegin();
908  if (!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid()) {
910  goto error;
911  }
912  size_t len = os.PutEnd(begin);
913  i += is.Tell() - 1;
914  if (len == 1)
915  c = *name;
916  else {
917  name += len;
918  isNumber = false;
919  i++;
920  continue;
921  }
922  }
923  else if (NeedPercentEncode(c)) {
925  goto error;
926  }
927  }
928 
929  i++;
930 
931  // Escaping "~0" -> '~', "~1" -> '/'
932  if (c == '~') {
933  if (i < length) {
934  c = source[i];
935  if (c == '0') c = '~';
936  else if (c == '1') c = '/';
937  else {
939  goto error;
940  }
941  i++;
942  }
943  else {
945  goto error;
946  }
947  }
948 
949  // First check for index: all of characters are digit
950  if (c < '0' || c > '9')
951  isNumber = false;
952 
953  *name++ = c;
954  }
955  token->length = static_cast<SizeType>(name - token->name);
956  if (token->length == 0)
957  isNumber = false;
958  *name++ = '\0'; // Null terminator
959 
960  // Second check for index: more than one digit cannot have leading zero
961  if (isNumber && token->length > 1 && token->name[0] == '0')
962  isNumber = false;
963 
964  // String to SizeType conversion
965  SizeType n = 0;
966  if (isNumber) {
967  for (size_t j = 0; j < token->length; j++) {
968  SizeType m = n * 10 + static_cast<SizeType>(token->name[j] - '0');
969  if (m < n) { // overflow detection
970  isNumber = false;
971  break;
972  }
973  n = m;
974  }
975  }
976 
977  token->index = isNumber ? n : kPointerInvalidIndex;
978  token++;
979  }
980 
981  RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer
983  return;
984 
985  error:
986  Allocator::Free(tokens_);
987  nameBuffer_ = 0;
988  tokens_ = 0;
989  tokenCount_ = 0;
990  parseErrorOffset_ = i;
991  return;
992  }
993 
995 
1000  template<bool uriFragment, typename OutputStream>
1001  bool Stringify(OutputStream& os) const {
1002  RAPIDJSON_ASSERT(IsValid());
1003 
1004  if (uriFragment)
1005  os.Put('#');
1006 
1007  for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
1008  os.Put('/');
1009  for (size_t j = 0; j < t->length; j++) {
1010  Ch c = t->name[j];
1011  if (c == '~') {
1012  os.Put('~');
1013  os.Put('0');
1014  }
1015  else if (c == '/') {
1016  os.Put('~');
1017  os.Put('1');
1018  }
1019  else if (uriFragment && NeedPercentEncode(c)) {
1020  // Transcode to UTF8 sequence
1023  if (!Transcoder<EncodingType, UTF8<> >().Validate(source, target))
1024  return false;
1025  j += source.Tell() - 1;
1026  }
1027  else
1028  os.Put(c);
1029  }
1030  }
1031  return true;
1032  }
1033 
1035 
1040  class PercentDecodeStream {
1041  public:
1042  typedef typename ValueType::Ch Ch;
1043 
1045 
1049  PercentDecodeStream(const Ch* source, const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {}
1050 
1051  Ch Take() {
1052  if (*src_ != '%' || src_ + 3 > end_) { // %XY triplet
1053  valid_ = false;
1054  return 0;
1055  }
1056  src_++;
1057  Ch c = 0;
1058  for (int j = 0; j < 2; j++) {
1059  c = static_cast<Ch>(c << 4);
1060  Ch h = *src_;
1061  if (h >= '0' && h <= '9') c = static_cast<Ch>(c + h - '0');
1062  else if (h >= 'A' && h <= 'F') c = static_cast<Ch>(c + h - 'A' + 10);
1063  else if (h >= 'a' && h <= 'f') c = static_cast<Ch>(c + h - 'a' + 10);
1064  else {
1065  valid_ = false;
1066  return 0;
1067  }
1068  src_++;
1069  }
1070  return c;
1071  }
1072 
1073  size_t Tell() const { return static_cast<size_t>(src_ - head_); }
1074  bool IsValid() const { return valid_; }
1075 
1076  private:
1077  const Ch* src_;
1078  const Ch* head_;
1079  const Ch* end_;
1080  bool valid_;
1081  };
1082 
1084  template <typename OutputStream>
1086  public:
1087  PercentEncodeStream(OutputStream& os) : os_(os) {}
1088  void Put(char c) { // UTF-8 must be byte
1089  unsigned char u = static_cast<unsigned char>(c);
1090  static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1091  os_.Put('%');
1092  os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u >> 4]));
1093  os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u & 15]));
1094  }
1095  private:
1096  OutputStream& os_;
1097  };
1098 
1099  Allocator* allocator_;
1100  Allocator* ownAllocator_;
1103  size_t tokenCount_;
1106 };
1107 
1110 
1112 
1113 
1115 
1116 template <typename T>
1117 typename T::ValueType& CreateValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::AllocatorType& a) {
1118  return pointer.Create(root, a);
1119 }
1120 
1121 template <typename T, typename CharType, size_t N>
1122 typename T::ValueType& CreateValueByPointer(T& root, const CharType(&source)[N], typename T::AllocatorType& a) {
1123  return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a);
1124 }
1125 
1126 // No allocator parameter
1127 
1128 template <typename DocumentType>
1129 typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer) {
1130  return pointer.Create(document);
1131 }
1132 
1133 template <typename DocumentType, typename CharType, size_t N>
1134 typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const CharType(&source)[N]) {
1135  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document);
1136 }
1137 
1139 
1140 template <typename T>
1141 typename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
1142  return pointer.Get(root, unresolvedTokenIndex);
1143 }
1144 
1145 template <typename T>
1146 const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
1147  return pointer.Get(root, unresolvedTokenIndex);
1148 }
1149 
1150 template <typename T, typename CharType, size_t N>
1151 typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) {
1152  return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1153 }
1154 
1155 template <typename T, typename CharType, size_t N>
1156 const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) {
1157  return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1158 }
1159 
1161 
1162 template <typename T>
1163 typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
1164  return pointer.GetWithDefault(root, defaultValue, a);
1165 }
1166 
1167 template <typename T>
1168 typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* defaultValue, typename T::AllocatorType& a) {
1169  return pointer.GetWithDefault(root, defaultValue, a);
1170 }
1171 
1172 #if RAPIDJSON_HAS_STDSTRING
1173 template <typename T>
1174 typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {
1175  return pointer.GetWithDefault(root, defaultValue, a);
1176 }
1177 #endif
1178 
1179 template <typename T, typename T2>
1180 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1181 GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 defaultValue, typename T::AllocatorType& a) {
1182  return pointer.GetWithDefault(root, defaultValue, a);
1183 }
1184 
1185 template <typename T, typename CharType, size_t N>
1186 typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
1187  return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1188 }
1189 
1190 template <typename T, typename CharType, size_t N>
1191 typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::Ch* defaultValue, typename T::AllocatorType& a) {
1192  return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1193 }
1194 
1195 #if RAPIDJSON_HAS_STDSTRING
1196 template <typename T, typename CharType, size_t N>
1197 typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {
1198  return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1199 }
1200 #endif
1201 
1202 template <typename T, typename CharType, size_t N, typename T2>
1203 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1204 GetValueByPointerWithDefault(T& root, const CharType(&source)[N], T2 defaultValue, typename T::AllocatorType& a) {
1205  return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1206 }
1207 
1208 // No allocator parameter
1209 
1210 template <typename DocumentType>
1211 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& defaultValue) {
1212  return pointer.GetWithDefault(document, defaultValue);
1213 }
1214 
1215 template <typename DocumentType>
1216 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* defaultValue) {
1217  return pointer.GetWithDefault(document, defaultValue);
1218 }
1219 
1220 #if RAPIDJSON_HAS_STDSTRING
1221 template <typename DocumentType>
1222 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1223  return pointer.GetWithDefault(document, defaultValue);
1224 }
1225 #endif
1226 
1227 template <typename DocumentType, typename T2>
1228 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1229 GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 defaultValue) {
1230  return pointer.GetWithDefault(document, defaultValue);
1231 }
1232 
1233 template <typename DocumentType, typename CharType, size_t N>
1234 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& defaultValue) {
1235  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1236 }
1237 
1238 template <typename DocumentType, typename CharType, size_t N>
1239 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* defaultValue) {
1240  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1241 }
1242 
1243 #if RAPIDJSON_HAS_STDSTRING
1244 template <typename DocumentType, typename CharType, size_t N>
1245 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1246  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1247 }
1248 #endif
1249 
1250 template <typename DocumentType, typename CharType, size_t N, typename T2>
1251 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1252 GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) {
1253  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1254 }
1255 
1257 
1258 template <typename T>
1259 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
1260  return pointer.Set(root, value, a);
1261 }
1262 
1263 template <typename T>
1264 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& value, typename T::AllocatorType& a) {
1265  return pointer.Set(root, value, a);
1266 }
1267 
1268 template <typename T>
1269 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* value, typename T::AllocatorType& a) {
1270  return pointer.Set(root, value, a);
1271 }
1272 
1273 #if RAPIDJSON_HAS_STDSTRING
1274 template <typename T>
1275 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {
1276  return pointer.Set(root, value, a);
1277 }
1278 #endif
1279 
1280 template <typename T, typename T2>
1281 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1282 SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 value, typename T::AllocatorType& a) {
1283  return pointer.Set(root, value, a);
1284 }
1285 
1286 template <typename T, typename CharType, size_t N>
1287 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
1288  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1289 }
1290 
1291 template <typename T, typename CharType, size_t N>
1292 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::ValueType& value, typename T::AllocatorType& a) {
1293  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1294 }
1295 
1296 template <typename T, typename CharType, size_t N>
1297 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::Ch* value, typename T::AllocatorType& a) {
1298  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1299 }
1300 
1301 #if RAPIDJSON_HAS_STDSTRING
1302 template <typename T, typename CharType, size_t N>
1303 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {
1304  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1305 }
1306 #endif
1307 
1308 template <typename T, typename CharType, size_t N, typename T2>
1309 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1310 SetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) {
1311  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1312 }
1313 
1314 // No allocator parameter
1315 
1316 template <typename DocumentType>
1317 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
1318  return pointer.Set(document, value);
1319 }
1320 
1321 template <typename DocumentType>
1322 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& value) {
1323  return pointer.Set(document, value);
1324 }
1325 
1326 template <typename DocumentType>
1327 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* value) {
1328  return pointer.Set(document, value);
1329 }
1330 
1331 #if RAPIDJSON_HAS_STDSTRING
1332 template <typename DocumentType>
1333 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& value) {
1334  return pointer.Set(document, value);
1335 }
1336 #endif
1337 
1338 template <typename DocumentType, typename T2>
1339 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1340 SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 value) {
1341  return pointer.Set(document, value);
1342 }
1343 
1344 template <typename DocumentType, typename CharType, size_t N>
1345 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
1346  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1347 }
1348 
1349 template <typename DocumentType, typename CharType, size_t N>
1350 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& value) {
1351  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1352 }
1353 
1354 template <typename DocumentType, typename CharType, size_t N>
1355 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* value) {
1356  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1357 }
1358 
1359 #if RAPIDJSON_HAS_STDSTRING
1360 template <typename DocumentType, typename CharType, size_t N>
1361 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& value) {
1362  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1363 }
1364 #endif
1365 
1366 template <typename DocumentType, typename CharType, size_t N, typename T2>
1367 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1368 SetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) {
1369  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1370 }
1371 
1373 
1374 template <typename T>
1375 typename T::ValueType& SwapValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
1376  return pointer.Swap(root, value, a);
1377 }
1378 
1379 template <typename T, typename CharType, size_t N>
1380 typename T::ValueType& SwapValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
1381  return GenericPointer<typename T::ValueType>(source, N - 1).Swap(root, value, a);
1382 }
1383 
1384 template <typename DocumentType>
1385 typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
1386  return pointer.Swap(document, value);
1387 }
1388 
1389 template <typename DocumentType, typename CharType, size_t N>
1390 typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
1391  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Swap(document, value);
1392 }
1393 
1395 
1396 template <typename T>
1398  return pointer.Erase(root);
1399 }
1400 
1401 template <typename T, typename CharType, size_t N>
1402 bool EraseValueByPointer(T& root, const CharType(&source)[N]) {
1403  return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root);
1404 }
1405 
1407 
1409 
1410 #if defined(__clang__) || defined(_MSC_VER)
1411 RAPIDJSON_DIAG_POP
1412 #endif
1413 
1414 #endif // RAPIDJSON_POINTER_H_
SizeType length
Length of the name.
Definition: pointer.h:99
T::ValueType & GetValueByPointerWithDefault(T &root, const GenericPointer< typename T::ValueType > &pointer, const typename T::ValueType &defaultValue, typename T::AllocatorType &a)
Definition: pointer.h:1163
char * u64toa(uint64_t value, char *buffer)
Definition: itoa.h:126
PointerParseErrorCode
Error code of parsing.
Definition: pointer.h:37
const CharType(& source)[N]
Definition: pointer.h:1204
GenericPointer(const Token *tokens, size_t tokenCount)
Constructor with user-supplied tokens.
Definition: pointer.h:163
A token is the basic units of internal representation.
Definition: pointer.h:97
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
Definition: pointer.h:244
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:384
GenericPointer & Swap(GenericPointer &other) RAPIDJSON_NOEXCEPT
Swap the content of this pointer with an other.
Definition: pointer.h:208
Allocator * ownAllocator_
Allocator owned by this Pointer.
Definition: pointer.h:1100
object
Definition: rapidjson.h:646
Invalid percent encoding in URI fragment.
Definition: pointer.h:42
GenericPointer(const Ch *source, Allocator *allocator=0)
Constructor that parses a string or URI fragment representation.
Definition: pointer.h:114
array
Definition: rapidjson.h:647
PercentEncodeStream(OutputStream &os)
Definition: pointer.h:1087
ValueType::EncodingType EncodingType
Encoding type from Value.
Definition: pointer.h:81
const Ch * name
Name of the token. It has null character at the end but it can contain null character.
Definition: pointer.h:98
Allocator * allocator_
The current allocator. It is either user-supplied or equal to ownAllocator_.
Definition: pointer.h:1099
GenericPointer(const GenericPointer &rhs)
Copy constructor.
Definition: pointer.h:166
GenericPointer(Allocator *allocator=0)
Default constructor.
Definition: pointer.h:107
static RAPIDJSON_NAMESPACE_BEGIN const SizeType kPointerInvalidIndex
Represents an invalid index in GenericPointer::Token.
Definition: pointer.h:31
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:121
size_t Tell() const
Definition: stream.h:161
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:2412
The parse is successful.
Definition: pointer.h:38
T::ValueType & SwapValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition: pointer.h:1375
Encoding conversion.
Definition: encodings.h:658
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:137
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition: rapidjson.h:625
Reference to a constant string (not taking a copy)
Definition: document.h:256
size_t PutEnd(Ch *begin)
Definition: stream.h:202
Read-only string stream.
Definition: fwd.h:47
GenericPointer< Value > Pointer
GenericPointer for Value (UTF-8, default allocator).
Definition: pointer.h:1109
A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence.
Definition: pointer.h:1085
size_t parseErrorOffset_
Offset in code unit when parsing fail.
Definition: pointer.h:1104
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.
Ch * nameBuffer_
A buffer containing all names in tokens.
Definition: pointer.h:1101
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition: fwd.h:126
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:124
~GenericPointer()
Destructor.
Definition: pointer.h:176
void Swap(T &a, T &b) RAPIDJSON_NOEXCEPT
Custom swap() to avoid dependency on C++ <algorithm> header.
Definition: swap.h:33
GenericPointer(const GenericPointer &rhs, Allocator *allocator)
Copy constructor.
Definition: pointer.h:171
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:629
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:1117
PointerParseErrorCode parseErrorCode_
Parsing error code.
Definition: pointer.h:1105
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1181
Token * tokens_
A list of tokens.
Definition: pointer.h:1102
SizeType index
A valid array index, if it is not equal to kPointerInvalidIndex.
Definition: pointer.h:100
Allocator * allocator
Definition: pointer.h:275
A character must percent encoded in URI fragment.
Definition: pointer.h:43
size_t tokenCount_
Number of tokens in tokens_.
Definition: pointer.h:1103
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1282
ValueType::Ch Ch
Character type from Value.
Definition: pointer.h:82
A token must begin with a &#39;/&#39;.
Definition: pointer.h:40
friend void swap(GenericPointer &a, GenericPointer &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition: pointer.h:231
bool EraseValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer)
Definition: pointer.h:1397
const GenericPointer< typename T::ValueType > T2 defaultValue
Definition: pointer.h:1181
SizeType StrLen(const Ch *s)
Custom strlen() which works on different character types.
Definition: strfunc.h:31
const GenericPointer< typename T::ValueType > & pointer
Definition: pointer.h:1181
A read-write string stream.
Definition: fwd.h:52
Type
Type of JSON value.
Definition: rapidjson.h:642
T::ValueType & SetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition: pointer.h:1259
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:406
GenericPointer & operator=(const GenericPointer &rhs)
Assignment operator.
Definition: pointer.h:183
A document for parsing JSON text as DOM.
Definition: document.h:57
T::ValueType * GetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, size_t *unresolvedTokenIndex=0)
Definition: pointer.h:1141
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:262
UTF-8 encoding.
Definition: encodings.h:96