Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 10:13:02

0001 // Tencent is pleased to support the open source community by making RapidJSON available.
0002 // 
0003 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
0004 //
0005 // Licensed under the MIT License (the "License"); you may not use this file except
0006 // in compliance with the License. You may obtain a copy of the License at
0007 //
0008 // http://opensource.org/licenses/MIT
0009 //
0010 // Unless required by applicable law or agreed to in writing, software distributed 
0011 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
0012 // CONDITIONS OF ANY KIND, either express or implied. See the License for the 
0013 // specific language governing permissions and limitations under the License.
0014 
0015 #ifndef RAPIDJSON_POINTER_H_
0016 #define RAPIDJSON_POINTER_H_
0017 
0018 #include "document.h"
0019 #include "uri.h"
0020 #include "internal/itoa.h"
0021 #include "error/error.h" // PointerParseErrorCode
0022 
0023 #ifdef __clang__
0024 RAPIDJSON_DIAG_PUSH
0025 RAPIDJSON_DIAG_OFF(switch-enum)
0026 #elif defined(_MSC_VER)
0027 RAPIDJSON_DIAG_PUSH
0028 RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
0029 #endif
0030 
0031 RAPIDJSON_NAMESPACE_BEGIN
0032 
0033 static const SizeType kPointerInvalidIndex = ~SizeType(0);  //!< Represents an invalid index in GenericPointer::Token
0034 
0035 ///////////////////////////////////////////////////////////////////////////////
0036 // GenericPointer
0037 
0038 //! Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
0039 /*!
0040     This class implements RFC 6901 "JavaScript Object Notation (JSON) Pointer" 
0041     (https://tools.ietf.org/html/rfc6901).
0042 
0043     A JSON pointer is for identifying a specific value in a JSON document
0044     (GenericDocument). It can simplify coding of DOM tree manipulation, because it
0045     can access multiple-level depth of DOM tree with single API call.
0046 
0047     After it parses a string representation (e.g. "/foo/0" or URI fragment 
0048     representation (e.g. "#/foo/0") into its internal representation (tokens),
0049     it can be used to resolve a specific value in multiple documents, or sub-tree 
0050     of documents.
0051 
0052     Contrary to GenericValue, Pointer can be copy constructed and copy assigned.
0053     Apart from assignment, a Pointer cannot be modified after construction.
0054 
0055     Although Pointer is very convenient, please aware that constructing Pointer
0056     involves parsing and dynamic memory allocation. A special constructor with user-
0057     supplied tokens eliminates these.
0058 
0059     GenericPointer depends on GenericDocument and GenericValue.
0060 
0061     \tparam ValueType The value type of the DOM tree. E.g. GenericValue<UTF8<> >
0062     \tparam Allocator The allocator type for allocating memory for internal representation.
0063 
0064     \note GenericPointer uses same encoding of ValueType.
0065     However, Allocator of GenericPointer is independent of Allocator of Value.
0066 */
0067 template <typename ValueType, typename Allocator = CrtAllocator>
0068 class GenericPointer {
0069 public:
0070     typedef typename ValueType::EncodingType EncodingType;  //!< Encoding type from Value
0071     typedef typename ValueType::Ch Ch;                      //!< Character type from Value
0072     typedef GenericUri<ValueType, Allocator> UriType;
0073 
0074 
0075   //! A token is the basic units of internal representation.
0076     /*!
0077         A JSON pointer string representation "/foo/123" is parsed to two tokens: 
0078         "foo" and 123. 123 will be represented in both numeric form and string form.
0079         They are resolved according to the actual value type (object or array).
0080 
0081         For token that are not numbers, or the numeric value is out of bound
0082         (greater than limits of SizeType), they are only treated as string form
0083         (i.e. the token's index will be equal to kPointerInvalidIndex).
0084 
0085         This struct is public so that user can create a Pointer without parsing and 
0086         allocation, using a special constructor.
0087     */
0088     struct Token {
0089         const Ch* name;             //!< Name of the token. It has null character at the end but it can contain null character.
0090         SizeType length;            //!< Length of the name.
0091         SizeType index;             //!< A valid array index, if it is not equal to kPointerInvalidIndex.
0092     };
0093 
0094     //!@name Constructors and destructor.
0095     //@{
0096 
0097     //! Default constructor.
0098     GenericPointer(Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
0099 
0100     //! Constructor that parses a string or URI fragment representation.
0101     /*!
0102         \param source A null-terminated, string or URI fragment representation of JSON pointer.
0103         \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.
0104     */
0105     explicit GenericPointer(const Ch* source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
0106         Parse(source, internal::StrLen(source));
0107     }
0108 
0109 #if RAPIDJSON_HAS_STDSTRING
0110     //! Constructor that parses a string or URI fragment representation.
0111     /*!
0112         \param source A string or URI fragment representation of JSON pointer.
0113         \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.
0114         \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
0115     */
0116     explicit GenericPointer(const std::basic_string<Ch>& source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
0117         Parse(source.c_str(), source.size());
0118     }
0119 #endif
0120 
0121     //! Constructor that parses a string or URI fragment representation, with length of the source string.
0122     /*!
0123         \param source A string or URI fragment representation of JSON pointer.
0124         \param length Length of source.
0125         \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.
0126         \note Slightly faster than the overload without length.
0127     */
0128     GenericPointer(const Ch* source, size_t length, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
0129         Parse(source, length);
0130     }
0131 
0132     //! Constructor with user-supplied tokens.
0133     /*!
0134         This constructor let user supplies const array of tokens.
0135         This prevents the parsing process and eliminates allocation.
0136         This is preferred for memory constrained environments.
0137 
0138         \param tokens An constant array of tokens representing the JSON pointer.
0139         \param tokenCount Number of tokens.
0140 
0141         \b Example
0142         \code
0143         #define NAME(s) { s, sizeof(s) / sizeof(s[0]) - 1, kPointerInvalidIndex }
0144         #define INDEX(i) { #i, sizeof(#i) - 1, i }
0145 
0146         static const Pointer::Token kTokens[] = { NAME("foo"), INDEX(123) };
0147         static const Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
0148         // Equivalent to static const Pointer p("/foo/123");
0149 
0150         #undef NAME
0151         #undef INDEX
0152         \endcode
0153     */
0154     GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
0155 
0156     //! Copy constructor.
0157     GenericPointer(const GenericPointer& rhs) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
0158         *this = rhs;
0159     }
0160 
0161     //! Copy constructor.
0162     GenericPointer(const GenericPointer& rhs, Allocator* allocator) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
0163         *this = rhs;
0164     }
0165 
0166     //! Destructor.
0167     ~GenericPointer() {
0168         if (nameBuffer_)    // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and tokens_ are not deallocated.
0169             Allocator::Free(tokens_);
0170         RAPIDJSON_DELETE(ownAllocator_);
0171     }
0172 
0173     //! Assignment operator.
0174     GenericPointer& operator=(const GenericPointer& rhs) {
0175         if (this != &rhs) {
0176             // Do not delete ownAllcator
0177             if (nameBuffer_)
0178                 Allocator::Free(tokens_);
0179 
0180             tokenCount_ = rhs.tokenCount_;
0181             parseErrorOffset_ = rhs.parseErrorOffset_;
0182             parseErrorCode_ = rhs.parseErrorCode_;
0183 
0184             if (rhs.nameBuffer_)
0185                 CopyFromRaw(rhs); // Normally parsed tokens.
0186             else {
0187                 tokens_ = rhs.tokens_; // User supplied const tokens.
0188                 nameBuffer_ = 0;
0189             }
0190         }
0191         return *this;
0192     }
0193 
0194     //! Swap the content of this pointer with an other.
0195     /*!
0196         \param other The pointer to swap with.
0197         \note Constant complexity.
0198     */
0199     GenericPointer& Swap(GenericPointer& other) RAPIDJSON_NOEXCEPT {
0200         internal::Swap(allocator_, other.allocator_);
0201         internal::Swap(ownAllocator_, other.ownAllocator_);
0202         internal::Swap(nameBuffer_, other.nameBuffer_);
0203         internal::Swap(tokens_, other.tokens_);
0204         internal::Swap(tokenCount_, other.tokenCount_);
0205         internal::Swap(parseErrorOffset_, other.parseErrorOffset_);
0206         internal::Swap(parseErrorCode_, other.parseErrorCode_);
0207         return *this;
0208     }
0209 
0210     //! free-standing swap function helper
0211     /*!
0212         Helper function to enable support for common swap implementation pattern based on \c std::swap:
0213         \code
0214         void swap(MyClass& a, MyClass& b) {
0215             using std::swap;
0216             swap(a.pointer, b.pointer);
0217             // ...
0218         }
0219         \endcode
0220         \see Swap()
0221      */
0222     friend inline void swap(GenericPointer& a, GenericPointer& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
0223 
0224     //@}
0225 
0226     //!@name Append token
0227     //@{
0228 
0229     //! Append a token and return a new Pointer
0230     /*!
0231         \param token Token to be appended.
0232         \param allocator Allocator for the newly return Pointer.
0233         \return A new Pointer with appended token.
0234     */
0235     GenericPointer Append(const Token& token, Allocator* allocator = 0) const {
0236         GenericPointer r;
0237         r.allocator_ = allocator;
0238         Ch *p = r.CopyFromRaw(*this, 1, token.length + 1);
0239         std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch));
0240         r.tokens_[tokenCount_].name = p;
0241         r.tokens_[tokenCount_].length = token.length;
0242         r.tokens_[tokenCount_].index = token.index;
0243         return r;
0244     }
0245 
0246     //! Append a name token with length, and return a new Pointer
0247     /*!
0248         \param name Name to be appended.
0249         \param length Length of name.
0250         \param allocator Allocator for the newly return Pointer.
0251         \return A new Pointer with appended token.
0252     */
0253     GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const {
0254         Token token = { name, length, kPointerInvalidIndex };
0255         return Append(token, allocator);
0256     }
0257 
0258     //! Append a name token without length, and return a new Pointer
0259     /*!
0260         \param name Name (const Ch*) to be appended.
0261         \param allocator Allocator for the newly return Pointer.
0262         \return A new Pointer with appended token.
0263     */
0264     template <typename T>
0265     RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >), (GenericPointer))
0266     Append(T* name, Allocator* allocator = 0) const {
0267         return Append(name, internal::StrLen(name), allocator);
0268     }
0269 
0270 #if RAPIDJSON_HAS_STDSTRING
0271     //! Append a name token, and return a new Pointer
0272     /*!
0273         \param name Name to be appended.
0274         \param allocator Allocator for the newly return Pointer.
0275         \return A new Pointer with appended token.
0276     */
0277     GenericPointer Append(const std::basic_string<Ch>& name, Allocator* allocator = 0) const {
0278         return Append(name.c_str(), static_cast<SizeType>(name.size()), allocator);
0279     }
0280 #endif
0281 
0282     //! Append a index token, and return a new Pointer
0283     /*!
0284         \param index Index to be appended.
0285         \param allocator Allocator for the newly return Pointer.
0286         \return A new Pointer with appended token.
0287     */
0288     GenericPointer Append(SizeType index, Allocator* allocator = 0) const {
0289         char buffer[21];
0290         char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer);
0291         SizeType length = static_cast<SizeType>(end - buffer);
0292         buffer[length] = '\0';
0293 
0294         if (sizeof(Ch) == 1) {
0295             Token token = { reinterpret_cast<Ch*>(buffer), length, index };
0296             return Append(token, allocator);
0297         }
0298         else {
0299             Ch name[21];
0300             for (size_t i = 0; i <= length; i++)
0301                 name[i] = static_cast<Ch>(buffer[i]);
0302             Token token = { name, length, index };
0303             return Append(token, allocator);
0304         }
0305     }
0306 
0307     //! Append a token by value, and return a new Pointer
0308     /*!
0309         \param token token to be appended.
0310         \param allocator Allocator for the newly return Pointer.
0311         \return A new Pointer with appended token.
0312     */
0313     GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const {
0314         if (token.IsString())
0315             return Append(token.GetString(), token.GetStringLength(), allocator);
0316         else {
0317             RAPIDJSON_ASSERT(token.IsUint64());
0318             RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0));
0319             return Append(static_cast<SizeType>(token.GetUint64()), allocator);
0320         }
0321     }
0322 
0323     //!@name Handling Parse Error
0324     //@{
0325 
0326     //! Check whether this is a valid pointer.
0327     bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; }
0328 
0329     //! Get the parsing error offset in code unit.
0330     size_t GetParseErrorOffset() const { return parseErrorOffset_; }
0331 
0332     //! Get the parsing error code.
0333     PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; }
0334 
0335     //@}
0336 
0337     //! Get the allocator of this pointer.
0338     Allocator& GetAllocator() { return *allocator_; }
0339 
0340     //!@name Tokens
0341     //@{
0342 
0343     //! Get the token array (const version only).
0344     const Token* GetTokens() const { return tokens_; }
0345 
0346     //! Get the number of tokens.
0347     size_t GetTokenCount() const { return tokenCount_; }
0348 
0349     //@}
0350 
0351     //!@name Equality/inequality operators
0352     //@{
0353 
0354     //! Equality operator.
0355     /*!
0356         \note When any pointers are invalid, always returns false.
0357     */
0358     bool operator==(const GenericPointer& rhs) const {
0359         if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_)
0360             return false;
0361 
0362         for (size_t i = 0; i < tokenCount_; i++) {
0363             if (tokens_[i].index != rhs.tokens_[i].index ||
0364                 tokens_[i].length != rhs.tokens_[i].length || 
0365                 (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch)* tokens_[i].length) != 0))
0366             {
0367                 return false;
0368             }
0369         }
0370 
0371         return true;
0372     }
0373 
0374     //! Inequality operator.
0375     /*!
0376         \note When any pointers are invalid, always returns true.
0377     */
0378     bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }
0379 
0380     //! Less than operator.
0381     /*!
0382         \note Invalid pointers are always greater than valid ones.
0383     */
0384     bool operator<(const GenericPointer& rhs) const {
0385         if (!IsValid())
0386             return false;
0387         if (!rhs.IsValid())
0388             return true;
0389 
0390         if (tokenCount_ != rhs.tokenCount_)
0391             return tokenCount_ < rhs.tokenCount_;
0392 
0393         for (size_t i = 0; i < tokenCount_; i++) {
0394             if (tokens_[i].index != rhs.tokens_[i].index)
0395                 return tokens_[i].index < rhs.tokens_[i].index;
0396 
0397             if (tokens_[i].length != rhs.tokens_[i].length)
0398                 return tokens_[i].length < rhs.tokens_[i].length;
0399 
0400             if (int cmp = std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length))
0401                 return cmp < 0;
0402         }
0403 
0404         return false;
0405     }
0406 
0407     //@}
0408 
0409     //!@name Stringify
0410     //@{
0411 
0412     //! Stringify the pointer into string representation.
0413     /*!
0414         \tparam OutputStream Type of output stream.
0415         \param os The output stream.
0416     */
0417     template<typename OutputStream>
0418     bool Stringify(OutputStream& os) const {
0419         return Stringify<false, OutputStream>(os);
0420     }
0421 
0422     //! Stringify the pointer into URI fragment representation.
0423     /*!
0424         \tparam OutputStream Type of output stream.
0425         \param os The output stream.
0426     */
0427     template<typename OutputStream>
0428     bool StringifyUriFragment(OutputStream& os) const {
0429         return Stringify<true, OutputStream>(os);
0430     }
0431 
0432     //@}
0433 
0434     //!@name Create value
0435     //@{
0436 
0437     //! Create a value in a subtree.
0438     /*!
0439         If the value is not exist, it creates all parent values and a JSON Null value.
0440         So it always succeed and return the newly created or existing value.
0441 
0442         Remind that it may change types of parents according to tokens, so it 
0443         potentially removes previously stored values. For example, if a document 
0444         was an array, and "/foo" is used to create a value, then the document 
0445         will be changed to an object, and all existing array elements are lost.
0446 
0447         \param root Root value of a DOM subtree to be resolved. It can be any value other than document root.
0448         \param allocator Allocator for creating the values if the specified value or its parents are not exist.
0449         \param alreadyExist If non-null, it stores whether the resolved value is already exist.
0450         \return The resolved newly created (a JSON Null value), or already exists value.
0451     */
0452     ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const {
0453         RAPIDJSON_ASSERT(IsValid());
0454         ValueType* v = &root;
0455         bool exist = true;
0456         for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
0457             if (v->IsArray() && t->name[0] == '-' && t->length == 1) {
0458                 v->PushBack(ValueType().Move(), allocator);
0459                 v = &((*v)[v->Size() - 1]);
0460                 exist = false;
0461             }
0462             else {
0463                 if (t->index == kPointerInvalidIndex) { // must be object name
0464                     if (!v->IsObject())
0465                         v->SetObject(); // Change to Object
0466                 }
0467                 else { // object name or array index
0468                     if (!v->IsArray() && !v->IsObject())
0469                         v->SetArray(); // Change to Array
0470                 }
0471 
0472                 if (v->IsArray()) {
0473                     if (t->index >= v->Size()) {
0474                         v->Reserve(t->index + 1, allocator);
0475                         while (t->index >= v->Size())
0476                             v->PushBack(ValueType().Move(), allocator);
0477                         exist = false;
0478                     }
0479                     v = &((*v)[t->index]);
0480                 }
0481                 else {
0482                     typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
0483                     if (m == v->MemberEnd()) {
0484                         v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
0485                         m = v->MemberEnd();
0486                         v = &(--m)->value; // Assumes AddMember() appends at the end
0487                         exist = false;
0488                     }
0489                     else
0490                         v = &m->value;
0491                 }
0492             }
0493         }
0494 
0495         if (alreadyExist)
0496             *alreadyExist = exist;
0497 
0498         return *v;
0499     }
0500 
0501     //! Creates a value in a document.
0502     /*!
0503         \param document A document to be resolved.
0504         \param alreadyExist If non-null, it stores whether the resolved value is already exist.
0505         \return The resolved newly created, or already exists value.
0506     */
0507     template <typename stackAllocator>
0508     ValueType& Create(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, bool* alreadyExist = 0) const {
0509         return Create(document, document.GetAllocator(), alreadyExist);
0510     }
0511 
0512     //@}
0513 
0514     //!@name Compute URI
0515     //@{
0516 
0517     //! Compute the in-scope URI for a subtree.
0518     //  For use with JSON pointers into JSON schema documents.
0519     /*!
0520         \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
0521         \param rootUri Root URI
0522         \param unresolvedTokenIndex If the pointer cannot resolve a token in the pointer, this parameter can obtain the index of unresolved token.
0523         \param allocator Allocator for Uris
0524         \return Uri if it can be resolved. Otherwise null.
0525 
0526         \note
0527         There are only 3 situations when a URI cannot be resolved:
0528         1. A value in the path is not an array nor object.
0529         2. An object value does not contain the token.
0530         3. A token is out of range of an array value.
0531 
0532         Use unresolvedTokenIndex to retrieve the token index.
0533     */
0534     UriType GetUri(ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0, Allocator* allocator = 0) const {
0535         static const Ch kIdString[] = { 'i', 'd', '\0' };
0536         static const ValueType kIdValue(kIdString, 2);
0537         UriType base = UriType(rootUri, allocator);
0538         RAPIDJSON_ASSERT(IsValid());
0539         ValueType* v = &root;
0540         for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
0541             switch (v->GetType()) {
0542                 case kObjectType:
0543                 {
0544                     // See if we have an id, and if so resolve with the current base
0545                     typename ValueType::MemberIterator m = v->FindMember(kIdValue);
0546                     if (m != v->MemberEnd() && (m->value).IsString()) {
0547                         UriType here = UriType(m->value, allocator).Resolve(base, allocator);
0548                         base = here;
0549                     }
0550                     m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
0551                     if (m == v->MemberEnd())
0552                         break;
0553                     v = &m->value;
0554                 }
0555                   continue;
0556                 case kArrayType:
0557                     if (t->index == kPointerInvalidIndex || t->index >= v->Size())
0558                         break;
0559                     v = &((*v)[t->index]);
0560                     continue;
0561                 default:
0562                     break;
0563             }
0564 
0565             // Error: unresolved token
0566             if (unresolvedTokenIndex)
0567                 *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
0568             return UriType(allocator);
0569         }
0570         return base;
0571     }
0572 
0573     UriType GetUri(const ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0, Allocator* allocator = 0) const {
0574       return GetUri(const_cast<ValueType&>(root), rootUri, unresolvedTokenIndex, allocator);
0575     }
0576 
0577 
0578     //!@name Query value
0579     //@{
0580 
0581     //! Query a value in a subtree.
0582     /*!
0583         \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
0584         \param unresolvedTokenIndex If the pointer cannot resolve a token in the pointer, this parameter can obtain the index of unresolved token.
0585         \return Pointer to the value if it can be resolved. Otherwise null.
0586 
0587         \note
0588         There are only 3 situations when a value cannot be resolved:
0589         1. A value in the path is not an array nor object.
0590         2. An object value does not contain the token.
0591         3. A token is out of range of an array value.
0592 
0593         Use unresolvedTokenIndex to retrieve the token index.
0594     */
0595     ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const {
0596         RAPIDJSON_ASSERT(IsValid());
0597         ValueType* v = &root;
0598         for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
0599             switch (v->GetType()) {
0600             case kObjectType:
0601                 {
0602                     typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
0603                     if (m == v->MemberEnd())
0604                         break;
0605                     v = &m->value;
0606                 }
0607                 continue;
0608             case kArrayType:
0609                 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
0610                     break;
0611                 v = &((*v)[t->index]);
0612                 continue;
0613             default:
0614                 break;
0615             }
0616 
0617             // Error: unresolved token
0618             if (unresolvedTokenIndex)
0619                 *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
0620             return 0;
0621         }
0622         return v;
0623     }
0624 
0625     //! Query a const value in a const subtree.
0626     /*!
0627         \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
0628         \return Pointer to the value if it can be resolved. Otherwise null.
0629     */
0630     const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const { 
0631         return Get(const_cast<ValueType&>(root), unresolvedTokenIndex);
0632     }
0633 
0634     //@}
0635 
0636     //!@name Query a value with default
0637     //@{
0638 
0639     //! Query a value in a subtree with default value.
0640     /*!
0641         Similar to Get(), but if the specified value do not exists, it creates all parents and clone the default value.
0642         So that this function always succeed.
0643 
0644         \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
0645         \param defaultValue Default value to be cloned if the value was not exists.
0646         \param allocator Allocator for creating the values if the specified value or its parents are not exist.
0647         \see Create()
0648     */
0649     ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const {
0650         bool alreadyExist;
0651         ValueType& v = Create(root, allocator, &alreadyExist);
0652         return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
0653     }
0654 
0655     //! Query a value in a subtree with default null-terminated string.
0656     ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const {
0657         bool alreadyExist;
0658         ValueType& v = Create(root, allocator, &alreadyExist);
0659         return alreadyExist ? v : v.SetString(defaultValue, allocator);
0660     }
0661 
0662 #if RAPIDJSON_HAS_STDSTRING
0663     //! Query a value in a subtree with default std::basic_string.
0664     ValueType& GetWithDefault(ValueType& root, const std::basic_string<Ch>& defaultValue, typename ValueType::AllocatorType& allocator) const {
0665         bool alreadyExist;
0666         ValueType& v = Create(root, allocator, &alreadyExist);
0667         return alreadyExist ? v : v.SetString(defaultValue, allocator);
0668     }
0669 #endif
0670 
0671     //! Query a value in a subtree with default primitive value.
0672     /*!
0673         \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
0674     */
0675     template <typename T>
0676     RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
0677     GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator) const {
0678         return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);
0679     }
0680 
0681     //! Query a value in a document with default value.
0682     template <typename stackAllocator>
0683     ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& defaultValue) const {
0684         return GetWithDefault(document, defaultValue, document.GetAllocator());
0685     }
0686 
0687     //! Query a value in a document with default null-terminated string.
0688     template <typename stackAllocator>
0689     ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* defaultValue) const {
0690         return GetWithDefault(document, defaultValue, document.GetAllocator());
0691     }
0692 
0693 #if RAPIDJSON_HAS_STDSTRING
0694     //! Query a value in a document with default std::basic_string.
0695     template <typename stackAllocator>
0696     ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& defaultValue) const {
0697         return GetWithDefault(document, defaultValue, document.GetAllocator());
0698     }
0699 #endif
0700 
0701     //! Query a value in a document with default primitive value.
0702     /*!
0703         \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
0704     */
0705     template <typename T, typename stackAllocator>
0706     RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
0707     GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T defaultValue) const {
0708         return GetWithDefault(document, defaultValue, document.GetAllocator());
0709     }
0710 
0711     //@}
0712 
0713     //!@name Set a value
0714     //@{
0715 
0716     //! Set a value in a subtree, with move semantics.
0717     /*!
0718         It creates all parents if they are not exist or types are different to the tokens.
0719         So this function always succeeds but potentially remove existing values.
0720 
0721         \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
0722         \param value Value to be set.
0723         \param allocator Allocator for creating the values if the specified value or its parents are not exist.
0724         \see Create()
0725     */
0726     ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
0727         return Create(root, allocator) = value;
0728     }
0729 
0730     //! Set a value in a subtree, with copy semantics.
0731     ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const {
0732         return Create(root, allocator).CopyFrom(value, allocator);
0733     }
0734 
0735     //! Set a null-terminated string in a subtree.
0736     ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const {
0737         return Create(root, allocator) = ValueType(value, allocator).Move();
0738     }
0739 
0740 #if RAPIDJSON_HAS_STDSTRING
0741     //! Set a std::basic_string in a subtree.
0742     ValueType& Set(ValueType& root, const std::basic_string<Ch>& value, typename ValueType::AllocatorType& allocator) const {
0743         return Create(root, allocator) = ValueType(value, allocator).Move();
0744     }
0745 #endif
0746 
0747     //! Set a primitive value in a subtree.
0748     /*!
0749         \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
0750     */
0751     template <typename T>
0752     RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
0753     Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const {
0754         return Create(root, allocator) = ValueType(value).Move();
0755     }
0756 
0757     //! Set a value in a document, with move semantics.
0758     template <typename stackAllocator>
0759     ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const {
0760         return Create(document) = value;
0761     }
0762 
0763     //! Set a value in a document, with copy semantics.
0764     template <typename stackAllocator>
0765     ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& value) const {
0766         return Create(document).CopyFrom(value, document.GetAllocator());
0767     }
0768 
0769     //! Set a null-terminated string in a document.
0770     template <typename stackAllocator>
0771     ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* value) const {
0772         return Create(document) = ValueType(value, document.GetAllocator()).Move();
0773     }
0774 
0775 #if RAPIDJSON_HAS_STDSTRING
0776     //! Sets a std::basic_string in a document.
0777     template <typename stackAllocator>
0778     ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& value) const {
0779         return Create(document) = ValueType(value, document.GetAllocator()).Move();
0780     }
0781 #endif
0782 
0783     //! Set a primitive value in a document.
0784     /*!
0785     \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
0786     */
0787     template <typename T, typename stackAllocator>
0788     RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
0789         Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T value) const {
0790             return Create(document) = value;
0791     }
0792 
0793     //@}
0794 
0795     //!@name Swap a value
0796     //@{
0797 
0798     //! Swap a value with a value in a subtree.
0799     /*!
0800         It creates all parents if they are not exist or types are different to the tokens.
0801         So this function always succeeds but potentially remove existing values.
0802 
0803         \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
0804         \param value Value to be swapped.
0805         \param allocator Allocator for creating the values if the specified value or its parents are not exist.
0806         \see Create()
0807     */
0808     ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
0809         return Create(root, allocator).Swap(value);
0810     }
0811 
0812     //! Swap a value with a value in a document.
0813     template <typename stackAllocator>
0814     ValueType& Swap(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const {
0815         return Create(document).Swap(value);
0816     }
0817 
0818     //@}
0819 
0820     //! Erase a value in a subtree.
0821     /*!
0822         \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
0823         \return Whether the resolved value is found and erased.
0824 
0825         \note Erasing with an empty pointer \c Pointer(""), i.e. the root, always fail and return false.
0826     */
0827     bool Erase(ValueType& root) const {
0828         RAPIDJSON_ASSERT(IsValid());
0829         if (tokenCount_ == 0) // Cannot erase the root
0830             return false;
0831 
0832         ValueType* v = &root;
0833         const Token* last = tokens_ + (tokenCount_ - 1);
0834         for (const Token *t = tokens_; t != last; ++t) {
0835             switch (v->GetType()) {
0836             case kObjectType:
0837                 {
0838                     typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
0839                     if (m == v->MemberEnd())
0840                         return false;
0841                     v = &m->value;
0842                 }
0843                 break;
0844             case kArrayType:
0845                 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
0846                     return false;
0847                 v = &((*v)[t->index]);
0848                 break;
0849             default:
0850                 return false;
0851             }
0852         }
0853 
0854         switch (v->GetType()) {
0855         case kObjectType:
0856             return v->EraseMember(GenericStringRef<Ch>(last->name, last->length));
0857         case kArrayType:
0858             if (last->index == kPointerInvalidIndex || last->index >= v->Size())
0859                 return false;
0860             v->Erase(v->Begin() + last->index);
0861             return true;
0862         default:
0863             return false;
0864         }
0865     }
0866 
0867 private:
0868     //! Clone the content from rhs to this.
0869     /*!
0870         \param rhs Source pointer.
0871         \param extraToken Extra tokens to be allocated.
0872         \param extraNameBufferSize Extra name buffer size (in number of Ch) to be allocated.
0873         \return Start of non-occupied name buffer, for storing extra names.
0874     */
0875     Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0) {
0876         if (!allocator_) // allocator is independently owned.
0877             ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
0878 
0879         size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens
0880         for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)
0881             nameBufferSize += t->length;
0882 
0883         tokenCount_ = rhs.tokenCount_ + extraToken;
0884         tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch)));
0885         nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
0886         if (rhs.tokenCount_ > 0) {
0887             std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token));
0888         }
0889         if (nameBufferSize > 0) {
0890             std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
0891         }
0892 
0893         // The names of each token point to a string in the nameBuffer_. The
0894         // previous memcpy copied over string pointers into the rhs.nameBuffer_,
0895         // but they should point to the strings in the new nameBuffer_.
0896         for (size_t i = 0; i < rhs.tokenCount_; ++i) {
0897           // The offset between the string address and the name buffer should
0898           // still be constant, so we can just get this offset and set each new
0899           // token name according the new buffer start + the known offset.
0900           std::ptrdiff_t name_offset = rhs.tokens_[i].name - rhs.nameBuffer_;
0901           tokens_[i].name = nameBuffer_ + name_offset;
0902         }
0903 
0904         return nameBuffer_ + nameBufferSize;
0905     }
0906 
0907     //! Check whether a character should be percent-encoded.
0908     /*!
0909         According to RFC 3986 2.3 Unreserved Characters.
0910         \param c The character (code unit) to be tested.
0911     */
0912     bool NeedPercentEncode(Ch c) const {
0913         return !((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~');
0914     }
0915 
0916     //! Parse a JSON String or its URI fragment representation into tokens.
0917 #ifndef __clang__ // -Wdocumentation
0918     /*!
0919         \param source Either a JSON Pointer string, or its URI fragment representation. Not need to be null terminated.
0920         \param length Length of the source string.
0921         \note Source cannot be JSON String Representation of JSON Pointer, e.g. In "/\u0000", \u0000 will not be unescaped.
0922     */
0923 #endif
0924     void Parse(const Ch* source, size_t length) {
0925         RAPIDJSON_ASSERT(source != NULL);
0926         RAPIDJSON_ASSERT(nameBuffer_ == 0);
0927         RAPIDJSON_ASSERT(tokens_ == 0);
0928 
0929         // Create own allocator if user did not supply.
0930         if (!allocator_)
0931             ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
0932 
0933         // Count number of '/' as tokenCount
0934         tokenCount_ = 0;
0935         for (const Ch* s = source; s != source + length; s++) 
0936             if (*s == '/')
0937                 tokenCount_++;
0938 
0939         Token* token = tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch)));
0940         Ch* name = nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
0941         size_t i = 0;
0942 
0943         // Detect if it is a URI fragment
0944         bool uriFragment = false;
0945         if (source[i] == '#') {
0946             uriFragment = true;
0947             i++;
0948         }
0949 
0950         if (i != length && source[i] != '/') {
0951             parseErrorCode_ = kPointerParseErrorTokenMustBeginWithSolidus;
0952             goto error;
0953         }
0954 
0955         while (i < length) {
0956             RAPIDJSON_ASSERT(source[i] == '/');
0957             i++; // consumes '/'
0958 
0959             token->name = name;
0960             bool isNumber = true;
0961 
0962             while (i < length && source[i] != '/') {
0963                 Ch c = source[i];
0964                 if (uriFragment) {
0965                     // Decoding percent-encoding for URI fragment
0966                     if (c == '%') {
0967                         PercentDecodeStream is(&source[i], source + length);
0968                         GenericInsituStringStream<EncodingType> os(name);
0969                         Ch* begin = os.PutBegin();
0970                         if (!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid()) {
0971                             parseErrorCode_ = kPointerParseErrorInvalidPercentEncoding;
0972                             goto error;
0973                         }
0974                         size_t len = os.PutEnd(begin);
0975                         i += is.Tell() - 1;
0976                         if (len == 1)
0977                             c = *name;
0978                         else {
0979                             name += len;
0980                             isNumber = false;
0981                             i++;
0982                             continue;
0983                         }
0984                     }
0985                     else if (NeedPercentEncode(c)) {
0986                         parseErrorCode_ = kPointerParseErrorCharacterMustPercentEncode;
0987                         goto error;
0988                     }
0989                 }
0990 
0991                 i++;
0992 
0993                 // Escaping "~0" -> '~', "~1" -> '/'
0994                 if (c == '~') {
0995                     if (i < length) {
0996                         c = source[i];
0997                         if (c == '0')       c = '~';
0998                         else if (c == '1')  c = '/';
0999                         else {
1000                             parseErrorCode_ = kPointerParseErrorInvalidEscape;
1001                             goto error;
1002                         }
1003                         i++;
1004                     }
1005                     else {
1006                         parseErrorCode_ = kPointerParseErrorInvalidEscape;
1007                         goto error;
1008                     }
1009                 }
1010 
1011                 // First check for index: all of characters are digit
1012                 if (c < '0' || c > '9')
1013                     isNumber = false;
1014 
1015                 *name++ = c;
1016             }
1017             token->length = static_cast<SizeType>(name - token->name);
1018             if (token->length == 0)
1019                 isNumber = false;
1020             *name++ = '\0'; // Null terminator
1021 
1022             // Second check for index: more than one digit cannot have leading zero
1023             if (isNumber && token->length > 1 && token->name[0] == '0')
1024                 isNumber = false;
1025 
1026             // String to SizeType conversion
1027             SizeType n = 0;
1028             if (isNumber) {
1029                 for (size_t j = 0; j < token->length; j++) {
1030                     SizeType m = n * 10 + static_cast<SizeType>(token->name[j] - '0');
1031                     if (m < n) {   // overflow detection
1032                         isNumber = false;
1033                         break;
1034                     }
1035                     n = m;
1036                 }
1037             }
1038 
1039             token->index = isNumber ? n : kPointerInvalidIndex;
1040             token++;
1041         }
1042 
1043         RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer
1044         parseErrorCode_ = kPointerParseErrorNone;
1045         return;
1046 
1047     error:
1048         Allocator::Free(tokens_);
1049         nameBuffer_ = 0;
1050         tokens_ = 0;
1051         tokenCount_ = 0;
1052         parseErrorOffset_ = i;
1053         return;
1054     }
1055 
1056     //! Stringify to string or URI fragment representation.
1057     /*!
1058         \tparam uriFragment True for stringifying to URI fragment representation. False for string representation.
1059         \tparam OutputStream type of output stream.
1060         \param os The output stream.
1061     */
1062     template<bool uriFragment, typename OutputStream>
1063     bool Stringify(OutputStream& os) const {
1064         RAPIDJSON_ASSERT(IsValid());
1065 
1066         if (uriFragment)
1067             os.Put('#');
1068 
1069         for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
1070             os.Put('/');
1071             for (size_t j = 0; j < t->length; j++) {
1072                 Ch c = t->name[j];
1073                 if (c == '~') {
1074                     os.Put('~');
1075                     os.Put('0');
1076                 }
1077                 else if (c == '/') {
1078                     os.Put('~');
1079                     os.Put('1');
1080                 }
1081                 else if (uriFragment && NeedPercentEncode(c)) { 
1082                     // Transcode to UTF8 sequence
1083                     GenericStringStream<typename ValueType::EncodingType> source(&t->name[j]);
1084                     PercentEncodeStream<OutputStream> target(os);
1085                     if (!Transcoder<EncodingType, UTF8<> >().Validate(source, target))
1086                         return false;
1087                     j += source.Tell() - 1;
1088                 }
1089                 else
1090                     os.Put(c);
1091             }
1092         }
1093         return true;
1094     }
1095 
1096     //! A helper stream for decoding a percent-encoded sequence into code unit.
1097     /*!
1098         This stream decodes %XY triplet into code unit (0-255).
1099         If it encounters invalid characters, it sets output code unit as 0 and 
1100         mark invalid, and to be checked by IsValid().
1101     */
1102     class PercentDecodeStream {
1103     public:
1104         typedef typename ValueType::Ch Ch;
1105 
1106         //! Constructor
1107         /*!
1108             \param source Start of the stream
1109             \param end Past-the-end of the stream.
1110         */
1111         PercentDecodeStream(const Ch* source, const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {}
1112 
1113         Ch Take() {
1114             if (*src_ != '%' || src_ + 3 > end_) { // %XY triplet
1115                 valid_ = false;
1116                 return 0;
1117             }
1118             src_++;
1119             Ch c = 0;
1120             for (int j = 0; j < 2; j++) {
1121                 c = static_cast<Ch>(c << 4);
1122                 Ch h = *src_;
1123                 if      (h >= '0' && h <= '9') c = static_cast<Ch>(c + h - '0');
1124                 else if (h >= 'A' && h <= 'F') c = static_cast<Ch>(c + h - 'A' + 10);
1125                 else if (h >= 'a' && h <= 'f') c = static_cast<Ch>(c + h - 'a' + 10);
1126                 else {
1127                     valid_ = false;
1128                     return 0;
1129                 }
1130                 src_++;
1131             }
1132             return c;
1133         }
1134 
1135         size_t Tell() const { return static_cast<size_t>(src_ - head_); }
1136         bool IsValid() const { return valid_; }
1137 
1138     private:
1139         const Ch* src_;     //!< Current read position.
1140         const Ch* head_;    //!< Original head of the string.
1141         const Ch* end_;     //!< Past-the-end position.
1142         bool valid_;        //!< Whether the parsing is valid.
1143     };
1144 
1145     //! A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence.
1146     template <typename OutputStream>
1147     class PercentEncodeStream {
1148     public:
1149         PercentEncodeStream(OutputStream& os) : os_(os) {}
1150         void Put(char c) { // UTF-8 must be byte
1151             unsigned char u = static_cast<unsigned char>(c);
1152             static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1153             os_.Put('%');
1154             os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u >> 4]));
1155             os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u & 15]));
1156         }
1157     private:
1158         OutputStream& os_;
1159     };
1160 
1161     Allocator* allocator_;                  //!< The current allocator. It is either user-supplied or equal to ownAllocator_.
1162     Allocator* ownAllocator_;               //!< Allocator owned by this Pointer.
1163     Ch* nameBuffer_;                        //!< A buffer containing all names in tokens.
1164     Token* tokens_;                         //!< A list of tokens.
1165     size_t tokenCount_;                     //!< Number of tokens in tokens_.
1166     size_t parseErrorOffset_;               //!< Offset in code unit when parsing fail.
1167     PointerParseErrorCode parseErrorCode_;  //!< Parsing error code.
1168 };
1169 
1170 //! GenericPointer for Value (UTF-8, default allocator).
1171 typedef GenericPointer<Value> Pointer;
1172 
1173 //!@name Helper functions for GenericPointer
1174 //@{
1175 
1176 //////////////////////////////////////////////////////////////////////////////
1177 
1178 template <typename T>
1179 typename T::ValueType& CreateValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::AllocatorType& a) {
1180     return pointer.Create(root, a);
1181 }
1182 
1183 template <typename T, typename CharType, size_t N>
1184 typename T::ValueType& CreateValueByPointer(T& root, const CharType(&source)[N], typename T::AllocatorType& a) {
1185     return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a);
1186 }
1187 
1188 // No allocator parameter
1189 
1190 template <typename DocumentType>
1191 typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer) {
1192     return pointer.Create(document);
1193 }
1194 
1195 template <typename DocumentType, typename CharType, size_t N>
1196 typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const CharType(&source)[N]) {
1197     return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document);
1198 }
1199 
1200 //////////////////////////////////////////////////////////////////////////////
1201 
1202 template <typename T>
1203 typename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
1204     return pointer.Get(root, unresolvedTokenIndex);
1205 }
1206 
1207 template <typename T>
1208 const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
1209     return pointer.Get(root, unresolvedTokenIndex);
1210 }
1211 
1212 template <typename T, typename CharType, size_t N>
1213 typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) {
1214     return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1215 }
1216 
1217 template <typename T, typename CharType, size_t N>
1218 const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) {
1219     return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1220 }
1221 
1222 //////////////////////////////////////////////////////////////////////////////
1223 
1224 template <typename T>
1225 typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
1226     return pointer.GetWithDefault(root, defaultValue, a);
1227 }
1228 
1229 template <typename T>
1230 typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* defaultValue, typename T::AllocatorType& a) {
1231     return pointer.GetWithDefault(root, defaultValue, a);
1232 }
1233 
1234 #if RAPIDJSON_HAS_STDSTRING
1235 template <typename T>
1236 typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {
1237     return pointer.GetWithDefault(root, defaultValue, a);
1238 }
1239 #endif
1240 
1241 template <typename T, typename T2>
1242 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1243 GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 defaultValue, typename T::AllocatorType& a) {
1244     return pointer.GetWithDefault(root, defaultValue, a);
1245 }
1246 
1247 template <typename T, typename CharType, size_t N>
1248 typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
1249     return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1250 }
1251 
1252 template <typename T, typename CharType, size_t N>
1253 typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::Ch* defaultValue, typename T::AllocatorType& a) {
1254     return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1255 }
1256 
1257 #if RAPIDJSON_HAS_STDSTRING
1258 template <typename T, typename CharType, size_t N>
1259 typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {
1260     return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1261 }
1262 #endif
1263 
1264 template <typename T, typename CharType, size_t N, typename T2>
1265 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1266 GetValueByPointerWithDefault(T& root, const CharType(&source)[N], T2 defaultValue, typename T::AllocatorType& a) {
1267     return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1268 }
1269 
1270 // No allocator parameter
1271 
1272 template <typename DocumentType>
1273 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& defaultValue) {
1274     return pointer.GetWithDefault(document, defaultValue);
1275 }
1276 
1277 template <typename DocumentType>
1278 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* defaultValue) {
1279     return pointer.GetWithDefault(document, defaultValue);
1280 }
1281 
1282 #if RAPIDJSON_HAS_STDSTRING
1283 template <typename DocumentType>
1284 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1285     return pointer.GetWithDefault(document, defaultValue);
1286 }
1287 #endif
1288 
1289 template <typename DocumentType, typename T2>
1290 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1291 GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 defaultValue) {
1292     return pointer.GetWithDefault(document, defaultValue);
1293 }
1294 
1295 template <typename DocumentType, typename CharType, size_t N>
1296 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& defaultValue) {
1297     return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1298 }
1299 
1300 template <typename DocumentType, typename CharType, size_t N>
1301 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* defaultValue) {
1302     return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1303 }
1304 
1305 #if RAPIDJSON_HAS_STDSTRING
1306 template <typename DocumentType, typename CharType, size_t N>
1307 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1308     return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1309 }
1310 #endif
1311 
1312 template <typename DocumentType, typename CharType, size_t N, typename T2>
1313 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1314 GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) {
1315     return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1316 }
1317 
1318 //////////////////////////////////////////////////////////////////////////////
1319 
1320 template <typename T>
1321 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
1322     return pointer.Set(root, value, a);
1323 }
1324 
1325 template <typename T>
1326 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& value, typename T::AllocatorType& a) {
1327     return pointer.Set(root, value, a);
1328 }
1329 
1330 template <typename T>
1331 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* value, typename T::AllocatorType& a) {
1332     return pointer.Set(root, value, a);
1333 }
1334 
1335 #if RAPIDJSON_HAS_STDSTRING
1336 template <typename T>
1337 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {
1338     return pointer.Set(root, value, a);
1339 }
1340 #endif
1341 
1342 template <typename T, typename T2>
1343 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1344 SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 value, typename T::AllocatorType& a) {
1345     return pointer.Set(root, value, a);
1346 }
1347 
1348 template <typename T, typename CharType, size_t N>
1349 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
1350     return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1351 }
1352 
1353 template <typename T, typename CharType, size_t N>
1354 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::ValueType& value, typename T::AllocatorType& a) {
1355     return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1356 }
1357 
1358 template <typename T, typename CharType, size_t N>
1359 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::Ch* value, typename T::AllocatorType& a) {
1360     return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1361 }
1362 
1363 #if RAPIDJSON_HAS_STDSTRING
1364 template <typename T, typename CharType, size_t N>
1365 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {
1366     return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1367 }
1368 #endif
1369 
1370 template <typename T, typename CharType, size_t N, typename T2>
1371 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1372 SetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) {
1373     return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1374 }
1375 
1376 // No allocator parameter
1377 
1378 template <typename DocumentType>
1379 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
1380     return pointer.Set(document, value);
1381 }
1382 
1383 template <typename DocumentType>
1384 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& value) {
1385     return pointer.Set(document, value);
1386 }
1387 
1388 template <typename DocumentType>
1389 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* value) {
1390     return pointer.Set(document, value);
1391 }
1392 
1393 #if RAPIDJSON_HAS_STDSTRING
1394 template <typename DocumentType>
1395 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& value) {
1396     return pointer.Set(document, value);
1397 }
1398 #endif
1399 
1400 template <typename DocumentType, typename T2>
1401 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1402 SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 value) {
1403     return pointer.Set(document, value);
1404 }
1405 
1406 template <typename DocumentType, typename CharType, size_t N>
1407 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
1408     return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1409 }
1410 
1411 template <typename DocumentType, typename CharType, size_t N>
1412 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& value) {
1413     return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1414 }
1415 
1416 template <typename DocumentType, typename CharType, size_t N>
1417 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* value) {
1418     return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1419 }
1420 
1421 #if RAPIDJSON_HAS_STDSTRING
1422 template <typename DocumentType, typename CharType, size_t N>
1423 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& value) {
1424     return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1425 }
1426 #endif
1427 
1428 template <typename DocumentType, typename CharType, size_t N, typename T2>
1429 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1430 SetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) {
1431     return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1432 }
1433 
1434 //////////////////////////////////////////////////////////////////////////////
1435 
1436 template <typename T>
1437 typename T::ValueType& SwapValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
1438     return pointer.Swap(root, value, a);
1439 }
1440 
1441 template <typename T, typename CharType, size_t N>
1442 typename T::ValueType& SwapValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
1443     return GenericPointer<typename T::ValueType>(source, N - 1).Swap(root, value, a);
1444 }
1445 
1446 template <typename DocumentType>
1447 typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
1448     return pointer.Swap(document, value);
1449 }
1450 
1451 template <typename DocumentType, typename CharType, size_t N>
1452 typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
1453     return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Swap(document, value);
1454 }
1455 
1456 //////////////////////////////////////////////////////////////////////////////
1457 
1458 template <typename T>
1459 bool EraseValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer) {
1460     return pointer.Erase(root);
1461 }
1462 
1463 template <typename T, typename CharType, size_t N>
1464 bool EraseValueByPointer(T& root, const CharType(&source)[N]) {
1465     return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root);
1466 }
1467 
1468 //@}
1469 
1470 RAPIDJSON_NAMESPACE_END
1471 
1472 #if defined(__clang__) || defined(_MSC_VER)
1473 RAPIDJSON_DIAG_POP
1474 #endif
1475 
1476 #endif // RAPIDJSON_POINTER_H_