aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2012-07-21 11:37:14 +0200
committerJay Berkenbilt <ejb@ql.org>2012-07-21 15:06:06 +0200
commit15eaed5c52c85dd97ce5bc829817c5535c527207 (patch)
tree9114c410414102d7de50184fb4866f8e881a33cc /libqpdf
parent8657c6f00489b5c26fc0c00f2fc91c5682acbe95 (diff)
downloadqpdf-15eaed5c52c85dd97ce5bc829817c5535c527207.tar.zst
Refactor: pull *InputSource out of QPDF
InputSource, FileInputSource, and BufferInputSource are now top-level classes instead of privately nested inside QPDF.
Diffstat (limited to 'libqpdf')
-rw-r--r--libqpdf/BufferInputSource.cc141
-rw-r--r--libqpdf/FileInputSource.cc141
-rw-r--r--libqpdf/InputSource.cc41
-rw-r--r--libqpdf/QPDF.cc314
-rw-r--r--libqpdf/build.mk3
5 files changed, 328 insertions, 312 deletions
diff --git a/libqpdf/BufferInputSource.cc b/libqpdf/BufferInputSource.cc
new file mode 100644
index 00000000..6909dce2
--- /dev/null
+++ b/libqpdf/BufferInputSource.cc
@@ -0,0 +1,141 @@
+#include <qpdf/BufferInputSource.hh>
+#include <string.h>
+#include <stdexcept>
+
+BufferInputSource::BufferInputSource(std::string const& description,
+ Buffer* buf, bool own_memory) :
+ own_memory(own_memory),
+ description(description),
+ buf(buf),
+ cur_offset(0)
+{
+}
+
+BufferInputSource::~BufferInputSource()
+{
+ if (own_memory)
+ {
+ delete this->buf;
+ }
+}
+
+qpdf_offset_t
+BufferInputSource::findAndSkipNextEOL()
+{
+ if (this->cur_offset < 0)
+ {
+ throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0");
+ }
+ qpdf_offset_t end_pos = (qpdf_offset_t) this->buf->getSize();
+ if (this->cur_offset >= end_pos)
+ {
+ this->last_offset = end_pos;
+ this->cur_offset = end_pos;
+ return end_pos;
+ }
+
+ qpdf_offset_t result = 0;
+ size_t len = (size_t)(end_pos - this->cur_offset);
+ unsigned char const* buffer = this->buf->getBuffer();
+
+ void* start = (void*)(buffer + this->cur_offset);
+ unsigned char* p1 = (unsigned char*)memchr(start, '\r', len);
+ unsigned char* p2 = (unsigned char*)memchr(start, '\n', len);
+ unsigned char* p = (p1 && p2) ? std::min(p1, p2) : p1 ? p1 : p2;
+ if (p)
+ {
+ result = p - buffer;
+ this->cur_offset = result + 1;
+ ++p;
+ while ((this->cur_offset < end_pos) &&
+ ((*p == '\r') || (*p == '\n')))
+ {
+ ++p;
+ ++this->cur_offset;
+ }
+ }
+ else
+ {
+ this->cur_offset = end_pos;
+ result = end_pos;
+ }
+ return result;
+}
+
+std::string const&
+BufferInputSource::getName() const
+{
+ return this->description;
+}
+
+qpdf_offset_t
+BufferInputSource::tell()
+{
+ return this->cur_offset;
+}
+
+void
+BufferInputSource::seek(qpdf_offset_t offset, int whence)
+{
+ switch (whence)
+ {
+ case SEEK_SET:
+ this->cur_offset = offset;
+ break;
+
+ case SEEK_END:
+ this->cur_offset = (qpdf_offset_t)this->buf->getSize() + offset;
+ break;
+
+ case SEEK_CUR:
+ this->cur_offset += offset;
+ break;
+
+ default:
+ throw std::logic_error(
+ "INTERNAL ERROR: invalid argument to BufferInputSource::seek");
+ break;
+ }
+
+ if (this->cur_offset < 0)
+ {
+ throw std::runtime_error(
+ this->description + ": seek before beginning of buffer");
+ }
+}
+
+void
+BufferInputSource::rewind()
+{
+ this->cur_offset = 0;
+}
+
+size_t
+BufferInputSource::read(char* buffer, size_t length)
+{
+ if (this->cur_offset < 0)
+ {
+ throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0");
+ }
+ qpdf_offset_t end_pos = (qpdf_offset_t) this->buf->getSize();
+ if (this->cur_offset >= end_pos)
+ {
+ this->last_offset = end_pos;
+ return 0;
+ }
+
+ this->last_offset = this->cur_offset;
+ size_t len = std::min((size_t)(end_pos - this->cur_offset), length);
+ memcpy(buffer, buf->getBuffer() + this->cur_offset, len);
+ this->cur_offset += len;
+ return len;
+}
+
+void
+BufferInputSource::unreadCh(char ch)
+{
+ if (this->cur_offset > 0)
+ {
+ --this->cur_offset;
+ }
+}
diff --git a/libqpdf/FileInputSource.cc b/libqpdf/FileInputSource.cc
new file mode 100644
index 00000000..b1f7b5d2
--- /dev/null
+++ b/libqpdf/FileInputSource.cc
@@ -0,0 +1,141 @@
+#include <qpdf/FileInputSource.hh>
+#include <string.h>
+#include <qpdf/QUtil.hh>
+#include <qpdf/QPDFExc.hh>
+
+FileInputSource::FileInputSource() :
+ close_file(false),
+ file(0)
+{
+}
+
+void
+FileInputSource::setFilename(char const* filename)
+{
+ destroy();
+ this->filename = filename;
+ this->close_file = true;
+ this->file = QUtil::fopen_wrapper(std::string("open ") + this->filename,
+ fopen(this->filename.c_str(), "rb"));
+}
+
+void
+FileInputSource::setFile(
+ char const* description, FILE* filep, bool close_file)
+{
+ destroy();
+ this->filename = description;
+ this->close_file = close_file;
+ this->file = filep;
+ this->seek(0, SEEK_SET);
+}
+
+FileInputSource::~FileInputSource()
+{
+ destroy();
+}
+
+void
+FileInputSource::destroy()
+{
+ if (this->file && this->close_file)
+ {
+ fclose(this->file);
+ this->file = 0;
+ }
+}
+
+qpdf_offset_t
+FileInputSource::findAndSkipNextEOL()
+{
+ qpdf_offset_t result = 0;
+ bool done = false;
+ char buf[10240];
+ while (! done)
+ {
+ qpdf_offset_t cur_offset = QUtil::tell(this->file);
+ size_t len = this->read(buf, sizeof(buf));
+ if (len == 0)
+ {
+ done = true;
+ result = this->tell();
+ }
+ else
+ {
+ char* p1 = (char*)memchr((void*)buf, '\r', len);
+ char* p2 = (char*)memchr((void*)buf, '\n', len);
+ char* p = (p1 && p2) ? std::min(p1, p2) : p1 ? p1 : p2;
+ if (p)
+ {
+ result = cur_offset + (p - buf);
+ // We found \r or \n. Keep reading until we get past
+ // \r and \n characters.
+ this->seek(result + 1, SEEK_SET);
+ char ch;
+ while (! done)
+ {
+ if (this->read(&ch, 1) == 0)
+ {
+ done = true;
+ }
+ else if (! ((ch == '\r') || (ch == '\n')))
+ {
+ this->unreadCh(ch);
+ done = true;
+ }
+ }
+ }
+ }
+ }
+ return result;
+}
+
+std::string const&
+FileInputSource::getName() const
+{
+ return this->filename;
+}
+
+qpdf_offset_t
+FileInputSource::tell()
+{
+ return QUtil::tell(this->file);
+}
+
+void
+FileInputSource::seek(qpdf_offset_t offset, int whence)
+{
+ QUtil::os_wrapper(std::string("seek to ") + this->filename + ", offset " +
+ QUtil::int_to_string(offset) + " (" +
+ QUtil::int_to_string(whence) + ")",
+ QUtil::seek(this->file, offset, whence));
+}
+
+void
+FileInputSource::rewind()
+{
+ ::rewind(this->file);
+}
+
+size_t
+FileInputSource::read(char* buffer, size_t length)
+{
+ this->last_offset = QUtil::tell(this->file);
+ size_t len = fread(buffer, 1, length, this->file);
+ if ((len == 0) && ferror(this->file))
+ {
+ throw QPDFExc(qpdf_e_system,
+ this->filename, "",
+ this->last_offset,
+ std::string("read ") +
+ QUtil::int_to_string(length) + " bytes");
+ }
+ return len;
+}
+
+void
+FileInputSource::unreadCh(char ch)
+{
+ QUtil::os_wrapper(this->filename + ": unread character",
+ ungetc((unsigned char)ch, this->file));
+}
diff --git a/libqpdf/InputSource.cc b/libqpdf/InputSource.cc
new file mode 100644
index 00000000..79c889bf
--- /dev/null
+++ b/libqpdf/InputSource.cc
@@ -0,0 +1,41 @@
+#include <qpdf/InputSource.hh>
+#include <string.h>
+#include <qpdf/PointerHolder.hh>
+
+void
+InputSource::setLastOffset(qpdf_offset_t offset)
+{
+ this->last_offset = offset;
+}
+
+qpdf_offset_t
+InputSource::getLastOffset() const
+{
+ return this->last_offset;
+}
+
+std::string
+InputSource::readLine(size_t max_line_length)
+{
+ // Return at most max_line_length characters from the next line.
+ // Lines are terminated by one or more \r or \n characters.
+ // Consume the trailing newline characters but don't return them.
+ // After this is called, the file will be positioned after a line
+ // terminator or at the end of the file, and last_offset will
+ // point to position the file had when this method was called.
+
+ qpdf_offset_t offset = this->tell();
+ char* buf = new char[max_line_length + 1];
+ PointerHolder<char> bp(true, buf);
+ memset(buf, '\0', max_line_length + 1);
+ this->read(buf, max_line_length);
+ this->seek(offset, SEEK_SET);
+ qpdf_offset_t eol = this->findAndSkipNextEOL();
+ this->last_offset = offset;
+ size_t line_length = eol - offset;
+ if (line_length < max_line_length)
+ {
+ buf[line_length] = '\0';
+ }
+ return std::string(buf);
+}
diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc
index 1a8a689d..43757735 100644
--- a/libqpdf/QPDF.cc
+++ b/libqpdf/QPDF.cc
@@ -11,6 +11,8 @@
#include <qpdf/PCRE.hh>
#include <qpdf/Pipeline.hh>
#include <qpdf/Pl_Discard.hh>
+#include <qpdf/FileInputSource.hh>
+#include <qpdf/BufferInputSource.hh>
#include <qpdf/QPDFExc.hh>
#include <qpdf/QPDF_Null.hh>
@@ -36,318 +38,6 @@ static char const* EMPTY_PDF =
"110\n"
"%%EOF\n";
-void
-QPDF::InputSource::setLastOffset(qpdf_offset_t offset)
-{
- this->last_offset = offset;
-}
-
-qpdf_offset_t
-QPDF::InputSource::getLastOffset() const
-{
- return this->last_offset;
-}
-
-std::string
-QPDF::InputSource::readLine(size_t max_line_length)
-{
- // Return at most max_line_length characters from the next line.
- // Lines are terminated by one or more \r or \n characters.
- // Consume the trailing newline characters but don't return them.
- // After this is called, the file will be positioned after a line
- // terminator or at the end of the file, and last_offset will
- // point to position the file had when this method was called.
-
- qpdf_offset_t offset = this->tell();
- char* buf = new char[max_line_length + 1];
- PointerHolder<char> bp(true, buf);
- memset(buf, '\0', max_line_length + 1);
- this->read(buf, max_line_length);
- this->seek(offset, SEEK_SET);
- qpdf_offset_t eol = this->findAndSkipNextEOL();
- this->last_offset = offset;
- size_t line_length = eol - offset;
- if (line_length < max_line_length)
- {
- buf[line_length] = '\0';
- }
- return std::string(buf);
-}
-
-QPDF::FileInputSource::FileInputSource() :
- close_file(false),
- file(0)
-{
-}
-
-void
-QPDF::FileInputSource::setFilename(char const* filename)
-{
- destroy();
- this->filename = filename;
- this->close_file = true;
- this->file = QUtil::fopen_wrapper(std::string("open ") + this->filename,
- fopen(this->filename.c_str(), "rb"));
-}
-
-void
-QPDF::FileInputSource::setFile(
- char const* description, FILE* filep, bool close_file)
-{
- destroy();
- this->filename = description;
- this->close_file = close_file;
- this->file = filep;
- this->seek(0, SEEK_SET);
-}
-
-QPDF::FileInputSource::~FileInputSource()
-{
- destroy();
-}
-
-void
-QPDF::FileInputSource::destroy()
-{
- if (this->file && this->close_file)
- {
- fclose(this->file);
- this->file = 0;
- }
-}
-
-qpdf_offset_t
-QPDF::FileInputSource::findAndSkipNextEOL()
-{
- qpdf_offset_t result = 0;
- bool done = false;
- char buf[10240];
- while (! done)
- {
- qpdf_offset_t cur_offset = QUtil::tell(this->file);
- size_t len = this->read(buf, sizeof(buf));
- if (len == 0)
- {
- done = true;
- result = this->tell();
- }
- else
- {
- char* p1 = (char*)memchr((void*)buf, '\r', len);
- char* p2 = (char*)memchr((void*)buf, '\n', len);
- char* p = (p1 && p2) ? std::min(p1, p2) : p1 ? p1 : p2;
- if (p)
- {
- result = cur_offset + (p - buf);
- // We found \r or \n. Keep reading until we get past
- // \r and \n characters.
- this->seek(result + 1, SEEK_SET);
- char ch;
- while (! done)
- {
- if (this->read(&ch, 1) == 0)
- {
- done = true;
- }
- else if (! ((ch == '\r') || (ch == '\n')))
- {
- this->unreadCh(ch);
- done = true;
- }
- }
- }
- }
- }
- return result;
-}
-
-std::string const&
-QPDF::FileInputSource::getName() const
-{
- return this->filename;
-}
-
-qpdf_offset_t
-QPDF::FileInputSource::tell()
-{
- return QUtil::tell(this->file);
-}
-
-void
-QPDF::FileInputSource::seek(qpdf_offset_t offset, int whence)
-{
- QUtil::os_wrapper(std::string("seek to ") + this->filename + ", offset " +
- QUtil::int_to_string(offset) + " (" +
- QUtil::int_to_string(whence) + ")",
- QUtil::seek(this->file, offset, whence));
-}
-
-void
-QPDF::FileInputSource::rewind()
-{
- ::rewind(this->file);
-}
-
-size_t
-QPDF::FileInputSource::read(char* buffer, size_t length)
-{
- this->last_offset = QUtil::tell(this->file);
- size_t len = fread(buffer, 1, length, this->file);
- if ((len == 0) && ferror(this->file))
- {
- throw QPDFExc(qpdf_e_system,
- this->filename, "",
- this->last_offset,
- std::string("read ") +
- QUtil::int_to_string(length) + " bytes");
- }
- return len;
-}
-
-void
-QPDF::FileInputSource::unreadCh(char ch)
-{
- QUtil::os_wrapper(this->filename + ": unread character",
- ungetc((unsigned char)ch, this->file));
-}
-
-QPDF::BufferInputSource::BufferInputSource(std::string const& description,
- Buffer* buf, bool own_memory) :
- own_memory(own_memory),
- description(description),
- buf(buf),
- cur_offset(0)
-{
-}
-
-QPDF::BufferInputSource::~BufferInputSource()
-{
- if (own_memory)
- {
- delete this->buf;
- }
-}
-
-qpdf_offset_t
-QPDF::BufferInputSource::findAndSkipNextEOL()
-{
- if (this->cur_offset < 0)
- {
- throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0");
- }
- qpdf_offset_t end_pos = (qpdf_offset_t) this->buf->getSize();
- if (this->cur_offset >= end_pos)
- {
- this->last_offset = end_pos;
- this->cur_offset = end_pos;
- return end_pos;
- }
-
- qpdf_offset_t result = 0;
- size_t len = (size_t)(end_pos - this->cur_offset);
- unsigned char const* buffer = this->buf->getBuffer();
-
- void* start = (void*)(buffer + this->cur_offset);
- unsigned char* p1 = (unsigned char*)memchr(start, '\r', len);
- unsigned char* p2 = (unsigned char*)memchr(start, '\n', len);
- unsigned char* p = (p1 && p2) ? std::min(p1, p2) : p1 ? p1 : p2;
- if (p)
- {
- result = p - buffer;
- this->cur_offset = result + 1;
- ++p;
- while ((this->cur_offset < end_pos) &&
- ((*p == '\r') || (*p == '\n')))
- {
- ++p;
- ++this->cur_offset;
- }
- }
- else
- {
- this->cur_offset = end_pos;
- result = end_pos;
- }
- return result;
-}
-
-std::string const&
-QPDF::BufferInputSource::getName() const
-{
- return this->description;
-}
-
-qpdf_offset_t
-QPDF::BufferInputSource::tell()
-{
- return this->cur_offset;
-}
-
-void
-QPDF::BufferInputSource::seek(qpdf_offset_t offset, int whence)
-{
- switch (whence)
- {
- case SEEK_SET:
- this->cur_offset = offset;
- break;
-
- case SEEK_END:
- this->cur_offset = (qpdf_offset_t)this->buf->getSize() + offset;
- break;
-
- case SEEK_CUR:
- this->cur_offset += offset;
- break;
-
- default:
- throw std::logic_error(
- "INTERNAL ERROR: invalid argument to BufferInputSource::seek");
- break;
- }
-
- if (this->cur_offset < 0)
- {
- throw std::runtime_error(
- this->description + ": seek before beginning of buffer");
- }
-}
-
-void
-QPDF::BufferInputSource::rewind()
-{
- this->cur_offset = 0;
-}
-
-size_t
-QPDF::BufferInputSource::read(char* buffer, size_t length)
-{
- if (this->cur_offset < 0)
- {
- throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0");
- }
- qpdf_offset_t end_pos = (qpdf_offset_t) this->buf->getSize();
- if (this->cur_offset >= end_pos)
- {
- this->last_offset = end_pos;
- return 0;
- }
-
- this->last_offset = this->cur_offset;
- size_t len = std::min((size_t)(end_pos - this->cur_offset), length);
- memcpy(buffer, buf->getBuffer() + this->cur_offset, len);
- this->cur_offset += len;
- return len;
-}
-
-void
-QPDF::BufferInputSource::unreadCh(char ch)
-{
- if (this->cur_offset > 0)
- {
- --this->cur_offset;
- }
-}
QPDF::ObjGen::ObjGen(int o = 0, int g = 0) :
obj(o),
diff --git a/libqpdf/build.mk b/libqpdf/build.mk
index 422878f2..cc379b63 100644
--- a/libqpdf/build.mk
+++ b/libqpdf/build.mk
@@ -8,6 +8,9 @@ SRCS_libqpdf = \
libqpdf/BitStream.cc \
libqpdf/BitWriter.cc \
libqpdf/Buffer.cc \
+ libqpdf/BufferInputSource.cc \
+ libqpdf/FileInputSource.cc \
+ libqpdf/InputSource.cc \
libqpdf/MD5.cc \
libqpdf/PCRE.cc \
libqpdf/Pipeline.cc \