Commit 949f2219ac99d6c37212fdb5ee27f5568d3416e4
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.
Showing
4 changed files
with
100 additions
and
20 deletions
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), |