2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-12-22 10:58:58 +00:00

Add methods InputSource::fastRead, fastUnRead and fastTell

Provide buffered input for QPDFTokenizer.
This commit is contained in:
m-holger 2022-08-26 23:55:56 +01:00
parent 13ef50cd27
commit 69a5fb7047
2 changed files with 71 additions and 5 deletions

View File

@ -93,6 +93,12 @@ class QPDF_DLL_CLASS InputSource
// efficient.
virtual void unreadCh(char ch) = 0;
// The following methods are for use by QPDFTokenizer
inline qpdf_offset_t fastTell();
inline bool fastRead(char&);
inline void fastUnread(bool);
inline void loadBuffer();
protected:
qpdf_offset_t last_offset;
@ -111,6 +117,68 @@ class QPDF_DLL_CLASS InputSource
};
std::shared_ptr<Members> m;
// State for fast... methods
static const qpdf_offset_t buf_size = 128;
char buffer[buf_size];
qpdf_offset_t buf_len = 0;
qpdf_offset_t buf_idx = 0;
qpdf_offset_t buf_start = 0;
};
inline void
InputSource::loadBuffer()
{
this->buf_idx = 0;
this->buf_len = qpdf_offset_t(read(this->buffer, this->buf_size));
// NB read sets last_offset
this->buf_start = this->last_offset;
}
inline qpdf_offset_t
InputSource::fastTell()
{
if (this->buf_len == 0) {
loadBuffer();
} else {
auto curr = tell();
if (curr < this->buf_start ||
curr >= (this->buf_start + this->buf_len)) {
loadBuffer();
} else {
this->last_offset = curr;
this->buf_idx = curr - this->buf_start;
}
}
return this->last_offset;
}
inline bool
InputSource::fastRead(char& ch)
{
// Before calling fastRead, fastTell must be called to prepare the buffer.
// Once reading is complete, fastUnread must be called to set the correct
// file position.
if (this->buf_idx < this->buf_len) {
ch = this->buffer[this->buf_idx];
++(this->buf_idx);
++(this->last_offset);
return true;
} else if (this->buf_len == 0) {
return false;
} else {
seek(this->buf_start + this->buf_len, SEEK_SET);
fastTell();
return fastRead(ch);
}
}
inline void
InputSource::fastUnread(bool back)
{
this->last_offset -= back ? 1 : 0;
seek(this->last_offset, SEEK_SET);
}
#endif // QPDF_INPUTSOURCE_HH

View File

@ -974,11 +974,11 @@ QPDFTokenizer::readToken(
bool allow_bad,
size_t max_len)
{
qpdf_offset_t offset = input->tell();
qpdf_offset_t offset = input->fastTell();
while (this->state != st_token_ready) {
char ch;
if (input->read(&ch, 1) == 0) {
if (!input->fastRead(ch)) {
presentEOF();
if ((this->type == tt_eof) && (!this->allow_eof)) {
@ -1013,9 +1013,7 @@ QPDFTokenizer::readToken(
bool unread_char;
char char_to_unread;
getToken(token, unread_char, char_to_unread);
if (unread_char) {
input->unreadCh(char_to_unread);
}
input->fastUnread(unread_char);
if (token.getType() != tt_eof) {
input->setLastOffset(offset);