Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/miloyip/rapidjson.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormiloyip <miloyip@gmail.com>2015-05-03 04:51:15 +0300
committermiloyip <miloyip@gmail.com>2015-05-03 04:51:15 +0300
commit28f14bd68f30872417a6c96dc4be1e7195c24f5d (patch)
tree88afe190a27fe5398b9d9bf56338ef481333db0f /include/rapidjson/pointer.h
parent2ee15de4a9f5813594820eb510dfcd2090238b18 (diff)
Add parsing of URI fragment representation of JSON pointer
Diffstat (limited to 'include/rapidjson/pointer.h')
-rw-r--r--include/rapidjson/pointer.h44
1 files changed, 42 insertions, 2 deletions
diff --git a/include/rapidjson/pointer.h b/include/rapidjson/pointer.h
index c0b22539..4086751e 100644
--- a/include/rapidjson/pointer.h
+++ b/include/rapidjson/pointer.h
@@ -25,7 +25,9 @@ enum PointerParseErrorCode {
kPointerParseErrorNone = 0,
kPointerParseErrorTokenMustBeginWithSolidus,
- kPointerParseErrorInvalidEscape
+ kPointerParseErrorInvalidEscape,
+ kPointerParseErrorInvalidPercentEncoding,
+ kPointerParseErrorCharacterMustPercentEncode
};
template <typename ValueType, typename Allocator = CrtAllocator>
@@ -363,6 +365,12 @@ public:
}
private:
+ //! Parse a JSON String or its URI fragment representation into tokens.
+ /*!
+ \param source Either a JSON Pointer string, or its URI fragment representation. Not need to be null terminated.
+ \param length Length of the source string.
+ \note Source cannot be JSON String Representation of JSON Pointer, e.g. In "/\u0000", \u0000 will not be unescaped.
+ */
void Parse(const Ch* source, size_t length) {
// Create own allocator if user did not supply.
if (!allocator_)
@@ -380,7 +388,14 @@ private:
size_t i = 0;
- if (length != 0 && source[i] != '/') {
+ // Detect if it is a URI fragment
+ bool uriFragment = false;
+ if (source[i] == '#') {
+ uriFragment = true;
+ i++;
+ }
+
+ if (i != length && source[i] != '/') {
parseErrorCode_ = kPointerParseErrorTokenMustBeginWithSolidus;
goto error;
}
@@ -395,6 +410,31 @@ private:
while (i < length && source[i] != '/') {
Ch c = source[i++];
+
+ if (uriFragment) {
+ // Decoding percent-encoding for URI fragment
+ if (c == '%') {
+ c = 0;
+ for (int j = 0; j < 2; j++) {
+ c <<= 4;
+ Ch h = source[i];
+ if (h >= '0' && h <= '9') c += h - '0';
+ else if (h >= 'A' && h <= 'F') c += h - 'A' + 10;
+ else if (h >= 'a' && h <= 'f') c += h - 'a' + 10;
+ else {
+ parseErrorCode_ = kPointerParseErrorInvalidPercentEncoding;
+ goto error;
+ }
+ i++;
+ }
+ }
+ else if (!((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~')) {
+ // RFC 3986 2.3 Unreserved Characters
+ i--;
+ parseErrorCode_ = kPointerParseErrorCharacterMustPercentEncode;
+ goto error;
+ }
+ }
// Escaping "~0" -> '~', "~1" -> '/'
if (c == '~') {