From 15eaed5c52c85dd97ce5bc829817c5535c527207 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sat, 21 Jul 2012 05:37:14 -0400 Subject: Refactor: pull *InputSource out of QPDF InputSource, FileInputSource, and BufferInputSource are now top-level classes instead of privately nested inside QPDF. --- libqpdf/QPDF.cc | 314 +------------------------------------------------------- 1 file changed, 2 insertions(+), 312 deletions(-) (limited to 'libqpdf/QPDF.cc') 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 #include #include +#include +#include #include #include @@ -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 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), -- cgit v1.2.3-70-g09d2