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