Elaztek Developer Hub
Blamite Game Engine - blam!  00398.09.22.23.2015.blamite
The core library for the Blamite Game Engine.
pointer.h
Go to the documentation of this file.
1 // Tencent is pleased to support the open source community by making RapidJSON available.
2 //
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
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;
104  };
105 
107 
108 
111 
113 
118  Parse(source, internal::StrLen(source));
119  }
120 
121 #if RAPIDJSON_HAS_STDSTRING
122 
129  Parse(source.c_str(), source.size());
130  }
131 #endif
132 
134 
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.
183  }
184 
187  if (this != &rhs) {
188  // Do not delete ownAllcator
189  if (nameBuffer_)
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 {
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>
696  return GetWithDefault(document, defaultValue, document.GetAllocator());
697  }
698 
700  template <typename stackAllocator>
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&))
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>
772  return Create(document) = value;
773  }
774 
776  template <typename stackAllocator>
778  return Create(document).CopyFrom(value, document.GetAllocator());
779  }
780 
782  template <typename stackAllocator>
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>
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.
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) {
934 
935  // Create own allocator if user did not supply.
936  if (!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:
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
1090  PercentEncodeStream<OutputStream> target(os);
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 
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]) {
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&))
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) {
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) {
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) {
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) {
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&))
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) {
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) {
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) {
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) {
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) {
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) {
1460 }
1461 
1463 
1464 template <typename T>
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_
GenericPointer
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition: fwd.h:126
RAPIDJSON_NAMESPACE_END
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:124
value
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1350
uri.h
kPointerParseErrorTokenMustBeginWithSolidus
@ kPointerParseErrorTokenMustBeginWithSolidus
A token must begin with a '/'.
Definition: pointer.h:41
RAPIDJSON_NAMESPACE_BEGIN
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:121
GetValueByPointerWithDefault
T::ValueType & GetValueByPointerWithDefault(T &root, const GenericPointer< typename T::ValueType > &pointer, const typename T::ValueType &defaultValue, typename T::AllocatorType &a)
Definition: pointer.h:1231
internal::IsGenericValue
Definition: document.h:509
GenericDocument
A document for parsing JSON text as DOM.
Definition: document.h:69
GenericPointer::UriType
GenericUri< ValueType, Allocator > UriType
Definition: pointer.h:84
Allocator
Concept for allocating, resizing and freeing memory block.
kArrayType
@ kArrayType
array
Definition: rapidjson.h:734
Transcoder
Encoding conversion.
Definition: encodings.h:658
Type
Type
Type of JSON value.
Definition: rapidjson.h:729
kPointerParseErrorInvalidPercentEncoding
@ kPointerParseErrorInvalidPercentEncoding
Invalid percent encoding in URI fragment.
Definition: pointer.h:43
GenericPointer::nameBuffer_
Ch * nameBuffer_
A buffer containing all names in tokens.
Definition: pointer.h:1169
GenericPointer::PercentEncodeStream::Put
void Put(char c)
Definition: pointer.h:1156
PointerParseErrorCode
PointerParseErrorCode
Error code of parsing.
Definition: pointer.h:38
document.h
GenericPointer::Append
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
GenericPointer::GenericPointer
GenericPointer(const GenericPointer &rhs)
Copy constructor.
Definition: pointer.h:169
GenericPointer::Append
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
Definition: pointer.h:247
kObjectType
@ kObjectType
object
Definition: rapidjson.h:733
GenericPointer::swap
friend void swap(GenericPointer &a, GenericPointer &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition: pointer.h:234
GenericPointer::parseErrorCode_
PointerParseErrorCode parseErrorCode_
Parsing error code.
Definition: pointer.h:1173
GenericPointer::GenericPointer
GenericPointer(Allocator *allocator=0)
Default constructor.
Definition: pointer.h:110
GenericPointer::Token
A token is the basic units of internal representation.
Definition: pointer.h:100
SwapValueByPointer
T::ValueType & SwapValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition: pointer.h:1443
kPointerParseErrorInvalidEscape
@ kPointerParseErrorInvalidEscape
Invalid escape.
Definition: pointer.h:42
GenericPointer::ownAllocator_
Allocator * ownAllocator_
Allocator owned by this Pointer.
Definition: pointer.h:1168
GenericInsituStringStream
A read-write string stream.
Definition: fwd.h:52
SizeType
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:415
NULL
Add a fourth parameter to bake specific font ranges NULL
Definition: README.txt:57
Pointer
GenericPointer< Value > Pointer
GenericPointer for Value (UTF-8, default allocator).
Definition: pointer.h:1177
GenericStringStream
Read-only string stream.
Definition: fwd.h:47
GenericPointer::allocator_
Allocator * allocator_
The current allocator. It is either user-supplied or equal to ownAllocator_.
Definition: pointer.h:1167
GenericPointer::RAPIDJSON_DISABLEIF_RETURN
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.
RAPIDJSON_ASSERT
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:437
itoa.h
GenericPointer::Token::length
SizeType length
Length of the name.
Definition: pointer.h:102
CreateValueByPointer
T::ValueType & CreateValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::AllocatorType &a)
Definition: pointer.h:1185
GenericPointer::operator=
GenericPointer & operator=(const GenericPointer &rhs)
Assignment operator.
Definition: pointer.h:186
a
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1249
kPointerParseErrorNone
@ kPointerParseErrorNone
The parse is successful.
Definition: pointer.h:39
GenericPointer::GenericPointer
GenericPointer(const Ch *source, Allocator *allocator=0)
Constructor that parses a string or URI fragment representation.
Definition: pointer.h:117
document
ARPHIC PUBLIC LICENSE Ltd Yung Chi Taiwan All rights reserved except as specified below Everyone is permitted to copy and distribute verbatim copies of this license document
Definition: ARPHICPL.TXT:7
GenericPointer::Token::index
SizeType index
A valid array index, if it is not equal to kPointerInvalidIndex.
Definition: pointer.h:103
GenericPointer::tokens_
Token * tokens_
A list of tokens.
Definition: pointer.h:1170
GenericPointer::~GenericPointer
~GenericPointer()
Destructor.
Definition: pointer.h:179
kPointerParseErrorCharacterMustPercentEncode
@ kPointerParseErrorCharacterMustPercentEncode
A character must percent encoded in URI fragment.
Definition: pointer.h:44
GenericPointer::GenericPointer
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
GenericPointer::Token::name
const Ch * name
Name of the token. It has null character at the end but it can contain null character.
Definition: pointer.h:101
Free
void Free(A &a, T *p, size_t n=1)
Definition: allocators.h:447
RAPIDJSON_NEW
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition: rapidjson.h:712
RAPIDJSON_DELETE
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:716
defaultValue
const GenericPointer< typename T::ValueType > T2 defaultValue
Definition: pointer.h:1249
GenericPointer::tokenCount_
size_t tokenCount_
Number of tokens in tokens_.
Definition: pointer.h:1171
GenericValue
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:66
UTF8
UTF-8 encoding.
Definition: encodings.h:96
pointer
const GenericPointer< typename T::ValueType > & pointer
Definition: pointer.h:1249
GenericPointer::PercentEncodeStream
A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence.
Definition: pointer.h:1153
GenericPointer::allocator
Allocator * allocator
Definition: pointer.h:278
internal::Swap
void Swap(T &a, T &b) RAPIDJSON_NOEXCEPT
Custom swap() to avoid dependency on C++ <algorithm> header.
Definition: swap.h:33
GenericPointer::GenericPointer
GenericPointer(const GenericPointer &rhs, Allocator *allocator)
Copy constructor.
Definition: pointer.h:174
RAPIDJSON_DISABLEIF_RETURN
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T2 >, internal::IsGenericValue< T2 > >),(typename T::ValueType &)) GetValueByPointerWithDefault(T &root
GenericStringRef
Reference to a constant string (not taking a copy)
Definition: document.h:346
GenericPointer::GenericPointer
GenericPointer(const Token *tokens, size_t tokenCount)
Constructor with user-supplied tokens.
Definition: pointer.h:166
GetValueByPointer
T::ValueType * GetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, size_t *unresolvedTokenIndex=0)
Definition: pointer.h:1209
internal::u64toa
char * u64toa(uint64_t value, char *buffer)
Definition: itoa.h:126
GenericPointer::Swap
GenericPointer & Swap(GenericPointer &other) RAPIDJSON_NOEXCEPT
Swap the content of this pointer with an other.
Definition: pointer.h:211
GenericPointer::EncodingType
ValueType::EncodingType EncodingType
Encoding type from Value.
Definition: pointer.h:82
GenericPointer::PercentEncodeStream::PercentEncodeStream
PercentEncodeStream(OutputStream &os)
Definition: pointer.h:1155
internal::u32toa
char * u32toa(uint32_t value, char *buffer)
Definition: itoa.h:39
GenericUri
Definition: uri.h:33
EraseValueByPointer
bool EraseValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer)
Definition: pointer.h:1465
GenericPointer::Ch
ValueType::Ch Ch
Character type from Value.
Definition: pointer.h:83
name
ARPHIC PUBLIC LICENSE Ltd Yung Chi Taiwan All rights reserved except as specified below Everyone is permitted to copy and distribute verbatim copies of this license but changing it is forbidden Preamble The licenses for most software are designed to take away your freedom to share and change it By the ARPHIC PUBLIC LICENSE specifically permits and encourages you to use this provided that you give the recipients all the rights that we gave you and make sure they can get the modifications of this software Legal Terms Font means the TrueType fonts AR PL Mingti2L AR PL KaitiM AR PL KaitiM and the derivatives of those fonts created through any modification including modifying reordering converting changing font name
Definition: ARPHICPL.TXT:16
internal::StrLen
SizeType StrLen(const Ch *s)
Custom strlen() which works on different character types.
Definition: strfunc.h:31
GenericPointer::parseErrorOffset_
size_t parseErrorOffset_
Offset in code unit when parsing fail.
Definition: pointer.h:1172
SetValueByPointer
T::ValueType & SetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
Definition: pointer.h:1327
source
const CharType(& source)[N]
Definition: pointer.h:1272