summaryrefslogtreecommitdiffstats
path: root/libqpdf/QPDF.cc
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/QPDF.cc
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/QPDF.cc')
-rw-r--r--libqpdf/QPDF.cc314
1 files changed, 2 insertions, 312 deletions
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),