/src/qpdf/libqpdf/BufferInputSource.cc
Line | Count | Source (jump to first uncovered line) |
1 | | #include <qpdf/BufferInputSource.hh> |
2 | | |
3 | | #include <qpdf/QIntC.hh> |
4 | | #include <algorithm> |
5 | | #include <cstring> |
6 | | #include <sstream> |
7 | | |
8 | | BufferInputSource::BufferInputSource(std::string const& description, Buffer* buf, bool own_memory) : |
9 | 77.0k | own_memory(own_memory), |
10 | 77.0k | description(description), |
11 | 77.0k | buf(buf), |
12 | 77.0k | cur_offset(0), |
13 | 77.0k | max_offset(buf ? QIntC::to_offset(buf->getSize()) : 0) |
14 | 77.0k | { |
15 | 77.0k | } |
16 | | |
17 | | BufferInputSource::BufferInputSource(std::string const& description, std::string const& contents) : |
18 | 0 | own_memory(true), |
19 | 0 | description(description), |
20 | 0 | buf(new Buffer(contents.length())), |
21 | 0 | cur_offset(0), |
22 | 0 | max_offset(QIntC::to_offset(buf->getSize())) |
23 | 0 | { |
24 | 0 | memcpy(buf->getBuffer(), contents.c_str(), contents.length()); |
25 | 0 | } |
26 | | |
27 | | BufferInputSource::~BufferInputSource() |
28 | 77.0k | { |
29 | 77.0k | if (own_memory) { |
30 | 2.86k | delete buf; |
31 | 2.86k | } |
32 | 77.0k | } |
33 | | |
34 | | qpdf_offset_t |
35 | | BufferInputSource::findAndSkipNextEOL() |
36 | 1.71M | { |
37 | 1.71M | if (cur_offset < 0) { |
38 | 0 | throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0"); |
39 | 0 | } |
40 | 1.71M | qpdf_offset_t end_pos = max_offset; |
41 | 1.71M | if (cur_offset >= end_pos) { |
42 | 6.97k | last_offset = end_pos; |
43 | 6.97k | cur_offset = end_pos; |
44 | 6.97k | return end_pos; |
45 | 6.97k | } |
46 | | |
47 | 1.70M | qpdf_offset_t result = 0; |
48 | 1.70M | unsigned char const* buffer = buf->getBuffer(); |
49 | 1.70M | unsigned char const* end = buffer + end_pos; |
50 | 1.70M | unsigned char const* p = buffer + cur_offset; |
51 | | |
52 | 143M | while ((p < end) && !((*p == '\r') || (*p == '\n'))) { |
53 | 141M | ++p; |
54 | 141M | } |
55 | 1.70M | if (p < end) { |
56 | 1.69M | result = p - buffer; |
57 | 1.69M | cur_offset = result + 1; |
58 | 1.69M | ++p; |
59 | 1.91M | while ((cur_offset < end_pos) && ((*p == '\r') || (*p == '\n'))) { |
60 | 227k | ++p; |
61 | 227k | ++cur_offset; |
62 | 227k | } |
63 | 1.69M | } else { |
64 | 13.0k | cur_offset = end_pos; |
65 | 13.0k | result = end_pos; |
66 | 13.0k | } |
67 | 1.70M | return result; |
68 | 1.71M | } |
69 | | |
70 | | std::string const& |
71 | | BufferInputSource::getName() const |
72 | 850k | { |
73 | 850k | return description; |
74 | 850k | } |
75 | | |
76 | | qpdf_offset_t |
77 | | BufferInputSource::tell() |
78 | 64.9M | { |
79 | 64.9M | return cur_offset; |
80 | 64.9M | } |
81 | | |
82 | | void |
83 | | BufferInputSource::seek(qpdf_offset_t offset, int whence) |
84 | 59.4M | { |
85 | 59.4M | switch (whence) { |
86 | 59.2M | case SEEK_SET: |
87 | 59.2M | cur_offset = offset; |
88 | 59.2M | break; |
89 | | |
90 | 40.9k | case SEEK_END: |
91 | 40.9k | QIntC::range_check(max_offset, offset); |
92 | 40.9k | cur_offset = max_offset + offset; |
93 | 40.9k | break; |
94 | | |
95 | 125k | case SEEK_CUR: |
96 | 125k | QIntC::range_check(cur_offset, offset); |
97 | 125k | cur_offset += offset; |
98 | 125k | break; |
99 | | |
100 | 0 | default: |
101 | 0 | throw std::logic_error("INTERNAL ERROR: invalid argument to BufferInputSource::seek"); |
102 | 0 | break; |
103 | 59.4M | } |
104 | | |
105 | 59.4M | if (cur_offset < 0) { |
106 | 333 | throw std::runtime_error(description + ": seek before beginning of buffer"); |
107 | 333 | } |
108 | 59.4M | } |
109 | | |
110 | | void |
111 | | BufferInputSource::rewind() |
112 | 0 | { |
113 | 0 | cur_offset = 0; |
114 | 0 | } |
115 | | |
116 | | size_t |
117 | | BufferInputSource::read(char* buffer, size_t length) |
118 | 7.25M | { |
119 | 7.25M | if (cur_offset < 0) { |
120 | 0 | throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0"); |
121 | 0 | } |
122 | 7.25M | qpdf_offset_t end_pos = max_offset; |
123 | 7.25M | if (cur_offset >= end_pos) { |
124 | 96.9k | last_offset = end_pos; |
125 | 96.9k | return 0; |
126 | 96.9k | } |
127 | | |
128 | 7.16M | last_offset = cur_offset; |
129 | 7.16M | size_t len = std::min(QIntC::to_size(end_pos - cur_offset), length); |
130 | 7.16M | memcpy(buffer, buf->getBuffer() + cur_offset, len); |
131 | 7.16M | cur_offset += QIntC::to_offset(len); |
132 | 7.16M | return len; |
133 | 7.25M | } |
134 | | |
135 | | void |
136 | | BufferInputSource::unreadCh(char ch) |
137 | 15.9k | { |
138 | 15.9k | if (cur_offset > 0) { |
139 | 15.9k | --cur_offset; |
140 | 15.9k | } |
141 | 15.9k | } |