Commit 7de0b3f3c083990842523112959f8e27a0d2e5a0

Authored by Jay Berkenbilt
1 parent 12f7a446

JSONHandler: add fallback handler support

.idea/dictionaries/ejb.xml
1 1 <component name="ProjectDictionaryState">
2 2 <dictionary name="ejb">
3 3 <words>
  4 + <w>phour</w>
4 5 <w>whoami</w>
5 6 </words>
6 7 </dictionary>
... ...
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&amp; 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: {
... ...