Commit 09020472700fa72bb4d093096888ce5b4bc2b0e5
1 parent
906034d9
Introduce private-API `qpdf::String` class and refactor string handling
Added `qpdf::String` class to encapsulate string operations. Updated `QPDFObjectHandle` string methods to utilize `qpdf::String`, streamlined empty string handling, and removed redundant test coverage entries.
Showing
4 changed files
with
118 additions
and
37 deletions
libqpdf/QPDFObjectHandle.cc
| @@ -999,50 +999,92 @@ QPDFObjectHandle::getValueAsName(std::string& value) const | @@ -999,50 +999,92 @@ QPDFObjectHandle::getValueAsName(std::string& value) const | ||
| 999 | return true; | 999 | return true; |
| 1000 | } | 1000 | } |
| 1001 | 1001 | ||
| 1002 | -// String accessors | 1002 | +// String methods |
| 1003 | + | ||
| 1004 | +QPDFObjectHandle | ||
| 1005 | +QPDFObjectHandle::newString(std::string const& str) | ||
| 1006 | +{ | ||
| 1007 | + return {QPDFObject::create<QPDF_String>(str)}; | ||
| 1008 | +} | ||
| 1009 | + | ||
| 1010 | +QPDFObjectHandle | ||
| 1011 | +QPDFObjectHandle::newUnicodeString(std::string const& utf8_str) | ||
| 1012 | +{ | ||
| 1013 | + return {QPDF_String::create_utf16(utf8_str)}; | ||
| 1014 | +} | ||
| 1015 | + | ||
| 1016 | +String::String(std::string const& str) : | ||
| 1017 | + BaseHandle(QPDFObject::create<QPDF_String>(str)) | ||
| 1018 | +{ | ||
| 1019 | +} | ||
| 1020 | + | ||
| 1021 | +String::String(std::string&& str) : | ||
| 1022 | + BaseHandle(QPDFObject::create<QPDF_String>(std::move(str))) | ||
| 1023 | +{ | ||
| 1024 | +} | ||
| 1025 | + | ||
| 1026 | +std::string const& | ||
| 1027 | +String::value() const | ||
| 1028 | +{ | ||
| 1029 | + auto* s = as<QPDF_String>(); | ||
| 1030 | + if (!s) { | ||
| 1031 | + throw invalid_error("String"); | ||
| 1032 | + } | ||
| 1033 | + return s->val; | ||
| 1034 | +} | ||
| 1035 | + | ||
| 1036 | +std::string | ||
| 1037 | +String::utf8_value() const | ||
| 1038 | +{ | ||
| 1039 | + auto* s = as<QPDF_String>(); | ||
| 1040 | + if (!s) { | ||
| 1041 | + throw invalid_error("String"); | ||
| 1042 | + } | ||
| 1043 | + return s->getUTF8Val(); | ||
| 1044 | +} | ||
| 1003 | 1045 | ||
| 1004 | std::string | 1046 | std::string |
| 1005 | QPDFObjectHandle::getStringValue() const | 1047 | QPDFObjectHandle::getStringValue() const |
| 1006 | { | 1048 | { |
| 1007 | - if (isString()) { | ||
| 1008 | - return obj->getStringValue(); | ||
| 1009 | - } else { | 1049 | + try { |
| 1050 | + return String(obj).value(); | ||
| 1051 | + } catch (std::invalid_argument&) { | ||
| 1010 | typeWarning("string", "returning empty string"); | 1052 | typeWarning("string", "returning empty string"); |
| 1011 | - QTC::TC("qpdf", "QPDFObjectHandle string returning empty string"); | ||
| 1012 | - return ""; | 1053 | + return {}; |
| 1013 | } | 1054 | } |
| 1014 | } | 1055 | } |
| 1015 | 1056 | ||
| 1016 | bool | 1057 | bool |
| 1017 | QPDFObjectHandle::getValueAsString(std::string& value) const | 1058 | QPDFObjectHandle::getValueAsString(std::string& value) const |
| 1018 | { | 1059 | { |
| 1019 | - if (!isString()) { | 1060 | + try { |
| 1061 | + value = String(obj).value(); | ||
| 1062 | + return true; | ||
| 1063 | + } catch (std::invalid_argument&) { | ||
| 1020 | return false; | 1064 | return false; |
| 1021 | } | 1065 | } |
| 1022 | - value = obj->getStringValue(); | ||
| 1023 | - return true; | ||
| 1024 | } | 1066 | } |
| 1025 | 1067 | ||
| 1026 | std::string | 1068 | std::string |
| 1027 | QPDFObjectHandle::getUTF8Value() const | 1069 | QPDFObjectHandle::getUTF8Value() const |
| 1028 | { | 1070 | { |
| 1029 | - if (auto str = as<QPDF_String>()) { | ||
| 1030 | - return str->getUTF8Val(); | ||
| 1031 | - } else { | 1071 | + try { |
| 1072 | + return String(obj).utf8_value(); | ||
| 1073 | + } catch (std::invalid_argument&) { | ||
| 1032 | typeWarning("string", "returning empty string"); | 1074 | typeWarning("string", "returning empty string"); |
| 1033 | - QTC::TC("qpdf", "QPDFObjectHandle string returning empty utf8"); | ||
| 1034 | - return ""; | 1075 | + return {}; |
| 1035 | } | 1076 | } |
| 1036 | } | 1077 | } |
| 1037 | 1078 | ||
| 1038 | bool | 1079 | bool |
| 1039 | QPDFObjectHandle::getValueAsUTF8(std::string& value) const | 1080 | QPDFObjectHandle::getValueAsUTF8(std::string& value) const |
| 1040 | { | 1081 | { |
| 1041 | - if (auto str = as<QPDF_String>()) { | ||
| 1042 | - value = str->getUTF8Val(); | 1082 | + try { |
| 1083 | + value = String(obj).utf8_value(); | ||
| 1043 | return true; | 1084 | return true; |
| 1085 | + } catch (std::invalid_argument&) { | ||
| 1086 | + return false; | ||
| 1044 | } | 1087 | } |
| 1045 | - return false; | ||
| 1046 | } | 1088 | } |
| 1047 | 1089 | ||
| 1048 | // Operator and Inline Image accessors | 1090 | // Operator and Inline Image accessors |
| @@ -1718,18 +1760,6 @@ QPDFObjectHandle::newReal(double value, int decimal_places, bool trim_trailing_z | @@ -1718,18 +1760,6 @@ QPDFObjectHandle::newReal(double value, int decimal_places, bool trim_trailing_z | ||
| 1718 | } | 1760 | } |
| 1719 | 1761 | ||
| 1720 | QPDFObjectHandle | 1762 | QPDFObjectHandle |
| 1721 | -QPDFObjectHandle::newString(std::string const& str) | ||
| 1722 | -{ | ||
| 1723 | - return {QPDFObject::create<QPDF_String>(str)}; | ||
| 1724 | -} | ||
| 1725 | - | ||
| 1726 | -QPDFObjectHandle | ||
| 1727 | -QPDFObjectHandle::newUnicodeString(std::string const& utf8_str) | ||
| 1728 | -{ | ||
| 1729 | - return {QPDF_String::create_utf16(utf8_str)}; | ||
| 1730 | -} | ||
| 1731 | - | ||
| 1732 | -QPDFObjectHandle | ||
| 1733 | QPDFObjectHandle::newOperator(std::string const& value) | 1763 | QPDFObjectHandle::newOperator(std::string const& value) |
| 1734 | { | 1764 | { |
| 1735 | return {QPDFObject::create<QPDF_Operator>(value)}; | 1765 | return {QPDFObject::create<QPDF_Operator>(value)}; |
libqpdf/qpdf/QPDFObjectHandle_private.hh
| @@ -412,15 +412,15 @@ namespace qpdf | @@ -412,15 +412,15 @@ namespace qpdf | ||
| 412 | { | 412 | { |
| 413 | } | 413 | } |
| 414 | 414 | ||
| 415 | - // Return the name value. If the object is not a valid Name, throw a | ||
| 416 | - // std::invalid_argument exception. | 415 | + // Return the name value. If the object is not a valid Name, throw a std::invalid_argument |
| 416 | + // exception. | ||
| 417 | operator std::string() const& | 417 | operator std::string() const& |
| 418 | { | 418 | { |
| 419 | return value(); | 419 | return value(); |
| 420 | } | 420 | } |
| 421 | 421 | ||
| 422 | - // Return the integer value. If the object is not a valid integer, throw a | ||
| 423 | - // std::invalid_argument exception. | 422 | + // Return the name value. If the object is not a valid name, throw a std::invalid_argument |
| 423 | + // exception. | ||
| 424 | std::string const& value() const; | 424 | std::string const& value() const; |
| 425 | 425 | ||
| 426 | // Return true if object value is equal to the 'rhs' value. Return false if the object is | 426 | // Return true if object value is equal to the 'rhs' value. Return false if the object is |
| @@ -589,7 +589,54 @@ namespace qpdf | @@ -589,7 +589,54 @@ namespace qpdf | ||
| 589 | void warn(std::string const& message); | 589 | void warn(std::string const& message); |
| 590 | 590 | ||
| 591 | static std::map<std::string, std::string> filter_abbreviations; | 591 | static std::map<std::string, std::string> filter_abbreviations; |
| 592 | - }; | 592 | + }; // class Stream |
| 593 | + | ||
| 594 | + class String final: public BaseHandle | ||
| 595 | + { | ||
| 596 | + public: | ||
| 597 | + String() = default; | ||
| 598 | + String(String const&) = default; | ||
| 599 | + String(String&&) = default; | ||
| 600 | + String& operator=(String const&) = default; | ||
| 601 | + String& operator=(String&&) = default; | ||
| 602 | + ~String() = default; | ||
| 603 | + | ||
| 604 | + explicit String(std::string const&); | ||
| 605 | + explicit String(std::string&&); | ||
| 606 | + | ||
| 607 | + String(QPDFObjectHandle const& oh) : | ||
| 608 | + BaseHandle(oh.type_code() == ::ot_string ? oh : QPDFObjectHandle()) | ||
| 609 | + { | ||
| 610 | + } | ||
| 611 | + | ||
| 612 | + String(QPDFObjectHandle&& oh) : | ||
| 613 | + BaseHandle(oh.type_code() == ::ot_string ? std::move(oh) : QPDFObjectHandle()) | ||
| 614 | + { | ||
| 615 | + } | ||
| 616 | + | ||
| 617 | + // Return the string value. If the object is not a valid string, throw a | ||
| 618 | + // std::invalid_argument exception. | ||
| 619 | + operator std::string() const& | ||
| 620 | + { | ||
| 621 | + return value(); | ||
| 622 | + } | ||
| 623 | + | ||
| 624 | + // Return the string value. If the object is not a valid string, throw a | ||
| 625 | + // std::invalid_argument exception. | ||
| 626 | + std::string const& value() const; | ||
| 627 | + | ||
| 628 | + // Return the string value. If the object is not a valid string, throw a | ||
| 629 | + // std::invalid_argument exception. | ||
| 630 | + std::string utf8_value() const; | ||
| 631 | + | ||
| 632 | + // Return true if object value is equal to the 'rhs' value. Return false if the object is | ||
| 633 | + // not a valid String. | ||
| 634 | + friend bool | ||
| 635 | + operator==(String const& lhs, std::string_view rhs) | ||
| 636 | + { | ||
| 637 | + return lhs && lhs.value() == rhs; | ||
| 638 | + } | ||
| 639 | + }; // class String | ||
| 593 | 640 | ||
| 594 | template <typename T> | 641 | template <typename T> |
| 595 | T* | 642 | T* |
libqpdf/qpdf/QPDFObject_private.hh
| @@ -30,6 +30,7 @@ namespace qpdf | @@ -30,6 +30,7 @@ namespace qpdf | ||
| 30 | class Integer; | 30 | class Integer; |
| 31 | class Name; | 31 | class Name; |
| 32 | class Stream; | 32 | class Stream; |
| 33 | + class String; | ||
| 33 | 34 | ||
| 34 | namespace impl | 35 | namespace impl |
| 35 | { | 36 | { |
| @@ -261,6 +262,7 @@ class QPDF_String final | @@ -261,6 +262,7 @@ class QPDF_String final | ||
| 261 | { | 262 | { |
| 262 | friend class QPDFObject; | 263 | friend class QPDFObject; |
| 263 | friend class qpdf::BaseHandle; | 264 | friend class qpdf::BaseHandle; |
| 265 | + friend class qpdf::String; | ||
| 264 | friend class qpdf::impl::Writer; | 266 | friend class qpdf::impl::Writer; |
| 265 | 267 | ||
| 266 | public: | 268 | public: |
| @@ -270,7 +272,11 @@ class QPDF_String final | @@ -270,7 +272,11 @@ class QPDF_String final | ||
| 270 | std::string getUTF8Val() const; | 272 | std::string getUTF8Val() const; |
| 271 | 273 | ||
| 272 | private: | 274 | private: |
| 273 | - QPDF_String(std::string val) : | 275 | + QPDF_String(std::string const& val) : |
| 276 | + val(val) | ||
| 277 | + { | ||
| 278 | + } | ||
| 279 | + QPDF_String(std::string&& val) : | ||
| 274 | val(std::move(val)) | 280 | val(std::move(val)) |
| 275 | { | 281 | { |
| 276 | } | 282 | } |
qpdf/qpdf.testcov
| @@ -174,8 +174,6 @@ QPDFParser eof in parse 0 | @@ -174,8 +174,6 @@ QPDFParser eof in parse 0 | ||
| 174 | QPDFParser eof in parseRemainder 0 | 174 | QPDFParser eof in parseRemainder 0 |
| 175 | QPDFObjectHandle boolean returning false 0 | 175 | QPDFObjectHandle boolean returning false 0 |
| 176 | QPDFObjectHandle real returning 0.0 0 | 176 | QPDFObjectHandle real returning 0.0 0 |
| 177 | -QPDFObjectHandle string returning empty string 0 | ||
| 178 | -QPDFObjectHandle string returning empty utf8 0 | ||
| 179 | QPDFObjectHandle operator returning fake value 0 | 177 | QPDFObjectHandle operator returning fake value 0 |
| 180 | QPDFObjectHandle inlineimage returning empty data 0 | 178 | QPDFObjectHandle inlineimage returning empty data 0 |
| 181 | QPDFObjectHandle array treating as empty vector 0 | 179 | QPDFObjectHandle array treating as empty vector 0 |