bes  Updated for version 3.20.10
pointer.h
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 
31 static const SizeType kPointerInvalidIndex = ~SizeType(0);
32 
34 
39 
44 };
45 
47 // GenericPointer
48 
50 
78 template <typename ValueType, typename Allocator = CrtAllocator>
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
120 
125  explicit GenericPointer(const std::basic_string<Ch>& source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
126  Parse(source.c_str(), source.size());
127  }
128 #endif
129 
131 
137  GenericPointer(const Ch* source, size_t length, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
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
281 
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(GenericValue<EncodingType>(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  m = v->MemberEnd();
495  v = &(--m)->value; // Assumes AddMember() appends at the end
496  exist = false;
497  }
498  else
499  v = &m->value;
500  }
501  }
502  }
503 
504  if (alreadyExist)
505  *alreadyExist = exist;
506 
507  return *v;
508  }
509 
511 
516  template <typename stackAllocator>
517  ValueType& Create(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, bool* alreadyExist = 0) const {
518  return Create(document, document.GetAllocator(), alreadyExist);
519  }
520 
522 
524 
525 
527 
540  ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const {
541  RAPIDJSON_ASSERT(IsValid());
542  ValueType* v = &root;
543  for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
544  switch (v->GetType()) {
545  case kObjectType:
546  {
547  typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
548  if (m == v->MemberEnd())
549  break;
550  v = &m->value;
551  }
552  continue;
553  case kArrayType:
554  if (t->index == kPointerInvalidIndex || t->index >= v->Size())
555  break;
556  v = &((*v)[t->index]);
557  continue;
558  default:
559  break;
560  }
561 
562  // Error: unresolved token
563  if (unresolvedTokenIndex)
564  *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
565  return 0;
566  }
567  return v;
568  }
569 
571 
575  const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const {
576  return Get(const_cast<ValueType&>(root), unresolvedTokenIndex);
577  }
578 
580 
582 
583 
585 
594  ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const {
595  bool alreadyExist;
596  ValueType& v = Create(root, allocator, &alreadyExist);
597  return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
598  }
599 
601  ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const {
602  bool alreadyExist;
603  ValueType& v = Create(root, allocator, &alreadyExist);
604  return alreadyExist ? v : v.SetString(defaultValue, allocator);
605  }
606 
607 #if RAPIDJSON_HAS_STDSTRING
609  ValueType& GetWithDefault(ValueType& root, const std::basic_string<Ch>& defaultValue, typename ValueType::AllocatorType& allocator) const {
610  bool alreadyExist;
611  ValueType& v = Create(root, allocator, &alreadyExist);
612  return alreadyExist ? v : v.SetString(defaultValue, allocator);
613  }
614 #endif
615 
617 
620  template <typename T>
621  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
622  GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator) const {
623  return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);
624  }
625 
627  template <typename stackAllocator>
628  ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& defaultValue) const {
629  return GetWithDefault(document, defaultValue, document.GetAllocator());
630  }
631 
633  template <typename stackAllocator>
634  ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* defaultValue) const {
635  return GetWithDefault(document, defaultValue, document.GetAllocator());
636  }
637 
638 #if RAPIDJSON_HAS_STDSTRING
640  template <typename stackAllocator>
641  ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& defaultValue) const {
642  return GetWithDefault(document, defaultValue, document.GetAllocator());
643  }
644 #endif
645 
647 
650  template <typename T, typename stackAllocator>
651  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
652  GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T defaultValue) const {
653  return GetWithDefault(document, defaultValue, document.GetAllocator());
654  }
655 
657 
659 
660 
662 
671  ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
672  return Create(root, allocator) = value;
673  }
674 
676  ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const {
677  return Create(root, allocator).CopyFrom(value, allocator);
678  }
679 
681  ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const {
682  return Create(root, allocator) = ValueType(value, allocator).Move();
683  }
684 
685 #if RAPIDJSON_HAS_STDSTRING
687  ValueType& Set(ValueType& root, const std::basic_string<Ch>& value, typename ValueType::AllocatorType& allocator) const {
688  return Create(root, allocator) = ValueType(value, allocator).Move();
689  }
690 #endif
691 
693 
696  template <typename T>
697  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
698  Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const {
699  return Create(root, allocator) = ValueType(value).Move();
700  }
701 
703  template <typename stackAllocator>
704  ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const {
705  return Create(document) = value;
706  }
707 
709  template <typename stackAllocator>
710  ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& value) const {
711  return Create(document).CopyFrom(value, document.GetAllocator());
712  }
713 
715  template <typename stackAllocator>
716  ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* value) const {
717  return Create(document) = ValueType(value, document.GetAllocator()).Move();
718  }
719 
720 #if RAPIDJSON_HAS_STDSTRING
722  template <typename stackAllocator>
723  ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& value) const {
724  return Create(document) = ValueType(value, document.GetAllocator()).Move();
725  }
726 #endif
727 
729 
732  template <typename T, typename stackAllocator>
733  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
735  return Create(document) = value;
736  }
737 
739 
741 
742 
744 
753  ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
754  return Create(root, allocator).Swap(value);
755  }
756 
758  template <typename stackAllocator>
759  ValueType& Swap(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const {
760  return Create(document).Swap(value);
761  }
762 
764 
766 
772  bool Erase(ValueType& root) const {
773  RAPIDJSON_ASSERT(IsValid());
774  if (tokenCount_ == 0) // Cannot erase the root
775  return false;
776 
777  ValueType* v = &root;
778  const Token* last = tokens_ + (tokenCount_ - 1);
779  for (const Token *t = tokens_; t != last; ++t) {
780  switch (v->GetType()) {
781  case kObjectType:
782  {
783  typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
784  if (m == v->MemberEnd())
785  return false;
786  v = &m->value;
787  }
788  break;
789  case kArrayType:
790  if (t->index == kPointerInvalidIndex || t->index >= v->Size())
791  return false;
792  v = &((*v)[t->index]);
793  break;
794  default:
795  return false;
796  }
797  }
798 
799  switch (v->GetType()) {
800  case kObjectType:
801  return v->EraseMember(GenericStringRef<Ch>(last->name, last->length));
802  case kArrayType:
803  if (last->index == kPointerInvalidIndex || last->index >= v->Size())
804  return false;
805  v->Erase(v->Begin() + last->index);
806  return true;
807  default:
808  return false;
809  }
810  }
811 
812 private:
814 
820  Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0) {
821  if (!allocator_) // allocator is independently owned.
823 
824  size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens
825  for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)
826  nameBufferSize += t->length;
827 
828  tokenCount_ = rhs.tokenCount_ + extraToken;
829  tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch)));
830  nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
831  if (rhs.tokenCount_ > 0) {
832  std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token));
833  }
834  if (nameBufferSize > 0) {
835  std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
836  }
837 
838  // Adjust pointers to name buffer
839  std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;
840  for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t)
841  t->name += diff;
842 
843  return nameBuffer_ + nameBufferSize;
844  }
845 
847 
851  bool NeedPercentEncode(Ch c) const {
852  return !((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~');
853  }
854 
856 #ifndef __clang__ // -Wdocumentation
862 #endif
863  void Parse(const Ch* source, size_t length) {
864  RAPIDJSON_ASSERT(source != NULL);
867 
868  // Create own allocator if user did not supply.
869  if (!allocator_)
871 
872  // Count number of '/' as tokenCount
873  tokenCount_ = 0;
874  for (const Ch* s = source; s != source + length; s++)
875  if (*s == '/')
876  tokenCount_++;
877 
878  Token* token = tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch)));
879  Ch* name = nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
880  size_t i = 0;
881 
882  // Detect if it is a URI fragment
883  bool uriFragment = false;
884  if (source[i] == '#') {
885  uriFragment = true;
886  i++;
887  }
888 
889  if (i != length && source[i] != '/') {
891  goto error;
892  }
893 
894  while (i < length) {
895  RAPIDJSON_ASSERT(source[i] == '/');
896  i++; // consumes '/'
897 
898  token->name = name;
899  bool isNumber = true;
900 
901  while (i < length && source[i] != '/') {
902  Ch c = source[i];
903  if (uriFragment) {
904  // Decoding percent-encoding for URI fragment
905  if (c == '%') {
906  PercentDecodeStream is(&source[i], source + length);
908  Ch* begin = os.PutBegin();
909  if (!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid()) {
911  goto error;
912  }
913  size_t len = os.PutEnd(begin);
914  i += is.Tell() - 1;
915  if (len == 1)
916  c = *name;
917  else {
918  name += len;
919  isNumber = false;
920  i++;
921  continue;
922  }
923  }
924  else if (NeedPercentEncode(c)) {
926  goto error;
927  }
928  }
929 
930  i++;
931 
932  // Escaping "~0" -> '~', "~1" -> '/'
933  if (c == '~') {
934  if (i < length) {
935  c = source[i];
936  if (c == '0') c = '~';
937  else if (c == '1') c = '/';
938  else {
940  goto error;
941  }
942  i++;
943  }
944  else {
946  goto error;
947  }
948  }
949 
950  // First check for index: all of characters are digit
951  if (c < '0' || c > '9')
952  isNumber = false;
953 
954  *name++ = c;
955  }
956  token->length = static_cast<SizeType>(name - token->name);
957  if (token->length == 0)
958  isNumber = false;
959  *name++ = '\0'; // Null terminator
960 
961  // Second check for index: more than one digit cannot have leading zero
962  if (isNumber && token->length > 1 && token->name[0] == '0')
963  isNumber = false;
964 
965  // String to SizeType conversion
966  SizeType n = 0;
967  if (isNumber) {
968  for (size_t j = 0; j < token->length; j++) {
969  SizeType m = n * 10 + static_cast<SizeType>(token->name[j] - '0');
970  if (m < n) { // overflow detection
971  isNumber = false;
972  break;
973  }
974  n = m;
975  }
976  }
977 
978  token->index = isNumber ? n : kPointerInvalidIndex;
979  token++;
980  }
981 
982  RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer
984  return;
985 
986  error:
987  Allocator::Free(tokens_);
988  nameBuffer_ = 0;
989  tokens_ = 0;
990  tokenCount_ = 0;
991  parseErrorOffset_ = i;
992  return;
993  }
994 
996 
1001  template<bool uriFragment, typename OutputStream>
1002  bool Stringify(OutputStream& os) const {
1003  RAPIDJSON_ASSERT(IsValid());
1004 
1005  if (uriFragment)
1006  os.Put('#');
1007 
1008  for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
1009  os.Put('/');
1010  for (size_t j = 0; j < t->length; j++) {
1011  Ch c = t->name[j];
1012  if (c == '~') {
1013  os.Put('~');
1014  os.Put('0');
1015  }
1016  else if (c == '/') {
1017  os.Put('~');
1018  os.Put('1');
1019  }
1020  else if (uriFragment && NeedPercentEncode(c)) {
1021  // Transcode to UTF8 sequence
1023  PercentEncodeStream<OutputStream> target(os);
1024  if (!Transcoder<EncodingType, UTF8<> >().Validate(source, target))
1025  return false;
1026  j += source.Tell() - 1;
1027  }
1028  else
1029  os.Put(c);
1030  }
1031  }
1032  return true;
1033  }
1034 
1036 
1041  class PercentDecodeStream {
1042  public:
1043  typedef typename ValueType::Ch Ch;
1044 
1046 
1050  PercentDecodeStream(const Ch* source, const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {}
1051 
1052  Ch Take() {
1053  if (*src_ != '%' || src_ + 3 > end_) { // %XY triplet
1054  valid_ = false;
1055  return 0;
1056  }
1057  src_++;
1058  Ch c = 0;
1059  for (int j = 0; j < 2; j++) {
1060  c = static_cast<Ch>(c << 4);
1061  Ch h = *src_;
1062  if (h >= '0' && h <= '9') c = static_cast<Ch>(c + h - '0');
1063  else if (h >= 'A' && h <= 'F') c = static_cast<Ch>(c + h - 'A' + 10);
1064  else if (h >= 'a' && h <= 'f') c = static_cast<Ch>(c + h - 'a' + 10);
1065  else {
1066  valid_ = false;
1067  return 0;
1068  }
1069  src_++;
1070  }
1071  return c;
1072  }
1073 
1074  size_t Tell() const { return static_cast<size_t>(src_ - head_); }
1075  bool IsValid() const { return valid_; }
1076 
1077  private:
1078  const Ch* src_;
1079  const Ch* head_;
1080  const Ch* end_;
1081  bool valid_;
1082  };
1083 
1085  template <typename OutputStream>
1087  public:
1088  PercentEncodeStream(OutputStream& os) : os_(os) {}
1089  void Put(char c) { // UTF-8 must be byte
1090  unsigned char u = static_cast<unsigned char>(c);
1091  static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1092  os_.Put('%');
1093  os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u >> 4]));
1094  os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u & 15]));
1095  }
1096  private:
1097  OutputStream& os_;
1098  };
1099 
1104  size_t tokenCount_;
1107 };
1108 
1111 
1113 
1114 
1116 
1117 template <typename T>
1118 typename T::ValueType& CreateValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::AllocatorType& a) {
1119  return pointer.Create(root, a);
1120 }
1121 
1122 template <typename T, typename CharType, size_t N>
1123 typename T::ValueType& CreateValueByPointer(T& root, const CharType(&source)[N], typename T::AllocatorType& a) {
1124  return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a);
1125 }
1126 
1127 // No allocator parameter
1128 
1129 template <typename DocumentType>
1130 typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer) {
1131  return pointer.Create(document);
1132 }
1133 
1134 template <typename DocumentType, typename CharType, size_t N>
1135 typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const CharType(&source)[N]) {
1136  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document);
1137 }
1138 
1140 
1141 template <typename T>
1142 typename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
1143  return pointer.Get(root, unresolvedTokenIndex);
1144 }
1145 
1146 template <typename T>
1147 const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
1148  return pointer.Get(root, unresolvedTokenIndex);
1149 }
1150 
1151 template <typename T, typename CharType, size_t N>
1152 typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) {
1153  return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1154 }
1155 
1156 template <typename T, typename CharType, size_t N>
1157 const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) {
1158  return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1159 }
1160 
1162 
1163 template <typename T>
1164 typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
1165  return pointer.GetWithDefault(root, defaultValue, a);
1166 }
1167 
1168 template <typename T>
1169 typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* defaultValue, typename T::AllocatorType& a) {
1170  return pointer.GetWithDefault(root, defaultValue, a);
1171 }
1172 
1173 #if RAPIDJSON_HAS_STDSTRING
1174 template <typename T>
1175 typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {
1176  return pointer.GetWithDefault(root, defaultValue, a);
1177 }
1178 #endif
1179 
1180 template <typename T, typename T2>
1181 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1182 GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 defaultValue, typename T::AllocatorType& a) {
1183  return pointer.GetWithDefault(root, defaultValue, a);
1184 }
1185 
1186 template <typename T, typename CharType, size_t N>
1187 typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
1188  return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1189 }
1190 
1191 template <typename T, typename CharType, size_t N>
1192 typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::Ch* defaultValue, typename T::AllocatorType& a) {
1193  return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1194 }
1195 
1196 #if RAPIDJSON_HAS_STDSTRING
1197 template <typename T, typename CharType, size_t N>
1198 typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {
1199  return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1200 }
1201 #endif
1202 
1203 template <typename T, typename CharType, size_t N, typename T2>
1204 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1205 GetValueByPointerWithDefault(T& root, const CharType(&source)[N], T2 defaultValue, typename T::AllocatorType& a) {
1206  return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1207 }
1208 
1209 // No allocator parameter
1210 
1211 template <typename DocumentType>
1212 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& defaultValue) {
1213  return pointer.GetWithDefault(document, defaultValue);
1214 }
1215 
1216 template <typename DocumentType>
1217 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* defaultValue) {
1218  return pointer.GetWithDefault(document, defaultValue);
1219 }
1220 
1221 #if RAPIDJSON_HAS_STDSTRING
1222 template <typename DocumentType>
1223 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1224  return pointer.GetWithDefault(document, defaultValue);
1225 }
1226 #endif
1227 
1228 template <typename DocumentType, typename T2>
1229 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1230 GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 defaultValue) {
1231  return pointer.GetWithDefault(document, defaultValue);
1232 }
1233 
1234 template <typename DocumentType, typename CharType, size_t N>
1235 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& defaultValue) {
1236  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1237 }
1238 
1239 template <typename DocumentType, typename CharType, size_t N>
1240 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* defaultValue) {
1241  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1242 }
1243 
1244 #if RAPIDJSON_HAS_STDSTRING
1245 template <typename DocumentType, typename CharType, size_t N>
1246 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1247  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1248 }
1249 #endif
1250 
1251 template <typename DocumentType, typename CharType, size_t N, typename T2>
1252 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1253 GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) {
1254  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1255 }
1256 
1258 
1259 template <typename T>
1260 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
1261  return pointer.Set(root, value, a);
1262 }
1263 
1264 template <typename T>
1265 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& value, typename T::AllocatorType& a) {
1266  return pointer.Set(root, value, a);
1267 }
1268 
1269 template <typename T>
1270 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* value, typename T::AllocatorType& a) {
1271  return pointer.Set(root, value, a);
1272 }
1273 
1274 #if RAPIDJSON_HAS_STDSTRING
1275 template <typename T>
1276 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {
1277  return pointer.Set(root, value, a);
1278 }
1279 #endif
1280 
1281 template <typename T, typename T2>
1282 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1283 SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 value, typename T::AllocatorType& a) {
1284  return pointer.Set(root, value, a);
1285 }
1286 
1287 template <typename T, typename CharType, size_t N>
1288 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
1289  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1290 }
1291 
1292 template <typename T, typename CharType, size_t N>
1293 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::ValueType& value, typename T::AllocatorType& a) {
1294  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1295 }
1296 
1297 template <typename T, typename CharType, size_t N>
1298 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::Ch* value, typename T::AllocatorType& a) {
1299  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1300 }
1301 
1302 #if RAPIDJSON_HAS_STDSTRING
1303 template <typename T, typename CharType, size_t N>
1304 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {
1305  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1306 }
1307 #endif
1308 
1309 template <typename T, typename CharType, size_t N, typename T2>
1310 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1311 SetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) {
1312  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1313 }
1314 
1315 // No allocator parameter
1316 
1317 template <typename DocumentType>
1318 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
1319  return pointer.Set(document, value);
1320 }
1321 
1322 template <typename DocumentType>
1323 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& value) {
1324  return pointer.Set(document, value);
1325 }
1326 
1327 template <typename DocumentType>
1328 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* value) {
1329  return pointer.Set(document, value);
1330 }
1331 
1332 #if RAPIDJSON_HAS_STDSTRING
1333 template <typename DocumentType>
1334 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& value) {
1335  return pointer.Set(document, value);
1336 }
1337 #endif
1338 
1339 template <typename DocumentType, typename T2>
1340 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1341 SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 value) {
1342  return pointer.Set(document, value);
1343 }
1344 
1345 template <typename DocumentType, typename CharType, size_t N>
1346 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
1347  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1348 }
1349 
1350 template <typename DocumentType, typename CharType, size_t N>
1351 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& value) {
1352  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1353 }
1354 
1355 template <typename DocumentType, typename CharType, size_t N>
1356 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* value) {
1357  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1358 }
1359 
1360 #if RAPIDJSON_HAS_STDSTRING
1361 template <typename DocumentType, typename CharType, size_t N>
1362 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& value) {
1363  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1364 }
1365 #endif
1366 
1367 template <typename DocumentType, typename CharType, size_t N, typename T2>
1368 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1369 SetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) {
1370  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1371 }
1372 
1374 
1375 template <typename T>
1376 typename T::ValueType& SwapValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
1377  return pointer.Swap(root, value, a);
1378 }
1379 
1380 template <typename T, typename CharType, size_t N>
1381 typename T::ValueType& SwapValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
1382  return GenericPointer<typename T::ValueType>(source, N - 1).Swap(root, value, a);
1383 }
1384 
1385 template <typename DocumentType>
1386 typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
1387  return pointer.Swap(document, value);
1388 }
1389 
1390 template <typename DocumentType, typename CharType, size_t N>
1391 typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
1392  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Swap(document, value);
1393 }
1394 
1396 
1397 template <typename T>
1398 bool EraseValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer) {
1399  return pointer.Erase(root);
1400 }
1401 
1402 template <typename T, typename CharType, size_t N>
1403 bool EraseValueByPointer(T& root, const CharType(&source)[N]) {
1404  return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root);
1405 }
1406 
1408 
1410 
1411 #if defined(__clang__) || defined(_MSC_VER)
1412 RAPIDJSON_DIAG_POP
1413 #endif
1414 
1415 #endif // RAPIDJSON_POINTER_H_
A document for parsing JSON text as DOM.
Definition: document.h:2203
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:2491
A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence.
Definition: pointer.h:1086
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition: pointer.h:79
GenericPointer & operator=(const GenericPointer &rhs)
Assignment operator.
Definition: pointer.h:183
friend void swap(GenericPointer &a, GenericPointer &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition: pointer.h:231
Ch * nameBuffer_
A buffer containing all names in tokens.
Definition: pointer.h:1102
Allocator * allocator_
The current allocator. It is either user-supplied or equal to ownAllocator_.
Definition: pointer.h:1100
GenericPointer(const GenericPointer &rhs, Allocator *allocator)
Copy constructor.
Definition: pointer.h:171
GenericPointer(const Ch *source, Allocator *allocator=0)
Constructor that parses a string or URI fragment representation.
Definition: pointer.h:114
ValueType::EncodingType EncodingType
Encoding type from Value.
Definition: pointer.h:81
GenericPointer(const Token *tokens, size_t tokenCount)
Constructor with user-supplied tokens.
Definition: pointer.h:163
GenericPointer(Allocator *allocator=0)
Default constructor.
Definition: pointer.h:107
GenericPointer & Swap(GenericPointer &other) RAPIDJSON_NOEXCEPT
Swap the content of this pointer with an other.
Definition: pointer.h:208
size_t tokenCount_
Number of tokens in tokens_.
Definition: pointer.h:1104
GenericPointer(const GenericPointer &rhs)
Copy constructor.
Definition: pointer.h:166
PointerParseErrorCode parseErrorCode_
Parsing error code.
Definition: pointer.h:1106
Token * tokens_
A list of tokens.
Definition: pointer.h:1103
Allocator * ownAllocator_
Allocator owned by this Pointer.
Definition: pointer.h:1101
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
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
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
Definition: pointer.h:244
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.
ValueType::Ch Ch
Character type from Value.
Definition: pointer.h:82
~GenericPointer()
Destructor.
Definition: pointer.h:176
size_t parseErrorOffset_
Offset in code unit when parsing fail.
Definition: pointer.h:1105
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:657
Concept for allocating, resizing and freeing memory block.
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:406
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:121
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:124
PointerParseErrorCode
Error code of parsing.
Definition: pointer.h:37
@ kPointerParseErrorInvalidEscape
Invalid escape.
Definition: pointer.h:41
@ kPointerParseErrorTokenMustBeginWithSolidus
A token must begin with a '/'.
Definition: pointer.h:40
@ kPointerParseErrorNone
The parse is successful.
Definition: pointer.h:38
@ kPointerParseErrorCharacterMustPercentEncode
A character must percent encoded in URI fragment.
Definition: pointer.h:43
@ kPointerParseErrorInvalidPercentEncoding
Invalid percent encoding in URI fragment.
Definition: pointer.h:42
Type
Type of JSON value.
Definition: rapidjson.h:664
@ kObjectType
object
Definition: rapidjson.h:668
@ kArrayType
array
Definition: rapidjson.h:669
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:651
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:384
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition: rapidjson.h:647
A read-write string stream.
Definition: stream.h:188
A token is the basic units of internal representation.
Definition: pointer.h:97
SizeType index
A valid array index, if it is not equal to kPointerInvalidIndex.
Definition: pointer.h:100
SizeType length
Length of the name.
Definition: pointer.h:99
const Ch * name
Name of the token. It has null character at the end but it can contain null character.
Definition: pointer.h:98
Reference to a constant string (not taking a copy)
Definition: document.h:335
Read-only string stream.
Definition: stream.h:154
Encoding conversion.
Definition: encodings.h:658
UTF-8 encoding.
Definition: encodings.h:96