Allow reading from InputSource and writing to Pipeline

Allowing users to subclass InputSource and Pipeline to read and write
from/to arbitrary sources provides the maximum flexibility for users
who want to read and write from other than files or memory.
This commit is contained in:
Jay Berkenbilt 2012-09-23 17:42:26 -04:00
parent 8c99e4a6c0
commit 041397fdab
8 changed files with 64 additions and 7 deletions

View File

@ -1,3 +1,10 @@
2012-09-23 Jay Berkenbilt <ejb@ql.org>
* Add public methods QPDF::processInputSource and
QPDFWriter::setOutputPipeline to allow users to read from custom
input sources and to write to custom pipelines. This allows the
maximum flexibility in sources for reading and writing PDF files.
2012-09-06 Jay Berkenbilt <ejb@ql.org>
* 3.0.2: release

View File

@ -72,6 +72,13 @@ class QPDF
char const* buf, size_t length,
char const* password = 0);
// Parse a PDF file loaded from a custom InputSource. If you have
// your own method of retrieving a PDF file, you can subclass
// InputSource and use this method.
QPDF_DLL
void processInputSource(PointerHolder<InputSource>,
char const* password = 0);
// Create a QPDF object for an empty PDF. This PDF has no pages
// or objects other than a minimal trailer, a document catalog,
// and a /Pages tree containing zero pages. Pages and other

View File

@ -95,6 +95,15 @@ class QPDFWriter
QPDF_DLL
Buffer* getBuffer();
// Supply your own pipeline object. Output will be written to
// this pipeline, and QPDFWriter will call finish() on the
// pipeline. It is the caller's responsibility to manage the
// memory for the pipeline. The pipeline is never deleted by
// QPDFWriter, which makes it possible for you to call additional
// methods on the pipeline after the writing is finished.
QPDF_DLL
void setOutputPipeline(Pipeline*);
// Setting Parameters
// Set the value of object stream mode. In disable mode, we never

View File

@ -138,9 +138,8 @@ void
QPDF::processFile(char const* filename, char const* password)
{
FileInputSource* fi = new FileInputSource();
this->file = fi;
fi->setFilename(filename);
parse(password);
processInputSource(fi, password);
}
void
@ -148,9 +147,8 @@ QPDF::processFile(char const* description, FILE* filep,
bool close_file, char const* password)
{
FileInputSource* fi = new FileInputSource();
this->file = fi;
fi->setFile(description, filep, close_file);
parse(password);
processInputSource(fi, password);
}
void
@ -158,10 +156,18 @@ QPDF::processMemoryFile(char const* description,
char const* buf, size_t length,
char const* password)
{
this->file =
processInputSource(
new BufferInputSource(description,
new Buffer((unsigned char*)buf, length),
true);
true),
password);
}
void
QPDF::processInputSource(PointerHolder<InputSource> source,
char const* password)
{
this->file = source;
parse(password);
}

View File

@ -134,6 +134,13 @@ QPDFWriter::getBuffer()
return result;
}
void
QPDFWriter::setOutputPipeline(Pipeline* p)
{
this->filename = "custom pipeline";
initializePipelineStack(p);
}
void
QPDFWriter::setObjectStreamMode(qpdf_object_stream_e mode)
{

View File

@ -149,7 +149,7 @@ $td->runtest("remove page we don't have",
$td->NORMALIZE_NEWLINES);
# ----------
$td->notify("--- Miscellaneous Tests ---");
$n_tests += 53;
$n_tests += 55;
$td->runtest("qpdf version",
{$td->COMMAND => "qpdf --version"},
@ -403,6 +403,13 @@ $td->runtest("check output",
$td->runtest("check output",
{$td->FILE => "d.pdf"},
{$td->FILE => "extra-header-lin-newline.pdf"});
$td->runtest("output to custom pipeline",
{$td->COMMAND => "test_driver 33 minimal.pdf"},
{$td->STRING => "test 33 done\n", $td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
$td->runtest("check output",
{$td->FILE => "a.pdf"},
{$td->FILE => "custom-pipeline.pdf"});
show_ntests();
# ----------

Binary file not shown.

View File

@ -1112,6 +1112,20 @@ void runtest(int n, char const* filename1, char const* filename2)
w.write();
}
}
else if (n == 33)
{
// Test writing to a custom pipeline
Pl_Buffer p("buffer");
QPDFWriter w(pdf);
w.setStaticID(true);
w.setOutputPipeline(&p);
w.write();
PointerHolder<Buffer> b = p.getBuffer();
FILE* f = QUtil::fopen_wrapper("open a.pdf",
fopen("a.pdf", "wb"));
fwrite(b->getBuffer(), b->getSize(), 1, f);
fclose(f);
}
else
{
throw std::runtime_error(std::string("invalid test ") +