Commit 24cf3bcadc9d60f5d7748401814f83fefacfb8b3

Authored by m-holger
1 parent 8768387c

Add qpdf private API methods InputSource::read_line

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