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/BufferInputSource.cc | 141 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 libqpdf/BufferInputSource.cc (limited to 'libqpdf/BufferInputSource.cc') 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 +#include +#include + +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; + } +} -- cgit v1.2.3-54-g00ecf