Commit f6293bd94c0723cfa80b65572a2cd7cc6f976d04

Authored by m-holger
Committed by Jay Berkenbilt
1 parent feafcc4e

C-API expose QPDFObjectHandle::getTypeCode and getTypeName (fixes #597)

include/qpdf/qpdf-c.h
@@ -663,6 +663,10 @@ extern "C" { @@ -663,6 +663,10 @@ extern "C" {
663 QPDF_BOOL qpdf_oh_is_indirect(qpdf_data qpdf, qpdf_oh oh); 663 QPDF_BOOL qpdf_oh_is_indirect(qpdf_data qpdf, qpdf_oh oh);
664 QPDF_DLL 664 QPDF_DLL
665 QPDF_BOOL qpdf_oh_is_scalar(qpdf_data qpdf, qpdf_oh oh); 665 QPDF_BOOL qpdf_oh_is_scalar(qpdf_data qpdf, qpdf_oh oh);
  666 + QPDF_DLL
  667 + enum qpdf_object_type_e qpdf_oh_get_type_code(qpdf_data qpdf, qpdf_oh oh);
  668 + QPDF_DLL
  669 + char const* qpdf_oh_get_type_name(qpdf_data qpdf, qpdf_oh oh);
666 670
667 QPDF_DLL 671 QPDF_DLL
668 qpdf_oh qpdf_oh_wrap_in_array(qpdf_data qpdf, qpdf_oh oh); 672 qpdf_oh qpdf_oh_wrap_in_array(qpdf_data qpdf, qpdf_oh oh);
libqpdf/qpdf-c.cc
@@ -1159,6 +1159,26 @@ QPDF_BOOL qpdf_oh_is_number(qpdf_data qpdf, qpdf_oh oh) @@ -1159,6 +1159,26 @@ QPDF_BOOL qpdf_oh_is_number(qpdf_data qpdf, qpdf_oh oh)
1159 }); 1159 });
1160 } 1160 }
1161 1161
  1162 +qpdf_object_type_e qpdf_oh_get_type_code(qpdf_data qpdf, qpdf_oh oh)
  1163 +{
  1164 + return do_with_oh<qpdf_object_type_e>(
  1165 + qpdf, oh, return_T<qpdf_object_type_e>(qpdf_ot_uninitialized),
  1166 + [](QPDFObjectHandle& o) {
  1167 + QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_type_code");
  1168 + return o.getTypeCode();
  1169 + });
  1170 +}
  1171 +
  1172 +char const* qpdf_oh_get_type_name(qpdf_data qpdf, qpdf_oh oh)
  1173 +{
  1174 + return do_with_oh<char const*>(
  1175 + qpdf, oh, return_T<char const*>(""), [qpdf](QPDFObjectHandle& o) {
  1176 + QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_type_name");
  1177 + qpdf->tmp_string = o.getTypeName();
  1178 + return qpdf->tmp_string.c_str();
  1179 + });
  1180 +}
  1181 +
