Commit f8e6274a2e004e1b0f0bb5ac8f8fb0fb76f34c66

Authored by m-holger
1 parent d42fda60

Move QPDF inner class definitions to new QPDF_private.hh

include/qpdf/QPDF.hh
@@ -725,165 +725,14 @@ class QPDF @@ -725,165 +725,14 @@ class QPDF
725 void removePage(QPDFObjectHandle page); 725 void removePage(QPDFObjectHandle page);
726 // End legacy page helpers 726 // End legacy page helpers
727 727
728 - // Writer class is restricted to QPDFWriter so that only it can call certain methods.  
729 - class Writer  
730 - {  
731 - friend class QPDFWriter;  
732 -  
733 - private:  
734 - static void  
735 - optimize(  
736 - QPDF& qpdf,  
737 - QPDFWriter::ObjTable const& obj,  
738 - std::function<int(QPDFObjectHandle&)> skip_stream_parameters)  
739 - {  
740 - return qpdf.optimize(obj, skip_stream_parameters);  
741 - }  
742 -  
743 - static void  
744 - getLinearizedParts(  
745 - QPDF& qpdf,  
746 - QPDFWriter::ObjTable const& obj,  
747 - std::vector<QPDFObjectHandle>& part4,  
748 - std::vector<QPDFObjectHandle>& part6,  
749 - std::vector<QPDFObjectHandle>& part7,  
750 - std::vector<QPDFObjectHandle>& part8,  
751 - std::vector<QPDFObjectHandle>& part9)  
752 - {  
753 - qpdf.getLinearizedParts(obj, part4, part6, part7, part8, part9);  
754 - }  
755 -  
756 - static void  
757 - generateHintStream(  
758 - QPDF& qpdf,  
759 - QPDFWriter::NewObjTable const& new_obj,  
760 - QPDFWriter::ObjTable const& obj,  
761 - std::shared_ptr<Buffer>& hint_stream,  
762 - int& S,  
763 - int& O,  
764 - bool compressed)  
765 - {  
766 - return qpdf.generateHintStream(new_obj, obj, hint_stream, S, O, compressed);  
767 - }  
768 -  
769 - static std::vector<QPDFObjGen>  
770 - getCompressibleObjGens(QPDF& qpdf)  
771 - {  
772 - return qpdf.getCompressibleObjVector();  
773 - }  
774 -  
775 - static std::vector<bool>  
776 - getCompressibleObjSet(QPDF& qpdf)  
777 - {  
778 - return qpdf.getCompressibleObjSet();  
779 - }  
780 -  
781 - static std::map<QPDFObjGen, QPDFXRefEntry> const&  
782 - getXRefTable(QPDF& qpdf)  
783 - {  
784 - return qpdf.getXRefTableInternal();  
785 - } 728 + // End of the public API. The following classes and methods are for qpdf internal use only.
786 729
787 - static size_t  
788 - tableSize(QPDF& qpdf)  
789 - {  
790 - return qpdf.tableSize();  
791 - }  
792 - };  
793 -  
794 - // The Resolver class is restricted to QPDFObject so that only it can resolve indirect  
795 - // references.  
796 - class Resolver  
797 - {  
798 - friend class QPDFObject;  
799 - friend class QPDF_Unresolved;  
800 -  
801 - private:  
802 - static QPDFObject*  
803 - resolved(QPDF* qpdf, QPDFObjGen og)  
804 - {  
805 - return qpdf->resolve(og);  
806 - }  
807 - };  
808 -  
809 - // StreamCopier class is restricted to QPDFObjectHandle so it can copy stream data.  
810 - class StreamCopier  
811 - {  
812 - friend class QPDFObjectHandle;  
813 -  
814 - private:  
815 - static void  
816 - copyStreamData(QPDF* qpdf, QPDFObjectHandle const& dest, QPDFObjectHandle const& src)  
817 - {  
818 - qpdf->copyStreamData(dest, src);  
819 - }  
820 - };  
821 -  
822 - // The ParseGuard class allows QPDFParser to detect re-entrant parsing. It also provides  
823 - // special access to allow the parser to create unresolved objects and dangling references.  
824 - class ParseGuard  
825 - {  
826 - friend class QPDFParser;  
827 -  
828 - private:  
829 - ParseGuard(QPDF* qpdf) :  
830 - qpdf(qpdf)  
831 - {  
832 - if (qpdf) {  
833 - qpdf->inParse(true);  
834 - }  
835 - }  
836 -  
837 - static std::shared_ptr<QPDFObject>  
838 - getObject(QPDF* qpdf, int id, int gen, bool parse_pdf)  
839 - {  
840 - return qpdf->getObjectForParser(id, gen, parse_pdf);  
841 - }  
842 -  
843 - ~ParseGuard()  
844 - {  
845 - if (qpdf) {  
846 - qpdf->inParse(false);  
847 - }  
848 - }  
849 - QPDF* qpdf;  
850 - };  
851 -  
852 - // Pipe class is restricted to QPDF_Stream.  
853 - class Pipe  
854 - {  
855 - friend class QPDF_Stream;  
856 -  
857 - private:  
858 - static bool  
859 - pipeStreamData(  
860 - QPDF* qpdf,  
861 - QPDFObjGen const& og,  
862 - qpdf_offset_t offset,  
863 - size_t length,  
864 - QPDFObjectHandle dict,  
865 - Pipeline* pipeline,  
866 - bool suppress_warnings,  
867 - bool will_retry)  
868 - {  
869 - return qpdf->pipeStreamData(  
870 - og, offset, length, dict, pipeline, suppress_warnings, will_retry);  
871 - }  
872 - };  
873 -  
874 - // JobSetter class is restricted to QPDFJob.  
875 - class JobSetter  
876 - {  
877 - friend class QPDFJob;  
878 -  
879 - private:  
880 - // Enable enhanced warnings for pdf file checking.  
881 - static void  
882 - setCheckMode(QPDF& qpdf, bool val)  
883 - {  
884 - qpdf.m->check_mode = val;  
885 - }  
886 - }; 730 + class Writer;
  731 + class Resolver;
  732 + class StreamCopier;
  733 + class ParseGuard;
  734 + class Pipe;
  735 + class JobSetter;
