15 #ifndef RAPIDJSON_POINTER_H_ 16 #define RAPIDJSON_POINTER_H_ 70 template <
typename ValueType,
typename Allocator = CrtAllocator>
74 typedef typename EncodingType::Ch
Ch;
110 #if RAPIDJSON_HAS_STDSTRING 118 Parse(source.c_str(), source.size());
130 Parse(source, length);
205 std::memcpy(p, token.
name, (token.
length + 1) *
sizeof(Ch));
230 template <
typename T>
236 #if RAPIDJSON_HAS_STDSTRING 259 if (
sizeof(
Ch) == 1) {
265 for (
size_t i = 0; i <=
length; i++)
279 if (token.IsString())
309 size_t GetTokenCount()
const {
return tokenCount_; }
340 bool operator!=(
const GenericPointer& rhs)
const {
return !(*
this == rhs); }
352 template<
typename OutputStream>
354 return Stringify<false, OutputStream>(os);
362 template<
typename OutputStream>
363 bool StringifyUriFragment(OutputStream& os)
const {
364 return Stringify<true, OutputStream>(os);
387 ValueType& Create(ValueType& root,
typename ValueType::AllocatorType&
allocator,
bool* alreadyExist = 0)
const {
389 ValueType*
v = &root;
392 if (v->IsArray() &&
t->name[0] ==
'-' &&
t->length == 1) {
394 v = &((*v)[v->Size() - 1]);
403 if (!v->IsArray() && !v->IsObject())
408 if (
t->index >= v->Size()) {
410 while (
t->index >= v->Size())
414 v = &((*v)[
t->index]);
418 if (m == v->MemberEnd()) {
420 v = &(--v->MemberEnd())->
value;
430 *alreadyExist = exist;
442 template <
typename stackAllocator>
444 return Create(document, document.
GetAllocator(), alreadyExist);
457 ValueType* Get(ValueType& root)
const {
459 ValueType*
v = &root;
461 switch (v->GetType()) {
465 if (m == v->MemberEnd())
473 v = &((*v)[
t->index]);
487 const ValueType* Get(
const ValueType& root)
const {
return Get(const_cast<ValueType&>(root)); }
504 ValueType& GetWithDefault(ValueType& root,
const ValueType&
defaultValue,
typename ValueType::AllocatorType&
allocator)
const {
506 Value&
v = Create(root, allocator, &alreadyExist);
507 return alreadyExist ? v : v.CopyFrom(
defaultValue, allocator);
511 ValueType& GetWithDefault(ValueType& root,
const Ch*
defaultValue,
typename ValueType::AllocatorType&
allocator)
const {
513 Value&
v = Create(root, allocator, &alreadyExist);
514 return alreadyExist ? v : v.SetString(
defaultValue, allocator);
517 #if RAPIDJSON_HAS_STDSTRING 518 ValueType& GetWithDefault(ValueType& root,
const std::basic_string<Ch>&
defaultValue,
typename ValueType::AllocatorType&
allocator)
const {
521 Value&
v = Create(root, allocator, &alreadyExist);
522 return alreadyExist ? v : v.SetString(
defaultValue, allocator);
530 template <
typename T>
532 GetWithDefault(ValueType& root, T
defaultValue,
typename ValueType::AllocatorType&
allocator)
const {
533 return GetWithDefault(root, ValueType(
defaultValue).Move(), allocator);
537 template <
typename stackAllocator>
539 return GetWithDefault(document, defaultValue, document.
GetAllocator());
543 template <
typename stackAllocator>
545 return GetWithDefault(document, defaultValue, document.
GetAllocator());
548 #if RAPIDJSON_HAS_STDSTRING 549 template <
typename stackAllocator>
552 return GetWithDefault(document, defaultValue, document.
GetAllocator());
560 template <
typename T,
typename stackAllocator>
581 ValueType&
Set(ValueType& root, ValueType&
value,
typename ValueType::AllocatorType&
allocator)
const {
582 return Create(root, allocator) =
value;
586 ValueType&
Set(ValueType& root,
const ValueType&
value,
typename ValueType::AllocatorType&
allocator)
const {
587 return Create(root, allocator).CopyFrom(value, allocator);
592 return Create(root, allocator) = ValueType(value, allocator).Move();
595 #if RAPIDJSON_HAS_STDSTRING 596 ValueType&
Set(ValueType& root,
const std::basic_string<Ch>&
value,
typename ValueType::AllocatorType&
allocator)
const {
598 return Create(root, allocator) = ValueType(
value, allocator).Move();
606 template <
typename T>
613 template <
typename stackAllocator>
615 return Create(document) =
value;
619 template <
typename stackAllocator>
621 return Create(document).CopyFrom(value, document.
GetAllocator());
625 template <
typename stackAllocator>
627 return Create(document) = ValueType(value, document.
GetAllocator()).Move();
630 #if RAPIDJSON_HAS_STDSTRING 631 template <
typename stackAllocator>
634 return Create(document) = ValueType(value, document.
GetAllocator()).Move();
642 template <
typename T,
typename stackAllocator>
645 return Create(document) =
value;
663 ValueType&
Swap(ValueType& root, ValueType&
value,
typename ValueType::AllocatorType&
allocator)
const {
664 return Create(root, allocator).Swap(value);
668 template <
typename stackAllocator>
670 return Create(document).Swap(value);
687 ValueType*
v = &root;
690 switch (v->GetType()) {
694 if (m == v->MemberEnd())
702 v = &((*v)[
t->index]);
709 switch (v->GetType()) {
715 v->Erase(v->Begin() + last->
index);
736 nameBufferSize +=
t->length;
778 for (
const Ch*
s = source;
s != source +
length;
s++)
787 bool uriFragment =
false;
788 if (source[i] ==
'#') {
793 if (i != length && source[i] !=
'/') {
803 bool isNumber =
true;
805 while (i < length && source[i] !=
'/') {
840 if (c ==
'0') c =
'~';
841 else if (c ==
'1') c =
'/';
866 if (isNumber && token->
length > 1 && token->
name[0] ==
'0')
872 for (
size_t j = 0; j < token->
length; j++) {
905 template<
bool uriFragment,
typename OutputStream>
914 for (
size_t j = 0; j <
t->length; j++) {
930 j += source.
Tell() - 1;
955 if (*src_ !=
'%' || src_ + 3 > end_) {
961 for (
int j = 0; j < 2; j++) {
964 if (h >=
'0' && h <=
'9') c += h -
'0';
965 else if (h >=
'A' && h <=
'F') c += h -
'A' + 10;
966 else if (h >=
'a' && h <=
'f') c += h -
'a' + 10;
976 size_t Tell()
const {
return src_ - head_; }
987 template <
typename OutputStream>
992 unsigned char u =
static_cast<unsigned char>(
c);
993 static const char hexDigits[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
995 os_.Put(hexDigits[u >> 4]);
996 os_.Put(hexDigits[u & 15]);
1019 template <
typename T>
1021 return pointer.Create(root, a);
1024 template <
typename T,
typename CharType,
size_t N>
1031 template <
typename DocumentType>
1033 return pointer.Create(document);
1036 template <
typename DocumentType,
typename CharType,
size_t N>
1043 template <
typename T>
1045 return pointer.Get(root);
1048 template <
typename T>
1050 return pointer.Get(root);
1053 template <
typename T,
typename CharType,
size_t N>
1058 template <
typename T,
typename CharType,
size_t N>
1065 template <
typename T>
1067 return pointer.GetWithDefault(root, defaultValue, a);
1070 template <
typename T>
1072 return pointer.GetWithDefault(root, defaultValue, a);
1075 #if RAPIDJSON_HAS_STDSTRING 1076 template <
typename T>
1078 return pointer.GetWithDefault(root, defaultValue, a);
1082 template <
typename T,
typename T2>
1085 return pointer.GetWithDefault(root, defaultValue, a);
1088 template <
typename T,
typename CharType,
size_t N>
1093 template <
typename T,
typename CharType,
size_t N>
1098 #if RAPIDJSON_HAS_STDSTRING 1099 template <
typename T,
typename CharType,
size_t N>
1105 template <
typename T,
typename CharType,
size_t N,
typename T2>
1113 template <
typename DocumentType>
1115 return pointer.GetWithDefault(document, defaultValue);
1118 template <
typename DocumentType>
1120 return pointer.GetWithDefault(document, defaultValue);
1123 #if RAPIDJSON_HAS_STDSTRING 1124 template <
typename DocumentType>
1126 return pointer.GetWithDefault(document, defaultValue);
1130 template <
typename DocumentType,
typename T2>
1133 return pointer.GetWithDefault(document, defaultValue);
1136 template <
typename DocumentType,
typename CharType,
size_t N>
1141 template <
typename DocumentType,
typename CharType,
size_t N>
1146 #if RAPIDJSON_HAS_STDSTRING 1147 template <
typename DocumentType,
typename CharType,
size_t N>
1148 typename DocumentType::ValueType&
GetValueByPointerWithDefault(DocumentType& document,
const CharType(&
source)[N],
const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1153 template <
typename DocumentType,
typename CharType,
size_t N,
typename T2>
1161 template <
typename T>
1163 return pointer.
Set(root, value, a);
1166 template <
typename T>
1168 return pointer.
Set(root, value, a);
1171 template <
typename T>
1173 return pointer.
Set(root, value, a);
1176 #if RAPIDJSON_HAS_STDSTRING 1177 template <
typename T>
1179 return pointer.
Set(root, value, a);
1183 template <
typename T,
typename T2>
1186 return pointer.Set(root, value, a);
1189 template <
typename T,
typename CharType,
size_t N>
1194 template <
typename T,
typename CharType,
size_t N>
1199 template <
typename T,
typename CharType,
size_t N>
1204 #if RAPIDJSON_HAS_STDSTRING 1205 template <
typename T,
typename CharType,
size_t N>
1206 typename T::ValueType&
SetValueByPointer(T& root,
const CharType(&
source)[N],
const std::basic_string<typename T::Ch>&
value,
typename T::AllocatorType&
a) {
1211 template <
typename T,
typename CharType,
size_t N,
typename T2>
1219 template <
typename DocumentType>
1221 return pointer.
Set(document, value);
1224 template <
typename DocumentType>
1226 return pointer.
Set(document, value);
1229 template <
typename DocumentType>
1231 return pointer.
Set(document, value);
1234 #if RAPIDJSON_HAS_STDSTRING 1235 template <
typename DocumentType>
1237 return pointer.
Set(document, value);
1241 template <
typename DocumentType,
typename T2>
1244 return pointer.
Set(document, value);
1247 template <
typename DocumentType,
typename CharType,
size_t N>
1248 typename DocumentType::ValueType&
SetValueByPointer(DocumentType& document,
const CharType(&
source)[N],
typename DocumentType::ValueType& value) {
1252 template <
typename DocumentType,
typename CharType,
size_t N>
1253 typename DocumentType::ValueType&
SetValueByPointer(DocumentType& document,
const CharType(&
source)[N],
const typename DocumentType::ValueType& value) {
1257 template <
typename DocumentType,
typename CharType,
size_t N>
1258 typename DocumentType::ValueType&
SetValueByPointer(DocumentType& document,
const CharType(&
source)[N],
const typename DocumentType::Ch* value) {
1262 #if RAPIDJSON_HAS_STDSTRING 1263 template <
typename DocumentType,
typename CharType,
size_t N>
1264 typename DocumentType::ValueType&
SetValueByPointer(DocumentType& document,
const CharType(&
source)[N],
const std::basic_string<typename DocumentType::Ch>& value) {
1269 template <
typename DocumentType,
typename CharType,
size_t N,
typename T2>
1277 template <
typename T>
1279 return pointer.
Swap(root, value, a);
1282 template <
typename T,
typename CharType,
size_t N>
1283 typename T::ValueType&
SwapValueByPointer(T& root,
const CharType(&
source)[N],
typename T::ValueType& value,
typename T::AllocatorType& a) {
1287 template <
typename DocumentType>
1289 return pointer.
Swap(document, value);
1292 template <
typename DocumentType,
typename CharType,
size_t N>
1293 typename DocumentType::ValueType&
SwapValueByPointer(DocumentType& document,
const CharType(&
source)[N],
typename DocumentType::ValueType& value) {
1299 template <
typename T>
1301 return pointer.
Erase(root);
1304 template <
typename T,
typename CharType,
size_t N>
1313 #endif // RAPIDJSON_POINTER_H_ bool operator==(const ngl::Mat3 &_m1, const ngl::Mat3 &_m2)
ValueType & Set(ValueType &root, const Ch *value, typename ValueType::AllocatorType &allocator) const
Set a null-terminated string in a subtree.
T::ValueType & GetValueByPointerWithDefault(T &root, const GenericPointer< typename T::ValueType > &pointer, const typename T::ValueType &defaultValue, typename T::AllocatorType &a)
char * u64toa(uint64_t value, char *buffer)
PointerParseErrorCode
Error code of parsing.
GenericPointer(const Ch *source, Allocator *allocator=0)
Constructor that parses a string or URI fragment representation.
SizeType length
Length of the name.
A token is the basic units of internal representation.
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...
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
bool Erase(ValueType &root) const
Erase a value in a subtree.
Token * tokens_
A list of tokens.
const Ch * end_
Past-the-end position.
Invalid percent encoding in URI fragment.
~GenericPointer()
Destructor.
const CharType(& source)[N]
ValueType & Swap(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, ValueType &value) const
Swap a value with a value in a document.
size_t tokenCount_
Number of tokens in tokens_.
bool valid_
Whether the parsing is valid.
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
GenericPointer(const Token *tokens, size_t tokenCount)
Constructor with user-supplied tokens.
GLsizei const GLfloat * value
static RAPIDJSON_NAMESPACE_BEGIN const SizeType kPointerInvalidIndex
Represents an invalid index in GenericPointer::Token.
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
ValueType::EncodingType EncodingType
Encoding type from Value.
ValueType & Swap(ValueType &root, ValueType &value, typename ValueType::AllocatorType &allocator) const
Swap a value with a value in a subtree.
T::ValueType & SwapValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
GLuint GLsizei GLsizei * length
GLsizei GLsizei GLchar * source
Allocator & GetAllocator()
Get the allocator of this document.
bool NeedPercentEncode(Ch c) const
Check whether a character should be percent-encoded.
ValueType & Set(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, ValueType &value) const
Set a value in a document, with move semantics.
Allocator stackAllocator stackAllocator T defaultValue const
A helper stream for decoding a percent-encoded sequence into code unit.
size_t parseErrorOffset_
Offset in code unit when parsing fail.
Reference to a constant string (not taking a copy)
ValueType & Set(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, const Ch *value) const
Set a null-terminated string in a document.
SizeType index
A valid array index, if it is not equal to kPointerInvalidIndex.
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
GenericPointer< Value > Pointer
GenericPointer for Value (UTF-8, default allocator).
A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence.
const Ch * src_
Current read position.
EncodingType::Ch Ch
Character type from Value.
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
#define RAPIDJSON_NEW(x)
! customization point for global new
GenericPointer()
Default constructor.
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
bool Stringify(OutputStream &os) const
Stringify to string or URI fragment representation.
#define RAPIDJSON_DELETE(x)
! customization point for global delete
PercentDecodeStream(const Ch *source, const Ch *end)
Constructor.
char * u32toa(uint32_t value, char *buffer)
T::ValueType & CreateValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::AllocatorType &a)
const Ch * head_
Original head of the string.
GLfloat GLfloat GLfloat GLfloat h
ValueType & Set(ValueType &root, ValueType &value, typename ValueType::AllocatorType &allocator) const
Set a value in a subtree, with move semantics.
Ch * nameBuffer_
A buffer containing all names in tokens.
A character must percent encoded in URI fragment.
GLdouble GLdouble GLdouble r
Allocator * ownAllocator_
Allocator owned by this Pointer.
GenericPointer(const GenericPointer &rhs)
Copy constructor.
A token must begin with a '/'.
GLuint const GLchar * name
PointerParseErrorCode parseErrorCode_
Parsing error code.
void Parse(const Ch *source, size_t length)
Parse a JSON String or its URI fragment representation into tokens.
bool EraseValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer)
Ch * CopyFromRaw(const GenericPointer &rhs, size_t extraToken=0, size_t extraNameBufferSize=0)
Clone the content from rhs to this.
T::ValueType * GetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer)
const GenericPointer< typename T::ValueType > T2 defaultValue
GenericPointer Append(const Ch *name, SizeType length, Allocator *allocator=0) const
Append a name token with length, and return a new Pointer.
SizeType StrLen(const Ch *s)
Custom strlen() which works on different character types.
GLsizei const void * pointer
A read-write string stream.
Allocator stackAllocator stackAllocator & document
T::ValueType & SetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
GLboolean GLboolean GLboolean GLboolean a
ValueType & Set(ValueType &root, const ValueType &value, typename ValueType::AllocatorType &allocator) const
Set a value in a subtree, with copy semantics.
ValueType & Set(GenericDocument< EncodingType, typename ValueType::AllocatorType, stackAllocator > &document, const ValueType &value) const
Set a value in a document, with copy semantics.
#define RAPIDJSON_ASSERT(x)
Assertion.
RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr< internal::IsSame< typename internal::RemoveConst< T >::Type, Ch > >),(GenericPointer)) Append(T *name
Append a name token without length, and return a new Pointer.
Allocator * allocator_
The current allocator. It is either user-supplied or equal to ownAllocator_.
const Ch * name
Name of the token. It has null character at the end but it can contain null character.
A document for parsing JSON text as DOM.
GenericPointer & operator=(const GenericPointer &rhs)
Assignment operator.
PercentEncodeStream(OutputStream &os)