aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorm-holger <m-holger@kubitscheck.org>2021-12-17 17:47:22 +0100
committerJay Berkenbilt <ejb@ql.org>2021-12-17 20:24:43 +0100
commitf6293bd94c0723cfa80b65572a2cd7cc6f976d04 (patch)
treef52abaad53b5bb7c8ec52133e284d340e54d2d48
parentfeafcc4e88798626c80840797822efbf55722716 (diff)
downloadqpdf-f6293bd94c0723cfa80b65572a2cd7cc6f976d04.tar.zst
C-API expose QPDFObjectHandle::getTypeCode and getTypeName (fixes #597)
-rw-r--r--include/qpdf/qpdf-c.h4
-rw-r--r--libqpdf/qpdf-c.cc20
-rw-r--r--qpdf/qpdf-ctest.c23
-rw-r--r--qpdf/qpdf.testcov2
-rw-r--r--qpdf/qtest/qpdf.test3
-rw-r--r--qpdf/qtest/qpdf/c-oh-uninitialized-objects.out2
6 files changed, 53 insertions, 1 deletions
diff --git a/include/qpdf/qpdf-c.h b/include/qpdf/qpdf-c.h
index 92cad46e..fa511337 100644
--- a/include/qpdf/qpdf-c.h
+++ b/include/qpdf/qpdf-c.h
@@ -663,6 +663,10 @@ extern "C" {
QPDF_BOOL qpdf_oh_is_indirect(qpdf_data qpdf, qpdf_oh oh);
QPDF_DLL
QPDF_BOOL qpdf_oh_is_scalar(qpdf_data qpdf, qpdf_oh oh);
+ QPDF_DLL
+ enum qpdf_object_type_e qpdf_oh_get_type_code(qpdf_data qpdf, qpdf_oh oh);
+ QPDF_DLL
+ char const* qpdf_oh_get_type_name(qpdf_data qpdf, qpdf_oh oh);
QPDF_DLL
qpdf_oh qpdf_oh_wrap_in_array(qpdf_data qpdf, qpdf_oh oh);
diff --git a/libqpdf/qpdf-c.cc b/libqpdf/qpdf-c.cc
index 299377c7..3f11d89c 100644
--- a/libqpdf/qpdf-c.cc
+++ b/libqpdf/qpdf-c.cc
@@ -1159,6 +1159,26 @@ QPDF_BOOL qpdf_oh_is_number(qpdf_data qpdf, qpdf_oh oh)
});
}
+qpdf_object_type_e qpdf_oh_get_type_code(qpdf_data qpdf, qpdf_oh oh)
+{
+ return do_with_oh<qpdf_object_type_e>(
+ qpdf, oh, return_T<qpdf_object_type_e>(qpdf_ot_uninitialized),
+ [](QPDFObjectHandle& o) {
+ QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_type_code");
+ return o.getTypeCode();
+ });
+}
+
+char const* qpdf_oh_get_type_name(qpdf_data qpdf, qpdf_oh oh)
+{
+ return do_with_oh<char const*>(
+ qpdf, oh, return_T<char const*>(""), [qpdf](QPDFObjectHandle& o) {
+ QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_type_name");
+ qpdf->tmp_string = o.getTypeName();
+ return qpdf->tmp_string.c_str();
+ });
+}
+
qpdf_oh qpdf_oh_wrap_in_array(qpdf_data qpdf, qpdf_oh oh)
{
return do_with_oh<qpdf_oh>(
diff --git a/qpdf/qpdf-ctest.c b/qpdf/qpdf-ctest.c
index cf03f0e0..f4142127 100644
--- a/qpdf/qpdf-ctest.c
+++ b/qpdf/qpdf-ctest.c
@@ -539,9 +539,13 @@ static void test24(char const* infile,
/* Go to the first page and look at all the keys */
qpdf_oh pages = qpdf_oh_get_key(qpdf, root, "/Pages");
assert(qpdf_oh_is_dictionary(qpdf, pages));
+ assert(qpdf_oh_get_type_code(qpdf, pages) == qpdf_ot_dictionary);
+ assert(strcmp(qpdf_oh_get_type_name(qpdf, pages), "dictionary") == 0);
assert(qpdf_oh_is_initialized(qpdf, pages));
qpdf_oh kids = qpdf_oh_get_key(qpdf, pages, "/Kids");
assert(qpdf_oh_is_array(qpdf, kids));
+ assert(qpdf_oh_get_type_code(qpdf, kids) == qpdf_ot_array);
+ assert(strcmp(qpdf_oh_get_type_name(qpdf, kids), "array") == 0);
assert(qpdf_oh_get_array_n_items(qpdf, kids) == 1);
qpdf_oh page1 = qpdf_oh_get_array_item(qpdf, kids, 0);
qpdf_oh_begin_dict_key_iter(qpdf, page1);
@@ -553,6 +557,8 @@ static void test24(char const* infile,
/* Inspect the first page */
qpdf_oh type = qpdf_oh_get_key(qpdf, page1, "/Type");
assert(qpdf_oh_is_name(qpdf, type));
+ assert(qpdf_oh_get_type_code(qpdf, type) == qpdf_ot_name);
+ assert(strcmp(qpdf_oh_get_type_name(qpdf, type), "name") == 0);
assert(strcmp(qpdf_oh_get_name(qpdf, type), "/Page") == 0);
qpdf_oh parent = qpdf_oh_get_key(qpdf, page1, "/Parent");
assert(qpdf_oh_is_indirect(qpdf, parent));
@@ -591,11 +597,15 @@ static void test24(char const* infile,
/* Look at page contents to exercise stream functions */
qpdf_oh contents = qpdf_oh_get_key(qpdf, page1, "/Contents");
assert(qpdf_oh_is_stream(qpdf, contents));
+ assert(qpdf_oh_get_type_code(qpdf, contents) == qpdf_ot_stream);
+ assert(strcmp(qpdf_oh_get_type_name(qpdf, contents), "stream") == 0);
qpdf_oh contents_dict = qpdf_oh_get_dict(qpdf, contents);
assert(! qpdf_oh_is_scalar(qpdf, contents));
assert(! qpdf_oh_is_scalar(qpdf, contents_dict));
qpdf_oh contents_length = qpdf_oh_get_key(qpdf, contents_dict, "/Length");
assert(qpdf_oh_is_integer(qpdf, contents_length));
+ assert(qpdf_oh_get_type_code(qpdf, contents_length) == qpdf_ot_integer);
+ assert(strcmp(qpdf_oh_get_type_name(qpdf, contents_length), "integer") == 0);
assert(qpdf_oh_is_scalar(qpdf, contents_length));
assert(qpdf_oh_is_number(qpdf, contents_length));
qpdf_oh contents_array = qpdf_oh_wrap_in_array(qpdf, contents);
@@ -635,6 +645,8 @@ static void test24(char const* infile,
qpdf_oh_release(qpdf, page1);
contents = qpdf_oh_get_key(qpdf, page1, "/Contents");
assert(qpdf_oh_is_null(qpdf, contents));
+ assert(qpdf_oh_get_type_code(qpdf, contents) == qpdf_ot_null);
+ assert(strcmp(qpdf_oh_get_type_name(qpdf, contents), "null") == 0);
assert(qpdf_oh_is_array(qpdf, mediabox));
qpdf_oh_release_all(qpdf);
assert(! qpdf_oh_is_null(qpdf, mediabox));
@@ -672,21 +684,31 @@ static void test25(char const* infile,
qpdf_oh p_bool = qpdf_oh_get_array_item(qpdf, parsed, 5);
assert(qpdf_oh_is_integer(qpdf, p_int) &&
qpdf_oh_get_int_value_as_int(qpdf, p_int) == 1);
+ assert(qpdf_oh_get_type_code(qpdf, p_int) == qpdf_ot_integer);
+ assert(strcmp(qpdf_oh_get_type_name(qpdf, p_int), "integer") == 0);
assert(qpdf_oh_is_real(qpdf, p_real) &&
(strcmp(qpdf_oh_get_real_value(qpdf, p_real), "2.0") == 0) &&
qpdf_oh_get_numeric_value(qpdf, p_real) == 2.0);
+ assert(qpdf_oh_get_type_code(qpdf, p_real) == qpdf_ot_real);
+ assert(strcmp(qpdf_oh_get_type_name(qpdf, p_real), "real") == 0);
assert(qpdf_oh_is_string(qpdf, p_string) &&
(strcmp(qpdf_oh_get_string_value(qpdf, p_string), "3\xf7") == 0) &&
(strcmp(qpdf_oh_get_utf8_value(qpdf, p_string), "3\xc3\xb7") == 0) &&
(strcmp(qpdf_oh_unparse_binary(qpdf, p_string), "<33f7>") == 0));
+ assert(qpdf_oh_get_type_code(qpdf, p_string) == qpdf_ot_string);
+ assert(strcmp(qpdf_oh_get_type_name(qpdf, p_string), "string") == 0);
assert(qpdf_oh_is_dictionary(qpdf, p_dict));
qpdf_oh p_five = qpdf_oh_get_key(qpdf, p_dict, "/Four");
assert(qpdf_oh_is_or_has_name(qpdf, p_five, "/Five"));
assert(qpdf_oh_is_or_has_name(
qpdf, qpdf_oh_get_array_item(qpdf, p_five, 0), "/Five"));
assert(qpdf_oh_is_null(qpdf, p_null));
+ assert(qpdf_oh_get_type_code(qpdf, p_null) == qpdf_ot_null);
+ assert(strcmp(qpdf_oh_get_type_name(qpdf, p_null), "null") == 0);
assert(qpdf_oh_is_bool(qpdf, p_bool) &&
(qpdf_oh_get_bool_value(qpdf, p_bool) == QPDF_TRUE));
+ assert(qpdf_oh_get_type_code(qpdf, p_bool) == qpdf_ot_boolean);
+ assert(strcmp(qpdf_oh_get_type_name(qpdf, p_bool), "boolean") == 0);
qpdf_oh_erase_item(qpdf, parsed, 4);
qpdf_oh_insert_item(
qpdf, parsed, 2,
@@ -743,6 +765,7 @@ static void test26(char const* infile,
qpdf_data qpdf2 = qpdf_init();
qpdf_oh trailer = qpdf_get_trailer(qpdf2);
assert(! qpdf_oh_is_initialized(qpdf2, trailer));
+ assert(qpdf_oh_get_type_code(qpdf, trailer) == qpdf_ot_uninitialized);
qpdf_cleanup(&qpdf2);
}
diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov
index ebe0d2b3..6422393d 100644
--- a/qpdf/qpdf.testcov
+++ b/qpdf/qpdf.testcov
@@ -474,6 +474,8 @@ qpdf-c called qpdf_oh_is_dictionary 0
qpdf-c called qpdf_oh_is_stream 0
qpdf-c called qpdf_oh_is_indirect 0
qpdf-c called qpdf_oh_is_scalar 0
+qpdf-c called qpdf_oh_get_type_code 0
+qpdf-c called qpdf_oh_get_type_name 0
qpdf-c array to wrap_in_array 0
qpdf-c non-array to wrap_in_array 0
qpdf-c called qpdf_oh_parse 0
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index a5d69a4b..cd401216 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -4845,7 +4845,8 @@ $td->runtest("check output",
$td->runtest("C uninitialized objects",
{$td->COMMAND => "qpdf-ctest 26 '' '' ''"},
- {$td->STRING => "C test 26 done\n", $td->EXIT_STATUS => 0},
+ {$td->FILE => "c-oh-uninitialized-objects.out",
+ $td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
$td->runtest("C string with embedded null",
{$td->COMMAND => "qpdf-ctest 27 '' '' ''"},
diff --git a/qpdf/qtest/qpdf/c-oh-uninitialized-objects.out b/qpdf/qtest/qpdf/c-oh-uninitialized-objects.out
new file mode 100644
index 00000000..0fe5d307
--- /dev/null
+++ b/qpdf/qtest/qpdf/c-oh-uninitialized-objects.out
@@ -0,0 +1,2 @@
+closed input source (C API object handle 1): attempted access to unknown object handle
+C test 26 done