887 736
888 // For testing only -- do not add to DLL 737 // For testing only -- do not add to DLL
889 static bool test_json_validators(); 738 static bool test_json_validators();
@@ -898,136 +747,13 @@ class QPDF @@ -898,136 +747,13 @@ class QPDF
898 747
899 static std::string const qpdf_version; 748 static std::string const qpdf_version;
900 749
901 - class ObjCache  
902 - {  
903 - public:  
904 - ObjCache() :  
905 - end_before_space(0),  
906 - end_after_space(0)  
907 - {  
908 - }  
909 - ObjCache(  
910 - std::shared_ptr<QPDFObject> object,  
911 - qpdf_offset_t end_before_space = 0,  
912 - qpdf_offset_t end_after_space = 0) :  
913 - object(object),  
914 - end_before_space(end_before_space),  
915 - end_after_space(end_after_space)  
916 - {  
917 - }  
918 -  
919 - std::shared_ptr<QPDFObject> object;  
920 - qpdf_offset_t end_before_space;  
921 - qpdf_offset_t end_after_space;  
922 - };  
923 -  
924 - class ObjCopier  
925 - {  
926 - public:  
927 - std::map<QPDFObjGen, QPDFObjectHandle> object_map;  
928 - std::vector<QPDFObjectHandle> to_copy;  
929 - QPDFObjGen::set visiting;  
930 - };  
931 -  
932 - class EncryptionParameters  
933 - {  
934 - friend class QPDF;  
935 -  
936 - public:  
937 - EncryptionParameters();  
938 -  
939 - private:  
940 - bool encrypted;  
941 - bool encryption_initialized;  
942 - int encryption_V;  
943 - int encryption_R;  
944 - bool encrypt_metadata;  
945 - std::map<std::string, encryption_method_e> crypt_filters;  
946 - encryption_method_e cf_stream;  
947 - encryption_method_e cf_string;  
948 - encryption_method_e cf_file;  
949 - std::string provided_password;  
950 - std::string user_password;  
951 - std::string encryption_key;  
952 - std::string cached_object_encryption_key;  
953 - QPDFObjGen cached_key_og;  
954 - bool user_password_matched;  
955 - bool owner_password_matched;  
956 - };  
957 -  
958 - class ForeignStreamData  
959 - {  
960 - friend class QPDF;  
961 -  
962 - public:  
963 - ForeignStreamData(  
964 - std::shared_ptr<EncryptionParameters> encp,  
965 - std::shared_ptr<InputSource> file,  
966 - QPDFObjGen const& foreign_og,  
967 - qpdf_offset_t offset,  
968 - size_t length,  
969 - QPDFObjectHandle local_dict);  
970 -  
971 - private:  
972 - std::shared_ptr<EncryptionParameters> encp;  
973 - std::shared_ptr<InputSource> file;  
974 - QPDFObjGen foreign_og;  
975 - qpdf_offset_t offset;  
976 - size_t length;  
977 - QPDFObjectHandle local_dict;  
978 - };  
979 -  
980 - class CopiedStreamDataProvider: public QPDFObjectHandle::StreamDataProvider  
981 - {  
982 - public:  
983 - CopiedStreamDataProvider(QPDF& destination_qpdf);  
984 - ~CopiedStreamDataProvider() override = default;  
985 - bool provideStreamData(  
986 - QPDFObjGen const& og,  
987 - Pipeline* pipeline,  
988 - bool suppress_warnings,  
989 - bool will_retry) override;  
990 - void registerForeignStream(QPDFObjGen const& local_og, QPDFObjectHandle foreign_stream);  
991 - void registerForeignStream(QPDFObjGen const& local_og, std::shared_ptr<ForeignStreamData>);  
992 -  
993 - private:  
994 - QPDF& destination_qpdf;  
995 - std::map<QPDFObjGen, QPDFObjectHandle> foreign_streams;  
996 - std::map<QPDFObjGen, std::shared_ptr<ForeignStreamData>> foreign_stream_data;  
997 - };  
998 -  
999 - class StringDecrypter: public QPDFObjectHandle::StringDecrypter  
1000 - {  
1001 - friend class QPDF;  
1002 -  
1003 - public:  
1004 - StringDecrypter(QPDF* qpdf, QPDFObjGen const& og);  
1005 - ~StringDecrypter() override = default;  
1006 - void decryptString(std::string& val) override;  
1007 -  
1008 - private:  
1009 - QPDF* qpdf;  
1010 - QPDFObjGen og;  
1011 - };  
1012 -  
1013 - class ResolveRecorder  
1014 - {  
1015 - public:  
1016 - ResolveRecorder(QPDF* qpdf, QPDFObjGen const& og) :  
1017 - qpdf(qpdf),  
1018 - iter(qpdf->m->resolving.insert(og).first)  
1019 - {  
1020 - }  
1021 - virtual ~ResolveRecorder()  
1022 - {  
1023 - this->qpdf->m->resolving.erase(iter);  
1024 - }  
1025 -  
1026 - private:  
1027 - QPDF* qpdf;  
1028 - std::set<QPDFObjGen>::const_iterator iter;  
1029 - };  
1030 - 750 + class ObjCache;
  751 + class ObjCopier;
  752 + class EncryptionParameters;
  753 + class ForeignStreamData;
  754 + class CopiedStreamDataProvider;
  755 + class StringDecrypter;
  756 + class ResolveRecorder;
