osb/source/core/StarJsonPath.cpp

77 lines
2.2 KiB
C++
Raw Normal View History

2023-06-20 04:33:09 +00:00
#include "StarJsonPath.hpp"
namespace Star {
namespace JsonPath {
TypeHint parsePointer(String& buffer, String const& path, String::const_iterator& iterator, String::const_iterator end) {
buffer.clear();
if (*iterator != '/')
2023-06-27 10:23:44 +00:00
throw ParsingException::format("Missing leading '/' in Json pointer \"{}\"", path);
2023-06-20 04:33:09 +00:00
iterator++;
while (iterator != end && *iterator != '/') {
if (*iterator == '~') {
++iterator;
if (iterator == end)
2023-06-27 10:23:44 +00:00
throw ParsingException::format("Incomplete escape sequence in Json pointer \"{}\"", path);
2023-06-20 04:33:09 +00:00
if (*iterator == '0')
buffer.append('~');
else if (*iterator == '1')
buffer.append('/');
else
2023-06-27 10:23:44 +00:00
throw ParsingException::format("Invalid escape sequence in Json pointer \"{}\"", path);
2023-06-20 04:33:09 +00:00
++iterator;
} else
buffer.append(*iterator++);
}
Maybe<size_t> index = maybeLexicalCast<size_t>(buffer);
if (index.isValid() || (buffer == "-" && iterator == end))
return TypeHint::Array;
return TypeHint::Object;
}
TypeHint parseQueryPath(String& buffer, String const& path, String::const_iterator& iterator, String::const_iterator end) {
buffer.clear();
if (*iterator == '.') {
2023-06-27 10:23:44 +00:00
throw ParsingException::format("Entry starts with '.' in query path \"{}\"", path);
2023-06-20 04:33:09 +00:00
} else if (*iterator == '[') {
// Parse array number and ']'
// Consume initial '['
++iterator;
while (iterator != end && *iterator >= '0' && *iterator <= '9')
buffer.append(*iterator++);
if (iterator == end || *iterator != ']')
2023-06-27 10:23:44 +00:00
throw ParsingException::format("Array has no trailing ']' or has invalid character in query path \"{}\"", path);
2023-06-20 04:33:09 +00:00
// Consume trailing ']'
++iterator;
// Consume trailing '.'
if (iterator != end && *iterator == '.')
++iterator;
return TypeHint::Array;
} else {
// Parse path up to next '.' or '['
while (iterator != end && *iterator != '.' && *iterator != '[')
buffer.append(*iterator++);
// Consume single trailing '.' if it exists
if (iterator != end && *iterator == '.')
++iterator;
return TypeHint::Object;
}
}
}
}