Commit c54837e2c47bddc7801429f756005d7f9d41f71c

Authored by m-holger
1 parent efde6274

Refactor `Writer` usage: encapsulate `Linearization` and `Objects` inside `impl:…

…:Doc`, rename related methods, and streamline usage across QPDFWriter and linearization modules.
libqpdf/QPDF.cc
... ... @@ -723,11 +723,11 @@ QPDF::getRoot()
723 723 std::map<QPDFObjGen, QPDFXRefEntry>
724 724 QPDF::getXRefTable()
725 725 {
726   - return m->objects.getXRefTableInternal();
  726 + return m->objects.xref_table();
727 727 }
728 728  
729 729 std::map<QPDFObjGen, QPDFXRefEntry> const&
730   -Objects::getXRefTableInternal()
  730 +Objects::xref_table()
731 731 {
732 732 if (!m->parsed) {
733 733 throw std::logic_error("QPDF::getXRefTable called before parsing.");
... ...
libqpdf/QPDFWriter.cc
... ... @@ -262,75 +262,17 @@ Pl_stack::Popper::pop()
262 262 }
263 263  
264 264 // Writer class is restricted to QPDFWriter so that only it can call certain methods.
265   -class QPDF::Doc::Writer: QPDF::Doc::Common
  265 +class impl::Doc::Writer: impl::Doc::Common
266 266 {
267 267 friend class QPDFWriter;
268 268 Writer(QPDF& qpdf) :
269 269 Common(qpdf, qpdf.doc().m),
270   - lin(m->lin),
271   - objects(m->objects)
  270 + lin(m->lin)
272 271 {
273 272 }
274 273  
275 274 protected:
276   - void
277   - optimize(
278   - QPDFWriter::ObjTable const& obj,
279   - std::function<int(QPDFObjectHandle&)> skip_stream_parameters)
280   - {
281   - lin.optimize(obj, skip_stream_parameters);
282   - }
283   -
284   - void
285   - getLinearizedParts(
286   - QPDFWriter::ObjTable const& obj,
287   - std::vector<QPDFObjectHandle>& part4,
288   - std::vector<QPDFObjectHandle>& part6,
289   - std::vector<QPDFObjectHandle>& part7,
290   - std::vector<QPDFObjectHandle>& part8,
291   - std::vector<QPDFObjectHandle>& part9)
292   - {
293   - lin.getLinearizedParts(obj, part4, part6, part7, part8, part9);
294   - }
295   -
296   - void
297   - generateHintStream(
298   - QPDFWriter::NewObjTable const& new_obj,
299   - QPDFWriter::ObjTable const& obj,
300   - std::string& hint_stream,
301   - int& S,
302   - int& O,
303   - bool compressed)
304   - {
305   - lin.generateHintStream(new_obj, obj, hint_stream, S, O, compressed);
306   - }
307   -
308   - std::vector<QPDFObjGen>
309   - getCompressibleObjGens()
310   - {
311   - return objects.getCompressibleObjVector();
312   - }
313   -
314   - std::vector<bool>
315   - getCompressibleObjSet()
316   - {
317   - return objects.getCompressibleObjSet();
318   - }
319   -
320   - std::map<QPDFObjGen, QPDFXRefEntry> const&
321   - getXRefTable()
322   - {
323   - return objects.getXRefTableInternal();
324   - }
325   -
326   - size_t
327   - tableSize()
328   - {
329   - return qpdf.m->objects.tableSize();
330   - }
331   -
332   - QPDF::Doc::Linearization& lin;
333   - QPDF::Doc::Objects& objects;
  275 + impl::Doc::Linearization& lin;
334 276 };
335 277  
336 278 class QPDFWriter::Members: QPDF::Doc::Writer
... ... @@ -2151,7 +2093,7 @@ QPDFWriter::Members::initializeSpecialStreams()
2151 2093 void
2152 2094 QPDFWriter::Members::preserveObjectStreams()
2153 2095 {
2154   - auto const& xref = getXRefTable();
  2096 + auto const& xref = objects.xref_table();
2155 2097 // Our object_to_object_stream map has to map ObjGen -> ObjGen since we may be generating object
2156 2098 // streams out of old objects that have generation numbers greater than zero. However in an
2157 2099 // existing PDF, all object stream objects and all objects in them must have generation 0
... ... @@ -2176,9 +2118,9 @@ QPDFWriter::Members::preserveObjectStreams()
2176 2118 if (iter->second.getType() == 2) {
2177 2119 // Pdf contains object streams.
2178 2120 obj.streams_empty = false;
2179   - auto eligible = getCompressibleObjSet();
  2121 + auto eligible = objects.compressible_set();
2180 2122 // The object pointed to by iter may be a previous generation, in which case it is
2181   - // removed by getCompressibleObjSet. We need to restart the loop (while the object
  2123 + // removed by compressible_set. We need to restart the loop (while the object
2182 2124 // table may contain multiple generations of an object).
2183 2125 for (iter = xref.cbegin(); iter != end; ++iter) {
2184 2126 if (iter->second.getType() == 2) {
... ... @@ -2207,7 +2149,7 @@ QPDFWriter::Members::generateObjectStreams()
2207 2149  
2208 2150 // This code doesn't do anything with /Extends.
2209 2151  
2210   - std::vector<QPDFObjGen> eligible = getCompressibleObjGens();
  2152 + auto eligible = objects.compressible_vector();
2211 2153 size_t n_object_streams = (eligible.size() + 99U) / 100U;
2212 2154  
2213 2155 initializeTables(2U * n_object_streams);
... ... @@ -2288,7 +2230,7 @@ QPDFWriter::Members::prepareFileForWrite()
2288 2230 void
2289 2231 QPDFWriter::Members::initializeTables(size_t extra)
2290 2232 {
2291   - auto size = QIntC::to_size(tableSize() + 100) + extra;
  2233 + auto size = objects.table_size() + 100u + extra;
2292 2234 obj.resize(size);
2293 2235 new_obj.resize(size);
2294 2236 }
... ... @@ -2568,7 +2510,7 @@ QPDFWriter::Members::writeHintStream(int hint_id)
2568 2510 int S = 0;
2569 2511 int O = 0;
2570 2512 bool compressed = compress_streams;
2571   - generateHintStream(new_obj, obj, hint_buffer, S, O, compressed);
  2513 + lin.generateHintStream(new_obj, obj, hint_buffer, S, O, compressed);
2572 2514  
2573 2515 openObject(hint_id);
2574 2516 setDataKey(hint_id);
... ... @@ -2771,14 +2713,14 @@ QPDFWriter::Members::writeLinearized()
2771 2713 }
2772 2714 };
2773 2715  
2774   - optimize(obj, skip_stream_parameters);
  2716 + lin.optimize(obj, skip_stream_parameters);
2775 2717  
2776 2718 std::vector<QPDFObjectHandle> part4;
2777 2719 std::vector<QPDFObjectHandle> part6;
2778 2720 std::vector<QPDFObjectHandle> part7;
2779 2721 std::vector<QPDFObjectHandle> part8;
2780 2722 std::vector<QPDFObjectHandle> part9;
2781   - getLinearizedParts(obj, part4, part6, part7, part8, part9);
  2723 + lin.parts(obj, part4, part6, part7, part8, part9);
2782 2724  
2783 2725 // Object number sequence:
2784 2726 //
... ...
libqpdf/QPDF_linearization.cc
... ... @@ -1681,7 +1681,7 @@ Lin::pushOutlinesToPart(
1681 1681 }
1682 1682  
1683 1683 void
1684   -Lin::getLinearizedParts(
  1684 +Lin::parts(
1685 1685 QPDFWriter::ObjTable const& obj,
1686 1686 std::vector<QPDFObjectHandle>& part4,
1687 1687 std::vector<QPDFObjectHandle>& part6,
... ...
libqpdf/QPDF_objects.cc
... ... @@ -1916,7 +1916,7 @@ QPDF::swapObjects(QPDFObjGen og1, QPDFObjGen og2)
1916 1916 }
1917 1917  
1918 1918 size_t
1919   -Objects::tableSize()
  1919 +Objects::table_size()
1920 1920 {
1921 1921 // If obj_cache is dense, accommodate all object in tables,else accommodate only original
1922 1922 // objects.
... ... @@ -1936,20 +1936,20 @@ Objects::tableSize()
1936 1936 }
1937 1937  
1938 1938 std::vector<QPDFObjGen>
1939   -Objects::getCompressibleObjVector()
  1939 +Objects::compressible_vector()
1940 1940 {
1941   - return getCompressibleObjGens<QPDFObjGen>();
  1941 + return compressible<QPDFObjGen>();
1942 1942 }
1943 1943  
1944 1944 std::vector<bool>
1945   -Objects::getCompressibleObjSet()
  1945 +Objects::compressible_set()
1946 1946 {
1947   - return getCompressibleObjGens<bool>();
  1947 + return compressible<bool>();
1948 1948 }
1949 1949  
1950 1950 template <typename T>
1951 1951 std::vector<T>
1952   -Objects::getCompressibleObjGens()
  1952 +Objects::compressible()
1953 1953 {
1954 1954 // Return a list of objects that are allowed to be in object streams. Walk through the objects
1955 1955 // by traversing the document from the root, including a traversal of the pages tree. This
... ... @@ -1969,10 +1969,9 @@ Objects::getCompressibleObjGens()
1969 1969 std::vector<T> result;
1970 1970 if constexpr (std::is_same_v<T, QPDFObjGen>) {
1971 1971 result.reserve(m->obj_cache.size());
1972   - } else if constexpr (std::is_same_v<T, bool>) {
1973   - result.resize(max_obj + 1U, false);
1974 1972 } else {
1975   - throw std::logic_error("Unsupported type in QPDF::getCompressibleObjGens");
  1973 + qpdf_static_expect(std::is_same_v<T, bool>);
  1974 + result.resize(max_obj + 1U, false);
1976 1975 }
1977 1976 while (!queue.empty()) {
1978 1977 auto obj = queue.back();
... ...
libqpdf/qpdf/QPDF_private.hh
... ... @@ -573,7 +573,7 @@ class QPDF::Doc::Linearization: Common
573 573  
574 574 // Get lists of all objects in order according to the part of a linearized file that they
575 575 // belong to.
576   - void getLinearizedParts(
  576 + void parts(
577 577 QPDFWriter::ObjTable const& obj,
578 578 std::vector<QPDFObjectHandle>& part4,
579 579 std::vector<QPDFObjectHandle>& part6,
... ... @@ -993,18 +993,19 @@ class QPDF::Doc::Objects: Common
993 993 QPDFObjectHandle makeIndirectFromQPDFObject(std::shared_ptr<QPDFObject> const& obj);
994 994 std::shared_ptr<QPDFObject> getObjectForParser(int id, int gen, bool parse_pdf);
995 995 std::shared_ptr<QPDFObject> getObjectForJSON(int id, int gen);
996   - size_t tableSize();
  996 + size_t table_size();
997 997  
998 998 // For QPDFWriter:
999 999  
1000   - std::map<QPDFObjGen, QPDFXRefEntry> const& getXRefTableInternal();
  1000 + std::map<QPDFObjGen, QPDFXRefEntry> const& xref_table();
  1001 + std::vector<QPDFObjGen> compressible_vector();
  1002 + std::vector<bool> compressible_set();
  1003 +
  1004 + private:
1001 1005 // Get a list of objects that would be permitted in an object stream.
1002 1006 template <typename T>
1003   - std::vector<T> getCompressibleObjGens();
1004   - std::vector<QPDFObjGen> getCompressibleObjVector();
1005   - std::vector<bool> getCompressibleObjSet();
  1007 + std::vector<T> compressible();
1006 1008  
1007   - private:
1008 1009 void setTrailer(QPDFObjectHandle obj);
1009 1010 void reconstruct_xref(QPDFExc& e, bool found_startxref = true);
1010 1011 void read_xref(qpdf_offset_t offset, bool in_stream_recovery = false);
... ...