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,6 +78,8 @@ class QPDF_DLL_CLASS InputSource | ||
| 78 | // The following methods are for internal use by qpdf only. | 78 | // The following methods are for internal use by qpdf only. |
| 79 | inline size_t read(std::string& str, size_t count, qpdf_offset_t at = -1); | 79 | inline size_t read(std::string& str, size_t count, qpdf_offset_t at = -1); |
| 80 | inline std::string read(size_t count, qpdf_offset_t at = -1); | 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 | inline qpdf_offset_t fastTell(); | 83 | inline qpdf_offset_t fastTell(); |
| 82 | inline bool fastRead(char&); | 84 | inline bool fastRead(char&); |
| 83 | inline void fastUnread(bool); | 85 | inline void fastUnread(bool); |
libqpdf/InputSource.cc
| @@ -5,6 +5,8 @@ | @@ -5,6 +5,8 @@ | ||
| 5 | #include <cstring> | 5 | #include <cstring> |
| 6 | #include <stdexcept> | 6 | #include <stdexcept> |
| 7 | 7 | ||
| 8 | +using namespace std::literals; | ||
| 9 | + | ||
| 8 | void | 10 | void |
| 9 | InputSource::setLastOffset(qpdf_offset_t offset) | 11 | InputSource::setLastOffset(qpdf_offset_t offset) |
| 10 | { | 12 | { |
| @@ -17,27 +19,42 @@ InputSource::getLastOffset() const | @@ -17,27 +19,42 @@ InputSource::getLastOffset() const | ||
| 17 | return this->last_offset; | 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 | // Return at most max_line_length characters from the next line. Lines are terminated by one or | 25 | // Return at most max_line_length characters from the next line. Lines are terminated by one or |
| 24 | // more \r or \n characters. Consume the trailing newline characters but don't return them. | 26 | // more \r or \n characters. Consume the trailing newline characters but don't return them. |
| 25 | // After this is called, the file will be positioned after a line terminator or at the end of | 27 | // After this is called, the file will be positioned after a line terminator or at the end of |
| 26 | // the file, and last_offset will point to position the file had when this method was called. | 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 | bool | 60 | bool |