1162 qpdf_oh qpdf_oh_wrap_in_array(qpdf_data qpdf, qpdf_oh oh) 1182 qpdf_oh qpdf_oh_wrap_in_array(qpdf_data qpdf, qpdf_oh oh)
1163 { 1183 {
1164 return do_with_oh<qpdf_oh>( 1184 return do_with_oh<qpdf_oh>(
qpdf/qpdf-ctest.c
@@ -539,9 +539,13 @@ static void test24(char const* infile, @@ -539,9 +539,13 @@ static void test24(char const* infile,
539 /* Go to the first page and look at all the keys */ 539 /* Go to the first page and look at all the keys */
540 qpdf_oh pages = qpdf_oh_get_key(qpdf, root, "/Pages"); 540 qpdf_oh pages = qpdf_oh_get_key(qpdf, root, "/Pages");
541 assert(qpdf_oh_is_dictionary(qpdf, pages)); 541 assert(qpdf_oh_is_dictionary(qpdf, pages));
  542 + assert(qpdf_oh_get_type_code(qpdf, pages) == qpdf_ot_dictionary);
  543 + assert(strcmp(qpdf_oh_get_type_name(qpdf, pages), "dictionary") == 0);
542 assert(qpdf_oh_is_initialized(qpdf, pages)); 544 assert(qpdf_oh_is_initialized(qpdf, pages));
543 qpdf_oh kids = qpdf_oh_get_key(qpdf, pages, "/Kids"); 545 qpdf_oh kids = qpdf_oh_get_key(qpdf, pages, "/Kids");
544 assert(qpdf_oh_is_array(qpdf, kids)); 546 assert(qpdf_oh_is_array(qpdf, kids));
  547 + assert(qpdf_oh_get_type_code(qpdf, kids) == qpdf_ot_array);
  548 + assert(strcmp(qpdf_oh_get_type_name(qpdf, kids), "array") == 0);
545 assert(qpdf_oh_get_array_n_items(qpdf, kids) == 1); 549 assert(qpdf_oh_get_array_n_items(qpdf, kids) == 1);
546 qpdf_oh page1 = qpdf_oh_get_array_item(qpdf, kids, 0); 550 qpdf_oh page1 = qpdf_oh_get_array_item(qpdf, kids, 0);
547 qpdf_oh_begin_dict_key_iter(qpdf, page1); 551 qpdf_oh_begin_dict_key_iter(qpdf, page1);
@@ -553,6 +557,8 @@ static void test24(char const* infile, @@ -553,6 +557,8 @@ static void test24(char const* infile,
553 /* Inspect the first page */ 557 /* Inspect the first page */
554 qpdf_oh type = qpdf_oh_get_key(qpdf, page1, "/Type"); 558 qpdf_oh type = qpdf_oh_get_key(qpdf, page1, "/Type");
555 assert(qpdf_oh_is_name(qpdf, type)); 559 assert(qpdf_oh_is_name(qpdf, type));
  560 + assert(qpdf_oh_get_type_code(qpdf, type) == qpdf_ot_name);
  561 + assert(strcmp(qpdf_oh_get_type_name(qpdf, type), "name") == 0);
556 assert(strcmp(qpdf_oh_get_name(qpdf, type), "/Page") == 0); 562 assert(strcmp(qpdf_oh_get_name(qpdf, type), "/Page") == 0);
557 qpdf_oh parent = qpdf_oh_get_key(qpdf, page1, "/Parent"); 563 qpdf_oh parent = qpdf_oh_get_key(qpdf, page1, "/Parent");
558 assert(qpdf_oh_is_indirect(qpdf, parent)); 564 assert(qpdf_oh_is_indirect(qpdf, parent));
@@ -591,11 +597,15 @@ static void test24(char const* infile, @@ -591,11 +597,15 @@ static void test24(char const* infile,
591 /* Look at page contents to exercise stream functions */ 597 /* Look at page contents to exercise stream functions */
592 qpdf_oh contents = qpdf_oh_get_key(qpdf, page1, "/Contents"); 598 qpdf_oh contents = qpdf_oh_get_key(qpdf, page1, "/Contents");
593 assert(qpdf_oh_is_stream(qpdf, contents)); 599 assert(qpdf_oh_is_stream(qpdf, contents));
  600 + assert(qpdf_oh_get_type_code(qpdf, contents) == qpdf_ot_stream);
  601 + assert(strcmp(qpdf_oh_get_type_name(qpdf, contents), "stream") == 0);
594 qpdf_oh contents_dict = qpdf_oh_get_dict(qpdf, contents); 602 qpdf_oh contents_dict = qpdf_oh_get_dict(qpdf, contents);
595 assert(! qpdf_oh_is_scalar(qpdf, contents)); 603 assert(! qpdf_oh_is_scalar(qpdf, contents));
596 assert(! qpdf_oh_is_scalar(qpdf, contents_dict)); 604 assert(! qpdf_oh_is_scalar(qpdf, contents_dict));
597 qpdf_oh contents_length = qpdf_oh_get_key(qpdf, contents_dict, "/Length"); 605 qpdf_oh contents_length = qpdf_oh_get_key(qpdf, contents_dict, "/Length");
598 assert(qpdf_oh_is_integer(qpdf, contents_length)); 606 assert(qpdf_oh_is_integer(qpdf, contents_length));
  607 + assert(qpdf_oh_get_type_code(qpdf, contents_length) == qpdf_ot_integer);
  608 + assert(strcmp(qpdf_oh_get_type_name(qpdf, contents_length), "integer") == 0);
599 assert(qpdf_oh_is_scalar(qpdf, contents_length)); 609 assert(qpdf_oh_is_scalar(qpdf, contents_length));
600 assert(qpdf_oh_is_number(qpdf, contents_length)); 610 assert(qpdf_oh_is_number(qpdf, contents_length));
601 qpdf_oh contents_array = qpdf_oh_wrap_in_array(qpdf, contents); 611 qpdf_oh contents_array = qpdf_oh_wrap_in_array(qpdf, contents);
@@ -635,6 +645,8 @@ static void test24(char const* infile, @@ -635,6 +645,8 @@ static void test24(char const* infile,
635 qpdf_oh_release(qpdf, page1); 645 qpdf_oh_release(qpdf, page1);
636 contents = qpdf_oh_get_key(qpdf, page1, "/Contents"); 646 contents = qpdf_oh_get_key(qpdf, page1, "/Contents");
637 assert(qpdf_oh_is_null(qpdf, contents)); 647 assert(qpdf_oh_is_null(qpdf, contents));
  648 + assert(qpdf_oh_get_type_code(qpdf, contents) == qpdf_ot_null);
  649 + assert(strcmp(qpdf_oh_get_type_name(qpdf, contents), "null") == 0);
638 assert(qpdf_oh_is_array(qpdf, mediabox)); 650 assert(qpdf_oh_is_array(qpdf, mediabox));
639 qpdf_oh_release_all(qpdf); 651 qpdf_oh_release_all(qpdf);
640 assert(! qpdf_oh_is_null(qpdf, mediabox)); 652 assert(! qpdf_oh_is_null(qpdf, mediabox));
@@ -672,21 +684,31 @@ static void test25(char const* infile, @@ -672,21 +684,31 @@ static void test25(char const* infile,
672 qpdf_oh p_bool = qpdf_oh_get_array_item(qpdf, parsed, 5); 684 qpdf_oh p_bool = qpdf_oh_get_array_item(qpdf, parsed, 5);
673 assert(qpdf_oh_is_integer(qpdf, p_int) && 685 assert(qpdf_oh_is_integer(qpdf, p_int) &&
674 qpdf_oh_get_int_value_as_int(qpdf, p_int) == 1); 686 qpdf_oh_get_int_value_as_int(qpdf, p_int) == 1);
  687 + assert(qpdf_oh_get_type_code(qpdf, p_int) == qpdf_ot_integer);
  688 + assert(strcmp(qpdf_oh_get_type_name(qpdf, p_int), "integer") == 0);
675 assert(qpdf_oh_is_real(qpdf, p_real) && 689 assert(qpdf_oh_is_real(qpdf, p_real) &&
676 (strcmp(qpdf_oh_get_real_value(qpdf, p_real), "2.0") == 0) && 690 (strcmp(qpdf_oh_get_real_value(qpdf, p_real), "2.0") == 0) &&
677 qpdf_oh_get_numeric_value(qpdf, p_real) == 2.0); 691 qpdf_oh_get_numeric_value(qpdf, p_real) == 2.0);
  692 + assert(qpdf_oh_get_type_code(qpdf, p_real) == qpdf_ot_real);
  693 + assert(strcmp(qpdf_oh_get_type_name(qpdf, p_real), "real") == 0);
678 assert(qpdf_oh_is_string(qpdf, p_string) && 694 assert(qpdf_oh_is_string(qpdf, p_string) &&
679 (strcmp(qpdf_oh_get_string_value(qpdf, p_string), "3\xf7") == 0) && 695 (strcmp(qpdf_oh_get_string_value(qpdf, p_string), "3\xf7") == 0) &&
680 (strcmp(qpdf_oh_get_utf8_value(qpdf, p_string), "3\xc3\xb7") == 0) && 696 (strcmp(qpdf_oh_get_utf8_value(qpdf, p_string), "3\xc3\xb7") == 0) &&
681 (strcmp(qpdf_oh_unparse_binary(qpdf, p_string), "<33f7>") == 0)); 697 (strcmp(qpdf_oh_unparse_binary(qpdf, p_string), "<33f7>") == 0));
  698 + assert(qpdf_oh_get_type_code(qpdf, p_string) == qpdf_ot_string);
  699 + assert(strcmp(qpdf_oh_get_type_name(qpdf, p_string), "string") == 0);
682 assert(qpdf_oh_is_dictionary(qpdf, p_dict)); 700 assert(qpdf_oh_is_dictionary(qpdf, p_dict));
683 qpdf_oh p_five = qpdf_oh_get_key(qpdf, p_dict, "/Four"); 701 qpdf_oh p_five = qpdf_oh_get_key(qpdf, p_dict, "/Four");
684 assert(qpdf_oh_is_or_has_name(qpdf, p_five, "/Five")); 702 assert(qpdf_oh_is_or_has_name(qpdf, p_five, "/Five"));
685 assert(qpdf_oh_is_or_has_name( 703 assert(qpdf_oh_is_or_has_name(
686 qpdf, qpdf_oh_get_array_item(qpdf, p_five, 0), "/Five")); 704 qpdf, qpdf_oh_get_array_item(qpdf, p_five, 0), "/Five"));
687 assert(qpdf_oh_is_null(qpdf, p_null)); 705 assert(qpdf_oh_is_null(qpdf, p_null));
  706 + assert(qpdf_oh_get_type_code(qpdf, p_null) == qpdf_ot_null);
  707 + assert(strcmp(qpdf_oh_get_type_name(qpdf, p_null), "null") == 0);
688 assert(qpdf_oh_is_bool(qpdf, p_bool) && 708 assert(qpdf_oh_is_bool(qpdf, p_bool) &&
689 (qpdf_oh_get_bool_value(qpdf, p_bool) == QPDF_TRUE)); 709 (qpdf_oh_get_bool_value(qpdf, p_bool) == QPDF_TRUE));
  710 + assert(qpdf_oh_get_type_code(qpdf, p_bool) == qpdf_ot_boolean);
  711 + assert(strcmp(qpdf_oh_get_type_name(qpdf, p_bool), "boolean") == 0);
690 qpdf_oh_erase_item(qpdf, parsed, 4); 712 qpdf_oh_erase_item(qpdf, parsed, 4);
691 qpdf_oh_insert_item( 713 qpdf_oh_insert_item(
692 qpdf, parsed, 2, 714 qpdf, parsed, 2,
@@ -743,6 +765,7 @@ static void test26(char const* infile, @@ -743,6 +765,7 @@ static void test26(char const* infile,
743 qpdf_data qpdf2 = qpdf_init(); 765 qpdf_data qpdf2 = qpdf_init();
744 qpdf_oh trailer = qpdf_get_trailer(qpdf2); 766 qpdf_oh trailer = qpdf_get_trailer(qpdf2);
745 assert(! qpdf_oh_is_initialized(qpdf2, trailer)); 767 assert(! qpdf_oh_is_initialized(qpdf2, trailer));
  768 + assert(qpdf_oh_get_type_code(qpdf, trailer) == qpdf_ot_uninitialized);
746 qpdf_cleanup(&qpdf2); 769 qpdf_cleanup(&qpdf2);
747 } 770 }
748 771
qpdf/qpdf.testcov
@@ -474,6 +474,8 @@ qpdf-c called qpdf_oh_is_dictionary 0 @@ -474,6 +474,8 @@ qpdf-c called qpdf_oh_is_dictionary 0
474 qpdf-c called qpdf_oh_is_stream 0 474 qpdf-c called qpdf_oh_is_stream 0
475 qpdf-c called qpdf_oh_is_indirect 0 475 qpdf-c called qpdf_oh_is_indirect 0
476 qpdf-c called qpdf_oh_is_scalar 0 476 qpdf-c called qpdf_oh_is_scalar 0
  477 +qpdf-c called qpdf_oh_get_type_code 0
  478 +qpdf-c called qpdf_oh_get_type_name 0
477 qpdf-c array to wrap_in_array 0 479 qpdf-c array to wrap_in_array 0
478 qpdf-c non-array to wrap_in_array 0 480 qpdf-c non-array to wrap_in_array 0
479 qpdf-c called qpdf_oh_parse 0 481 qpdf-c called qpdf_oh_parse 0
qpdf/qtest/qpdf.test
@@ -4845,7 +4845,8 @@ $td-&gt;runtest(&quot;check output&quot;, @@ -4845,7 +4845,8 @@ $td-&gt;runtest(&quot;check output&quot;,
4845 4845
4846 $td->runtest("C uninitialized objects", 4846 $td->runtest("C uninitialized objects",
4847 {$td->COMMAND => "qpdf-ctest 26 '' '' ''"}, 4847 {$td->COMMAND => "qpdf-ctest 26 '' '' ''"},
4848 - {$td->STRING => "C test 26 done\n", $td->EXIT_STATUS => 0}, 4848 + {$td->FILE => "c-oh-uninitialized-objects.out",
  4849 + $td->EXIT_STATUS => 0},
4849 $td->NORMALIZE_NEWLINES); 4850 $td->NORMALIZE_NEWLINES);
4850 $td->runtest("C string with embedded null", 4851 $td->runtest("C string with embedded null",
4851 {$td->COMMAND => "qpdf-ctest 27 '' '' ''"}, 4852 {$td->COMMAND => "qpdf-ctest 27 '' '' ''"},
qpdf/qtest/qpdf/c-oh-uninitialized-objects.out 0 → 100644
  1 +closed input source (C API object handle 1): attempted access to unknown object handle
  2 +C test 26 done