1031 class JSONReactor; 757 class JSONReactor;
1032 758
1033 void parse(char const* password); 759 void parse(char const* password);
@@ -1196,200 +922,19 @@ class QPDF @@ -1196,200 +922,19 @@ class QPDF
1196 replaceForeignIndirectObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top); 922 replaceForeignIndirectObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top);
1197 void copyStreamData(QPDFObjectHandle dest_stream, QPDFObjectHandle src_stream); 923 void copyStreamData(QPDFObjectHandle dest_stream, QPDFObjectHandle src_stream);
1198 924
1199 - // Linearization Hint table structures.  
1200 - // Naming conventions:  
1201 -  
1202 - // HSomething is the Something Hint Table or table header  
1203 - // HSomethingEntry is an entry in the Something table  
1204 -  
1205 - // delta_something + min_something = something  
1206 - // nbits_something = number of bits required for something  
1207 -  
1208 - // something_offset is the pre-adjusted offset in the file. If >=  
1209 - // H0_offset, H0_length must be added to get an actual file  
1210 - // offset.  
1211 -  
1212 - // PDF 1.4: Table F.4  
1213 - struct HPageOffsetEntry  
1214 - {  
1215 - int delta_nobjects{0}; // 1  
1216 - qpdf_offset_t delta_page_length{0}; // 2  
1217 - // vectors' sizes = nshared_objects  
1218 - int nshared_objects{0}; // 3  
1219 - std::vector<int> shared_identifiers; // 4  
1220 - std::vector<int> shared_numerators; // 5  
1221 - qpdf_offset_t delta_content_offset{0}; // 6  
1222 - qpdf_offset_t delta_content_length{0}; // 7  
1223 - };  
1224 -  
1225 - // PDF 1.4: Table F.3  
1226 - struct HPageOffset  
1227 - {  
1228 - int min_nobjects{0}; // 1  
1229 - qpdf_offset_t first_page_offset{0}; // 2  
1230 - int nbits_delta_nobjects{0}; // 3  
1231 - int min_page_length{0}; // 4  
1232 - int nbits_delta_page_length{0}; // 5  
1233 - int min_content_offset{0}; // 6  
1234 - int nbits_delta_content_offset{0}; // 7  
1235 - int min_content_length{0}; // 8  
1236 - int nbits_delta_content_length{0}; // 9  
1237 - int nbits_nshared_objects{0}; // 10  
1238 - int nbits_shared_identifier{0}; // 11  
1239 - int nbits_shared_numerator{0}; // 12  
1240 - int shared_denominator{0}; // 13  
1241 - // vector size is npages  
1242 - std::vector<HPageOffsetEntry> entries;  
1243 - };  
1244 -  
1245 - // PDF 1.4: Table F.6  
1246 - struct HSharedObjectEntry  
1247 - {  
1248 - // Item 3 is a 128-bit signature (unsupported by Acrobat)  
1249 - int delta_group_length{0}; // 1  
1250 - int signature_present{0}; // 2 -- always 0  
1251 - int nobjects_minus_one{0}; // 4 -- always 0  
1252 - };  
1253 -  
1254 - // PDF 1.4: Table F.5  
1255 - struct HSharedObject  
1256 - {  
1257 - int first_shared_obj{0}; // 1  
1258 - qpdf_offset_t first_shared_offset{0}; // 2  
1259 - int nshared_first_page{0}; // 3  
1260 - int nshared_total{0}; // 4  
1261 - int nbits_nobjects{0}; // 5  
1262 - int min_group_length{0}; // 6  
1263 - int nbits_delta_group_length{0}; // 7  
1264 - // vector size is nshared_total  
1265 - std::vector<HSharedObjectEntry> entries;  
1266 - };  
1267 -  
1268 - // PDF 1.4: Table F.9  
1269 - struct HGeneric  
1270 - {  
1271 - int first_object{0}; // 1  
1272 - qpdf_offset_t first_object_offset{0}; // 2  
1273 - int nobjects{0}; // 3  
1274 - int group_length{0}; // 4  
1275 - };  
1276 -  
1277 - // Other linearization data structures  
1278 -  
1279 - // Initialized from Linearization Parameter dictionary  
1280 - struct LinParameters  
1281 - {  
1282 - qpdf_offset_t file_size{0}; // /L  
1283 - int first_page_object{0}; // /O  
1284 - qpdf_offset_t first_page_end{0}; // /E  
1285 - int npages{0}; // /N  
1286 - qpdf_offset_t xref_zero_offset{0}; // /T  
1287 - int first_page{0}; // /P  
1288 - qpdf_offset_t H_offset{0}; // offset of primary hint stream  
1289 - qpdf_offset_t H_length{0}; // length of primary hint stream  
1290 - };  
1291 -  
1292 - // Computed hint table value data structures. These tables contain the computed values on which  
1293 - // the hint table values are based. They exclude things like number of bits and store actual  
1294 - // values instead of mins and deltas. File offsets are also absolute rather than being offset  
1295 - // by the size of the primary hint table. We populate the hint table structures from these  
1296 - // during writing and compare the hint table values with these during validation. We ignore  
1297 - // some values for various reasons described in the code. Those values are omitted from these  
1298 - // structures. Note also that object numbers are object numbers from the input file, not the  
1299 - // output file.  
1300 -  
1301 - // Naming convention: CHSomething is analogous to HSomething above. "CH" is computed hint.  
1302 -  
1303 - struct CHPageOffsetEntry  
1304 - {  
1305 - int nobjects{0};  
1306 - int nshared_objects{0};  
1307 - // vectors' sizes = nshared_objects  
1308 - std::vector<int> shared_identifiers;  
1309 - };  
1310 -  
1311 - struct CHPageOffset  
1312 - {  
1313 - // vector size is npages  
1314 - std::vector<CHPageOffsetEntry> entries;  
1315 - };  
1316 -  
1317 - struct CHSharedObjectEntry  
1318 - {  
1319 - CHSharedObjectEntry(int object) :  
1320 - object(object)  
1321 - {  
1322 - }  
1323 -  
1324 - int object;  
1325 - };  
1326 -  
1327 - // PDF 1.4: Table F.5  
1328 - struct CHSharedObject  
1329 - {  
1330 - int first_shared_obj{0};  
1331 - int nshared_first_page{0};  
1332 - int nshared_total{0};  
1333 - // vector size is nshared_total  
1334 - std::vector<CHSharedObjectEntry> entries;  
1335 - };  
1336 -  
1337 - // No need for CHGeneric -- HGeneric is fine as is.  
1338 -  
1339 - // Data structures to support optimization -- implemented in QPDF_optimization.cc  
1340 -  
1341 - class ObjUser  
1342 - {  
1343 - public:  
1344 - enum user_e { ou_bad, ou_page, ou_thumb, ou_trailer_key, ou_root_key, ou_root };  
1345 -  
1346 - // type is set to ou_bad  
1347 - ObjUser();  
1348 -  
1349 - // type must be ou_root  
1350 - ObjUser(user_e type);  
1351 -  
1352 - // type must be one of ou_page or ou_thumb  
1353 - ObjUser(user_e type, int pageno);  
1354 -  
1355 - // type must be one of ou_trailer_key or ou_root_key  
1356 - ObjUser(user_e type, std::string const& key);  
1357 -  
1358 - bool operator<(ObjUser const&) const;  
1359 -  
1360 - user_e ou_type;  
1361 - int pageno; // if ou_page;  
1362 - std::string key; // if ou_trailer_key or ou_root_key  
1363 - };  
1364 -  
1365 - struct UpdateObjectMapsFrame  
1366 - {  
1367 - UpdateObjectMapsFrame(ObjUser const& ou, QPDFObjectHandle oh, bool top);  
1368 -  
1369 - ObjUser const& ou;  
1370 - QPDFObjectHandle oh;  
1371 - bool top;  
1372 - };  
1373 -  
1374 - class PatternFinder: public InputSource::Finder  
1375 - {  
1376 - public:  
1377 - PatternFinder(QPDF& qpdf, bool (QPDF::*checker)()) :  
1378 - qpdf(qpdf),  
1379 - checker(checker)  
1380 - {  
1381 - }  
1382 - ~PatternFinder() override = default;  
1383 - bool  
1384 - check() override  
1385 - {  
1386 - return (this->qpdf.*checker)();  
1387 - }  
1388 -  
1389 - private:  
1390 - QPDF& qpdf;  
1391 - bool (QPDF::*checker)();  
1392 - }; 925 + struct HPageOffsetEntry;
  926 + struct HPageOffset;
  927 + struct HSharedObjectEntry;
  928 + struct HSharedObject;
  929 + struct HGeneric;
  930 + struct LinParameters;
  931 + struct CHPageOffsetEntry;
  932 + struct CHPageOffset;
  933 + struct CHSharedObjectEntry;
  934 + struct CHSharedObject;
  935 + class ObjUser;
  936 + struct UpdateObjectMapsFrame;
  937 + class PatternFinder;
