Commit 873562f46bcc61e29f696477d41914fdeb050ea8
1 parent
8d7ed764
Move QPDFObject::as to BaseHandle
Showing
9 changed files
with
61 additions
and
91 deletions
include/qpdf/ObjectHandle.hh
include/qpdf/QPDF.hh
| ... | ... | @@ -798,9 +798,10 @@ class QPDF |
| 798 | 798 | { |
| 799 | 799 | friend class QPDFObject; |
| 800 | 800 | friend class QPDF_Unresolved; |
| 801 | + friend class qpdf::BaseHandle; | |
| 801 | 802 | |
| 802 | 803 | private: |
| 803 | - static QPDFObject* | |
| 804 | + static std::shared_ptr<QPDFObject> const& | |
| 804 | 805 | resolved(QPDF* qpdf, QPDFObjGen og) |
| 805 | 806 | { |
| 806 | 807 | return qpdf->resolve(og); |
| ... | ... | @@ -1072,7 +1073,7 @@ class QPDF |
| 1072 | 1073 | QPDFObjGen exp_og, |
| 1073 | 1074 | QPDFObjGen& og, |
| 1074 | 1075 | bool skip_cache_if_in_xref); |
| 1075 | - QPDFObject* resolve(QPDFObjGen og); | |
| 1076 | + std::shared_ptr<QPDFObject> const& resolve(QPDFObjGen og); | |
| 1076 | 1077 | void resolveObjectsInStream(int obj_stream_number); |
| 1077 | 1078 | void stopOnError(std::string const& message); |
| 1078 | 1079 | QPDFObjGen nextObjGen(); | ... | ... |
include/qpdf/QPDFObjectHandle.hh
| ... | ... | @@ -1359,20 +1359,6 @@ class QPDFObjectHandle final: public qpdf::BaseHandle |
| 1359 | 1359 | inline qpdf::Stream as_stream(qpdf::typed options = qpdf::typed::strict) const; |
| 1360 | 1360 | |
| 1361 | 1361 | private: |
| 1362 | - QPDF_Array* asArray() const; | |
| 1363 | - QPDF_Bool* asBool() const; | |
| 1364 | - QPDF_Dictionary* asDictionary() const; | |
| 1365 | - QPDF_InlineImage* asInlineImage() const; | |
| 1366 | - QPDF_Integer* asInteger() const; | |
| 1367 | - QPDF_Name* asName() const; | |
| 1368 | - QPDF_Null* asNull() const; | |
| 1369 | - QPDF_Operator* asOperator() const; | |
| 1370 | - QPDF_Real* asReal() const; | |
| 1371 | - QPDF_Reserved* asReserved() const; | |
| 1372 | - QPDF_Stream* asStream() const; | |
| 1373 | - QPDF_Stream* asStreamWithAssert() const; | |
| 1374 | - QPDF_String* asString() const; | |
| 1375 | - | |
| 1376 | 1362 | void typeWarning(char const* expected_type, std::string const& warning) const; |
| 1377 | 1363 | void objectWarning(std::string const& warning) const; |
| 1378 | 1364 | void assertType(char const* type_name, bool istype) const; | ... | ... |
libqpdf/QPDF.cc
| ... | ... | @@ -1867,11 +1867,11 @@ QPDF::readObjectAtOffset( |
| 1867 | 1867 | return oh; |
| 1868 | 1868 | } |
| 1869 | 1869 | |
| 1870 | -QPDFObject* | |
| 1870 | +std::shared_ptr<QPDFObject> const& | |
| 1871 | 1871 | QPDF::resolve(QPDFObjGen og) |
| 1872 | 1872 | { |
| 1873 | 1873 | if (!isUnresolved(og)) { |
| 1874 | - return m->obj_cache[og].object.get(); | |
| 1874 | + return m->obj_cache[og].object; | |
| 1875 | 1875 | } |
| 1876 | 1876 | |
| 1877 | 1877 | if (m->resolving.count(og)) { |
| ... | ... | @@ -1880,7 +1880,7 @@ QPDF::resolve(QPDFObjGen og) |
| 1880 | 1880 | QTC::TC("qpdf", "QPDF recursion loop in resolve"); |
| 1881 | 1881 | warn(damagedPDF("", "loop detected resolving object " + og.unparse(' '))); |
| 1882 | 1882 | updateCache(og, QPDFObject::create<QPDF_Null>(), -1, -1); |
| 1883 | - return m->obj_cache[og].object.get(); | |
| 1883 | + return m->obj_cache[og].object; | |
| 1884 | 1884 | } |
| 1885 | 1885 | ResolveRecorder rr(this, og); |
| 1886 | 1886 | |
| ... | ... | @@ -1919,9 +1919,9 @@ QPDF::resolve(QPDFObjGen og) |
| 1919 | 1919 | updateCache(og, QPDFObject::create<QPDF_Null>(), -1, -1); |
| 1920 | 1920 | } |
| 1921 | 1921 | |
| 1922 | - auto result(m->obj_cache[og].object); | |
| 1922 | + auto& result(m->obj_cache[og].object); | |
| 1923 | 1923 | result->setDefaultDescription(this, og); |
| 1924 | - return result.get(); | |
| 1924 | + return result; | |
| 1925 | 1925 | } |
| 1926 | 1926 | |
| 1927 | 1927 | void | ... | ... |
libqpdf/QPDFObjectHandle.cc
| ... | ... | @@ -697,24 +697,6 @@ QPDFObjectHandle::getTypeName() const |
| 697 | 697 | return obj ? tn[getTypeCode()] : "uninitialized"; |
| 698 | 698 | } |
| 699 | 699 | |
| 700 | -QPDF_Bool* | |
| 701 | -QPDFObjectHandle::asBool() const | |
| 702 | -{ | |
| 703 | - return obj ? obj->as<QPDF_Bool>() : nullptr; | |
| 704 | -} | |
| 705 | - | |
| 706 | -QPDF_Integer* | |
| 707 | -QPDFObjectHandle::asInteger() const | |
| 708 | -{ | |
| 709 | - return obj ? obj->as<QPDF_Integer>() : nullptr; | |
| 710 | -} | |
| 711 | - | |
| 712 | -QPDF_String* | |
| 713 | -QPDFObjectHandle::asString() const | |
| 714 | -{ | |
| 715 | - return obj ? obj->as<QPDF_String>() : nullptr; | |
| 716 | -} | |
| 717 | - | |
| 718 | 700 | bool |
| 719 | 701 | QPDFObjectHandle::isDestroyed() const |
| 720 | 702 | { |
| ... | ... | @@ -861,8 +843,7 @@ QPDFObjectHandle::isStreamOfType(std::string const& type, std::string const& sub |
| 861 | 843 | bool |
| 862 | 844 | QPDFObjectHandle::getBoolValue() const |
| 863 | 845 | { |
| 864 | - auto boolean = asBool(); | |
| 865 | - if (boolean) { | |
| 846 | + if (auto boolean = as<QPDF_Bool>()) { | |
| 866 | 847 | return boolean->val; |
| 867 | 848 | } else { |
| 868 | 849 | typeWarning("boolean", "returning false"); |
| ... | ... | @@ -874,12 +855,11 @@ QPDFObjectHandle::getBoolValue() const |
| 874 | 855 | bool |
| 875 | 856 | QPDFObjectHandle::getValueAsBool(bool& value) const |
| 876 | 857 | { |
| 877 | - auto boolean = asBool(); | |
| 878 | - if (boolean == nullptr) { | |
| 879 | - return false; | |
| 858 | + if (auto boolean = as<QPDF_Bool>()) { | |
| 859 | + value = boolean->val; | |
| 860 | + return true; | |
| 880 | 861 | } |
| 881 | - value = boolean->val; | |
| 882 | - return true; | |
| 862 | + return false; | |
| 883 | 863 | } |
| 884 | 864 | |
| 885 | 865 | // Integer accessors |
| ... | ... | @@ -887,8 +867,7 @@ QPDFObjectHandle::getValueAsBool(bool& value) const |
| 887 | 867 | long long |
| 888 | 868 | QPDFObjectHandle::getIntValue() const |
| 889 | 869 | { |
| 890 | - auto integer = asInteger(); | |
| 891 | - if (integer) { | |
| 870 | + if (auto integer = as<QPDF_Integer>()) { | |
| 892 | 871 | return integer->val; |
| 893 | 872 | } else { |
| 894 | 873 | typeWarning("integer", "returning 0"); |
| ... | ... | @@ -900,12 +879,11 @@ QPDFObjectHandle::getIntValue() const |
| 900 | 879 | bool |
| 901 | 880 | QPDFObjectHandle::getValueAsInt(long long& value) const |
| 902 | 881 | { |
| 903 | - auto integer = asInteger(); | |
| 904 | - if (integer == nullptr) { | |
| 905 | - return false; | |
| 882 | + if (auto integer = as<QPDF_Integer>()) { | |
| 883 | + value = integer->val; | |
| 884 | + return true; | |
| 906 | 885 | } |
| 907 | - value = integer->val; | |
| 908 | - return true; | |
| 886 | + return false; | |
| 909 | 887 | } |
| 910 | 888 | |
| 911 | 889 | int |
| ... | ... | @@ -1062,8 +1040,7 @@ QPDFObjectHandle::getValueAsString(std::string& value) const |
| 1062 | 1040 | std::string |
| 1063 | 1041 | QPDFObjectHandle::getUTF8Value() const |
| 1064 | 1042 | { |
| 1065 | - auto str = asString(); | |
| 1066 | - if (str) { | |
| 1043 | + if (auto str = as<QPDF_String>()) { | |
| 1067 | 1044 | return str->getUTF8Val(); |
| 1068 | 1045 | } else { |
| 1069 | 1046 | typeWarning("string", "returning empty string"); |
| ... | ... | @@ -1075,12 +1052,11 @@ QPDFObjectHandle::getUTF8Value() const |
| 1075 | 1052 | bool |
| 1076 | 1053 | QPDFObjectHandle::getValueAsUTF8(std::string& value) const |
| 1077 | 1054 | { |
| 1078 | - auto str = asString(); | |
| 1079 | - if (str == nullptr) { | |
| 1080 | - return false; | |
| 1055 | + if (auto str = as<QPDF_String>()) { | |
| 1056 | + value = str->getUTF8Val(); | |
| 1057 | + return true; | |
| 1081 | 1058 | } |
| 1082 | - value = str->getUTF8Val(); | |
| 1083 | - return true; | |
| 1059 | + return false; | |
| 1084 | 1060 | } |
| 1085 | 1061 | |
| 1086 | 1062 | // Operator and Inline Image accessors |
| ... | ... | @@ -1487,7 +1463,7 @@ QPDFObjectHandle::unparseResolved() const |
| 1487 | 1463 | std::string |
| 1488 | 1464 | QPDFObjectHandle::unparseBinary() const |
| 1489 | 1465 | { |
| 1490 | - if (auto str = asString()) { | |
| 1466 | + if (auto str = as<QPDF_String>()) { | |
| 1491 | 1467 | return str->unparse(true); |
| 1492 | 1468 | } else { |
| 1493 | 1469 | return unparse(); | ... | ... |
libqpdf/QPDF_Array.cc
| ... | ... | @@ -59,11 +59,10 @@ QPDF_Array::QPDF_Array(std::vector<std::shared_ptr<QPDFObject>>&& v, bool sparse |
| 59 | 59 | QPDF_Array* |
| 60 | 60 | Array::array() const |
| 61 | 61 | { |
| 62 | - if (obj) { | |
| 63 | - if (auto a = obj->as<QPDF_Array>()) { | |
| 64 | - return a; | |
| 65 | - } | |
| 62 | + if (auto a = as<QPDF_Array>()) { | |
| 63 | + return a; | |
| 66 | 64 | } |
| 65 | + | |
| 67 | 66 | throw std::runtime_error("Expected an array but found a non-array object"); |
| 68 | 67 | return nullptr; // unreachable |
| 69 | 68 | } | ... | ... |
libqpdf/QPDF_Dictionary.cc
| ... | ... | @@ -9,10 +9,8 @@ using namespace qpdf; |
| 9 | 9 | QPDF_Dictionary* |
| 10 | 10 | BaseDictionary::dict() const |
| 11 | 11 | { |
| 12 | - if (obj) { | |
| 13 | - if (auto d = obj->as<QPDF_Dictionary>()) { | |
| 14 | - return d; | |
| 15 | - } | |
| 12 | + if (auto d = as<QPDF_Dictionary>()) { | |
| 13 | + return d; | |
| 16 | 14 | } |
| 17 | 15 | throw std::runtime_error("Expected a dictionary but found a non-dictionary object"); |
| 18 | 16 | return nullptr; // unreachable | ... | ... |
libqpdf/qpdf/QPDFObjectHandle_private.hh
| ... | ... | @@ -204,12 +204,13 @@ namespace qpdf |
| 204 | 204 | QPDF_Stream::Members* |
| 205 | 205 | stream() const |
| 206 | 206 | { |
| 207 | - if (obj) { | |
| 208 | - if (auto s = obj->as<QPDF_Stream>()) { | |
| 209 | - return s->m.get(); | |
| 207 | + if (auto s = as<QPDF_Stream>()) { | |
| 208 | + if (auto ptr = s->m.get()) { | |
| 209 | + return ptr; | |
| 210 | 210 | } |
| 211 | + throw std::logic_error("QPDF_Stream: unexpected nullptr"); | |
| 211 | 212 | } |
| 212 | - throw std::runtime_error("operation for stream attempted on object of type dictionary"); | |
| 213 | + throw std::runtime_error("operation for stream attempted on non-stream object"); | |
| 213 | 214 | return nullptr; // unreachable |
| 214 | 215 | } |
| 215 | 216 | bool filterable( |
| ... | ... | @@ -226,6 +227,26 @@ namespace qpdf |
| 226 | 227 | filter_factories; |
| 227 | 228 | }; |
| 228 | 229 | |
| 230 | + template <typename T> | |
| 231 | + T* | |
| 232 | + BaseHandle::as() const | |
| 233 | + { | |
| 234 | + if (!obj) { | |
| 235 | + return nullptr; | |
| 236 | + } | |
| 237 | + if (std::holds_alternative<T>(obj->value)) { | |
| 238 | + return &std::get<T>(obj->value); | |
| 239 | + } | |
| 240 | + if (std::holds_alternative<QPDF_Unresolved>(obj->value)) { | |
| 241 | + return BaseHandle(QPDF::Resolver::resolved(obj->qpdf, obj->og)).as<T>(); | |
| 242 | + } | |
| 243 | + if (std::holds_alternative<QPDF_Reference>(obj->value)) { | |
| 244 | + // see comment in QPDF_Reference. | |
| 245 | + return BaseHandle(std::get<QPDF_Reference>(obj->value).obj).as<T>(); | |
| 246 | + } | |
| 247 | + return nullptr; | |
| 248 | + } | |
| 249 | + | |
| 229 | 250 | inline qpdf_object_type_e |
| 230 | 251 | BaseHandle::type_code() const |
| 231 | 252 | { | ... | ... |
libqpdf/qpdf/QPDFObject_private.hh
| ... | ... | @@ -172,6 +172,7 @@ class QPDF_Reference |
| 172 | 172 | // objects that are an indirect reference we will need to support multiple levels of |
| 173 | 173 | // indirection, including the possibility of circular references. |
| 174 | 174 | friend class QPDFObject; |
| 175 | + friend class qpdf::BaseHandle; | |
| 175 | 176 | |
| 176 | 177 | QPDF_Reference(std::shared_ptr<QPDFObject> obj) : |
| 177 | 178 | obj(std::move(obj)) |
| ... | ... | @@ -366,7 +367,7 @@ class QPDFObject |
| 366 | 367 | const QPDFObject* |
| 367 | 368 | resolved_object() const |
| 368 | 369 | { |
| 369 | - return isUnresolved() ? QPDF::Resolver::resolved(qpdf, og) : this; | |
| 370 | + return isUnresolved() ? QPDF::Resolver::resolved(qpdf, og).get() : this; | |
| 370 | 371 | } |
| 371 | 372 | |
| 372 | 373 | struct JSON_Descr |
| ... | ... | @@ -461,25 +462,10 @@ class QPDFObject |
| 461 | 462 | return og; |
| 462 | 463 | } |
| 463 | 464 | |
| 464 | - template <typename T> | |
| 465 | - T* | |
| 466 | - as() | |
| 467 | - { | |
| 468 | - if (std::holds_alternative<T>(value)) { | |
| 469 | - return &std::get<T>(value); | |
| 470 | - } | |
| 471 | - if (std::holds_alternative<QPDF_Unresolved>(value)) { | |
| 472 | - return QPDF::Resolver::resolved(qpdf, og)->as<T>(); | |
| 473 | - } | |
| 474 | - if (std::holds_alternative<QPDF_Reference>(value)) { | |
| 475 | - // see comment in QPDF_Reference. | |
| 476 | - return std::get<QPDF_Reference>(value).obj->as<T>(); | |
| 477 | - } | |
| 478 | - return nullptr; | |
| 479 | - } | |
| 480 | - | |
| 481 | 465 | private: |
| 482 | 466 | friend class QPDF_Stream; |
| 467 | + friend class qpdf::BaseHandle; | |
| 468 | + | |
| 483 | 469 | typedef std::variant< |
| 484 | 470 | std::monostate, |
| 485 | 471 | QPDF_Reserved, | ... | ... |