Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a9ed3feca3 | ||
|
|
eb2a092d70 | ||
|
|
2a2c7d30f0 |
No files matched your search
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <algorithm> // all_of
|
#include <algorithm> // all_of, copy
|
||||||
#include <array> // array
|
#include <array> // array
|
||||||
#include <cctype> // isdigit
|
#include <cctype> // isdigit
|
||||||
#include <cerrno> // errno, ERANGE
|
#include <cerrno> // errno, ERANGE
|
||||||
@@ -82,12 +82,34 @@ class json_pointer
|
|||||||
{
|
{
|
||||||
// one buffer: every token adds its escaped form (at least its length) and a slash
|
// one buffer: every token adds its escaped form (at least its length) and a slash
|
||||||
std::size_t length = 0;
|
std::size_t length = 0;
|
||||||
|
bool plain = true;
|
||||||
for (const auto& reference_token : reference_tokens)
|
for (const auto& reference_token : reference_tokens)
|
||||||
{
|
{
|
||||||
length += reference_token.size() + 1;
|
length += reference_token.size() + 1;
|
||||||
|
const char* const data = reference_token.data();
|
||||||
|
for (std::size_t i = 0, size = reference_token.size(); plain && i < size; ++i)
|
||||||
|
{
|
||||||
|
plain = data[i] != '~' && data[i] != '/';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string_t result;
|
string_t result;
|
||||||
|
if (JSON_HEDLEY_LIKELY(plain))
|
||||||
|
{
|
||||||
|
// nothing to escape: the tokens are copied into the string
|
||||||
|
result.resize(length);
|
||||||
|
if (length != 0)
|
||||||
|
{
|
||||||
|
char* out = &result[0];
|
||||||
|
for (const auto& reference_token : reference_tokens)
|
||||||
|
{
|
||||||
|
*out++ = '/';
|
||||||
|
out = std::copy(reference_token.data(), reference_token.data() + reference_token.size(), out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
result.reserve(length);
|
result.reserve(length);
|
||||||
for (const auto& reference_token : reference_tokens)
|
for (const auto& reference_token : reference_tokens)
|
||||||
{
|
{
|
||||||
@@ -1198,33 +1220,32 @@ class json_pointer
|
|||||||
}
|
}
|
||||||
result.reserve(token_count);
|
result.reserve(token_count);
|
||||||
|
|
||||||
// extract the reference tokens:
|
// extract the reference tokens: every one runs from after a slash to
|
||||||
// - slash: position of the last read slash (or end of string)
|
// the next slash or the end of the string; a token without a '~' (the
|
||||||
// - start: position after the previous slash
|
// common case) is stored as it is, others are checked and unescaped
|
||||||
for (
|
const char* const data = reference_string.data();
|
||||||
// search for the first slash after the first character
|
const char* const end = data + size;
|
||||||
std::size_t slash = reference_string.find_first_of('/', 1),
|
for (const char* start = data + 1;; ++start)
|
||||||
// set the beginning of the first reference token
|
|
||||||
start = 1;
|
|
||||||
// we can stop if start == 0 (if slash == string_t::npos)
|
|
||||||
start != 0;
|
|
||||||
// set the beginning of the next reference token
|
|
||||||
// (will eventually be 0 if slash == string_t::npos)
|
|
||||||
start = (slash == string_t::npos) ? 0 : slash + 1,
|
|
||||||
// find next slash
|
|
||||||
slash = reference_string.find_first_of('/', start))
|
|
||||||
{
|
{
|
||||||
// use the text between the beginning of the reference token
|
const char* slash = start;
|
||||||
// (start) and the last slash (slash).
|
bool escaped = false;
|
||||||
const auto count = (slash == string_t::npos ? reference_string.size() : slash) - start;
|
while (slash != end && *slash != '/')
|
||||||
auto reference_token = string_t(reference_string.data() + start, count);
|
|
||||||
|
|
||||||
// check reference tokens are properly escaped; a token without
|
|
||||||
// a '~' (the common case) needs neither check nor unescaping
|
|
||||||
std::size_t pos = reference_token.find_first_of('~');
|
|
||||||
if (pos != string_t::npos)
|
|
||||||
{
|
{
|
||||||
for (; pos != string_t::npos; pos = reference_token.find_first_of('~', pos + 1))
|
escaped = escaped || *slash == '~';
|
||||||
|
++slash;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto count = static_cast<std::size_t>(slash - start);
|
||||||
|
if (JSON_HEDLEY_LIKELY(!escaped))
|
||||||
|
{
|
||||||
|
result.emplace_back(start, count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto reference_token = string_t(start, count);
|
||||||
|
|
||||||
|
// check reference tokens are properly escaped
|
||||||
|
for (std::size_t pos = reference_token.find_first_of('~'); pos != string_t::npos; pos = reference_token.find_first_of('~', pos + 1))
|
||||||
{
|
{
|
||||||
JSON_ASSERT(reference_token[pos] == '~');
|
JSON_ASSERT(reference_token[pos] == '~');
|
||||||
|
|
||||||
@@ -1238,10 +1259,14 @@ class json_pointer
|
|||||||
}
|
}
|
||||||
|
|
||||||
detail::unescape(reference_token);
|
detail::unescape(reference_token);
|
||||||
|
result.push_back(std::move(reference_token));
|
||||||
}
|
}
|
||||||
|
|
||||||
// finally, store the reference token
|
if (slash == end)
|
||||||
result.push_back(std::move(reference_token));
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
start = slash;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
Generated
+53
-28
@@ -22350,7 +22350,7 @@ NLOHMANN_JSON_NAMESPACE_END
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <algorithm> // all_of
|
#include <algorithm> // all_of, copy
|
||||||
#include <array> // array
|
#include <array> // array
|
||||||
#include <cctype> // isdigit
|
#include <cctype> // isdigit
|
||||||
#include <cerrno> // errno, ERANGE
|
#include <cerrno> // errno, ERANGE
|
||||||
@@ -22432,12 +22432,34 @@ class json_pointer
|
|||||||
{
|
{
|
||||||
// one buffer: every token adds its escaped form (at least its length) and a slash
|
// one buffer: every token adds its escaped form (at least its length) and a slash
|
||||||
std::size_t length = 0;
|
std::size_t length = 0;
|
||||||
|
bool plain = true;
|
||||||
for (const auto& reference_token : reference_tokens)
|
for (const auto& reference_token : reference_tokens)
|
||||||
{
|
{
|
||||||
length += reference_token.size() + 1;
|
length += reference_token.size() + 1;
|
||||||
|
const char* const data = reference_token.data();
|
||||||
|
for (std::size_t i = 0, size = reference_token.size(); plain && i < size; ++i)
|
||||||
|
{
|
||||||
|
plain = data[i] != '~' && data[i] != '/';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string_t result;
|
string_t result;
|
||||||
|
if (JSON_HEDLEY_LIKELY(plain))
|
||||||
|
{
|
||||||
|
// nothing to escape: the tokens are copied into the string
|
||||||
|
result.resize(length);
|
||||||
|
if (length != 0)
|
||||||
|
{
|
||||||
|
char* out = &result[0];
|
||||||
|
for (const auto& reference_token : reference_tokens)
|
||||||
|
{
|
||||||
|
*out++ = '/';
|
||||||
|
out = std::copy(reference_token.data(), reference_token.data() + reference_token.size(), out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
result.reserve(length);
|
result.reserve(length);
|
||||||
for (const auto& reference_token : reference_tokens)
|
for (const auto& reference_token : reference_tokens)
|
||||||
{
|
{
|
||||||
@@ -23548,33 +23570,32 @@ class json_pointer
|
|||||||
}
|
}
|
||||||
result.reserve(token_count);
|
result.reserve(token_count);
|
||||||
|
|
||||||
// extract the reference tokens:
|
// extract the reference tokens: every one runs from after a slash to
|
||||||
// - slash: position of the last read slash (or end of string)
|
// the next slash or the end of the string; a token without a '~' (the
|
||||||
// - start: position after the previous slash
|
// common case) is stored as it is, others are checked and unescaped
|
||||||
for (
|
const char* const data = reference_string.data();
|
||||||
// search for the first slash after the first character
|
const char* const end = data + size;
|
||||||
std::size_t slash = reference_string.find_first_of('/', 1),
|
for (const char* start = data + 1;; ++start)
|
||||||
// set the beginning of the first reference token
|
|
||||||
start = 1;
|
|
||||||
// we can stop if start == 0 (if slash == string_t::npos)
|
|
||||||
start != 0;
|
|
||||||
// set the beginning of the next reference token
|
|
||||||
// (will eventually be 0 if slash == string_t::npos)
|
|
||||||
start = (slash == string_t::npos) ? 0 : slash + 1,
|
|
||||||
// find next slash
|
|
||||||
slash = reference_string.find_first_of('/', start))
|
|
||||||
{
|
{
|
||||||
// use the text between the beginning of the reference token
|
const char* slash = start;
|
||||||
// (start) and the last slash (slash).
|
bool escaped = false;
|
||||||
const auto count = (slash == string_t::npos ? reference_string.size() : slash) - start;
|
while (slash != end && *slash != '/')
|
||||||
auto reference_token = string_t(reference_string.data() + start, count);
|
|
||||||
|
|
||||||
// check reference tokens are properly escaped; a token without
|
|
||||||
// a '~' (the common case) needs neither check nor unescaping
|
|
||||||
std::size_t pos = reference_token.find_first_of('~');
|
|
||||||
if (pos != string_t::npos)
|
|
||||||
{
|
{
|
||||||
for (; pos != string_t::npos; pos = reference_token.find_first_of('~', pos + 1))
|
escaped = escaped || *slash == '~';
|
||||||
|
++slash;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto count = static_cast<std::size_t>(slash - start);
|
||||||
|
if (JSON_HEDLEY_LIKELY(!escaped))
|
||||||
|
{
|
||||||
|
result.emplace_back(start, count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto reference_token = string_t(start, count);
|
||||||
|
|
||||||
|
// check reference tokens are properly escaped
|
||||||
|
for (std::size_t pos = reference_token.find_first_of('~'); pos != string_t::npos; pos = reference_token.find_first_of('~', pos + 1))
|
||||||
{
|
{
|
||||||
JSON_ASSERT(reference_token[pos] == '~');
|
JSON_ASSERT(reference_token[pos] == '~');
|
||||||
|
|
||||||
@@ -23588,10 +23609,14 @@ class json_pointer
|
|||||||
}
|
}
|
||||||
|
|
||||||
detail::unescape(reference_token);
|
detail::unescape(reference_token);
|
||||||
|
result.push_back(std::move(reference_token));
|
||||||
}
|
}
|
||||||
|
|
||||||
// finally, store the reference token
|
if (slash == end)
|
||||||
result.push_back(std::move(reference_token));
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
start = slash;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
Reference in new issue
Block a user