1393 938
1394 // Methods to support pattern finding 939 // Methods to support pattern finding
1395 static bool validatePDFVersion(char const*&, std::string& version); 940 static bool validatePDFVersion(char const*&, std::string& version);
@@ -1486,90 +1031,7 @@ class QPDF @@ -1486,90 +1031,7 @@ class QPDF
1486 return QIntC::to_ulonglong(i); 1031 return QIntC::to_ulonglong(i);
1487 } 1032 }
1488 1033
1489 - class Members  
1490 - {  
1491 - friend class QPDF;  
1492 - friend class ResolveRecorder;  
1493 -  
1494 - public:  
1495 - QPDF_DLL  
1496 - ~Members() = default;  
1497 -  
1498 - private:  
1499 - Members();  
1500 - Members(Members const&) = delete;  
1501 -  
1502 - std::shared_ptr<QPDFLogger> log;  
1503 - unsigned long long unique_id{0};  
1504 - QPDFTokenizer tokenizer;  
1505 - std::shared_ptr<InputSource> file;  
1506 - std::string last_object_description;  
1507 - bool provided_password_is_hex_key{false};  
1508 - bool ignore_xref_streams{false};  
1509 - bool suppress_warnings{false};  
1510 - size_t max_warnings{0};  
1511 - bool attempt_recovery{true};  
1512 - bool check_mode{false};  
1513 - std::shared_ptr<EncryptionParameters> encp;  
1514 - std::string pdf_version;  
1515 - std::map<QPDFObjGen, QPDFXRefEntry> xref_table;  
1516 - // Various tables are indexed by object id, with potential size id + 1  
1517 - int xref_table_max_id{std::numeric_limits<int>::max() - 1};  
1518 - qpdf_offset_t xref_table_max_offset{0};  
1519 - std::set<int> deleted_objects;  
1520 - std::map<QPDFObjGen, ObjCache> obj_cache;  
1521 - std::set<QPDFObjGen> resolving;  
1522 - QPDFObjectHandle trailer;  
1523 - std::vector<QPDFObjectHandle> all_pages;  
1524 - bool invalid_page_found{false};  
1525 - std::map<QPDFObjGen, int> pageobj_to_pages_pos;  
1526 - bool pushed_inherited_attributes_to_pages{false};  
1527 - bool ever_pushed_inherited_attributes_to_pages{false};  
1528 - bool ever_called_get_all_pages{false};  
1529 - std::vector<QPDFExc> warnings;  
1530 - std::map<unsigned long long, ObjCopier> object_copiers;  
1531 - std::shared_ptr<QPDFObjectHandle::StreamDataProvider> copied_streams;  
1532 - // copied_stream_data_provider is owned by copied_streams  
1533 - CopiedStreamDataProvider* copied_stream_data_provider{nullptr};  
1534 - bool reconstructed_xref{false};  
1535 - bool fixed_dangling_refs{false};  
1536 - bool immediate_copy_from{false};  
1537 - bool in_parse{false};  
1538 - bool parsed{false};  
1539 - std::set<int> resolved_object_streams;  
1540 -  
1541 - // Linearization data  
1542 - qpdf_offset_t first_xref_item_offset{0}; // actual value from file  
1543 - bool uncompressed_after_compressed{false};  
1544 - bool linearization_warnings{false};  
1545 -  
1546 - // Linearization parameter dictionary and hint table data: may be read from file or computed  
1547 - // prior to writing a linearized file  
1548 - QPDFObjectHandle lindict;  
1549 - LinParameters linp;  
1550 - HPageOffset page_offset_hints;  
1551 - HSharedObject shared_object_hints;  
1552 - HGeneric outline_hints;  
1553 -  
1554 - // Computed linearization data: used to populate above tables during writing and to compare  
1555 - // with them during validation. c_ means computed.  
1556 - LinParameters c_linp;  
1557 - CHPageOffset c_page_offset_data;  
1558 - CHSharedObject c_shared_object_data;  
1559 - HGeneric c_outline_data;  
1560 -  
1561 - // Object ordering data for linearized files: initialized by calculateLinearizationData().  
1562 - // Part numbers refer to the PDF 1.4 specification.  
1563 - std::vector<QPDFObjectHandle> part4;  
1564 - std::vector<QPDFObjectHandle> part6;  
1565 - std::vector<QPDFObjectHandle> part7;  
1566 - std::vector<QPDFObjectHandle> part8;  
1567 - std::vector<QPDFObjectHandle> part9;  
1568 -  
1569 - // Optimization data  
1570 - std::map<ObjUser, std::set<QPDFObjGen>> obj_user_to_objects;  
1571 - std::map<QPDFObjGen, std::set<ObjUser>> object_to_obj_users;  
1572 - }; 1034 + class Members;
1573 1035
1574 // Keep all member variables inside the Members object, which we dynamically allocate. This 1036 // Keep all member variables inside the Members object, which we dynamically allocate. This
1575 // makes it possible to add new private members without breaking binary compatibility. 1037 // makes it possible to add new private members without breaking binary compatibility.
libqpdf/QPDF.cc
1 #include <qpdf/qpdf-config.h> // include first for large file support 1 #include <qpdf/qpdf-config.h> // include first for large file support
2 2
3 -#include <qpdf/QPDF.hh> 3 +#include <qpdf/QPDF_private.hh>
4 4
5 #include <array> 5 #include <array>
6 #include <atomic> 6 #include <atomic>
libqpdf/QPDFJob.cc
@@ -13,7 +13,6 @@ @@ -13,7 +13,6 @@
13 #include <qpdf/Pl_StdioFile.hh> 13 #include <qpdf/Pl_StdioFile.hh>
14 #include <qpdf/Pl_String.hh> 14 #include <qpdf/Pl_String.hh>
15 #include <qpdf/QIntC.hh> 15 #include <qpdf/QIntC.hh>
16 -#include <qpdf/QPDF.hh>  
17 #include <qpdf/QPDFAcroFormDocumentHelper.hh> 16 #include <qpdf/QPDFAcroFormDocumentHelper.hh>
18 #include <qpdf/QPDFCryptoProvider.hh> 17 #include <qpdf/QPDFCryptoProvider.hh>
19 #include <qpdf/QPDFEmbeddedFileDocumentHelper.hh> 18 #include <qpdf/QPDFEmbeddedFileDocumentHelper.hh>
@@ -26,6 +25,7 @@ @@ -26,6 +25,7 @@
26 #include <qpdf/QPDFSystemError.hh> 25 #include <qpdf/QPDFSystemError.hh>
27 #include <qpdf/QPDFUsage.hh> 26 #include <qpdf/QPDFUsage.hh>
28 #include <qpdf/QPDFWriter.hh> 27 #include <qpdf/QPDFWriter.hh>
  28 +#include <qpdf/QPDF_private.hh>
