Commit 7de0b3f3c083990842523112959f8e27a0d2e5a0
1 parent
12f7a446
JSONHandler: add fallback handler support
Showing
5 changed files
with
28 additions
and
1 deletions
.idea/dictionaries/ejb.xml
libqpdf/JSONHandler.cc
| ... | ... | @@ -17,10 +17,10 @@ struct Handlers |
| 17 | 17 | JSONHandler::void_handler_t dict_end_handler{nullptr}; |
| 18 | 18 | JSONHandler::json_handler_t array_start_handler{nullptr}; |
| 19 | 19 | JSONHandler::void_handler_t array_end_handler{nullptr}; |
| 20 | - JSONHandler::void_handler_t final_handler{nullptr}; | |
| 21 | 20 | std::map<std::string, std::shared_ptr<JSONHandler>> dict_handlers; |
| 22 | 21 | std::shared_ptr<JSONHandler> fallback_dict_handler; |
| 23 | 22 | std::shared_ptr<JSONHandler> array_item_handler; |
| 23 | + std::shared_ptr<JSONHandler> fallback_handler; | |
| 24 | 24 | }; |
| 25 | 25 | |
| 26 | 26 | class JSONHandler::Members |
| ... | ... | @@ -111,6 +111,12 @@ JSONHandler::addArrayHandlers( |
| 111 | 111 | } |
| 112 | 112 | |
| 113 | 113 | void |
| 114 | +JSONHandler::addFallbackHandler(std::shared_ptr<JSONHandler> h) | |
| 115 | +{ | |
| 116 | + m->h.fallback_handler = std::move(h); | |
| 117 | +} | |
| 118 | + | |
| 119 | +void | |
| 114 | 120 | JSONHandler::handle(std::string const& path, JSON j) |
| 115 | 121 | { |
| 116 | 122 | if (m->h.any_handler) { |
| ... | ... | @@ -169,6 +175,11 @@ JSONHandler::handle(std::string const& path, JSON j) |
| 169 | 175 | return; |
| 170 | 176 | } |
| 171 | 177 | |
| 178 | + if (m->h.fallback_handler) { | |
| 179 | + m->h.fallback_handler->handle(path, j); | |
| 180 | + return; | |
| 181 | + } | |
| 182 | + | |
| 172 | 183 | // It would be nice to include information about what type the object was and what types were |
| 173 | 184 | // allowed, but we're relying on schema validation to make sure input is properly structured |
| 174 | 185 | // before calling the handlers. It would be different if this code were trying to be part of a | ... | ... |
libqpdf/qpdf/JSONHandler.hh
| ... | ... | @@ -45,6 +45,9 @@ class JSONHandler |
| 45 | 45 | void addArrayHandlers( |
| 46 | 46 | json_handler_t start_fn, void_handler_t end_fn, std::shared_ptr<JSONHandler> item_handlers); |
| 47 | 47 | |
| 48 | + // If no handlers is called, the fallback handler will be used to try to handle the item. | |
| 49 | + void addFallbackHandler(std::shared_ptr<JSONHandler>); | |
| 50 | + | |
| 48 | 51 | // Apply handlers recursively to a JSON object. |
| 49 | 52 | void handle(std::string const& path, JSON j); |
| 50 | 53 | ... | ... |
libtests/json_handler.cc
| ... | ... | @@ -77,6 +77,7 @@ make_all_handler() |
| 77 | 77 | auto h5s = std::make_shared<JSONHandler>(); |
| 78 | 78 | h->addDictKeyHandler("five", h5s); |
| 79 | 79 | h5s->addArrayHandlers(print_json, make_print_message("array end"), h5); |
| 80 | + h5s->addFallbackHandler(h5); | |
| 80 | 81 | auto h6 = std::make_shared<JSONHandler>(); |
| 81 | 82 | h6->addDictHandlers(print_json, make_print_message("dict end")); |
| 82 | 83 | auto h6a = std::make_shared<JSONHandler>(); |
| ... | ... | @@ -109,6 +110,11 @@ test_all() |
| 109 | 110 | "six": {"a": {"b": "quack", "Q": "baaa"}, "b": "moo"} |
| 110 | 111 | })"); |
| 111 | 112 | h->handle(".", j); |
| 113 | + std::cerr << "-- fallback --" << std::endl; | |
| 114 | + j = JSON::parse(R"({ | |
| 115 | + "five": "not-array" | |
| 116 | +})"); | |
| 117 | + h->handle(".", j); | |
| 112 | 118 | } |
| 113 | 119 | |
| 114 | 120 | static void | ... | ... |
libtests/qtest/json_handler/json_handler.out
| ... | ... | @@ -63,6 +63,12 @@ |
| 63 | 63 | .three: bool: true |
| 64 | 64 | .two: number: 3.14 |
| 65 | 65 | .: json: dict end |
| 66 | +-- fallback -- | |
| 67 | +.: json: { | |
| 68 | + "five": "not-array" | |
| 69 | +} | |
| 70 | +.five: string: not-array | |
| 71 | +.: json: dict end | |
| 66 | 72 | -- errors -- |
| 67 | 73 | bad type at top: JSON handler: value at . is not of expected type |
| 68 | 74 | .: json: { | ... | ... |