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 37 #include <qpdf/Buffer.hh>
38 38 #include <qpdf/InputSource.hh>
39 39 #include <qpdf/JSON.hh>
  40 +#include <qpdf/ObjectHandle.hh>
40 41 #include <qpdf/QPDFObjGen.hh>
41 42 #include <qpdf/QPDFTokenizer.hh>
42 43  
... ... @@ -55,13 +56,14 @@ class QPDF_Reserved;
55 56 class QPDF_Stream;
56 57 class QPDF_String;
57 58 class QPDFObject;
  59 +class QPDFObjectHandle;
58 60 class QPDFTokenizer;
59 61 class QPDFExc;
60 62 class Pl_QPDFTokenizer;
61 63 class QPDFMatrix;
62 64 class QPDFParser;
63 65  
64   -class QPDFObjectHandle
  66 +class QPDFObjectHandle final: public qpdf::BaseHandle
65 67 {
66 68 friend class QPDFParser;
67 69  
... ... @@ -290,18 +292,12 @@ class QPDFObjectHandle
290 292 QPDFObjectHandle(QPDFObjectHandle const&) = default;
291 293 QPDF_DLL
292 294 QPDFObjectHandle& operator=(QPDFObjectHandle const&) = default;
293   -
294 295 QPDF_DLL
295 296 QPDFObjectHandle(QPDFObjectHandle&&) = default;
296 297 QPDF_DLL
297 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 302 // This method returns true if the QPDFObjectHandle objects point to exactly the same underlying
307 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 1325 // The following methods do not form part of the public API and are for internal use only.
1330 1326  
1331 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 1335 std::shared_ptr<QPDFObject>
... ... @@ -1386,10 +1386,6 @@ class QPDFObjectHandle
1386 1386 arrayOrStreamToStreamArray(std::string const& description, std::string& all_description);
1387 1387 static void warn(QPDF*, QPDFExc const&);
1388 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 1391 #ifndef QPDF_NO_QPDF_STRING
... ... @@ -1606,6 +1602,22 @@ class QPDFObjectHandle::QPDFArrayItems
1606 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 1621 inline int
1610 1622 QPDFObjectHandle::getObjectID() const
1611 1623 {
... ... @@ -1625,15 +1637,9 @@ QPDFObjectHandle::isIndirect() const
1625 1637 }
1626 1638  
1627 1639 inline bool
1628   -QPDFObjectHandle::isInitialized() const noexcept
  1640 +QPDFObjectHandle::isInitialized() const
1629 1641 {
1630 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 1645 #endif // QPDFOBJECTHANDLE_HH
... ...
libqpdf/QPDFObjectHandle.cc
... ... @@ -39,6 +39,14 @@
39 39  
40 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 50 namespace
43 51 {
44 52 class TerminateParsing
... ...
libqpdf/QPDF_Dictionary.cc
1 1 #include <qpdf/QPDF_Dictionary.hh>
2 2  
3 3 #include <qpdf/JSON_writer.hh>
  4 +#include <qpdf/QPDFObjectHandle.hh>
4 5 #include <qpdf/QPDFObject_private.hh>
5 6 #include <qpdf/QPDF_Name.hh>
6 7 #include <qpdf/QPDF_Null.hh>
7 8 #include <qpdf/QUtil.hh>
8 9  
9 10 using namespace std::literals;
  11 +using namespace qpdf;
10 12  
11 13 QPDF_Dictionary::QPDF_Dictionary(std::map<std::string, QPDFObjectHandle> const& items) :
12 14 QPDFValue(::ot_dictionary),
... ...