29 #include <qpdf/QTC.hh> 29 #include <qpdf/QTC.hh>
30 #include <qpdf/QUtil.hh> 30 #include <qpdf/QUtil.hh>
31 31
libqpdf/QPDFWriter.cc
@@ -14,10 +14,10 @@ @@ -14,10 +14,10 @@
14 #include <qpdf/Pl_RC4.hh> 14 #include <qpdf/Pl_RC4.hh>
15 #include <qpdf/Pl_StdioFile.hh> 15 #include <qpdf/Pl_StdioFile.hh>
16 #include <qpdf/QIntC.hh> 16 #include <qpdf/QIntC.hh>
17 -#include <qpdf/QPDF.hh>  
18 #include <qpdf/QPDFObjectHandle.hh> 17 #include <qpdf/QPDFObjectHandle.hh>
19 #include <qpdf/QPDF_Name.hh> 18 #include <qpdf/QPDF_Name.hh>
20 #include <qpdf/QPDF_String.hh> 19 #include <qpdf/QPDF_String.hh>
  20 +#include <qpdf/QPDF_private.hh>
21 #include <qpdf/QTC.hh> 21 #include <qpdf/QTC.hh>
22 #include <qpdf/QUtil.hh> 22 #include <qpdf/QUtil.hh>
23 #include <qpdf/RC4.hh> 23 #include <qpdf/RC4.hh>
libqpdf/QPDF_Stream.cc
@@ -10,8 +10,8 @@ @@ -10,8 +10,8 @@
10 #include <qpdf/Pl_Flate.hh> 10 #include <qpdf/Pl_Flate.hh>
11 #include <qpdf/Pl_QPDFTokenizer.hh> 11 #include <qpdf/Pl_QPDFTokenizer.hh>
12 #include <qpdf/QIntC.hh> 12 #include <qpdf/QIntC.hh>
13 -#include <qpdf/QPDF.hh>  
14 #include <qpdf/QPDFExc.hh> 13 #include <qpdf/QPDFExc.hh>
  14 +#include <qpdf/QPDF_private.hh>
15 #include <qpdf/QTC.hh> 15 #include <qpdf/QTC.hh>
16 #include <qpdf/QUtil.hh> 16 #include <qpdf/QUtil.hh>
17 #include <qpdf/SF_ASCII85Decode.hh> 17 #include <qpdf/SF_ASCII85Decode.hh>
libqpdf/QPDF_encryption.cc
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 3
4 #include <qpdf/assert_debug.h> 4 #include <qpdf/assert_debug.h>
5 5
6 -#include <qpdf/QPDF.hh> 6 +#include <qpdf/QPDF_private.hh>
7 7
8 #include <qpdf/QPDFExc.hh> 8 #include <qpdf/QPDFExc.hh>
9 9
libqpdf/QPDF_linearization.cc
1 // See doc/linearization. 1 // See doc/linearization.
2 2
3 -#include <qpdf/QPDF.hh> 3 +#include <qpdf/QPDF_private.hh>
4 4
5 #include <qpdf/BitStream.hh> 5 #include <qpdf/BitStream.hh>
6 #include <qpdf/BitWriter.hh> 6 #include <qpdf/BitWriter.hh>
libqpdf/QPDF_optimization.cc
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 2
3 #include <qpdf/assert_debug.h> 3 #include <qpdf/assert_debug.h>
4 4
5 -#include <qpdf/QPDF.hh> 5 +#include <qpdf/QPDF_private.hh>
6 6
7 #include <qpdf/QPDFExc.hh> 7 #include <qpdf/QPDFExc.hh>
8 #include <qpdf/QPDFWriter_private.hh> 8 #include <qpdf/QPDFWriter_private.hh>
libqpdf/QPDF_pages.cc
1 -#include <qpdf/QPDF.hh> 1 +#include <qpdf/QPDF_private.hh>
2 2
3 #include <qpdf/QPDFExc.hh> 3 #include <qpdf/QPDFExc.hh>
4 #include <qpdf/QTC.hh> 4 #include <qpdf/QTC.hh>
libqpdf/qpdf/QPDFObject_private.hh
@@ -6,14 +6,13 @@ @@ -6,14 +6,13 @@
6 6
7 #include <qpdf/Constants.h> 7 #include <qpdf/Constants.h>
8 #include <qpdf/JSON.hh> 8 #include <qpdf/JSON.hh>
9 -#include <qpdf/QPDF.hh>  
10 #include <qpdf/QPDFValue.hh> 9 #include <qpdf/QPDFValue.hh>
  10 +#include <qpdf/QPDF_private.hh>
