Commit 67edbfd954a4249d6c78bd375294e4a5bbde3846
1 parent
fa8dd266
Un-inline QUtil functions
Add new private Util.hh header to define inline functions and expose as ordinary functions in QUtil.
Showing
12 changed files
with
202 additions
and
123 deletions
include/qpdf/QUtil.hh
| @@ -190,7 +190,7 @@ namespace QUtil | @@ -190,7 +190,7 @@ namespace QUtil | ||
| 190 | 190 | ||
| 191 | // Returns lower-case hex-encoded version of the char including a leading "#". | 191 | // Returns lower-case hex-encoded version of the char including a leading "#". |
| 192 | QPDF_DLL | 192 | QPDF_DLL |
| 193 | - inline std::string hex_encode_char(char); | 193 | + std::string hex_encode_char(char); |
| 194 | 194 | ||
| 195 | // Returns a string that is the result of decoding the input string. The input string may | 195 | // Returns a string that is the result of decoding the input string. The input string may |
| 196 | // consist of mixed case hexadecimal digits. Any characters that are not hexadecimal digits will | 196 | // consist of mixed case hexadecimal digits. Any characters that are not hexadecimal digits will |
| @@ -202,7 +202,7 @@ namespace QUtil | @@ -202,7 +202,7 @@ namespace QUtil | ||
| 202 | // Decode a single hex digit into a char in the range 0 <= char < 16. Return a char >= 16 if | 202 | // Decode a single hex digit into a char in the range 0 <= char < 16. Return a char >= 16 if |
| 203 | // digit is not a valid hex digit. | 203 | // digit is not a valid hex digit. |
| 204 | QPDF_DLL | 204 | QPDF_DLL |
| 205 | - inline constexpr char hex_decode_char(char digit) noexcept; | 205 | + char hex_decode_char(char digit); |
| 206 | 206 | ||
| 207 | // Set stdin, stdout to binary mode | 207 | // Set stdin, stdout to binary mode |
| 208 | QPDF_DLL | 208 | QPDF_DLL |
| @@ -431,16 +431,16 @@ namespace QUtil | @@ -431,16 +431,16 @@ namespace QUtil | ||
| 431 | // These routines help the tokenizer recognize certain character classes without using ctype, | 431 | // These routines help the tokenizer recognize certain character classes without using ctype, |
| 432 | // which we avoid because of locale considerations. | 432 | // which we avoid because of locale considerations. |
| 433 | QPDF_DLL | 433 | QPDF_DLL |
| 434 | - inline bool is_hex_digit(char); | 434 | + bool is_hex_digit(char); |
| 435 | 435 | ||
| 436 | QPDF_DLL | 436 | QPDF_DLL |
| 437 | - inline bool is_space(char); | 437 | + bool is_space(char); |
| 438 | 438 | ||
| 439 | QPDF_DLL | 439 | QPDF_DLL |
| 440 | - inline bool is_digit(char); | 440 | + bool is_digit(char); |
| 441 | 441 | ||
| 442 | QPDF_DLL | 442 | QPDF_DLL |
| 443 | - inline bool is_number(char const*); | 443 | + bool is_number(char const*); |
| 444 | 444 | ||
| 445 | // This method parses the numeric range syntax used by the qpdf command-line tool. May throw | 445 | // This method parses the numeric range syntax used by the qpdf command-line tool. May throw |
| 446 | // std::runtime_error. A numeric range is as comma-separated list of groups. A group may be a | 446 | // std::runtime_error. A numeric range is as comma-separated list of groups. A group may be a |
| @@ -489,65 +489,4 @@ namespace QUtil | @@ -489,65 +489,4 @@ namespace QUtil | ||
| 489 | size_t get_max_memory_usage(); | 489 | size_t get_max_memory_usage(); |
| 490 | }; // namespace QUtil | 490 | }; // namespace QUtil |
| 491 | 491 | ||
| 492 | -inline bool | ||
| 493 | -QUtil::is_hex_digit(char ch) | ||
| 494 | -{ | ||
| 495 | - return hex_decode_char(ch) < '\20'; | ||
| 496 | -} | ||
| 497 | - | ||
| 498 | -inline bool | ||
| 499 | -QUtil::is_space(char ch) | ||
| 500 | -{ | ||
| 501 | - return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\v'; | ||
| 502 | -} | ||
| 503 | - | ||
| 504 | -inline bool | ||
| 505 | -QUtil::is_digit(char ch) | ||
| 506 | -{ | ||
| 507 | - return ((ch >= '0') && (ch <= '9')); | ||
| 508 | -} | ||
| 509 | - | ||
| 510 | -inline bool | ||
| 511 | -QUtil::is_number(char const* p) | ||
| 512 | -{ | ||
| 513 | - // ^[\+\-]?(\.\d*|\d+(\.\d*)?)$ | ||
| 514 | - if (!*p) { | ||
| 515 | - return false; | ||
| 516 | - } | ||
| 517 | - if ((*p == '-') || (*p == '+')) { | ||
| 518 | - ++p; | ||
| 519 | - } | ||
| 520 | - bool found_dot = false; | ||
| 521 | - bool found_digit = false; | ||
| 522 | - for (; *p; ++p) { | ||
| 523 | - if (*p == '.') { | ||
| 524 | - if (found_dot) { | ||
| 525 | - // only one dot | ||
| 526 | - return false; | ||
| 527 | - } | ||
| 528 | - found_dot = true; | ||
| 529 | - } else if (QUtil::is_digit(*p)) { | ||
| 530 | - found_digit = true; | ||
| 531 | - } else { | ||
| 532 | - return false; | ||
| 533 | - } | ||
| 534 | - } | ||
| 535 | - return found_digit; | ||
| 536 | -} | ||
| 537 | - | ||
| 538 | -inline std::string | ||
| 539 | -QUtil::hex_encode_char(char c) | ||
| 540 | -{ | ||
| 541 | - static auto constexpr hexchars = "0123456789abcdef"; | ||
| 542 | - return {'#', hexchars[static_cast<unsigned char>(c) >> 4], hexchars[c & 0x0f]}; | ||
| 543 | -} | ||
| 544 | - | ||
| 545 | -inline constexpr char | ||
| 546 | -QUtil::hex_decode_char(char digit) noexcept | ||
| 547 | -{ | ||
| 548 | - return digit <= '9' && digit >= '0' | ||
| 549 | - ? char(digit - '0') | ||
| 550 | - : (digit >= 'a' ? char(digit - 'a' + 10) : (digit >= 'A' ? char(digit - 'A' + 10) : '\20')); | ||
| 551 | -} | ||
| 552 | - | ||
| 553 | #endif // QUTIL_HH | 492 | #endif // QUTIL_HH |
libqpdf/JSON.cc
| @@ -8,9 +8,13 @@ | @@ -8,9 +8,13 @@ | ||
| 8 | #include <qpdf/Pl_String.hh> | 8 | #include <qpdf/Pl_String.hh> |
| 9 | #include <qpdf/QTC.hh> | 9 | #include <qpdf/QTC.hh> |
| 10 | #include <qpdf/QUtil.hh> | 10 | #include <qpdf/QUtil.hh> |
| 11 | +#include <qpdf/Util.hh> | ||
| 12 | + | ||
| 11 | #include <cstring> | 13 | #include <cstring> |
| 12 | #include <stdexcept> | 14 | #include <stdexcept> |
| 13 | 15 | ||
| 16 | +using namespace qpdf; | ||
| 17 | + | ||
| 14 | JSON::Members::Members(std::unique_ptr<JSON_value> value) : | 18 | JSON::Members::Members(std::unique_ptr<JSON_value> value) : |
| 15 | value(std::move(value)) | 19 | value(std::move(value)) |
| 16 | { | 20 | { |
| @@ -761,7 +765,7 @@ JSONParser::tokenError() | @@ -761,7 +765,7 @@ JSONParser::tokenError() | ||
| 761 | QTC::TC("libtests", "JSON parse unexpected sign"); | 765 | QTC::TC("libtests", "JSON parse unexpected sign"); |
| 762 | throw std::runtime_error( | 766 | throw std::runtime_error( |
| 763 | "JSON: offset " + std::to_string(offset) + ": numeric literal: unexpected sign"); | 767 | "JSON: offset " + std::to_string(offset) + ": numeric literal: unexpected sign"); |
| 764 | - } else if (QUtil::is_space(*p) || strchr("{}[]:,", *p)) { | 768 | + } else if (util::is_space(*p) || strchr("{}[]:,", *p)) { |
| 765 | QTC::TC("libtests", "JSON parse incomplete number"); | 769 | QTC::TC("libtests", "JSON parse incomplete number"); |
| 766 | throw std::runtime_error( | 770 | throw std::runtime_error( |
| 767 | "JSON: offset " + std::to_string(offset) + ": numeric literal: incomplete number"); | 771 | "JSON: offset " + std::to_string(offset) + ": numeric literal: incomplete number"); |
| @@ -1078,7 +1082,7 @@ JSONParser::getToken() | @@ -1078,7 +1082,7 @@ JSONParser::getToken() | ||
| 1078 | 1082 | ||
| 1079 | case ls_u4: | 1083 | case ls_u4: |
| 1080 | using ui = unsigned int; | 1084 | using ui = unsigned int; |
| 1081 | - if (ui val = ui(QUtil::hex_decode_char(*p)); val < 16) { | 1085 | + if (ui val = ui(util::hex_decode_char(*p)); val < 16) { |
| 1082 | u_value = 16 * u_value + val; | 1086 | u_value = 16 * u_value + val; |
| 1083 | } else { | 1087 | } else { |
| 1084 | tokenError(); | 1088 | tokenError(); |
libqpdf/Pl_Base64.cc
| @@ -2,9 +2,13 @@ | @@ -2,9 +2,13 @@ | ||
| 2 | 2 | ||
| 3 | #include <qpdf/QIntC.hh> | 3 | #include <qpdf/QIntC.hh> |
| 4 | #include <qpdf/QUtil.hh> | 4 | #include <qpdf/QUtil.hh> |
| 5 | +#include <qpdf/Util.hh> | ||
| 6 | + | ||
| 5 | #include <cstring> | 7 | #include <cstring> |
| 6 | #include <stdexcept> | 8 | #include <stdexcept> |
| 7 | 9 | ||
| 10 | +using namespace qpdf; | ||
| 11 | + | ||
| 8 | static char | 12 | static char |
| 9 | to_c(unsigned int ch) | 13 | to_c(unsigned int ch) |
| 10 | { | 14 | { |
| @@ -50,7 +54,7 @@ Pl_Base64::decode(unsigned char const* data, size_t len) | @@ -50,7 +54,7 @@ Pl_Base64::decode(unsigned char const* data, size_t len) | ||
| 50 | { | 54 | { |
| 51 | unsigned char const* p = data; | 55 | unsigned char const* p = data; |
| 52 | while (len > 0) { | 56 | while (len > 0) { |
| 53 | - if (!QUtil::is_space(to_c(*p))) { | 57 | + if (!util::is_space(to_c(*p))) { |
| 54 | this->buf[this->pos++] = *p; | 58 | this->buf[this->pos++] = *p; |
| 55 | if (this->pos == 4) { | 59 | if (this->pos == 4) { |
| 56 | flush(); | 60 | flush(); |
libqpdf/QPDF.cc
| @@ -22,6 +22,9 @@ | @@ -22,6 +22,9 @@ | ||
| 22 | #include <qpdf/QPDFParser.hh> | 22 | #include <qpdf/QPDFParser.hh> |
| 23 | #include <qpdf/QTC.hh> | 23 | #include <qpdf/QTC.hh> |
| 24 | #include <qpdf/QUtil.hh> | 24 | #include <qpdf/QUtil.hh> |
| 25 | +#include <qpdf/Util.hh> | ||
| 26 | + | ||
| 27 | +using namespace qpdf; | ||
| 25 | 28 | ||
| 26 | // This must be a fixed value. This API returns a const reference to it, and the C API relies on its | 29 | // This must be a fixed value. This API returns a const reference to it, and the C API relies on its |
| 27 | // being static as well. | 30 | // being static as well. |
| @@ -368,14 +371,14 @@ QPDF::numWarnings() const | @@ -368,14 +371,14 @@ QPDF::numWarnings() const | ||
| 368 | bool | 371 | bool |
| 369 | QPDF::validatePDFVersion(char const*& p, std::string& version) | 372 | QPDF::validatePDFVersion(char const*& p, std::string& version) |
| 370 | { | 373 | { |
| 371 | - bool valid = QUtil::is_digit(*p); | 374 | + bool valid = util::is_digit(*p); |
| 372 | if (valid) { | 375 | if (valid) { |
| 373 | - while (QUtil::is_digit(*p)) { | 376 | + while (util::is_digit(*p)) { |
| 374 | version.append(1, *p++); | 377 | version.append(1, *p++); |
| 375 | } | 378 | } |
| 376 | - if ((*p == '.') && QUtil::is_digit(*(p + 1))) { | 379 | + if ((*p == '.') && util::is_digit(*(p + 1))) { |
| 377 | version.append(1, *p++); | 380 | version.append(1, *p++); |
| 378 | - while (QUtil::is_digit(*p)) { | 381 | + while (util::is_digit(*p)) { |
| 379 | version.append(1, *p++); | 382 | version.append(1, *p++); |
| 380 | } | 383 | } |
| 381 | } else { | 384 | } else { |
| @@ -709,7 +712,7 @@ QPDF::read_xref(qpdf_offset_t xref_offset) | @@ -709,7 +712,7 @@ QPDF::read_xref(qpdf_offset_t xref_offset) | ||
| 709 | while (!done) { | 712 | while (!done) { |
| 710 | char ch; | 713 | char ch; |
| 711 | if (1 == m->file->read(&ch, 1)) { | 714 | if (1 == m->file->read(&ch, 1)) { |
| 712 | - if (QUtil::is_space(ch)) { | 715 | + if (util::is_space(ch)) { |
| 713 | skipped_space = true; | 716 | skipped_space = true; |
| 714 | } else { | 717 | } else { |
| 715 | m->file->unreadCh(ch); | 718 | m->file->unreadCh(ch); |
| @@ -724,7 +727,7 @@ QPDF::read_xref(qpdf_offset_t xref_offset) | @@ -724,7 +727,7 @@ QPDF::read_xref(qpdf_offset_t xref_offset) | ||
| 724 | m->file->read(buf, sizeof(buf) - 1); | 727 | m->file->read(buf, sizeof(buf) - 1); |
| 725 | // The PDF spec says xref must be followed by a line terminator, but files exist in the wild | 728 | // The PDF spec says xref must be followed by a line terminator, but files exist in the wild |
| 726 | // where it is terminated by arbitrary whitespace. | 729 | // where it is terminated by arbitrary whitespace. |
| 727 | - if ((strncmp(buf, "xref", 4) == 0) && QUtil::is_space(buf[4])) { | 730 | + if ((strncmp(buf, "xref", 4) == 0) && util::is_space(buf[4])) { |
| 728 | if (skipped_space) { | 731 | if (skipped_space) { |
| 729 | QTC::TC("qpdf", "QPDF xref skipped space"); | 732 | QTC::TC("qpdf", "QPDF xref skipped space"); |
| 730 | warn(damagedPDF("", 0, "extraneous whitespace seen before xref")); | 733 | warn(damagedPDF("", 0, "extraneous whitespace seen before xref")); |
| @@ -737,8 +740,8 @@ QPDF::read_xref(qpdf_offset_t xref_offset) | @@ -737,8 +740,8 @@ QPDF::read_xref(qpdf_offset_t xref_offset) | ||
| 737 | : (buf[4] == ' ') ? 2 | 740 | : (buf[4] == ' ') ? 2 |
| 738 | : 9999)); | 741 | : 9999)); |
| 739 | int skip = 4; | 742 | int skip = 4; |
| 740 | - // buf is null-terminated, and QUtil::is_space('\0') is false, so this won't overrun. | ||
| 741 | - while (QUtil::is_space(buf[skip])) { | 743 | + // buf is null-terminated, and util::is_space('\0') is false, so this won't overrun. |
| 744 | + while (util::is_space(buf[skip])) { | ||
| 742 | ++skip; | 745 | ++skip; |
| 743 | } | 746 | } |
| 744 | xref_offset = read_xrefTable(xref_offset + skip); | 747 | xref_offset = read_xrefTable(xref_offset + skip); |
| @@ -795,37 +798,37 @@ QPDF::parse_xrefFirst(std::string const& line, int& obj, int& num, int& bytes) | @@ -795,37 +798,37 @@ QPDF::parse_xrefFirst(std::string const& line, int& obj, int& num, int& bytes) | ||
| 795 | char const* start = line.c_str(); | 798 | char const* start = line.c_str(); |
| 796 | 799 | ||
| 797 | // Skip zero or more spaces | 800 | // Skip zero or more spaces |
| 798 | - while (QUtil::is_space(*p)) { | 801 | + while (util::is_space(*p)) { |
| 799 | ++p; | 802 | ++p; |
| 800 | } | 803 | } |
| 801 | // Require digit | 804 | // Require digit |
| 802 | - if (!QUtil::is_digit(*p)) { | 805 | + if (!util::is_digit(*p)) { |
| 803 | return false; | 806 | return false; |
| 804 | } | 807 | } |
| 805 | // Gather digits | 808 | // Gather digits |
| 806 | std::string obj_str; | 809 | std::string obj_str; |
| 807 | - while (QUtil::is_digit(*p)) { | 810 | + while (util::is_digit(*p)) { |
| 808 | obj_str.append(1, *p++); | 811 | obj_str.append(1, *p++); |
| 809 | } | 812 | } |
| 810 | // Require space | 813 | // Require space |
| 811 | - if (!QUtil::is_space(*p)) { | 814 | + if (!util::is_space(*p)) { |
| 812 | return false; | 815 | return false; |
| 813 | } | 816 | } |
| 814 | // Skip spaces | 817 | // Skip spaces |
| 815 | - while (QUtil::is_space(*p)) { | 818 | + while (util::is_space(*p)) { |
| 816 | ++p; | 819 | ++p; |
| 817 | } | 820 | } |
| 818 | // Require digit | 821 | // Require digit |
| 819 | - if (!QUtil::is_digit(*p)) { | 822 | + if (!util::is_digit(*p)) { |
| 820 | return false; | 823 | return false; |
| 821 | } | 824 | } |
| 822 | // Gather digits | 825 | // Gather digits |
| 823 | std::string num_str; | 826 | std::string num_str; |
| 824 | - while (QUtil::is_digit(*p)) { | 827 | + while (util::is_digit(*p)) { |
| 825 | num_str.append(1, *p++); | 828 | num_str.append(1, *p++); |
| 826 | } | 829 | } |
| 827 | // Skip any space including line terminators | 830 | // Skip any space including line terminators |
| 828 | - while (QUtil::is_space(*p)) { | 831 | + while (util::is_space(*p)) { |
| 829 | ++p; | 832 | ++p; |
| 830 | } | 833 | } |
| 831 | bytes = toI(p - start); | 834 | bytes = toI(p - start); |
| @@ -847,51 +850,51 @@ QPDF::read_bad_xrefEntry(qpdf_offset_t& f1, int& f2, char& type) | @@ -847,51 +850,51 @@ QPDF::read_bad_xrefEntry(qpdf_offset_t& f1, int& f2, char& type) | ||
| 847 | 850 | ||
| 848 | // Skip zero or more spaces. There aren't supposed to be any. | 851 | // Skip zero or more spaces. There aren't supposed to be any. |
| 849 | bool invalid = false; | 852 | bool invalid = false; |
| 850 | - while (QUtil::is_space(*p)) { | 853 | + while (util::is_space(*p)) { |
| 851 | ++p; | 854 | ++p; |
| 852 | QTC::TC("qpdf", "QPDF ignore first space in xref entry"); | 855 | QTC::TC("qpdf", "QPDF ignore first space in xref entry"); |
| 853 | invalid = true; | 856 | invalid = true; |
| 854 | } | 857 | } |
| 855 | // Require digit | 858 | // Require digit |
| 856 | - if (!QUtil::is_digit(*p)) { | 859 | + if (!util::is_digit(*p)) { |
| 857 | return false; | 860 | return false; |
| 858 | } | 861 | } |
| 859 | // Gather digits | 862 | // Gather digits |
| 860 | std::string f1_str; | 863 | std::string f1_str; |
| 861 | - while (QUtil::is_digit(*p)) { | 864 | + while (util::is_digit(*p)) { |
| 862 | f1_str.append(1, *p++); | 865 | f1_str.append(1, *p++); |
| 863 | } | 866 | } |
| 864 | // Require space | 867 | // Require space |
| 865 | - if (!QUtil::is_space(*p)) { | 868 | + if (!util::is_space(*p)) { |
| 866 | return false; | 869 | return false; |
| 867 | } | 870 | } |
| 868 | - if (QUtil::is_space(*(p + 1))) { | 871 | + if (util::is_space(*(p + 1))) { |
| 869 | QTC::TC("qpdf", "QPDF ignore first extra space in xref entry"); | 872 | QTC::TC("qpdf", "QPDF ignore first extra space in xref entry"); |
| 870 | invalid = true; | 873 | invalid = true; |
| 871 | } | 874 | } |
| 872 | // Skip spaces | 875 | // Skip spaces |
| 873 | - while (QUtil::is_space(*p)) { | 876 | + while (util::is_space(*p)) { |
| 874 | ++p; | 877 | ++p; |
| 875 | } | 878 | } |
| 876 | // Require digit | 879 | // Require digit |
| 877 | - if (!QUtil::is_digit(*p)) { | 880 | + if (!util::is_digit(*p)) { |
| 878 | return false; | 881 | return false; |
| 879 | } | 882 | } |
| 880 | // Gather digits | 883 | // Gather digits |
| 881 | std::string f2_str; | 884 | std::string f2_str; |
| 882 | - while (QUtil::is_digit(*p)) { | 885 | + while (util::is_digit(*p)) { |
| 883 | f2_str.append(1, *p++); | 886 | f2_str.append(1, *p++); |
| 884 | } | 887 | } |
| 885 | // Require space | 888 | // Require space |
| 886 | - if (!QUtil::is_space(*p)) { | 889 | + if (!util::is_space(*p)) { |
| 887 | return false; | 890 | return false; |
| 888 | } | 891 | } |
| 889 | - if (QUtil::is_space(*(p + 1))) { | 892 | + if (util::is_space(*(p + 1))) { |
| 890 | QTC::TC("qpdf", "QPDF ignore second extra space in xref entry"); | 893 | QTC::TC("qpdf", "QPDF ignore second extra space in xref entry"); |
| 891 | invalid = true; | 894 | invalid = true; |
| 892 | } | 895 | } |
| 893 | // Skip spaces | 896 | // Skip spaces |
| 894 | - while (QUtil::is_space(*p)) { | 897 | + while (util::is_space(*p)) { |
| 895 | ++p; | 898 | ++p; |
| 896 | } | 899 | } |
| 897 | if ((*p == 'f') || (*p == 'n')) { | 900 | if ((*p == 'f') || (*p == 'n')) { |
| @@ -938,12 +941,12 @@ QPDF::read_xrefEntry(qpdf_offset_t& f1, int& f2, char& type) | @@ -938,12 +941,12 @@ QPDF::read_xrefEntry(qpdf_offset_t& f1, int& f2, char& type) | ||
| 938 | ++f1_len; | 941 | ++f1_len; |
| 939 | ++p; | 942 | ++p; |
| 940 | } | 943 | } |
| 941 | - while (QUtil::is_digit(*p) && f1_len++ < 10) { | 944 | + while (util::is_digit(*p) && f1_len++ < 10) { |
| 942 | f1 *= 10; | 945 | f1 *= 10; |
| 943 | f1 += *p++ - '0'; | 946 | f1 += *p++ - '0'; |
| 944 | } | 947 | } |
| 945 | // Require space | 948 | // Require space |
| 946 | - if (!QUtil::is_space(*p++)) { | 949 | + if (!util::is_space(*p++)) { |
| 947 | // Entry doesn't start with space or digit. | 950 | // Entry doesn't start with space or digit. |
| 948 | // C++20: [[unlikely]] | 951 | // C++20: [[unlikely]] |
| 949 | return false; | 952 | return false; |
| @@ -953,11 +956,11 @@ QPDF::read_xrefEntry(qpdf_offset_t& f1, int& f2, char& type) | @@ -953,11 +956,11 @@ QPDF::read_xrefEntry(qpdf_offset_t& f1, int& f2, char& type) | ||
| 953 | ++f2_len; | 956 | ++f2_len; |
| 954 | ++p; | 957 | ++p; |
| 955 | } | 958 | } |
| 956 | - while (QUtil::is_digit(*p) && f2_len++ < 5) { | 959 | + while (util::is_digit(*p) && f2_len++ < 5) { |
| 957 | f2 *= 10; | 960 | f2 *= 10; |
| 958 | f2 += static_cast<int>(*p++ - '0'); | 961 | f2 += static_cast<int>(*p++ - '0'); |
| 959 | } | 962 | } |
| 960 | - if (QUtil::is_space(*p++) && (*p == 'f' || *p == 'n')) { | 963 | + if (util::is_space(*p++) && (*p == 'f' || *p == 'n')) { |
| 961 | // C++20: [[likely]] | 964 | // C++20: [[likely]] |
| 962 | type = *p; | 965 | type = *p; |
| 963 | // No test for valid line[19]. | 966 | // No test for valid line[19]. |
| @@ -1602,7 +1605,7 @@ QPDF::validateStreamLineEnd(QPDFObjectHandle& object, QPDFObjGen og, qpdf_offset | @@ -1602,7 +1605,7 @@ QPDF::validateStreamLineEnd(QPDFObjectHandle& object, QPDFObjGen og, qpdf_offset | ||
| 1602 | } | 1605 | } |
| 1603 | return; | 1606 | return; |
| 1604 | } | 1607 | } |
| 1605 | - if (!QUtil::is_space(ch)) { | 1608 | + if (!util::is_space(ch)) { |
| 1606 | QTC::TC("qpdf", "QPDF stream without newline"); | 1609 | QTC::TC("qpdf", "QPDF stream without newline"); |
| 1607 | m->file->unreadCh(ch); | 1610 | m->file->unreadCh(ch); |
| 1608 | warn(damagedPDF( | 1611 | warn(damagedPDF( |
libqpdf/QPDFArgParser.cc
| @@ -5,10 +5,13 @@ | @@ -5,10 +5,13 @@ | ||
| 5 | #include <qpdf/QPDFUsage.hh> | 5 | #include <qpdf/QPDFUsage.hh> |
| 6 | #include <qpdf/QTC.hh> | 6 | #include <qpdf/QTC.hh> |
| 7 | #include <qpdf/QUtil.hh> | 7 | #include <qpdf/QUtil.hh> |
| 8 | +#include <qpdf/Util.hh> | ||
| 9 | + | ||
| 8 | #include <cstdlib> | 10 | #include <cstdlib> |
| 9 | #include <cstring> | 11 | #include <cstring> |
| 10 | #include <iostream> | 12 | #include <iostream> |
| 11 | 13 | ||
| 14 | +using namespace qpdf; | ||
| 12 | using namespace std::literals; | 15 | using namespace std::literals; |
| 13 | 16 | ||
| 14 | QPDFArgParser::Members::Members(int argc, char const* const argv[], char const* progname_env) : | 17 | QPDFArgParser::Members::Members(int argc, char const* const argv[], char const* progname_env) : |
| @@ -285,7 +288,7 @@ QPDFArgParser::handleBashArguments() | @@ -285,7 +288,7 @@ QPDFArgParser::handleBashArguments() | ||
| 285 | bool append = false; | 288 | bool append = false; |
| 286 | switch (state) { | 289 | switch (state) { |
| 287 | case st_top: | 290 | case st_top: |
| 288 | - if (QUtil::is_space(ch)) { | 291 | + if (util::is_space(ch)) { |
| 289 | if (!arg.empty()) { | 292 | if (!arg.empty()) { |
| 290 | m->bash_argv.push_back(QUtil::make_shared_cstr(arg)); | 293 | m->bash_argv.push_back(QUtil::make_shared_cstr(arg)); |
| 291 | arg.clear(); | 294 | arg.clear(); |
libqpdf/QPDFJob.cc
| @@ -29,9 +29,12 @@ | @@ -29,9 +29,12 @@ | ||
| 29 | #include <qpdf/QPDFWriter.hh> | 29 | #include <qpdf/QPDFWriter.hh> |
| 30 | #include <qpdf/QTC.hh> | 30 | #include <qpdf/QTC.hh> |
| 31 | #include <qpdf/QUtil.hh> | 31 | #include <qpdf/QUtil.hh> |
| 32 | +#include <qpdf/Util.hh> | ||
| 32 | 33 | ||
| 33 | #include <qpdf/auto_job_schema.hh> // JOB_SCHEMA_DATA | 34 | #include <qpdf/auto_job_schema.hh> // JOB_SCHEMA_DATA |
| 34 | 35 | ||
| 36 | +using namespace qpdf; | ||
| 37 | + | ||
| 35 | namespace | 38 | namespace |
| 36 | { | 39 | { |
| 37 | class ImageOptimizer: public QPDFObjectHandle::StreamDataProvider | 40 | class ImageOptimizer: public QPDFObjectHandle::StreamDataProvider |
| @@ -388,7 +391,7 @@ QPDFJob::parseRotationParameter(std::string const& parameter) | @@ -388,7 +391,7 @@ QPDFJob::parseRotationParameter(std::string const& parameter) | ||
| 388 | if ((first == '+') || (first == '-')) { | 391 | if ((first == '+') || (first == '-')) { |
| 389 | relative = ((first == '+') ? 1 : -1); | 392 | relative = ((first == '+') ? 1 : -1); |
| 390 | angle_str = angle_str.substr(1); | 393 | angle_str = angle_str.substr(1); |
| 391 | - } else if (!QUtil::is_digit(angle_str.at(0))) { | 394 | + } else if (!util::is_digit(angle_str.at(0))) { |
| 392 | angle_str = ""; | 395 | angle_str = ""; |
| 393 | } | 396 | } |
| 394 | } | 397 | } |
libqpdf/QPDFObjectHandle.cc
| @@ -15,6 +15,7 @@ | @@ -15,6 +15,7 @@ | ||
| 15 | #include <qpdf/QIntC.hh> | 15 | #include <qpdf/QIntC.hh> |
| 16 | #include <qpdf/QTC.hh> | 16 | #include <qpdf/QTC.hh> |
| 17 | #include <qpdf/QUtil.hh> | 17 | #include <qpdf/QUtil.hh> |
| 18 | +#include <qpdf/Util.hh> | ||
| 18 | 19 | ||
| 19 | #include <algorithm> | 20 | #include <algorithm> |
| 20 | #include <array> | 21 | #include <array> |
| @@ -279,7 +280,7 @@ Name::normalize(std::string const& name) | @@ -279,7 +280,7 @@ Name::normalize(std::string const& name) | ||
| 279 | } else if ( | 280 | } else if ( |
| 280 | ch < 33 || ch == '#' || ch == '/' || ch == '(' || ch == ')' || ch == '{' || ch == '}' || | 281 | ch < 33 || ch == '#' || ch == '/' || ch == '(' || ch == ')' || ch == '{' || ch == '}' || |
| 281 | ch == '<' || ch == '>' || ch == '[' || ch == ']' || ch == '%' || ch > 126) { | 282 | ch == '<' || ch == '>' || ch == '[' || ch == ']' || ch == '%' || ch > 126) { |
| 282 | - result += QUtil::hex_encode_char(ch); | 283 | + result += util::hex_encode_char(ch); |
| 283 | } else { | 284 | } else { |
| 284 | result += ch; | 285 | result += ch; |
| 285 | } | 286 | } |
libqpdf/QPDFTokenizer.cc
| @@ -8,11 +8,14 @@ | @@ -8,11 +8,14 @@ | ||
| 8 | #include <qpdf/QPDFObjectHandle.hh> | 8 | #include <qpdf/QPDFObjectHandle.hh> |
| 9 | #include <qpdf/QTC.hh> | 9 | #include <qpdf/QTC.hh> |
| 10 | #include <qpdf/QUtil.hh> | 10 | #include <qpdf/QUtil.hh> |
| 11 | +#include <qpdf/Util.hh> | ||
| 11 | 12 | ||
| 12 | #include <cstdlib> | 13 | #include <cstdlib> |
| 13 | #include <cstring> | 14 | #include <cstring> |
| 14 | #include <stdexcept> | 15 | #include <stdexcept> |
| 15 | 16 | ||
| 17 | +using namespace qpdf; | ||
| 18 | + | ||
| 16 | static inline bool | 19 | static inline bool |
| 17 | is_delimiter(char ch) | 20 | is_delimiter(char ch) |
| 18 | { | 21 | { |
| @@ -123,7 +126,7 @@ QPDFTokenizer::includeIgnorable() | @@ -123,7 +126,7 @@ QPDFTokenizer::includeIgnorable() | ||
| 123 | bool | 126 | bool |
| 124 | QPDFTokenizer::isSpace(char ch) | 127 | QPDFTokenizer::isSpace(char ch) |
| 125 | { | 128 | { |
| 126 | - return ((ch == '\0') || QUtil::is_space(ch)); | 129 | + return (ch == '\0' || util::is_space(ch)); |
| 127 | } | 130 | } |
| 128 | 131 | ||
| 129 | bool | 132 | bool |
| @@ -440,7 +443,7 @@ QPDFTokenizer::inNameHex1(char ch) | @@ -440,7 +443,7 @@ QPDFTokenizer::inNameHex1(char ch) | ||
| 440 | { | 443 | { |
| 441 | this->hex_char = ch; | 444 | this->hex_char = ch; |
| 442 | 445 | ||
| 443 | - if (char hval = QUtil::hex_decode_char(ch); hval < '0') { | 446 | + if (char hval = util::hex_decode_char(ch); hval < '0') { |
| 444 | this->char_code = int(hval) << 4; | 447 | this->char_code = int(hval) << 4; |
| 445 | this->state = st_name_hex2; | 448 | this->state = st_name_hex2; |
| 446 | } else { | 449 | } else { |
| @@ -456,7 +459,7 @@ QPDFTokenizer::inNameHex1(char ch) | @@ -456,7 +459,7 @@ QPDFTokenizer::inNameHex1(char ch) | ||
| 456 | void | 459 | void |
| 457 | QPDFTokenizer::inNameHex2(char ch) | 460 | QPDFTokenizer::inNameHex2(char ch) |
| 458 | { | 461 | { |
| 459 | - if (char hval = QUtil::hex_decode_char(ch); hval < '0') { | 462 | + if (char hval = util::hex_decode_char(ch); hval < '0') { |
| 460 | this->char_code |= int(hval); | 463 | this->char_code |= int(hval); |
| 461 | } else { | 464 | } else { |
| 462 | QTC::TC("qpdf", "QPDFTokenizer bad name 2"); | 465 | QTC::TC("qpdf", "QPDFTokenizer bad name 2"); |
| @@ -483,7 +486,7 @@ QPDFTokenizer::inNameHex2(char ch) | @@ -483,7 +486,7 @@ QPDFTokenizer::inNameHex2(char ch) | ||
| 483 | void | 486 | void |
| 484 | QPDFTokenizer::inSign(char ch) | 487 | QPDFTokenizer::inSign(char ch) |
| 485 | { | 488 | { |
| 486 | - if (QUtil::is_digit(ch)) { | 489 | + if (util::is_digit(ch)) { |
| 487 | this->state = st_number; | 490 | this->state = st_number; |
| 488 | } else if (ch == '.') { | 491 | } else if (ch == '.') { |
| 489 | this->state = st_decimal; | 492 | this->state = st_decimal; |
| @@ -496,7 +499,7 @@ QPDFTokenizer::inSign(char ch) | @@ -496,7 +499,7 @@ QPDFTokenizer::inSign(char ch) | ||
| 496 | void | 499 | void |
| 497 | QPDFTokenizer::inDecimal(char ch) | 500 | QPDFTokenizer::inDecimal(char ch) |
| 498 | { | 501 | { |
| 499 | - if (QUtil::is_digit(ch)) { | 502 | + if (util::is_digit(ch)) { |
| 500 | this->state = st_real; | 503 | this->state = st_real; |
| 501 | } else { | 504 | } else { |
| 502 | this->state = st_literal; | 505 | this->state = st_literal; |
| @@ -507,7 +510,7 @@ QPDFTokenizer::inDecimal(char ch) | @@ -507,7 +510,7 @@ QPDFTokenizer::inDecimal(char ch) | ||
| 507 | void | 510 | void |
| 508 | QPDFTokenizer::inNumber(char ch) | 511 | QPDFTokenizer::inNumber(char ch) |
| 509 | { | 512 | { |
| 510 | - if (QUtil::is_digit(ch)) { | 513 | + if (util::is_digit(ch)) { |
| 511 | } else if (ch == '.') { | 514 | } else if (ch == '.') { |
| 512 | this->state = st_real; | 515 | this->state = st_real; |
| 513 | } else if (isDelimiter(ch)) { | 516 | } else if (isDelimiter(ch)) { |
| @@ -523,7 +526,7 @@ QPDFTokenizer::inNumber(char ch) | @@ -523,7 +526,7 @@ QPDFTokenizer::inNumber(char ch) | ||
| 523 | void | 526 | void |
| 524 | QPDFTokenizer::inReal(char ch) | 527 | QPDFTokenizer::inReal(char ch) |
| 525 | { | 528 | { |
| 526 | - if (QUtil::is_digit(ch)) { | 529 | + if (util::is_digit(ch)) { |
| 527 | } else if (isDelimiter(ch)) { | 530 | } else if (isDelimiter(ch)) { |
| 528 | this->type = tt_real; | 531 | this->type = tt_real; |
| 529 | this->state = st_token_ready; | 532 | this->state = st_token_ready; |
| @@ -645,7 +648,7 @@ QPDFTokenizer::inLiteral(char ch) | @@ -645,7 +648,7 @@ QPDFTokenizer::inLiteral(char ch) | ||
| 645 | void | 648 | void |
| 646 | QPDFTokenizer::inHexstring(char ch) | 649 | QPDFTokenizer::inHexstring(char ch) |
| 647 | { | 650 | { |
| 648 | - if (char hval = QUtil::hex_decode_char(ch); hval < '0') { | 651 | + if (char hval = util::hex_decode_char(ch); hval < '0') { |
| 649 | this->char_code = int(hval) << 4; | 652 | this->char_code = int(hval) << 4; |
| 650 | this->state = st_in_hexstring_2nd; | 653 | this->state = st_in_hexstring_2nd; |
| 651 | 654 | ||
| @@ -667,7 +670,7 @@ QPDFTokenizer::inHexstring(char ch) | @@ -667,7 +670,7 @@ QPDFTokenizer::inHexstring(char ch) | ||
| 667 | void | 670 | void |
| 668 | QPDFTokenizer::inHexstring2nd(char ch) | 671 | QPDFTokenizer::inHexstring2nd(char ch) |
| 669 | { | 672 | { |
| 670 | - if (char hval = QUtil::hex_decode_char(ch); hval < '0') { | 673 | + if (char hval = util::hex_decode_char(ch); hval < '0') { |
| 671 | this->val += char(this->char_code) | hval; | 674 | this->val += char(this->char_code) | hval; |
| 672 | this->state = st_in_hexstring; | 675 | this->state = st_in_hexstring; |
| 673 | 676 |
libqpdf/QPDF_json.cc
| @@ -9,9 +9,13 @@ | @@ -9,9 +9,13 @@ | ||
| 9 | #include <qpdf/QPDFObject_private.hh> | 9 | #include <qpdf/QPDFObject_private.hh> |
| 10 | #include <qpdf/QTC.hh> | 10 | #include <qpdf/QTC.hh> |
| 11 | #include <qpdf/QUtil.hh> | 11 | #include <qpdf/QUtil.hh> |
| 12 | +#include <qpdf/Util.hh> | ||
| 13 | + | ||
| 12 | #include <algorithm> | 14 | #include <algorithm> |
| 13 | #include <cstring> | 15 | #include <cstring> |
| 14 | 16 | ||
| 17 | +using namespace qpdf; | ||
| 18 | + | ||
| 15 | // This chart shows an example of the state transitions that would occur in parsing a minimal file. | 19 | // This chart shows an example of the state transitions that would occur in parsing a minimal file. |
| 16 | 20 | ||
| 17 | // | | 21 | // | |
| @@ -67,10 +71,10 @@ is_indirect_object(std::string const& v, int& obj, int& gen) | @@ -67,10 +71,10 @@ is_indirect_object(std::string const& v, int& obj, int& gen) | ||
| 67 | char const* p = v.c_str(); | 71 | char const* p = v.c_str(); |
| 68 | std::string o_str; | 72 | std::string o_str; |
| 69 | std::string g_str; | 73 | std::string g_str; |
| 70 | - if (!QUtil::is_digit(*p)) { | 74 | + if (!util::is_digit(*p)) { |
| 71 | return false; | 75 | return false; |
| 72 | } | 76 | } |
| 73 | - while (QUtil::is_digit(*p)) { | 77 | + while (util::is_digit(*p)) { |
| 74 | o_str.append(1, *p++); | 78 | o_str.append(1, *p++); |
| 75 | } | 79 | } |
| 76 | if (*p != ' ') { | 80 | if (*p != ' ') { |
| @@ -79,10 +83,10 @@ is_indirect_object(std::string const& v, int& obj, int& gen) | @@ -79,10 +83,10 @@ is_indirect_object(std::string const& v, int& obj, int& gen) | ||
| 79 | while (*p == ' ') { | 83 | while (*p == ' ') { |
| 80 | ++p; | 84 | ++p; |
| 81 | } | 85 | } |
| 82 | - if (!QUtil::is_digit(*p)) { | 86 | + if (!util::is_digit(*p)) { |
| 83 | return false; | 87 | return false; |
| 84 | } | 88 | } |
| 85 | - while (QUtil::is_digit(*p)) { | 89 | + while (util::is_digit(*p)) { |
| 86 | g_str.append(1, *p++); | 90 | g_str.append(1, *p++); |
| 87 | } | 91 | } |
| 88 | if (*p != ' ') { | 92 | if (*p != ' ') { |
| @@ -128,7 +132,7 @@ is_binary_string(std::string const& v, std::string& str) | @@ -128,7 +132,7 @@ is_binary_string(std::string const& v, std::string& str) | ||
| 128 | str = v.substr(2); | 132 | str = v.substr(2); |
| 129 | int count = 0; | 133 | int count = 0; |
| 130 | for (char c: str) { | 134 | for (char c: str) { |
| 131 | - if (!QUtil::is_hex_digit(c)) { | 135 | + if (!util::is_hex_digit(c)) { |
| 132 | return false; | 136 | return false; |
| 133 | } | 137 | } |
| 134 | ++count; | 138 | ++count; |
libqpdf/QPDF_linearization.cc
| @@ -12,11 +12,14 @@ | @@ -12,11 +12,14 @@ | ||
| 12 | #include <qpdf/QPDFWriter_private.hh> | 12 | #include <qpdf/QPDFWriter_private.hh> |
| 13 | #include <qpdf/QTC.hh> | 13 | #include <qpdf/QTC.hh> |
| 14 | #include <qpdf/QUtil.hh> | 14 | #include <qpdf/QUtil.hh> |
| 15 | +#include <qpdf/Util.hh> | ||
| 15 | 16 | ||
| 16 | #include <algorithm> | 17 | #include <algorithm> |
| 17 | #include <cmath> | 18 | #include <cmath> |
| 18 | #include <cstring> | 19 | #include <cstring> |
| 19 | 20 | ||
| 21 | +using namespace qpdf; | ||
| 22 | + | ||
| 20 | template <class T, class int_type> | 23 | template <class T, class int_type> |
| 21 | static void | 24 | static void |
| 22 | load_vector_int( | 25 | load_vector_int( |
| @@ -105,7 +108,7 @@ QPDF::isLinearized() | @@ -105,7 +108,7 @@ QPDF::isLinearized() | ||
| 105 | char* p = buf; | 108 | char* p = buf; |
| 106 | while (lindict_obj == -1) { | 109 | while (lindict_obj == -1) { |
| 107 | // Find a digit or end of buffer | 110 | // Find a digit or end of buffer |
| 108 | - while (((p - buf) < tbuf_size) && (!QUtil::is_digit(*p))) { | 111 | + while (((p - buf) < tbuf_size) && (!util::is_digit(*p))) { |
| 109 | ++p; | 112 | ++p; |
| 110 | } | 113 | } |
| 111 | if (p - buf == tbuf_size) { | 114 | if (p - buf == tbuf_size) { |
| @@ -114,7 +117,7 @@ QPDF::isLinearized() | @@ -114,7 +117,7 @@ QPDF::isLinearized() | ||
| 114 | // Seek to the digit. Then skip over digits for a potential | 117 | // Seek to the digit. Then skip over digits for a potential |
| 115 | // next iteration. | 118 | // next iteration. |
| 116 | m->file->seek(p - buf, SEEK_SET); | 119 | m->file->seek(p - buf, SEEK_SET); |
| 117 | - while (((p - buf) < tbuf_size) && QUtil::is_digit(*p)) { | 120 | + while (((p - buf) < tbuf_size) && util::is_digit(*p)) { |
| 118 | ++p; | 121 | ++p; |
| 119 | } | 122 | } |
| 120 | 123 |
libqpdf/QUtil.cc
| @@ -8,6 +8,7 @@ | @@ -8,6 +8,7 @@ | ||
| 8 | #include <qpdf/QIntC.hh> | 8 | #include <qpdf/QIntC.hh> |
| 9 | #include <qpdf/QPDFSystemError.hh> | 9 | #include <qpdf/QPDFSystemError.hh> |
| 10 | #include <qpdf/QTC.hh> | 10 | #include <qpdf/QTC.hh> |
| 11 | +#include <qpdf/Util.hh> | ||
| 11 | 12 | ||
| 12 | #include <cerrno> | 13 | #include <cerrno> |
| 13 | #include <cstdlib> | 14 | #include <cstdlib> |
| @@ -37,6 +38,8 @@ | @@ -37,6 +38,8 @@ | ||
| 37 | # include <malloc.h> | 38 | # include <malloc.h> |
| 38 | #endif | 39 | #endif |
| 39 | 40 | ||
| 41 | +using namespace qpdf; | ||
| 42 | + | ||
| 40 | // First element is 24 | 43 | // First element is 24 |
| 41 | static unsigned short pdf_doc_low_to_unicode[] = { | 44 | static unsigned short pdf_doc_low_to_unicode[] = { |
| 42 | 0x02d8, // 0x18 BREVE | 45 | 0x02d8, // 0x18 BREVE |
| @@ -396,7 +399,7 @@ unsigned long long | @@ -396,7 +399,7 @@ unsigned long long | ||
| 396 | QUtil::string_to_ull(char const* str) | 399 | QUtil::string_to_ull(char const* str) |
| 397 | { | 400 | { |
| 398 | char const* p = str; | 401 | char const* p = str; |
| 399 | - while (*p && is_space(*p)) { | 402 | + while (*p && util::is_space(*p)) { |
| 400 | ++p; | 403 | ++p; |
| 401 | } | 404 | } |
| 402 | if (*p == '-') { | 405 | if (*p == '-') { |
| @@ -739,7 +742,7 @@ QUtil::hex_decode(std::string const& input) | @@ -739,7 +742,7 @@ QUtil::hex_decode(std::string const& input) | ||
| 739 | bool first = true; | 742 | bool first = true; |
| 740 | char decoded; | 743 | char decoded; |
| 741 | for (auto ch: input) { | 744 | for (auto ch: input) { |
| 742 | - ch = hex_decode_char(ch); | 745 | + ch = util::hex_decode_char(ch); |
| 743 | if (ch < '\20') { | 746 | if (ch < '\20') { |
| 744 | if (first) { | 747 | if (first) { |
| 745 | decoded = static_cast<char>(ch << 4); | 748 | decoded = static_cast<char>(ch << 4); |
| @@ -2002,3 +2005,63 @@ QUtil::get_max_memory_usage() | @@ -2002,3 +2005,63 @@ QUtil::get_max_memory_usage() | ||
| 2002 | return 0; | 2005 | return 0; |
| 2003 | #endif | 2006 | #endif |
| 2004 | } | 2007 | } |
| 2008 | + | ||
| 2009 | +char | ||
| 2010 | +QUtil::hex_decode_char(char digit) | ||
| 2011 | +{ | ||
| 2012 | + return util::hex_decode_char(digit); | ||
| 2013 | +} | ||
| 2014 | + | ||
| 2015 | +std::string | ||
| 2016 | +QUtil::hex_encode_char(char c) | ||
| 2017 | +{ | ||
| 2018 | + return util::hex_encode_char(c); | ||
| 2019 | +} | ||
| 2020 | + | ||
| 2021 | +bool | ||
| 2022 | +QUtil::is_number(char const* p) | ||
| 2023 | +{ | ||
| 2024 | + // No longer used by qpdf. | ||
| 2025 | + | ||
| 2026 | + // ^[\+\-]?(\.\d*|\d+(\.\d*)?)$ | ||
| 2027 | + if (!*p) { | ||
| 2028 | + return false; | ||
| 2029 | + } | ||
| 2030 | + if ((*p == '-') || (*p == '+')) { | ||
| 2031 | + ++p; | ||
| 2032 | + } | ||
| 2033 | + bool found_dot = false; | ||
| 2034 | + bool found_digit = false; | ||
| 2035 | + for (; *p; ++p) { | ||
| 2036 | + if (*p == '.') { | ||
| 2037 | + if (found_dot) { | ||
| 2038 | + // only one dot | ||
| 2039 | + return false; | ||
| 2040 | + } | ||
| 2041 | + found_dot = true; | ||
| 2042 | + } else if (util::is_digit(*p)) { | ||
| 2043 | + found_digit = true; | ||
| 2044 | + } else { | ||
| 2045 | + return false; | ||
| 2046 | + } | ||
| 2047 | + } | ||
| 2048 | + return found_digit; | ||
| 2049 | +} | ||
| 2050 | + | ||
| 2051 | +bool | ||
| 2052 | +QUtil::is_space(char c) | ||
| 2053 | +{ | ||
| 2054 | + return util::is_space(c); | ||
| 2055 | +} | ||
| 2056 | + | ||
| 2057 | +bool | ||
| 2058 | +QUtil::is_digit(char c) | ||
| 2059 | +{ | ||
| 2060 | + return util::is_digit(c); | ||
| 2061 | +} | ||
| 2062 | + | ||
| 2063 | +bool | ||
| 2064 | +QUtil::is_hex_digit(char c) | ||
| 2065 | +{ | ||
| 2066 | + return util::is_hex_digit(c); | ||
| 2067 | +} |
libqpdf/qpdf/Util.hh
0 → 100644
| 1 | +#ifndef UTIL_HH | ||
| 2 | +#define UTIL_HH | ||
| 3 | + | ||
| 4 | +#include <string> | ||
| 5 | + | ||
| 6 | +namespace qpdf::util | ||
| 7 | +{ | ||
| 8 | + // This is a collection of useful utility functions for qpdf internal use. They include inline | ||
| 9 | + // functions, some of which are exposed as regular functions in QUtil. Implementations are in | ||
| 10 | + // QUtil.cc. | ||
| 11 | + | ||
| 12 | + inline constexpr char | ||
| 13 | + hex_decode_char(char digit) | ||
| 14 | + { | ||
| 15 | + return digit <= '9' && digit >= '0' | ||
| 16 | + ? char(digit - '0') | ||
| 17 | + : (digit >= 'a' ? char(digit - 'a' + 10) | ||
| 18 | + : (digit >= 'A' ? char(digit - 'A' + 10) : '\20')); | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + inline constexpr bool | ||
| 22 | + is_hex_digit(char ch) | ||
| 23 | + { | ||
| 24 | + return hex_decode_char(ch) < '\20'; | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + inline constexpr bool | ||
| 28 | + is_space(char ch) | ||
| 29 | + { | ||
| 30 | + return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\v'; | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + inline bool | ||
| 34 | + is_digit(char ch) | ||
| 35 | + { | ||
| 36 | + return (ch >= '0' && ch <= '9'); | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + // Returns lower-case hex-encoded version of the char including a leading "#". | ||
| 40 | + inline std::string | ||
| 41 | + hex_encode_char(char c) | ||
| 42 | + { | ||
| 43 | + static auto constexpr hexchars = "0123456789abcdef"; | ||
| 44 | + return {'#', hexchars[static_cast<unsigned char>(c) >> 4], hexchars[c & 0x0f]}; | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | +} // namespace qpdf::util | ||
| 48 | + | ||
| 49 | +#endif // UTIL_HH |