From cee2592ed1f1c8ac5ca3048c48ac082e47358a6b Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Wed, 10 Jul 2013 11:07:40 -0400 Subject: [PATCH] Change API/ABI and withdraw 4.2.0 --- ChangeLog | 20 +++++++++++++++++++- TODO | 21 +++++++-------------- include/qpdf/QPDF.hh | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------- libqpdf/QPDF.cc | 24 ------------------------ libqpdf/QPDFWriter.cc | 13 +++++++------ 5 files changed, 101 insertions(+), 84 deletions(-) diff --git a/ChangeLog b/ChangeLog index a5f0aa1..15b337b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,24 @@ +2013-07-10 Jay Berkenbilt + + * 4.2.0 turned out to be binary incompatible on some platforms + even though there were no changes to the public API. Therefore + the 4.2.0 release has been withdrawn, and is being replaced with a + 5.0.0 release that acknowledges the ABI change and also removes + some problematic methods from the public API. + + * Remove methods from public API that were only intended to be + used by QPDFWriter and really didn't make sense to call from + anywhere else as they required internal knowledge that only + QPDFWriter had: + - QPDF::getLinearizedParts + - QPDF::generateHintStream + - QPDF::getObjectStreamData + - QPDF::getCompressibleObjGens + - QPDF::getCompressibleObjects + 2013-07-07 Jay Berkenbilt - * 4.2.0: release + * 4.2.0: release [withdrawn] * Ignore error case of a stream's decode parameters having invalid length when there are no stream filters. diff --git a/TODO b/TODO index 1749b84..6df0fcf 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,12 @@ -4.3.0 +5.1.0 ===== + * Figure out what about a3576a73593987b26cd3eff346f8f7c11f713cbd + broke binary compatibility. + + * Implement automated testing for binary compatibility and add to + release checklist. + * Add method to push inheritable resources to a single page by walking up and copying without overwrite. Above logic will also be sufficient to fix the limitation in @@ -55,19 +61,6 @@ -Next ABI change -=============== - - * Remove QPDF::getCompressibleObjects() - - * For public QPDF methods that are only public so QPDFWriter can - call them, make them private and provide a nested caller class with - QPDFWriter as a friend for access just like is being done now for - some other methods. This will reduce the risk that future changes - in the interface between QPDFWriter and QPDF will result in - breaking ABI changes. - - General ======= diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh index b90dea3..e30e467 100644 --- a/include/qpdf/QPDF.hh +++ b/include/qpdf/QPDF.hh @@ -411,45 +411,6 @@ class QPDF void optimize(std::map const& object_stream_data, bool allow_changes = true); - // For QPDFWriter: - - // Get lists of all objects in order according to the part of a - // linearized file that they belong to. - QPDF_DLL - void getLinearizedParts( - std::map const& object_stream_data, - std::vector& part4, - std::vector& part6, - std::vector& part7, - std::vector& part8, - std::vector& part9); - - QPDF_DLL - void generateHintStream(std::map const& xref, - std::map const& lengths, - std::map const& obj_renumber, - PointerHolder& hint_stream, - int& S, int& O); - - // Map object to object stream that contains it - QPDF_DLL - void getObjectStreamData(std::map&); - - // Get a list of objects that would be permitted in an object - // stream. - QPDF_DLL - std::vector getCompressibleObjGens(); - - // Deprecated: get a list of objects that would be permitted in an - // object stream. This method is deprecated and will be removed. - // It's incorrect because it disregards the generations of the - // compressible objects, which can lead (and has lead) to bugs. - // This method will throw an exception if any of the objects - // returned have a generation of other than zero. Use - // getCompressibleObjGens() instead. - QPDF_DLL - std::vector getCompressibleObjects(); - // Convenience routines for common functions. See also // QPDFObjectHandle.hh for additional convenience routines. @@ -504,6 +465,49 @@ class QPDF QPDF_DLL void removePage(QPDFObjectHandle page); + // Writer class is restricted to QPDFWriter so that only it can + // call certain methods. + class Writer + { + friend class QPDFWriter; + private: + + static void getLinearizedParts( + QPDF& qpdf, + std::map const& object_stream_data, + std::vector& part4, + std::vector& part6, + std::vector& part7, + std::vector& part8, + std::vector& part9) + { + qpdf.getLinearizedParts(object_stream_data, + part4, part6, part7, part8, part9); + } + + static void generateHintStream( + QPDF& qpdf, + std::map const& xref, + std::map const& lengths, + std::map const& obj_renumber, + PointerHolder& hint_stream, + int& S, int& O) + { + return qpdf.generateHintStream(xref, lengths, obj_renumber, + hint_stream, S, O); + } + + static void getObjectStreamData(QPDF& qpdf, std::map& omap) + { + qpdf.getObjectStreamData(omap); + } + + static std::vector getCompressibleObjGens(QPDF& qpdf) + { + return qpdf.getCompressibleObjGens(); + } + }; + // Resolver class is restricted to QPDFObjectHandle so that only // it can resolve indirect references. class Resolver @@ -635,6 +639,31 @@ class QPDF QPDFObjectHandle dict, Pipeline* pipeline); + // For QPDFWriter: + + // Get lists of all objects in order according to the part of a + // linearized file that they belong to. + void getLinearizedParts( + std::map const& object_stream_data, + std::vector& part4, + std::vector& part6, + std::vector& part7, + std::vector& part8, + std::vector& part9); + + void generateHintStream(std::map const& xref, + std::map const& lengths, + std::map const& obj_renumber, + PointerHolder& hint_stream, + int& S, int& O); + + // Map object to object stream that contains it + void getObjectStreamData(std::map&); + + // Get a list of objects that would be permitted in an object + // stream. + std::vector getCompressibleObjGens(); + // methods to support page handling void getAllPagesInternal(QPDFObjectHandle cur_pages, diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc index 2bdfa96..1126b5f 100644 --- a/libqpdf/QPDF.cc +++ b/libqpdf/QPDF.cc @@ -1952,30 +1952,6 @@ QPDF::getObjectStreamData(std::map& omap) } } -std::vector -QPDF::getCompressibleObjects() -{ - std::vector objects = getCompressibleObjGens(); - std::vector result; - for (std::vector::iterator iter = objects.begin(); - iter != objects.end(); ++iter) - { - if ((*iter).getGen() != 0) - { - throw std::logic_error( - "QPDF::getCompressibleObjects() would return an object ID" - " for an object with generation != 0. Use" - " QPDF::getCompressibleObjGens() instead." - " See comments in QPDF.hh."); - } - else - { - result.push_back((*iter).getObj()); - } - } - return result; -} - std::vector QPDF::getCompressibleObjGens() { diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc index 499129b..863e753 100644 --- a/libqpdf/QPDFWriter.cc +++ b/libqpdf/QPDFWriter.cc @@ -1913,7 +1913,7 @@ QPDFWriter::preserveObjectStreams() // must have generation 0 because the PDF spec does not provide // any way to do otherwise. std::map omap; - this->pdf.getObjectStreamData(omap); + QPDF::Writer::getObjectStreamData(this->pdf, omap); for (std::map::iterator iter = omap.begin(); iter != omap.end(); ++iter) { @@ -1936,7 +1936,7 @@ QPDFWriter::generateObjectStreams() // This code doesn't do anything with /Extends. std::vector const& eligible = - this->pdf.getCompressibleObjGens(); + QPDF::Writer::getCompressibleObjGens(this->pdf); unsigned int n_object_streams = (eligible.size() + 99) / 100; unsigned int n_per = eligible.size() / n_object_streams; if (n_per * n_object_streams < eligible.size()) @@ -2339,8 +2339,8 @@ QPDFWriter::writeHintStream(int hint_id) PointerHolder hint_buffer; int S = 0; int O = 0; - pdf.generateHintStream( - this->xref, this->lengths, this->obj_renumber_no_gen, + QPDF::Writer::generateHintStream( + this->pdf, this->xref, this->lengths, this->obj_renumber_no_gen, hint_buffer, S, O); openObject(hint_id); @@ -2610,8 +2610,9 @@ QPDFWriter::writeLinearized() std::vector part7; std::vector part8; std::vector part9; - pdf.getLinearizedParts(this->object_to_object_stream_no_gen, - part4, part6, part7, part8, part9); + QPDF::Writer::getLinearizedParts( + this->pdf, this->object_to_object_stream_no_gen, + part4, part6, part7, part8, part9); // Object number sequence: // -- libgit2 0.21.4