Commit 949f2219ac99d6c37212fdb5ee27f5568d3416e4

Authored by m-holger
1 parent 3fcf5696

Add new class qpdf::BaseHandle

The new class is only usable as base classes and does not support direct
instantiation or upcasting.

Add operators to convert to bool, QPDFObjectHandle and QPDFObjGen.

Derive QPDFObjectHandle from BaseHandle and make final.
include/qpdf/ObjectHandle.hh 0 → 100644
  1 +// Copyright (c) 2005-2021 Jay Berkenbilt
  2 +// Copyright (c) 2022-2025 Jay Berkenbilt and Manfred Holger
  3 +//
  4 +// This file is part of qpdf.
  5 +//
  6 +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
  7 +// in compliance with the License. You may obtain a copy of the License at
  8 +//
  9 +// http://www.apache.org/licenses/LICENSE-2.0
  10 +//
  11 +// Unless required by applicable law or agreed to in writing, software distributed under the License
  12 +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
  13 +// or implied. See the License for the specific language governing permissions and limitations under
  14 +// the License.
  15 +//
  16 +// Versions of qpdf prior to version 7 were released under the terms of version 2.0 of the Artistic
  17 +// License. At your option, you may continue to consider qpdf to be licensed under those terms.
  18 +// Please see the manual for additional information.
  19 +
  20 +#ifndef OBJECTHANDLE_HH
  21 +#define OBJECTHANDLE_HH
  22 +
  23 +#include <qpdf/Constants.h>
  24 +#include <qpdf/DLL.h>
  25 +#include <qpdf/Types.h>
  26 +
  27 +#include <qpdf/QPDFObjGen.hh>
  28 +
  29 +class QPDF_Dictionary;
  30 +class QPDFObject;
  31 +class QPDFObjectHandle;
  32 +
  33 +namespace qpdf
  34 +{
  35 + // Basehandle is only used as a base-class for QPDFObjectHandle like classes. Currently the only
  36 + // methods exposed in public API are operators to convert derived objects to QPDFObjectHandle,
  37 + // QPDFObjGen and bool.
  38 + class BaseHandle
  39 + {
  40 + public:
  41 + explicit inline operator bool() const;
  42 + inline operator QPDFObjectHandle() const;
  43 + operator QPDFObjGen() const;
  44 +
  45 + // The rest of the header file is for qpdf internal use only.
  46 +
  47 + protected:
  48 + BaseHandle() = default;
  49 + BaseHandle(std::shared_ptr<QPDFObject> const& obj) :
  50 + obj(obj) {};
  51 + BaseHandle(std::shared_ptr<QPDFObject>&& obj) :
  52 + obj(std::move(obj)) {};
  53 + BaseHandle(BaseHandle const&) = default;
  54 + BaseHandle& operator=(BaseHandle const&) = default;
  55 + BaseHandle(BaseHandle&&) = default;
  56 + BaseHandle& operator=(BaseHandle&&) = default;
  57 + ~BaseHandle() = default;
  58 +
  59 + std::shared_ptr<QPDFObject> obj;
  60 + };
  61 +
  62 +} // namespace qpdf
  63 +
  64 +#endif // QPDFOBJECTHANDLE_HH
include/qpdf/QPDFObjectHandle.hh
@@ -37,6 +37,7 @@ @@ -37,6 +37,7 @@
37 #include <qpdf/Buffer.hh> 37 #include <qpdf/Buffer.hh>
38 #include <qpdf/InputSource.hh> 38 #include <qpdf/InputSource.hh>
39 #include <qpdf/JSON.hh> 39 #include <qpdf/JSON.hh>
  40 +#include <qpdf/ObjectHandle.hh>
40 #include <qpdf/QPDFObjGen.hh> 41 #include <qpdf/QPDFObjGen.hh>
41 #include <qpdf/QPDFTokenizer.hh> 42 #include <qpdf/QPDFTokenizer.hh>
42 43
@@ -55,13 +56,14 @@ class QPDF_Reserved; @@ -55,13 +56,14 @@ class QPDF_Reserved;
55 class QPDF_Stream; 56 class QPDF_Stream;
56 class QPDF_String; 57 class QPDF_String;
57 class QPDFObject; 58 class QPDFObject;
  59 +class QPDFObjectHandle;
