aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorm-holger <m-holger@kubitscheck.org>2022-08-27 00:55:56 +0200
committerm-holger <m-holger@kubitscheck.org>2022-08-27 00:55:56 +0200
commit69a5fb70472a2112d2bbb938ee3718250d2364cf (patch)
treea95bef3322f7989534e5f9dc8f6af9f61a5d1e3f /include
parent13ef50cd27f13687040da9342b398079567b7521 (diff)
downloadqpdf-69a5fb70472a2112d2bbb938ee3718250d2364cf.tar.zst
Add methods InputSource::fastRead, fastUnRead and fastTell
Provide buffered input for QPDFTokenizer.
Diffstat (limited to 'include')
-rw-r--r--include/qpdf/InputSource.hh68
1 files changed, 68 insertions, 0 deletions
diff --git a/include/qpdf/InputSource.hh b/include/qpdf/InputSource.hh
index 9feb8ec3..e9d99cdb 100644
--- a/include/qpdf/InputSource.hh
+++ b/include/qpdf/InputSource.hh
@@ -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