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 | 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 | 1046 | std::string |
| 1005 | 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 | 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 | 1057 | bool |
| 1017 | 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 | 1064 | return false; |
| 1021 | 1065 | } |
| 1022 | - value = obj->getStringValue(); | |
| 1023 | - return true; | |
| 1024 | 1066 | } |
| 1025 | 1067 | |
| 1026 | 1068 | std::string |
| 1027 | 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 | 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 | 1079 | bool |
| 1039 | 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 | 1084 | return true; |
| 1085 | + } catch (std::invalid_argument&) { | |
| 1086 | + return false; | |
| 1044 | 1087 | } |
| 1045 | - return false; | |
| 1046 | 1088 | } |
| 1047 | 1089 | |
| 1048 | 1090 | // Operator and Inline Image accessors |
| ... | ... | @@ -1718,18 +1760,6 @@ QPDFObjectHandle::newReal(double value, int decimal_places, bool trim_trailing_z |
| 1718 | 1760 | } |
| 1719 | 1761 | |
| 1720 | 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 | 1763 | QPDFObjectHandle::newOperator(std::string const& value) |
| 1734 | 1764 | { |
| 1735 | 1765 | return {QPDFObject::create<QPDF_Operator>(value)}; | ... | ... |
libqpdf/qpdf/QPDFObjectHandle_private.hh
| ... | ... | @@ -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 | 417 | operator std::string() const& |
| 418 | 418 | { |
| 419 | 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 | 424 | std::string const& value() const; |
| 425 | 425 | |
| 426 | 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 | 589 | void warn(std::string const& message); |
| 590 | 590 | |
| 591 | 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 | 641 | template <typename T> |
| 595 | 642 | T* | ... | ... |
libqpdf/qpdf/QPDFObject_private.hh
| ... | ... | @@ -30,6 +30,7 @@ namespace qpdf |
| 30 | 30 | class Integer; |
| 31 | 31 | class Name; |
| 32 | 32 | class Stream; |
| 33 | + class String; | |
| 33 | 34 | |
| 34 | 35 | namespace impl |
| 35 | 36 | { |
| ... | ... | @@ -261,6 +262,7 @@ class QPDF_String final |
| 261 | 262 | { |
| 262 | 263 | friend class QPDFObject; |
| 263 | 264 | friend class qpdf::BaseHandle; |
| 265 | + friend class qpdf::String; | |
| 264 | 266 | friend class qpdf::impl::Writer; |
| 265 | 267 | |
| 266 | 268 | public: |
| ... | ... | @@ -270,7 +272,11 @@ class QPDF_String final |
| 270 | 272 | std::string getUTF8Val() const; |
| 271 | 273 | |
| 272 | 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 | 280 | val(std::move(val)) |
| 275 | 281 | { |
| 276 | 282 | } | ... | ... |
qpdf/qpdf.testcov
| ... | ... | @@ -174,8 +174,6 @@ QPDFParser eof in parse 0 |
| 174 | 174 | QPDFParser eof in parseRemainder 0 |
| 175 | 175 | QPDFObjectHandle boolean returning false 0 |
| 176 | 176 | QPDFObjectHandle real returning 0.0 0 |
| 177 | -QPDFObjectHandle string returning empty string 0 | |
| 178 | -QPDFObjectHandle string returning empty utf8 0 | |
| 179 | 177 | QPDFObjectHandle operator returning fake value 0 |
| 180 | 178 | QPDFObjectHandle inlineimage returning empty data 0 |
| 181 | 179 | QPDFObjectHandle array treating as empty vector 0 | ... | ... |