aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/qpdf-c.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2021-12-10 17:09:42 +0100
committerJay Berkenbilt <ejb@ql.org>2021-12-10 18:16:02 +0100
commit72c10d8617c799432e28dabf1679b1a6f5245c02 (patch)
tree6dd53c3979e4ef3cd159af030abee1fa39436656 /libqpdf/qpdf-c.cc
parent3340dbe9761ef35d580d77a73e17d204579624f1 (diff)
downloadqpdf-72c10d8617c799432e28dabf1679b1a6f5245c02.tar.zst
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
Diffstat (limited to 'libqpdf/qpdf-c.cc')
-rw-r--r--libqpdf/qpdf-c.cc663
1 files changed, 388 insertions, 275 deletions
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<Buffer> 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<qpdf_oh, PointerHolder<QPDFObjectHandle>> oh_cache;
qpdf_oh next_oh;
std::set<std::string> 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<bool*>(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<class RET>
+static RET trap_oh_errors(
+ qpdf_data qpdf,
+ std::function<RET()> fallback,
+ std::function<RET(qpdf_data)> 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 <class T>
+static std::function<T()> return_T(T const& r)
+{
+ return [&r]() { return r; };
+}
+
+static QPDF_BOOL return_false()
+{
+ return QPDF_FALSE;
+}
+
+static std::function<qpdf_oh()> return_uninitialized(qpdf_data qpdf)
+{
+ return [qpdf]() { return qpdf_oh_new_uninitialized(qpdf); };
+}
+
+static std::function<qpdf_oh()> 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_oh>(
+ 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_oh>(
+ qpdf, return_uninitialized(qpdf), [] (qpdf_data q) {
+ return new_object(q, q->qpdf->getRoot());
+ });
+}
+
+template<class RET>
+static RET do_with_oh(
+ qpdf_data qpdf, qpdf_oh oh,
+ std::function<RET()> fallback,
+ std::function<RET(QPDFObjectHandle&)> fn)
+{
+ return trap_oh_errors<RET>(
+ 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<void(QPDFObjectHandle&)> fn)
+{
+ do_with_oh<bool>(
+ qpdf, oh, return_T<bool>(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_BOOL>(
+ 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_BOOL>(
+ 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_BOOL>(
+ 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_BOOL>(
+ 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_BOOL>(
+ 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_BOOL>(
+ 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_BOOL>(
+ 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_BOOL>(
+ 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_BOOL>(
+ 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_BOOL>(
+ 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_BOOL>(
+ 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_BOOL>(
+ 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_BOOL>(
+ 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_BOOL>(
+ 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_BOOL>(
+ 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<QPDFObjectHandle>{
- *qpdf->oh_cache[oh]}));
- }
+ return do_with_oh<qpdf_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<QPDFObjectHandle>{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_oh>(
+ 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_BOOL>(
+ 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<long long>(
+ qpdf, oh, return_T<long long>(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<int>(
+ qpdf, oh, return_T<int>(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<unsigned long long>(
+ qpdf, oh, return_T<unsigned long long>(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<unsigned int>(
+ qpdf, oh, return_T<unsigned int>(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<char const*>(
+ qpdf, oh, return_T<char const*>(""), [&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<double>(
+ qpdf, oh, return_T<double>(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<char const*>(
+ qpdf, oh, return_T<char const*>(""), [&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<char const*>(
+ qpdf, oh, return_T<char const*>(""), [&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<char const*>(
+ qpdf, oh, return_T<char const*>(""), [&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<int>(
+ qpdf, oh, return_T<int>(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>(
+ 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<std::set<std::string>>(
+ qpdf, oh,
+ [](){ return std::set<std::string>(); },
+ [](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_BOOL>(
+ 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>(
+ 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_BOOL>(
+ 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<QPDFObjectHandle>(
+ 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>(
+ 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<int>(
+ qpdf, oh, return_T<int>(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<int>(
+ qpdf, oh, return_T<int>(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<char const*>(
+ qpdf, oh, return_T<char const*>(""), [&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<char const*>(
+ qpdf, oh, return_T<char const*>(""), [&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<char const*>(
+ qpdf, oh, return_T<char const*>(""), [&qpdf](QPDFObjectHandle& o) {
+ QTC::TC("qpdf", "qpdf-c called qpdf_oh_unparse_binary");
+ qpdf->tmp_string = o.unparseBinary();
+ return qpdf->tmp_string.c_str();
+ });
}