1 #include <qpdf/qpdf-c.h>
2
3 #include <qpdf/QPDF.hh>
4 #include <qpdf/QPDFWriter.hh>
5 #include <qpdf/QTC.hh>
6 #include <qpdf/QPDFExc.hh>
7 #include <qpdf/Pl_Discard.hh>
8 #include <qpdf/Pl_Buffer.hh>
9 #include <qpdf/QIntC.hh>
10 #include <qpdf/QUtil.hh>
11
12 #include <list>
13 #include <string>
14 #include <stdexcept>
15 #include <cstring>
16 #include <functional>
17
18 struct _qpdf_error
19 {
20 PointerHolder<QPDFExc> exc;
21 };
22
23 struct _qpdf_data
24 {
25 _qpdf_data();
26 ~_qpdf_data();
27
28 PointerHolder<QPDF> qpdf;
29 PointerHolder<QPDFWriter> qpdf_writer;
30
31 PointerHolder<QPDFExc> error;
32 _qpdf_error tmp_error;
33 std::list<QPDFExc> warnings;
34 std::string tmp_string;
35
36 // Parameters for functions we call
37 char const* filename; // or description
38 char const* buffer;
39 unsigned long long size;
40 char const* password;
41 bool write_memory;
42 PointerHolder<Buffer> output_buffer;
43
44 // QPDFObjectHandle support
45 bool silence_errors;
46 bool oh_error_occurred;
47 std::map<qpdf_oh, PointerHolder<QPDFObjectHandle>> oh_cache;
48 qpdf_oh next_oh;
49 std::set<std::string> cur_iter_dict_keys;
50 std::set<std::string>::const_iterator dict_iter;
51 std::string cur_dict_key;
52 };
53
_qpdf_data()54 _qpdf_data::_qpdf_data() :
55 write_memory(false),
56 silence_errors(false),
57 oh_error_occurred(false),
58 next_oh(0)
59 {
60 }
61
~_qpdf_data()62 _qpdf_data::~_qpdf_data()
63 {
64 }
65
66 class ProgressReporter: public QPDFWriter::ProgressReporter
67 {
68 public:
69 ProgressReporter(void (*handler)(int, void*), void* data);
70 virtual ~ProgressReporter() = default;
71 virtual void reportProgress(int);
72
73 private:
74 void (*handler)(int, void*);
75 void* data;
76 };
77
ProgressReporter(void (* handler)(int,void *),void * data)78 ProgressReporter::ProgressReporter(void (*handler)(int, void*), void* data) :
79 handler(handler),
80 data(data)
81 {
82 }
83
84 void
reportProgress(int progress)85 ProgressReporter::reportProgress(int progress)
86 {
87 this->handler(progress, this->data);
88 }
89
90 // must set qpdf->filename and qpdf->password
call_read(qpdf_data qpdf)91 static void call_read(qpdf_data qpdf)
92 {
93 qpdf->qpdf->processFile(qpdf->filename, qpdf->password);
94 }
95
96 // must set qpdf->filename, qpdf->buffer, qpdf->size, and qpdf->password
call_read_memory(qpdf_data qpdf)97 static void call_read_memory(qpdf_data qpdf)
98 {
99 qpdf->qpdf->processMemoryFile(qpdf->filename, qpdf->buffer,
100 QIntC::to_size(qpdf->size), qpdf->password);
101 }
102
103 // must set qpdf->filename
call_init_write(qpdf_data qpdf)104 static void call_init_write(qpdf_data qpdf)
105 {
106 qpdf->qpdf_writer = new QPDFWriter(*(qpdf->qpdf), qpdf->filename);
107 }
108
call_init_write_memory(qpdf_data qpdf)109 static void call_init_write_memory(qpdf_data qpdf)
110 {
111 qpdf->qpdf_writer = new QPDFWriter(*(qpdf->qpdf));
112 qpdf->qpdf_writer->setOutputMemory();
113 }
114
call_write(qpdf_data qpdf)115 static void call_write(qpdf_data qpdf)
116 {
117 qpdf->qpdf_writer->write();
118 }
119
call_check(qpdf_data qpdf)120 static void call_check(qpdf_data qpdf)
121 {
122 QPDFWriter w(*qpdf->qpdf);
123 Pl_Discard discard;
124 w.setOutputPipeline(&discard);
125 w.setDecodeLevel(qpdf_dl_all);
126 w.write();
127 }
128
trap_errors(qpdf_data qpdf,std::function<void (qpdf_data)> fn)129 static QPDF_ERROR_CODE trap_errors(
130 qpdf_data qpdf, std::function<void(qpdf_data)> fn)
131 {
132 QPDF_ERROR_CODE status = QPDF_SUCCESS;
133 try
134 {
135 fn(qpdf);
136 }
137 catch (QPDFExc& e)
138 {
139 qpdf->error = new QPDFExc(e);
140 status |= QPDF_ERRORS;
141 }
142 catch (std::runtime_error& e)
143 {
144 qpdf->error = new QPDFExc(qpdf_e_system, "", "", 0, e.what());
145 status |= QPDF_ERRORS;
146 }
147 catch (std::exception& e)
148 {
149 qpdf->error = new QPDFExc(qpdf_e_internal, "", "", 0, e.what());
150 status |= QPDF_ERRORS;
151 }
152
153 if (qpdf_more_warnings(qpdf))
154 {
155 status |= QPDF_WARNINGS;
156 }
157 return status;
158 }
159
qpdf_get_qpdf_version()160 char const* qpdf_get_qpdf_version()
161 {
162 QTC::TC("qpdf", "qpdf-c called qpdf_get_qpdf_version");
163 return QPDF::QPDFVersion().c_str();
164 }
165
qpdf_init()166 qpdf_data qpdf_init()
167 {
168 QTC::TC("qpdf", "qpdf-c called qpdf_init");
169 qpdf_data qpdf = new _qpdf_data();
170 qpdf->qpdf = new QPDF();
171 return qpdf;
172 }
173
qpdf_cleanup(qpdf_data * qpdf)174 void qpdf_cleanup(qpdf_data* qpdf)
175 {
176 QTC::TC("qpdf", "qpdf-c called qpdf_cleanup");
177 qpdf_oh_release_all(*qpdf);
178 if ((*qpdf)->error.getPointer())
179 {
180 QTC::TC("qpdf", "qpdf-c cleanup warned about unhandled error");
181 std::cerr << "WARNING: application did not handle error: "
182 << (*qpdf)->error->what() << std::endl;
183
184 }
185 delete *qpdf;
186 *qpdf = 0;
187 }
188
qpdf_get_last_string_length(qpdf_data qpdf)189 size_t qpdf_get_last_string_length(qpdf_data qpdf)
190 {
191 return qpdf->tmp_string.length();
192 }
193
qpdf_more_warnings(qpdf_data qpdf)194 QPDF_BOOL qpdf_more_warnings(qpdf_data qpdf)
195 {
196 QTC::TC("qpdf", "qpdf-c called qpdf_more_warnings");
197
198 if (qpdf->warnings.empty())
199 {
200 std::vector<QPDFExc> w = qpdf->qpdf->getWarnings();
201 if (! w.empty())
202 {
203 qpdf->warnings.assign(w.begin(), w.end());
204 }
205 }
206 if (qpdf->warnings.empty())
207 {
208 return QPDF_FALSE;
209 }
210 else
211 {
212 return QPDF_TRUE;
213 }
214 }
215
qpdf_has_error(qpdf_data qpdf)216 QPDF_BOOL qpdf_has_error(qpdf_data qpdf)
217 {
218 QTC::TC("qpdf", "qpdf-c called qpdf_has_error");
219 return (qpdf->error.getPointer() ? QPDF_TRUE : QPDF_FALSE);
220 }
221
qpdf_get_error(qpdf_data qpdf)222 qpdf_error qpdf_get_error(qpdf_data qpdf)
223 {
224 if (qpdf->error.getPointer())
225 {
226 qpdf->tmp_error.exc = qpdf->error;
227 qpdf->error = 0;
228 QTC::TC("qpdf", "qpdf-c qpdf_get_error returned error");
229 return &qpdf->tmp_error;
230 }
231 else
232 {
233 return 0;
234 }
235 }
236
qpdf_next_warning(qpdf_data qpdf)237 qpdf_error qpdf_next_warning(qpdf_data qpdf)
238 {
239 if (qpdf_more_warnings(qpdf))
240 {
241 qpdf->tmp_error.exc = new QPDFExc(qpdf->warnings.front());
242 qpdf->warnings.pop_front();
243 QTC::TC("qpdf", "qpdf-c qpdf_next_warning returned warning");
244 return &qpdf->tmp_error;
245 }
246 else
247 {
248 return 0;
249 }
250 }
251
qpdf_get_error_full_text(qpdf_data qpdf,qpdf_error e)252 char const* qpdf_get_error_full_text(qpdf_data qpdf, qpdf_error e)
253 {
254 if (e == 0)
255 {
256 return "";
257 }
258 return e->exc->what();
259 }
260
qpdf_get_error_code(qpdf_data qpdf,qpdf_error e)261 enum qpdf_error_code_e qpdf_get_error_code(qpdf_data qpdf, qpdf_error e)
262 {
263 if (e == 0)
264 {
265 return qpdf_e_success;
266 }
267 return e->exc->getErrorCode();
268 }
269
qpdf_get_error_filename(qpdf_data qpdf,qpdf_error e)270 char const* qpdf_get_error_filename(qpdf_data qpdf, qpdf_error e)
271 {
272 if (e == 0)
273 {
274 return "";
275 }
276 return e->exc->getFilename().c_str();
277 }
278
qpdf_get_error_file_position(qpdf_data qpdf,qpdf_error e)279 unsigned long long qpdf_get_error_file_position(qpdf_data qpdf, qpdf_error e)
280 {
281 if (e == 0)
282 {
283 return 0;
284 }
285 return QIntC::to_ulonglong(e->exc->getFilePosition());
286 }
287
qpdf_get_error_message_detail(qpdf_data qpdf,qpdf_error e)288 char const* qpdf_get_error_message_detail(qpdf_data qpdf, qpdf_error e)
289 {
290 if (e == 0)
291 {
292 return "";
293 }
294 return e->exc->getMessageDetail().c_str();
295 }
296
qpdf_check_pdf(qpdf_data qpdf)297 QPDF_ERROR_CODE qpdf_check_pdf(qpdf_data qpdf)
298 {
299 QPDF_ERROR_CODE status = trap_errors(qpdf, &call_check);
300 QTC::TC("qpdf", "qpdf-c called qpdf_check_pdf");
301 return status;
302 }
303
qpdf_set_suppress_warnings(qpdf_data qpdf,QPDF_BOOL value)304 void qpdf_set_suppress_warnings(qpdf_data qpdf, QPDF_BOOL value)
305 {
306 QTC::TC("qpdf", "qpdf-c called qpdf_set_suppress_warnings");
307 qpdf->qpdf->setSuppressWarnings(value != QPDF_FALSE);
308 }
309
qpdf_set_ignore_xref_streams(qpdf_data qpdf,QPDF_BOOL value)310 void qpdf_set_ignore_xref_streams(qpdf_data qpdf, QPDF_BOOL value)
311 {
312 QTC::TC("qpdf", "qpdf-c called qpdf_set_ignore_xref_streams");
313 qpdf->qpdf->setIgnoreXRefStreams(value != QPDF_FALSE);
314 }
315
qpdf_set_attempt_recovery(qpdf_data qpdf,QPDF_BOOL value)316 void qpdf_set_attempt_recovery(qpdf_data qpdf, QPDF_BOOL value)
317 {
318 QTC::TC("qpdf", "qpdf-c called qpdf_set_attempt_recovery");
319 qpdf->qpdf->setAttemptRecovery(value != QPDF_FALSE);
320 }
321
qpdf_read(qpdf_data qpdf,char const * filename,char const * password)322 QPDF_ERROR_CODE qpdf_read(qpdf_data qpdf, char const* filename,
323 char const* password)
324 {
325 QPDF_ERROR_CODE status = QPDF_SUCCESS;
326 qpdf->filename = filename;
327 qpdf->password = password;
328 status = trap_errors(qpdf, &call_read);
329 // We no longer have a good way to exercise a file with both
330 // warnings and errors because qpdf is getting much better at
331 // recovering.
332 QTC::TC("qpdf", "qpdf-c called qpdf_read",
333 (status == 0) ? 0
334 : (status & QPDF_WARNINGS) ? 1
335 : (status & QPDF_ERRORS) ? 2 :
336 -1
337 );
338 return status;
339 }
340
qpdf_read_memory(qpdf_data qpdf,char const * description,char const * buffer,unsigned long long size,char const * password)341 QPDF_ERROR_CODE qpdf_read_memory(qpdf_data qpdf,
342 char const* description,
343 char const* buffer,
344 unsigned long long size,
345 char const* password)
346 {
347 QPDF_ERROR_CODE status = QPDF_SUCCESS;
348 qpdf->filename = description;
349 qpdf->buffer = buffer;
350 qpdf->size = size;
351 qpdf->password = password;
352 status = trap_errors(qpdf, &call_read_memory);
353 QTC::TC("qpdf", "qpdf-c called qpdf_read_memory", status);
354 return status;
355 }
356
qpdf_get_pdf_version(qpdf_data qpdf)357 char const* qpdf_get_pdf_version(qpdf_data qpdf)
358 {
359 QTC::TC("qpdf", "qpdf-c called qpdf_get_pdf_version");
360 qpdf->tmp_string = qpdf->qpdf->getPDFVersion();
361 return qpdf->tmp_string.c_str();
362 }
363
qpdf_get_pdf_extension_level(qpdf_data qpdf)364 int qpdf_get_pdf_extension_level(qpdf_data qpdf)
365 {
366 QTC::TC("qpdf", "qpdf-c called qpdf_get_pdf_extension_level");
367 return qpdf->qpdf->getExtensionLevel();
368 }
369
qpdf_get_user_password(qpdf_data qpdf)370 char const* qpdf_get_user_password(qpdf_data qpdf)
371 {
372 QTC::TC("qpdf", "qpdf-c called qpdf_get_user_password");
373 qpdf->tmp_string = qpdf->qpdf->getTrimmedUserPassword();
374 return qpdf->tmp_string.c_str();
375 }
376
qpdf_get_info_key(qpdf_data qpdf,char const * key)377 char const* qpdf_get_info_key(qpdf_data qpdf, char const* key)
378 {
379 char const* result = 0;
380 QPDFObjectHandle trailer = qpdf->qpdf->getTrailer();
381 if (trailer.hasKey("/Info"))
382 {
383 QPDFObjectHandle info = trailer.getKey("/Info");
384 if (info.hasKey(key))
385 {
386 QPDFObjectHandle value = info.getKey(key);
387 if (value.isString())
388 {
389 qpdf->tmp_string = value.getStringValue();
390 result = qpdf->tmp_string.c_str();
391 }
392 }
393 }
394 QTC::TC("qpdf", "qpdf-c get_info_key", (result == 0 ? 0 : 1));
395 return result;
396 }
397
qpdf_set_info_key(qpdf_data qpdf,char const * key,char const * value)398 void qpdf_set_info_key(qpdf_data qpdf, char const* key, char const* value)
399 {
400 if ((key == 0) || (std::strlen(key) == 0) || (key[0] != '/'))
401 {
402 return;
403 }
404 QPDFObjectHandle value_object;
405 if (value)
406 {
407 QTC::TC("qpdf", "qpdf-c set_info_key to value");
408 value_object = QPDFObjectHandle::newString(value);
409 }
410 else
411 {
412 QTC::TC("qpdf", "qpdf-c set_info_key to null");
413 value_object = QPDFObjectHandle::newNull();
414 }
415
416 QPDFObjectHandle trailer = qpdf->qpdf->getTrailer();
417 if (! trailer.hasKey("/Info"))
418 {
419 QTC::TC("qpdf", "qpdf-c add info to trailer");
420 trailer.replaceKey(
421 "/Info",
422 qpdf->qpdf->makeIndirectObject(QPDFObjectHandle::newDictionary()));
423 }
424 else
425 {
426 QTC::TC("qpdf", "qpdf-c set-info-key use existing info");
427 }
428
429 QPDFObjectHandle info = trailer.getKey("/Info");
430 info.replaceOrRemoveKey(key, value_object);
431 }
432
qpdf_is_linearized(qpdf_data qpdf)433 QPDF_BOOL qpdf_is_linearized(qpdf_data qpdf)
434 {
435 QTC::TC("qpdf", "qpdf-c called qpdf_is_linearized");
436 return (qpdf->qpdf->isLinearized() ? QPDF_TRUE : QPDF_FALSE);
437 }
438
qpdf_is_encrypted(qpdf_data qpdf)439 QPDF_BOOL qpdf_is_encrypted(qpdf_data qpdf)
440 {
441 QTC::TC("qpdf", "qpdf-c called qpdf_is_encrypted");
442 return (qpdf->qpdf->isEncrypted() ? QPDF_TRUE : QPDF_FALSE);
443 }
444
qpdf_allow_accessibility(qpdf_data qpdf)445 QPDF_BOOL qpdf_allow_accessibility(qpdf_data qpdf)
446 {
447 QTC::TC("qpdf", "qpdf-c called qpdf_allow_accessibility");
448 return (qpdf->qpdf->allowAccessibility() ? QPDF_TRUE : QPDF_FALSE);
449 }
450
qpdf_allow_extract_all(qpdf_data qpdf)451 QPDF_BOOL qpdf_allow_extract_all(qpdf_data qpdf)
452 {
453 QTC::TC("qpdf", "qpdf-c called qpdf_allow_extract_all");
454 return (qpdf->qpdf->allowExtractAll() ? QPDF_TRUE : QPDF_FALSE);
455 }
456
qpdf_allow_print_low_res(qpdf_data qpdf)457 QPDF_BOOL qpdf_allow_print_low_res(qpdf_data qpdf)
458 {
459 QTC::TC("qpdf", "qpdf-c called qpdf_allow_print_low_res");
460 return (qpdf->qpdf->allowPrintLowRes() ? QPDF_TRUE : QPDF_FALSE);
461 }
462
qpdf_allow_print_high_res(qpdf_data qpdf)463 QPDF_BOOL qpdf_allow_print_high_res(qpdf_data qpdf)
464 {
465 QTC::TC("qpdf", "qpdf-c called qpdf_allow_print_high_res");
466 return (qpdf->qpdf->allowPrintHighRes() ? QPDF_TRUE : QPDF_FALSE);
467 }
468
qpdf_allow_modify_assembly(qpdf_data qpdf)469 QPDF_BOOL qpdf_allow_modify_assembly(qpdf_data qpdf)
470 {
471 QTC::TC("qpdf", "qpdf-c called qpdf_allow_modify_assembly");
472 return (qpdf->qpdf->allowModifyAssembly() ? QPDF_TRUE : QPDF_FALSE);
473 }
474
qpdf_allow_modify_form(qpdf_data qpdf)475 QPDF_BOOL qpdf_allow_modify_form(qpdf_data qpdf)
476 {
477 QTC::TC("qpdf", "qpdf-c called qpdf_allow_modify_form");
478 return (qpdf->qpdf->allowModifyForm() ? QPDF_TRUE : QPDF_FALSE);
479 }
480
qpdf_allow_modify_annotation(qpdf_data qpdf)481 QPDF_BOOL qpdf_allow_modify_annotation(qpdf_data qpdf)
482 {
483 QTC::TC("qpdf", "qpdf-c called qpdf_allow_modify_annotation");
484 return (qpdf->qpdf->allowModifyAnnotation() ? QPDF_TRUE : QPDF_FALSE);
485 }
486
qpdf_allow_modify_other(qpdf_data qpdf)487 QPDF_BOOL qpdf_allow_modify_other(qpdf_data qpdf)
488 {
489 QTC::TC("qpdf", "qpdf-c called qpdf_allow_modify_other");
490 return (qpdf->qpdf->allowModifyOther() ? QPDF_TRUE : QPDF_FALSE);
491 }
492
qpdf_allow_modify_all(qpdf_data qpdf)493 QPDF_BOOL qpdf_allow_modify_all(qpdf_data qpdf)
494 {
495 QTC::TC("qpdf", "qpdf-c called qpdf_allow_modify_all");
496 return (qpdf->qpdf->allowModifyAll() ? QPDF_TRUE : QPDF_FALSE);
497 }
498
qpdf_init_write_internal(qpdf_data qpdf)499 static void qpdf_init_write_internal(qpdf_data qpdf)
500 {
501 if (qpdf->qpdf_writer.getPointer())
502 {
503 QTC::TC("qpdf", "qpdf-c called qpdf_init_write multiple times");
504 qpdf->qpdf_writer = 0;
505 if (qpdf->output_buffer.getPointer())
506 {
507 qpdf->output_buffer = 0;
508 qpdf->write_memory = false;
509 qpdf->filename = 0;
510 }
511 }
512 }
513
qpdf_init_write(qpdf_data qpdf,char const * filename)514 QPDF_ERROR_CODE qpdf_init_write(qpdf_data qpdf, char const* filename)
515 {
516 qpdf_init_write_internal(qpdf);
517 qpdf->filename = filename;
518 QPDF_ERROR_CODE status = trap_errors(qpdf, &call_init_write);
519 QTC::TC("qpdf", "qpdf-c called qpdf_init_write", status);
520 return status;
521 }
522
qpdf_init_write_memory(qpdf_data qpdf)523 QPDF_ERROR_CODE qpdf_init_write_memory(qpdf_data qpdf)
524 {
525 qpdf_init_write_internal(qpdf);
526 QPDF_ERROR_CODE status = trap_errors(qpdf, &call_init_write_memory);
527 QTC::TC("qpdf", "qpdf-c called qpdf_init_write_memory");
528 qpdf->write_memory = true;
529 return status;
530 }
531
qpdf_get_buffer_internal(qpdf_data qpdf)532 static void qpdf_get_buffer_internal(qpdf_data qpdf)
533 {
534 if (qpdf->write_memory && (qpdf->output_buffer == 0))
535 {
536 qpdf->output_buffer = qpdf->qpdf_writer->getBuffer();
537 }
538 }
539
qpdf_get_buffer_length(qpdf_data qpdf)540 size_t qpdf_get_buffer_length(qpdf_data qpdf)
541 {
542 qpdf_get_buffer_internal(qpdf);
543 size_t result = 0;
544 if (qpdf->output_buffer.getPointer())
545 {
546 result = qpdf->output_buffer->getSize();
547 }
548 return result;
549 }
550
qpdf_get_buffer(qpdf_data qpdf)551 unsigned char const* qpdf_get_buffer(qpdf_data qpdf)
552 {
553 unsigned char const* result = 0;
554 qpdf_get_buffer_internal(qpdf);
555 if (qpdf->output_buffer.getPointer())
556 {
557 result = qpdf->output_buffer->getBuffer();
558 }
559 return result;
560 }
561
qpdf_set_object_stream_mode(qpdf_data qpdf,qpdf_object_stream_e mode)562 void qpdf_set_object_stream_mode(qpdf_data qpdf, qpdf_object_stream_e mode)
563 {
564 QTC::TC("qpdf", "qpdf-c called qpdf_set_object_stream_mode");
565 qpdf->qpdf_writer->setObjectStreamMode(mode);
566 }
567
qpdf_set_compress_streams(qpdf_data qpdf,QPDF_BOOL value)568 void qpdf_set_compress_streams(qpdf_data qpdf, QPDF_BOOL value)
569 {
570 QTC::TC("qpdf", "qpdf-c called qpdf_set_compress_streams");
571 qpdf->qpdf_writer->setCompressStreams(value != QPDF_FALSE);
572 }
573
qpdf_set_decode_level(qpdf_data qpdf,qpdf_stream_decode_level_e level)574 void qpdf_set_decode_level(qpdf_data qpdf, qpdf_stream_decode_level_e level)
575 {
576 QTC::TC("qpdf", "qpdf-c called qpdf_set_decode_level");
577 qpdf->qpdf_writer->setDecodeLevel(level);
578 }
579
qpdf_set_preserve_unreferenced_objects(qpdf_data qpdf,QPDF_BOOL value)580 void qpdf_set_preserve_unreferenced_objects(qpdf_data qpdf, QPDF_BOOL value)
581 {
582 QTC::TC("qpdf", "qpdf-c called qpdf_set_preserve_unreferenced_objects");
583 qpdf->qpdf_writer->setPreserveUnreferencedObjects(value != QPDF_FALSE);
584 }
585
qpdf_set_newline_before_endstream(qpdf_data qpdf,QPDF_BOOL value)586 void qpdf_set_newline_before_endstream(qpdf_data qpdf, QPDF_BOOL value)
587 {
588 QTC::TC("qpdf", "qpdf-c called qpdf_set_newline_before_endstream");
589 qpdf->qpdf_writer->setNewlineBeforeEndstream(value != QPDF_FALSE);
590 }
591
qpdf_set_stream_data_mode(qpdf_data qpdf,qpdf_stream_data_e mode)592 void qpdf_set_stream_data_mode(qpdf_data qpdf, qpdf_stream_data_e mode)
593 {
594 QTC::TC("qpdf", "qpdf-c called qpdf_set_stream_data_mode");
595 qpdf->qpdf_writer->setStreamDataMode(mode);
596 }
597
qpdf_set_content_normalization(qpdf_data qpdf,QPDF_BOOL value)598 void qpdf_set_content_normalization(qpdf_data qpdf, QPDF_BOOL value)
599 {
600 QTC::TC("qpdf", "qpdf-c called qpdf_set_content_normalization");
601 qpdf->qpdf_writer->setContentNormalization(value != QPDF_FALSE);
602 }
603
qpdf_set_qdf_mode(qpdf_data qpdf,QPDF_BOOL value)604 void qpdf_set_qdf_mode(qpdf_data qpdf, QPDF_BOOL value)
605 {
606 QTC::TC("qpdf", "qpdf-c called qpdf_set_qdf_mode");
607 qpdf->qpdf_writer->setQDFMode(value != QPDF_FALSE);
608 }
609
qpdf_set_deterministic_ID(qpdf_data qpdf,QPDF_BOOL value)610 void qpdf_set_deterministic_ID(qpdf_data qpdf, QPDF_BOOL value)
611 {
612 QTC::TC("qpdf", "qpdf-c called qpdf_set_deterministic_ID");
613 qpdf->qpdf_writer->setDeterministicID(value != QPDF_FALSE);
614 }
615
qpdf_set_static_ID(qpdf_data qpdf,QPDF_BOOL value)616 void qpdf_set_static_ID(qpdf_data qpdf, QPDF_BOOL value)
617 {
618 QTC::TC("qpdf", "qpdf-c called qpdf_set_static_ID");
619 qpdf->qpdf_writer->setStaticID(value != QPDF_FALSE);
620 }
621
qpdf_set_static_aes_IV(qpdf_data qpdf,QPDF_BOOL value)622 void qpdf_set_static_aes_IV(qpdf_data qpdf, QPDF_BOOL value)
623 {
624 QTC::TC("qpdf", "qpdf-c called qpdf_set_static_aes_IV");
625 qpdf->qpdf_writer->setStaticAesIV(value != QPDF_FALSE);
626 }
627
qpdf_set_suppress_original_object_IDs(qpdf_data qpdf,QPDF_BOOL value)628 void qpdf_set_suppress_original_object_IDs(
629 qpdf_data qpdf, QPDF_BOOL value)
630 {
631 QTC::TC("qpdf", "qpdf-c called qpdf_set_suppress_original_object_IDs");
632 qpdf->qpdf_writer->setSuppressOriginalObjectIDs(value != QPDF_FALSE);
633 }
634
qpdf_set_preserve_encryption(qpdf_data qpdf,QPDF_BOOL value)635 void qpdf_set_preserve_encryption(qpdf_data qpdf, QPDF_BOOL value)
636 {
637 QTC::TC("qpdf", "qpdf-c called qpdf_set_preserve_encryption");
638 qpdf->qpdf_writer->setPreserveEncryption(value != QPDF_FALSE);
639 }
640
qpdf_set_r2_encryption_parameters(qpdf_data qpdf,char const * user_password,char const * owner_password,QPDF_BOOL allow_print,QPDF_BOOL allow_modify,QPDF_BOOL allow_extract,QPDF_BOOL allow_annotate)641 void qpdf_set_r2_encryption_parameters(
642 qpdf_data qpdf, char const* user_password, char const* owner_password,
643 QPDF_BOOL allow_print, QPDF_BOOL allow_modify,
644 QPDF_BOOL allow_extract, QPDF_BOOL allow_annotate)
645 {
646 QTC::TC("qpdf", "qpdf-c called qpdf_set_r2_encryption_parameters");
647 qpdf->qpdf_writer->setR2EncryptionParameters(
648 user_password, owner_password,
649 allow_print != QPDF_FALSE, allow_modify != QPDF_FALSE,
650 allow_extract != QPDF_FALSE, allow_annotate != QPDF_FALSE);
651 }
652
qpdf_set_r3_encryption_parameters2(qpdf_data qpdf,char const * user_password,char const * owner_password,QPDF_BOOL allow_accessibility,QPDF_BOOL allow_extract,QPDF_BOOL allow_assemble,QPDF_BOOL allow_annotate_and_form,QPDF_BOOL allow_form_filling,QPDF_BOOL allow_modify_other,enum qpdf_r3_print_e print)653 void qpdf_set_r3_encryption_parameters2(
654 qpdf_data qpdf, char const* user_password, char const* owner_password,
655 QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
656 QPDF_BOOL allow_assemble, QPDF_BOOL allow_annotate_and_form,
657 QPDF_BOOL allow_form_filling, QPDF_BOOL allow_modify_other,
658 enum qpdf_r3_print_e print)
659 {
660 QTC::TC("qpdf", "qpdf-c called qpdf_set_r3_encryption_parameters");
661 qpdf->qpdf_writer->setR3EncryptionParameters(
662 user_password, owner_password,
663 allow_accessibility != QPDF_FALSE, allow_extract != QPDF_FALSE,
664 allow_assemble != QPDF_FALSE, allow_annotate_and_form != QPDF_FALSE,
665 allow_form_filling != QPDF_FALSE, allow_modify_other != QPDF_FALSE,
666 print);
667 }
668
qpdf_set_r4_encryption_parameters2(qpdf_data qpdf,char const * user_password,char const * owner_password,QPDF_BOOL allow_accessibility,QPDF_BOOL allow_extract,QPDF_BOOL allow_assemble,QPDF_BOOL allow_annotate_and_form,QPDF_BOOL allow_form_filling,QPDF_BOOL allow_modify_other,enum qpdf_r3_print_e print,QPDF_BOOL encrypt_metadata,QPDF_BOOL use_aes)669 void qpdf_set_r4_encryption_parameters2(
670 qpdf_data qpdf, char const* user_password, char const* owner_password,
671 QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
672 QPDF_BOOL allow_assemble, QPDF_BOOL allow_annotate_and_form,
673 QPDF_BOOL allow_form_filling, QPDF_BOOL allow_modify_other,
674 enum qpdf_r3_print_e print,
675 QPDF_BOOL encrypt_metadata, QPDF_BOOL use_aes)
676 {
677 QTC::TC("qpdf", "qpdf-c called qpdf_set_r4_encryption_parameters");
678 qpdf->qpdf_writer->setR4EncryptionParameters(
679 user_password, owner_password,
680 allow_accessibility != QPDF_FALSE, allow_extract != QPDF_FALSE,
681 allow_assemble != QPDF_FALSE, allow_annotate_and_form != QPDF_FALSE,
682 allow_form_filling != QPDF_FALSE, allow_modify_other != QPDF_FALSE,
683 print, encrypt_metadata != QPDF_FALSE, use_aes != QPDF_FALSE);
684 }
685
686
qpdf_set_r5_encryption_parameters2(qpdf_data qpdf,char const * user_password,char const * owner_password,QPDF_BOOL allow_accessibility,QPDF_BOOL allow_extract,QPDF_BOOL allow_assemble,QPDF_BOOL allow_annotate_and_form,QPDF_BOOL allow_form_filling,QPDF_BOOL allow_modify_other,enum qpdf_r3_print_e print,QPDF_BOOL encrypt_metadata)687 void qpdf_set_r5_encryption_parameters2(
688 qpdf_data qpdf, char const* user_password, char const* owner_password,
689 QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
690 QPDF_BOOL allow_assemble, QPDF_BOOL allow_annotate_and_form,
691 QPDF_BOOL allow_form_filling, QPDF_BOOL allow_modify_other,
692 enum qpdf_r3_print_e print, QPDF_BOOL encrypt_metadata)
693 {
694 QTC::TC("qpdf", "qpdf-c called qpdf_set_r5_encryption_parameters");
695 qpdf->qpdf_writer->setR5EncryptionParameters(
696 user_password, owner_password,
697 allow_accessibility != QPDF_FALSE, allow_extract != QPDF_FALSE,
698 allow_assemble != QPDF_FALSE, allow_annotate_and_form != QPDF_FALSE,
699 allow_form_filling != QPDF_FALSE, allow_modify_other != QPDF_FALSE,
700 print, encrypt_metadata != QPDF_FALSE);
701 }
702
qpdf_set_r6_encryption_parameters2(qpdf_data qpdf,char const * user_password,char const * owner_password,QPDF_BOOL allow_accessibility,QPDF_BOOL allow_extract,QPDF_BOOL allow_assemble,QPDF_BOOL allow_annotate_and_form,QPDF_BOOL allow_form_filling,QPDF_BOOL allow_modify_other,enum qpdf_r3_print_e print,QPDF_BOOL encrypt_metadata)703 void qpdf_set_r6_encryption_parameters2(
704 qpdf_data qpdf, char const* user_password, char const* owner_password,
705 QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
706 QPDF_BOOL allow_assemble, QPDF_BOOL allow_annotate_and_form,
707 QPDF_BOOL allow_form_filling, QPDF_BOOL allow_modify_other,
708 enum qpdf_r3_print_e print, QPDF_BOOL encrypt_metadata)
709 {
710 QTC::TC("qpdf", "qpdf-c called qpdf_set_r6_encryption_parameters");
711 qpdf->qpdf_writer->setR6EncryptionParameters(
712 user_password, owner_password,
713 allow_accessibility != QPDF_FALSE, allow_extract != QPDF_FALSE,
714 allow_assemble != QPDF_FALSE, allow_annotate_and_form != QPDF_FALSE,
715 allow_form_filling != QPDF_FALSE, allow_modify_other != QPDF_FALSE,
716 print, encrypt_metadata != QPDF_FALSE);
717 }
718
qpdf_set_r3_encryption_parameters(qpdf_data qpdf,char const * user_password,char const * owner_password,QPDF_BOOL allow_accessibility,QPDF_BOOL allow_extract,qpdf_r3_print_e print,qpdf_r3_modify_e modify)719 void qpdf_set_r3_encryption_parameters(
720 qpdf_data qpdf, char const* user_password, char const* owner_password,
721 QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
722 qpdf_r3_print_e print, qpdf_r3_modify_e modify)
723 {
724 #ifdef _MSC_VER
725 # pragma warning (disable: 4996)
726 #endif
727 #if (defined(__GNUC__) || defined(__clang__))
728 # pragma GCC diagnostic push
729 # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
730 #endif
731 qpdf->qpdf_writer->setR3EncryptionParameters(
732 user_password, owner_password,
733 allow_accessibility != QPDF_FALSE, allow_extract != QPDF_FALSE,
734 print, modify);
735 #if (defined(__GNUC__) || defined(__clang__))
736 # pragma GCC diagnostic pop
737 #endif
738 }
739
qpdf_set_r4_encryption_parameters(qpdf_data qpdf,char const * user_password,char const * owner_password,QPDF_BOOL allow_accessibility,QPDF_BOOL allow_extract,qpdf_r3_print_e print,qpdf_r3_modify_e modify,QPDF_BOOL encrypt_metadata,QPDF_BOOL use_aes)740 void qpdf_set_r4_encryption_parameters(
741 qpdf_data qpdf, char const* user_password, char const* owner_password,
742 QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
743 qpdf_r3_print_e print, qpdf_r3_modify_e modify,
744 QPDF_BOOL encrypt_metadata, QPDF_BOOL use_aes)
745 {
746 #ifdef _MSC_VER
747 # pragma warning (disable: 4996)
748 #endif
749 #if (defined(__GNUC__) || defined(__clang__))
750 # pragma GCC diagnostic push
751 # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
752 #endif
753 qpdf->qpdf_writer->setR4EncryptionParameters(
754 user_password, owner_password,
755 allow_accessibility != QPDF_FALSE, allow_extract != QPDF_FALSE,
756 print, modify,
757 encrypt_metadata != QPDF_FALSE, use_aes != QPDF_FALSE);
758 #if (defined(__GNUC__) || defined(__clang__))
759 # pragma GCC diagnostic pop
760 #endif
761 }
762
qpdf_set_r5_encryption_parameters(qpdf_data qpdf,char const * user_password,char const * owner_password,QPDF_BOOL allow_accessibility,QPDF_BOOL allow_extract,qpdf_r3_print_e print,qpdf_r3_modify_e modify,QPDF_BOOL encrypt_metadata)763 void qpdf_set_r5_encryption_parameters(
764 qpdf_data qpdf, char const* user_password, char const* owner_password,
765 QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
766 qpdf_r3_print_e print, qpdf_r3_modify_e modify,
767 QPDF_BOOL encrypt_metadata)
768 {
769 #ifdef _MSC_VER
770 # pragma warning (disable: 4996)
771 #endif
772 #if (defined(__GNUC__) || defined(__clang__))
773 # pragma GCC diagnostic push
774 # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
775 #endif
776 qpdf->qpdf_writer->setR5EncryptionParameters(
777 user_password, owner_password,
778 allow_accessibility != QPDF_FALSE, allow_extract != QPDF_FALSE,
779 print, modify,
780 encrypt_metadata != QPDF_FALSE);
781 #if (defined(__GNUC__) || defined(__clang__))
782 # pragma GCC diagnostic pop
783 #endif
784 }
785
qpdf_set_r6_encryption_parameters(qpdf_data qpdf,char const * user_password,char const * owner_password,QPDF_BOOL allow_accessibility,QPDF_BOOL allow_extract,qpdf_r3_print_e print,qpdf_r3_modify_e modify,QPDF_BOOL encrypt_metadata)786 void qpdf_set_r6_encryption_parameters(
787 qpdf_data qpdf, char const* user_password, char const* owner_password,
788 QPDF_BOOL allow_accessibility, QPDF_BOOL allow_extract,
789 qpdf_r3_print_e print, qpdf_r3_modify_e modify,
790 QPDF_BOOL encrypt_metadata)
791 {
792 #ifdef _MSC_VER
793 # pragma warning (disable: 4996)
794 #endif
795 #if (defined(__GNUC__) || defined(__clang__))
796 # pragma GCC diagnostic push
797 # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
798 #endif
799 qpdf->qpdf_writer->setR6EncryptionParameters(
800 user_password, owner_password,
801 allow_accessibility != QPDF_FALSE, allow_extract != QPDF_FALSE,
802 print, modify, encrypt_metadata != QPDF_FALSE);
803 #if (defined(__GNUC__) || defined(__clang__))
804 # pragma GCC diagnostic pop
805 #endif
806 }
807
qpdf_set_linearization(qpdf_data qpdf,QPDF_BOOL value)808 void qpdf_set_linearization(qpdf_data qpdf, QPDF_BOOL value)
809 {
810 QTC::TC("qpdf", "qpdf-c called qpdf_set_linearization");
811 qpdf->qpdf_writer->setLinearization(value != QPDF_FALSE);
812 }
813
qpdf_set_minimum_pdf_version(qpdf_data qpdf,char const * version)814 void qpdf_set_minimum_pdf_version(qpdf_data qpdf, char const* version)
815 {
816 qpdf_set_minimum_pdf_version_and_extension(qpdf, version, 0);
817 }
818
qpdf_set_minimum_pdf_version_and_extension(qpdf_data qpdf,char const * version,int extension_level)819 void qpdf_set_minimum_pdf_version_and_extension(
820 qpdf_data qpdf, char const* version, int extension_level)
821 {
822 QTC::TC("qpdf", "qpdf-c called qpdf_set_minimum_pdf_version");
823 qpdf->qpdf_writer->setMinimumPDFVersion(version, extension_level);
824 }
825
qpdf_force_pdf_version(qpdf_data qpdf,char const * version)826 void qpdf_force_pdf_version(qpdf_data qpdf, char const* version)
827 {
828 qpdf_force_pdf_version_and_extension(qpdf, version, 0);
829 }
830
qpdf_force_pdf_version_and_extension(qpdf_data qpdf,char const * version,int extension_level)831 void qpdf_force_pdf_version_and_extension(
832 qpdf_data qpdf, char const* version, int extension_level)
833 {
834 QTC::TC("qpdf", "qpdf-c called qpdf_force_pdf_version");
835 qpdf->qpdf_writer->forcePDFVersion(version, extension_level);
836 }
837
qpdf_register_progress_reporter(qpdf_data qpdf,void (* report_progress)(int percent,void * data),void * data)838 void qpdf_register_progress_reporter(
839 qpdf_data qpdf,
840 void (*report_progress)(int percent, void* data),
841 void* data)
842 {
843 QTC::TC("qpdf", "qpdf-c registered progress reporter");
844 qpdf->qpdf_writer->registerProgressReporter(
845 new ProgressReporter(report_progress, data));
846 }
847
qpdf_write(qpdf_data qpdf)848 QPDF_ERROR_CODE qpdf_write(qpdf_data qpdf)
849 {
850 QPDF_ERROR_CODE status = QPDF_SUCCESS;
851 status = trap_errors(qpdf, &call_write);
852 QTC::TC("qpdf", "qpdf-c called qpdf_write", (status == 0) ? 0 : 1);
853 return status;
854 }
855
qpdf_silence_errors(qpdf_data qpdf)856 void qpdf_silence_errors(qpdf_data qpdf)
857 {
858 QTC::TC("qpdf", "qpdf-c silence oh errors");
859 qpdf->silence_errors = true;
860 }
861
862 template<class RET>
trap_oh_errors(qpdf_data qpdf,std::function<RET ()> fallback,std::function<RET (qpdf_data)> fn)863 static RET trap_oh_errors(
864 qpdf_data qpdf,
865 std::function<RET()> fallback,
866 std::function<RET(qpdf_data)> fn)
867 {
868 // Note: fallback is a function so we don't have to evaluate it
869 // unless needed. This is important because sometimes the fallback
870 // creates an object.
871 RET ret;
872 QPDF_ERROR_CODE status = trap_errors(qpdf, [&ret, fn] (qpdf_data q) {
873 ret = fn(q);
874 });
875 if (status & QPDF_ERRORS)
876 {
877 if (! qpdf->silence_errors)
878 {
879 QTC::TC("qpdf", "qpdf-c warn about oh error",
880 qpdf->oh_error_occurred ? 0 : 1);
881 if (! qpdf->oh_error_occurred)
882 {
883 qpdf->warnings.push_back(
884 QPDFExc(
885 qpdf_e_internal,
886 qpdf->qpdf->getFilename(),
887 "", 0,
888 "C API function caught an exception that it isn't"
889 " returning; please point the application developer"
890 " to ERROR HANDLING in qpdf-c.h"));
891 qpdf->oh_error_occurred = true;
892 }
893 std::cerr << qpdf->error->what() << std::endl;
894 }
895 return fallback();
896 }
897 return ret;
898 }
899
900 static qpdf_oh
new_object(qpdf_data qpdf,QPDFObjectHandle const & qoh)901 new_object(qpdf_data qpdf, QPDFObjectHandle const& qoh)
902 {
903 qpdf_oh oh = ++qpdf->next_oh; // never return 0
904 qpdf->oh_cache[oh] = new QPDFObjectHandle(qoh);
905 return oh;
906 }
907
qpdf_oh_new_object(qpdf_data qpdf,qpdf_oh oh)908 qpdf_oh qpdf_oh_new_object(qpdf_data qpdf, qpdf_oh oh)
909 {
910 QTC::TC("qpdf", "qpdf-c called qpdf_new_object");
911 return new_object(qpdf, *(qpdf->oh_cache[oh]));
912 }
913
qpdf_oh_release(qpdf_data qpdf,qpdf_oh oh)914 void qpdf_oh_release(qpdf_data qpdf, qpdf_oh oh)
915 {
916 QTC::TC("qpdf", "qpdf-c called qpdf_oh_release");
917 qpdf->oh_cache.erase(oh);
918 }
919
qpdf_oh_release_all(qpdf_data qpdf)920 void qpdf_oh_release_all(qpdf_data qpdf)
921 {
922 QTC::TC("qpdf", "qpdf-c called qpdf_oh_release_all");
923 qpdf->oh_cache.clear();
924 }
925
926 template <class T>
return_T(T const & r)927 static std::function<T()> return_T(T const& r)
928 {
929 return [&r]() { return r; };
930 }
931
return_false()932 static QPDF_BOOL return_false()
933 {
934 return QPDF_FALSE;
935 }
936
return_uninitialized(qpdf_data qpdf)937 static std::function<qpdf_oh()> return_uninitialized(qpdf_data qpdf)
938 {
939 return [qpdf]() { return qpdf_oh_new_uninitialized(qpdf); };
940 }
941
return_null(qpdf_data qpdf)942 static std::function<qpdf_oh()> return_null(qpdf_data qpdf)
943 {
944 return [qpdf]() { return qpdf_oh_new_null(qpdf); };
945 }
946
qpdf_get_trailer(qpdf_data qpdf)947 qpdf_oh qpdf_get_trailer(qpdf_data qpdf)
948 {
949 QTC::TC("qpdf", "qpdf-c called qpdf_get_trailer");
950 return trap_oh_errors<qpdf_oh>(
951 qpdf, return_uninitialized(qpdf), [] (qpdf_data q) {
952 return new_object(q, q->qpdf->getTrailer());
953 });
954 }
955
qpdf_get_root(qpdf_data qpdf)956 qpdf_oh qpdf_get_root(qpdf_data qpdf)
957 {
958 QTC::TC("qpdf", "qpdf-c called qpdf_get_root");
959 return trap_oh_errors<qpdf_oh>(
960 qpdf, return_uninitialized(qpdf), [] (qpdf_data q) {
961 return new_object(q, q->qpdf->getRoot());
962 });
963 }
964
qpdf_get_object_by_id(qpdf_data qpdf,int objid,int generation)965 qpdf_oh qpdf_get_object_by_id(qpdf_data qpdf, int objid, int generation)
966 {
967 QTC::TC("qpdf", "qpdf-c called qpdf_get_object_by_id");
968 return new_object(qpdf, qpdf->qpdf->getObjectByID(objid, generation));
969 }
970
971 template<class RET>
do_with_oh(qpdf_data qpdf,qpdf_oh oh,std::function<RET ()> fallback,std::function<RET (QPDFObjectHandle &)> fn)972 static RET do_with_oh(
973 qpdf_data qpdf, qpdf_oh oh,
974 std::function<RET()> fallback,
975 std::function<RET(QPDFObjectHandle&)> fn)
976 {
977 return trap_oh_errors<RET>(
978 qpdf, fallback, [fn, oh](qpdf_data q) {
979 auto i = q->oh_cache.find(oh);
980 bool result = ((i != q->oh_cache.end()) &&
981 (i->second).getPointer());
982 if (! result)
983 {
984 QTC::TC("qpdf", "qpdf-c invalid object handle");
985 throw QPDFExc(
986 qpdf_e_internal,
987 q->qpdf->getFilename(),
988 std::string("C API object handle ") +
989 QUtil::uint_to_string(oh),
990 0, "attempted access to unknown object handle");
991 }
992 return fn(*(q->oh_cache[oh]));
993 });
994 }
995
do_with_oh_void(qpdf_data qpdf,qpdf_oh oh,std::function<void (QPDFObjectHandle &)> fn)996 static void do_with_oh_void(
997 qpdf_data qpdf, qpdf_oh oh,
998 std::function<void(QPDFObjectHandle&)> fn)
999 {
1000 do_with_oh<bool>(
1001 qpdf, oh, return_T<bool>(false), [fn](QPDFObjectHandle& o) {
1002 fn(o);
1003 return true; // unused
1004 });
1005 }
1006
qpdf_replace_object(qpdf_data qpdf,int objid,int generation,qpdf_oh oh)1007 void qpdf_replace_object(qpdf_data qpdf, int objid, int generation, qpdf_oh oh)
1008 {
1009 do_with_oh_void(
1010 qpdf, oh, [qpdf, objid, generation](QPDFObjectHandle& o) {
1011 QTC::TC("qpdf", "qpdf-c called qpdf_replace_object");
1012 qpdf->qpdf->replaceObject(objid, generation, o);
1013 });
1014 }
1015
qpdf_oh_is_initialized(qpdf_data qpdf,qpdf_oh oh)1016 QPDF_BOOL qpdf_oh_is_initialized(qpdf_data qpdf, qpdf_oh oh)
1017 {
1018 QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_initialized");
1019 return do_with_oh<QPDF_BOOL>(
1020 qpdf, oh, return_false, [](QPDFObjectHandle& o) {
1021 return o.isInitialized();
1022 });
1023 }
1024
qpdf_oh_is_bool(qpdf_data qpdf,qpdf_oh oh)1025 QPDF_BOOL qpdf_oh_is_bool(qpdf_data qpdf, qpdf_oh oh)
1026 {
1027 QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_bool");
1028 return do_with_oh<QPDF_BOOL>(
1029 qpdf, oh, return_false, [](QPDFObjectHandle& o) {
1030 return o.isBool();
1031 });
1032 }
1033
qpdf_oh_is_null(qpdf_data qpdf,qpdf_oh oh)1034 QPDF_BOOL qpdf_oh_is_null(qpdf_data qpdf, qpdf_oh oh)
1035 {
1036 QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_null");
1037 return do_with_oh<QPDF_BOOL>(
1038 qpdf, oh, return_false, [](QPDFObjectHandle& o) {
1039 return o.isNull();
1040 });
1041 }
1042
qpdf_oh_is_integer(qpdf_data qpdf,qpdf_oh oh)1043 QPDF_BOOL qpdf_oh_is_integer(qpdf_data qpdf, qpdf_oh oh)
1044 {
1045 QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_integer");
1046 return do_with_oh<QPDF_BOOL>(
1047 qpdf, oh, return_false, [](QPDFObjectHandle& o) {
1048 return o.isInteger();
1049 });
1050 }
1051
qpdf_oh_is_real(qpdf_data qpdf,qpdf_oh oh)1052 QPDF_BOOL qpdf_oh_is_real(qpdf_data qpdf, qpdf_oh oh)
1053 {
1054 QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_real");
1055 return do_with_oh<QPDF_BOOL>(
1056 qpdf, oh, return_false, [](QPDFObjectHandle& o) {
1057 return o.isReal();
1058 });
1059 }
1060
qpdf_oh_is_name(qpdf_data qpdf,qpdf_oh oh)1061 QPDF_BOOL qpdf_oh_is_name(qpdf_data qpdf, qpdf_oh oh)
1062 {
1063 QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_name");
1064 return do_with_oh<QPDF_BOOL>(
1065 qpdf, oh, return_false, [](QPDFObjectHandle& o) {
1066 return o.isName();
1067 });
1068 }
1069
qpdf_oh_is_string(qpdf_data qpdf,qpdf_oh oh)1070 QPDF_BOOL qpdf_oh_is_string(qpdf_data qpdf, qpdf_oh oh)
1071 {
1072 QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_string");
1073 return do_with_oh<QPDF_BOOL>(
1074 qpdf, oh, return_false, [](QPDFObjectHandle& o) {
1075 return o.isString();
1076 });
1077 }
1078
qpdf_oh_is_operator(qpdf_data qpdf,qpdf_oh oh)1079 QPDF_BOOL qpdf_oh_is_operator(qpdf_data qpdf, qpdf_oh oh)
1080 {
1081 QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_operator");
1082 return do_with_oh<QPDF_BOOL>(
1083 qpdf, oh, return_false, [](QPDFObjectHandle& o) {
1084 return o.isOperator();
1085 });
1086 }
1087
qpdf_oh_is_inline_image(qpdf_data qpdf,qpdf_oh oh)1088 QPDF_BOOL qpdf_oh_is_inline_image(qpdf_data qpdf, qpdf_oh oh)
1089 {
1090 QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_inline_image");
1091 return do_with_oh<QPDF_BOOL>(
1092 qpdf, oh, return_false, [](QPDFObjectHandle& o) {
1093 return o.isInlineImage();
1094 });
1095 }
1096
qpdf_oh_is_array(qpdf_data qpdf,qpdf_oh oh)1097 QPDF_BOOL qpdf_oh_is_array(qpdf_data qpdf, qpdf_oh oh)
1098 {
1099 QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_array");
1100 return do_with_oh<QPDF_BOOL>(
1101 qpdf, oh, return_false, [](QPDFObjectHandle& o) {
1102 return o.isArray();
1103 });
1104 }
1105
qpdf_oh_is_dictionary(qpdf_data qpdf,qpdf_oh oh)1106 QPDF_BOOL qpdf_oh_is_dictionary(qpdf_data qpdf, qpdf_oh oh)
1107 {
1108 QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_dictionary");
1109 return do_with_oh<QPDF_BOOL>(
1110 qpdf, oh, return_false, [](QPDFObjectHandle& o) {
1111 return o.isDictionary();
1112 });
1113 }
1114
qpdf_oh_is_stream(qpdf_data qpdf,qpdf_oh oh)1115 QPDF_BOOL qpdf_oh_is_stream(qpdf_data qpdf, qpdf_oh oh)
1116 {
1117 QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_stream");
1118 return do_with_oh<QPDF_BOOL>(
1119 qpdf, oh, return_false, [](QPDFObjectHandle& o) {
1120 return o.isStream();
1121 });
1122 }
1123
qpdf_oh_is_indirect(qpdf_data qpdf,qpdf_oh oh)1124 QPDF_BOOL qpdf_oh_is_indirect(qpdf_data qpdf, qpdf_oh oh)
1125 {
1126 QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_indirect");
1127 return do_with_oh<QPDF_BOOL>(
1128 qpdf, oh, return_false, [](QPDFObjectHandle& o) {
1129 return o.isIndirect();
1130 });
1131 }
1132
qpdf_oh_is_scalar(qpdf_data qpdf,qpdf_oh oh)1133 QPDF_BOOL qpdf_oh_is_scalar(qpdf_data qpdf, qpdf_oh oh)
1134 {
1135 QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_scalar");
1136 return do_with_oh<QPDF_BOOL>(
1137 qpdf, oh, return_false, [](QPDFObjectHandle& o) {
1138 return o.isScalar();
1139 });
1140 }
1141
qpdf_oh_is_number(qpdf_data qpdf,qpdf_oh oh)1142 QPDF_BOOL qpdf_oh_is_number(qpdf_data qpdf, qpdf_oh oh)
1143 {
1144 return do_with_oh<QPDF_BOOL>(
1145 qpdf, oh, return_false, [](QPDFObjectHandle& o) {
1146 QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_number");
1147 return o.isNumber();
1148 });
1149 }
1150
qpdf_oh_get_type_code(qpdf_data qpdf,qpdf_oh oh)1151 qpdf_object_type_e qpdf_oh_get_type_code(qpdf_data qpdf, qpdf_oh oh)
1152 {
1153 return do_with_oh<qpdf_object_type_e>(
1154 qpdf, oh, return_T<qpdf_object_type_e>(ot_uninitialized),
1155 [](QPDFObjectHandle& o) {
1156 QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_type_code");
1157 return o.getTypeCode();
1158 });
1159 }
1160
qpdf_oh_get_type_name(qpdf_data qpdf,qpdf_oh oh)1161 char const* qpdf_oh_get_type_name(qpdf_data qpdf, qpdf_oh oh)
1162 {
1163 return do_with_oh<char const*>(
1164 qpdf, oh, return_T<char const*>(""), [qpdf](QPDFObjectHandle& o) {
1165 QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_type_name");
1166 qpdf->tmp_string = o.getTypeName();
1167 return qpdf->tmp_string.c_str();
1168 });
1169 }
1170
qpdf_oh_wrap_in_array(qpdf_data qpdf,qpdf_oh oh)1171 qpdf_oh qpdf_oh_wrap_in_array(qpdf_data qpdf, qpdf_oh oh)
1172 {
1173 return do_with_oh<qpdf_oh>(
1174 qpdf, oh,
1175 [qpdf](){ return qpdf_oh_new_array(qpdf); },
1176 [qpdf](QPDFObjectHandle& qoh) {
1177 if (qoh.isArray())
1178 {
1179 QTC::TC("qpdf", "qpdf-c array to wrap_in_array");
1180 return new_object(qpdf, qoh);
1181 }
1182 else
1183 {
1184 QTC::TC("qpdf", "qpdf-c non-array to wrap_in_array");
1185 return new_object(qpdf,
1186 QPDFObjectHandle::newArray(
1187 std::vector<QPDFObjectHandle>{qoh}));
1188 }
1189 });
1190 }
1191
qpdf_oh_parse(qpdf_data qpdf,char const * object_str)1192 qpdf_oh qpdf_oh_parse(qpdf_data qpdf, char const* object_str)
1193 {
1194 QTC::TC("qpdf", "qpdf-c called qpdf_oh_parse");
1195 return trap_oh_errors<qpdf_oh>(
1196 qpdf, return_uninitialized(qpdf), [object_str] (qpdf_data q) {
1197 return new_object(q, QPDFObjectHandle::parse(object_str));
1198 });
1199 }
1200
qpdf_oh_get_bool_value(qpdf_data qpdf,qpdf_oh oh)1201 QPDF_BOOL qpdf_oh_get_bool_value(qpdf_data qpdf, qpdf_oh oh)
1202 {
1203 return do_with_oh<QPDF_BOOL>(
1204 qpdf, oh, return_false, [](QPDFObjectHandle& o) {
1205 QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_bool_value");
1206 return o.getBoolValue();
1207 });
1208 }
1209
qpdf_oh_get_int_value(qpdf_data qpdf,qpdf_oh oh)1210 long long qpdf_oh_get_int_value(qpdf_data qpdf, qpdf_oh oh)
1211 {
1212 return do_with_oh<long long>(
1213 qpdf, oh, return_T<long long>(0LL), [](QPDFObjectHandle& o) {
1214 QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_int_value");
1215 return o.getIntValue();
1216 });
1217 }
1218
qpdf_oh_get_int_value_as_int(qpdf_data qpdf,qpdf_oh oh)1219 int qpdf_oh_get_int_value_as_int(qpdf_data qpdf, qpdf_oh oh)
1220 {
1221 return do_with_oh<int>(
1222 qpdf, oh, return_T<int>(0), [](QPDFObjectHandle& o) {
1223 QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_int_value_as_int");
1224 return o.getIntValueAsInt();
1225 });
1226 }
1227
qpdf_oh_get_uint_value(qpdf_data qpdf,qpdf_oh oh)1228 unsigned long long qpdf_oh_get_uint_value(qpdf_data qpdf, qpdf_oh oh)
1229 {
1230 return do_with_oh<unsigned long long>(
1231 qpdf, oh, return_T<unsigned long long>(0ULL), [](QPDFObjectHandle& o) {
1232 QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_uint_value");
1233 return o.getUIntValue();
1234 });
1235 }
1236
qpdf_oh_get_uint_value_as_uint(qpdf_data qpdf,qpdf_oh oh)1237 unsigned int qpdf_oh_get_uint_value_as_uint(qpdf_data qpdf, qpdf_oh oh)
1238 {
1239 return do_with_oh<unsigned int>(
1240 qpdf, oh, return_T<unsigned int>(0U), [](QPDFObjectHandle& o) {
1241 QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_uint_value_as_uint");
1242 return o.getUIntValueAsUInt();
1243 });
1244 }
1245
qpdf_oh_get_real_value(qpdf_data qpdf,qpdf_oh oh)1246 char const* qpdf_oh_get_real_value(qpdf_data qpdf, qpdf_oh oh)
1247 {
1248 return do_with_oh<char const*>(
1249 qpdf, oh, return_T<char const*>(""), [qpdf](QPDFObjectHandle& o) {
1250 QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_real_value");
1251 qpdf->tmp_string = o.getRealValue();
1252 return qpdf->tmp_string.c_str();
1253 });
1254 }
1255
qpdf_oh_get_numeric_value(qpdf_data qpdf,qpdf_oh oh)1256 double qpdf_oh_get_numeric_value(qpdf_data qpdf, qpdf_oh oh)
1257 {
1258 return do_with_oh<double>(
1259 qpdf, oh, return_T<double>(0.0), [](QPDFObjectHandle& o) {
1260 QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_numeric_value");
1261 return o.getNumericValue();
1262 });
1263 }
1264
qpdf_oh_get_name(qpdf_data qpdf,qpdf_oh oh)1265 char const* qpdf_oh_get_name(qpdf_data qpdf, qpdf_oh oh)
1266 {
1267 return do_with_oh<char const*>(
1268 qpdf, oh, return_T<char const*>(""), [qpdf](QPDFObjectHandle& o) {
1269 QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_name");
1270 qpdf->tmp_string = o.getName();
1271 return qpdf->tmp_string.c_str();
1272 });
1273 }
1274
qpdf_oh_get_string_value(qpdf_data qpdf,qpdf_oh oh)1275 char const* qpdf_oh_get_string_value(qpdf_data qpdf, qpdf_oh oh)
1276 {
1277 return do_with_oh<char const*>(
1278 qpdf, oh, return_T<char const*>(""), [qpdf](QPDFObjectHandle& o) {
1279 QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_string_value");
1280 qpdf->tmp_string = o.getStringValue();
1281 return qpdf->tmp_string.c_str();
1282 });
1283 }
1284
qpdf_oh_get_utf8_value(qpdf_data qpdf,qpdf_oh oh)1285 char const* qpdf_oh_get_utf8_value(qpdf_data qpdf, qpdf_oh oh)
1286 {
1287 return do_with_oh<char const*>(
1288 qpdf, oh, return_T<char const*>(""), [qpdf](QPDFObjectHandle& o) {
1289 QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_utf8_value");
1290 qpdf->tmp_string = o.getUTF8Value();
1291 return qpdf->tmp_string.c_str();
1292 });
1293 }
1294
qpdf_oh_get_binary_string_value(qpdf_data qpdf,qpdf_oh oh,size_t * length)1295 char const* qpdf_oh_get_binary_string_value(
1296 qpdf_data qpdf, qpdf_oh oh, size_t* length)
1297 {
1298 return do_with_oh<char const*>(
1299 qpdf, oh,
1300 return_T<char const*>(""),
1301 [qpdf, length](QPDFObjectHandle& o) {
1302 QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_binary_string_value");
1303 qpdf->tmp_string = o.getStringValue();
1304 *length = qpdf->tmp_string.length();
1305 return qpdf->tmp_string.c_str();
1306 });
1307 }
1308
qpdf_oh_get_array_n_items(qpdf_data qpdf,qpdf_oh oh)1309 int qpdf_oh_get_array_n_items(qpdf_data qpdf, qpdf_oh oh)
1310 {
1311 return do_with_oh<int>(
1312 qpdf, oh, return_T<int>(0), [](QPDFObjectHandle& o) {
1313 QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_array_n_items");
1314 return o.getArrayNItems();
1315 });
1316 }
1317
qpdf_oh_get_array_item(qpdf_data qpdf,qpdf_oh oh,int n)1318 qpdf_oh qpdf_oh_get_array_item(qpdf_data qpdf, qpdf_oh oh, int n)
1319 {
1320 return do_with_oh<qpdf_oh>(
1321 qpdf, oh, return_null(qpdf), [qpdf, n](QPDFObjectHandle& o) {
1322 QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_array_item");
1323 return new_object(qpdf, o.getArrayItem(n));
1324 });
1325 }
1326
qpdf_oh_begin_dict_key_iter(qpdf_data qpdf,qpdf_oh oh)1327 void qpdf_oh_begin_dict_key_iter(qpdf_data qpdf, qpdf_oh oh)
1328 {
1329 qpdf->cur_iter_dict_keys = do_with_oh<std::set<std::string>>(
1330 qpdf, oh,
1331 [](){ return std::set<std::string>(); },
1332 [](QPDFObjectHandle& o) {
1333 QTC::TC("qpdf", "qpdf-c called qpdf_oh_begin_dict_key_iter");
1334 return o.getKeys();
1335 });
1336 qpdf->dict_iter = qpdf->cur_iter_dict_keys.begin();
1337 }
1338
qpdf_oh_dict_more_keys(qpdf_data qpdf)1339 QPDF_BOOL qpdf_oh_dict_more_keys(qpdf_data qpdf)
1340 {
1341 QTC::TC("qpdf", "qpdf-c called qpdf_oh_dict_more_keys");
1342 return qpdf->dict_iter != qpdf->cur_iter_dict_keys.end();
1343 }
1344
qpdf_oh_dict_next_key(qpdf_data qpdf)1345 char const* qpdf_oh_dict_next_key(qpdf_data qpdf)
1346 {
1347 QTC::TC("qpdf", "qpdf-c called qpdf_oh_dict_next_key");
1348 if (qpdf_oh_dict_more_keys(qpdf))
1349 {
1350 qpdf->cur_dict_key = *qpdf->dict_iter;
1351 ++qpdf->dict_iter;
1352 return qpdf->cur_dict_key.c_str();
1353 }
1354 else
1355 {
1356 return nullptr;
1357 }
1358 }
1359
qpdf_oh_has_key(qpdf_data qpdf,qpdf_oh oh,char const * key)1360 QPDF_BOOL qpdf_oh_has_key(qpdf_data qpdf, qpdf_oh oh, char const* key)
1361 {
1362 return do_with_oh<QPDF_BOOL>(
1363 qpdf, oh, return_false, [key](QPDFObjectHandle& o) {
1364 QTC::TC("qpdf", "qpdf-c called qpdf_oh_has_key");
1365 return o.hasKey(key);
1366 });
1367 }
1368
qpdf_oh_get_key(qpdf_data qpdf,qpdf_oh oh,char const * key)1369 qpdf_oh qpdf_oh_get_key(qpdf_data qpdf, qpdf_oh oh, char const* key)
1370 {
1371 return do_with_oh<qpdf_oh>(
1372 qpdf, oh, return_null(qpdf), [qpdf, key](QPDFObjectHandle& o) {
1373 QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_key");
1374 return new_object(qpdf, o.getKey(key));
1375 });
1376 }
1377
qpdf_oh_is_or_has_name(qpdf_data qpdf,qpdf_oh oh,char const * key)1378 QPDF_BOOL qpdf_oh_is_or_has_name(qpdf_data qpdf, qpdf_oh oh, char const* key)
1379 {
1380 return do_with_oh<QPDF_BOOL>(
1381 qpdf, oh, return_false, [key](QPDFObjectHandle& o) {
1382 QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_or_has_name");
1383 return o.isOrHasName(key);
1384 });
1385 }
1386
qpdf_oh_new_uninitialized(qpdf_data qpdf)1387 qpdf_oh qpdf_oh_new_uninitialized(qpdf_data qpdf)
1388 {
1389 QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_uninitialized");
1390 return new_object(qpdf, QPDFObjectHandle());
1391 }
1392
qpdf_oh_new_null(qpdf_data qpdf)1393 qpdf_oh qpdf_oh_new_null(qpdf_data qpdf)
1394 {
1395 QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_null");
1396 return new_object(qpdf, QPDFObjectHandle::newNull());
1397 }
1398
qpdf_oh_new_bool(qpdf_data qpdf,QPDF_BOOL value)1399 qpdf_oh qpdf_oh_new_bool(qpdf_data qpdf, QPDF_BOOL value)
1400 {
1401 QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_bool");
1402 return new_object(qpdf, QPDFObjectHandle::newBool(value));
1403 }
1404
qpdf_oh_new_integer(qpdf_data qpdf,long long value)1405 qpdf_oh qpdf_oh_new_integer(qpdf_data qpdf, long long value)
1406 {
1407 QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_integer");
1408 return new_object(qpdf, QPDFObjectHandle::newInteger(value));
1409 }
1410
qpdf_oh_new_real_from_string(qpdf_data qpdf,char const * value)1411 qpdf_oh qpdf_oh_new_real_from_string(qpdf_data qpdf, char const* value)
1412 {
1413 QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_real_from_string");
1414 return new_object(qpdf, QPDFObjectHandle::newReal(value));
1415 }
1416
qpdf_oh_new_real_from_double(qpdf_data qpdf,double value,int decimal_places)1417 qpdf_oh qpdf_oh_new_real_from_double(qpdf_data qpdf,
1418 double value, int decimal_places)
1419 {
1420 QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_real_from_double");
1421 return new_object(qpdf, QPDFObjectHandle::newReal(value, decimal_places));
1422 }
1423
qpdf_oh_new_name(qpdf_data qpdf,char const * name)1424 qpdf_oh qpdf_oh_new_name(qpdf_data qpdf, char const* name)
1425 {
1426 QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_name");
1427 return new_object(qpdf, QPDFObjectHandle::newName(name));
1428 }
1429
qpdf_oh_new_string(qpdf_data qpdf,char const * str)1430 qpdf_oh qpdf_oh_new_string(qpdf_data qpdf, char const* str)
1431 {
1432 QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_string");
1433 return new_object(qpdf, QPDFObjectHandle::newString(str));
1434 }
1435
qpdf_oh_new_unicode_string(qpdf_data qpdf,char const * utf8_str)1436 qpdf_oh qpdf_oh_new_unicode_string(qpdf_data qpdf, char const* utf8_str)
1437 {
1438 QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_unicode_string");
1439 return new_object(qpdf, QPDFObjectHandle::newUnicodeString(utf8_str));
1440 }
1441
qpdf_oh_new_binary_string(qpdf_data qpdf,char const * str,size_t length)1442 qpdf_oh qpdf_oh_new_binary_string(
1443 qpdf_data qpdf, char const* str, size_t length)
1444 {
1445 QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_binary_string");
1446 return new_object(
1447 qpdf, QPDFObjectHandle::newString(std::string(str, length)));
1448 }
1449
qpdf_oh_new_array(qpdf_data qpdf)1450 qpdf_oh qpdf_oh_new_array(qpdf_data qpdf)
1451 {
1452 QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_array");
1453 return new_object(qpdf, QPDFObjectHandle::newArray());
1454 }
1455
qpdf_oh_new_dictionary(qpdf_data qpdf)1456 qpdf_oh qpdf_oh_new_dictionary(qpdf_data qpdf)
1457 {
1458 QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_dictionary");
1459 return new_object(qpdf, QPDFObjectHandle::newDictionary());
1460 }
1461
qpdf_oh_new_stream(qpdf_data qpdf)1462 qpdf_oh qpdf_oh_new_stream(qpdf_data qpdf)
1463 {
1464 QTC::TC("qpdf", "qpdf-c called qpdf_oh_new_stream");
1465 return new_object(
1466 qpdf, QPDFObjectHandle::newStream(qpdf->qpdf.getPointer()));
1467 }
1468
qpdf_oh_make_direct(qpdf_data qpdf,qpdf_oh oh)1469 void qpdf_oh_make_direct(qpdf_data qpdf, qpdf_oh oh)
1470 {
1471 do_with_oh_void(
1472 qpdf, oh, [](QPDFObjectHandle& o) {
1473 QTC::TC("qpdf", "qpdf-c called qpdf_oh_make_direct");
1474 o.makeDirect();
1475 });
1476 }
1477
qpdf_make_indirect_object(qpdf_data qpdf,qpdf_oh oh)1478 qpdf_oh qpdf_make_indirect_object(qpdf_data qpdf, qpdf_oh oh)
1479 {
1480 return do_with_oh<qpdf_oh>(
1481 qpdf, oh,
1482 return_uninitialized(qpdf),
1483 [qpdf](QPDFObjectHandle& o) {
1484 return new_object(qpdf, qpdf->qpdf->makeIndirectObject(o));
1485 });
1486 }
1487
1488 static QPDFObjectHandle
qpdf_oh_item_internal(qpdf_data qpdf,qpdf_oh item)1489 qpdf_oh_item_internal(qpdf_data qpdf, qpdf_oh item)
1490 {
1491 return do_with_oh<QPDFObjectHandle>(
1492 qpdf, item,
1493 [](){return QPDFObjectHandle::newNull();},
1494 [](QPDFObjectHandle& o) {
1495 return o;
1496 });
1497 }
1498
qpdf_oh_set_array_item(qpdf_data qpdf,qpdf_oh oh,int at,qpdf_oh item)1499 void qpdf_oh_set_array_item(qpdf_data qpdf, qpdf_oh oh,
1500 int at, qpdf_oh item)
1501 {
1502 do_with_oh_void(
1503 qpdf, oh, [qpdf, at, item](QPDFObjectHandle& o) {
1504 QTC::TC("qpdf", "qpdf-c called qpdf_oh_set_array_item");
1505 o.setArrayItem(at, qpdf_oh_item_internal(qpdf, item));
1506 });
1507 }
1508
qpdf_oh_insert_item(qpdf_data qpdf,qpdf_oh oh,int at,qpdf_oh item)1509 void qpdf_oh_insert_item(qpdf_data qpdf, qpdf_oh oh, int at, qpdf_oh item)
1510 {
1511 do_with_oh_void(
1512 qpdf, oh, [qpdf, at, item](QPDFObjectHandle& o) {
1513 QTC::TC("qpdf", "qpdf-c called qpdf_oh_insert_item");
1514 o.insertItem(at, qpdf_oh_item_internal(qpdf, item));
1515 });
1516 }
1517
qpdf_oh_append_item(qpdf_data qpdf,qpdf_oh oh,qpdf_oh item)1518 void qpdf_oh_append_item(qpdf_data qpdf, qpdf_oh oh, qpdf_oh item)
1519 {
1520 do_with_oh_void(
1521 qpdf, oh, [qpdf, item](QPDFObjectHandle& o) {
1522 QTC::TC("qpdf", "qpdf-c called qpdf_oh_append_item");
1523 o.appendItem(qpdf_oh_item_internal(qpdf, item));
1524 });
1525 }
1526
qpdf_oh_erase_item(qpdf_data qpdf,qpdf_oh oh,int at)1527 void qpdf_oh_erase_item(qpdf_data qpdf, qpdf_oh oh, int at)
1528 {
1529 do_with_oh_void(
1530 qpdf, oh, [at](QPDFObjectHandle& o) {
1531 QTC::TC("qpdf", "qpdf-c called qpdf_oh_erase_item");
1532 o.eraseItem(at);
1533 });
1534 }
1535
qpdf_oh_replace_key(qpdf_data qpdf,qpdf_oh oh,char const * key,qpdf_oh item)1536 void qpdf_oh_replace_key(qpdf_data qpdf, qpdf_oh oh,
1537 char const* key, qpdf_oh item)
1538 {
1539 do_with_oh_void(
1540 qpdf, oh, [qpdf, key, item](QPDFObjectHandle& o) {
1541 QTC::TC("qpdf", "qpdf-c called qpdf_oh_replace_key");
1542 o.replaceKey(key, qpdf_oh_item_internal(qpdf, item));
1543 });
1544 }
1545
qpdf_oh_remove_key(qpdf_data qpdf,qpdf_oh oh,char const * key)1546 void qpdf_oh_remove_key(qpdf_data qpdf, qpdf_oh oh, char const* key)
1547 {
1548 do_with_oh_void(
1549 qpdf, oh, [key](QPDFObjectHandle& o) {
1550 QTC::TC("qpdf", "qpdf-c called qpdf_oh_remove_key");
1551 o.removeKey(key);
1552 });
1553 }
1554
qpdf_oh_replace_or_remove_key(qpdf_data qpdf,qpdf_oh oh,char const * key,qpdf_oh item)1555 void qpdf_oh_replace_or_remove_key(qpdf_data qpdf, qpdf_oh oh,
1556 char const* key, qpdf_oh item)
1557 {
1558 do_with_oh_void(
1559 qpdf, oh, [qpdf, key, item](QPDFObjectHandle& o) {
1560 QTC::TC("qpdf", "qpdf-c called qpdf_oh_replace_or_remove_key");
1561 o.replaceOrRemoveKey(key, qpdf_oh_item_internal(qpdf, item));
1562 });
1563 }
1564
qpdf_oh_get_dict(qpdf_data qpdf,qpdf_oh oh)1565 qpdf_oh qpdf_oh_get_dict(qpdf_data qpdf, qpdf_oh oh)
1566 {
1567 return do_with_oh<qpdf_oh>(
1568 qpdf, oh, return_null(qpdf), [qpdf](QPDFObjectHandle& o) {
1569 QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_dict");
1570 return new_object(qpdf, o.getDict());
1571 });
1572 }
1573
qpdf_oh_get_object_id(qpdf_data qpdf,qpdf_oh oh)1574 int qpdf_oh_get_object_id(qpdf_data qpdf, qpdf_oh oh)
1575 {
1576 return do_with_oh<int>(
1577 qpdf, oh, return_T<int>(0), [](QPDFObjectHandle& o) {
1578 QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_object_id");
1579 return o.getObjectID();
1580 });
1581 }
1582
qpdf_oh_get_generation(qpdf_data qpdf,qpdf_oh oh)1583 int qpdf_oh_get_generation(qpdf_data qpdf, qpdf_oh oh)
1584 {
1585 return do_with_oh<int>(
1586 qpdf, oh, return_T<int>(0), [](QPDFObjectHandle& o) {
1587 QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_generation");
1588 return o.getGeneration();
1589 });
1590 }
1591
qpdf_oh_unparse(qpdf_data qpdf,qpdf_oh oh)1592 char const* qpdf_oh_unparse(qpdf_data qpdf, qpdf_oh oh)
1593 {
1594 return do_with_oh<char const*>(
1595 qpdf, oh, return_T<char const*>(""), [qpdf](QPDFObjectHandle& o) {
1596 QTC::TC("qpdf", "qpdf-c called qpdf_oh_unparse");
1597 qpdf->tmp_string = o.unparse();
1598 return qpdf->tmp_string.c_str();
1599 });
1600 }
1601
qpdf_oh_unparse_resolved(qpdf_data qpdf,qpdf_oh oh)1602 char const* qpdf_oh_unparse_resolved(qpdf_data qpdf, qpdf_oh oh)
1603 {
1604 return do_with_oh<char const*>(
1605 qpdf, oh, return_T<char const*>(""), [qpdf](QPDFObjectHandle& o) {
1606 QTC::TC("qpdf", "qpdf-c called qpdf_oh_unparse_resolved");
1607 qpdf->tmp_string = o.unparseResolved();
1608 return qpdf->tmp_string.c_str();
1609 });
1610 }
1611
qpdf_oh_unparse_binary(qpdf_data qpdf,qpdf_oh oh)1612 char const* qpdf_oh_unparse_binary(qpdf_data qpdf, qpdf_oh oh)
1613 {
1614 return do_with_oh<char const*>(
1615 qpdf, oh, return_T<char const*>(""), [qpdf](QPDFObjectHandle& o) {
1616 QTC::TC("qpdf", "qpdf-c called qpdf_oh_unparse_binary");
1617 qpdf->tmp_string = o.unparseBinary();
1618 return qpdf->tmp_string.c_str();
1619 });
1620 }
1621
qpdf_oh_copy_foreign_object(qpdf_data qpdf,qpdf_data other_qpdf,qpdf_oh foreign_oh)1622 qpdf_oh qpdf_oh_copy_foreign_object(
1623 qpdf_data qpdf, qpdf_data other_qpdf, qpdf_oh foreign_oh)
1624 {
1625 return do_with_oh<qpdf_oh>(
1626 other_qpdf, foreign_oh,
1627 return_uninitialized(qpdf),
1628 [qpdf](QPDFObjectHandle& o) {
1629 QTC::TC("qpdf", "qpdf-c called qpdf_oh_copy_foreign_object");
1630 return new_object(qpdf, qpdf->qpdf->copyForeignObject(o));
1631 });
1632 }
1633
qpdf_oh_get_stream_data(qpdf_data qpdf,qpdf_oh stream_oh,qpdf_stream_decode_level_e decode_level,QPDF_BOOL * filtered,unsigned char ** bufp,size_t * len)1634 QPDF_ERROR_CODE qpdf_oh_get_stream_data(
1635 qpdf_data qpdf, qpdf_oh stream_oh,
1636 qpdf_stream_decode_level_e decode_level, QPDF_BOOL* filtered,
1637 unsigned char** bufp, size_t* len)
1638 {
1639 return trap_errors(qpdf, [stream_oh, decode_level,
1640 filtered, bufp, len] (qpdf_data q) {
1641 auto stream = qpdf_oh_item_internal(q, stream_oh);
1642 Pipeline* p = nullptr;
1643 Pl_Buffer buf("stream data");
1644 if (bufp)
1645 {
1646 p = &buf;
1647 }
1648 bool was_filtered = false;
1649 if (stream.pipeStreamData(
1650 p, &was_filtered, 0, decode_level, false, false))
1651 {
1652 QTC::TC("qpdf", "qpdf-c stream data buf set",
1653 bufp ? 0 : 1);
1654 if (p && bufp && len)
1655 {
1656 buf.getMallocBuffer(bufp, len);
1657 }
1658 QTC::TC("qpdf", "qpdf-c stream data filtered set",
1659 filtered ? 0 : 1);
1660 if (filtered)
1661 {
1662 *filtered = was_filtered ? QPDF_TRUE : QPDF_FALSE;
1663 }
1664 }
1665 else
1666 {
1667 throw std::runtime_error(
1668 "unable to access stream data for stream " + stream.unparse());
1669 }
1670 });
1671 }
1672
qpdf_oh_get_page_content_data(qpdf_data qpdf,qpdf_oh page_oh,unsigned char ** bufp,size_t * len)1673 QPDF_ERROR_CODE qpdf_oh_get_page_content_data(
1674 qpdf_data qpdf, qpdf_oh page_oh,
1675 unsigned char** bufp, size_t* len)
1676 {
1677 return trap_errors(qpdf, [page_oh, bufp, len] (qpdf_data q) {
1678 QTC::TC("qpdf", "qpdf-c called qpdf_oh_get_page_content_data");
1679 auto o = qpdf_oh_item_internal(q, page_oh);
1680 Pl_Buffer buf("page contents");
1681 o.pipePageContents(&buf);
1682 buf.getMallocBuffer(bufp, len);
1683 });
1684 }
1685
qpdf_oh_replace_stream_data(qpdf_data qpdf,qpdf_oh stream_oh,unsigned char const * buf,size_t len,qpdf_oh filter_oh,qpdf_oh decode_parms_oh)1686 void qpdf_oh_replace_stream_data(
1687 qpdf_data qpdf, qpdf_oh stream_oh,
1688 unsigned char const* buf, size_t len,
1689 qpdf_oh filter_oh, qpdf_oh decode_parms_oh)
1690 {
1691 do_with_oh_void(qpdf, stream_oh, [
1692 qpdf, buf, len, filter_oh,
1693 decode_parms_oh](QPDFObjectHandle& o) {
1694 QTC::TC("qpdf", "qpdf-c called qpdf_oh_replace_stream_data");
1695 auto filter = qpdf_oh_item_internal(qpdf, filter_oh);
1696 auto decode_parms = qpdf_oh_item_internal(qpdf, decode_parms_oh);
1697 // XXX test with binary data with null
1698 o.replaceStreamData(
1699 std::string(reinterpret_cast<char const*>(buf), len),
1700 filter, decode_parms);
1701 });
1702 }
1703
qpdf_get_num_pages(qpdf_data qpdf)1704 int qpdf_get_num_pages(qpdf_data qpdf)
1705 {
1706 QTC::TC("qpdf", "qpdf-c called qpdf_num_pages");
1707 int n = -1;
1708 QPDF_ERROR_CODE code = trap_errors(qpdf, [&n](qpdf_data q) {
1709 n = QIntC::to_int(q->qpdf->getAllPages().size());
1710 });
1711 if (code & QPDF_ERRORS)
1712 {
1713 return -1;
1714 }
1715 return n;
1716 }
1717
qpdf_get_page_n(qpdf_data qpdf,size_t i)1718 qpdf_oh qpdf_get_page_n(qpdf_data qpdf, size_t i)
1719 {
1720 QTC::TC("qpdf", "qpdf-c called qpdf_get_page_n");
1721 qpdf_oh result = 0;
1722 QPDF_ERROR_CODE code = trap_errors(qpdf, [&result, i](qpdf_data q) {
1723 result = new_object(q, q->qpdf->getAllPages().at(i));
1724 });
1725 if ((code & QPDF_ERRORS) || (result == 0))
1726 {
1727 return qpdf_oh_new_uninitialized(qpdf);
1728 }
1729 return result;
1730 }
1731
qpdf_update_all_pages_cache(qpdf_data qpdf)1732 QPDF_ERROR_CODE qpdf_update_all_pages_cache(qpdf_data qpdf)
1733 {
1734 QTC::TC("qpdf", "qpdf-c called qpdf_update_all_pages_cache");
1735 return trap_errors(qpdf, [](qpdf_data q) {
1736 q->qpdf->updateAllPagesCache();
1737 });
1738 }
1739
qpdf_find_page_by_id(qpdf_data qpdf,int objid,int generation)1740 int qpdf_find_page_by_id(qpdf_data qpdf, int objid, int generation)
1741 {
1742 QTC::TC("qpdf", "qpdf-c called qpdf_find_page_by_id");
1743 int n = -1;
1744 QPDFObjGen og(objid, generation);
1745 QPDF_ERROR_CODE code = trap_errors(qpdf, [&n, &og](qpdf_data q) {
1746 n = QIntC::to_int(q->qpdf->findPage(og));
1747 });
1748 if (code & QPDF_ERRORS)
1749 {
1750 return -1;
1751 }
1752 return n;
1753 }
1754
qpdf_find_page_by_oh(qpdf_data qpdf,qpdf_oh oh)1755 int qpdf_find_page_by_oh(qpdf_data qpdf, qpdf_oh oh)
1756 {
1757 QTC::TC("qpdf", "qpdf-c called qpdf_find_page_by_oh");
1758 return do_with_oh<int>(
1759 qpdf, oh, return_T<int>(-1), [qpdf](QPDFObjectHandle& o) {
1760 return qpdf->qpdf->findPage(o);
1761 });
1762 }
1763
qpdf_push_inherited_attributes_to_page(qpdf_data qpdf)1764 QPDF_ERROR_CODE qpdf_push_inherited_attributes_to_page(qpdf_data qpdf)
1765 {
1766 QTC::TC("qpdf", "qpdf-c called qpdf_push_inherited_attributes_to_page");
1767 return trap_errors(qpdf, [](qpdf_data q) {
1768 q->qpdf->pushInheritedAttributesToPage();
1769 });
1770 }
1771
qpdf_add_page(qpdf_data qpdf,qpdf_data newpage_qpdf,qpdf_oh newpage,QPDF_BOOL first)1772 QPDF_ERROR_CODE qpdf_add_page(
1773 qpdf_data qpdf, qpdf_data newpage_qpdf, qpdf_oh newpage, QPDF_BOOL first)
1774 {
1775 QTC::TC("qpdf", "qpdf-c called qpdf_add_page");
1776 auto page = qpdf_oh_item_internal(newpage_qpdf, newpage);
1777 return trap_errors(qpdf, [&page, first](qpdf_data q) {
1778 q->qpdf->addPage(page, first);
1779 });
1780 }
1781
qpdf_add_page_at(qpdf_data qpdf,qpdf_data newpage_qpdf,qpdf_oh newpage,QPDF_BOOL before,qpdf_oh refpage)1782 QPDF_ERROR_CODE qpdf_add_page_at(
1783 qpdf_data qpdf, qpdf_data newpage_qpdf, qpdf_oh newpage,
1784 QPDF_BOOL before, qpdf_oh refpage)
1785 {
1786 QTC::TC("qpdf", "qpdf-c called qpdf_add_page_at");
1787 auto page = qpdf_oh_item_internal(newpage_qpdf, newpage);
1788 auto ref = qpdf_oh_item_internal(qpdf, refpage);
1789 return trap_errors(qpdf, [&page, before, &ref](qpdf_data q) {
1790 q->qpdf->addPageAt(page, before, ref);
1791 });
1792 }
1793
qpdf_remove_page(qpdf_data qpdf,qpdf_oh page)1794 QPDF_ERROR_CODE qpdf_remove_page(qpdf_data qpdf, qpdf_oh page)
1795 {
1796 QTC::TC("qpdf", "qpdf-c called qpdf_remove_page");
1797 auto p = qpdf_oh_item_internal(qpdf, page);
1798 return trap_errors(qpdf, [&p](qpdf_data q) {
1799 q->qpdf->removePage(p);
1800 });
1801 }
1802