58 class QPDFTokenizer; 60 class QPDFTokenizer;
59 class QPDFExc; 61 class QPDFExc;
60 class Pl_QPDFTokenizer; 62 class Pl_QPDFTokenizer;
61 class QPDFMatrix; 63 class QPDFMatrix;
62 class QPDFParser; 64 class QPDFParser;
63 65
64 -class QPDFObjectHandle 66 +class QPDFObjectHandle final: public qpdf::BaseHandle
65 { 67 {
66 friend class QPDFParser; 68 friend class QPDFParser;
67 69
@@ -290,18 +292,12 @@ class QPDFObjectHandle @@ -290,18 +292,12 @@ class QPDFObjectHandle
290 QPDFObjectHandle(QPDFObjectHandle const&) = default; 292 QPDFObjectHandle(QPDFObjectHandle const&) = default;
291 QPDF_DLL 293 QPDF_DLL
292 QPDFObjectHandle& operator=(QPDFObjectHandle const&) = default; 294 QPDFObjectHandle& operator=(QPDFObjectHandle const&) = default;
293 -  
294 QPDF_DLL 295 QPDF_DLL
295 QPDFObjectHandle(QPDFObjectHandle&&) = default; 296 QPDFObjectHandle(QPDFObjectHandle&&) = default;
296 QPDF_DLL 297 QPDF_DLL
297 QPDFObjectHandle& operator=(QPDFObjectHandle&&) = default; 298 QPDFObjectHandle& operator=(QPDFObjectHandle&&) = default;
298 299
299 - // Return true if the QPDFObjectHandle is initialized. This allows object handles to be used in  
300 - // if statements with initializer.  
301 - QPDF_DLL  
302 - explicit inline operator bool() const noexcept;  
303 -  
304 - [[deprecated("use operator bool()")]] QPDF_DLL inline bool isInitialized() const noexcept; 300 + [[deprecated("use operator bool()")]] QPDF_DLL inline bool isInitialized() const;
305 301
306 // This method returns true if the QPDFObjectHandle objects point to exactly the same underlying 302 // This method returns true if the QPDFObjectHandle objects point to exactly the same underlying
307 // object, meaning that changes to one are reflected in the other, or "if you paint one, the 303 // object, meaning that changes to one are reflected in the other, or "if you paint one, the
@@ -1329,7 +1325,11 @@ class QPDFObjectHandle @@ -1329,7 +1325,11 @@ class QPDFObjectHandle
1329 // The following methods do not form part of the public API and are for internal use only. 1325 // The following methods do not form part of the public API and are for internal use only.
1330 1326
1331 QPDFObjectHandle(std::shared_ptr<QPDFObject> const& obj) : 1327 QPDFObjectHandle(std::shared_ptr<QPDFObject> const& obj) :
1332 - obj(obj) 1328 + qpdf::BaseHandle(obj)
  1329 + {
  1330 + }
  1331 + QPDFObjectHandle(std::shared_ptr<QPDFObject>&& obj) :
  1332 + qpdf::BaseHandle(std::move(obj))
1333 { 1333 {
1334 } 1334 }
1335 std::shared_ptr<QPDFObject> 1335 std::shared_ptr<QPDFObject>
@@ -1386,10 +1386,6 @@ class QPDFObjectHandle @@ -1386,10 +1386,6 @@ class QPDFObjectHandle
1386 arrayOrStreamToStreamArray(std::string const& description, std::string& all_description); 1386 arrayOrStreamToStreamArray(std::string const& description, std::string& all_description);
1387 static void warn(QPDF*, QPDFExc const&); 1387 static void warn(QPDF*, QPDFExc const&);
1388 void checkOwnership(QPDFObjectHandle const&) const; 1388 void checkOwnership(QPDFObjectHandle const&) const;
1389 -  
1390 - // Moving members of QPDFObjectHandle into a smart pointer incurs a substantial performance  
1391 - // penalty since QPDFObjectHandle objects are copied around so frequently.  
1392 - std::shared_ptr<QPDFObject> obj;  
1393 }; 1389 };
1394 1390
1395 #ifndef QPDF_NO_QPDF_STRING 1391 #ifndef QPDF_NO_QPDF_STRING
@@ -1606,6 +1602,22 @@ class QPDFObjectHandle::QPDFArrayItems @@ -1606,6 +1602,22 @@ class QPDFObjectHandle::QPDFArrayItems
1606 QPDFObjectHandle oh; 1602 QPDFObjectHandle oh;
1607 }; 1603 };
1608 1604
  1605 +namespace qpdf
  1606 +{
  1607 + inline BaseHandle::
  1608 + operator bool() const
  1609 + {
  1610 + return static_cast<bool>(obj);
  1611 + }
  1612 +
  1613 + inline BaseHandle::
  1614 + operator QPDFObjectHandle() const
  1615 + {
  1616 + return {obj};
  1617 + }
  1618 +
  1619 +} // namespace qpdf
  1620 +
