Commit bc1c4bb57864c4dbe9b7e42a77e0653c0d473071

Authored by Jay Berkenbilt
1 parent ed6a56a3

Add QPDF::processFile that takes an open FILE*

ChangeLog
  1 +2012-06-21 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * libqpdf/QPDF.cc: new processFile method that takes an open FILE*
  4 + instead of a filename.
  5 +
1 6 2012-06-20 Jay Berkenbilt <ejb@ql.org>
2 7  
3 8 * Add new array mutation routines to QPDFObjectHandle.
... ...
include/qpdf/QPDF.hh
... ... @@ -52,6 +52,14 @@ class QPDF
52 52 QPDF_DLL
53 53 void processFile(char const* filename, char const* password = 0);
54 54  
  55 + // Parse a PDF from a stdio FILE*. The FILE must be open in
  56 + // binary mode and must be seekable. It may be open read only.
  57 + // This works exactly like processFile except that the PDF file is
  58 + // read from an already opened FILE*. The caller is responsible
  59 + // for closing the file.
  60 + QPDF_DLL
  61 + void processFile(FILE* file, char const* password = 0);
  62 +
55 63 // Parse a PDF file loaded into a memory buffer. This works
56 64 // exactly like processFile except that the PDF file is in memory
57 65 // instead of on disk. The description appears in any warning or
... ... @@ -400,6 +408,7 @@ class QPDF
400 408 public:
401 409 FileInputSource();
402 410 void setFilename(char const* filename);
  411 + void setFile(FILE* filep);
403 412 virtual ~FileInputSource();
404 413 virtual std::string const& getName() const;
405 414 virtual off_t tell();
... ... @@ -414,6 +423,7 @@ class QPDF
414 423  
415 424 void destroy();
416 425  
  426 + bool close_file;
417 427 std::string filename;
418 428 FILE* file;
419 429 };
... ...
libqpdf/QPDF.cc
... ... @@ -80,6 +80,7 @@ QPDF::InputSource::readLine()
80 80 }
81 81  
82 82 QPDF::FileInputSource::FileInputSource() :
  83 + close_file(false),
83 84 file(0)
84 85 {
85 86 }
... ... @@ -89,10 +90,21 @@ QPDF::FileInputSource::setFilename(char const* filename)
89 90 {
90 91 destroy();
91 92 this->filename = filename;
  93 + this->close_file = true;
92 94 this->file = QUtil::fopen_wrapper(std::string("open ") + this->filename,
93 95 fopen(this->filename.c_str(), "rb"));
94 96 }
95 97  
  98 +void
  99 +QPDF::FileInputSource::setFile(FILE* f)
  100 +{
  101 + destroy();
  102 + this->filename = "stdio FILE";
  103 + this->close_file = false;
  104 + this->file = f;
  105 + this->seek(0, SEEK_SET);
  106 +}
  107 +
96 108 QPDF::FileInputSource::~FileInputSource()
97 109 {
98 110 destroy();
... ... @@ -101,7 +113,7 @@ QPDF::FileInputSource::~FileInputSource()
101 113 void
102 114 QPDF::FileInputSource::destroy()
103 115 {
104   - if (this->file)
  116 + if (this->file && this->close_file)
105 117 {
106 118 fclose(this->file);
107 119 this->file = 0;
... ... @@ -317,6 +329,15 @@ QPDF::processFile(char const* filename, char const* password)
317 329 }
318 330  
319 331 void
  332 +QPDF::processFile(FILE* filep, char const* password)
  333 +{
  334 + FileInputSource* fi = new FileInputSource();
  335 + this->file = fi;
  336 + fi->setFile(filep);
  337 + parse(password);
  338 +}
  339 +
  340 +void
320 341 QPDF::processMemoryFile(char const* description,
321 342 char const* buf, size_t length,
322 343 char const* password)
... ...
qpdf/qpdf.testcov
... ... @@ -200,3 +200,6 @@ qpdf-c set_info_key to null 0
200 200 qpdf-c set-info-key use existing info 0
201 201 qpdf-c add info to trailer 0
202 202 qpdf-c called qpdf_init_write_memory 0
  203 +exercise processFile(name) 0
  204 +exercise processFile(FILE*) 0
  205 +exercise processMemoryFile 0
... ...
qpdf/test_driver.cc
... ... @@ -60,17 +60,29 @@ void runtest(int n, char const* filename)
60 60 {
61 61 QPDF pdf;
62 62 PointerHolder<char> file_buf;
  63 + FILE* filep = 0;
63 64 if (n == 0)
64 65 {
65 66 pdf.setAttemptRecovery(false);
66 67 }
67 68 if (n % 2 == 0)
68 69 {
69   - pdf.processFile(filename);
  70 + if (n % 4 == 0)
  71 + {
  72 + QTC::TC("qpdf", "exercise processFile(name)");
  73 + pdf.processFile(filename);
  74 + }
  75 + else
  76 + {
  77 + QTC::TC("qpdf", "exercise processFile(FILE*)");
  78 + filep = QUtil::fopen_wrapper(std::string("open ") + filename,
  79 + fopen(filename, "rb"));
  80 + pdf.processFile(filep);
  81 + }
70 82 }
71 83 else
72 84 {
73   - // Exercise processMemoryFile
  85 + QTC::TC("qpdf", "exercise processMemoryFile");
74 86 FILE* f = QUtil::fopen_wrapper(std::string("open ") + filename,
75 87 fopen(filename, "rb"));
76 88 fseek(f, 0, SEEK_END);
... ... @@ -623,6 +635,10 @@ void runtest(int n, char const* filename)
623 635 QUtil::int_to_string(n));
624 636 }
625 637  
  638 + if (filep)
  639 + {
  640 + fclose(filep);
  641 + }
626 642 std::cout << "test " << n << " done" << std::endl;
627 643 }
628 644  
... ...