diff options
Diffstat (limited to 'libqpdf/qpdf/JSONHandler.hh')
-rw-r--r-- | libqpdf/qpdf/JSONHandler.hh | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/libqpdf/qpdf/JSONHandler.hh b/libqpdf/qpdf/JSONHandler.hh new file mode 100644 index 00000000..dbea505f --- /dev/null +++ b/libqpdf/qpdf/JSONHandler.hh @@ -0,0 +1,130 @@ +#ifndef JSONHANDLER_HH +#define JSONHANDLER_HH + +#include <qpdf/DLL.h> +#include <qpdf/PointerHolder.hh> +#include <qpdf/JSON.hh> +#include <string> +#include <map> +#include <functional> +#include <memory> + +// This class allows a sax-like walk through a JSON object with +// functionality that mostly mirrors QPDFArgParser. It is primarily +// here to facilitate automatic generation of some of the code to help +// keep QPDFJob json consistent with command-line arguments. + +class JSONHandler +{ + public: + // A QPDFUsage exception is thrown if there are any errors + // validating the JSON object. + QPDF_DLL + JSONHandler(); + + QPDF_DLL + ~JSONHandler() = default; + + // Based on the type of handler, expect the object to be of a + // certain type. QPDFUsage is thrown otherwise. Multiple handlers + // may be registered, which allows the object to be of various + // types. If an anyHandler is added, no other handler will be + // called. There is no "final" handler -- if the top-level is a + // dictionary or array, just use its end handler. + + typedef std::function<void( + std::string const& path, JSON value)> json_handler_t; + typedef std::function<void( + std::string const& path)> void_handler_t; + typedef std::function<void( + std::string const& path, std::string const& value)> string_handler_t; + typedef std::function<void( + std::string const& path, bool value)> bool_handler_t; + + // If an any handler is added, it will be called for any value + // including null, and no other handler will be called. + QPDF_DLL + void addAnyHandler(json_handler_t fn); + + // If any of the remaining handlers are registered, each + // registered handle will be called. + QPDF_DLL + void addNullHandler(void_handler_t fn); + QPDF_DLL + void addStringHandler(string_handler_t fn); + QPDF_DLL + void addNumberHandler(string_handler_t fn); + QPDF_DLL + void addBoolHandler(bool_handler_t fn); + + QPDF_DLL + void addDictHandlers(void_handler_t start_fn, void_handler_t end_fn); + QPDF_DLL + void addDictKeyHandler( + std::string const& key, std::shared_ptr<JSONHandler>); + QPDF_DLL + void addFallbackDictHandler(std::shared_ptr<JSONHandler>); + + QPDF_DLL + void addArrayHandlers(void_handler_t start_fn, + void_handler_t end_fn, + std::shared_ptr<JSONHandler> item_handlers); + + // Apply handlers recursively to a JSON object. + QPDF_DLL + void handle(std::string const& path, JSON j); + + private: + JSONHandler(JSONHandler const&) = delete; + + static void usage(std::string const& msg); + + struct Handlers + { + Handlers() : + any_handler(nullptr), + null_handler(nullptr), + string_handler(nullptr), + number_handler(nullptr), + bool_handler(nullptr), + dict_start_handler(nullptr), + dict_end_handler(nullptr), + array_start_handler(nullptr), + array_end_handler(nullptr), + final_handler(nullptr) + { + } + + json_handler_t any_handler; + void_handler_t null_handler; + string_handler_t string_handler; + string_handler_t number_handler; + bool_handler_t bool_handler; + void_handler_t dict_start_handler; + void_handler_t dict_end_handler; + void_handler_t array_start_handler; + void_handler_t array_end_handler; + void_handler_t final_handler; + std::map<std::string, std::shared_ptr<JSONHandler>> dict_handlers; + std::shared_ptr<JSONHandler> fallback_dict_handler; + std::shared_ptr<JSONHandler> array_item_handler; + }; + + class Members + { + friend class JSONHandler; + + public: + QPDF_DLL + ~Members() = default; + + private: + Members(); + Members(Members const&) = delete; + + Handlers h; + }; + PointerHolder<Members> m; +}; + +#endif // JSONHANDLER_HH |