/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 | 81.2k | own_memory(own_memory), |
10 | 81.2k | description(description), |
11 | 81.2k | buf(buf), |
12 | 81.2k | cur_offset(0), |
13 | 81.2k | max_offset(buf ? QIntC::to_offset(buf->getSize()) : 0) |
14 | 81.2k | { |
15 | 81.2k | } |
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 | 81.2k | { |
29 | 81.2k | if (own_memory) { |
30 | 0 | delete buf; |
31 | 0 | } |
32 | 81.2k | } |
33 | | |
34 | | qpdf_offset_t |
35 | | BufferInputSource::findAndSkipNextEOL() |
36 | 2.12M | { |
37 | 2.12M | if (cur_offset < 0) { |
38 | 0 | throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0"); |
39 | 0 | } |
40 | 2.12M | qpdf_offset_t end_pos = max_offset; |
41 | 2.12M | if (cur_offset >= end_pos) { |
42 | 8.16k | last_offset = end_pos; |
43 | 8.16k | cur_offset = end_pos; |
44 | 8.16k | return end_pos; |
45 | 8.16k | } |
46 | | |
47 | 2.11M | qpdf_offset_t result = 0; |
48 | 2.11M | unsigned char const* buffer = buf->getBuffer(); |
49 | 2.11M | unsigned char const* end = buffer + end_pos; |
50 | 2.11M | unsigned char const* p = buffer + cur_offset; |
51 | | |
52 | 160M | while ((p < end) && !((*p == '\r') || (*p == '\n'))) { |
53 | 157M | ++p; |
54 | 157M | } |
55 | 2.11M | if (p < end) { |
56 | 2.10M | result = p - buffer; |
57 | 2.10M | cur_offset = result + 1; |
58 | 2.10M | ++p; |
59 | 2.35M | while ((cur_offset < end_pos) && ((*p == '\r') || (*p == '\n'))) { |
60 | 254k | ++p; |
61 | 254k | ++cur_offset; |
62 | 254k | } |
63 | 2.10M | } else { |
64 | 13.4k | cur_offset = end_pos; |
65 | 13.4k | result = end_pos; |
66 | 13.4k | } |
67 | 2.11M | return result; |
68 | 2.12M | } |
69 | | |
70 | | std::string const& |
71 | | BufferInputSource::getName() const |
72 | 965k | { |
73 | 965k | return description; |
74 | 965k | } |
75 | | |
76 | | qpdf_offset_t |
77 | | BufferInputSource::tell() |
78 | 21.9M | { |
79 | 21.9M | return cur_offset; |
80 | 21.9M | } |
81 | | |
82 | | void |
83 | | BufferInputSource::seek(qpdf_offset_t offset, int whence) |
84 | 13.8M | { |
85 | 13.8M | switch (whence) { |
86 | 13.6M | case SEEK_SET: |
87 | 13.6M | cur_offset = offset; |
88 | 13.6M | break; |
89 | | |
90 | 44.6k | case SEEK_END: |
91 | 44.6k | QIntC::range_check(max_offset, offset); |
92 | 44.6k | cur_offset = max_offset + offset; |
93 | 44.6k | break; |
94 | | |
95 | 158k | case SEEK_CUR: |
96 | 158k | QIntC::range_check(cur_offset, offset); |
97 | 158k | cur_offset += offset; |
98 | 158k | break; |
99 | | |
100 | 0 | default: |
101 | 0 | throw std::logic_error("INTERNAL ERROR: invalid argument to BufferInputSource::seek"); |
102 | 0 | break; |
103 | 13.8M | } |
104 | | |
105 | 13.8M | if (cur_offset < 0) { |
106 | 341 | throw std::runtime_error(description + ": seek before beginning of buffer"); |
107 | 341 | } |
108 | 13.8M | } |
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 | 2.33M | { |
119 | 2.33M | if (cur_offset < 0) { |
120 | 0 | throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0"); |
121 | 0 | } |
122 | 2.33M | qpdf_offset_t end_pos = max_offset; |
123 | 2.33M | if (cur_offset >= end_pos) { |
124 | 95.1k | last_offset = end_pos; |
125 | 95.1k | return 0; |
126 | 95.1k | } |
127 | | |
128 | 2.24M | last_offset = cur_offset; |
129 | 2.24M | size_t len = std::min(QIntC::to_size(end_pos - cur_offset), length); |
130 | 2.24M | memcpy(buffer, buf->getBuffer() + cur_offset, len); |
131 | 2.24M | cur_offset += QIntC::to_offset(len); |
132 | 2.24M | return len; |
133 | 2.33M | } |
134 | | |
135 | | void |
136 | | BufferInputSource::unreadCh(char ch) |
137 | 14.6k | { |
138 | 14.6k | if (cur_offset > 0) { |
139 | 14.6k | --cur_offset; |
140 | 14.6k | } |
141 | 14.6k | } |