1609 inline int 1621 inline int
1610 QPDFObjectHandle::getObjectID() const 1622 QPDFObjectHandle::getObjectID() const
1611 { 1623 {
@@ -1625,15 +1637,9 @@ QPDFObjectHandle::isIndirect() const @@ -1625,15 +1637,9 @@ QPDFObjectHandle::isIndirect() const
1625 } 1637 }
1626 1638
1627 inline bool 1639 inline bool
1628 -QPDFObjectHandle::isInitialized() const noexcept 1640 +QPDFObjectHandle::isInitialized() const
1629 { 1641 {
1630 return obj != nullptr; 1642 return obj != nullptr;
1631 } 1643 }
1632 1644
1633 -inline QPDFObjectHandle::  
1634 -operator bool() const noexcept  
1635 -{  
1636 - return static_cast<bool>(obj);  
1637 -}  
1638 -  
1639 #endif // QPDFOBJECTHANDLE_HH 1645 #endif // QPDFOBJECTHANDLE_HH
libqpdf/QPDFObjectHandle.cc
@@ -39,6 +39,14 @@ @@ -39,6 +39,14 @@
39 39
40 using namespace std::literals; 40 using namespace std::literals;
41 41
  42 +using namespace qpdf;
  43 +
  44 +BaseHandle::
  45 +operator QPDFObjGen() const
  46 +{
  47 + return obj ? obj->getObjGen() : QPDFObjGen();
  48 +}
  49 +
42 namespace 50 namespace
43 { 51 {
44 class TerminateParsing 52 class TerminateParsing
libqpdf/QPDF_Dictionary.cc
1 #include <qpdf/QPDF_Dictionary.hh> 1 #include <qpdf/QPDF_Dictionary.hh>
2 2
3 #include <qpdf/JSON_writer.hh> 3 #include <qpdf/JSON_writer.hh>
  4 +#include <qpdf/QPDFObjectHandle.hh>
4 #include <qpdf/QPDFObject_private.hh> 5 #include <qpdf/QPDFObject_private.hh>
5 #include <qpdf/QPDF_Name.hh> 6 #include <qpdf/QPDF_Name.hh>
6 #include <qpdf/QPDF_Null.hh> 7 #include <qpdf/QPDF_Null.hh>
7 #include <qpdf/QUtil.hh> 8 #include <qpdf/QUtil.hh>
8 9
9 using namespace std::literals; 10 using namespace std::literals;
  11 +using namespace qpdf;
10 12
11 QPDF_Dictionary::QPDF_Dictionary(std::map<std::string, QPDFObjectHandle> const& items) : 13 QPDF_Dictionary::QPDF_Dictionary(std::map<std::string, QPDFObjectHandle> const& items) :
12 QPDFValue(::ot_dictionary), 14 QPDFValue(::ot_dictionary),