mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
Support JSON pointer in DOM navigation model
This commit is contained in:
+67
-33
@@ -6,43 +6,77 @@
|
||||
#ifndef ASSERT
|
||||
#define ASSERT(x) \
|
||||
{ if (!(x)) { \
|
||||
char buf[4096]; \
|
||||
snprintf (buf, 4096, "Failure in \"%s\", line %d\n", \
|
||||
__FILE__, __LINE__); \
|
||||
abort (); \
|
||||
std::cerr << "Failed assertion " << #x << std::endl; \
|
||||
return false; \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
// {"/~01abc": [0, {"\\\" 0": ["value0", "value1"]}]}"
|
||||
std::string json =
|
||||
"{\"/~01abc\": [0, {\"\\\\\\\" 0\": [\"value0\", \"value1\"]}]}";
|
||||
simdjson::ParsedJson pj;
|
||||
simdjson::json_parse(json.c_str(), json.length(), pj);
|
||||
ASSERT(pj.is_valid());
|
||||
simdjson::ParsedJson::Iterator it(pj.doc);
|
||||
using namespace simdjson;
|
||||
|
||||
// valid JSON String Representation pointer
|
||||
std::string pointer1("/~1~001abc/1/\\\\\\\" 0/0");
|
||||
ASSERT(it.move_to(pointer1.c_str(), pointer1.length()));
|
||||
ASSERT(it.is_string());
|
||||
ASSERT(it.get_string() == std::string("value0"));
|
||||
const padded_string TEST_JSON = R"(
|
||||
{
|
||||
"/~01abc": [
|
||||
0,
|
||||
{
|
||||
"\\\" 0": [
|
||||
"value0",
|
||||
"value1"
|
||||
]
|
||||
}
|
||||
],
|
||||
"0": "0 ok",
|
||||
"01": "01 ok",
|
||||
"": "empty ok",
|
||||
"arr": []
|
||||
}
|
||||
)"_padded;
|
||||
|
||||
// valid URI Fragment Identifier Representation pointer
|
||||
std::string pointer2("#/~1~001abc/1/%x5C%x22%x200/1");
|
||||
ASSERT(it.move_to(pointer2.c_str(), pointer2.length()));
|
||||
ASSERT(it.is_string());
|
||||
ASSERT(it.get_string() == std::string("value1"));
|
||||
|
||||
// invalid pointer with leading 0 in index
|
||||
std::string pointer3("#/~1~001abc/01");
|
||||
ASSERT(!it.move_to(pointer3.c_str(), pointer3.length())); // failed
|
||||
ASSERT(it.is_string()); // has probably not moved
|
||||
ASSERT(it.get_string() == std::string("value1")); // has not move
|
||||
|
||||
// "the (nonexistent) member after the last array element"
|
||||
std::string pointer4("/~1~001abc/-");
|
||||
ASSERT(it.move_to(pointer4.c_str(), pointer4.length()));
|
||||
ASSERT(it.get_type() == ']');
|
||||
bool json_pointer_success_test(const char *json_pointer, std::string_view expected_value) {
|
||||
std::cout << "Running successful JSON pointer test '" << json_pointer << "' ..." << std::endl;
|
||||
auto doc = document::parse(TEST_JSON);
|
||||
auto [value, error] = doc[json_pointer].as_string();
|
||||
if (error) { std::cerr << "Unexpected Error: " << error << std::endl; return false; }
|
||||
ASSERT(value == expected_value);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool json_pointer_success_test(const char *json_pointer) {
|
||||
std::cout << "Running successful JSON pointer test '" << json_pointer << "' ..." << std::endl;
|
||||
auto doc = document::parse(TEST_JSON);
|
||||
auto [value, error] = doc[json_pointer];
|
||||
if (error) { std::cerr << "Unexpected Error: " << error << std::endl; return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool json_pointer_failure_test(const char *json_pointer, error_code expected_failure_test) {
|
||||
std::cout << "Running invalid JSON pointer test '" << json_pointer << "' ..." << std::endl;
|
||||
auto doc = document::parse(TEST_JSON);
|
||||
auto [value, error] = doc[json_pointer];
|
||||
ASSERT(error == expected_failure_test);
|
||||
return true;
|
||||
}
|
||||
|
||||
int main() {
|
||||
if (
|
||||
json_pointer_success_test(R"(/~1~001abc/1/\\\" 0/0)", "value0") &&
|
||||
json_pointer_success_test(R"(/~1~001abc/1/\\\" 0/1)", "value1") &&
|
||||
json_pointer_failure_test(R"(/~1~001abc/1/\\\" 0/2)", INDEX_OUT_OF_BOUNDS) && // index actually out of bounds
|
||||
json_pointer_success_test("/arr") && // get array
|
||||
json_pointer_failure_test("/arr/0", INDEX_OUT_OF_BOUNDS) && // array index 0 out of bounds on empty array
|
||||
json_pointer_success_test("/~1~001abc") && // get object
|
||||
json_pointer_success_test("/0", "0 ok") && // object index with integer-ish key
|
||||
json_pointer_success_test("/01", "01 ok") && // object index with key that would be an invalid integer
|
||||
json_pointer_success_test("/", "empty ok") && // object index with empty key
|
||||
json_pointer_failure_test("/~01abc", NO_SUCH_FIELD) && // Test that we don't try to compare the literal key
|
||||
json_pointer_failure_test("/~1~001abc/01", INVALID_JSON_POINTER) && // Leading 0 in integer index
|
||||
json_pointer_failure_test("/~1~001abc/", INVALID_JSON_POINTER) && // Empty index to array
|
||||
json_pointer_failure_test("/~1~001abc/-", INDEX_OUT_OF_BOUNDS) && // End index is always out of bounds
|
||||
true
|
||||
) {
|
||||
std::cout << "Success!" << std::endl;
|
||||
} else {
|
||||
std::cerr << "Failed!" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user