Commit 81cb79620a361d7047c72be27d1ede48d5da4e93
1 parent
3a055d5b
Refactor `is::OffsetBuffer` to remove dependency on `BufferInputSource`, improvi…
…ng encapsulation and maintainability.
Showing
3 changed files
with
110 additions
and
18 deletions
libqpdf/BufferInputSource.cc
| 1 | #include <qpdf/BufferInputSource.hh> | 1 | #include <qpdf/BufferInputSource.hh> |
| 2 | +#include <qpdf/InputSource_private.hh> | ||
| 2 | 3 | ||
| 4 | +#include <qpdf/Buffer.hh> | ||
| 3 | #include <qpdf/QIntC.hh> | 5 | #include <qpdf/QIntC.hh> |
| 6 | + | ||
| 4 | #include <algorithm> | 7 | #include <algorithm> |
| 5 | #include <cstring> | 8 | #include <cstring> |
| 6 | #include <sstream> | 9 | #include <sstream> |
| 7 | 10 | ||
| 11 | +using namespace qpdf; | ||
| 12 | + | ||
| 8 | BufferInputSource::BufferInputSource(std::string const& description, Buffer* buf, bool own_memory) : | 13 | BufferInputSource::BufferInputSource(std::string const& description, Buffer* buf, bool own_memory) : |
| 9 | own_memory(own_memory), | 14 | own_memory(own_memory), |
| 10 | description(description), | 15 | description(description), |
| @@ -139,3 +144,86 @@ BufferInputSource::unreadCh(char ch) | @@ -139,3 +144,86 @@ BufferInputSource::unreadCh(char ch) | ||
| 139 | --cur_offset; | 144 | --cur_offset; |
| 140 | } | 145 | } |
| 141 | } | 146 | } |
| 147 | + | ||
| 148 | +qpdf_offset_t | ||
| 149 | +is::OffsetBuffer::findAndSkipNextEOL_internal() | ||
| 150 | +{ | ||
| 151 | + if (cur_offset < 0) { | ||
| 152 | + throw std::logic_error("INTERNAL ERROR: is::OffsetBuffer offset < 0"); | ||
| 153 | + } | ||
| 154 | + qpdf_offset_t end_pos = max_offset; | ||
| 155 | + if (cur_offset >= end_pos) { | ||
| 156 | + last_offset = end_pos + global_offset; | ||
| 157 | + cur_offset = end_pos; | ||
| 158 | + return end_pos; | ||
| 159 | + } | ||
| 160 | + | ||
| 161 | + qpdf_offset_t result = 0; | ||
| 162 | + unsigned char const* buffer = buf->getBuffer(); | ||
| 163 | + unsigned char const* end = buffer + end_pos; | ||
| 164 | + unsigned char const* p = buffer + cur_offset; | ||
| 165 | + | ||
| 166 | + while (p < end && !(*p == '\r' || *p == '\n')) { | ||
| 167 | + ++p; | ||
| 168 | + } | ||
| 169 | + if (p < end) { | ||
| 170 | + result = p - buffer; | ||
| 171 | + cur_offset = result + 1; | ||
| 172 | + ++p; | ||
| 173 | + while (cur_offset < end_pos && (*p == '\r' || *p == '\n')) { | ||
| 174 | + ++p; | ||
| 175 | + ++cur_offset; | ||
| 176 | + } | ||
| 177 | + } else { | ||
| 178 | + cur_offset = end_pos; | ||
| 179 | + result = end_pos; | ||
| 180 | + } | ||
| 181 | + return result; | ||
| 182 | +} | ||
| 183 | + | ||
| 184 | +void | ||
| 185 | +is::OffsetBuffer::seek_internal(qpdf_offset_t offset, int whence) | ||
| 186 | +{ | ||
| 187 | + switch (whence) { | ||
| 188 | + case SEEK_SET: | ||
| 189 | + cur_offset = offset; | ||
| 190 | + break; | ||
| 191 | + | ||
| 192 | + case SEEK_END: | ||
| 193 | + QIntC::range_check(max_offset, offset); | ||
| 194 | + cur_offset = max_offset + offset; | ||
| 195 | + break; | ||
| 196 | + | ||
| 197 | + case SEEK_CUR: | ||
| 198 | + QIntC::range_check(cur_offset, offset); | ||
| 199 | + cur_offset += offset; | ||
| 200 | + break; | ||
| 201 | + | ||
| 202 | + default: | ||
| 203 | + throw std::logic_error("INTERNAL ERROR: invalid argument to BufferInputSource::seek"); | ||
| 204 | + break; | ||
| 205 | + } | ||
| 206 | + | ||
| 207 | + if (cur_offset < 0) { | ||
| 208 | + throw std::runtime_error(description + ": seek before beginning of buffer"); | ||
| 209 | + } | ||
| 210 | +} | ||
| 211 | + | ||
| 212 | +size_t | ||
| 213 | +is::OffsetBuffer::read(char* buffer, size_t length) | ||
| 214 | +{ | ||
| 215 | + if (cur_offset < 0) { | ||
| 216 | + throw std::logic_error("INTERNAL ERROR: is::OffsetBuffer offset < 0"); | ||
| 217 | + } | ||
| 218 | + qpdf_offset_t end_pos = max_offset; | ||
| 219 | + if (cur_offset >= end_pos) { | ||
| 220 | + last_offset = end_pos + global_offset; | ||
| 221 | + return 0; | ||
| 222 | + } | ||
| 223 | + | ||
| 224 | + last_offset = cur_offset + global_offset; | ||
| 225 | + size_t len = std::min(QIntC::to_size(end_pos - cur_offset), length); | ||
| 226 | + memcpy(buffer, buf->getBuffer() + cur_offset, len); | ||
| 227 | + cur_offset += QIntC::to_offset(len); | ||
| 228 | + return len; | ||
| 229 | +} |
libqpdf/QPDFObjectHandle.cc
| @@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
| 2 | 2 | ||
| 3 | #include <qpdf/QPDFObjectHandle_private.hh> | 3 | #include <qpdf/QPDFObjectHandle_private.hh> |
| 4 | 4 | ||
| 5 | -#include <qpdf/InputSource_private.hh> | 5 | +#include <qpdf/BufferInputSource.hh> |
| 6 | #include <qpdf/JSON_writer.hh> | 6 | #include <qpdf/JSON_writer.hh> |
| 7 | #include <qpdf/Pipeline_private.hh> | 7 | #include <qpdf/Pipeline_private.hh> |
| 8 | #include <qpdf/Pl_Buffer.hh> | 8 | #include <qpdf/Pl_Buffer.hh> |
libqpdf/qpdf/InputSource_private.hh
| 1 | #ifndef QPDF_INPUTSOURCE_PRIVATE_HH | 1 | #ifndef QPDF_INPUTSOURCE_PRIVATE_HH |
| 2 | #define QPDF_INPUTSOURCE_PRIVATE_HH | 2 | #define QPDF_INPUTSOURCE_PRIVATE_HH |
| 3 | 3 | ||
| 4 | -#include <qpdf/BufferInputSource.hh> | 4 | +#include <qpdf/Buffer.hh> |
| 5 | #include <qpdf/InputSource.hh> | 5 | #include <qpdf/InputSource.hh> |
| 6 | 6 | ||
| 7 | #include <limits> | 7 | #include <limits> |
| @@ -14,7 +14,9 @@ namespace qpdf::is | @@ -14,7 +14,9 @@ namespace qpdf::is | ||
| 14 | { | 14 | { |
| 15 | public: | 15 | public: |
| 16 | OffsetBuffer(std::string const& description, Buffer* buf, qpdf_offset_t global_offset) : | 16 | OffsetBuffer(std::string const& description, Buffer* buf, qpdf_offset_t global_offset) : |
| 17 | - proxied(description, buf), | 17 | + description(description), |
| 18 | + buf(buf), | ||
| 19 | + max_offset(buf ? static_cast<qpdf_offset_t>(buf->getSize()) : 0), | ||
| 18 | global_offset(global_offset) | 20 | global_offset(global_offset) |
| 19 | { | 21 | { |
| 20 | if (global_offset < 0) { | 22 | if (global_offset < 0) { |
| @@ -28,53 +30,55 @@ namespace qpdf::is | @@ -28,53 +30,55 @@ namespace qpdf::is | ||
| 28 | qpdf_offset_t | 30 | qpdf_offset_t |
| 29 | findAndSkipNextEOL() final | 31 | findAndSkipNextEOL() final |
| 30 | { | 32 | { |
| 31 | - return proxied.findAndSkipNextEOL() + global_offset; | 33 | + return findAndSkipNextEOL_internal() + global_offset; |
| 32 | } | 34 | } |
| 33 | 35 | ||
| 34 | std::string const& | 36 | std::string const& |
| 35 | getName() const final | 37 | getName() const final |
| 36 | { | 38 | { |
| 37 | - return proxied.getName(); | 39 | + return description; |
| 38 | } | 40 | } |
| 39 | 41 | ||
| 40 | qpdf_offset_t | 42 | qpdf_offset_t |
| 41 | tell() final | 43 | tell() final |
| 42 | { | 44 | { |
| 43 | - return proxied.tell() + global_offset; | 45 | + return cur_offset + global_offset; |
| 44 | } | 46 | } |
| 45 | 47 | ||
| 46 | void | 48 | void |
| 47 | seek(qpdf_offset_t offset, int whence) final | 49 | seek(qpdf_offset_t offset, int whence) final |
| 48 | { | 50 | { |
| 49 | if (whence == SEEK_SET) { | 51 | if (whence == SEEK_SET) { |
| 50 | - proxied.seek(offset - global_offset, whence); | 52 | + seek_internal(offset - global_offset, whence); |
| 51 | } else { | 53 | } else { |
| 52 | - proxied.seek(offset, whence); | 54 | + seek_internal(offset, whence); |
| 53 | } | 55 | } |
| 54 | } | 56 | } |
| 55 | 57 | ||
| 56 | void | 58 | void |
| 57 | rewind() final | 59 | rewind() final |
| 58 | { | 60 | { |
| 59 | - seek(0, SEEK_SET); | 61 | + seek_internal(0, SEEK_SET); |
| 60 | } | 62 | } |
| 61 | 63 | ||
| 62 | - size_t | ||
| 63 | - read(char* buffer, size_t length) final | ||
| 64 | - { | ||
| 65 | - size_t result = proxied.read(buffer, length); | ||
| 66 | - setLastOffset(proxied.getLastOffset() + global_offset); | ||
| 67 | - return result; | ||
| 68 | - } | 64 | + size_t read(char* buffer, size_t length) final; |
| 69 | 65 | ||
| 70 | void | 66 | void |
| 71 | unreadCh(char ch) final | 67 | unreadCh(char ch) final |
| 72 | { | 68 | { |
| 73 | - proxied.unreadCh(ch); | 69 | + if (cur_offset > 0) { |
| 70 | + --cur_offset; | ||
| 71 | + } | ||
| 74 | } | 72 | } |
| 75 | 73 | ||
| 76 | private: | 74 | private: |
| 77 | - BufferInputSource proxied; | 75 | + qpdf_offset_t findAndSkipNextEOL_internal(); |
| 76 | + void seek_internal(qpdf_offset_t offset, int whence); | ||
| 77 | + | ||
| 78 | + std::string description; | ||
| 79 | + Buffer* buf; | ||
| 80 | + qpdf_offset_t cur_offset{0}; | ||
| 81 | + qpdf_offset_t max_offset; | ||
| 78 | qpdf_offset_t global_offset; | 82 | qpdf_offset_t global_offset; |
| 79 | }; | 83 | }; |
| 80 | 84 |