Skip to content

Commit

Permalink
Change list to vector for outline helpers (fixes qpdf#297)
Browse files Browse the repository at this point in the history
This change works around STL problems with Embarcadero C++ Builder
version 10.2, but std::vector is more common than std::list in qpdf,
and this is a relatively new API, so an API change is tolerable.

Thanks to Thorsten Schöning <[email protected]>
for the fix.
  • Loading branch information
ams-tschoening authored and jberkenbilt committed Jul 4, 2019
1 parent 4db1de9 commit 8f06da7
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 25 deletions.
10 changes: 10 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
2019-07-03 Jay Berkenbilt <[email protected]>

* Non-compatible API change: change
QPDFOutlineDocumentHelper::getTopLevelOutlines and
QPDFOutlineObjectHelper::getKids to return a std::vector instead
of a std::list of QPDFOutlineObjectHelper objects. This is to work
around bugs with some compilers' STL implementations that are
choking with list here. There's no deep reason for these to be
lists instead of vectors. Fixes #297.

2019-06-22 Jay Berkenbilt <[email protected]>

* Handle encrypted files with missing or invalid /Length entries
Expand Down
6 changes: 3 additions & 3 deletions examples/pdf-bookmarks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -135,16 +135,16 @@ void show_bookmark_details(QPDFOutlineObjectHelper outline,
std::cout << outline.getTitle() << std::endl;
}

void extract_bookmarks(std::list<QPDFOutlineObjectHelper> outlines,
void extract_bookmarks(std::vector<QPDFOutlineObjectHelper> outlines,
std::vector<int>& numbers)
{
numbers.push_back(0);
for (std::list<QPDFOutlineObjectHelper>::iterator iter = outlines.begin();
for (std::vector<QPDFOutlineObjectHelper>::iterator iter = outlines.begin();
iter != outlines.end(); ++iter)
{
++(numbers.back());
show_bookmark_details(*iter, numbers);
std::list<QPDFOutlineObjectHelper>::iterator next = iter;
std::vector<QPDFOutlineObjectHelper>::iterator next = iter;
++next;
bool has_next = (next != outlines.end());
if ((style == st_lines) && (! has_next))
Expand Down
6 changes: 3 additions & 3 deletions fuzz/qpdf_fuzzer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -170,13 +170,13 @@ void
FuzzHelper::testOutlines()
{
PointerHolder<QPDF> q = getQpdf();
std::list<std::list<QPDFOutlineObjectHelper> > queue;
std::list<std::vector<QPDFOutlineObjectHelper> > queue;
QPDFOutlineDocumentHelper odh(*q);
queue.push_back(odh.getTopLevelOutlines());
while (! queue.empty())
{
std::list<QPDFOutlineObjectHelper>& outlines = *(queue.begin());
for (std::list<QPDFOutlineObjectHelper>::iterator iter =
std::vector<QPDFOutlineObjectHelper>& outlines = *(queue.begin());
for (std::vector<QPDFOutlineObjectHelper>::iterator iter =
outlines.begin();
iter != outlines.end(); ++iter)
{
Expand Down
10 changes: 5 additions & 5 deletions include/qpdf/QPDFOutlineDocumentHelper.hh
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@

#include <qpdf/QPDF.hh>
#include <map>
#include <list>
#include <set>
#include <vector>

#include <qpdf/DLL.h>

Expand All @@ -51,7 +51,7 @@ class QPDFOutlineDocumentHelper: public QPDFDocumentHelper
bool hasOutlines();

QPDF_DLL
std::list<QPDFOutlineObjectHelper> getTopLevelOutlines();
std::vector<QPDFOutlineObjectHelper> getTopLevelOutlines();

// If the name is a name object, look it up in the /Dests key of
// the document catalog. If the name is a string, look it up in
Expand All @@ -64,7 +64,7 @@ class QPDFOutlineDocumentHelper: public QPDFDocumentHelper
// Return a list outlines that are known to target the specified
// page
QPDF_DLL
std::list<QPDFOutlineObjectHelper> getOutlinesForPage(QPDFObjGen const&);
std::vector<QPDFOutlineObjectHelper> getOutlinesForPage(QPDFObjGen const&);

class Accessor
{
Expand Down Expand Up @@ -95,11 +95,11 @@ class QPDFOutlineDocumentHelper: public QPDFDocumentHelper
Members();
Members(Members const&);

std::list<QPDFOutlineObjectHelper> outlines;
std::vector<QPDFOutlineObjectHelper> outlines;
std::set<QPDFObjGen> seen;
QPDFObjectHandle dest_dict;
PointerHolder<QPDFNameTreeObjectHelper> names_dest;
std::map<QPDFObjGen, std::list<QPDFOutlineObjectHelper> > by_page;
std::map<QPDFObjGen, std::vector<QPDFOutlineObjectHelper> > by_page;
};

PointerHolder<Members> m;
Expand Down
6 changes: 3 additions & 3 deletions include/qpdf/QPDFOutlineObjectHelper.hh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

#include <qpdf/QPDFObjectHelper.hh>
#include <qpdf/QPDFObjGen.hh>
#include <list>
#include <vector>

class QPDFOutlineDocumentHelper;

Expand Down Expand Up @@ -55,7 +55,7 @@ class QPDFOutlineObjectHelper: public QPDFObjectHelper

// Return children as a list.
QPDF_DLL
std::list<QPDFOutlineObjectHelper> getKids();
std::vector<QPDFOutlineObjectHelper> getKids();

// Return the destination, regardless of whether it is named or
// explicit and whether it is directly provided or in a GoTo
Expand Down Expand Up @@ -113,7 +113,7 @@ class QPDFOutlineObjectHelper: public QPDFObjectHelper

QPDFOutlineDocumentHelper& dh;
PointerHolder<QPDFOutlineObjectHelper> parent;
std::list<QPDFOutlineObjectHelper> kids;
std::vector<QPDFOutlineObjectHelper> kids;
};

PointerHolder<Members> m;
Expand Down
8 changes: 4 additions & 4 deletions libqpdf/QPDFOutlineDocumentHelper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ QPDFOutlineDocumentHelper::hasOutlines()
return ! this->m->outlines.empty();
}

std::list<QPDFOutlineObjectHelper>
std::vector<QPDFOutlineObjectHelper>
QPDFOutlineDocumentHelper::getTopLevelOutlines()
{
return this->m->outlines;
Expand All @@ -59,19 +59,19 @@ QPDFOutlineDocumentHelper::initializeByPage()
QPDFOutlineObjectHelper oh = queue.front();
queue.pop_front();
this->m->by_page[oh.getDestPage().getObjGen()].push_back(oh);
std::list<QPDFOutlineObjectHelper> kids = oh.getKids();
std::vector<QPDFOutlineObjectHelper> kids = oh.getKids();
queue.insert(queue.end(), kids.begin(), kids.end());
}
}

std::list<QPDFOutlineObjectHelper>
std::vector<QPDFOutlineObjectHelper>
QPDFOutlineDocumentHelper::getOutlinesForPage(QPDFObjGen const& og)
{
if (this->m->by_page.empty())
{
initializeByPage();
}
std::list<QPDFOutlineObjectHelper> result;
std::vector<QPDFOutlineObjectHelper> result;
if (this->m->by_page.count(og))
{
result = this->m->by_page[og];
Expand Down
2 changes: 1 addition & 1 deletion libqpdf/QPDFOutlineObjectHelper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ QPDFOutlineObjectHelper::getParent()
return this->m->parent;
}

std::list<QPDFOutlineObjectHelper>
std::vector<QPDFOutlineObjectHelper>
QPDFOutlineObjectHelper::getKids()
{
return this->m->kids;
Expand Down
10 changes: 10 additions & 0 deletions manual/qpdf-manual.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4314,6 +4314,16 @@ print "\n";
higher level methods for tokenizing content streams.
</para>
</listitem>
<listitem>
<para>
Change
<function>QPDFOutlineDocumentHelper::getTopLevelOutlines</function>
and <function>QPDFOutlineObjectHelper::getKids</function> to
return a <type>std::vector</type> instead of a
<type>std::list</type> of
<classname>QPDFOutlineObjectHelper</classname> objects.
</para>
</listitem>
<listitem>
<para>
When <command>qpdf --check</command> or <command>qpdf
Expand Down
8 changes: 4 additions & 4 deletions qpdf/qpdf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3493,9 +3493,9 @@ static void do_json_pages(QPDF& pdf, Options& o, JSON& j)
"label", pldh.getLabelForPage(pageno).getJSON());
JSON j_outlines = j_page.addDictionaryMember(
"outlines", JSON::makeArray());
std::list<QPDFOutlineObjectHelper> outlines =
std::vector<QPDFOutlineObjectHelper> outlines =
odh.getOutlinesForPage(page.getObjGen());
for (std::list<QPDFOutlineObjectHelper>::iterator oiter =
for (std::vector<QPDFOutlineObjectHelper>::iterator oiter =
outlines.begin();
oiter != outlines.end(); ++oiter)
{
Expand Down Expand Up @@ -3543,10 +3543,10 @@ static void do_json_page_labels(QPDF& pdf, Options& o, JSON& j)
}

static void add_outlines_to_json(
std::list<QPDFOutlineObjectHelper> outlines, JSON& j,
std::vector<QPDFOutlineObjectHelper> outlines, JSON& j,
std::map<QPDFObjGen, int>& page_numbers)
{
for (std::list<QPDFOutlineObjectHelper>::iterator iter = outlines.begin();
for (std::vector<QPDFOutlineObjectHelper>::iterator iter = outlines.begin();
iter != outlines.end(); ++iter)
{
QPDFOutlineObjectHelper& ol = *iter;
Expand Down
4 changes: 2 additions & 2 deletions qpdf/test_driver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1805,9 +1805,9 @@ void runtest(int n, char const* filename1, char const* arg2)
for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin();
iter != pages.end(); ++iter, ++pageno)
{
std::list<QPDFOutlineObjectHelper> outlines =
std::vector<QPDFOutlineObjectHelper> outlines =
odh.getOutlinesForPage((*iter).getObjectHandle().getObjGen());
for (std::list<QPDFOutlineObjectHelper>::iterator oiter =
for (std::vector<QPDFOutlineObjectHelper>::iterator oiter =
outlines.begin();
oiter != outlines.end(); ++oiter)
{
Expand Down

0 comments on commit 8f06da7

Please sign in to comment.