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 67 BaseHandle& operator=(BaseHandle&&) = default;
68 68 ~BaseHandle() = default;
69 69  
  70 + template <typename T>
  71 + T* as() const;
  72 +
70 73 std::shared_ptr<QPDFObject> obj;
71 74 };
72 75  
... ...
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&amp; type, std::string const&amp; 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&amp; 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&amp; 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&lt;std::shared_ptr&lt;QPDFObject&gt;&gt;&amp;&amp; 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,
... ...