// Copyright (c) 2005-2021 Jay Berkenbilt // // This file is part of qpdf. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // Versions of qpdf prior to version 7 were released under the terms // of version 2.0 of the Artistic License. At your option, you may // continue to consider qpdf to be licensed under those terms. Please // see the manual for additional information. #ifndef JSONHANDLER_HH #define JSONHANDLER_HH #include #include #include #include #include #include #include // 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 json_handler_t; typedef std::function void_handler_t; typedef std::function string_handler_t; typedef std::function 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); QPDF_DLL void addFallbackDictHandler(std::shared_ptr); QPDF_DLL void addArrayHandlers(void_handler_t start_fn, void_handler_t end_fn, std::shared_ptr 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> dict_handlers; std::shared_ptr fallback_dict_handler; std::shared_ptr array_item_handler; }; class Members { friend class JSONHandler; public: QPDF_DLL ~Members() = default; private: Members(); Members(Members const&) = delete; Handlers h; }; PointerHolder m; }; #endif // JSONHANDLER_HH