15 #ifndef RAPIDJSON_POINTER_H_ 16 #define RAPIDJSON_POINTER_H_ 23 RAPIDJSON_DIAG_OFF(
switch -
enum)
24 #elif defined(_MSC_VER) 26 RAPIDJSON_DIAG_OFF(4512)
79 template <
typename ValueType,
typename Allocator = CrtAllocator>
84 typedef typename ValueType::Ch
Ch;
139 #if RAPIDJSON_HAS_STDSTRING 156 Parse(source.c_str(), source.size());
177 Parse(source, length);
321 Ch* p = r.CopyFromRaw(*
this, 1, token.
length + 1);
322 std::memcpy(p, token.
name, (token.
length + 1) *
sizeof(Ch));
348 template <
typename T>
356 #if RAPIDJSON_HAS_STDSTRING 384 Token token = {
reinterpret_cast<Ch*
>(buffer), length, index };
390 for (
size_t i = 0; i <=
length; i++)
391 name[i] = static_cast<Ch>(buffer[i]);
405 if (token.IsString())
425 size_t GetParseErrorOffset()
const 439 Allocator& GetAllocator()
448 const Token* GetTokens()
const 454 size_t GetTokenCount()
const 492 return !(*
this == rhs);
534 template <
typename OutputStream>
535 bool Stringify(OutputStream& os)
const 537 return Stringify<false, OutputStream>(os);
545 template <
typename OutputStream>
546 bool StringifyUriFragment(OutputStream& os)
const 548 return Stringify<true, OutputStream>(os);
571 ValueType& Create(ValueType& root,
typename ValueType::AllocatorType&
allocator,
bool* alreadyExist = 0)
const 574 ValueType* v = &root;
578 if (v->IsArray() && t->name[0] ==
'-' && t->length == 1)
580 v->PushBack(ValueType().Move(), allocator);
581 v = &((*v)[v->Size() - 1]);
586 if (t->index == kPointerInvalidIndex)
593 if (!v->IsArray() && !v->IsObject())
599 if (t->index >= v->Size())
601 v->Reserve(t->index + 1, allocator);
602 while (t->index >= v->Size())
603 v->PushBack(ValueType().Move(), allocator);
606 v = &((*v)[t->index]);
611 if (m == v->MemberEnd())
613 v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(),
allocator);
614 v = &(--v->MemberEnd())->
value;
624 *alreadyExist = exist;
635 template <
typename stackAllocator>
637 bool* alreadyExist = 0)
const 639 return Create(document, document.
GetAllocator(), alreadyExist);
662 ValueType* Get(ValueType& root,
size_t* unresolvedTokenIndex = 0)
const 665 ValueType* v = &root;
668 switch (v->GetType())
673 if (m == v->MemberEnd())
679 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
681 v = &((*v)[t->index]);
688 if (unresolvedTokenIndex)
689 *unresolvedTokenIndex =
static_cast<size_t>(t -
tokens_);
700 const ValueType* Get(
const ValueType& root,
size_t* unresolvedTokenIndex = 0)
const 702 return Get(const_cast<ValueType&>(root), unresolvedTokenIndex);
720 ValueType& GetWithDefault(ValueType& root,
const ValueType&
defaultValue,
721 typename ValueType::AllocatorType& allocator)
const 724 ValueType& v = Create(root, allocator, &alreadyExist);
725 return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
729 ValueType& GetWithDefault(ValueType& root,
const Ch* defaultValue,
typename ValueType::AllocatorType& allocator)
const 732 ValueType& v = Create(root, allocator, &alreadyExist);
733 return alreadyExist ? v : v.SetString(defaultValue, allocator);
736 #if RAPIDJSON_HAS_STDSTRING 737 ValueType& GetWithDefault(ValueType& root,
const std::basic_string<Ch>& defaultValue,
739 typename ValueType::AllocatorType& allocator)
const 742 ValueType& v = Create(root, allocator, &alreadyExist);
743 return alreadyExist ? v : v.SetString(defaultValue, allocator);
751 template <
typename T>
753 GetWithDefault(ValueType& root, T defaultValue,
typename ValueType::AllocatorType& allocator)
const 755 return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);
759 template <
typename stackAllocator>
761 const ValueType& defaultValue)
const 763 return GetWithDefault(document, defaultValue, document.
GetAllocator());
767 template <
typename stackAllocator>
769 const Ch* defaultValue)
const 771 return GetWithDefault(document, defaultValue, document.
GetAllocator());
774 #if RAPIDJSON_HAS_STDSTRING 775 template <
typename stackAllocator>
778 const std::basic_string<Ch>& defaultValue)
const 780 return GetWithDefault(document, defaultValue, document.
GetAllocator());
788 template <
typename T,
typename stackAllocator>
791 T defaultValue)
const 793 return GetWithDefault(document, defaultValue, document.
GetAllocator());
811 ValueType& Set(ValueType& root, ValueType&
value,
typename ValueType::AllocatorType& allocator)
const 813 return Create(root, allocator) =
value;
817 ValueType& Set(ValueType& root,
const ValueType& value,
typename ValueType::AllocatorType& allocator)
const 819 return Create(root, allocator).CopyFrom(value, allocator);
823 ValueType& Set(ValueType& root,
const Ch* value,
typename ValueType::AllocatorType& allocator)
const 825 return Create(root, allocator) = ValueType(value, allocator).Move();
828 #if RAPIDJSON_HAS_STDSTRING 829 ValueType& Set(ValueType& root,
const std::basic_string<Ch>& value,
831 typename ValueType::AllocatorType& allocator)
const 833 return Create(root, allocator) = ValueType(value, allocator).Move();
841 template <
typename T>
843 Set(ValueType& root, T value,
typename ValueType::AllocatorType& allocator)
const 845 return Create(root, allocator) = ValueType(value).Move();
849 template <
typename stackAllocator>
851 ValueType& value)
const 853 return Create(document) =
value;
857 template <
typename stackAllocator>
859 const ValueType& value)
const 861 return Create(document).CopyFrom(value, document.
GetAllocator());
865 template <
typename stackAllocator>
867 const Ch* value)
const 869 return Create(document) = ValueType(value, document.
GetAllocator()).Move();
872 #if RAPIDJSON_HAS_STDSTRING 873 template <
typename stackAllocator>
876 const std::basic_string<Ch>& value)
const 878 return Create(document) = ValueType(value, document.
GetAllocator()).Move();
886 template <
typename T,
typename stackAllocator>
890 return Create(document) =
value;
908 ValueType&
Swap(ValueType& root, ValueType& value,
typename ValueType::AllocatorType& allocator)
const 910 return Create(root, allocator).
Swap(value);
914 template <
typename stackAllocator>
916 ValueType& value)
const 918 return Create(document).
Swap(value);
930 bool Erase(ValueType& root)
const 936 ValueType* v = &root;
940 switch (v->GetType())
945 if (m == v->MemberEnd())
951 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
953 v = &((*v)[t->index]);
960 switch (v->GetType())
965 if (last->
index == kPointerInvalidIndex || last->
index >= v->Size())
967 v->Erase(v->Begin() + last->
index);
982 Ch* CopyFromRaw(
const GenericPointer& rhs,
size_t extraToken = 0,
size_t extraNameBufferSize = 0)
989 nameBufferSize += t->length;
999 if (nameBufferSize > 0)
1017 bool NeedPercentEncode(
Ch c)
const 1019 return !((c >=
'0' && c <= '9') || (c >=
'A' && c <= 'Z') || (c >=
'a' && c <=
'z') || c ==
'-' || c ==
'.' ||
1020 c ==
'_' || c ==
'~');
1024 #ifndef __clang__ // -Wdocumentation 1043 for (
const Ch*
s = source;
s != source +
length;
s++)
1052 bool uriFragment =
false;
1053 if (source[i] ==
'#')
1059 if (i != length && source[i] !=
'/')
1071 bool isNumber =
true;
1073 while (i < length && source[i] !=
'/')
1081 PercentDecodeStream is(&source[i], source + length);
1089 size_t len = os.
PutEnd(begin);
1101 else if (NeedPercentEncode(c))
1135 if (c < '0' || c >
'9')
1146 if (isNumber && token->
length > 1 && token->
name[0] ==
'0')
1153 for (
size_t j = 0; j < token->
length; j++)
1188 template <
bool uriFragment,
typename OutputStream>
1189 bool Stringify(OutputStream& os)
const 1199 for (
size_t j = 0; j < t->length; j++)
1212 else if (uriFragment && NeedPercentEncode(c))
1219 j += source.
Tell() - 1;
1234 class PercentDecodeStream
1237 typedef typename ValueType::Ch
Ch;
1244 PercentDecodeStream(
const Ch* source,
const Ch* end) : src_(source), head_(source), end_(end), valid_(
true)
1250 if (*src_ !=
'%' || src_ + 3 > end_)
1257 for (
int j = 0; j < 2; j++)
1259 c =
static_cast<Ch
>(c << 4);
1261 if (h >=
'0' && h <=
'9')
1262 c =
static_cast<Ch
>(c + h -
'0');
1263 else if (h >=
'A' && h <=
'F')
1264 c =
static_cast<Ch
>(c + h -
'A' + 10);
1265 else if (h >=
'a' && h <=
'f')
1266 c =
static_cast<Ch
>(c + h -
'a' + 10);
1279 return static_cast<size_t>(src_ - head_);
1281 bool IsValid()
const 1294 template <
typename OutputStream>
1303 unsigned char u =
static_cast<unsigned char>(c);
1304 static const char hexDigits[16] = {
1305 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' 1308 os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u >> 4]));
1309 os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u & 15]));
1333 template <
typename T>
1335 typename T::AllocatorType&
a)
1337 return pointer.Create(root, a);
1340 template <
typename T,
typename CharType,
size_t N>
1348 template <
typename DocumentType>
1352 return pointer.Create(document);
1355 template <
typename DocumentType,
typename CharType,
size_t N>
1363 template <
typename T>
1365 size_t* unresolvedTokenIndex = 0)
1367 return pointer.Get(root, unresolvedTokenIndex);
1370 template <
typename T>
1372 size_t* unresolvedTokenIndex = 0)
1374 return pointer.Get(root, unresolvedTokenIndex);
1377 template <
typename T,
typename CharType,
size_t N>
1383 template <
typename T,
typename CharType,
size_t N>
1385 size_t* unresolvedTokenIndex = 0)
1392 template <
typename T>
1395 typename T::AllocatorType&
a)
1397 return pointer.GetWithDefault(root, defaultValue, a);
1400 template <
typename T>
1402 const typename T::Ch*
defaultValue,
typename T::AllocatorType&
a)
1404 return pointer.GetWithDefault(root, defaultValue, a);
1407 #if RAPIDJSON_HAS_STDSTRING 1408 template <
typename T>
1411 typename T::AllocatorType&
a)
1413 return pointer.GetWithDefault(root, defaultValue, a);
1417 template <
typename T,
typename T2>
1419 (
typename T::ValueType&))
1421 typename T::AllocatorType& a)
1423 return pointer.GetWithDefault(root, defaultValue, a);
1426 template <
typename T,
typename CharType,
size_t N>
1429 typename T::AllocatorType&
a)
1434 template <
typename T,
typename CharType,
size_t N>
1436 const typename T::Ch*
defaultValue,
typename T::AllocatorType&
a)
1441 #if RAPIDJSON_HAS_STDSTRING 1442 template <
typename T,
typename CharType,
size_t N>
1445 typename T::AllocatorType&
a)
1451 template <
typename T,
typename CharType,
size_t N,
typename T2>
1453 (
typename T::ValueType&))
1461 template <
typename DocumentType>
1462 typename DocumentType::ValueType&
1466 return pointer.GetWithDefault(document, defaultValue);
1469 template <
typename DocumentType>
1470 typename DocumentType::ValueType&
1474 return pointer.GetWithDefault(document, defaultValue);
1477 #if RAPIDJSON_HAS_STDSTRING 1478 template <
typename DocumentType>
1479 typename DocumentType::ValueType&
1481 const std::basic_string<typename DocumentType::Ch>&
defaultValue)
1483 return pointer.GetWithDefault(document, defaultValue);
1487 template <
typename DocumentType,
typename T2>
1489 (
typename DocumentType::ValueType&))
1493 return pointer.GetWithDefault(document, defaultValue);
1496 template <
typename DocumentType,
typename CharType,
size_t N>
1498 const typename DocumentType::ValueType& defaultValue)
1503 template <
typename DocumentType,
typename CharType,
size_t N>
1505 const typename DocumentType::Ch* defaultValue)
1510 #if RAPIDJSON_HAS_STDSTRING 1511 template <
typename DocumentType,
typename CharType,
size_t N>
1512 typename DocumentType::ValueType&
1514 const std::basic_string<typename DocumentType::Ch>& defaultValue)
1520 template <
typename DocumentType,
typename CharType,
size_t N,
typename T2>
1522 (
typename DocumentType::ValueType&))
1530 template <
typename T>
1532 typename T::ValueType&
value,
typename T::AllocatorType&
a)
1534 return pointer.Set(root, value, a);
1537 template <
typename T>
1539 const typename T::ValueType&
value,
typename T::AllocatorType&
a)
1541 return pointer.Set(root, value, a);
1544 template <
typename T>
1546 const typename T::Ch*
value,
typename T::AllocatorType&
a)
1548 return pointer.Set(root, value, a);
1551 #if RAPIDJSON_HAS_STDSTRING 1552 template <
typename T>
1554 const std::basic_string<typename T::Ch>&
value,
typename T::AllocatorType&
a)
1556 return pointer.Set(root, value, a);
1560 template <
typename T,
typename T2>
1562 (
typename T::ValueType&))
1565 return pointer.Set(root, value, a);
1568 template <
typename T,
typename CharType,
size_t N>
1570 typename T::AllocatorType&
a)
1575 template <
typename T,
typename CharType,
size_t N>
1577 typename T::AllocatorType&
a)
1582 template <
typename T,
typename CharType,
size_t N>
1584 typename T::AllocatorType&
a)
1589 #if RAPIDJSON_HAS_STDSTRING 1590 template <
typename T,
typename CharType,
size_t N>
1592 const std::basic_string<typename T::Ch>&
value,
typename T::AllocatorType&
a)
1598 template <
typename T,
typename CharType,
size_t N,
typename T2>
1600 (
typename T::ValueType&))
1608 template <
typename DocumentType>
1611 typename DocumentType::ValueType& value)
1613 return pointer.Set(document, value);
1616 template <
typename DocumentType>
1619 const typename DocumentType::ValueType& value)
1621 return pointer.Set(document, value);
1624 template <
typename DocumentType>
1627 const typename DocumentType::Ch* value)
1629 return pointer.Set(document, value);
1632 #if RAPIDJSON_HAS_STDSTRING 1633 template <
typename DocumentType>
1636 const std::basic_string<typename DocumentType::Ch>& value)
1638 return pointer.Set(document, value);
1642 template <
typename DocumentType,
typename T2>
1644 (
typename DocumentType::ValueType&))
1647 return pointer.Set(document, value);
1650 template <
typename DocumentType,
typename CharType,
size_t N>
1652 typename DocumentType::ValueType& value)
1657 template <
typename DocumentType,
typename CharType,
size_t N>
1659 const typename DocumentType::ValueType& value)
1664 template <
typename DocumentType,
typename CharType,
size_t N>
1666 const typename DocumentType::Ch* value)
1671 #if RAPIDJSON_HAS_STDSTRING 1672 template <
typename DocumentType,
typename CharType,
size_t N>
1674 const std::basic_string<typename DocumentType::Ch>& value)
1680 template <
typename DocumentType,
typename CharType,
size_t N,
typename T2>
1682 (
typename DocumentType::ValueType&))
1690 template <
typename T>
1692 typename T::ValueType& value,
typename T::AllocatorType& a)
1694 return pointer.
Swap(root, value, a);
1697 template <
typename T,
typename CharType,
size_t N>
1699 typename T::AllocatorType& a)
1704 template <
typename DocumentType>
1707 typename DocumentType::ValueType& value)
1709 return pointer.
Swap(document, value);
1712 template <
typename DocumentType,
typename CharType,
size_t N>
1714 typename DocumentType::ValueType& value)
1721 template <
typename T>
1724 return pointer.Erase(root);
1727 template <
typename T,
typename CharType,
size_t N>
1737 #if defined(__clang__) || defined(_MSC_VER) 1741 #endif // RAPIDJSON_POINTER_H_ GenericPointer(const Token *tokens, size_t tokenCount)
Constructor with user-supplied tokens.
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)
const CharType(& source)[N]
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
#define RAPIDJSON_ASSERT(x)
Assertion.
Ch * nameBuffer_
A buffer containing all names in tokens.
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
ValueType::EncodingType EncodingType
Encoding type from Value.
Invalid percent encoding in URI fragment.
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...
PointerParseErrorCode parseErrorCode_
Parsing error code.
GenericPointer(const GenericPointer &rhs)
Copy constructor.
Token * tokens_
A list of tokens.
static RAPIDJSON_NAMESPACE_BEGIN const SizeType kPointerInvalidIndex
Represents an invalid index in GenericPointer::Token.
GenericPointer Append(const Ch *name, SizeType length, Allocator *allocator=0) const
Append a name token with length, and return a new Pointer.
SizeType index
A valid array index, if it is not equal to kPointerInvalidIndex.
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
T::ValueType & swapValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
A token is the basic units of internal representation.
A document for parsing JSON text as DOM.
A token must begin with a '/'.
A read-write string stream.
SizeType length
Length of the name.
GenericPointer(const Ch *source, Allocator *allocator=0)
Constructor that parses a string or URI fragment representation.
size_t parseErrorOffset_
Offset in code unit when parsing fail.
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
friend void swap(GenericPointer &a, GenericPointer &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
GenericPointer & operator=(const GenericPointer &rhs)
Assignment operator.
A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence.
GenericPointer< Value > Pointer
GenericPointer for Value (UTF-8, default allocator).
PercentEncodeStream(OutputStream &os)
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 & GetAllocator()
Get the allocator of this document.
size_t tokenCount_
Number of tokens in tokens_.
void Swap(T &a, T &b) RAPIDJSON_NOEXCEPT
Custom swap() to avoid dependency on C++ <algorithm> header.
#define RAPIDJSON_DELETE(x)
! customization point for global delete
char * u32toa(uint32_t value, char *buffer)
T::ValueType & CreateValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::AllocatorType &a)
GenericPointer(const GenericPointer &rhs, Allocator *allocator)
Copy constructor.
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
ValueType::Ch Ch
Character type from Value.
const Ch * name
Name of the token. It has null character at the end but it can contain null character.
PointerParseErrorCode
Error code of parsing.
const GenericPointer< typename T::ValueType > T2 value
GenericPointer Append(const Token &token, Allocator *allocator=0) const
Append a token and return a new Pointer.
GenericPointer & Swap(GenericPointer &other) RAPIDJSON_NOEXCEPT
Swap the content of this pointer with an other.
bool EraseValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer)
const GenericPointer< typename T::ValueType > T2 defaultValue
SizeType StrLen(const Ch *s)
Custom strlen() which works on different character types.
Reference to a constant string (not taking a copy)
Allocator * allocator_
The current allocator. It is either user-supplied or equal to ownAllocator_.
const GenericPointer< typename T::ValueType > & pointer
A character must percent encoded in URI fragment.
Allocator * ownAllocator_
Allocator owned by this Pointer.
T::ValueType & SetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, typename T::ValueType &value, typename T::AllocatorType &a)
GenericPointer(Allocator *allocator=0)
Default constructor.
T::ValueType * GetValueByPointer(T &root, const GenericPointer< typename T::ValueType > &pointer, size_t *unresolvedTokenIndex=0)
~GenericPointer()
Destructor.