mirror of
https://github.com/qpdf/qpdf.git
synced 2024-11-16 01:27:07 +00:00
79f6b4823b
Have classes contain only a single private member of type PointerHolder<Members>. This makes it safe to change the structure of the Members class without breaking binary compatibility. Many of the classes already follow this pattern quite successfully. This brings in the rest of the class that are part of the public API.
171 lines
3.8 KiB
C++
171 lines
3.8 KiB
C++
#include <qpdf/BufferInputSource.hh>
|
|
#include <qpdf/QIntC.hh>
|
|
#include <string.h>
|
|
#include <stdexcept>
|
|
#include <algorithm>
|
|
|
|
BufferInputSource::Members::Members(bool own_memory,
|
|
std::string const& description,
|
|
Buffer* buf) :
|
|
own_memory(own_memory),
|
|
description(description),
|
|
buf(buf),
|
|
cur_offset(0)
|
|
{
|
|
}
|
|
|
|
BufferInputSource::Members::~Members()
|
|
{
|
|
}
|
|
|
|
BufferInputSource::BufferInputSource(std::string const& description,
|
|
Buffer* buf, bool own_memory) :
|
|
m(new Members(own_memory, description, buf))
|
|
{
|
|
}
|
|
|
|
BufferInputSource::BufferInputSource(std::string const& description,
|
|
std::string const& contents) :
|
|
m(new Members(true, description, 0))
|
|
{
|
|
this->m->buf = new Buffer(contents.length());
|
|
unsigned char* bp = this->m->buf->getBuffer();
|
|
memcpy(bp, contents.c_str(), contents.length());
|
|
}
|
|
|
|
BufferInputSource::~BufferInputSource()
|
|
{
|
|
if (this->m->own_memory)
|
|
{
|
|
delete this->m->buf;
|
|
}
|
|
}
|
|
|
|
qpdf_offset_t const
|
|
BufferInputSource::bufSizeAsOffset() const
|
|
{
|
|
return QIntC::to_offset(this->m->buf->getSize());
|
|
}
|
|
|
|
qpdf_offset_t
|
|
BufferInputSource::findAndSkipNextEOL()
|
|
{
|
|
if (this->m->cur_offset < 0)
|
|
{
|
|
throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0");
|
|
}
|
|
qpdf_offset_t end_pos = bufSizeAsOffset();
|
|
if (this->m->cur_offset >= end_pos)
|
|
{
|
|
this->last_offset = end_pos;
|
|
this->m->cur_offset = end_pos;
|
|
return end_pos;
|
|
}
|
|
|
|
qpdf_offset_t result = 0;
|
|
size_t len = QIntC::to_size(end_pos - this->m->cur_offset);
|
|
unsigned char const* buffer = this->m->buf->getBuffer();
|
|
|
|
void* start = const_cast<unsigned char*>(buffer) + this->m->cur_offset;
|
|
unsigned char* p1 = static_cast<unsigned char*>(memchr(start, '\r', len));
|
|
unsigned char* p2 = static_cast<unsigned char*>(memchr(start, '\n', len));
|
|
unsigned char* p = (p1 && p2) ? std::min(p1, p2) : p1 ? p1 : p2;
|
|
if (p)
|
|
{
|
|
result = p - buffer;
|
|
this->m->cur_offset = result + 1;
|
|
++p;
|
|
while ((this->m->cur_offset < end_pos) &&
|
|
((*p == '\r') || (*p == '\n')))
|
|
{
|
|
++p;
|
|
++this->m->cur_offset;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this->m->cur_offset = end_pos;
|
|
result = end_pos;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
std::string const&
|
|
BufferInputSource::getName() const
|
|
{
|
|
return this->m->description;
|
|
}
|
|
|
|
qpdf_offset_t
|
|
BufferInputSource::tell()
|
|
{
|
|
return this->m->cur_offset;
|
|
}
|
|
|
|
void
|
|
BufferInputSource::seek(qpdf_offset_t offset, int whence)
|
|
{
|
|
switch (whence)
|
|
{
|
|
case SEEK_SET:
|
|
this->m->cur_offset = offset;
|
|
break;
|
|
|
|
case SEEK_END:
|
|
this->m->cur_offset = bufSizeAsOffset() + offset;
|
|
break;
|
|
|
|
case SEEK_CUR:
|
|
this->m->cur_offset += offset;
|
|
break;
|
|
|
|
default:
|
|
throw std::logic_error(
|
|
"INTERNAL ERROR: invalid argument to BufferInputSource::seek");
|
|
break;
|
|
}
|
|
|
|
if (this->m->cur_offset < 0)
|
|
{
|
|
throw std::runtime_error(
|
|
this->m->description + ": seek before beginning of buffer");
|
|
}
|
|
}
|
|
|
|
void
|
|
BufferInputSource::rewind()
|
|
{
|
|
this->m->cur_offset = 0;
|
|
}
|
|
|
|
size_t
|
|
BufferInputSource::read(char* buffer, size_t length)
|
|
{
|
|
if (this->m->cur_offset < 0)
|
|
{
|
|
throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0");
|
|
}
|
|
qpdf_offset_t end_pos = bufSizeAsOffset();
|
|
if (this->m->cur_offset >= end_pos)
|
|
{
|
|
this->last_offset = end_pos;
|
|
return 0;
|
|
}
|
|
|
|
this->last_offset = this->m->cur_offset;
|
|
size_t len = std::min(
|
|
QIntC::to_size(end_pos - this->m->cur_offset), length);
|
|
memcpy(buffer, this->m->buf->getBuffer() + this->m->cur_offset, len);
|
|
this->m->cur_offset += QIntC::to_offset(len);
|
|
return len;
|
|
}
|
|
|
|
void
|
|
BufferInputSource::unreadCh(char ch)
|
|
{
|
|
if (this->m->cur_offset > 0)
|
|
{
|
|
--this->m->cur_offset;
|
|
}
|
|
}
|