Commit f1a2d3160a1dbaf735cce597d0f6f40e76f7f223
1 parent
66f1fd2a
Add JSON v2 support to C API
Showing
14 changed files
with
535 additions
and
11 deletions
ChangeLog
| 1 | 1 | 2022-09-08 Jay Berkenbilt <ejb@ql.org> |
| 2 | 2 | |
| 3 | + * Added new functions to the C API to support qpdf JSON: | |
| 4 | + qpdf_create_from_json_file, qpdf_create_from_json_data, | |
| 5 | + qpdf_update_from_json_file, qpdf_update_from_json_data, and | |
| 6 | + qpdf_write_json. Examples can be found in qpdf-ctest.c (in the | |
| 7 | + source tree), tests 42 through 47. | |
| 8 | + | |
| 3 | 9 | * Add QPDFObjectHandle::isDestroyed() to test whether an indirect |
| 4 | 10 | object was from a QPDF that has been destroyed. |
| 5 | 11 | ... | ... |
TODO
| ... | ... | @@ -8,12 +8,6 @@ Always |
| 8 | 8 | Next |
| 9 | 9 | ==== |
| 10 | 10 | |
| 11 | -Before Release: | |
| 12 | - | |
| 13 | -* Support json v2 in the C API. At a minimum, write_json, | |
| 14 | - create_from_json, and update_from_json need to be there and should | |
| 15 | - take the same kinds of functions as the C API for logger. | |
| 16 | - | |
| 17 | 11 | Pending changes: |
| 18 | 12 | |
| 19 | 13 | * Consider also exposing a way to set a new logger and to get the | ... | ... |
include/qpdf/qpdf-c.h
| ... | ... | @@ -257,8 +257,6 @@ extern "C" { |
| 257 | 257 | QPDF_DLL |
| 258 | 258 | QPDF_ERROR_CODE qpdf_check_pdf(qpdf_data qpdf); |
| 259 | 259 | |
| 260 | - /* READ FUNCTIONS */ | |
| 261 | - | |
| 262 | 260 | /* READ PARAMETER FUNCTIONS -- must be called before qpdf_read */ |
| 263 | 261 | |
| 264 | 262 | QPDF_DLL |
| ... | ... | @@ -267,6 +265,10 @@ extern "C" { |
| 267 | 265 | QPDF_DLL |
| 268 | 266 | void qpdf_set_attempt_recovery(qpdf_data qpdf, QPDF_BOOL value); |
| 269 | 267 | |
| 268 | + /* PROCESS FUNCTIONS */ | |
| 269 | + | |
| 270 | + /* This functions process a PDF or JSON input source. */ | |
| 271 | + | |
| 270 | 272 | /* Calling qpdf_read causes processFile to be called in the C++ |
| 271 | 273 | * API. Basic parsing is performed, but data from the file is |
| 272 | 274 | * only read as needed. For files without passwords, pass a null |
| ... | ... | @@ -297,8 +299,40 @@ extern "C" { |
| 297 | 299 | QPDF_DLL |
| 298 | 300 | QPDF_ERROR_CODE qpdf_empty_pdf(qpdf_data qpdf); |
| 299 | 301 | |
| 300 | - /* Read functions below must be called after qpdf_read or | |
| 301 | - * qpdf_read_memory. */ | |
| 302 | + /* Create a PDF from a JSON file. This calls createFromJSON in the | |
| 303 | + * C++ API. | |
| 304 | + */ | |
| 305 | + QPDF_DLL | |
| 306 | + QPDF_ERROR_CODE | |
| 307 | + qpdf_create_from_json_file(qpdf_data qpdf, char const* filename); | |
| 308 | + | |
| 309 | + /* Create a PDF from JSON data in a null-terminated string. This | |
| 310 | + * calls createFromJSON in the C++ API. | |
| 311 | + */ | |
| 312 | + QPDF_DLL | |
| 313 | + QPDF_ERROR_CODE | |
| 314 | + qpdf_create_from_json_data( | |
| 315 | + qpdf_data qpdf, char const* buffer, unsigned long long size); | |
| 316 | + | |
| 317 | + /* JSON UPDATE FUNCTIONS */ | |
| 318 | + | |
| 319 | + /* Update a QPDF object from a JSON file or buffer. These | |
| 320 | + * functions call updateFromJSON. One of the other processing | |
| 321 | + * functions has to be called first so that the QPDF object is | |
| 322 | + * initialized with PDF data. | |
| 323 | + */ | |
| 324 | + QPDF_DLL | |
| 325 | + QPDF_ERROR_CODE | |
| 326 | + qpdf_update_from_json_file(qpdf_data qpdf, char const* filename); | |
| 327 | + QPDF_DLL | |
| 328 | + QPDF_ERROR_CODE | |
| 329 | + qpdf_update_from_json_data( | |
| 330 | + qpdf_data qpdf, char const* buffer, unsigned long long size); | |
| 331 | + | |
| 332 | + /* READ FUNCTIONS */ | |
| 333 | + | |
| 334 | + /* Read functions below must be called after qpdf_read or any of | |
| 335 | + * the other functions that process a PDF. */ | |
| 302 | 336 | |
| 303 | 337 | /* |
| 304 | 338 | * NOTE: Functions that return char* are returning a pointer to an |
| ... | ... | @@ -371,6 +405,39 @@ extern "C" { |
| 371 | 405 | QPDF_DLL |
| 372 | 406 | QPDF_BOOL qpdf_allow_modify_all(qpdf_data qpdf); |
| 373 | 407 | |
| 408 | + /* JSON WRITE FUNCTIONS */ | |
| 409 | + | |
| 410 | + /* This function serializes the PDF to JSON. This calls writeJSON | |
| 411 | + * from the C++ API. | |
| 412 | + * | |
| 413 | + * - version: the JSON version, currently must be 2 | |
| 414 | + * - fn: a function that will be called with blocks of JSON data; | |
| 415 | + * will be called with data, a length, and the value of the | |
| 416 | + * udata parameter to this function | |
| 417 | + * - udata: will be passed as the third argument to fn with each | |
| 418 | + * call; use this for your own tracking or pass a null pointer | |
| 419 | + * if you don't need it | |
| 420 | + * - For decode_level, json_stream_data, file_prefix, and | |
| 421 | + * wanted_objects, see comments in QPDF.hh. For this API, | |
| 422 | + * wanted_objects should be a null-terminated array of | |
| 423 | + * null-terminated strings. Pass a null pointer if you want all | |
| 424 | + * objects. | |
| 425 | + */ | |
| 426 | + | |
| 427 | + /* Function should return 0 on success. */ | |
| 428 | + typedef int (*qpdf_write_fn_t)(char const* data, size_t len, void* udata); | |
| 429 | + | |
| 430 | + QPDF_DLL | |
| 431 | + QPDF_ERROR_CODE qpdf_write_json( | |
| 432 | + qpdf_data qpdf, | |
| 433 | + int version, | |
| 434 | + qpdf_write_fn_t fn, | |
| 435 | + void* udata, | |
| 436 | + enum qpdf_stream_decode_level_e decode_level, | |
| 437 | + enum qpdf_json_stream_data_e json_stream_data, | |
| 438 | + char const* file_prefix, | |
| 439 | + char const* const* wanted_objects); | |
| 440 | + | |
| 374 | 441 | /* WRITE FUNCTIONS */ |
| 375 | 442 | |
| 376 | 443 | /* Set up for writing. No writing is actually performed until the | ... | ... |
libqpdf/qpdf-c.cc
| ... | ... | @@ -2,8 +2,10 @@ |
| 2 | 2 | |
| 3 | 3 | #include <qpdf/QPDF.hh> |
| 4 | 4 | |
| 5 | +#include <qpdf/BufferInputSource.hh> | |
| 5 | 6 | #include <qpdf/Pl_Buffer.hh> |
| 6 | 7 | #include <qpdf/Pl_Discard.hh> |
| 8 | +#include <qpdf/Pl_Function.hh> | |
| 7 | 9 | #include <qpdf/QIntC.hh> |
| 8 | 10 | #include <qpdf/QPDFExc.hh> |
| 9 | 11 | #include <qpdf/QPDFLogger.hh> |
| ... | ... | @@ -2029,3 +2031,89 @@ qpdf_remove_page(qpdf_data qpdf, qpdf_oh page) |
| 2029 | 2031 | auto p = qpdf_oh_item_internal(qpdf, page); |
| 2030 | 2032 | return trap_errors(qpdf, [&p](qpdf_data q) { q->qpdf->removePage(p); }); |
| 2031 | 2033 | } |
| 2034 | + | |
| 2035 | +QPDF_ERROR_CODE | |
| 2036 | +qpdf_create_from_json_file(qpdf_data qpdf, char const* filename) | |
| 2037 | +{ | |
| 2038 | + QPDF_ERROR_CODE status = QPDF_SUCCESS; | |
| 2039 | + qpdf->filename = filename; | |
| 2040 | + status = trap_errors( | |
| 2041 | + qpdf, [](qpdf_data q) { q->qpdf->createFromJSON(q->filename); }); | |
| 2042 | + return status; | |
| 2043 | +} | |
| 2044 | + | |
| 2045 | +QPDF_ERROR_CODE | |
| 2046 | +qpdf_create_from_json_data( | |
| 2047 | + qpdf_data qpdf, char const* buffer, unsigned long long size) | |
| 2048 | +{ | |
| 2049 | + QPDF_ERROR_CODE status = QPDF_SUCCESS; | |
| 2050 | + qpdf->filename = "json buffer"; | |
| 2051 | + qpdf->buffer = buffer; | |
| 2052 | + qpdf->size = size; | |
| 2053 | + auto b = | |
| 2054 | + new Buffer(QUtil::unsigned_char_pointer(buffer), QIntC::to_size(size)); | |
| 2055 | + auto is = std::make_shared<BufferInputSource>(qpdf->filename, b, true); | |
| 2056 | + status = | |
| 2057 | + trap_errors(qpdf, [&is](qpdf_data q) { q->qpdf->createFromJSON(is); }); | |
| 2058 | + return status; | |
| 2059 | +} | |
| 2060 | + | |
| 2061 | +QPDF_ERROR_CODE | |
| 2062 | +qpdf_update_from_json_file(qpdf_data qpdf, char const* filename) | |
| 2063 | +{ | |
| 2064 | + QPDF_ERROR_CODE status = QPDF_SUCCESS; | |
| 2065 | + status = trap_errors( | |
| 2066 | + qpdf, [filename](qpdf_data q) { q->qpdf->updateFromJSON(filename); }); | |
| 2067 | + return status; | |
| 2068 | +} | |
| 2069 | + | |
| 2070 | +QPDF_ERROR_CODE | |
| 2071 | +qpdf_update_from_json_data( | |
| 2072 | + qpdf_data qpdf, char const* buffer, unsigned long long size) | |
| 2073 | +{ | |
| 2074 | + QPDF_ERROR_CODE status = QPDF_SUCCESS; | |
| 2075 | + auto b = | |
| 2076 | + new Buffer(QUtil::unsigned_char_pointer(buffer), QIntC::to_size(size)); | |
| 2077 | + auto is = std::make_shared<BufferInputSource>(qpdf->filename, b, true); | |
| 2078 | + status = | |
| 2079 | + trap_errors(qpdf, [&is](qpdf_data q) { q->qpdf->updateFromJSON(is); }); | |
| 2080 | + return status; | |
| 2081 | +} | |
| 2082 | + | |
| 2083 | +QPDF_ERROR_CODE | |
| 2084 | +qpdf_write_json( | |
| 2085 | + qpdf_data qpdf, | |
| 2086 | + int version, | |
| 2087 | + qpdf_write_fn_t fn, | |
| 2088 | + void* udata, | |
| 2089 | + enum qpdf_stream_decode_level_e decode_level, | |
| 2090 | + enum qpdf_json_stream_data_e json_stream_data, | |
| 2091 | + char const* file_prefix, | |
| 2092 | + char const* const* wanted_objects) | |
| 2093 | +{ | |
| 2094 | + QPDF_ERROR_CODE status = QPDF_SUCCESS; | |
| 2095 | + auto p = std::make_shared<Pl_Function>("write_json", nullptr, fn, udata); | |
| 2096 | + std::set<std::string> wanted_objects_set; | |
| 2097 | + if (wanted_objects) { | |
| 2098 | + for (auto i = wanted_objects; *i; ++i) { | |
| 2099 | + wanted_objects_set.insert(*i); | |
| 2100 | + } | |
| 2101 | + } | |
| 2102 | + status = trap_errors( | |
| 2103 | + qpdf, | |
| 2104 | + [version, | |
| 2105 | + p, | |
| 2106 | + decode_level, | |
| 2107 | + json_stream_data, | |
| 2108 | + file_prefix, | |
| 2109 | + &wanted_objects_set](qpdf_data q) { | |
| 2110 | + q->qpdf->writeJSON( | |
| 2111 | + version, | |
| 2112 | + p.get(), | |
| 2113 | + decode_level, | |
| 2114 | + json_stream_data, | |
| 2115 | + file_prefix, | |
| 2116 | + wanted_objects_set); | |
| 2117 | + }); | |
| 2118 | + return status; | |
| 2119 | +} | ... | ... |
manual/release-notes.rst
| ... | ... | @@ -40,6 +40,10 @@ For a detailed list of changes, please see the file |
| 40 | 40 | - New C++ API calls: ``QPDF::writeJSON``, |
| 41 | 41 | ``QPDF::createFromJSON``, ``QPDF::updateFromJSON`` |
| 42 | 42 | |
| 43 | + - New C API calls: ``qpdf_create_from_json_file``, | |
| 44 | + ``qpdf_create_from_json_data``, ``qpdf_update_from_json_file``, | |
| 45 | + ``qpdf_update_from_json_data``, and ``qpdf_write_json``. | |
| 46 | + | |
| 43 | 47 | - Complete documentation can be found at :ref:`json`. A |
| 44 | 48 | comprehensive list of changes from version 1 to version 2 can be |
| 45 | 49 | found at :ref:`json-v2-changes`. | ... | ... |
qpdf/qpdf-ctest.c
| ... | ... | @@ -133,6 +133,13 @@ count_progress(int percent, void* data) |
| 133 | 133 | ++(*(int*)data); |
| 134 | 134 | } |
| 135 | 135 | |
| 136 | +static int | |
| 137 | +write_to_file(char const* data, size_t size, void* udata) | |
| 138 | +{ | |
| 139 | + FILE* f = (FILE*)udata; | |
| 140 | + return fwrite(data, 1, size, f) != size; | |
| 141 | +} | |
| 142 | + | |
| 136 | 143 | static void |
| 137 | 144 | test01( |
| 138 | 145 | char const* infile, |
| ... | ... | @@ -1458,7 +1465,7 @@ test41( |
| 1458 | 1465 | char const* outfile, |
| 1459 | 1466 | char const* xarg) |
| 1460 | 1467 | { |
| 1461 | - /* Empty PDF -- infile is ignored*/ | |
| 1468 | + /* Empty PDF -- infile is ignored */ | |
| 1462 | 1469 | assert(qpdf_empty_pdf(qpdf) == 0); |
| 1463 | 1470 | qpdf_init_write(qpdf, outfile); |
| 1464 | 1471 | qpdf_set_static_ID(qpdf, QPDF_TRUE); |
| ... | ... | @@ -1466,6 +1473,110 @@ test41( |
| 1466 | 1473 | report_errors(); |
| 1467 | 1474 | } |
| 1468 | 1475 | |
| 1476 | +static void | |
| 1477 | +test42( | |
| 1478 | + char const* infile, | |
| 1479 | + char const* password, | |
| 1480 | + char const* outfile, | |
| 1481 | + char const* xarg) | |
| 1482 | +{ | |
| 1483 | + assert(qpdf_create_from_json_file(qpdf, infile) == QPDF_SUCCESS); | |
| 1484 | + qpdf_init_write(qpdf, outfile); | |
| 1485 | + qpdf_set_static_ID(qpdf, QPDF_TRUE); | |
| 1486 | + qpdf_write(qpdf); | |
| 1487 | + report_errors(); | |
| 1488 | +} | |
| 1489 | + | |
| 1490 | +static void | |
| 1491 | +test43( | |
| 1492 | + char const* infile, | |
| 1493 | + char const* password, | |
| 1494 | + char const* outfile, | |
| 1495 | + char const* xarg) | |
| 1496 | +{ | |
| 1497 | + char* buf = NULL; | |
| 1498 | + unsigned long size = 0; | |
| 1499 | + read_file_into_memory(infile, &buf, &size); | |
| 1500 | + assert(qpdf_create_from_json_data(qpdf, buf, size) == QPDF_SUCCESS); | |
| 1501 | + qpdf_init_write(qpdf, outfile); | |
| 1502 | + qpdf_set_static_ID(qpdf, QPDF_TRUE); | |
| 1503 | + qpdf_write(qpdf); | |
| 1504 | + report_errors(); | |
| 1505 | + free(buf); | |
| 1506 | +} | |
| 1507 | + | |
| 1508 | +static void | |
| 1509 | +test44( | |
| 1510 | + char const* infile, | |
| 1511 | + char const* password, | |
| 1512 | + char const* outfile, | |
| 1513 | + char const* xarg) | |
| 1514 | +{ | |
| 1515 | + assert(qpdf_read(qpdf, infile, password) == 0); | |
| 1516 | + assert(qpdf_update_from_json_file(qpdf, xarg) == QPDF_SUCCESS); | |
| 1517 | + qpdf_init_write(qpdf, outfile); | |
| 1518 | + qpdf_set_static_ID(qpdf, QPDF_TRUE); | |
| 1519 | + qpdf_write(qpdf); | |
| 1520 | + report_errors(); | |
| 1521 | +} | |
| 1522 | + | |
| 1523 | +static void | |
| 1524 | +test45( | |
| 1525 | + char const* infile, | |
| 1526 | + char const* password, | |
| 1527 | + char const* outfile, | |
| 1528 | + char const* xarg) | |
| 1529 | +{ | |
| 1530 | + char* buf = NULL; | |
| 1531 | + unsigned long size = 0; | |
| 1532 | + read_file_into_memory(xarg, &buf, &size); | |
| 1533 | + assert(qpdf_read(qpdf, infile, password) == 0); | |
| 1534 | + assert(qpdf_update_from_json_data(qpdf, buf, size) == QPDF_SUCCESS); | |
| 1535 | + qpdf_init_write(qpdf, outfile); | |
| 1536 | + qpdf_set_static_ID(qpdf, QPDF_TRUE); | |
| 1537 | + qpdf_write(qpdf); | |
| 1538 | + report_errors(); | |
| 1539 | + free(buf); | |
| 1540 | +} | |
| 1541 | + | |
| 1542 | +static void | |
| 1543 | +test46( | |
| 1544 | + char const* infile, | |
| 1545 | + char const* password, | |
| 1546 | + char const* outfile, | |
| 1547 | + char const* xarg) | |
| 1548 | +{ | |
| 1549 | + FILE* f = safe_fopen(outfile, "wb"); | |
| 1550 | + assert(qpdf_read(qpdf, infile, password) == 0); | |
| 1551 | + qpdf_write_json( | |
| 1552 | + qpdf, 2, write_to_file, f, qpdf_dl_none, qpdf_sj_inline, "", NULL); | |
| 1553 | + fclose(f); | |
| 1554 | + report_errors(); | |
| 1555 | +} | |
| 1556 | + | |
| 1557 | +static void | |
| 1558 | +test47( | |
| 1559 | + char const* infile, | |
| 1560 | + char const* password, | |
| 1561 | + char const* outfile, | |
| 1562 | + char const* xarg) | |
| 1563 | +{ | |
| 1564 | + FILE* f = safe_fopen(outfile, "wb"); | |
| 1565 | + assert(qpdf_read(qpdf, infile, password) == 0); | |
| 1566 | + char const* wanted_objects[] = {"obj:4 0 R", "trailer", NULL}; | |
| 1567 | + qpdf_write_json( | |
| 1568 | + qpdf, | |
| 1569 | + 2, | |
| 1570 | + write_to_file, | |
| 1571 | + f, | |
| 1572 | + qpdf_dl_specialized, | |
| 1573 | + qpdf_sj_file, | |
| 1574 | + xarg, | |
| 1575 | + wanted_objects); | |
| 1576 | + fclose(f); | |
| 1577 | + report_errors(); | |
| 1578 | +} | |
| 1579 | + | |
| 1469 | 1580 | int |
| 1470 | 1581 | main(int argc, char* argv[]) |
| 1471 | 1582 | { |
| ... | ... | @@ -1542,6 +1653,12 @@ main(int argc, char* argv[]) |
| 1542 | 1653 | : (n == 39) ? test39 |
| 1543 | 1654 | : (n == 40) ? test40 |
| 1544 | 1655 | : (n == 41) ? test41 |
| 1656 | + : (n == 42) ? test42 | |
| 1657 | + : (n == 43) ? test43 | |
| 1658 | + : (n == 44) ? test44 | |
| 1659 | + : (n == 45) ? test45 | |
| 1660 | + : (n == 46) ? test46 | |
| 1661 | + : (n == 47) ? test47 | |
| 1545 | 1662 | : 0); |
| 1546 | 1663 | |
| 1547 | 1664 | if (fn == 0) { | ... | ... |
qpdf/qtest/qpdf-json.test
| ... | ... | @@ -288,5 +288,58 @@ $td->runtest("simple version of writeJSON", |
| 288 | 288 | {$td->FILE => "minimal-write-json.json", $td->EXIT_STATUS => 0}, |
| 289 | 289 | $td->NORMALIZE_NEWLINES); |
| 290 | 290 | |
| 291 | +$n_tests += 13; | |
| 292 | +$td->runtest("C API create from json file", | |
| 293 | + {$td->COMMAND => "qpdf-ctest 42 minimal.json '' a.pdf"}, | |
| 294 | + {$td->STRING => "C test 42 done\n", $td->EXIT_STATUS => 0}, | |
| 295 | + $td->NORMALIZE_NEWLINES); | |
| 296 | +$td->runtest("check C API create from file", | |
| 297 | + {$td->FILE => "a.pdf"}, | |
| 298 | + {$td->FILE => "qpdf-ctest-42-43.pdf"}); | |
| 299 | +$td->runtest("C API create from json buffer", | |
| 300 | + {$td->COMMAND => "qpdf-ctest 43 minimal.json '' a.pdf"}, | |
| 301 | + {$td->STRING => "C test 43 done\n", $td->EXIT_STATUS => 0}, | |
| 302 | + $td->NORMALIZE_NEWLINES); | |
| 303 | +$td->runtest("check C API create from buffer", | |
| 304 | + {$td->FILE => "a.pdf"}, | |
| 305 | + {$td->FILE => "qpdf-ctest-42-43.pdf"}); | |
| 306 | +$td->runtest("C API update from json file", | |
| 307 | + {$td->COMMAND => | |
| 308 | + "qpdf-ctest 44 minimal.pdf '' a.pdf minimal-update.json"}, | |
| 309 | + {$td->STRING => "C test 44 done\n", $td->EXIT_STATUS => 0}, | |
| 310 | + $td->NORMALIZE_NEWLINES); | |
| 311 | +$td->runtest("check C API update from file", | |
| 312 | + {$td->FILE => "a.pdf"}, | |
| 313 | + {$td->FILE => "qpdf-ctest-44-45.pdf"}); | |
| 314 | +$td->runtest("C API update from json buffer", | |
| 315 | + {$td->COMMAND => | |
| 316 | + "qpdf-ctest 45 minimal.pdf '' a.pdf minimal-update.json"}, | |
| 317 | + {$td->STRING => "C test 45 done\n", $td->EXIT_STATUS => 0}, | |
| 318 | + $td->NORMALIZE_NEWLINES); | |
| 319 | +$td->runtest("check C API update from buffer", | |
| 320 | + {$td->FILE => "a.pdf"}, | |
| 321 | + {$td->FILE => "qpdf-ctest-44-45.pdf"}); | |
| 322 | +$td->runtest("C API write to JSON 1", | |
| 323 | + {$td->COMMAND => | |
| 324 | + "qpdf-ctest 46 minimal.pdf '' a.json"}, | |
| 325 | + {$td->STRING => "C test 46 done\n", $td->EXIT_STATUS => 0}, | |
| 326 | + $td->NORMALIZE_NEWLINES); | |
| 327 | +$td->runtest("check C API write to JSON 1", | |
| 328 | + {$td->FILE => "a.json"}, | |
| 329 | + {$td->FILE => "qpdf-ctest-46.json"}, | |
| 330 | + $td->NORMALIZE_NEWLINES); | |
| 331 | +$td->runtest("C API write to JSON 2", | |
| 332 | + {$td->COMMAND => | |
| 333 | + "qpdf-ctest 47 minimal.pdf '' a.json auto"}, | |
| 334 | + {$td->STRING => "C test 47 done\n", $td->EXIT_STATUS => 0}, | |
| 335 | + $td->NORMALIZE_NEWLINES); | |
| 336 | +$td->runtest("check C API write to JSON 2", | |
| 337 | + {$td->FILE => "a.json"}, | |
| 338 | + {$td->FILE => "qpdf-ctest-47.json"}, | |
| 339 | + $td->NORMALIZE_NEWLINES); | |
| 340 | +$td->runtest("check C API write to JSON stream", | |
| 341 | + {$td->FILE => "auto-4"}, | |
| 342 | + {$td->FILE => "qpdf-ctest-47-4"}); | |
| 343 | + | |
| 291 | 344 | cleanup(); |
| 292 | 345 | $td->report($n_tests); | ... | ... |
qpdf/qtest/qpdf/minimal-update.json
0 → 100644
| 1 | +{ | |
| 2 | + "qpdf": [ | |
| 3 | + { | |
| 4 | + "jsonversion": 2, | |
| 5 | + "pushedinheritedpageresources": false, | |
| 6 | + "calledgetallpages": false | |
| 7 | + }, | |
| 8 | + { | |
| 9 | + "obj:4 0 R": { | |
| 10 | + "stream": { | |
| 11 | + "data": "QlQKICAvRjEgMjQgVGYKICA3MiA3MjAgVGQKICAoU2FsYWQpIFRqCkVUCg==", | |
| 12 | + "dict": {} | |
| 13 | + } | |
| 14 | + } | |
| 15 | + } | |
| 16 | + ] | |
| 17 | +} | ... | ... |
qpdf/qtest/qpdf/minimal.json
0 → 100644
| 1 | +{ | |
| 2 | + "qpdf": [ | |
| 3 | + { | |
| 4 | + "jsonversion": 2, | |
| 5 | + "pdfversion": "1.3", | |
| 6 | + "pushedinheritedpageresources": false, | |
| 7 | + "calledgetallpages": false, | |
| 8 | + "maxobjectid": 6 | |
| 9 | + }, | |
| 10 | + { | |
| 11 | + "obj:1 0 R": { | |
| 12 | + "value": { | |
| 13 | + "/Pages": "2 0 R", | |
| 14 | + "/Type": "/Catalog" | |
| 15 | + } | |
| 16 | + }, | |
| 17 | + "obj:2 0 R": { | |
| 18 | + "value": { | |
| 19 | + "/Count": 1, | |
| 20 | + "/Kids": [ | |
| 21 | + "3 0 R" | |
| 22 | + ], | |
| 23 | + "/Type": "/Pages" | |
| 24 | + } | |
| 25 | + }, | |
| 26 | + "obj:3 0 R": { | |
| 27 | + "value": { | |
| 28 | + "/Contents": "4 0 R", | |
| 29 | + "/MediaBox": [ | |
| 30 | + 0, | |
| 31 | + 0, | |
| 32 | + 612, | |
| 33 | + 792 | |
| 34 | + ], | |
| 35 | + "/Parent": "2 0 R", | |
| 36 | + "/Resources": { | |
| 37 | + "/Font": { | |
| 38 | + "/F1": "6 0 R" | |
| 39 | + }, | |
| 40 | + "/ProcSet": "5 0 R" | |
| 41 | + }, | |
| 42 | + "/Type": "/Page" | |
| 43 | + } | |
| 44 | + }, | |
| 45 | + "obj:4 0 R": { | |
| 46 | + "stream": { | |
| 47 | + "data": "QlQKICAvRjEgMjQgVGYKICA3MiA3MjAgVGQKICAoUG90YXRvKSBUagpFVAo=", | |
| 48 | + "dict": {} | |
| 49 | + } | |
| 50 | + }, | |
| 51 | + "obj:5 0 R": { | |
| 52 | + "value": [ | |
| 53 | + "/PDF", | |
| 54 | + "/Text" | |
| 55 | + ] | |
| 56 | + }, | |
| 57 | + "obj:6 0 R": { | |
| 58 | + "value": { | |
| 59 | + "/BaseFont": "/Helvetica", | |
| 60 | + "/Encoding": "/WinAnsiEncoding", | |
| 61 | + "/Name": "/F1", | |
| 62 | + "/Subtype": "/Type1", | |
| 63 | + "/Type": "/Font" | |
| 64 | + } | |
| 65 | + }, | |
| 66 | + "trailer": { | |
| 67 | + "value": { | |
| 68 | + "/Root": "1 0 R", | |
| 69 | + "/Size": 7 | |
| 70 | + } | |
| 71 | + } | |
| 72 | + } | |
| 73 | + ] | |
| 74 | +} | ... | ... |
qpdf/qtest/qpdf/qpdf-ctest-42-43.pdf
0 → 100644
No preview for this file type
qpdf/qtest/qpdf/qpdf-ctest-44-45.pdf
0 → 100644
No preview for this file type
qpdf/qtest/qpdf/qpdf-ctest-46.json
0 → 100644
| 1 | +{ | |
| 2 | + "qpdf": [ | |
| 3 | + { | |
| 4 | + "jsonversion": 2, | |
| 5 | + "pdfversion": "1.3", | |
| 6 | + "pushedinheritedpageresources": false, | |
| 7 | + "calledgetallpages": false, | |
| 8 | + "maxobjectid": 6 | |
| 9 | + }, | |
| 10 | + { | |
| 11 | + "obj:1 0 R": { | |
| 12 | + "value": { | |
| 13 | + "/Pages": "2 0 R", | |
| 14 | + "/Type": "/Catalog" | |
| 15 | + } | |
| 16 | + }, | |
| 17 | + "obj:2 0 R": { | |
| 18 | + "value": { | |
| 19 | + "/Count": 1, | |
| 20 | + "/Kids": [ | |
| 21 | + "3 0 R" | |
| 22 | + ], | |
| 23 | + "/Type": "/Pages" | |
| 24 | + } | |
| 25 | + }, | |
| 26 | + "obj:3 0 R": { | |
| 27 | + "value": { | |
| 28 | + "/Contents": "4 0 R", | |
| 29 | + "/MediaBox": [ | |
| 30 | + 0, | |
| 31 | + 0, | |
| 32 | + 612, | |
| 33 | + 792 | |
| 34 | + ], | |
| 35 | + "/Parent": "2 0 R", | |
| 36 | + "/Resources": { | |
| 37 | + "/Font": { | |
| 38 | + "/F1": "6 0 R" | |
| 39 | + }, | |
| 40 | + "/ProcSet": "5 0 R" | |
| 41 | + }, | |
| 42 | + "/Type": "/Page" | |
| 43 | + } | |
| 44 | + }, | |
| 45 | + "obj:4 0 R": { | |
| 46 | + "stream": { | |
| 47 | + "data": "QlQKICAvRjEgMjQgVGYKICA3MiA3MjAgVGQKICAoUG90YXRvKSBUagpFVAo=", | |
| 48 | + "dict": {} | |
| 49 | + } | |
| 50 | + }, | |
| 51 | + "obj:5 0 R": { | |
| 52 | + "value": [ | |
| 53 | + "/PDF", | |
| 54 | + "/Text" | |
| 55 | + ] | |
| 56 | + }, | |
| 57 | + "obj:6 0 R": { | |
| 58 | + "value": { | |
| 59 | + "/BaseFont": "/Helvetica", | |
| 60 | + "/Encoding": "/WinAnsiEncoding", | |
| 61 | + "/Name": "/F1", | |
| 62 | + "/Subtype": "/Type1", | |
| 63 | + "/Type": "/Font" | |
| 64 | + } | |
| 65 | + }, | |
| 66 | + "trailer": { | |
| 67 | + "value": { | |
| 68 | + "/Root": "1 0 R", | |
| 69 | + "/Size": 7 | |
| 70 | + } | |
| 71 | + } | |
| 72 | + } | |
| 73 | + ] | |
| 74 | +} | ... | ... |
qpdf/qtest/qpdf/qpdf-ctest-47-4
0 → 100644
qpdf/qtest/qpdf/qpdf-ctest-47.json
0 → 100644
| 1 | +{ | |
| 2 | + "qpdf": [ | |
| 3 | + { | |
| 4 | + "jsonversion": 2, | |
| 5 | + "pdfversion": "1.3", | |
| 6 | + "pushedinheritedpageresources": false, | |
| 7 | + "calledgetallpages": false, | |
| 8 | + "maxobjectid": 6 | |
| 9 | + }, | |
| 10 | + { | |
| 11 | + "obj:4 0 R": { | |
| 12 | + "stream": { | |
| 13 | + "datafile": "auto-4", | |
| 14 | + "dict": {} | |
| 15 | + } | |
| 16 | + }, | |
| 17 | + "trailer": { | |
| 18 | + "value": { | |
| 19 | + "/Root": "1 0 R", | |
| 20 | + "/Size": 7 | |
| 21 | + } | |
| 22 | + } | |
| 23 | + } | |
| 24 | + ] | |
| 25 | +} | ... | ... |