Add QUtil::pipe_file and QUtil::file_provider

This commit is contained in:
Jay Berkenbilt 2021-02-07 16:54:16 -05:00
parent efdd46da51
commit 553ac7f353
5 changed files with 63 additions and 1 deletions

View File

@ -1,3 +1,8 @@
2021-02-07 Jay Berkenbilt <ejb@ql.org>
* Add new functions QUtil::pipe_file and QUtil::file_provider for
sending the contents of a file through a pipeline as binary data.
2021-02-04 Jay Berkenbilt <ejb@ql.org>
* Add new option --pasword-file=file for reading the decryption

View File

@ -34,6 +34,7 @@
#include <time.h>
class RandomDataProvider;
class Pipeline;
namespace QUtil
{
@ -119,6 +120,18 @@ namespace QUtil
QPDF_DLL
void rename_file(char const* oldname, char const* newname);
// Write the contents of filename as a binary file to the
// pipeline.
QPDF_DLL
void
pipe_file(char const* filename, Pipeline* p);
// Return a function that will send the contents of the given file
// through the given pipeline as binary data.
QPDF_DLL
std::function<void(Pipeline*)>
file_provider(std::string const& filename);
QPDF_DLL
char* copy_string(std::string const&);

View File

@ -7,6 +7,7 @@
#include <qpdf/QPDFSystemError.hh>
#include <qpdf/QTC.hh>
#include <qpdf/QIntC.hh>
#include <qpdf/Pipeline.hh>
#include <cmath>
#include <iomanip>
@ -612,6 +613,35 @@ QUtil::rename_file(char const* oldname, char const* newname)
#endif
}
void
QUtil::pipe_file(char const* filename, Pipeline* p)
{
// Exercised in test suite by testing file_provider.
FILE* f = safe_fopen(filename, "rb");
FileCloser fc(f);
size_t len = 0;
int constexpr size = 8192;
unsigned char buf[size];
while ((len = fread(buf, 1, size, f)) > 0)
{
p->write(buf, len);
}
p->finish();
if (ferror(f))
{
throw std::runtime_error(
std::string("failure reading file ") + filename);
}
}
std::function<void(Pipeline*)>
QUtil::file_provider(std::string const& filename)
{
return [filename](Pipeline* p) {
pipe_file(filename.c_str(), p);
};
}
char*
QUtil::copy_string(std::string const& str)
{
@ -1018,6 +1048,7 @@ QUtil::read_file_into_memory(
PointerHolder<char>& file_buf, size_t& size)
{
FILE* f = safe_fopen(filename, "rb");
FileCloser fc(f);
fseek(f, 0, SEEK_END);
size = QIntC::to_size(QUtil::tell(f));
fseek(f, 0, SEEK_SET);
@ -1048,7 +1079,6 @@ QUtil::read_file_into_memory(
uint_to_string(size));
}
}
fclose(f);
}
static bool read_char_from_FILE(char& ch, FILE* f)

View File

@ -6,6 +6,7 @@
#include <qpdf/QUtil.hh>
#include <qpdf/PointerHolder.hh>
#include <qpdf/QPDFSystemError.hh>
#include <qpdf/Pl_Buffer.hh>
#include <string.h>
#include <limits.h>
#include <assert.h>
@ -483,6 +484,12 @@ void read_from_file_test()
assert(memcmp(p, "This file is used for qutil testing.", 36) == 0);
assert(p[59] == static_cast<char>(13));
assert(memcmp(p + 24641, "very long.", 10) == 0);
Pl_Buffer b2("buffer");
// QUtil::file_provider also exercises QUtil::pipe_file
QUtil::file_provider("other-file")(&b2);
auto buf2 = b2.getBuffer();
assert(buf2->getSize() == size);
assert(memcmp(buf2->getBuffer(), p, size) == 0);
}
void assert_hex_encode(std::string const& input, std::string const& expected)

View File

@ -4964,6 +4964,13 @@ print "\n";
read/write implementation of name and number trees.
</para>
</listitem>
<listitem>
<para>
Add new functions <function>QUtil::pipe_file</function> and
<function>QUtil::file_provider</function> for sending the
contents of a file through a pipeline as binary data.
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>