Commit 211a7f57be1913a32239b9868c85f18cd6b28683
1 parent
9a398504
QUtil::read_lines_from_file: optional EOL preservation
Showing
3 changed files
with
43 additions
and
4 deletions
ChangeLog
| 1 | +2020-01-13 Jay Berkenbilt <ejb@ql.org> | ||
| 2 | + | ||
| 3 | + * QUtil::read_lines_from_file: add new versions that use FILE*, | ||
| 4 | + use FILE* instead if std::ifstream internally to support correct | ||
| 5 | + handling of Unicode filenames in Windows, and add the option to | ||
| 6 | + preserve line endings. | ||
| 7 | + | ||
| 1 | 2019-11-17 Jay Berkenbilt <ejb@ql.org> | 8 | 2019-11-17 Jay Berkenbilt <ejb@ql.org> |
| 2 | 9 | ||
| 3 | * 9.1.0: release | 10 | * 9.1.0: release |
libqpdf/QUtil.cc
| @@ -1116,11 +1116,18 @@ QUtil::read_lines_from_file(std::function<bool(char&)> next_char, | @@ -1116,11 +1116,18 @@ QUtil::read_lines_from_file(std::function<bool(char&)> next_char, | ||
| 1116 | } | 1116 | } |
| 1117 | if (c == '\n') | 1117 | if (c == '\n') |
| 1118 | { | 1118 | { |
| 1119 | - // Remove any carriage return that preceded the | ||
| 1120 | - // newline and discard the newline | ||
| 1121 | - if ((! buf->empty()) && ((*(buf->rbegin())) == '\r')) | 1119 | + if (preserve_eol) |
| 1122 | { | 1120 | { |
| 1123 | - buf->erase(buf->length() - 1); | 1121 | + buf->append(1, c); |
| 1122 | + } | ||
| 1123 | + else | ||
| 1124 | + { | ||
| 1125 | + // Remove any carriage return that preceded the | ||
| 1126 | + // newline and discard the newline | ||
| 1127 | + if ((! buf->empty()) && ((*(buf->rbegin())) == '\r')) | ||
| 1128 | + { | ||
| 1129 | + buf->erase(buf->length() - 1); | ||
| 1130 | + } | ||
| 1124 | } | 1131 | } |
| 1125 | buf = 0; | 1132 | buf = 0; |
| 1126 | } | 1133 | } |
libtests/qutil.cc
| @@ -418,6 +418,31 @@ void read_from_file_test() | @@ -418,6 +418,31 @@ void read_from_file_test() | ||
| 418 | fclose(fp); | 418 | fclose(fp); |
| 419 | } | 419 | } |
| 420 | 420 | ||
| 421 | + // Test with EOL preservation | ||
| 422 | + std::list<std::string> lines2 = | ||
| 423 | + QUtil::read_lines_from_file("other-file", true); | ||
| 424 | + auto line = lines2.begin(); | ||
| 425 | + assert(37 == (*line).length()); | ||
| 426 | + assert('.' == (*line).at(35)); | ||
| 427 | + assert('\n' == (*line).at(36)); | ||
| 428 | + ++line; | ||
| 429 | + assert(24 == (*line).length()); | ||
| 430 | + assert('.' == (*line).at(21)); | ||
| 431 | + assert('\r' == (*line).at(22)); | ||
| 432 | + assert('\n' == (*line).at(23)); | ||
| 433 | + ++line; | ||
| 434 | + assert(24591 == (*line).length()); | ||
| 435 | + assert('.' == (*line).at(24589)); | ||
| 436 | + assert('\n' == (*line).at(24590)); | ||
| 437 | + // Test the other versions and make sure we get the same results | ||
| 438 | + { | ||
| 439 | + std::ifstream infs("other-file", std::ios_base::binary); | ||
| 440 | + assert(QUtil::read_lines_from_file(infs, true) == lines2); | ||
| 441 | + FILE* fp = QUtil::safe_fopen("other-file", "rb"); | ||
| 442 | + assert(QUtil::read_lines_from_file(fp, true) == lines2); | ||
| 443 | + fclose(fp); | ||
| 444 | + } | ||
| 445 | + | ||
| 421 | PointerHolder<char> buf; | 446 | PointerHolder<char> buf; |
| 422 | size_t size = 0; | 447 | size_t size = 0; |
| 423 | QUtil::read_file_into_memory("other-file", buf, size); | 448 | QUtil::read_file_into_memory("other-file", buf, size); |