/src/qpdf/libqpdf/OffsetInputSource.cc
Line | Count | Source |
1 | | #include <qpdf/OffsetInputSource.hh> |
2 | | |
3 | | #include <qpdf/Util.hh> |
4 | | |
5 | | #include <limits> |
6 | | #include <sstream> |
7 | | #include <stdexcept> |
8 | | |
9 | | using namespace qpdf; |
10 | | |
11 | | OffsetInputSource::OffsetInputSource( |
12 | | std::shared_ptr<InputSource> proxied, qpdf_offset_t global_offset) : |
13 | 1.38k | proxied(proxied), |
14 | 1.38k | global_offset(global_offset) |
15 | 1.38k | { |
16 | 1.38k | util::assertion(global_offset >= 0, "OffsetInputSource constructed with negative offset"); |
17 | 1.38k | max_safe_offset = std::numeric_limits<qpdf_offset_t>::max() - global_offset; |
18 | 1.38k | } |
19 | | |
20 | | qpdf_offset_t |
21 | | OffsetInputSource::findAndSkipNextEOL() |
22 | 701k | { |
23 | 701k | return proxied->findAndSkipNextEOL() - global_offset; |
24 | 701k | } |
25 | | |
26 | | std::string const& |
27 | | OffsetInputSource::getName() const |
28 | 95.3k | { |
29 | 95.3k | return proxied->getName(); |
30 | 95.3k | } |
31 | | |
32 | | qpdf_offset_t |
33 | | OffsetInputSource::tell() |
34 | 7.20M | { |
35 | 7.20M | return proxied->tell() - global_offset; |
36 | 7.20M | } |
37 | | |
38 | | void |
39 | | OffsetInputSource::seek(qpdf_offset_t offset, int whence) |
40 | 2.88M | { |
41 | 2.88M | if (whence == SEEK_SET) { |
42 | 2.86M | if (offset > max_safe_offset) { |
43 | 1 | std::ostringstream msg; |
44 | 1 | msg.imbue(std::locale::classic()); |
45 | 1 | msg << "seeking to " << offset << " offset by " << global_offset |
46 | 1 | << " would cause an overflow of the offset type"; |
47 | 1 | throw std::range_error(msg.str()); |
48 | 1 | } |
49 | 2.86M | proxied->seek(offset + global_offset, whence); |
50 | 2.86M | } else { |
51 | 24.0k | proxied->seek(offset, whence); |
52 | 24.0k | } |
53 | 2.88M | util::no_ci_rt_error_if(tell() < 0, "offset input source: seek before beginning of file"); |
54 | 2.88M | } |
55 | | |
56 | | void |
57 | | OffsetInputSource::rewind() |
58 | 0 | { |
59 | 0 | seek(0, SEEK_SET); |
60 | 0 | } |
61 | | |
62 | | size_t |
63 | | OffsetInputSource::read(char* buffer, size_t length) |
64 | 574k | { |
65 | 574k | size_t result = proxied->read(buffer, length); |
66 | 574k | setLastOffset(proxied->getLastOffset() - global_offset); |
67 | 574k | return result; |
68 | 574k | } |
69 | | |
70 | | void |
71 | | OffsetInputSource::unreadCh(char ch) |
72 | 684 | { |
73 | 684 | proxied->unreadCh(ch); |
74 | 684 | } |