Commit 24cf3bcadc9d60f5d7748401814f83fefacfb8b3
1 parent
8768387c
Add qpdf private API methods InputSource::read_line
Showing
2 changed files
with
33 additions
and
14 deletions
include/qpdf/InputSource.hh
| ... | ... | @@ -78,6 +78,8 @@ class QPDF_DLL_CLASS InputSource |
| 78 | 78 | // The following methods are for internal use by qpdf only. |
| 79 | 79 | inline size_t read(std::string& str, size_t count, qpdf_offset_t at = -1); |
| 80 | 80 | inline std::string read(size_t count, qpdf_offset_t at = -1); |
| 81 | + size_t read_line(std::string& str, size_t count, qpdf_offset_t at = -1); | |
| 82 | + std::string read_line(size_t count, qpdf_offset_t at = -1); | |
| 81 | 83 | inline qpdf_offset_t fastTell(); |
| 82 | 84 | inline bool fastRead(char&); |
| 83 | 85 | inline void fastUnread(bool); | ... | ... |
libqpdf/InputSource.cc
| ... | ... | @@ -5,6 +5,8 @@ |
| 5 | 5 | #include <cstring> |
| 6 | 6 | #include <stdexcept> |
| 7 | 7 | |
| 8 | +using namespace std::literals; | |
| 9 | + | |
| 8 | 10 | void |
| 9 | 11 | InputSource::setLastOffset(qpdf_offset_t offset) |
| 10 | 12 | { |
| ... | ... | @@ -17,27 +19,42 @@ InputSource::getLastOffset() const |
| 17 | 19 | return this->last_offset; |
| 18 | 20 | } |
| 19 | 21 | |
| 20 | -std::string | |
| 21 | -InputSource::readLine(size_t max_line_length) | |
| 22 | +size_t | |
| 23 | +InputSource::read_line(std::string& str, size_t count, qpdf_offset_t at) | |
| 22 | 24 | { |
| 23 | 25 | // Return at most max_line_length characters from the next line. Lines are terminated by one or |
| 24 | 26 | // more \r or \n characters. Consume the trailing newline characters but don't return them. |
| 25 | 27 | // After this is called, the file will be positioned after a line terminator or at the end of |
| 26 | 28 | // the file, and last_offset will point to position the file had when this method was called. |
| 27 | 29 | |
| 28 | - qpdf_offset_t offset = this->tell(); | |
| 29 | - auto bp = std::make_unique<char[]>(max_line_length + 1); | |
| 30 | - char* buf = bp.get(); | |
| 31 | - memset(buf, '\0', max_line_length + 1); | |
| 32 | - this->read(buf, max_line_length); | |
| 33 | - this->seek(offset, SEEK_SET); | |
| 34 | - qpdf_offset_t eol = this->findAndSkipNextEOL(); | |
| 35 | - this->last_offset = offset; | |
| 36 | - size_t line_length = QIntC::to_size(eol - offset); | |
| 37 | - if (line_length < max_line_length) { | |
| 38 | - buf[line_length] = '\0'; | |
| 30 | + read(str, count, at); | |
| 31 | + auto eol = str.find_first_of("\n\r"sv); | |
| 32 | + if (eol != std::string::npos) { | |
| 33 | + auto next_line = str.find_first_not_of("\n\r"sv, eol); | |
| 34 | + str.resize(eol); | |
| 35 | + if (eol != std::string::npos) { | |
| 36 | + seek(last_offset + static_cast<qpdf_offset_t>(next_line), SEEK_SET); | |
| 37 | + return eol; | |
| 38 | + } | |
| 39 | 39 | } |
| 40 | - return {buf}; | |
| 40 | + // We did not necessarily find the end of the trailing newline sequence. | |
| 41 | + seek(last_offset, SEEK_SET); | |
| 42 | + findAndSkipNextEOL(); | |
| 43 | + return eol; | |
| 44 | +} | |
| 45 | + | |
| 46 | +std::string | |
| 47 | +InputSource::readLine(size_t max_line_length) | |
| 48 | +{ | |
| 49 | + return read_line(max_line_length); | |
| 50 | +} | |
| 51 | + | |
| 52 | +inline std::string | |
| 53 | +InputSource::read_line(size_t count, qpdf_offset_t at) | |
| 54 | +{ | |
| 55 | + std::string result(count, '\0'); | |
| 56 | + read_line(result, count, at); | |
| 57 | + return result; | |
| 41 | 58 | } |
| 42 | 59 | |
| 43 | 60 | bool | ... | ... |