Commit 873562f46bcc61e29f696477d41914fdeb050ea8

Authored by m-holger
1 parent 8d7ed764

Move QPDFObject::as to BaseHandle

include/qpdf/ObjectHandle.hh
@@ -67,6 +67,9 @@ namespace qpdf @@ -67,6 +67,9 @@ namespace qpdf
67 BaseHandle& operator=(BaseHandle&&) = default; 67 BaseHandle& operator=(BaseHandle&&) = default;
68 ~BaseHandle() = default; 68 ~BaseHandle() = default;
69 69
  70 + template <typename T>
  71 + T* as() const;
  72 +
70 std::shared_ptr<QPDFObject> obj; 73 std::shared_ptr<QPDFObject> obj;
71 }; 74 };
72 75
include/qpdf/QPDF.hh
@@ -798,9 +798,10 @@ class QPDF @@ -798,9 +798,10 @@ class QPDF
798 { 798 {
799 friend class QPDFObject; 799 friend class QPDFObject;
800 friend class QPDF_Unresolved; 800 friend class QPDF_Unresolved;
  801 + friend class qpdf::BaseHandle;
801 802
802 private: 803 private:
803 - static QPDFObject* 804 + static std::shared_ptr<QPDFObject> const&
804 resolved(QPDF* qpdf, QPDFObjGen og) 805 resolved(QPDF* qpdf, QPDFObjGen og)
805 { 806 {
806 return qpdf->resolve(og); 807 return qpdf->resolve(og);
@@ -1072,7 +1073,7 @@ class QPDF @@ -1072,7 +1073,7 @@ class QPDF
1072 QPDFObjGen exp_og, 1073 QPDFObjGen exp_og,
1073 QPDFObjGen& og, 1074 QPDFObjGen& og,
1074 bool skip_cache_if_in_xref); 1075 bool skip_cache_if_in_xref);
1075 - QPDFObject* resolve(QPDFObjGen og); 1076 + std::shared_ptr<QPDFObject> const& resolve(QPDFObjGen og);
1076 void resolveObjectsInStream(int obj_stream_number); 1077 void resolveObjectsInStream(int obj_stream_number);
1077 void stopOnError(std::string const& message); 1078 void stopOnError(std::string const& message);
1078 QPDFObjGen nextObjGen(); 1079 QPDFObjGen nextObjGen();
include/qpdf/QPDFObjectHandle.hh
@@ -1359,20 +1359,6 @@ class QPDFObjectHandle final: public qpdf::BaseHandle @@ -1359,20 +1359,6 @@ class QPDFObjectHandle final: public qpdf::BaseHandle
1359 inline qpdf::Stream as_stream(qpdf::typed options = qpdf::typed::strict) const; 1359 inline qpdf::Stream as_stream(qpdf::typed options = qpdf::typed::strict) const;
1360 1360
1361 private: 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 void typeWarning(char const* expected_type, std::string const& warning) const; 1362 void typeWarning(char const* expected_type, std::string const& warning) const;
1377 void objectWarning(std::string const& warning) const; 1363 void objectWarning(std::string const& warning) const;
1378 void assertType(char const* type_name, bool istype) const; 1364 void assertType(char const* type_name, bool istype) const;
libqpdf/QPDF.cc
@@ -1867,11 +1867,11 @@ QPDF::readObjectAtOffset( @@ -1867,11 +1867,11 @@ QPDF::readObjectAtOffset(
1867 return oh; 1867 return oh;
1868 } 1868 }
1869 1869
1870 -QPDFObject* 1870 +std::shared_ptr<QPDFObject> const&
1871 QPDF::resolve(QPDFObjGen og) 1871 QPDF::resolve(QPDFObjGen og)
1872 { 1872 {
1873 if (!isUnresolved(og)) { 1873 if (!isUnresolved(og)) {
1874 - return m->obj_cache[og].object.get(); 1874 + return m->obj_cache[og].object;
1875 } 1875 }
1876 1876
1877 if (m->resolving.count(og)) { 1877 if (m->resolving.count(og)) {
@@ -1880,7 +1880,7 @@ QPDF::resolve(QPDFObjGen og) @@ -1880,7 +1880,7 @@ QPDF::resolve(QPDFObjGen og)
1880 QTC::TC("qpdf", "QPDF recursion loop in resolve"); 1880 QTC::TC("qpdf", "QPDF recursion loop in resolve");
1881 warn(damagedPDF("", "loop detected resolving object " + og.unparse(' '))); 1881 warn(damagedPDF("", "loop detected resolving object " + og.unparse(' ')));
1882 updateCache(og, QPDFObject::create<QPDF_Null>(), -1, -1); 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 ResolveRecorder rr(this, og); 1885 ResolveRecorder rr(this, og);
1886 1886
@@ -1919,9 +1919,9 @@ QPDF::resolve(QPDFObjGen og) @@ -1919,9 +1919,9 @@ QPDF::resolve(QPDFObjGen og)
1919 updateCache(og, QPDFObject::create<QPDF_Null>(), -1, -1); 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 result->setDefaultDescription(this, og); 1923 result->setDefaultDescription(this, og);
1924 - return result.get(); 1924 + return result;
1925 } 1925 }
1926 1926
1927 void 1927 void
libqpdf/QPDFObjectHandle.cc
@@ -697,24 +697,6 @@ QPDFObjectHandle::getTypeName() const @@ -697,24 +697,6 @@ QPDFObjectHandle::getTypeName() const
697 return obj ? tn[getTypeCode()] : "uninitialized"; 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 bool 700 bool
719 QPDFObjectHandle::isDestroyed() const 701 QPDFObjectHandle::isDestroyed() const
720 { 702 {
@@ -861,8 +843,7 @@ QPDFObjectHandle::isStreamOfType(std::string const&amp; type, std::string const&amp; sub @@ -861,8 +843,7 @@ QPDFObjectHandle::isStreamOfType(std::string const&amp; type, std::string const&amp; sub
861 bool 843 bool
862 QPDFObjectHandle::getBoolValue() const 844 QPDFObjectHandle::getBoolValue() const
863 { 845 {
864 - auto boolean = asBool();  
865 - if (boolean) { 846 + if (auto boolean = as<QPDF_Bool>()) {
866 return boolean->val; 847 return boolean->val;
867 } else { 848 } else {
868 typeWarning("boolean", "returning false"); 849 typeWarning("boolean", "returning false");
@@ -874,12 +855,11 @@ QPDFObjectHandle::getBoolValue() const @@ -874,12 +855,11 @@ QPDFObjectHandle::getBoolValue() const
874 bool 855 bool
875 QPDFObjectHandle::getValueAsBool(bool& value) const 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 // Integer accessors 865 // Integer accessors
@@ -887,8 +867,7 @@ QPDFObjectHandle::getValueAsBool(bool&amp; value) const @@ -887,8 +867,7 @@ QPDFObjectHandle::getValueAsBool(bool&amp; value) const
887 long long 867 long long
888 QPDFObjectHandle::getIntValue() const 868 QPDFObjectHandle::getIntValue() const
889 { 869 {
890 - auto integer = asInteger();  
891 - if (integer) { 870 + if (auto integer = as<QPDF_Integer>()) {
892 return integer->val; 871 return integer->val;
893 } else { 872 } else {
894 typeWarning("integer", "returning 0"); 873 typeWarning("integer", "returning 0");
@@ -900,12 +879,11 @@ QPDFObjectHandle::getIntValue() const @@ -900,12 +879,11 @@ QPDFObjectHandle::getIntValue() const
900 bool 879 bool
901 QPDFObjectHandle::getValueAsInt(long long& value) const 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 int 889 int
@@ -1062,8 +1040,7 @@ QPDFObjectHandle::getValueAsString(std::string&amp; value) const @@ -1062,8 +1040,7 @@ QPDFObjectHandle::getValueAsString(std::string&amp; value) const
1062 std::string 1040 std::string
1063 QPDFObjectHandle::getUTF8Value() const 1041 QPDFObjectHandle::getUTF8Value() const
1064 { 1042 {
1065 - auto str = asString();  
1066 - if (str) { 1043 + if (auto str = as<QPDF_String>()) {
1067 return str->getUTF8Val(); 1044 return str->getUTF8Val();
1068 } else { 1045 } else {
1069 typeWarning("string", "returning empty string"); 1046 typeWarning("string", "returning empty string");
@@ -1075,12 +1052,11 @@ QPDFObjectHandle::getUTF8Value() const @@ -1075,12 +1052,11 @@ QPDFObjectHandle::getUTF8Value() const
1075 bool 1052 bool
1076 QPDFObjectHandle::getValueAsUTF8(std::string& value) const 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 // Operator and Inline Image accessors 1062 // Operator and Inline Image accessors
@@ -1487,7 +1463,7 @@ QPDFObjectHandle::unparseResolved() const @@ -1487,7 +1463,7 @@ QPDFObjectHandle::unparseResolved() const
1487 std::string 1463 std::string
1488 QPDFObjectHandle::unparseBinary() const 1464 QPDFObjectHandle::unparseBinary() const
1489 { 1465 {
1490 - if (auto str = asString()) { 1466 + if (auto str = as<QPDF_String>()) {
1491 return str->unparse(true); 1467 return str->unparse(true);
1492 } else { 1468 } else {
1493 return unparse(); 1469 return unparse();
libqpdf/QPDF_Array.cc
@@ -59,11 +59,10 @@ QPDF_Array::QPDF_Array(std::vector&lt;std::shared_ptr&lt;QPDFObject&gt;&gt;&amp;&amp; v, bool sparse @@ -59,11 +59,10 @@ QPDF_Array::QPDF_Array(std::vector&lt;std::shared_ptr&lt;QPDFObject&gt;&gt;&amp;&amp; v, bool sparse
59 QPDF_Array* 59 QPDF_Array*
60 Array::array() const 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 throw std::runtime_error("Expected an array but found a non-array object"); 66 throw std::runtime_error("Expected an array but found a non-array object");
68 return nullptr; // unreachable 67 return nullptr; // unreachable
69 } 68 }
libqpdf/QPDF_Dictionary.cc
@@ -9,10 +9,8 @@ using namespace qpdf; @@ -9,10 +9,8 @@ using namespace qpdf;
9 QPDF_Dictionary* 9 QPDF_Dictionary*
10 BaseDictionary::dict() const 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 throw std::runtime_error("Expected a dictionary but found a non-dictionary object"); 15 throw std::runtime_error("Expected a dictionary but found a non-dictionary object");
18 return nullptr; // unreachable 16 return nullptr; // unreachable
libqpdf/qpdf/QPDFObjectHandle_private.hh
@@ -204,12 +204,13 @@ namespace qpdf @@ -204,12 +204,13 @@ namespace qpdf
204 QPDF_Stream::Members* 204 QPDF_Stream::Members*
205 stream() const 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 return nullptr; // unreachable 214 return nullptr; // unreachable
214 } 215 }
215 bool filterable( 216 bool filterable(
@@ -226,6 +227,26 @@ namespace qpdf @@ -226,6 +227,26 @@ namespace qpdf
226 filter_factories; 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 inline qpdf_object_type_e 250 inline qpdf_object_type_e
230 BaseHandle::type_code() const 251 BaseHandle::type_code() const
231 { 252 {
libqpdf/qpdf/QPDFObject_private.hh
@@ -172,6 +172,7 @@ class QPDF_Reference @@ -172,6 +172,7 @@ class QPDF_Reference
172 // objects that are an indirect reference we will need to support multiple levels of 172 // objects that are an indirect reference we will need to support multiple levels of
173 // indirection, including the possibility of circular references. 173 // indirection, including the possibility of circular references.
174 friend class QPDFObject; 174 friend class QPDFObject;
  175 + friend class qpdf::BaseHandle;
175 176
176 QPDF_Reference(std::shared_ptr<QPDFObject> obj) : 177 QPDF_Reference(std::shared_ptr<QPDFObject> obj) :
177 obj(std::move(obj)) 178 obj(std::move(obj))
@@ -366,7 +367,7 @@ class QPDFObject @@ -366,7 +367,7 @@ class QPDFObject
366 const QPDFObject* 367 const QPDFObject*
367 resolved_object() const 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 struct JSON_Descr 373 struct JSON_Descr
@@ -461,25 +462,10 @@ class QPDFObject @@ -461,25 +462,10 @@ class QPDFObject
461 return og; 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 private: 465 private:
482 friend class QPDF_Stream; 466 friend class QPDF_Stream;
  467 + friend class qpdf::BaseHandle;
  468 +
483 typedef std::variant< 469 typedef std::variant<
484 std::monostate, 470 std::monostate,
485 QPDF_Reserved, 471 QPDF_Reserved,