SimulationCraft
SimulationCraft is a tool to explore combat mechanics in the popular MMO RPG World of Warcraft (tm).
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.
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 "uri.h"
20 #include "internal/itoa.h"
21 
22 #ifdef __clang__
23 RAPIDJSON_DIAG_PUSH
24 RAPIDJSON_DIAG_OFF(switch-enum)
25 #elif defined(_MSC_VER)
26 RAPIDJSON_DIAG_PUSH
27 RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
28 #endif
29 
31 
32 static const SizeType kPointerInvalidIndex = ~SizeType(0);
33 
35 
40 
45 };
46 
48 // GenericPointer
49 
51 
79 template <typename ValueType, typename Allocator = CrtAllocator>
80 class GenericPointer {
81 public:
82  typedef typename ValueType::EncodingType EncodingType;
83  typedef typename ValueType::Ch Ch;
85 
86 
88 
100  struct Token {
101  const Ch* name;
102  SizeType length;
103  SizeType index;
104  };
105 
107 
108 
111 
113 
117  explicit GenericPointer(const Ch* source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
118  Parse(source, internal::StrLen(source));
119  }
120 
121 #if RAPIDJSON_HAS_STDSTRING
122 
128  explicit GenericPointer(const std::basic_string<Ch>& source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
129  Parse(source.c_str(), source.size());
130  }
131 #endif
132 
134 
140  GenericPointer(const Ch* source, size_t length, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
141  Parse(source, length);
142  }
143 
145 
166  GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
167 
170  *this = rhs;
171  }
172 
175  *this = rhs;
176  }
177 
180  if (nameBuffer_) // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and tokens_ are not deallocated.
181  Allocator::Free(tokens_);
182  RAPIDJSON_DELETE(ownAllocator_);
183  }
184 
187  if (this != &rhs) {
188  // Do not delete ownAllcator
189  if (nameBuffer_)
190  Allocator::Free(tokens_);
191 
192  tokenCount_ = rhs.tokenCount_;
195 
196  if (rhs.nameBuffer_)
197  CopyFromRaw(rhs); // Normally parsed tokens.
198  else {
199  tokens_ = rhs.tokens_; // User supplied const tokens.
200  nameBuffer_ = 0;
201  }
202  }
203  return *this;
204  }
205 
207 
211  GenericPointer& Swap(GenericPointer& other) RAPIDJSON_NOEXCEPT {
212  internal::Swap(allocator_, other.allocator_);
213  internal::Swap(ownAllocator_, other.ownAllocator_);
214  internal::Swap(nameBuffer_, other.nameBuffer_);
215  internal::Swap(tokens_, other.tokens_);
216  internal::Swap(tokenCount_, other.tokenCount_);
217  internal::Swap(parseErrorOffset_, other.parseErrorOffset_);
218  internal::Swap(parseErrorCode_, other.parseErrorCode_);
219  return *this;
220  }
221 
223 
234  friend inline void swap(GenericPointer& a, GenericPointer& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
235 
237 
239 
240 
242 
247  GenericPointer Append(const Token& token, Allocator* allocator = 0) const {
248  GenericPointer r;
249  r.allocator_ = allocator;
250  Ch *p = r.CopyFromRaw(*this, 1, token.length + 1);
251  std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch));
252  r.tokens_[tokenCount_].name = p;
253  r.tokens_[tokenCount_].length = token.length;
254  r.tokens_[tokenCount_].index = token.index;
255  return r;
256  }
257 
259 
265  GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const {
266  Token token = { name, length, kPointerInvalidIndex };
267  return Append(token, allocator);
268  }
269 
271 
276  template <typename T>
277  RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >), (GenericPointer))
278  Append(T* name, Allocator* allocator = 0) const {
279  return Append(name, internal::StrLen(name), allocator);
280  }
281 
282 #if RAPIDJSON_HAS_STDSTRING
283 
289  GenericPointer Append(const std::basic_string<Ch>& name, Allocator* allocator = 0) const {
290  return Append(name.c_str(), static_cast<SizeType>(name.size()), allocator);
291  }
292 #endif
293 
295 
300  GenericPointer Append(SizeType index, Allocator* allocator = 0) const {
301  char buffer[21];
302  char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer);
303  SizeType length = static_cast<SizeType>(end - buffer);
304  buffer[length] = '\0';
305 
306  if (sizeof(Ch) == 1) {
307  Token token = { reinterpret_cast<Ch*>(buffer), length, index };
308  return Append(token, allocator);
309  }
310  else {
311  Ch name[21];
312  for (size_t i = 0; i <= length; i++)
313  name[i] = static_cast<Ch>(buffer[i]);
314  Token token = { name, length, index };
315  return Append(token, allocator);
316  }
317  }
318 
320 
325  GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const {
326  if (token.IsString())
327  return Append(token.GetString(), token.GetStringLength(), allocator);
328  else {
329  RAPIDJSON_ASSERT(token.IsUint64());
330  RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0));
331  return Append(static_cast<SizeType>(token.GetUint64()), allocator);
332  }
333  }
334 
336 
337 
339  bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; }
340 
342  size_t GetParseErrorOffset() const { return parseErrorOffset_; }
343 
345  PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; }
346 
348 
350  Allocator& GetAllocator() { return *allocator_; }
351 
353 
354 
356  const Token* GetTokens() const { return tokens_; }
357 
359  size_t GetTokenCount() const { return tokenCount_; }
360 
362 
364 
365 
367 
370  bool operator==(const GenericPointer& rhs) const {
371  if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_)
372  return false;
373 
374  for (size_t i = 0; i < tokenCount_; i++) {
375  if (tokens_[i].index != rhs.tokens_[i].index ||
376  tokens_[i].length != rhs.tokens_[i].length ||
377  (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch)* tokens_[i].length) != 0))
378  {
379  return false;
380  }
381  }
382 
383  return true;
384  }
385 
387 
390  bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }
391 
393 
396  bool operator<(const GenericPointer& rhs) const {
397  if (!IsValid())
398  return false;
399  if (!rhs.IsValid())
400  return true;
401 
402  if (tokenCount_ != rhs.tokenCount_)
403  return tokenCount_ < rhs.tokenCount_;
404 
405  for (size_t i = 0; i < tokenCount_; i++) {
406  if (tokens_[i].index != rhs.tokens_[i].index)
407  return tokens_[i].index < rhs.tokens_[i].index;
408 
409  if (tokens_[i].length != rhs.tokens_[i].length)
410  return tokens_[i].length < rhs.tokens_[i].length;
411 
412  if (int cmp = std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length))
413  return cmp < 0;
414  }
415 
416  return false;
417  }
418 
420 
422 
423 
425 
429  template<typename OutputStream>
430  bool Stringify(OutputStream& os) const {
431  return Stringify<false, OutputStream>(os);
432  }
433 
435 
439  template<typename OutputStream>
440  bool StringifyUriFragment(OutputStream& os) const {
441  return Stringify<true, OutputStream>(os);
442  }
443 
445 
447 
448 
450 
464  ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const {
465  RAPIDJSON_ASSERT(IsValid());
466  ValueType* v = &root;
467  bool exist = true;
468  for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
469  if (v->IsArray() && t->name[0] == '-' && t->length == 1) {
470  v->PushBack(ValueType().Move(), allocator);
471  v = &((*v)[v->Size() - 1]);
472  exist = false;
473  }
474  else {
475  if (t->index == kPointerInvalidIndex) { // must be object name
476  if (!v->IsObject())
477  v->SetObject(); // Change to Object
478  }
479  else { // object name or array index
480  if (!v->IsArray() && !v->IsObject())
481  v->SetArray(); // Change to Array
482  }
483 
484  if (v->IsArray()) {
485  if (t->index >= v->Size()) {
486  v->Reserve(t->index + 1, allocator);
487  while (t->index >= v->Size())
488  v->PushBack(ValueType().Move(), allocator);
489  exist = false;
490  }
491  v = &((*v)[t->index]);
492  }
493  else {
494  typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
495  if (m == v->MemberEnd()) {
496  v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
497  m = v->MemberEnd();
498  v = &(--m)->value; // Assumes AddMember() appends at the end
499  exist = false;
500  }
501  else
502  v = &m->value;
503  }
504  }
505  }
506 
507  if (alreadyExist)
508  *alreadyExist = exist;
509 
510  return *v;
511  }
512 
514 
519  template <typename stackAllocator>
520  ValueType& Create(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, bool* alreadyExist = 0) const {
521  return Create(document, document.GetAllocator(), alreadyExist);
522  }
523 
525 
527 
528 
530  // For use with JSON pointers into JSON schema documents.
546  UriType GetUri(ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0, Allocator* allocator = 0) const {
547  static const Ch kIdString[] = { 'i', 'd', '\0' };
548  static const ValueType kIdValue(kIdString, 2);
549  UriType base = UriType(rootUri, allocator);
550  RAPIDJSON_ASSERT(IsValid());
551  ValueType* v = &root;
552  for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
553  switch (v->GetType()) {
554  case kObjectType:
555  {
556  // See if we have an id, and if so resolve with the current base
557  typename ValueType::MemberIterator m = v->FindMember(kIdValue);
558  if (m != v->MemberEnd() && (m->value).IsString()) {
559  UriType here = UriType(m->value, allocator).Resolve(base, allocator);
560  base = here;
561  }
562  m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
563  if (m == v->MemberEnd())
564  break;
565  v = &m->value;
566  }
567  continue;
568  case kArrayType:
569  if (t->index == kPointerInvalidIndex || t->index >= v->Size())
570  break;
571  v = &((*v)[t->index]);
572  continue;
573  default:
574  break;
575  }
576 
577  // Error: unresolved token
578  if (unresolvedTokenIndex)
579  *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
580  return UriType(allocator);
581  }
582  return base;
583  }
584 
585  UriType GetUri(const ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0, Allocator* allocator = 0) const {
586  return GetUri(const_cast<ValueType&>(root), rootUri, unresolvedTokenIndex, allocator);
587  }
588 
589 
591 
592 
594 
607  ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const {
608  RAPIDJSON_ASSERT(IsValid());
609  ValueType* v = &root;
610  for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
611  switch (v->GetType()) {
612  case kObjectType:
613  {
614  typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
615  if (m == v->MemberEnd())
616  break;
617  v = &m->value;
618  }
619  continue;
620  case kArrayType:
621  if (t->index == kPointerInvalidIndex || t->index >= v->Size())
622  break;
623  v = &((*v)[t->index]);
624  continue;
625  default:
626  break;
627  }
628 
629  // Error: unresolved token
630  if (unresolvedTokenIndex)
631  *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
632  return 0;
633  }
634  return v;
635  }
636 
638 
642  const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const {
643  return Get(const_cast<ValueType&>(root), unresolvedTokenIndex);
644  }
645 
647 
649 
650 
652 
661  ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const {
662  bool alreadyExist;
663  ValueType& v = Create(root, allocator, &alreadyExist);
664  return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
665  }
666 
668  ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const {
669  bool alreadyExist;
670  ValueType& v = Create(root, allocator, &alreadyExist);
671  return alreadyExist ? v : v.SetString(defaultValue, allocator);
672  }
673 
674 #if RAPIDJSON_HAS_STDSTRING
675  ValueType& GetWithDefault(ValueType& root, const std::basic_string<Ch>& defaultValue, typename ValueType::AllocatorType& allocator) const {
677  bool alreadyExist;
678  ValueType& v = Create(root, allocator, &alreadyExist);
679  return alreadyExist ? v : v.SetString(defaultValue, allocator);
680  }
681 #endif
682 
684 
687  template <typename T>
688  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
689  GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator) const {
690  return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);
691  }
692 
694  template <typename stackAllocator>
695  ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& defaultValue) const {
696  return GetWithDefault(document, defaultValue, document.GetAllocator());
697  }
698 
700  template <typename stackAllocator>
701  ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* defaultValue) const {
702  return GetWithDefault(document, defaultValue, document.GetAllocator());
703  }
704 
705 #if RAPIDJSON_HAS_STDSTRING
706  template <typename stackAllocator>
708  ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& defaultValue) const {
709  return GetWithDefault(document, defaultValue, document.GetAllocator());
710  }
711 #endif
712 
714 
717  template <typename T, typename stackAllocator>
718  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
719  GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T defaultValue) const {
720  return GetWithDefault(document, defaultValue, document.GetAllocator());
721  }
722 
724 
726 
727 
729 
738  ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
739  return Create(root, allocator) = value;
740  }
741 
743  ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const {
744  return Create(root, allocator).CopyFrom(value, allocator);
745  }
746 
748  ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const {
749  return Create(root, allocator) = ValueType(value, allocator).Move();
750  }
751 
752 #if RAPIDJSON_HAS_STDSTRING
753  ValueType& Set(ValueType& root, const std::basic_string<Ch>& value, typename ValueType::AllocatorType& allocator) const {
755  return Create(root, allocator) = ValueType(value, allocator).Move();
756  }
757 #endif
758 
760 
763  template <typename T>
764  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
765  Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const {
766  return Create(root, allocator) = ValueType(value).Move();
767  }
768 
770  template <typename stackAllocator>
771  ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const {
772  return Create(document) = value;
773  }
774 
776  template <typename stackAllocator>
777  ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& value) const {
778  return Create(document).CopyFrom(value, document.GetAllocator());
779  }
780 
782  template <typename stackAllocator>
783  ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* value) const {
784  return Create(document) = ValueType(value, document.GetAllocator()).Move();
785  }
786 
787 #if RAPIDJSON_HAS_STDSTRING
788  template <typename stackAllocator>
790  ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& value) const {
791  return Create(document) = ValueType(value, document.GetAllocator()).Move();
792  }
793 #endif
794 
796 
799  template <typename T, typename stackAllocator>
800  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
802  return Create(document) = value;
803  }
804 
806 
808 
809 
811 
820  ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
821  return Create(root, allocator).Swap(value);
822  }
823 
825  template <typename stackAllocator>
826  ValueType& Swap(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const {
827  return Create(document).Swap(value);
828  }
829 
831 
833 
839  bool Erase(ValueType& root) const {
840  RAPIDJSON_ASSERT(IsValid());
841  if (tokenCount_ == 0) // Cannot erase the root
842  return false;
843 
844  ValueType* v = &root;
845  const Token* last = tokens_ + (tokenCount_ - 1);
846  for (const Token *t = tokens_; t != last; ++t) {
847  switch (v->GetType()) {
848  case kObjectType:
849  {
850  typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
851  if (m == v->MemberEnd())
852  return false;
853  v = &m->value;
854  }
855  break;
856  case kArrayType:
857  if (t->index == kPointerInvalidIndex || t->index >= v->Size())
858  return false;
859  v = &((*v)[t->index]);
860  break;
861  default:
862  return false;
863  }
864  }
865 
866  switch (v->GetType()) {
867  case kObjectType:
868  return v->EraseMember(GenericStringRef<Ch>(last->name, last->length));
869  case kArrayType:
870  if (last->index == kPointerInvalidIndex || last->index >= v->Size())
871  return false;
872  v->Erase(v->Begin() + last->index);
873  return true;
874  default:
875  return false;
876  }
877  }
878 
879 private:
881 
887  Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0) {
888  if (!allocator_) // allocator is independently owned.
889  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
890 
891  size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens
892  for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)
893  nameBufferSize += t->length;
894 
895  tokenCount_ = rhs.tokenCount_ + extraToken;
896  tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch)));
897  nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
898  if (rhs.tokenCount_ > 0) {
899  std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token));
900  }
901  if (nameBufferSize > 0) {
902  std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
903  }
904 
905  // Adjust pointers to name buffer
906  std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;
907  for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t)
908  t->name += diff;
909 
910  return nameBuffer_ + nameBufferSize;
911  }
912 
914 
918  bool NeedPercentEncode(Ch c) const {
919  return !((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~');
920  }
921 
923 #ifndef __clang__ // -Wdocumentation
924 
929 #endif
930  void Parse(const Ch* source, size_t length) {
931  RAPIDJSON_ASSERT(source != NULL);
934 
935  // Create own allocator if user did not supply.
936  if (!allocator_)
937  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
938 
939  // Count number of '/' as tokenCount
940  tokenCount_ = 0;
941  for (const Ch* s = source; s != source + length; s++)
942  if (*s == '/')
943  tokenCount_++;
944 
945  Token* token = tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch)));
946  Ch* name = nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
947  size_t i = 0;
948 
949  // Detect if it is a URI fragment
950  bool uriFragment = false;
951  if (source[i] == '#') {
952  uriFragment = true;
953  i++;
954  }
955 
956  if (i != length && source[i] != '/') {
958  goto error;
959  }
960 
961  while (i < length) {
962  RAPIDJSON_ASSERT(source[i] == '/');
963  i++; // consumes '/'
964 
965  token->name = name;
966  bool isNumber = true;
967 
968  while (i < length && source[i] != '/') {
969  Ch c = source[i];
970  if (uriFragment) {
971  // Decoding percent-encoding for URI fragment
972  if (c == '%') {
973  PercentDecodeStream is(&source[i], source + length);
975  Ch* begin = os.PutBegin();
976  if (!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid()) {
978  goto error;
979  }
980  size_t len = os.PutEnd(begin);
981  i += is.Tell() - 1;
982  if (len == 1)
983  c = *name;
984  else {
985  name += len;
986  isNumber = false;
987  i++;
988  continue;
989  }
990  }
991  else if (NeedPercentEncode(c)) {
993  goto error;
994  }
995  }
996 
997  i++;
998 
999  // Escaping "~0" -> '~', "~1" -> '/'
1000  if (c == '~') {
1001  if (i < length) {
1002  c = source[i];
1003  if (c == '0') c = '~';
1004  else if (c == '1') c = '/';
1005  else {
1007  goto error;
1008  }
1009  i++;
1010  }
1011  else {
1013  goto error;
1014  }
1015  }
1016 
1017  // First check for index: all of characters are digit
1018  if (c < '0' || c > '9')
1019  isNumber = false;
1020 
1021  *name++ = c;
1022  }
1023  token->length = static_cast<SizeType>(name - token->name);
1024  if (token->length == 0)
1025  isNumber = false;
1026  *name++ = '\0'; // Null terminator
1027 
1028  // Second check for index: more than one digit cannot have leading zero
1029  if (isNumber && token->length > 1 && token->name[0] == '0')
1030  isNumber = false;
1031 
1032  // String to SizeType conversion
1033  SizeType n = 0;
1034  if (isNumber) {
1035  for (size_t j = 0; j < token->length; j++) {
1036  SizeType m = n * 10 + static_cast<SizeType>(token->name[j] - '0');
1037  if (m < n) { // overflow detection
1038  isNumber = false;
1039  break;
1040  }
1041  n = m;
1042  }
1043  }
1044 
1045  token->index = isNumber ? n : kPointerInvalidIndex;
1046  token++;
1047  }
1048 
1049  RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer
1051  return;
1052 
1053  error:
1054  Allocator::Free(tokens_);
1055  nameBuffer_ = 0;
1056  tokens_ = 0;
1057  tokenCount_ = 0;
1058  parseErrorOffset_ = i;
1059  return;
1060  }
1061 
1063 
1068  template<bool uriFragment, typename OutputStream>
1069  bool Stringify(OutputStream& os) const {
1070  RAPIDJSON_ASSERT(IsValid());
1071 
1072  if (uriFragment)
1073  os.Put('#');
1074 
1075  for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
1076  os.Put('/');
1077  for (size_t j = 0; j < t->length; j++) {
1078  Ch c = t->name[j];
1079  if (c == '~') {
1080  os.Put('~');
1081  os.Put('0');
1082  }
1083  else if (c == '/') {
1084  os.Put('~');
1085  os.Put('1');
1086  }
1087  else if (uriFragment && NeedPercentEncode(c)) {
1088  // Transcode to UTF8 sequence
1091  if (!Transcoder<EncodingType, UTF8<> >().Validate(source, target))
1092  return false;
1093  j += source.Tell() - 1;
1094  }
1095  else
1096  os.Put(c);
1097  }
1098  }
1099  return true;
1100  }
1101 
1103 
1108  class PercentDecodeStream {
1109  public:
1110  typedef typename ValueType::Ch Ch;
1111 
1113 
1117  PercentDecodeStream(const Ch* source, const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {}
1118 
1119  Ch Take() {
1120  if (*src_ != '%' || src_ + 3 > end_) { // %XY triplet
1121  valid_ = false;
1122  return 0;
1123  }
1124  src_++;
1125  Ch c = 0;
1126  for (int j = 0; j < 2; j++) {
1127  c = static_cast<Ch>(c << 4);
1128  Ch h = *src_;
1129  if (h >= '0' && h <= '9') c = static_cast<Ch>(c + h - '0');
1130  else if (h >= 'A' && h <= 'F') c = static_cast<Ch>(c + h - 'A' + 10);
1131  else if (h >= 'a' && h <= 'f') c = static_cast<Ch>(c + h - 'a' + 10);
1132  else {
1133  valid_ = false;
1134  return 0;
1135  }
1136  src_++;
1137  }
1138  return c;
1139  }
1140 
1141  size_t Tell() const { return static_cast<size_t>(src_ - head_); }
1142  bool IsValid() const { return valid_; }
1143 
1144  private:
1145  const Ch* src_;
1146  const Ch* head_;
1147  const Ch* end_;
1148  bool valid_;
1149  };
1150 
1152  template <typename OutputStream>
1154  public:
1155  PercentEncodeStream(OutputStream& os) : os_(os) {}
1156  void Put(char c) { // UTF-8 must be byte
1157  unsigned char u = static_cast<unsigned char>(c);
1158  static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1159  os_.Put('%');
1160  os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u >> 4]));
1161  os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u & 15]));
1162  }
1163  private:
1164  OutputStream& os_;
1165  };
1166 
1167  Allocator* allocator_;
1168  Allocator* ownAllocator_;
1171  size_t tokenCount_;
1174 };
1175 
1178 
1180 
1181 
1183 
1184 template <typename T>
1185 typename T::ValueType& CreateValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::AllocatorType& a) {
1186  return pointer.Create(root, a);
1187 }
1188 
1189 template <typename T, typename CharType, size_t N>
1190 typename T::ValueType& CreateValueByPointer(T& root, const CharType(&source)[N], typename T::AllocatorType& a) {
1191  return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a);
1192 }
1193 
1194 // No allocator parameter
1195 
1196 template <typename DocumentType>
1197 typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer) {
1198  return pointer.Create(document);
1199 }
1200 
1201 template <typename DocumentType, typename CharType, size_t N>
1202 typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const CharType(&source)[N]) {
1203  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document);
1204 }
1205 
1207 
1208 template <typename T>
1209 typename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
1210  return pointer.Get(root, unresolvedTokenIndex);
1211 }
1212 
1213 template <typename T>
1214 const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
1215  return pointer.Get(root, unresolvedTokenIndex);
1216 }
1217 
1218 template <typename T, typename CharType, size_t N>
1219 typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) {
1220  return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1221 }
1222 
1223 template <typename T, typename CharType, size_t N>
1224 const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) {
1225  return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1226 }
1227 
1229 
1230 template <typename T>
1231 typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
1232  return pointer.GetWithDefault(root, defaultValue, a);
1233 }
1234 
1235 template <typename T>
1236 typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* defaultValue, typename T::AllocatorType& a) {
1237  return pointer.GetWithDefault(root, defaultValue, a);
1238 }
1239 
1240 #if RAPIDJSON_HAS_STDSTRING
1241 template <typename T>
1242 typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {
1243  return pointer.GetWithDefault(root, defaultValue, a);
1244 }
1245 #endif
1246 
1247 template <typename T, typename T2>
1248 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1249 GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 defaultValue, typename T::AllocatorType& a) {
1250  return pointer.GetWithDefault(root, defaultValue, a);
1251 }
1252 
1253 template <typename T, typename CharType, size_t N>
1254 typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
1255  return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1256 }
1257 
1258 template <typename T, typename CharType, size_t N>
1259 typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::Ch* defaultValue, typename T::AllocatorType& a) {
1260  return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1261 }
1262 
1263 #if RAPIDJSON_HAS_STDSTRING
1264 template <typename T, typename CharType, size_t N>
1265 typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {
1266  return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1267 }
1268 #endif
1269 
1270 template <typename T, typename CharType, size_t N, typename T2>
1271 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1272 GetValueByPointerWithDefault(T& root, const CharType(&source)[N], T2 defaultValue, typename T::AllocatorType& a) {
1273  return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1274 }
1275 
1276 // No allocator parameter
1277 
1278 template <typename DocumentType>
1279 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& defaultValue) {
1280  return pointer.GetWithDefault(document, defaultValue);
1281 }
1282 
1283 template <typename DocumentType>
1284 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* defaultValue) {
1285  return pointer.GetWithDefault(document, defaultValue);
1286 }
1287 
1288 #if RAPIDJSON_HAS_STDSTRING
1289 template <typename DocumentType>
1290 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1291  return pointer.GetWithDefault(document, defaultValue);
1292 }
1293 #endif
1294 
1295 template <typename DocumentType, typename T2>
1296 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1297 GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 defaultValue) {
1298  return pointer.GetWithDefault(document, defaultValue);
1299 }
1300 
1301 template <typename DocumentType, typename CharType, size_t N>
1302 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& defaultValue) {
1303  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1304 }
1305 
1306 template <typename DocumentType, typename CharType, size_t N>
1307 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* defaultValue) {
1308  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1309 }
1310 
1311 #if RAPIDJSON_HAS_STDSTRING
1312 template <typename DocumentType, typename CharType, size_t N>
1313 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1314  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1315 }
1316 #endif
1317 
1318 template <typename DocumentType, typename CharType, size_t N, typename T2>
1319 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1320 GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) {
1321  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1322 }
1323 
1325 
1326 template <typename T>
1327 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
1328  return pointer.Set(root, value, a);
1329 }
1330 
1331 template <typename T>
1332 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& value, typename T::AllocatorType& a) {
1333  return pointer.Set(root, value, a);
1334 }
1335 
1336 template <typename T>
1337 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* value, typename T::AllocatorType& a) {
1338  return pointer.Set(root, value, a);
1339 }
1340 
1341 #if RAPIDJSON_HAS_STDSTRING
1342 template <typename T>
1343 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {
1344  return pointer.Set(root, value, a);
1345 }
1346 #endif
1347 
1348 template <typename T, typename T2>
1349 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1350 SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 value, typename T::AllocatorType& a) {
1351  return pointer.Set(root, value, a);
1352 }
1353 
1354 template <typename T, typename CharType, size_t N>
1355 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
1356  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1357 }
1358 
1359 template <typename T, typename CharType, size_t N>
1360 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::ValueType& value, typename T::AllocatorType& a) {
1361  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1362 }
1363 
1364 template <typename T, typename CharType, size_t N>
1365 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::Ch* value, typename T::AllocatorType& a) {
1366  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1367 }
1368 
1369 #if RAPIDJSON_HAS_STDSTRING
1370 template <typename T, typename CharType, size_t N>
1371 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {
1372  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1373 }
1374 #endif
1375 
1376 template <typename T, typename CharType, size_t N, typename T2>
1377 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1378 SetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) {
1379  return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1380 }
1381 
1382 // No allocator parameter
1383 
1384 template <typename DocumentType>
1385 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
1386  return pointer.Set(document, value);
1387 }
1388 
1389 template <typename DocumentType>
1390 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& value) {
1391  return pointer.Set(document, value);
1392 }
1393 
1394 template <typename DocumentType>
1395 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* value) {
1396  return pointer.Set(document, value);
1397 }
1398 
1399 #if RAPIDJSON_HAS_STDSTRING
1400 template <typename DocumentType>
1401 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& value) {
1402  return pointer.Set(document, value);
1403 }
1404 #endif
1405 
1406 template <typename DocumentType, typename T2>
1407 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1408 SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 value) {
1409  return pointer.Set(document, value);
1410 }
1411 
1412 template <typename DocumentType, typename CharType, size_t N>
1413 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
1414  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1415 }
1416 
1417 template <typename DocumentType, typename CharType, size_t N>
1418 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& value) {
1419  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1420 }
1421 
1422 template <typename DocumentType, typename CharType, size_t N>
1423 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* value) {
1424  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1425 }
1426 
1427 #if RAPIDJSON_HAS_STDSTRING
1428 template <typename DocumentType, typename CharType, size_t N>
1429 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& value) {
1430  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1431 }
1432 #endif
1433 
1434 template <typename DocumentType, typename CharType, size_t N, typename T2>
1435 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1436 SetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) {
1437  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1438 }
1439 
1441 
1442 template <typename T>
1443 typename T::ValueType& SwapValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
1444  return pointer.Swap(root, value, a);
1445 }
1446 
1447 template <typename T, typename CharType, size_t N>
1448 typename T::ValueType& SwapValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
1449  return GenericPointer<typename T::ValueType>(source, N - 1).Swap(root, value, a);
1450 }
1451 
1452 template <typename DocumentType>
1453 typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
1454  return pointer.Swap(document, value);
1455 }
1456 
1457 template <typename DocumentType, typename CharType, size_t N>
1458 typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
1459  return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Swap(document, value);
1460 }
1461 
1463 
1464 template <typename T>
1465 bool EraseValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer) {
1466  return pointer.Erase(root);
1467 }
1468 
1469 template <typename T, typename CharType, size_t N>
1470 bool EraseValueByPointer(T& root, const CharType(&source)[N]) {
1471  return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root);
1472 }
1473 
1475 
1477 
1478 #if defined(__clang__) || defined(_MSC_VER)
1479 RAPIDJSON_DIAG_POP
1480 #endif
1481 
1482 #endif // RAPIDJSON_POINTER_H_
PointerParseErrorCode
Error code of parsing.
Definition: pointer.h:38
GenericPointer(const Ch *source, Allocator *allocator=0)
Constructor that parses a string or URI fragment representation.
Definition: pointer.h:117
SizeType length
Length of the name.
Definition: pointer.h:102
A token is the basic units of internal representation.
Definition: pointer.h:100
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:140
Token * tokens_
A list of tokens.
Definition: pointer.h:1170
Invalid percent encoding in URI fragment.
Definition: pointer.h:43
~GenericPointer()
Destructor.
Definition: pointer.h:179
size_t tokenCount_
Number of tokens in tokens_.
Definition: pointer.h:1171
GenericPointer(const GenericPointer &rhs, Allocator *allocator)
Copy constructor.
Definition: pointer.h:174
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:66
GenericPointer(const Token *tokens, size_t tokenCount)
Constructor with user-supplied tokens.
Definition: pointer.h:166
GenericPointer & Swap(GenericPointer &other) RAPIDJSON_NOEXCEPT
Swap the content of this pointer with an other.
Definition: pointer.h:211
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:121
ValueType::EncodingType EncodingType
Encoding type from Value.
Definition: pointer.h:82
The parse is successful.
Definition: pointer.h:39
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:2782
Encoding conversion.
Definition: encodings.h:658
ValueType::Ch Ch
Character type from Value.
Definition: pointer.h:83
A contiguous memory buffer with an optional growing ability.
Definition: core.h:778
Definition: document.h:509
size_t parseErrorOffset_
Offset in code unit when parsing fail.
Definition: pointer.h:1172
Reference to a constant string (not taking a copy)
Definition: document.h:346
SizeType index
A valid array index, if it is not equal to kPointerInvalidIndex.
Definition: pointer.h:103
Read-only string stream.
Definition: fwd.h:47
A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence.
Definition: pointer.h:1153
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 Append(const Ch *name, SizeType length, Allocator *allocator=0) const
Append a name token with length, and return a new Pointer.
Definition: pointer.h:265
Ch * nameBuffer_
A buffer containing all names in tokens.
Definition: pointer.h:1169
A character must percent encoded in URI fragment.
Definition: pointer.h:44
Allocator * ownAllocator_
Allocator owned by this Pointer.
Definition: pointer.h:1168
GenericPointer(const GenericPointer &rhs)
Copy constructor.
Definition: pointer.h:169
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
Definition: pointer.h:247
A token must begin with a &#39;/&#39;.
Definition: pointer.h:41
PointerParseErrorCode parseErrorCode_
Parsing error code.
Definition: pointer.h:1173
friend void swap(GenericPointer &a, GenericPointer &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition: pointer.h:234
GenericPointer(Allocator *allocator=0)
Default constructor.
Definition: pointer.h:110
Definition: core.h:1208
A read-write string stream.
Definition: fwd.h:52
Definition: uri.h:33
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:437
Invalid escape.
Definition: pointer.h:42
RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr< internal::IsSame< typename internal::RemoveConst< T >::Type, Ch > >),(GenericPointer)) Append(T *name
Append a name token without length, and return a new Pointer.
Allocator * allocator_
The current allocator. It is either user-supplied or equal to ownAllocator_.
Definition: pointer.h:1167
const Ch * name
Name of the token. It has null character at the end but it can contain null character.
Definition: pointer.h:101
A document for parsing JSON text as DOM.
Definition: document.h:69
GenericPointer & operator=(const GenericPointer &rhs)
Assignment operator.
Definition: pointer.h:186
UTF-8 encoding.
Definition: encodings.h:96