2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-12-22 19:08:59 +00:00

Refactor QPDF::emptyPDF

This commit is contained in:
m-holger 2024-08-13 16:18:04 +01:00
parent 39abb11376
commit 88fd7ca99a
2 changed files with 40 additions and 32 deletions

View File

@ -32,67 +32,51 @@
// being static as well. // being static as well.
std::string const QPDF::qpdf_version(QPDF_VERSION); std::string const QPDF::qpdf_version(QPDF_VERSION);
static char const* EMPTY_PDF = (
// force line break
"%PDF-1.3\n"
"1 0 obj\n"
"<< /Type /Catalog /Pages 2 0 R >>\n"
"endobj\n"
"2 0 obj\n"
"<< /Type /Pages /Kids [] /Count 0 >>\n"
"endobj\n"
"xref\n"
"0 3\n"
"0000000000 65535 f \n"
"0000000009 00000 n \n"
"0000000058 00000 n \n"
"trailer << /Size 3 /Root 1 0 R >>\n"
"startxref\n"
"110\n"
"%%EOF\n");
namespace namespace
{ {
class InvalidInputSource: public InputSource class InvalidInputSource final: public InputSource
{ {
public: public:
~InvalidInputSource() override = default; InvalidInputSource(std::string const& name) :
name(name)
{
}
~InvalidInputSource() final = default;
qpdf_offset_t qpdf_offset_t
findAndSkipNextEOL() override findAndSkipNextEOL() final
{ {
throwException(); throwException();
return 0; return 0;
} }
std::string const& std::string const&
getName() const override getName() const final
{ {
static std::string name("closed input source");
return name; return name;
} }
qpdf_offset_t qpdf_offset_t
tell() override tell() final
{ {
throwException(); throwException();
return 0; return 0;
} }
void void
seek(qpdf_offset_t offset, int whence) override seek(qpdf_offset_t offset, int whence) final
{ {
throwException(); throwException();
} }
void void
rewind() override rewind() final
{ {
throwException(); throwException();
} }
size_t size_t
read(char* buffer, size_t length) override read(char* buffer, size_t length) final
{ {
throwException(); throwException();
return 0; return 0;
} }
void void
unreadCh(char ch) override unreadCh(char ch) final
{ {
throwException(); throwException();
} }
@ -105,6 +89,8 @@ namespace
"source. QPDF operations are invalid before processFile (or " "source. QPDF operations are invalid before processFile (or "
"another process method) or after closeInputSource"); "another process method) or after closeInputSource");
} }
std::string const& name;
}; };
} // namespace } // namespace
@ -198,7 +184,7 @@ QPDF::EncryptionParameters::EncryptionParameters() :
QPDF::Members::Members(QPDF& qpdf) : QPDF::Members::Members(QPDF& qpdf) :
log(QPDFLogger::defaultLogger()), log(QPDFLogger::defaultLogger()),
file_sp(new InvalidInputSource()), file_sp(new InvalidInputSource(no_input_name)),
file(file_sp.get()), file(file_sp.get()),
encp(new EncryptionParameters), encp(new EncryptionParameters),
xref_table(qpdf, file) xref_table(qpdf, file)
@ -278,7 +264,8 @@ QPDF::processInputSource(std::shared_ptr<InputSource> source, char const* passwo
void void
QPDF::closeInputSource() QPDF::closeInputSource()
{ {
m->file_sp = std::shared_ptr<InputSource>(new InvalidInputSource()); m->no_input_name = "closed input source";
m->file_sp = std::shared_ptr<InputSource>(new InvalidInputSource(m->no_input_name));
m->file = m->file_sp.get(); m->file = m->file_sp.get();
} }
@ -291,7 +278,9 @@ QPDF::setPasswordIsHexKey(bool val)
void void
QPDF::emptyPDF() QPDF::emptyPDF()
{ {
processMemoryFile("empty PDF", EMPTY_PDF, strlen(EMPTY_PDF)); m->pdf_version = "1.3";
m->no_input_name = "empty PDF";
m->xref_table.initialize_empty();
} }
void void
@ -489,6 +478,22 @@ QPDF::warn(
warn(QPDFExc(error_code, getFilename(), object, offset, message)); warn(QPDFExc(error_code, getFilename(), object, offset, message));
} }
void
QPDF::Xref_table::initialize_empty()
{
initialized_ = true;
trailer_ = QPDFObjectHandle::newDictionary();
auto rt = qpdf.makeIndirectObject(QPDFObjectHandle::newDictionary());
auto pgs = qpdf.makeIndirectObject(QPDFObjectHandle::newDictionary());
pgs.replaceKey("/Type", QPDFObjectHandle::newName("/Pages"));
pgs.replaceKey("/Kids", QPDFObjectHandle::newArray());
pgs.replaceKey("/Count", QPDFObjectHandle::newInteger(0));
rt.replaceKey("/Type", QPDFObjectHandle::newName("/Catalog"));
rt.replaceKey("/Pages", pgs);
trailer_.replaceKey("/Root", rt);
trailer_.replaceKey("/Size", QPDFObjectHandle::newInteger(3));
}
void void
QPDF::Xref_table::initialize() QPDF::Xref_table::initialize()
{ {

View File

@ -15,6 +15,7 @@ class QPDF::Xref_table
} }
void initialize(); void initialize();
void initialize_empty();
void reconstruct(QPDFExc& e); void reconstruct(QPDFExc& e);
void show(); void show();
bool resolve(); bool resolve();
@ -640,6 +641,8 @@ class QPDF::Members
std::shared_ptr<QPDFLogger> log; std::shared_ptr<QPDFLogger> log;
unsigned long long unique_id{0}; unsigned long long unique_id{0};
QPDFTokenizer tokenizer; QPDFTokenizer tokenizer;
// Filename to use if there is no input PDF
std::string no_input_name{"closed input source"};
// If file_sp is updated, file must also be updated. // If file_sp is updated, file must also be updated.
std::shared_ptr<InputSource> file_sp; std::shared_ptr<InputSource> file_sp;
InputSource* file; InputSource* file;