Commit 81cb79620a361d7047c72be27d1ede48d5da4e93

Authored by m-holger
1 parent 3a055d5b

Refactor `is::OffsetBuffer` to remove dependency on `BufferInputSource`, improvi…

…ng encapsulation and maintainability.
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