From 72c10d8617c799432e28dabf1679b1a6f5245c02 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Fri, 10 Dec 2021 11:09:42 -0500 Subject: C API: overhaul error handling * Handle error conditions that occur when using the object handle interfaces. In the past, some exceptions were not correctly converted to errors or warnings. * Add more detailed information to qpdf-c.h * Make it possible to work more explicitly with uninitialized objects --- libqpdf/qpdf-c.cc | 663 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 388 insertions(+), 275 deletions(-) (limited to 'libqpdf') diff --git a/libqpdf/qpdf-c.cc b/libqpdf/qpdf-c.cc index 063adaf2..b7e67e85 100644 --- a/libqpdf/qpdf-c.cc +++ b/libqpdf/qpdf-c.cc @@ -41,6 +41,9 @@ struct _qpdf_data PointerHolder output_buffer; // QPDFObjectHandle support + void (*oh_error_handler)(qpdf_data, qpdf_error, void*); + void* oh_error_handler_data; + bool default_oh_error_handler_called; std::map> oh_cache; qpdf_oh next_oh; std::set cur_iter_dict_keys; @@ -48,8 +51,32 @@ struct _qpdf_data std::string cur_dict_key; }; +static void default_oh_error_handler(qpdf_data qpdf, qpdf_error e, void* data) +{ + bool* called = reinterpret_cast(data); + if (called != nullptr) + { + QTC::TC("qpdf", "qpdf-c warn about oh error", *called ? 0 : 1); + if (! *called) + { + qpdf->warnings.push_back( + QPDFExc( + qpdf_e_internal, + qpdf->qpdf->getFilename(), + "", 0, + "C API object handle accessor errors occurred," + " and the application did not define an error handler")); + *called = true; + } + } + std::cerr << e->exc->what() << std::endl; +} + _qpdf_data::_qpdf_data() : write_memory(false), + oh_error_handler(default_oh_error_handler), + oh_error_handler_data(&this->default_oh_error_handler_called), + default_oh_error_handler_called(false), next_oh(0) { } @@ -170,6 +197,13 @@ void qpdf_cleanup(qpdf_data* qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_cleanup"); qpdf_oh_release_all(*qpdf); + if ((*qpdf)->error.getPointer()) + { + QTC::TC("qpdf", "qpdf-c cleanup warned about unhandled error"); + std::cerr << "WARNING: application did not handle error: " + << (*qpdf)->error->what() << std::endl; + + } delete *qpdf; *qpdf = 0; } @@ -841,6 +875,38 @@ QPDF_ERROR_CODE qpdf_write(qpdf_data qpdf) return status; } +void qpdf_register_oh_error_handler( + qpdf_data qpdf, + void (*handle_error)(qpdf_data qpdf, qpdf_error error, void* data), + void* data) +{ + QTC::TC("qpdf", "qpdf-c registered oh error handler"); + qpdf->oh_error_handler = handle_error; + qpdf->oh_error_handler_data = data; +} + +template +static RET trap_oh_errors( + qpdf_data qpdf, + std::function fallback, + std::function fn) +{ + // Note: fallback is a function so we don't have to evaluate it + // unless needed. This is important because sometimes the fallback + // creates an object. + RET ret; + QPDF_ERROR_CODE status = trap_errors(qpdf, [&ret, &fn] (qpdf_data q) { + ret = fn(q); + }); + if (status & QPDF_ERRORS) + { + (*qpdf->oh_error_handler)( + qpdf, qpdf_get_error(qpdf), qpdf->oh_error_handler_data); + return fallback(); + } + return ret; +} + static qpdf_oh new_object(qpdf_data qpdf, QPDFObjectHandle const& qoh) { @@ -867,310 +933,367 @@ void qpdf_oh_release_all(qpdf_data qpdf) qpdf->oh_cache.clear(); } +template +static std::function return_T(T const& r) +{ + return [&r]() { return r; }; +} + +static QPDF_BOOL return_false() +{ + return QPDF_FALSE; +} + +static std::function return_uninitialized(qpdf_data qpdf) +{ + return [qpdf]() { return qpdf_oh_new_uninitialized(qpdf); }; +} + +static std::function return_null(qpdf_data qpdf) +{ + return [qpdf]() { return qpdf_oh_new_null(qpdf); }; +} + qpdf_oh qpdf_get_trailer(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_get_trailer"); - return new_object(qpdf, qpdf->qpdf->getTrailer()); + return trap_oh_errors( + qpdf, return_uninitialized(qpdf), [] (qpdf_data q) { + return new_object(q, q->qpdf->getTrailer()); + }); } qpdf_oh qpdf_get_root(qpdf_data qpdf) { QTC::TC("qpdf", "qpdf-c called qpdf_get_root"); - return new_object(qpdf, qpdf->qpdf->getRoot()); -} - -static bool -qpdf_oh_valid_internal(qpdf_data qpdf, qpdf_oh oh) -{ - auto i = qpdf->oh_cache.find(oh); - bool result = ((i != qpdf->oh_cache.end()) && - (i->second).getPointer()); - if (! result) - { - QTC::TC("qpdf", "qpdf-c invalid object handle"); - qpdf->warnings.push_back( - QPDFExc( - qpdf_e_damaged_pdf, - qpdf->qpdf->getFilename(), - std::string("C API object handle ") + - QUtil::uint_to_string(oh), - 0, "attempted access to unknown object handle")); - } - return result; + return trap_oh_errors( + qpdf, return_uninitialized(qpdf), [] (qpdf_data q) { + return new_object(q, q->qpdf->getRoot()); + }); +} + +template +static RET do_with_oh( + qpdf_data qpdf, qpdf_oh oh, + std::function fallback, + std::function fn) +{ + return trap_oh_errors( + qpdf, fallback, [&fn, &oh](qpdf_data q) { + auto i = q->oh_cache.find(oh); + bool result = ((i != q->oh_cache.end()) && + (i->second).getPointer()); + if (! result) + { + QTC::TC("qpdf", "qpdf-c invalid object handle"); + throw QPDFExc( + qpdf_e_internal, + q->qpdf->getFilename(), + std::string("C API object handle ") + + QUtil::uint_to_string(oh), + 0, "attempted access to unknown object handle"); + } + return fn(*(q->oh_cache[oh])); + }); +} + +static void do_with_oh_void( + qpdf_data qpdf, qpdf_oh oh, + std::function fn) +{ + do_with_oh( + qpdf, oh, return_T(false), [&fn](QPDFObjectHandle& o) { + fn(o); + return true; // unused + }); } QPDF_BOOL qpdf_oh_is_initialized(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_initialized"); - return (qpdf_oh_valid_internal(qpdf, oh) && - qpdf->oh_cache[oh]->isInitialized()); + return do_with_oh( + qpdf, oh, return_false, [](QPDFObjectHandle& o) { + return o.isInitialized(); + }); } QPDF_BOOL qpdf_oh_is_bool(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_bool"); - return (qpdf_oh_valid_internal(qpdf, oh) && - qpdf->oh_cache[oh]->isBool()); + return do_with_oh( + qpdf, oh, return_false, [](QPDFObjectHandle& o) { + return o.isBool(); + }); } QPDF_BOOL qpdf_oh_is_null(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_null"); - return (qpdf_oh_valid_internal(qpdf, oh) && - qpdf->oh_cache[oh]->isNull()); + return do_with_oh( + qpdf, oh, return_false, [](QPDFObjectHandle& o) { + return o.isNull(); + }); } QPDF_BOOL qpdf_oh_is_integer(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_integer"); - return (qpdf_oh_valid_internal(qpdf, oh) && - qpdf->oh_cache[oh]->isInteger()); + return do_with_oh( + qpdf, oh, return_false, [](QPDFObjectHandle& o) { + return o.isInteger(); + }); } QPDF_BOOL qpdf_oh_is_real(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_real"); - return (qpdf_oh_valid_internal(qpdf, oh) && - qpdf->oh_cache[oh]->isReal()); + return do_with_oh( + qpdf, oh, return_false, [](QPDFObjectHandle& o) { + return o.isReal(); + }); } QPDF_BOOL qpdf_oh_is_name(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_name"); - return (qpdf_oh_valid_internal(qpdf, oh) && - qpdf->oh_cache[oh]->isName()); + return do_with_oh( + qpdf, oh, return_false, [](QPDFObjectHandle& o) { + return o.isName(); + }); } QPDF_BOOL qpdf_oh_is_string(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_string"); - return (qpdf_oh_valid_internal(qpdf, oh) && - qpdf->oh_cache[oh]->isString()); + return do_with_oh( + qpdf, oh, return_false, [](QPDFObjectHandle& o) { + return o.isString(); + }); } QPDF_BOOL qpdf_oh_is_operator(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_operator"); - return (qpdf_oh_valid_internal(qpdf, oh) && - qpdf->oh_cache[oh]->isOperator()); + return do_with_oh( + qpdf, oh, return_false, [](QPDFObjectHandle& o) { + return o.isOperator(); + }); } QPDF_BOOL qpdf_oh_is_inline_image(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_inline_image"); - return (qpdf_oh_valid_internal(qpdf, oh) && - qpdf->oh_cache[oh]->isInlineImage()); + return do_with_oh( + qpdf, oh, return_false, [](QPDFObjectHandle& o) { + return o.isInlineImage(); + }); } QPDF_BOOL qpdf_oh_is_array(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_array"); - return (qpdf_oh_valid_internal(qpdf, oh) && - qpdf->oh_cache[oh]->isArray()); + return do_with_oh( + qpdf, oh, return_false, [](QPDFObjectHandle& o) { + return o.isArray(); + }); } QPDF_BOOL qpdf_oh_is_dictionary(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_dictionary"); - return (qpdf_oh_valid_internal(qpdf, oh) && - qpdf->oh_cache[oh]->isDictionary()); + return do_with_oh( + qpdf, oh, return_false, [](QPDFObjectHandle& o) { + return o.isDictionary(); + }); } QPDF_BOOL qpdf_oh_is_stream(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_stream"); - return (qpdf_oh_valid_internal(qpdf, oh) && - qpdf->oh_cache[oh]->isStream()); + return do_with_oh( + qpdf, oh, return_false, [](QPDFObjectHandle& o) { + return o.isStream(); + }); } QPDF_BOOL qpdf_oh_is_indirect(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_indirect"); - return (qpdf_oh_valid_internal(qpdf, oh) && - qpdf->oh_cache[oh]->isIndirect()); + return do_with_oh( + qpdf, oh, return_false, [](QPDFObjectHandle& o) { + return o.isIndirect(); + }); } QPDF_BOOL qpdf_oh_is_scalar(qpdf_data qpdf, qpdf_oh oh) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_scalar"); - return (qpdf_oh_valid_internal(qpdf, oh) && - qpdf->oh_cache[oh]->isScalar()); + return do_with_oh( + qpdf, oh, return_false, [](QPDFObjectHandle& o) { + return o.isScalar(); + }); +} + +QPDF_BOOL qpdf_oh_is_number(qpdf_data qpdf, qpdf_oh oh) +{ + return do_with_oh( + qpdf, oh, return_false, [](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_number"); + return o.isNumber(); + }); } qpdf_oh qpdf_oh_wrap_in_array(qpdf_data qpdf, qpdf_oh oh) { - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return qpdf_oh_new_array(qpdf); - } - auto qoh = qpdf->oh_cache[oh]; - if (qoh->isArray()) - { - QTC::TC("qpdf", "qpdf-c array to wrap_in_array"); - return new_object(qpdf, *qoh); - } - else - { - QTC::TC("qpdf", "qpdf-c non-array to wrap_in_array"); - return new_object(qpdf, - QPDFObjectHandle::newArray( - std::vector{ - *qpdf->oh_cache[oh]})); - } + return do_with_oh( + qpdf, oh, + [&qpdf](){ return qpdf_oh_new_array(qpdf); }, + [&qpdf](QPDFObjectHandle& qoh) { + if (qoh.isArray()) + { + QTC::TC("qpdf", "qpdf-c array to wrap_in_array"); + return new_object(qpdf, qoh); + } + else + { + QTC::TC("qpdf", "qpdf-c non-array to wrap_in_array"); + return new_object(qpdf, + QPDFObjectHandle::newArray( + std::vector{qoh})); + } + }); } qpdf_oh qpdf_oh_parse(qpdf_data qpdf, char const* object_str) { QTC::TC("qpdf", "qpdf-c called qpdf_oh_parse"); - return new_object(qpdf, QPDFObjectHandle::parse(object_str)); + return trap_oh_errors( + qpdf, return_uninitialized(qpdf), [&object_str] (qpdf_data q) { + return new_object(q, QPDFObjectHandle::parse(object_str)); + }); } QPDF_BOOL qpdf_oh_get_bool_value(qpdf_data qpdf, qpdf_oh oh) { - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return QPDF_FALSE; - } - QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_bool_value"); - return qpdf->oh_cache[oh]->getBoolValue(); + return do_with_oh( + qpdf, oh, return_false, [](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_bool_value"); + return o.getBoolValue(); + }); } long long qpdf_oh_get_int_value(qpdf_data qpdf, qpdf_oh oh) { - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return 0LL; - } - QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_int_value"); - return qpdf->oh_cache[oh]->getIntValue(); + return do_with_oh( + qpdf, oh, return_T(0LL), [](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_int_value"); + return o.getIntValue(); + }); } int qpdf_oh_get_int_value_as_int(qpdf_data qpdf, qpdf_oh oh) { - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return 0; - } - QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_int_value_as_int"); - return qpdf->oh_cache[oh]->getIntValueAsInt(); + return do_with_oh( + qpdf, oh, return_T(0), [](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_int_value_as_int"); + return o.getIntValueAsInt(); + }); } unsigned long long qpdf_oh_get_uint_value(qpdf_data qpdf, qpdf_oh oh) { - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return 0ULL; - } - QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_uint_value"); - return qpdf->oh_cache[oh]->getUIntValue(); + return do_with_oh( + qpdf, oh, return_T(0ULL), [](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_uint_value"); + return o.getUIntValue(); + }); } unsigned int qpdf_oh_get_uint_value_as_uint(qpdf_data qpdf, qpdf_oh oh) { - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return 0U; - } - QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_uint_value_as_uint"); - return qpdf->oh_cache[oh]->getUIntValueAsUInt(); + return do_with_oh( + qpdf, oh, return_T(0U), [](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_uint_value_as_uint"); + return o.getUIntValueAsUInt(); + }); } char const* qpdf_oh_get_real_value(qpdf_data qpdf, qpdf_oh oh) { - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return ""; - } - QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_real_value"); - qpdf->tmp_string = qpdf->oh_cache[oh]->getRealValue(); - return qpdf->tmp_string.c_str(); -} - -QPDF_BOOL qpdf_oh_is_number(qpdf_data qpdf, qpdf_oh oh) -{ - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return QPDF_FALSE; - } - QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_number"); - return qpdf->oh_cache[oh]->isNumber(); + return do_with_oh( + qpdf, oh, return_T(""), [&qpdf](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_real_value"); + qpdf->tmp_string = o.getRealValue(); + return qpdf->tmp_string.c_str(); + }); } double qpdf_oh_get_numeric_value(qpdf_data qpdf, qpdf_oh oh) { - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return 0.0; - } - QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_numeric_value"); - return qpdf->oh_cache[oh]->getNumericValue(); + return do_with_oh( + qpdf, oh, return_T(0.0), [](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_numeric_value"); + return o.getNumericValue(); + }); } char const* qpdf_oh_get_name(qpdf_data qpdf, qpdf_oh oh) { - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return ""; - } - QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_name"); - qpdf->tmp_string = qpdf->oh_cache[oh]->getName(); - return qpdf->tmp_string.c_str(); + return do_with_oh( + qpdf, oh, return_T(""), [&qpdf](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_name"); + qpdf->tmp_string = o.getName(); + return qpdf->tmp_string.c_str(); + }); } char const* qpdf_oh_get_string_value(qpdf_data qpdf, qpdf_oh oh) { - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return ""; - } - QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_string_value"); - qpdf->tmp_string = qpdf->oh_cache[oh]->getStringValue(); - return qpdf->tmp_string.c_str(); + return do_with_oh( + qpdf, oh, return_T(""), [&qpdf](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_string_value"); + qpdf->tmp_string = o.getStringValue(); + return qpdf->tmp_string.c_str(); + }); } char const* qpdf_oh_get_utf8_value(qpdf_data qpdf, qpdf_oh oh) { - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return ""; - } - QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_utf8_value"); - qpdf->tmp_string = qpdf->oh_cache[oh]->getUTF8Value(); - return qpdf->tmp_string.c_str(); + return do_with_oh( + qpdf, oh, return_T(""), [&qpdf](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_utf8_value"); + qpdf->tmp_string = o.getUTF8Value(); + return qpdf->tmp_string.c_str(); + }); } int qpdf_oh_get_array_n_items(qpdf_data qpdf, qpdf_oh oh) { - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return 0; - } - QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_array_n_items"); - return qpdf->oh_cache[oh]->getArrayNItems(); + return do_with_oh( + qpdf, oh, return_T(0), [](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_array_n_items"); + return o.getArrayNItems(); + }); } qpdf_oh qpdf_oh_get_array_item(qpdf_data qpdf, qpdf_oh oh, int n) { - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return qpdf_oh_new_null(qpdf); - } - QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_array_item"); - return new_object(qpdf, qpdf->oh_cache[oh]->getArrayItem(n)); + return do_with_oh( + qpdf, oh, return_null(qpdf), [&qpdf, &n](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_array_item"); + return new_object(qpdf, o.getArrayItem(n)); + }); } void qpdf_oh_begin_dict_key_iter(qpdf_data qpdf, qpdf_oh oh) { - if (qpdf_oh_valid_internal(qpdf, oh) && - qpdf_oh_is_dictionary(qpdf, oh)) - { - QTC::TC("qpdf", "qpdf-c called qpdf_oh_begin_dict_key_iter"); - qpdf->cur_iter_dict_keys = qpdf->oh_cache[oh]->getKeys(); - } - else - { - qpdf->cur_iter_dict_keys = {}; - } + qpdf->cur_iter_dict_keys = do_with_oh>( + qpdf, oh, + [](){ return std::set(); }, + [](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_begin_dict_key_iter"); + return o.getKeys(); + }); qpdf->dict_iter = qpdf->cur_iter_dict_keys.begin(); } @@ -1197,32 +1320,35 @@ char const* qpdf_oh_dict_next_key(qpdf_data qpdf) QPDF_BOOL qpdf_oh_has_key(qpdf_data qpdf, qpdf_oh oh, char const* key) { - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return QPDF_FALSE; - } - QTC::TC("qpdf", "qpdf-c called qpdf_oh_has_key"); - return qpdf->oh_cache[oh]->hasKey(key); + return do_with_oh( + qpdf, oh, return_false, [&key](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_has_key"); + return o.hasKey(key); + }); } qpdf_oh qpdf_oh_get_key(qpdf_data qpdf, qpdf_oh oh, char const* key) { - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return qpdf_oh_new_null(qpdf); - } - QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_key"); - return new_object(qpdf, qpdf->oh_cache[oh]->getKey(key)); + return do_with_oh( + qpdf, oh, return_null(qpdf), [&qpdf, &key](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_key"); + return new_object(qpdf, o.getKey(key)); + }); } QPDF_BOOL qpdf_oh_is_or_has_name(qpdf_data qpdf, qpdf_oh oh, char const* key) { - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return QPDF_FALSE; - } - QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_or_has_name"); - return qpdf->oh_cache[oh]->isOrHasName(key); + return do_with_oh( + qpdf, oh, return_false, [&key](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_or_has_name"); + return o.isOrHasName(key); + }); +} + +qpdf_oh qpdf_oh_new_uninitialized(qpdf_data qpdf) +{ + QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_uninitialized"); + return new_object(qpdf, QPDFObjectHandle()); } qpdf_oh qpdf_oh_new_null(qpdf_data qpdf) @@ -1288,156 +1414,143 @@ qpdf_oh qpdf_oh_new_dictionary(qpdf_data qpdf) void qpdf_oh_make_direct(qpdf_data qpdf, qpdf_oh oh) { - if (qpdf_oh_valid_internal(qpdf, oh)) - { - QTC::TC("qpdf", "qpdf-c called qpdf_oh_make_direct"); - qpdf->oh_cache[oh]->makeDirect(); - } + do_with_oh_void( + qpdf, oh, [](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_make_direct"); + o.makeDirect(); + }); } static QPDFObjectHandle qpdf_oh_item_internal(qpdf_data qpdf, qpdf_oh item) { - if (qpdf_oh_valid_internal(qpdf, item)) - { - return *(qpdf->oh_cache[item]); - } - else - { - return QPDFObjectHandle::newNull(); - } + return do_with_oh( + qpdf, item, + [](){return QPDFObjectHandle::newNull();}, + [](QPDFObjectHandle& o) { + return o; + }); } void qpdf_oh_set_array_item(qpdf_data qpdf, qpdf_oh oh, int at, qpdf_oh item) { - if (qpdf_oh_is_array(qpdf, oh)) - { - QTC::TC("qpdf", "qpdf-c called qpdf_oh_set_array_item"); - qpdf->oh_cache[oh]->setArrayItem( - at, qpdf_oh_item_internal(qpdf, item)); - } + do_with_oh_void( + qpdf, oh, [&qpdf, &at, &item](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_set_array_item"); + o.setArrayItem(at, qpdf_oh_item_internal(qpdf, item)); + }); } void qpdf_oh_insert_item(qpdf_data qpdf, qpdf_oh oh, int at, qpdf_oh item) { - if (qpdf_oh_is_array(qpdf, oh)) - { - QTC::TC("qpdf", "qpdf-c called qpdf_oh_insert_item"); - qpdf->oh_cache[oh]->insertItem( - at, qpdf_oh_item_internal(qpdf, item)); - } + do_with_oh_void( + qpdf, oh, [&qpdf, &at, &item](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_insert_item"); + o.insertItem(at, qpdf_oh_item_internal(qpdf, item)); + }); } void qpdf_oh_append_item(qpdf_data qpdf, qpdf_oh oh, qpdf_oh item) { - if (qpdf_oh_is_array(qpdf, oh)) - { - QTC::TC("qpdf", "qpdf-c called qpdf_oh_append_item"); - qpdf->oh_cache[oh]->appendItem( - qpdf_oh_item_internal(qpdf, item)); - } + do_with_oh_void( + qpdf, oh, [&qpdf, &item](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_append_item"); + o.appendItem(qpdf_oh_item_internal(qpdf, item)); + }); } void qpdf_oh_erase_item(qpdf_data qpdf, qpdf_oh oh, int at) { - if (qpdf_oh_is_array(qpdf, oh)) - { - QTC::TC("qpdf", "qpdf-c called qpdf_oh_erase_item"); - qpdf->oh_cache[oh]->eraseItem(at); - } + do_with_oh_void( + qpdf, oh, [&at](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_erase_item"); + o.eraseItem(at); + }); } void qpdf_oh_replace_key(qpdf_data qpdf, qpdf_oh oh, char const* key, qpdf_oh item) { - if (qpdf_oh_is_dictionary(qpdf, oh)) - { - QTC::TC("qpdf", "qpdf-c called qpdf_oh_replace_key"); - qpdf->oh_cache[oh]->replaceKey( - key, qpdf_oh_item_internal(qpdf, item)); - } + do_with_oh_void( + qpdf, oh, [&qpdf, &key, &item](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_replace_key"); + o.replaceKey(key, qpdf_oh_item_internal(qpdf, item)); + }); } void qpdf_oh_remove_key(qpdf_data qpdf, qpdf_oh oh, char const* key) { - if (qpdf_oh_is_dictionary(qpdf, oh)) - { - QTC::TC("qpdf", "qpdf-c called qpdf_oh_remove_key"); - qpdf->oh_cache[oh]->removeKey(key); - } + do_with_oh_void( + qpdf, oh, [&key](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_remove_key"); + o.removeKey(key); + }); } void qpdf_oh_replace_or_remove_key(qpdf_data qpdf, qpdf_oh oh, char const* key, qpdf_oh item) { - if (qpdf_oh_is_dictionary(qpdf, oh)) - { - QTC::TC("qpdf", "qpdf-c called qpdf_oh_replace_or_remove_key"); - qpdf->oh_cache[oh]->replaceOrRemoveKey( - key, qpdf_oh_item_internal(qpdf, item)); - } + do_with_oh_void( + qpdf, oh, [&qpdf, &key, &item](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_replace_or_remove_key"); + o.replaceOrRemoveKey(key, qpdf_oh_item_internal(qpdf, item)); + }); } qpdf_oh qpdf_oh_get_dict(qpdf_data qpdf, qpdf_oh oh) { - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return qpdf_oh_new_null(qpdf); - } - QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_dict"); - return new_object(qpdf, qpdf->oh_cache[oh]->getDict()); + return do_with_oh( + qpdf, oh, return_null(qpdf), [&qpdf](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_dict"); + return new_object(qpdf, o.getDict()); + }); } int qpdf_oh_get_object_id(qpdf_data qpdf, qpdf_oh oh) { - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return 0; - } - QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_object_id"); - return qpdf->oh_cache[oh]->getObjectID(); + return do_with_oh( + qpdf, oh, return_T(0), [](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_object_id"); + return o.getObjectID(); + }); } int qpdf_oh_get_generation(qpdf_data qpdf, qpdf_oh oh) { - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return 0; - } - QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_generation"); - return qpdf->oh_cache[oh]->getGeneration(); + return do_with_oh( + qpdf, oh, return_T(0), [](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_generation"); + return o.getGeneration(); + }); } char const* qpdf_oh_unparse(qpdf_data qpdf, qpdf_oh oh) { - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return ""; - } - QTC::TC("qpdf", "qpdf-c called qpdf_oh_unparse"); - qpdf->tmp_string = qpdf->oh_cache[oh]->unparse(); - return qpdf->tmp_string.c_str(); + return do_with_oh( + qpdf, oh, return_T(""), [&qpdf](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_unparse"); + qpdf->tmp_string = o.unparse(); + return qpdf->tmp_string.c_str(); + }); } char const* qpdf_oh_unparse_resolved(qpdf_data qpdf, qpdf_oh oh) { - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return ""; - } - QTC::TC("qpdf", "qpdf-c called qpdf_oh_unparse_resolved"); - qpdf->tmp_string = qpdf->oh_cache[oh]->unparseResolved(); - return qpdf->tmp_string.c_str(); + return do_with_oh( + qpdf, oh, return_T(""), [&qpdf](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_unparse_resolved"); + qpdf->tmp_string = o.unparseResolved(); + return qpdf->tmp_string.c_str(); + }); } char const* qpdf_oh_unparse_binary(qpdf_data qpdf, qpdf_oh oh) { - if (! qpdf_oh_valid_internal(qpdf, oh)) - { - return ""; - } - QTC::TC("qpdf", "qpdf-c called qpdf_oh_unparse_binary"); - qpdf->tmp_string = qpdf->oh_cache[oh]->unparseBinary(); - return qpdf->tmp_string.c_str(); + return do_with_oh( + qpdf, oh, return_T(""), [&qpdf](QPDFObjectHandle& o) { + QTC::TC("qpdf", "qpdf-c called qpdf_oh_unparse_binary"); + qpdf->tmp_string = o.unparseBinary(); + return qpdf->tmp_string.c_str(); + }); } -- cgit v1.2.3-54-g00ecf