mirror of
https://github.com/qpdf/qpdf.git
synced 2025-01-03 15:17:29 +00:00
Add methods InputSource::fastRead, fastUnRead and fastTell
Provide buffered input for QPDFTokenizer.
This commit is contained in:
parent
13ef50cd27
commit
69a5fb7047
@ -93,6 +93,12 @@ class QPDF_DLL_CLASS InputSource
|
|||||||
// efficient.
|
// efficient.
|
||||||
virtual void unreadCh(char ch) = 0;
|
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:
|
protected:
|
||||||
qpdf_offset_t last_offset;
|
qpdf_offset_t last_offset;
|
||||||
|
|
||||||
@ -111,6 +117,68 @@ class QPDF_DLL_CLASS InputSource
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<Members> m;
|
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
|
#endif // QPDF_INPUTSOURCE_HH
|
||||||
|
@ -974,11 +974,11 @@ QPDFTokenizer::readToken(
|
|||||||
bool allow_bad,
|
bool allow_bad,
|
||||||
size_t max_len)
|
size_t max_len)
|
||||||
{
|
{
|
||||||
qpdf_offset_t offset = input->tell();
|
qpdf_offset_t offset = input->fastTell();
|
||||||
|
|
||||||
while (this->state != st_token_ready) {
|
while (this->state != st_token_ready) {
|
||||||
char ch;
|
char ch;
|
||||||
if (input->read(&ch, 1) == 0) {
|
if (!input->fastRead(ch)) {
|
||||||
presentEOF();
|
presentEOF();
|
||||||
|
|
||||||
if ((this->type == tt_eof) && (!this->allow_eof)) {
|
if ((this->type == tt_eof) && (!this->allow_eof)) {
|
||||||
@ -1013,9 +1013,7 @@ QPDFTokenizer::readToken(
|
|||||||
bool unread_char;
|
bool unread_char;
|
||||||
char char_to_unread;
|
char char_to_unread;
|
||||||
getToken(token, unread_char, char_to_unread);
|
getToken(token, unread_char, char_to_unread);
|
||||||
if (unread_char) {
|
input->fastUnread(unread_char);
|
||||||
input->unreadCh(char_to_unread);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (token.getType() != tt_eof) {
|
if (token.getType() != tt_eof) {
|
||||||
input->setLastOffset(offset);
|
input->setLastOffset(offset);
|
||||||
|
Loading…
Reference in New Issue
Block a user