11 #include <qpdf/Types.h> 11 #include <qpdf/Types.h>
12 12
13 #include <string> 13 #include <string>
14 #include <string_view> 14 #include <string_view>
15 15
16 -class QPDF;  
17 class QPDFObjectHandle; 16 class QPDFObjectHandle;
18 17
19 class QPDFObject 18 class QPDFObject
libqpdf/qpdf/QPDF_private.hh 0 โ†’ 100644
  1 +#ifndef QPDF_PRIVATE_HH
  2 +#define QPDF_PRIVATE_HH
  3 +
  4 +#include <qpdf/QPDF.hh>
  5 +
  6 +// Writer class is restricted to QPDFWriter so that only it can call certain methods.
  7 +class QPDF::Writer
  8 +{
  9 + friend class QPDFWriter;
  10 +
  11 + private:
  12 + static void
  13 + optimize(
  14 + QPDF& qpdf,
  15 + QPDFWriter::ObjTable const& obj,
  16 + std::function<int(QPDFObjectHandle&)> skip_stream_parameters)
  17 + {
  18 + return qpdf.optimize(obj, skip_stream_parameters);
  19 + }
  20 +
  21 + static void
  22 + getLinearizedParts(
  23 + QPDF& qpdf,
  24 + QPDFWriter::ObjTable const& obj,
  25 + std::vector<QPDFObjectHandle>& part4,
  26 + std::vector<QPDFObjectHandle>& part6,
  27 + std::vector<QPDFObjectHandle>& part7,
  28 + std::vector<QPDFObjectHandle>& part8,
  29 + std::vector<QPDFObjectHandle>& part9)
  30 + {
  31 + qpdf.getLinearizedParts(obj, part4, part6, part7, part8, part9);
  32 + }
  33 +
  34 + static void
  35 + generateHintStream(
  36 + QPDF& qpdf,
  37 + QPDFWriter::NewObjTable const& new_obj,
  38 + QPDFWriter::ObjTable const& obj,
  39 + std::shared_ptr<Buffer>& hint_stream,
  40 + int& S,
  41 + int& O,
  42 + bool compressed)
  43 + {
  44 + return qpdf.generateHintStream(new_obj, obj, hint_stream, S, O, compressed);
  45 + }
  46 +
  47 + static std::vector<QPDFObjGen>
  48 + getCompressibleObjGens(QPDF& qpdf)
  49 + {
  50 + return qpdf.getCompressibleObjVector();
  51 + }
  52 +
  53 + static std::vector<bool>
  54 + getCompressibleObjSet(QPDF& qpdf)
  55 + {
  56 + return qpdf.getCompressibleObjSet();
  57 + }
  58 +
  59 + static std::map<QPDFObjGen, QPDFXRefEntry> const&
  60 + getXRefTable(QPDF& qpdf)
  61 + {
  62 + return qpdf.getXRefTableInternal();
  63 + }
  64 +
  65 + static size_t
  66 + tableSize(QPDF& qpdf)
  67 + {
  68 + return qpdf.tableSize();
  69 + }
  70 +};
  71 +
  72 +// The Resolver class is restricted to QPDFObject so that only it can resolve indirect
  73 +// references.
  74 +class QPDF::Resolver
  75 +{
  76 + friend class QPDFObject;
  77 + friend class QPDF_Unresolved;
  78 +
  79 + private:
  80 + static QPDFObject*
  81 + resolved(QPDF* qpdf, QPDFObjGen og)
  82 + {
  83 + return qpdf->resolve(og);
  84 + }
  85 +};
  86 +
  87 +// StreamCopier class is restricted to QPDFObjectHandle so it can copy stream data.
  88 +class QPDF::StreamCopier
  89 +{
  90 + friend class QPDFObjectHandle;
  91 +
  92 + private:
  93 + static void
  94 + copyStreamData(QPDF* qpdf, QPDFObjectHandle const& dest, QPDFObjectHandle const& src)
  95 + {
  96 + qpdf->copyStreamData(dest, src);
  97 + }
  98 +};
  99 +
  100 +// The ParseGuard class allows QPDFParser to detect re-entrant parsing. It also provides
  101 +// special access to allow the parser to create unresolved objects and dangling references.
  102 +class QPDF::ParseGuard
  103 +{
  104 + friend class QPDFParser;
  105 +
  106 + private:
  107 + ParseGuard(QPDF* qpdf) :
  108 + qpdf(qpdf)
  109 + {
  110 + if (qpdf) {
  111 + qpdf->inParse(true);
  112 + }
  113 + }
  114 +
  115 + static std::shared_ptr<QPDFObject>
  116 + getObject(QPDF* qpdf, int id, int gen, bool parse_pdf)
  117 + {
  118 + return qpdf->getObjectForParser(id, gen, parse_pdf);
  119 + }
  120 +
  121 + ~ParseGuard()
  122 + {
  123 + if (qpdf) {
  124 + qpdf->inParse(false);
  125 + }
  126 + }
  127 + QPDF* qpdf;
  128 +};
  129 +
  130 +// Pipe class is restricted to QPDF_Stream.
  131 +class QPDF::Pipe
  132 +{
  133 + friend class QPDF_Stream;
  134 +
  135 + private:
  136 + static bool
  137 + pipeStreamData(
  138 + QPDF* qpdf,
  139 + QPDFObjGen const& og,
  140 + qpdf_offset_t offset,
  141 + size_t length,
  142 + QPDFObjectHandle dict,
  143 + Pipeline* pipeline,
  144 + bool suppress_warnings,
  145 + bool will_retry)
  146 + {
  147 + return qpdf->pipeStreamData(
  148 + og, offset, length, dict, pipeline, suppress_warnings, will_retry);
  149 + }
  150 +};
  151 +
  152 +class QPDF::ObjCache
  153 +{
  154 + public:
  155 + ObjCache() :
  156 + end_before_space(0),
  157 + end_after_space(0)
  158 + {
  159 + }
  160 + ObjCache(
  161 + std::shared_ptr<QPDFObject> object,
  162 + qpdf_offset_t end_before_space = 0,
  163 + qpdf_offset_t end_after_space = 0) :
  164 + object(object),
  165 + end_before_space(end_before_space),
  166 + end_after_space(end_after_space)
  167 + {
  168 + }
  169 +
  170 + std::shared_ptr<QPDFObject> object;
  171 + qpdf_offset_t end_before_space;
  172 + qpdf_offset_t end_after_space;
  173 +};
  174 +
  175 +class QPDF::ObjCopier
  176 +{
  177 + public:
  178 + std::map<QPDFObjGen, QPDFObjectHandle> object_map;
  179 + std::vector<QPDFObjectHandle> to_copy;
  180 + QPDFObjGen::set visiting;
  181 +};
  182 +
  183 +class QPDF::EncryptionParameters
  184 +{
  185 + friend class QPDF;
  186 +
  187 + public:
  188 + EncryptionParameters();
  189 +
  190 + private:
  191 + bool encrypted;
  192 + bool encryption_initialized;
  193 + int encryption_V;
  194 + int encryption_R;
  195 + bool encrypt_metadata;
  196 + std::map<std::string, encryption_method_e> crypt_filters;
  197 + encryption_method_e cf_stream;
  198 + encryption_method_e cf_string;
  199 + encryption_method_e cf_file;
  200 + std::string provided_password;
  201 + std::string user_password;
  202 + std::string encryption_key;
  203 + std::string cached_object_encryption_key;
  204 + QPDFObjGen cached_key_og;
  205 + bool user_password_matched;
  206 + bool owner_password_matched;
  207 +};
  208 +
  209 +class QPDF::ForeignStreamData
  210 +{
  211 + friend class QPDF;
  212 +
  213 + public:
  214 + ForeignStreamData(
  215 + std::shared_ptr<EncryptionParameters> encp,
  216 + std::shared_ptr<InputSource> file,
  217 + QPDFObjGen const& foreign_og,
  218 + qpdf_offset_t offset,
  219 + size_t length,
  220 + QPDFObjectHandle local_dict);
  221 +
  222 + private:
  223 + std::shared_ptr<EncryptionParameters> encp;
  224 + std::shared_ptr<InputSource> file;
  225 + QPDFObjGen foreign_og;
  226 + qpdf_offset_t offset;
  227 + size_t length;
  228 + QPDFObjectHandle local_dict;
  229 +};
  230 +
  231 +class QPDF::CopiedStreamDataProvider: public QPDFObjectHandle::StreamDataProvider
  232 +{
  233 + public:
  234 + CopiedStreamDataProvider(QPDF& destination_qpdf);
  235 + ~CopiedStreamDataProvider() override = default;
  236 + bool provideStreamData(
  237 + QPDFObjGen const& og, Pipeline* pipeline, bool suppress_warnings, bool will_retry) override;
  238 + void registerForeignStream(QPDFObjGen const& local_og, QPDFObjectHandle foreign_stream);
  239 + void registerForeignStream(QPDFObjGen const& local_og, std::shared_ptr<ForeignStreamData>);
  240 +
  241 + private:
  242 + QPDF& destination_qpdf;
  243 + std::map<QPDFObjGen, QPDFObjectHandle> foreign_streams;
  244 + std::map<QPDFObjGen, std::shared_ptr<ForeignStreamData>> foreign_stream_data;
  245 +};
  246 +
  247 +class QPDF::StringDecrypter: public QPDFObjectHandle::StringDecrypter
  248 +{
  249 + friend class QPDF;
  250 +
  251 + public:
  252 + StringDecrypter(QPDF* qpdf, QPDFObjGen const& og);
  253 + ~StringDecrypter() override = default;
  254 + void decryptString(std::string& val) override;
  255 +
  256 + private:
  257 + QPDF* qpdf;
  258 + QPDFObjGen og;
  259 +};
  260 +
  261 +// PDF 1.4: Table F.4
  262 +struct QPDF::HPageOffsetEntry
  263 +{
  264 + int delta_nobjects{0}; // 1
  265 + qpdf_offset_t delta_page_length{0}; // 2
  266 + // vectors' sizes = nshared_objects
  267 + int nshared_objects{0}; // 3
  268 + std::vector<int> shared_identifiers; // 4
  269 + std::vector<int> shared_numerators; // 5
  270 + qpdf_offset_t delta_content_offset{0}; // 6
  271 + qpdf_offset_t delta_content_length{0}; // 7
  272 +};
  273 +
  274 +// PDF 1.4: Table F.3
  275 +struct QPDF::HPageOffset
  276 +{
  277 + int min_nobjects{0}; // 1
  278 + qpdf_offset_t first_page_offset{0}; // 2
  279 + int nbits_delta_nobjects{0}; // 3
  280 + int min_page_length{0}; // 4
  281 + int nbits_delta_page_length{0}; // 5
  282 + int min_content_offset{0}; // 6
  283 + int nbits_delta_content_offset{0}; // 7
  284 + int min_content_length{0}; // 8
  285 + int nbits_delta_content_length{0}; // 9
  286 + int nbits_nshared_objects{0}; // 10
  287 + int nbits_shared_identifier{0}; // 11
  288 + int nbits_shared_numerator{0}; // 12
  289 + int shared_denominator{0}; // 13
  290 + // vector size is npages
  291 + std::vector<HPageOffsetEntry> entries;
  292 +};
  293 +
  294 +// PDF 1.4: Table F.6
  295 +struct QPDF::HSharedObjectEntry
  296 +{
  297 + // Item 3 is a 128-bit signature (unsupported by Acrobat)
  298 + int delta_group_length{0}; // 1
  299 + int signature_present{0}; // 2 -- always 0
  300 + int nobjects_minus_one{0}; // 4 -- always 0
  301 +};
  302 +
  303 +// PDF 1.4: Table F.5
  304 +struct QPDF::HSharedObject
  305 +{
  306 + int first_shared_obj{0}; // 1
  307 + qpdf_offset_t first_shared_offset{0}; // 2
  308 + int nshared_first_page{0}; // 3
  309 + int nshared_total{0}; // 4
  310 + int nbits_nobjects{0}; // 5
  311 + int min_group_length{0}; // 6
  312 + int nbits_delta_group_length{0}; // 7
  313 + // vector size is nshared_total
  314 + std::vector<HSharedObjectEntry> entries;
  315 +};
  316 +
  317 +// PDF 1.4: Table F.9
  318 +struct QPDF::HGeneric
  319 +{
  320 + int first_object{0}; // 1
  321 + qpdf_offset_t first_object_offset{0}; // 2
  322 + int nobjects{0}; // 3
  323 + int group_length{0}; // 4
  324 +};
  325 +
  326 +// Other linearization data structures
  327 +
  328 +// Initialized from Linearization Parameter dictionary
  329 +struct QPDF::LinParameters
  330 +{
  331 + qpdf_offset_t file_size{0}; // /L
  332 + int first_page_object{0}; // /O
  333 + qpdf_offset_t first_page_end{0}; // /E
  334 + int npages{0}; // /N
  335 + qpdf_offset_t xref_zero_offset{0}; // /T
  336 + int first_page{0}; // /P
  337 + qpdf_offset_t H_offset{0}; // offset of primary hint stream
  338 + qpdf_offset_t H_length{0}; // length of primary hint stream
  339 +};
  340 +
  341 +// Computed hint table value data structures. These tables contain the computed values on which
  342 +// the hint table values are based. They exclude things like number of bits and store actual
  343 +// values instead of mins and deltas. File offsets are also absolute rather than being offset
  344 +// by the size of the primary hint table. We populate the hint table structures from these
  345 +// during writing and compare the hint table values with these during validation. We ignore
  346 +// some values for various reasons described in the code. Those values are omitted from these
  347 +// structures. Note also that object numbers are object numbers from the input file, not the
  348 +// output file.
  349 +
  350 +// Naming convention: CHSomething is analogous to HSomething above. "CH" is computed hint.
  351 +
  352 +struct QPDF::CHPageOffsetEntry
  353 +{
  354 + int nobjects{0};
  355 + int nshared_objects{0};
  356 + // vectors' sizes = nshared_objects
  357 + std::vector<int> shared_identifiers;
  358 +};
  359 +
  360 +struct QPDF::CHPageOffset
  361 +{
  362 + // vector size is npages
  363 + std::vector<CHPageOffsetEntry> entries;
  364 +};
  365 +
  366 +struct QPDF::CHSharedObjectEntry
  367 +{
  368 + CHSharedObjectEntry(int object) :
  369 + object(object)
  370 + {
  371 + }
  372 +
  373 + int object;
  374 +};
  375 +
  376 +// PDF 1.4: Table F.5
  377 +struct QPDF::CHSharedObject
  378 +{
  379 + int first_shared_obj{0};
  380 + int nshared_first_page{0};
  381 + int nshared_total{0};
  382 + // vector size is nshared_total
  383 + std::vector<CHSharedObjectEntry> entries;
  384 +};
  385 +
  386 +// No need for CHGeneric -- HGeneric is fine as is.
  387 +
  388 +// Data structures to support optimization -- implemented in QPDF_optimization.cc
  389 +
  390 +class QPDF::ObjUser
  391 +{
  392 + public:
  393 + enum user_e { ou_bad, ou_page, ou_thumb, ou_trailer_key, ou_root_key, ou_root };
  394 +
  395 + // type is set to ou_bad
  396 + ObjUser();
  397 +
  398 + // type must be ou_root
  399 + ObjUser(user_e type);
  400 +
  401 + // type must be one of ou_page or ou_thumb
  402 + ObjUser(user_e type, int pageno);
  403 +
  404 + // type must be one of ou_trailer_key or ou_root_key
  405 + ObjUser(user_e type, std::string const& key);
  406 +
  407 + bool operator<(ObjUser const&) const;
  408 +
  409 + user_e ou_type;
  410 + int pageno; // if ou_page;
  411 + std::string key; // if ou_trailer_key or ou_root_key
  412 +};
  413 +
  414 +struct QPDF::UpdateObjectMapsFrame
  415 +{
  416 + UpdateObjectMapsFrame(ObjUser const& ou, QPDFObjectHandle oh, bool top);
  417 +
  418 + ObjUser const& ou;
  419 + QPDFObjectHandle oh;
  420 + bool top;
  421 +};
  422 +
  423 +class QPDF::PatternFinder: public InputSource::Finder
  424 +{
  425 + public:
  426 + PatternFinder(QPDF& qpdf, bool (QPDF::*checker)()) :
  427 + qpdf(qpdf),
  428 + checker(checker)
  429 + {
  430 + }
  431 + ~PatternFinder() override = default;
  432 + bool
  433 + check() override
  434 + {
  435 + return (this->qpdf.*checker)();
  436 + }
  437 +
  438 + private:
  439 + QPDF& qpdf;
  440 + bool (QPDF::*checker)();
  441 +};
  442 +
  443 +class QPDF::Members
  444 +{
  445 + friend class QPDF;
  446 + friend class ResolveRecorder;
  447 +
  448 + public:
  449 + QPDF_DLL
  450 + ~Members() = default;
  451 +
  452 + private:
  453 + Members();
  454 + Members(Members const&) = delete;
  455 +
  456 + std::shared_ptr<QPDFLogger> log;
  457 + unsigned long long unique_id{0};
  458 + QPDFTokenizer tokenizer;
  459 + std::shared_ptr<InputSource> file;
  460 + std::string last_object_description;
  461 + bool provided_password_is_hex_key{false};
  462 + bool ignore_xref_streams{false};
  463 + bool suppress_warnings{false};
  464 + size_t max_warnings{0};
  465 + bool attempt_recovery{true};
  466 + bool check_mode{false};
  467 + std::shared_ptr<EncryptionParameters> encp;
  468 + std::string pdf_version;
  469 + std::map<QPDFObjGen, QPDFXRefEntry> xref_table;
  470 + // Various tables are indexed by object id, with potential size id + 1
  471 + int xref_table_max_id{std::numeric_limits<int>::max() - 1};
  472 + qpdf_offset_t xref_table_max_offset{0};
  473 + std::set<int> deleted_objects;
  474 + std::map<QPDFObjGen, ObjCache> obj_cache;
  475 + std::set<QPDFObjGen> resolving;
  476 + QPDFObjectHandle trailer;
  477 + std::vector<QPDFObjectHandle> all_pages;
  478 + bool invalid_page_found{false};
  479 + std::map<QPDFObjGen, int> pageobj_to_pages_pos;
  480 + bool pushed_inherited_attributes_to_pages{false};
  481 + bool ever_pushed_inherited_attributes_to_pages{false};
  482 + bool ever_called_get_all_pages{false};
  483 + std::vector<QPDFExc> warnings;
  484 + std::map<unsigned long long, ObjCopier> object_copiers;
  485 + std::shared_ptr<QPDFObjectHandle::StreamDataProvider> copied_streams;
  486 + // copied_stream_data_provider is owned by copied_streams
  487 + CopiedStreamDataProvider* copied_stream_data_provider{nullptr};
  488 + bool reconstructed_xref{false};
  489 + bool fixed_dangling_refs{false};
  490 + bool immediate_copy_from{false};
  491 + bool in_parse{false};
  492 + bool parsed{false};
  493 + std::set<int> resolved_object_streams;
  494 +
  495 + // Linearization data
  496 + qpdf_offset_t first_xref_item_offset{0}; // actual value from file
  497 + bool uncompressed_after_compressed{false};
  498 + bool linearization_warnings{false};
  499 +
  500 + // Linearization parameter dictionary and hint table data: may be read from file or computed
  501 + // prior to writing a linearized file
  502 + QPDFObjectHandle lindict;
  503 + LinParameters linp;
  504 + HPageOffset page_offset_hints;
  505 + HSharedObject shared_object_hints;
  506 + HGeneric outline_hints;
  507 +
  508 + // Computed linearization data: used to populate above tables during writing and to compare
  509 + // with them during validation. c_ means computed.
  510 + LinParameters c_linp;
  511 + CHPageOffset c_page_offset_data;
  512 + CHSharedObject c_shared_object_data;
  513 + HGeneric c_outline_data;
  514 +
  515 + // Object ordering data for linearized files: initialized by calculateLinearizationData().
  516 + // Part numbers refer to the PDF 1.4 specification.
  517 + std::vector<QPDFObjectHandle> part4;
  518 + std::vector<QPDFObjectHandle> part6;
  519 + std::vector<QPDFObjectHandle> part7;
  520 + std::vector<QPDFObjectHandle> part8;
  521 + std::vector<QPDFObjectHandle> part9;
  522 +
  523 + // Optimization data
  524 + std::map<ObjUser, std::set<QPDFObjGen>> obj_user_to_objects;
  525 + std::map<QPDFObjGen, std::set<ObjUser>> object_to_obj_users;
  526 +};
  527 +
  528 +// JobSetter class is restricted to QPDFJob.
  529 +class QPDF::JobSetter
  530 +{
  531 + friend class QPDFJob;
  532 +
  533 + private:
  534 + // Enable enhanced warnings for pdf file checking.
  535 + static void
  536 + setCheckMode(QPDF& qpdf, bool val)
  537 + {
  538 + qpdf.m->check_mode = val;
  539 + }
  540 +};
  541 +
  542 +class QPDF::ResolveRecorder
  543 +{
  544 + public:
  545 + ResolveRecorder(QPDF* qpdf, QPDFObjGen const& og) :
  546 + qpdf(qpdf),
  547 + iter(qpdf->m->resolving.insert(og).first)
  548 + {
  549 + }
  550 + virtual ~ResolveRecorder()
  551 + {
  552 + this->qpdf->m->resolving.erase(iter);
  553 + }
  554 +
  555 + private:
  556 + QPDF* qpdf;
  557 + std::set<QPDFObjGen>::const_iterator iter;
  558 +};
  559 +
  560 +#endif // QPDF_PRIVATE_HH