Commit a72ce95c922228e624e47bb43a68c55a9dd8eab2
1 parent
9f444ffe
setOutputStreams
git-svn-id: svn+q:///qpdf/trunk@1035 71b93d88-0707-0410-a8cf-f5a4172ac649
Showing
11 changed files
with
276 additions
and
45 deletions
ChangeLog
| 1 | 2010-10-01 Jay Berkenbilt <ejb@ql.org> | 1 | 2010-10-01 Jay Berkenbilt <ejb@ql.org> |
| 2 | 2 | ||
| 3 | + * include/qpdf/QPDF.hh: Add setOutputStreams method to allow | ||
| 4 | + redirection of library-generated output/error to alternative | ||
| 5 | + streams. | ||
| 6 | + | ||
| 3 | * include/qpdf/QPDF.hh: Add processMemoryFile method for | 7 | * include/qpdf/QPDF.hh: Add processMemoryFile method for |
| 4 | processing a PDF file from a memory buffer instead of a file. | 8 | processing a PDF file from a memory buffer instead of a file. |
| 5 | 9 |
TODO
| 1 | -General | ||
| 2 | -======= | 1 | +2.2.1 |
| 2 | +===== | ||
| 3 | + | ||
| 4 | + * Remove cerr and cout from QPDF*.cc | ||
| 3 | 5 | ||
| 4 | * QPDF::checkLinearization writes things to std::cout, which makes it | 6 | * QPDF::checkLinearization writes things to std::cout, which makes it |
| 5 | hard for GUIs that want to display the result. Go through all | 7 | hard for GUIs that want to display the result. Go through all |
| @@ -12,6 +14,10 @@ General | @@ -12,6 +14,10 @@ General | ||
| 12 | rethrow if needed. The old version should call the ostream version | 14 | rethrow if needed. The old version should call the ostream version |
| 13 | with std::cout. | 15 | with std::cout. |
| 14 | 16 | ||
| 17 | + | ||
| 18 | +General | ||
| 19 | +======= | ||
| 20 | + | ||
| 15 | * In general, take a fresh look at private methods to see which, if | 21 | * In general, take a fresh look at private methods to see which, if |
| 16 | any, should be protected. | 22 | any, should be protected. |
| 17 | 23 |
include/qpdf/QPDF.hh
| @@ -12,6 +12,7 @@ | @@ -12,6 +12,7 @@ | ||
| 12 | #include <string> | 12 | #include <string> |
| 13 | #include <map> | 13 | #include <map> |
| 14 | #include <list> | 14 | #include <list> |
| 15 | +#include <iostream> | ||
| 15 | 16 | ||
| 16 | #include <qpdf/DLL.h> | 17 | #include <qpdf/DLL.h> |
| 17 | 18 | ||
| @@ -61,6 +62,21 @@ class QPDF | @@ -61,6 +62,21 @@ class QPDF | ||
| 61 | 62 | ||
| 62 | // Parameter settings | 63 | // Parameter settings |
| 63 | 64 | ||
| 65 | + // By default, warning messages are issued to std::cerr and output | ||
| 66 | + // messages printed by certain check calls are issued to | ||
| 67 | + // std::cout. This method allows you to specify alternative | ||
| 68 | + // streams for this purpose. Note that no normal QPDF operations | ||
| 69 | + // generate output to std::cout, so for applications that just | ||
| 70 | + // wish to avoid creating output and don't call any check | ||
| 71 | + // functions, calling setSuppressWarnings(true) is sufficient. | ||
| 72 | + // Applications that wish to present check or warning information | ||
| 73 | + // to users may replace the output and error streams to capture | ||
| 74 | + // the output and errors for other use. A null value for either | ||
| 75 | + // stream will cause QPDF to use std::cout or std::cerr as | ||
| 76 | + // appropriate. | ||
| 77 | + QPDF_DLL | ||
| 78 | + void setOutputStreams(std::ostream* out_stream, std::ostream* err_stream); | ||
| 79 | + | ||
| 64 | // If true, ignore any cross-reference streams in a hybrid file | 80 | // If true, ignore any cross-reference streams in a hybrid file |
| 65 | // (one that contains both cross-reference streams and | 81 | // (one that contains both cross-reference streams and |
| 66 | // cross-reference tables). This can be useful for testing to | 82 | // cross-reference tables). This can be useful for testing to |
| @@ -68,7 +84,8 @@ class QPDF | @@ -68,7 +84,8 @@ class QPDF | ||
| 68 | QPDF_DLL | 84 | QPDF_DLL |
| 69 | void setIgnoreXRefStreams(bool); | 85 | void setIgnoreXRefStreams(bool); |
| 70 | 86 | ||
| 71 | - // By default, any warnings are issued to stderr as they are | 87 | + // By default, any warnings are issued to std::cerr or the error |
| 88 | + // stream specified in a call to setOutputStreams as they are | ||
| 72 | // encountered. If this is called with a true value, reporting of | 89 | // encountered. If this is called with a true value, reporting of |
| 73 | // warnings is suppressed. You may still retrieve warnings by | 90 | // warnings is suppressed. You may still retrieve warnings by |
| 74 | // calling getWarnings. | 91 | // calling getWarnings. |
| @@ -88,7 +105,7 @@ class QPDF | @@ -88,7 +105,7 @@ class QPDF | ||
| 88 | // clear the list. This method may be called even if processFile | 105 | // clear the list. This method may be called even if processFile |
| 89 | // throws an exception. Note that if setSuppressWarnings was not | 106 | // throws an exception. Note that if setSuppressWarnings was not |
| 90 | // called or was called with a false value, any warnings retrieved | 107 | // called or was called with a false value, any warnings retrieved |
| 91 | - // here will have already been issued to stderr. | 108 | + // here will have already been output. |
| 92 | QPDF_DLL | 109 | QPDF_DLL |
| 93 | std::vector<QPDFExc> getWarnings(); | 110 | std::vector<QPDFExc> getWarnings(); |
| 94 | 111 | ||
| @@ -204,12 +221,14 @@ class QPDF | @@ -204,12 +221,14 @@ class QPDF | ||
| 204 | 221 | ||
| 205 | // Performs various sanity checks on a linearized file. Return | 222 | // Performs various sanity checks on a linearized file. Return |
| 206 | // true if no errors or warnings. Otherwise, return false and | 223 | // true if no errors or warnings. Otherwise, return false and |
| 207 | - // output errors and warnings to stdout. | 224 | + // output errors and warnings to std::cout or the output stream |
| 225 | + // specified in a call to setOutputStreams. | ||
| 208 | QPDF_DLL | 226 | QPDF_DLL |
| 209 | bool checkLinearization(); | 227 | bool checkLinearization(); |
| 210 | 228 | ||
| 211 | // Calls checkLinearization() and, if possible, prints normalized | 229 | // Calls checkLinearization() and, if possible, prints normalized |
| 212 | - // contents of some of the hints tables to stdout. Normalization | 230 | + // contents of some of the hints tables to std::cout or the output |
| 231 | + // stream specified in a call to setOutputStreams. Normalization | ||
| 213 | // includes adding min values to delta values and adjusting | 232 | // includes adding min values to delta values and adjusting |
| 214 | // offsets based on the location and size of the primary hint | 233 | // offsets based on the location and size of the primary hint |
| 215 | // stream. | 234 | // stream. |
| @@ -803,6 +822,8 @@ class QPDF | @@ -803,6 +822,8 @@ class QPDF | ||
| 803 | bool encryption_initialized; | 822 | bool encryption_initialized; |
| 804 | bool ignore_xref_streams; | 823 | bool ignore_xref_streams; |
| 805 | bool suppress_warnings; | 824 | bool suppress_warnings; |
| 825 | + std::ostream* out_stream; | ||
| 826 | + std::ostream* err_stream; | ||
| 806 | bool attempt_recovery; | 827 | bool attempt_recovery; |
| 807 | int encryption_V; | 828 | int encryption_V; |
| 808 | bool encrypt_metadata; | 829 | bool encrypt_metadata; |
libqpdf/QPDF.cc
| @@ -267,6 +267,8 @@ QPDF::QPDF() : | @@ -267,6 +267,8 @@ QPDF::QPDF() : | ||
| 267 | encryption_initialized(false), | 267 | encryption_initialized(false), |
| 268 | ignore_xref_streams(false), | 268 | ignore_xref_streams(false), |
| 269 | suppress_warnings(false), | 269 | suppress_warnings(false), |
| 270 | + out_stream(&std::cout), | ||
| 271 | + err_stream(&std::cerr), | ||
| 270 | attempt_recovery(true), | 272 | attempt_recovery(true), |
| 271 | encryption_V(0), | 273 | encryption_V(0), |
| 272 | encrypt_metadata(true), | 274 | encrypt_metadata(true), |
| @@ -333,6 +335,13 @@ QPDF::setIgnoreXRefStreams(bool val) | @@ -333,6 +335,13 @@ QPDF::setIgnoreXRefStreams(bool val) | ||
| 333 | } | 335 | } |
| 334 | 336 | ||
| 335 | void | 337 | void |
| 338 | +QPDF::setOutputStreams(std::ostream* out, std::ostream* err) | ||
| 339 | +{ | ||
| 340 | + this->out_stream = out ? out : &std::cout; | ||
| 341 | + this->err_stream = err ? err : &std::cerr; | ||
| 342 | +} | ||
| 343 | + | ||
| 344 | +void | ||
| 336 | QPDF::setSuppressWarnings(bool val) | 345 | QPDF::setSuppressWarnings(bool val) |
| 337 | { | 346 | { |
| 338 | this->suppress_warnings = val; | 347 | this->suppress_warnings = val; |
| @@ -449,7 +458,8 @@ QPDF::warn(QPDFExc const& e) | @@ -449,7 +458,8 @@ QPDF::warn(QPDFExc const& e) | ||
| 449 | this->warnings.push_back(e); | 458 | this->warnings.push_back(e); |
| 450 | if (! this->suppress_warnings) | 459 | if (! this->suppress_warnings) |
| 451 | { | 460 | { |
| 452 | - std::cerr << "WARNING: " << this->warnings.back().what() << std::endl; | 461 | + *err_stream << "WARNING: " |
| 462 | + << this->warnings.back().what() << std::endl; | ||
| 453 | } | 463 | } |
| 454 | } | 464 | } |
| 455 | 465 | ||
| @@ -1045,16 +1055,16 @@ QPDF::showXRefTable() | @@ -1045,16 +1055,16 @@ QPDF::showXRefTable() | ||
| 1045 | { | 1055 | { |
| 1046 | ObjGen const& og = (*iter).first; | 1056 | ObjGen const& og = (*iter).first; |
| 1047 | QPDFXRefEntry const& entry = (*iter).second; | 1057 | QPDFXRefEntry const& entry = (*iter).second; |
| 1048 | - std::cout << og.obj << "/" << og.gen << ": "; | 1058 | + *out_stream << og.obj << "/" << og.gen << ": "; |
| 1049 | switch (entry.getType()) | 1059 | switch (entry.getType()) |
| 1050 | { | 1060 | { |
| 1051 | case 1: | 1061 | case 1: |
| 1052 | - std::cout << "uncompressed; offset = " << entry.getOffset(); | 1062 | + *out_stream << "uncompressed; offset = " << entry.getOffset(); |
| 1053 | break; | 1063 | break; |
| 1054 | 1064 | ||
| 1055 | case 2: | 1065 | case 2: |
| 1056 | - std::cout << "compressed; stream = " << entry.getObjStreamNumber() | ||
| 1057 | - << ", index = " << entry.getObjStreamIndex(); | 1066 | + *out_stream << "compressed; stream = " << entry.getObjStreamNumber() |
| 1067 | + << ", index = " << entry.getObjStreamIndex(); | ||
| 1058 | break; | 1068 | break; |
| 1059 | 1069 | ||
| 1060 | default: | 1070 | default: |
| @@ -1062,7 +1072,7 @@ QPDF::showXRefTable() | @@ -1062,7 +1072,7 @@ QPDF::showXRefTable() | ||
| 1062 | " showing xref_table"); | 1072 | " showing xref_table"); |
| 1063 | break; | 1073 | break; |
| 1064 | } | 1074 | } |
| 1065 | - std::cout << std::endl; | 1075 | + *out_stream << std::endl; |
| 1066 | } | 1076 | } |
| 1067 | } | 1077 | } |
| 1068 | 1078 |
libqpdf/QPDF_linearization.cc
| @@ -64,7 +64,7 @@ QPDF::checkLinearization() | @@ -64,7 +64,7 @@ QPDF::checkLinearization() | ||
| 64 | } | 64 | } |
| 65 | catch (QPDFExc& e) | 65 | catch (QPDFExc& e) |
| 66 | { | 66 | { |
| 67 | - std::cout << e.what() << std::endl; | 67 | + *out_stream << e.what() << std::endl; |
| 68 | } | 68 | } |
| 69 | return result; | 69 | return result; |
| 70 | } | 70 | } |
| @@ -351,9 +351,9 @@ QPDF::readHintStream(Pipeline& pl, off_t offset, size_t length) | @@ -351,9 +351,9 @@ QPDF::readHintStream(Pipeline& pl, off_t offset, size_t length) | ||
| 351 | if ((computed_end < min_end_offset) || | 351 | if ((computed_end < min_end_offset) || |
| 352 | (computed_end > max_end_offset)) | 352 | (computed_end > max_end_offset)) |
| 353 | { | 353 | { |
| 354 | - std::cout << "expected = " << computed_end | ||
| 355 | - << "; actual = " << min_end_offset << ".." | ||
| 356 | - << max_end_offset << std::endl; | 354 | + *out_stream << "expected = " << computed_end |
| 355 | + << "; actual = " << min_end_offset << ".." | ||
| 356 | + << max_end_offset << std::endl; | ||
| 357 | throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), | 357 | throw QPDFExc(qpdf_e_damaged_pdf, this->file->getName(), |
| 358 | "linearization dictionary", | 358 | "linearization dictionary", |
| 359 | this->file->getLastOffset(), | 359 | this->file->getLastOffset(), |
| @@ -617,7 +617,7 @@ QPDF::checkLinearizationInternal() | @@ -617,7 +617,7 @@ QPDF::checkLinearizationInternal() | ||
| 617 | for (std::list<std::string>::iterator iter = errors.begin(); | 617 | for (std::list<std::string>::iterator iter = errors.begin(); |
| 618 | iter != errors.end(); ++iter) | 618 | iter != errors.end(); ++iter) |
| 619 | { | 619 | { |
| 620 | - std::cout << "ERROR: " << (*iter) << std::endl; | 620 | + *out_stream << "ERROR: " << (*iter) << std::endl; |
| 621 | } | 621 | } |
| 622 | } | 622 | } |
| 623 | 623 | ||
| @@ -627,7 +627,7 @@ QPDF::checkLinearizationInternal() | @@ -627,7 +627,7 @@ QPDF::checkLinearizationInternal() | ||
| 627 | for (std::list<std::string>::iterator iter = warnings.begin(); | 627 | for (std::list<std::string>::iterator iter = warnings.begin(); |
| 628 | iter != warnings.end(); ++iter) | 628 | iter != warnings.end(); ++iter) |
| 629 | { | 629 | { |
| 630 | - std::cout << "WARNING: " << (*iter) << std::endl; | 630 | + *out_stream << "WARNING: " << (*iter) << std::endl; |
| 631 | } | 631 | } |
| 632 | } | 632 | } |
| 633 | 633 | ||
| @@ -1008,17 +1008,17 @@ QPDF::showLinearizationData() | @@ -1008,17 +1008,17 @@ QPDF::showLinearizationData() | ||
| 1008 | } | 1008 | } |
| 1009 | catch (QPDFExc& e) | 1009 | catch (QPDFExc& e) |
| 1010 | { | 1010 | { |
| 1011 | - std::cout << e.what() << std::endl; | 1011 | + *out_stream << e.what() << std::endl; |
| 1012 | } | 1012 | } |
| 1013 | } | 1013 | } |
| 1014 | 1014 | ||
| 1015 | void | 1015 | void |
| 1016 | QPDF::dumpLinearizationDataInternal() | 1016 | QPDF::dumpLinearizationDataInternal() |
| 1017 | { | 1017 | { |
| 1018 | - std::cout << this->file->getName() << ": linearization data:" << std::endl | ||
| 1019 | - << std::endl; | 1018 | + *out_stream << this->file->getName() << ": linearization data:" << std::endl |
| 1019 | + << std::endl; | ||
| 1020 | 1020 | ||
| 1021 | - std::cout | 1021 | + *out_stream |
| 1022 | << "file_size: " << this->linp.file_size << std::endl | 1022 | << "file_size: " << this->linp.file_size << std::endl |
| 1023 | << "first_page_object: " << this->linp.first_page_object << std::endl | 1023 | << "first_page_object: " << this->linp.first_page_object << std::endl |
| 1024 | << "first_page_end: " << this->linp.first_page_end << std::endl | 1024 | << "first_page_end: " << this->linp.first_page_end << std::endl |
| @@ -1029,19 +1029,19 @@ QPDF::dumpLinearizationDataInternal() | @@ -1029,19 +1029,19 @@ QPDF::dumpLinearizationDataInternal() | ||
| 1029 | << "H_length: " << this->linp.H_length << std::endl | 1029 | << "H_length: " << this->linp.H_length << std::endl |
| 1030 | << std::endl; | 1030 | << std::endl; |
| 1031 | 1031 | ||
| 1032 | - std::cout << "Page Offsets Hint Table" << std::endl | ||
| 1033 | - << std::endl; | 1032 | + *out_stream << "Page Offsets Hint Table" << std::endl |
| 1033 | + << std::endl; | ||
| 1034 | dumpHPageOffset(); | 1034 | dumpHPageOffset(); |
| 1035 | - std::cout << std::endl | ||
| 1036 | - << "Shared Objects Hint Table" << std::endl | ||
| 1037 | - << std::endl; | 1035 | + *out_stream << std::endl |
| 1036 | + << "Shared Objects Hint Table" << std::endl | ||
| 1037 | + << std::endl; | ||
| 1038 | dumpHSharedObject(); | 1038 | dumpHSharedObject(); |
| 1039 | 1039 | ||
| 1040 | if (this->outline_hints.nobjects > 0) | 1040 | if (this->outline_hints.nobjects > 0) |
| 1041 | { | 1041 | { |
| 1042 | - std::cout << std::endl | ||
| 1043 | - << "Outlines Hint Table" << std::endl | ||
| 1044 | - << std::endl; | 1042 | + *out_stream << std::endl |
| 1043 | + << "Outlines Hint Table" << std::endl | ||
| 1044 | + << std::endl; | ||
| 1045 | dumpHGeneric(this->outline_hints); | 1045 | dumpHGeneric(this->outline_hints); |
| 1046 | } | 1046 | } |
| 1047 | } | 1047 | } |
| @@ -1064,7 +1064,7 @@ void | @@ -1064,7 +1064,7 @@ void | ||
| 1064 | QPDF::dumpHPageOffset() | 1064 | QPDF::dumpHPageOffset() |
| 1065 | { | 1065 | { |
| 1066 | HPageOffset& t = this->page_offset_hints; | 1066 | HPageOffset& t = this->page_offset_hints; |
| 1067 | - std::cout | 1067 | + *out_stream |
| 1068 | << "min_nobjects: " << t.min_nobjects | 1068 | << "min_nobjects: " << t.min_nobjects |
| 1069 | << std::endl | 1069 | << std::endl |
| 1070 | << "first_page_offset: " << adjusted_offset(t.first_page_offset) | 1070 | << "first_page_offset: " << adjusted_offset(t.first_page_offset) |
| @@ -1095,7 +1095,7 @@ QPDF::dumpHPageOffset() | @@ -1095,7 +1095,7 @@ QPDF::dumpHPageOffset() | ||
| 1095 | for (int i1 = 0; i1 < this->linp.npages; ++i1) | 1095 | for (int i1 = 0; i1 < this->linp.npages; ++i1) |
| 1096 | { | 1096 | { |
| 1097 | HPageOffsetEntry& pe = t.entries[i1]; | 1097 | HPageOffsetEntry& pe = t.entries[i1]; |
| 1098 | - std::cout | 1098 | + *out_stream |
| 1099 | << "Page " << i1 << ":" << std::endl | 1099 | << "Page " << i1 << ":" << std::endl |
| 1100 | << " nobjects: " << pe.delta_nobjects + t.min_nobjects | 1100 | << " nobjects: " << pe.delta_nobjects + t.min_nobjects |
| 1101 | << std::endl | 1101 | << std::endl |
| @@ -1109,10 +1109,10 @@ QPDF::dumpHPageOffset() | @@ -1109,10 +1109,10 @@ QPDF::dumpHPageOffset() | ||
| 1109 | << " nshared_objects: " << pe.nshared_objects << std::endl; | 1109 | << " nshared_objects: " << pe.nshared_objects << std::endl; |
| 1110 | for (int i2 = 0; i2 < pe.nshared_objects; ++i2) | 1110 | for (int i2 = 0; i2 < pe.nshared_objects; ++i2) |
| 1111 | { | 1111 | { |
| 1112 | - std::cout << " identifier " << i2 << ": " | ||
| 1113 | - << pe.shared_identifiers[i2] << std::endl; | ||
| 1114 | - std::cout << " numerator " << i2 << ": " | ||
| 1115 | - << pe.shared_numerators[i2] << std::endl; | 1112 | + *out_stream << " identifier " << i2 << ": " |
| 1113 | + << pe.shared_identifiers[i2] << std::endl; | ||
| 1114 | + *out_stream << " numerator " << i2 << ": " | ||
| 1115 | + << pe.shared_numerators[i2] << std::endl; | ||
| 1116 | } | 1116 | } |
| 1117 | } | 1117 | } |
| 1118 | } | 1118 | } |
| @@ -1121,7 +1121,7 @@ void | @@ -1121,7 +1121,7 @@ void | ||
| 1121 | QPDF::dumpHSharedObject() | 1121 | QPDF::dumpHSharedObject() |
| 1122 | { | 1122 | { |
| 1123 | HSharedObject& t = this->shared_object_hints; | 1123 | HSharedObject& t = this->shared_object_hints; |
| 1124 | - std::cout | 1124 | + *out_stream |
| 1125 | << "first_shared_obj: " << t.first_shared_obj | 1125 | << "first_shared_obj: " << t.first_shared_obj |
| 1126 | << std::endl | 1126 | << std::endl |
| 1127 | << "first_shared_offset: " << adjusted_offset(t.first_shared_offset) | 1127 | << "first_shared_offset: " << adjusted_offset(t.first_shared_offset) |
| @@ -1140,19 +1140,19 @@ QPDF::dumpHSharedObject() | @@ -1140,19 +1140,19 @@ QPDF::dumpHSharedObject() | ||
| 1140 | for (int i = 0; i < t.nshared_total; ++i) | 1140 | for (int i = 0; i < t.nshared_total; ++i) |
| 1141 | { | 1141 | { |
| 1142 | HSharedObjectEntry& se = t.entries[i]; | 1142 | HSharedObjectEntry& se = t.entries[i]; |
| 1143 | - std::cout << "Shared Object " << i << ":" << std::endl; | ||
| 1144 | - std::cout << " group length: " | ||
| 1145 | - << se.delta_group_length + t.min_group_length << std::endl; | 1143 | + *out_stream << "Shared Object " << i << ":" << std::endl; |
| 1144 | + *out_stream << " group length: " | ||
| 1145 | + << se.delta_group_length + t.min_group_length << std::endl; | ||
| 1146 | // PDF spec says signature present nobjects_minus_one are | 1146 | // PDF spec says signature present nobjects_minus_one are |
| 1147 | // always 0, so print them only if they have a non-zero value. | 1147 | // always 0, so print them only if they have a non-zero value. |
| 1148 | if (se.signature_present) | 1148 | if (se.signature_present) |
| 1149 | { | 1149 | { |
| 1150 | - std::cout << " signature present" << std::endl; | 1150 | + *out_stream << " signature present" << std::endl; |
| 1151 | } | 1151 | } |
| 1152 | if (se.nobjects_minus_one != 0) | 1152 | if (se.nobjects_minus_one != 0) |
| 1153 | { | 1153 | { |
| 1154 | - std::cout << " nobjects: " | ||
| 1155 | - << se.nobjects_minus_one + 1 << std::endl; | 1154 | + *out_stream << " nobjects: " |
| 1155 | + << se.nobjects_minus_one + 1 << std::endl; | ||
| 1156 | } | 1156 | } |
| 1157 | } | 1157 | } |
| 1158 | } | 1158 | } |
| @@ -1160,7 +1160,7 @@ QPDF::dumpHSharedObject() | @@ -1160,7 +1160,7 @@ QPDF::dumpHSharedObject() | ||
| 1160 | void | 1160 | void |
| 1161 | QPDF::dumpHGeneric(HGeneric& t) | 1161 | QPDF::dumpHGeneric(HGeneric& t) |
| 1162 | { | 1162 | { |
| 1163 | - std::cout | 1163 | + *out_stream |
| 1164 | << "first_object: " << t.first_object | 1164 | << "first_object: " << t.first_object |
| 1165 | << std::endl | 1165 | << std::endl |
| 1166 | << "first_object_offset: " << adjusted_offset(t.first_object_offset) | 1166 | << "first_object_offset: " << adjusted_offset(t.first_object_offset) |
manual/qpdf-manual.xml
| @@ -2075,6 +2075,61 @@ print "\n"; | @@ -2075,6 +2075,61 @@ print "\n"; | ||
| 2075 | </para> | 2075 | </para> |
| 2076 | <variablelist> | 2076 | <variablelist> |
| 2077 | <varlistentry> | 2077 | <varlistentry> |
| 2078 | + <term>2.2.1: XXX</term> | ||
| 2079 | + <listitem> | ||
| 2080 | + <itemizedlist> | ||
| 2081 | + <listitem> | ||
| 2082 | + <para> | ||
| 2083 | + Add new method <classname>QPDF::processMemoryFile</classname> | ||
| 2084 | + for operating on PDF files that are loaded into memory rather | ||
| 2085 | + than in a file on disk. | ||
| 2086 | + </para> | ||
| 2087 | + </listitem> | ||
| 2088 | + <listitem> | ||
| 2089 | + <para> | ||
| 2090 | + Add new method <classname>QPDF::setOutputStreams</classname> | ||
| 2091 | + to replace <varname>std::cout</varname> and | ||
| 2092 | + <varname>std::cerr</varname> with other streams for generation | ||
| 2093 | + of diagnostic messages and error messages. This can be useful | ||
| 2094 | + for GUIs or other applications that want to capture any output | ||
| 2095 | + generated by the library to present to the user in some other | ||
| 2096 | + way. Note that QPDF does not write to | ||
| 2097 | + <varname>std::cout</varname> (or the specified output stream) | ||
| 2098 | + except where explicitly mentioned in | ||
| 2099 | + <filename>QPDF.hh</filename>, and that the only use of the | ||
| 2100 | + error stream is for warnings. Note also that output of | ||
| 2101 | + warnings is suppressed when | ||
| 2102 | + <literal>setSuppressWarnings(true)</literal> is called. | ||
| 2103 | + </para> | ||
| 2104 | + </listitem> | ||
| 2105 | + <listitem> | ||
| 2106 | + <para> | ||
| 2107 | + Give a warning but otherwise ignore empty PDF objects by | ||
| 2108 | + treating them as null. Empty object are not permitted by the | ||
| 2109 | + PDF specification but have been known to appear in some actual | ||
| 2110 | + PDF files. | ||
| 2111 | + </para> | ||
| 2112 | + </listitem> | ||
| 2113 | + <listitem> | ||
| 2114 | + <para> | ||
| 2115 | + Handle inline image filter abbreviations when the appear as | ||
| 2116 | + stream filter abbreviations. The PDF specification does not | ||
| 2117 | + allow use of stream filter abbreviations in this way, but | ||
| 2118 | + Adobe Reader and some other PDF readers accept them since they | ||
| 2119 | + sometimes appear incorrectly in actual PDF files. | ||
| 2120 | + </para> | ||
| 2121 | + </listitem> | ||
| 2122 | + <listitem> | ||
| 2123 | + <para> | ||
| 2124 | + Implement miscellaneous enhancements to | ||
| 2125 | + <classname>PointerHolder</classname> and | ||
| 2126 | + <classname>Buffer</classname> to support other changes. | ||
| 2127 | + </para> | ||
| 2128 | + </listitem> | ||
| 2129 | + </itemizedlist> | ||
| 2130 | + </listitem> | ||
| 2131 | + </varlistentry> | ||
| 2132 | + <varlistentry> | ||
| 2078 | <term>2.2.0: August 14, 2010</term> | 2133 | <term>2.2.0: August 14, 2010</term> |
| 2079 | <listitem> | 2134 | <listitem> |
| 2080 | <itemizedlist> | 2135 | <itemizedlist> |
qpdf/qtest/qpdf.test
| @@ -111,7 +111,7 @@ $td->runtest("new stream", | @@ -111,7 +111,7 @@ $td->runtest("new stream", | ||
| 111 | show_ntests(); | 111 | show_ntests(); |
| 112 | # ---------- | 112 | # ---------- |
| 113 | $td->notify("--- Miscellaneous Tests ---"); | 113 | $td->notify("--- Miscellaneous Tests ---"); |
| 114 | -$n_tests += 26; | 114 | +$n_tests += 28; |
| 115 | 115 | ||
| 116 | $td->runtest("qpdf version", | 116 | $td->runtest("qpdf version", |
| 117 | {$td->COMMAND => "qpdf --version"}, | 117 | {$td->COMMAND => "qpdf --version"}, |
| @@ -245,6 +245,18 @@ $td->runtest("empty object", | @@ -245,6 +245,18 @@ $td->runtest("empty object", | ||
| 245 | $td->EXIT_STATUS => 3}, | 245 | $td->EXIT_STATUS => 3}, |
| 246 | $td->NORMALIZE_NEWLINES); | 246 | $td->NORMALIZE_NEWLINES); |
| 247 | 247 | ||
| 248 | +$td->runtest("error/output redirection to null", | ||
| 249 | + {$td->COMMAND => "test_driver 12 linearized-and-warnings.pdf"}, | ||
| 250 | + {$td->FILE => "linearized-and-warnings-1.out", | ||
| 251 | + $td->EXIT_STATUS => 0}, | ||
| 252 | + $td->NORMALIZE_NEWLINES); | ||
| 253 | + | ||
| 254 | +$td->runtest("error/output redirection to strings", | ||
| 255 | + {$td->COMMAND => "test_driver 13 linearized-and-warnings.pdf"}, | ||
| 256 | + {$td->FILE => "linearized-and-warnings-2.out", | ||
| 257 | + $td->EXIT_STATUS => 0}, | ||
| 258 | + $td->NORMALIZE_NEWLINES); | ||
| 259 | + | ||
| 248 | show_ntests(); | 260 | show_ntests(); |
| 249 | # ---------- | 261 | # ---------- |
| 250 | $td->notify("--- Error Condition Tests ---"); | 262 | $td->notify("--- Error Condition Tests ---"); |
qpdf/qtest/qpdf/linearized-and-warnings-1.out
0 → 100644
| 1 | +WARNING: linearized-and-warnings.pdf (object 2 0, file position 1117): empty object treated as null | ||
| 2 | +linearized-and-warnings.pdf: linearization data: | ||
| 3 | + | ||
| 4 | +file_size: 1310 | ||
| 5 | +first_page_object: 6 | ||
| 6 | +first_page_end: 1044 | ||
| 7 | +npages: 1 | ||
| 8 | +xref_zero_offset: 1132 | ||
| 9 | +first_page: 0 | ||
| 10 | +H_offset: 528 | ||
| 11 | +H_length: 118 | ||
| 12 | + | ||
| 13 | +Page Offsets Hint Table | ||
| 14 | + | ||
| 15 | +min_nobjects: 4 | ||
| 16 | +first_page_offset: 646 | ||
| 17 | +nbits_delta_nobjects: 0 | ||
| 18 | +min_page_length: 398 | ||
| 19 | +nbits_delta_page_length: 0 | ||
| 20 | +min_content_offset: 0 | ||
| 21 | +nbits_delta_content_offset: 0 | ||
| 22 | +min_content_length: 398 | ||
| 23 | +nbits_delta_content_length: 0 | ||
| 24 | +nbits_nshared_objects: 0 | ||
| 25 | +nbits_shared_identifier: 3 | ||
| 26 | +nbits_shared_numerator: 0 | ||
| 27 | +shared_denominator: 4 | ||
| 28 | +Page 0: | ||
| 29 | + nobjects: 4 | ||
| 30 | + length: 398 | ||
| 31 | + content_offset: 0 | ||
| 32 | + content_length: 398 | ||
| 33 | + nshared_objects: 0 | ||
| 34 | + | ||
| 35 | +Shared Objects Hint Table | ||
| 36 | + | ||
| 37 | +first_shared_obj: 0 | ||
| 38 | +first_shared_offset: 0 | ||
| 39 | +nshared_first_page: 4 | ||
| 40 | +nshared_total: 4 | ||
| 41 | +nbits_nobjects: 0 | ||
| 42 | +min_group_length: 30 | ||
| 43 | +nbits_delta_group_length: 7 | ||
| 44 | +Shared Object 0: | ||
| 45 | + group length: 143 | ||
| 46 | +Shared Object 1: | ||
| 47 | + group length: 118 | ||
| 48 | +Shared Object 2: | ||
| 49 | + group length: 30 | ||
| 50 | +Shared Object 3: | ||
| 51 | + group length: 107 | ||
| 52 | +test 12 done |
qpdf/qtest/qpdf/linearized-and-warnings-2.out
0 → 100644
| 1 | +---output--- | ||
| 2 | +linearized-and-warnings.pdf: linearization data: | ||
| 3 | + | ||
| 4 | +file_size: 1310 | ||
| 5 | +first_page_object: 6 | ||
| 6 | +first_page_end: 1044 | ||
| 7 | +npages: 1 | ||
| 8 | +xref_zero_offset: 1132 | ||
| 9 | +first_page: 0 | ||
| 10 | +H_offset: 528 | ||
| 11 | +H_length: 118 | ||
| 12 | + | ||
| 13 | +Page Offsets Hint Table | ||
| 14 | + | ||
| 15 | +min_nobjects: 4 | ||
| 16 | +first_page_offset: 646 | ||
| 17 | +nbits_delta_nobjects: 0 | ||
| 18 | +min_page_length: 398 | ||
| 19 | +nbits_delta_page_length: 0 | ||
| 20 | +min_content_offset: 0 | ||
| 21 | +nbits_delta_content_offset: 0 | ||
| 22 | +min_content_length: 398 | ||
| 23 | +nbits_delta_content_length: 0 | ||
| 24 | +nbits_nshared_objects: 0 | ||
| 25 | +nbits_shared_identifier: 3 | ||
| 26 | +nbits_shared_numerator: 0 | ||
| 27 | +shared_denominator: 4 | ||
| 28 | +Page 0: | ||
| 29 | + nobjects: 4 | ||
| 30 | + length: 398 | ||
| 31 | + content_offset: 0 | ||
| 32 | + content_length: 398 | ||
| 33 | + nshared_objects: 0 | ||
| 34 | + | ||
| 35 | +Shared Objects Hint Table | ||
| 36 | + | ||
| 37 | +first_shared_obj: 0 | ||
| 38 | +first_shared_offset: 0 | ||
| 39 | +nshared_first_page: 4 | ||
| 40 | +nshared_total: 4 | ||
| 41 | +nbits_nobjects: 0 | ||
| 42 | +min_group_length: 30 | ||
| 43 | +nbits_delta_group_length: 7 | ||
| 44 | +Shared Object 0: | ||
| 45 | + group length: 143 | ||
| 46 | +Shared Object 1: | ||
| 47 | + group length: 118 | ||
| 48 | +Shared Object 2: | ||
| 49 | + group length: 30 | ||
| 50 | +Shared Object 3: | ||
| 51 | + group length: 107 | ||
| 52 | +---error--- | ||
| 53 | +WARNING: linearized-and-warnings.pdf (object 2 0, file position 1117): empty object treated as null | ||
| 54 | +test 13 done |
qpdf/qtest/qpdf/linearized-and-warnings.pdf
0 → 100644
No preview for this file type
qpdf/test_driver.cc
| @@ -10,6 +10,7 @@ | @@ -10,6 +10,7 @@ | ||
| 10 | #include <qpdf/Pl_Flate.hh> | 10 | #include <qpdf/Pl_Flate.hh> |
| 11 | #include <qpdf/QPDFWriter.hh> | 11 | #include <qpdf/QPDFWriter.hh> |
| 12 | #include <iostream> | 12 | #include <iostream> |
| 13 | +#include <sstream> | ||
| 13 | #include <stdio.h> | 14 | #include <stdio.h> |
| 14 | #include <string.h> | 15 | #include <string.h> |
| 15 | #include <stdlib.h> | 16 | #include <stdlib.h> |
| @@ -502,6 +503,22 @@ void runtest(int n, char const* filename) | @@ -502,6 +503,22 @@ void runtest(int n, char const* filename) | ||
| 502 | std::cout << "raw stream data okay" << std::endl; | 503 | std::cout << "raw stream data okay" << std::endl; |
| 503 | } | 504 | } |
| 504 | } | 505 | } |
| 506 | + else if (n == 12) | ||
| 507 | + { | ||
| 508 | + pdf.setOutputStreams(0, 0); | ||
| 509 | + pdf.showLinearizationData(); | ||
| 510 | + } | ||
| 511 | + else if (n == 13) | ||
| 512 | + { | ||
| 513 | + std::ostringstream out; | ||
| 514 | + std::ostringstream err; | ||
| 515 | + pdf.setOutputStreams(&out, &err); | ||
| 516 | + pdf.showLinearizationData(); | ||
| 517 | + std::cout << "---output---" << std::endl | ||
| 518 | + << out.str() | ||
| 519 | + << "---error---" << std::endl | ||
| 520 | + << err.str(); | ||
| 521 | + } | ||
| 505 | else | 522 | else |
| 506 | { | 523 | { |
| 507 | throw std::runtime_error(std::string("invalid test ") + | 524 | throw std::runtime_error(std::string("invalid test ") + |