2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-12-22 10:58:58 +00:00

JSONHandler: add fallback handler support

This commit is contained in:
Jay Berkenbilt 2024-01-09 20:28:28 -05:00
parent 12f7a4461b
commit 7de0b3f3c0
5 changed files with 28 additions and 1 deletions

View File

@ -1,6 +1,7 @@
<component name="ProjectDictionaryState"> <component name="ProjectDictionaryState">
<dictionary name="ejb"> <dictionary name="ejb">
<words> <words>
<w>phour</w>
<w>whoami</w> <w>whoami</w>
</words> </words>
</dictionary> </dictionary>

View File

@ -17,10 +17,10 @@ struct Handlers
JSONHandler::void_handler_t dict_end_handler{nullptr}; JSONHandler::void_handler_t dict_end_handler{nullptr};
JSONHandler::json_handler_t array_start_handler{nullptr}; JSONHandler::json_handler_t array_start_handler{nullptr};
JSONHandler::void_handler_t array_end_handler{nullptr}; JSONHandler::void_handler_t array_end_handler{nullptr};
JSONHandler::void_handler_t final_handler{nullptr};
std::map<std::string, std::shared_ptr<JSONHandler>> dict_handlers; std::map<std::string, std::shared_ptr<JSONHandler>> dict_handlers;
std::shared_ptr<JSONHandler> fallback_dict_handler; std::shared_ptr<JSONHandler> fallback_dict_handler;
std::shared_ptr<JSONHandler> array_item_handler; std::shared_ptr<JSONHandler> array_item_handler;
std::shared_ptr<JSONHandler> fallback_handler;
}; };
class JSONHandler::Members class JSONHandler::Members
@ -110,6 +110,12 @@ JSONHandler::addArrayHandlers(
m->h.array_item_handler = ah; m->h.array_item_handler = ah;
} }
void
JSONHandler::addFallbackHandler(std::shared_ptr<JSONHandler> h)
{
m->h.fallback_handler = std::move(h);
}
void void
JSONHandler::handle(std::string const& path, JSON j) JSONHandler::handle(std::string const& path, JSON j)
{ {
@ -169,6 +175,11 @@ JSONHandler::handle(std::string const& path, JSON j)
return; return;
} }
if (m->h.fallback_handler) {
m->h.fallback_handler->handle(path, j);
return;
}
// It would be nice to include information about what type the object was and what types were // It would be nice to include information about what type the object was and what types were
// allowed, but we're relying on schema validation to make sure input is properly structured // allowed, but we're relying on schema validation to make sure input is properly structured
// before calling the handlers. It would be different if this code were trying to be part of a // before calling the handlers. It would be different if this code were trying to be part of a

View File

@ -45,6 +45,9 @@ class JSONHandler
void addArrayHandlers( void addArrayHandlers(
json_handler_t start_fn, void_handler_t end_fn, std::shared_ptr<JSONHandler> item_handlers); json_handler_t start_fn, void_handler_t end_fn, std::shared_ptr<JSONHandler> item_handlers);
// If no handlers is called, the fallback handler will be used to try to handle the item.
void addFallbackHandler(std::shared_ptr<JSONHandler>);
// Apply handlers recursively to a JSON object. // Apply handlers recursively to a JSON object.
void handle(std::string const& path, JSON j); void handle(std::string const& path, JSON j);

View File

@ -77,6 +77,7 @@ make_all_handler()
auto h5s = std::make_shared<JSONHandler>(); auto h5s = std::make_shared<JSONHandler>();
h->addDictKeyHandler("five", h5s); h->addDictKeyHandler("five", h5s);
h5s->addArrayHandlers(print_json, make_print_message("array end"), h5); h5s->addArrayHandlers(print_json, make_print_message("array end"), h5);
h5s->addFallbackHandler(h5);
auto h6 = std::make_shared<JSONHandler>(); auto h6 = std::make_shared<JSONHandler>();
h6->addDictHandlers(print_json, make_print_message("dict end")); h6->addDictHandlers(print_json, make_print_message("dict end"));
auto h6a = std::make_shared<JSONHandler>(); auto h6a = std::make_shared<JSONHandler>();
@ -107,6 +108,11 @@ test_all()
"five": ["x", false, "y", null, true], "five": ["x", false, "y", null, true],
"phour": null, "phour": null,
"six": {"a": {"b": "quack", "Q": "baaa"}, "b": "moo"} "six": {"a": {"b": "quack", "Q": "baaa"}, "b": "moo"}
})");
h->handle(".", j);
std::cerr << "-- fallback --" << std::endl;
j = JSON::parse(R"({
"five": "not-array"
})"); })");
h->handle(".", j); h->handle(".", j);
} }

View File

@ -63,6 +63,12 @@
.three: bool: true .three: bool: true
.two: number: 3.14 .two: number: 3.14
.: json: dict end .: json: dict end
-- fallback --
.: json: {
"five": "not-array"
}
.five: string: not-array
.: json: dict end
-- errors -- -- errors --
bad type at top: JSON handler: value at . is not of expected type bad type at top: JSON handler: value at . is not of expected type
.: json: { .: json: {