mirror of
https://github.com/qpdf/qpdf.git
synced 2025-02-02 11:58:25 +00:00
Refactor: pull *InputSource out of QPDF
InputSource, FileInputSource, and BufferInputSource are now top-level classes instead of privately nested inside QPDF.
This commit is contained in:
parent
8657c6f004
commit
15eaed5c52
28
include/qpdf/BufferInputSource.hh
Normal file
28
include/qpdf/BufferInputSource.hh
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef __QPDF_BUFFERINPUTSOURCE_HH__
|
||||
#define __QPDF_BUFFERINPUTSOURCE_HH__
|
||||
|
||||
#include <qpdf/InputSource.hh>
|
||||
#include <qpdf/Buffer.hh>
|
||||
|
||||
class BufferInputSource: public InputSource
|
||||
{
|
||||
public:
|
||||
BufferInputSource(std::string const& description, Buffer* buf,
|
||||
bool own_memory = false);
|
||||
virtual ~BufferInputSource();
|
||||
virtual qpdf_offset_t findAndSkipNextEOL();
|
||||
virtual std::string const& getName() const;
|
||||
virtual qpdf_offset_t tell();
|
||||
virtual void seek(qpdf_offset_t offset, int whence);
|
||||
virtual void rewind();
|
||||
virtual size_t read(char* buffer, size_t length);
|
||||
virtual void unreadCh(char ch);
|
||||
|
||||
private:
|
||||
bool own_memory;
|
||||
std::string description;
|
||||
Buffer* buf;
|
||||
qpdf_offset_t cur_offset;
|
||||
};
|
||||
|
||||
#endif // __QPDF_BUFFERINPUTSOURCE_HH__
|
32
include/qpdf/FileInputSource.hh
Normal file
32
include/qpdf/FileInputSource.hh
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef __QPDF_FILEINPUTSOURCE_HH__
|
||||
#define __QPDF_FILEINPUTSOURCE_HH__
|
||||
|
||||
#include <qpdf/InputSource.hh>
|
||||
|
||||
class FileInputSource: public InputSource
|
||||
{
|
||||
public:
|
||||
FileInputSource();
|
||||
void setFilename(char const* filename);
|
||||
void setFile(char const* description, FILE* filep, bool close_file);
|
||||
virtual ~FileInputSource();
|
||||
virtual qpdf_offset_t findAndSkipNextEOL();
|
||||
virtual std::string const& getName() const;
|
||||
virtual qpdf_offset_t tell();
|
||||
virtual void seek(qpdf_offset_t offset, int whence);
|
||||
virtual void rewind();
|
||||
virtual size_t read(char* buffer, size_t length);
|
||||
virtual void unreadCh(char ch);
|
||||
|
||||
private:
|
||||
FileInputSource(FileInputSource const&);
|
||||
FileInputSource& operator=(FileInputSource const&);
|
||||
|
||||
void destroy();
|
||||
|
||||
bool close_file;
|
||||
std::string filename;
|
||||
FILE* file;
|
||||
};
|
||||
|
||||
#endif // __QPDF_FILEINPUTSOURCE_HH__
|
35
include/qpdf/InputSource.hh
Normal file
35
include/qpdf/InputSource.hh
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef __QPDF_INPUTSOURCE_HH__
|
||||
#define __QPDF_INPUTSOURCE_HH__
|
||||
|
||||
#include <qpdf/Types.h>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
class InputSource
|
||||
{
|
||||
public:
|
||||
InputSource() :
|
||||
last_offset(0)
|
||||
{
|
||||
}
|
||||
virtual ~InputSource()
|
||||
{
|
||||
}
|
||||
|
||||
void setLastOffset(qpdf_offset_t);
|
||||
qpdf_offset_t getLastOffset() const;
|
||||
std::string readLine(size_t max_line_length);
|
||||
|
||||
virtual qpdf_offset_t findAndSkipNextEOL() = 0;
|
||||
virtual std::string const& getName() const = 0;
|
||||
virtual qpdf_offset_t tell() = 0;
|
||||
virtual void seek(qpdf_offset_t offset, int whence) = 0;
|
||||
virtual void rewind() = 0;
|
||||
virtual size_t read(char* buffer, size_t length) = 0;
|
||||
virtual void unreadCh(char ch) = 0;
|
||||
|
||||
protected:
|
||||
qpdf_offset_t last_offset;
|
||||
};
|
||||
|
||||
#endif // __QPDF_INPUTSOURCE_HH__
|
@ -21,6 +21,7 @@
|
||||
#include <qpdf/QPDFObjectHandle.hh>
|
||||
#include <qpdf/QPDFTokenizer.hh>
|
||||
#include <qpdf/Buffer.hh>
|
||||
#include <qpdf/InputSource.hh>
|
||||
|
||||
class QPDF_Stream;
|
||||
class BitStream;
|
||||
@ -474,80 +475,6 @@ class QPDF
|
||||
private:
|
||||
static std::string qpdf_version;
|
||||
|
||||
class InputSource
|
||||
{
|
||||
public:
|
||||
InputSource() :
|
||||
last_offset(0)
|
||||
{
|
||||
}
|
||||
virtual ~InputSource()
|
||||
{
|
||||
}
|
||||
|
||||
void setLastOffset(qpdf_offset_t);
|
||||
qpdf_offset_t getLastOffset() const;
|
||||
std::string readLine(size_t max_line_length);
|
||||
|
||||
virtual qpdf_offset_t findAndSkipNextEOL() = 0;
|
||||
virtual std::string const& getName() const = 0;
|
||||
virtual qpdf_offset_t tell() = 0;
|
||||
virtual void seek(qpdf_offset_t offset, int whence) = 0;
|
||||
virtual void rewind() = 0;
|
||||
virtual size_t read(char* buffer, size_t length) = 0;
|
||||
virtual void unreadCh(char ch) = 0;
|
||||
|
||||
protected:
|
||||
qpdf_offset_t last_offset;
|
||||
};
|
||||
|
||||
class FileInputSource: public InputSource
|
||||
{
|
||||
public:
|
||||
FileInputSource();
|
||||
void setFilename(char const* filename);
|
||||
void setFile(char const* description, FILE* filep, bool close_file);
|
||||
virtual ~FileInputSource();
|
||||
virtual qpdf_offset_t findAndSkipNextEOL();
|
||||
virtual std::string const& getName() const;
|
||||
virtual qpdf_offset_t tell();
|
||||
virtual void seek(qpdf_offset_t offset, int whence);
|
||||
virtual void rewind();
|
||||
virtual size_t read(char* buffer, size_t length);
|
||||
virtual void unreadCh(char ch);
|
||||
|
||||
private:
|
||||
FileInputSource(FileInputSource const&);
|
||||
FileInputSource& operator=(FileInputSource const&);
|
||||
|
||||
void destroy();
|
||||
|
||||
bool close_file;
|
||||
std::string filename;
|
||||
FILE* file;
|
||||
};
|
||||
|
||||
class BufferInputSource: public InputSource
|
||||
{
|
||||
public:
|
||||
BufferInputSource(std::string const& description, Buffer* buf,
|
||||
bool own_memory = false);
|
||||
virtual ~BufferInputSource();
|
||||
virtual qpdf_offset_t findAndSkipNextEOL();
|
||||
virtual std::string const& getName() const;
|
||||
virtual qpdf_offset_t tell();
|
||||
virtual void seek(qpdf_offset_t offset, int whence);
|
||||
virtual void rewind();
|
||||
virtual size_t read(char* buffer, size_t length);
|
||||
virtual void unreadCh(char ch);
|
||||
|
||||
private:
|
||||
bool own_memory;
|
||||
std::string description;
|
||||
Buffer* buf;
|
||||
qpdf_offset_t cur_offset;
|
||||
};
|
||||
|
||||
class ObjGen
|
||||
{
|
||||
public:
|
||||
|
141
libqpdf/BufferInputSource.cc
Normal file
141
libqpdf/BufferInputSource.cc
Normal file
@ -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;
|
||||
}
|
||||
}
|
141
libqpdf/FileInputSource.cc
Normal file
141
libqpdf/FileInputSource.cc
Normal file
@ -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));
|
||||
}
|
41
libqpdf/InputSource.cc
Normal file
41
libqpdf/InputSource.cc
Normal file
@ -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);
|
||||
}
|
314
libqpdf/QPDF.cc
314
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),
|
||||
|
@ -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 \
|
||||
|
Loading…
x
Reference in New Issue
Block a user