aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorm-holger <m-holger@kubitscheck.org>2022-06-16 18:45:04 +0200
committerJay Berkenbilt <jberkenbilt@users.noreply.github.com>2022-06-27 18:47:02 +0200
commitf0a8178091dfc87bbf9a6751f8fedf007e8eb144 (patch)
tree9a4b3af6d96a274016f0feecbc5deecb345c5f4f
parent5aa8225f493dc3c3171662fecc8a9ff5d0a16feb (diff)
downloadqpdf-f0a8178091dfc87bbf9a6751f8fedf007e8eb144.tar.zst
Refactor QPDFObject creation and cloning
Move responsibility for creating shared pointers to objects and cloning from QPDFObjectHandle to QPDFObject.
-rw-r--r--include/qpdf/QPDFObject.hh2
-rw-r--r--include/qpdf/QPDFObjectHandle.hh2
-rw-r--r--libqpdf/QPDF.cc2
-rw-r--r--libqpdf/QPDFObject.cc7
-rw-r--r--libqpdf/QPDFObjectHandle.cc83
-rw-r--r--libqpdf/QPDF_Array.cc24
-rw-r--r--libqpdf/QPDF_Bool.cc12
-rw-r--r--libqpdf/QPDF_Dictionary.cc12
-rw-r--r--libqpdf/QPDF_InlineImage.cc14
-rw-r--r--libqpdf/QPDF_Integer.cc12
-rw-r--r--libqpdf/QPDF_Name.cc12
-rw-r--r--libqpdf/QPDF_Null.cc12
-rw-r--r--libqpdf/QPDF_Operator.cc14
-rw-r--r--libqpdf/QPDF_Real.cc19
-rw-r--r--libqpdf/QPDF_Reserved.cc12
-rw-r--r--libqpdf/QPDF_Stream.cc19
-rw-r--r--libqpdf/QPDF_String.cc19
-rw-r--r--libqpdf/qpdf/QPDF_Array.hh8
-rw-r--r--libqpdf/qpdf/QPDF_Bool.hh4
-rw-r--r--libqpdf/qpdf/QPDF_Dictionary.hh4
-rw-r--r--libqpdf/qpdf/QPDF_InlineImage.hh4
-rw-r--r--libqpdf/qpdf/QPDF_Integer.hh4
-rw-r--r--libqpdf/qpdf/QPDF_Name.hh4
-rw-r--r--libqpdf/qpdf/QPDF_Null.hh4
-rw-r--r--libqpdf/qpdf/QPDF_Operator.hh4
-rw-r--r--libqpdf/qpdf/QPDF_Real.hh8
-rw-r--r--libqpdf/qpdf/QPDF_Reserved.hh4
-rw-r--r--libqpdf/qpdf/QPDF_Stream.hh12
-rw-r--r--libqpdf/qpdf/QPDF_String.hh8
-rw-r--r--qpdf/qpdf.testcov11
30 files changed, 261 insertions, 95 deletions
diff --git a/include/qpdf/QPDFObject.hh b/include/qpdf/QPDFObject.hh
index 982cd126..eb7c4b90 100644
--- a/include/qpdf/QPDFObject.hh
+++ b/include/qpdf/QPDFObject.hh
@@ -63,6 +63,7 @@ class QPDFObject
static constexpr object_type_e ot_inlineimage = ::ot_inlineimage;
virtual ~QPDFObject() = default;
+ virtual std::shared_ptr<QPDFObject> shallowCopy() = 0;
virtual std::string unparse() = 0;
virtual JSON getJSON(int json_version) = 0;
@@ -102,6 +103,7 @@ class QPDFObject
releaseResolved()
{
}
+ static std::shared_ptr<QPDFObject> do_create(QPDFObject*);
private:
QPDFObject(QPDFObject const&) = delete;
diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh
index 07e70531..cda257f1 100644
--- a/include/qpdf/QPDFObjectHandle.hh
+++ b/include/qpdf/QPDFObjectHandle.hh
@@ -1551,7 +1551,7 @@ class QPDFObjectHandle
private:
QPDFObjectHandle(QPDF*, int objid, int generation);
- QPDFObjectHandle(QPDFObject*);
+ QPDFObjectHandle(std::shared_ptr<QPDFObject> const&);
enum parser_state_e {
st_top,
diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc
index b51c5571..9ad33376 100644
--- a/libqpdf/QPDF.cc
+++ b/libqpdf/QPDF.cc
@@ -1989,7 +1989,7 @@ QPDF::resolve(int objid, int generation)
this->m->file->getLastOffset(),
("loop detected resolving object " + QUtil::int_to_string(objid) +
" " + QUtil::int_to_string(generation)));
- return std::shared_ptr<QPDFObject>(new QPDF_Null);
+ return QPDF_Null::create();
}
ResolveRecorder rr(this, og);
diff --git a/libqpdf/QPDFObject.cc b/libqpdf/QPDFObject.cc
index 39eb01a2..39a5fa50 100644
--- a/libqpdf/QPDFObject.cc
+++ b/libqpdf/QPDFObject.cc
@@ -6,6 +6,13 @@ QPDFObject::QPDFObject() :
{
}
+std::shared_ptr<QPDFObject>
+QPDFObject::do_create(QPDFObject* object)
+{
+ std::shared_ptr<QPDFObject> obj(object);
+ return obj;
+}
+
void
QPDFObject::setDescription(QPDF* qpdf, std::string const& description)
{
diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc
index 4ef4f4d9..d39f93be 100644
--- a/libqpdf/QPDFObjectHandle.cc
+++ b/libqpdf/QPDFObjectHandle.cc
@@ -235,7 +235,7 @@ QPDFObjectHandle::QPDFObjectHandle(QPDF* qpdf, int objid, int generation) :
{
}
-QPDFObjectHandle::QPDFObjectHandle(QPDFObject* data) :
+QPDFObjectHandle::QPDFObjectHandle(std::shared_ptr<QPDFObject> const& data) :
initialized(true),
qpdf(0),
objid(0),
@@ -2335,7 +2335,7 @@ QPDFObjectHandle::parseInternal(
if (old_state == st_array) {
// There's no newArray(SparseOHArray) since
// SparseOHArray is not part of the public API.
- object = QPDFObjectHandle(new QPDF_Array(olist));
+ object = QPDFObjectHandle(QPDF_Array::create(olist));
setObjectDescriptionFromInput(
object, context, object_description, input, offset);
// The `offset` points to the next of "[". Set the
@@ -2499,25 +2499,25 @@ QPDFObjectHandle::newIndirect(QPDF* qpdf, int objid, int generation)
QPDFObjectHandle
QPDFObjectHandle::newBool(bool value)
{
- return QPDFObjectHandle(new QPDF_Bool(value));
+ return QPDFObjectHandle(QPDF_Bool::create(value));
}
QPDFObjectHandle
QPDFObjectHandle::newNull()
{
- return QPDFObjectHandle(new QPDF_Null());
+ return QPDFObjectHandle(QPDF_Null::create());
}
QPDFObjectHandle
QPDFObjectHandle::newInteger(long long value)
{
- return QPDFObjectHandle(new QPDF_Integer(value));
+ return QPDFObjectHandle(QPDF_Integer::create(value));
}
QPDFObjectHandle
QPDFObjectHandle::newReal(std::string const& value)
{
- return QPDFObjectHandle(new QPDF_Real(value));
+ return QPDFObjectHandle(QPDF_Real::create(value));
}
QPDFObjectHandle
@@ -2525,37 +2525,37 @@ QPDFObjectHandle::newReal(
double value, int decimal_places, bool trim_trailing_zeroes)
{
return QPDFObjectHandle(
- new QPDF_Real(value, decimal_places, trim_trailing_zeroes));
+ QPDF_Real::create(value, decimal_places, trim_trailing_zeroes));
}
QPDFObjectHandle
QPDFObjectHandle::newName(std::string const& name)
{
- return QPDFObjectHandle(new QPDF_Name(name));
+ return QPDFObjectHandle(QPDF_Name::create(name));
}
QPDFObjectHandle
QPDFObjectHandle::newString(std::string const& str)
{
- return QPDFObjectHandle(new QPDF_String(str));
+ return QPDFObjectHandle(QPDF_String::create(str));
}
QPDFObjectHandle
QPDFObjectHandle::newUnicodeString(std::string const& utf8_str)
{
- return QPDFObjectHandle(QPDF_String::new_utf16(utf8_str));
+ return QPDFObjectHandle(QPDF_String::create_utf16(utf8_str));
}
QPDFObjectHandle
QPDFObjectHandle::newOperator(std::string const& value)
{
- return QPDFObjectHandle(new QPDF_Operator(value));
+ return QPDFObjectHandle(QPDF_Operator::create(value));
}
QPDFObjectHandle
QPDFObjectHandle::newInlineImage(std::string const& value)
{
- return QPDFObjectHandle(new QPDF_InlineImage(value));
+ return QPDFObjectHandle(QPDF_InlineImage::create(value));
}
QPDFObjectHandle
@@ -2567,7 +2567,7 @@ QPDFObjectHandle::newArray()
QPDFObjectHandle
QPDFObjectHandle::newArray(std::vector<QPDFObjectHandle> const& items)
{
- return QPDFObjectHandle(new QPDF_Array(items));
+ return QPDFObjectHandle(QPDF_Array::create(items));
}
QPDFObjectHandle
@@ -2635,7 +2635,7 @@ QPDFObjectHandle
QPDFObjectHandle::newDictionary(
std::map<std::string, QPDFObjectHandle> const& items)
{
- return QPDFObjectHandle(new QPDF_Dictionary(items));
+ return QPDFObjectHandle(QPDF_Dictionary::create(items));
}
QPDFObjectHandle
@@ -2647,8 +2647,8 @@ QPDFObjectHandle::newStream(
qpdf_offset_t offset,
size_t length)
{
- QPDFObjectHandle result = QPDFObjectHandle(
- new QPDF_Stream(qpdf, objid, generation, stream_dict, offset, length));
+ QPDFObjectHandle result = QPDFObjectHandle(QPDF_Stream::create(
+ qpdf, objid, generation, stream_dict, offset, length));
if (offset) {
result.setParsedOffset(offset);
}
@@ -2665,8 +2665,7 @@ QPDFObjectHandle::newStream(QPDF* qpdf)
QTC::TC("qpdf", "QPDFObjectHandle newStream");
QPDFObjectHandle stream_dict = newDictionary();
QPDFObjectHandle result = qpdf->makeIndirectObject(
- QPDFObjectHandle(new QPDF_Stream(qpdf, 0, 0, stream_dict, 0, 0)));
- // Indirect objects are guaranteed to be initialized
+ QPDFObjectHandle(QPDF_Stream::create(qpdf, 0, 0, stream_dict, 0, 0)));
result.dereference();
QPDF_Stream* stream = dynamic_cast<QPDF_Stream*>(result.obj.get());
stream->setObjGen(result.getObjectID(), result.getGeneration());
@@ -2706,7 +2705,7 @@ QPDFObjectHandle::newReserved(QPDF* qpdf)
QPDFObjectHandle
QPDFObjectHandle::makeReserved()
{
- return QPDFObjectHandle(new QPDF_Reserved());
+ return QPDFObjectHandle(QPDF_Reserved::create());
}
void
@@ -2753,17 +2752,9 @@ QPDFObjectHandle::shallowCopyInternal(
throw std::runtime_error("attempt to make a shallow copy of a stream");
}
- if (isArray()) {
- QTC::TC("qpdf", "QPDFObjectHandle shallow copy array");
- // No newArray for shallow copying the sparse array
- QPDF_Array* arr = dynamic_cast<QPDF_Array*>(obj.get());
- new_obj =
- QPDFObjectHandle(new QPDF_Array(arr->getElementsForShallowCopy()));
- } else if (isDictionary()) {
- QTC::TC("qpdf", "QPDFObjectHandle shallow copy dictionary");
- new_obj = newDictionary(getDictAsMap());
+ if (isArray() || isDictionary()) {
+ new_obj = QPDFObjectHandle(obj->shallowCopy());
} else {
- QTC::TC("qpdf", "QPDFObjectHandle shallow copy scalar");
new_obj = *this;
}
@@ -2812,27 +2803,14 @@ QPDFObjectHandle::copyObject(
std::shared_ptr<QPDFObject> new_obj;
- if (isBool()) {
- QTC::TC("qpdf", "QPDFObjectHandle clone bool");
- new_obj = std::shared_ptr<QPDFObject>(new QPDF_Bool(getBoolValue()));
- } else if (isNull()) {
- QTC::TC("qpdf", "QPDFObjectHandle clone null");
- new_obj = std::shared_ptr<QPDFObject>(new QPDF_Null());
- } else if (isInteger()) {
- QTC::TC("qpdf", "QPDFObjectHandle clone integer");
- new_obj = std::shared_ptr<QPDFObject>(new QPDF_Integer(getIntValue()));
- } else if (isReal()) {
- QTC::TC("qpdf", "QPDFObjectHandle clone real");
- new_obj = std::shared_ptr<QPDFObject>(new QPDF_Real(getRealValue()));
- } else if (isName()) {
- QTC::TC("qpdf", "QPDFObjectHandle clone name");
- new_obj = std::shared_ptr<QPDFObject>(new QPDF_Name(getName()));
- } else if (isString()) {
- QTC::TC("qpdf", "QPDFObjectHandle clone string");
- new_obj =
- std::shared_ptr<QPDFObject>(new QPDF_String(getStringValue()));
+ if (isBool() ||
+ isInteger() ||
+ isName() ||
+ isNull() ||
+ isReal() ||
+ isString()) {
+ new_obj = obj->shallowCopy();
} else if (isArray()) {
- QTC::TC("qpdf", "QPDFObjectHandle clone array");
std::vector<QPDFObjectHandle> items;
int n = getArrayNItems();
for (int i = 0; i < n; ++i) {
@@ -2843,9 +2821,8 @@ QPDFObjectHandle::copyObject(
visited, cross_indirect, first_level_only, stop_at_streams);
}
}
- new_obj = std::shared_ptr<QPDFObject>(new QPDF_Array(items));
+ new_obj = QPDF_Array::create(items);
} else if (isDictionary()) {
- QTC::TC("qpdf", "QPDFObjectHandle clone dictionary");
std::map<std::string, QPDFObjectHandle> items;
for (auto const& key: getKeys()) {
items[key] = getKey(key);
@@ -2855,7 +2832,7 @@ QPDFObjectHandle::copyObject(
visited, cross_indirect, first_level_only, stop_at_streams);
}
}
- new_obj = std::shared_ptr<QPDFObject>(new QPDF_Dictionary(items));
+ new_obj = QPDF_Dictionary::create(items);
} else {
throw std::logic_error("QPDFObjectHandle::makeDirectInternal: "
"unknown object type");
@@ -3144,7 +3121,7 @@ QPDFObjectHandle::dereference()
if (obj.get() == 0) {
// QPDF::resolve never returns an uninitialized object, but
// check just in case.
- this->obj = std::shared_ptr<QPDFObject>(new QPDF_Null());
+ this->obj = QPDF_Null::create();
} else if (dynamic_cast<QPDF_Reserved*>(obj.get())) {
// Do not resolve
this->reserved = true;
diff --git a/libqpdf/QPDF_Array.cc b/libqpdf/QPDF_Array.cc
index fd046ec7..55e4d20a 100644
--- a/libqpdf/QPDF_Array.cc
+++ b/libqpdf/QPDF_Array.cc
@@ -14,6 +14,24 @@ QPDF_Array::QPDF_Array(SparseOHArray const& items) :
{
}
+std::shared_ptr<QPDFObject>
+QPDF_Array::create(std::vector<QPDFObjectHandle> const& items)
+{
+ return do_create(new QPDF_Array(items));
+}
+
+std::shared_ptr<QPDFObject>
+QPDF_Array::create(SparseOHArray const& items)
+{
+ return do_create(new QPDF_Array(items));
+}
+
+std::shared_ptr<QPDFObject>
+QPDF_Array::shallowCopy()
+{
+ return create(elements);
+}
+
void
QPDF_Array::releaseResolved()
{
@@ -121,12 +139,6 @@ QPDF_Array::eraseItem(int at)
this->elements.erase(QIntC::to_size(at));
}
-SparseOHArray const&
-QPDF_Array::getElementsForShallowCopy() const
-{
- return this->elements;
-}
-
void
QPDF_Array::addExplicitElementsToList(std::list<QPDFObjectHandle>& l) const
{
diff --git a/libqpdf/QPDF_Bool.cc b/libqpdf/QPDF_Bool.cc
index 74d2ec3b..f26325c3 100644
--- a/libqpdf/QPDF_Bool.cc
+++ b/libqpdf/QPDF_Bool.cc
@@ -5,6 +5,18 @@ QPDF_Bool::QPDF_Bool(bool val) :
{
}
+std::shared_ptr<QPDFObject>
+QPDF_Bool::create(bool value)
+{
+ return do_create(new QPDF_Bool(value));
+}
+
+std::shared_ptr<QPDFObject>
+QPDF_Bool::shallowCopy()
+{
+ return create(val);
+}
+
std::string
QPDF_Bool::unparse()
{
diff --git a/libqpdf/QPDF_Dictionary.cc b/libqpdf/QPDF_Dictionary.cc
index 9453b64a..be3c5dcd 100644
--- a/libqpdf/QPDF_Dictionary.cc
+++ b/libqpdf/QPDF_Dictionary.cc
@@ -9,6 +9,18 @@ QPDF_Dictionary::QPDF_Dictionary(
{
}
+std::shared_ptr<QPDFObject>
+QPDF_Dictionary::create(std::map<std::string, QPDFObjectHandle> const& items)
+{
+ return do_create(new QPDF_Dictionary(items));
+}
+
+std::shared_ptr<QPDFObject>
+QPDF_Dictionary::shallowCopy()
+{
+ return create(items);
+}
+
void
QPDF_Dictionary::releaseResolved()
{
diff --git a/libqpdf/QPDF_InlineImage.cc b/libqpdf/QPDF_InlineImage.cc
index 84f4fa19..c3c656e0 100644
--- a/libqpdf/QPDF_InlineImage.cc
+++ b/libqpdf/QPDF_InlineImage.cc
@@ -1,12 +1,22 @@
#include <qpdf/QPDF_InlineImage.hh>
-#include <qpdf/QUtil.hh>
-
QPDF_InlineImage::QPDF_InlineImage(std::string const& val) :
val(val)
{
}
+std::shared_ptr<QPDFObject>
+QPDF_InlineImage::create(std::string const& val)
+{
+ return do_create(new QPDF_InlineImage(val));
+}
+
+std::shared_ptr<QPDFObject>
+QPDF_InlineImage::shallowCopy()
+{
+ return create(val);
+}
+
std::string
QPDF_InlineImage::unparse()
{
diff --git a/libqpdf/QPDF_Integer.cc b/libqpdf/QPDF_Integer.cc
index c42fa246..e8d23e4a 100644
--- a/libqpdf/QPDF_Integer.cc
+++ b/libqpdf/QPDF_Integer.cc
@@ -7,6 +7,18 @@ QPDF_Integer::QPDF_Integer(long long val) :
{
}
+std::shared_ptr<QPDFObject>
+QPDF_Integer::create(long long value)
+{
+ return do_create(new QPDF_Integer(value));
+}
+
+std::shared_ptr<QPDFObject>
+QPDF_Integer::shallowCopy()
+{
+ return create(val);
+}
+
std::string
QPDF_Integer::unparse()
{
diff --git a/libqpdf/QPDF_Name.cc b/libqpdf/QPDF_Name.cc
index 236d6133..73990775 100644
--- a/libqpdf/QPDF_Name.cc
+++ b/libqpdf/QPDF_Name.cc
@@ -9,6 +9,18 @@ QPDF_Name::QPDF_Name(std::string const& name) :
{
}
+std::shared_ptr<QPDFObject>
+QPDF_Name::create(std::string const& name)
+{
+ return do_create(new QPDF_Name(name));
+}
+
+std::shared_ptr<QPDFObject>
+QPDF_Name::shallowCopy()
+{
+ return create(name);
+}
+
std::string
QPDF_Name::normalizeName(std::string const& name)
{
diff --git a/libqpdf/QPDF_Null.cc b/libqpdf/QPDF_Null.cc
index 166b0302..b015ed8b 100644
--- a/libqpdf/QPDF_Null.cc
+++ b/libqpdf/QPDF_Null.cc
@@ -1,5 +1,17 @@
#include <qpdf/QPDF_Null.hh>
+std::shared_ptr<QPDFObject>
+QPDF_Null::create()
+{
+ return do_create(new QPDF_Null());
+}
+
+std::shared_ptr<QPDFObject>
+QPDF_Null::shallowCopy()
+{
+ return create();
+}
+
std::string
QPDF_Null::unparse()
{
diff --git a/libqpdf/QPDF_Operator.cc b/libqpdf/QPDF_Operator.cc
index f7da813a..cd5009ae 100644
--- a/libqpdf/QPDF_Operator.cc
+++ b/libqpdf/QPDF_Operator.cc
@@ -1,12 +1,22 @@
#include <qpdf/QPDF_Operator.hh>
-#include <qpdf/QUtil.hh>
-
QPDF_Operator::QPDF_Operator(std::string const& val) :
val(val)
{
}
+std::shared_ptr<QPDFObject>
+QPDF_Operator::create(std::string const& val)
+{
+ return do_create(new QPDF_Operator(val));
+}
+
+std::shared_ptr<QPDFObject>
+QPDF_Operator::shallowCopy()
+{
+ return create(val);
+}
+
std::string
QPDF_Operator::unparse()
{
diff --git a/libqpdf/QPDF_Real.cc b/libqpdf/QPDF_Real.cc
index 4b32b035..138bbb3c 100644
--- a/libqpdf/QPDF_Real.cc
+++ b/libqpdf/QPDF_Real.cc
@@ -13,6 +13,25 @@ QPDF_Real::QPDF_Real(
{
}
+std::shared_ptr<QPDFObject>
+QPDF_Real::create(std::string const& val)
+{
+ return do_create(new QPDF_Real(val));
+}
+
+std::shared_ptr<QPDFObject>
+QPDF_Real::create(double value, int decimal_places, bool trim_trailing_zeroes)
+{
+ return do_create(
+ new QPDF_Real(value, decimal_places, trim_trailing_zeroes));
+}
+
+std::shared_ptr<QPDFObject>
+QPDF_Real::shallowCopy()
+{
+ return create(val);
+}
+
std::string
QPDF_Real::unparse()
{
diff --git a/libqpdf/QPDF_Reserved.cc b/libqpdf/QPDF_Reserved.cc
index 775dee02..5808a369 100644
--- a/libqpdf/QPDF_Reserved.cc
+++ b/libqpdf/QPDF_Reserved.cc
@@ -2,6 +2,18 @@
#include <stdexcept>
+std::shared_ptr<QPDFObject>
+QPDF_Reserved::create()
+{
+ return do_create(new QPDF_Reserved());
+}
+
+std::shared_ptr<QPDFObject>
+QPDF_Reserved::shallowCopy()
+{
+ return create();
+}
+
std::string
QPDF_Reserved::unparse()
{
diff --git a/libqpdf/QPDF_Stream.cc b/libqpdf/QPDF_Stream.cc
index edb4a739..c4c69659 100644
--- a/libqpdf/QPDF_Stream.cc
+++ b/libqpdf/QPDF_Stream.cc
@@ -134,6 +134,25 @@ QPDF_Stream::QPDF_Stream(
QUtil::int_to_string(this->generation));
}
+std::shared_ptr<QPDFObject>
+QPDF_Stream::create(
+ QPDF* qpdf,
+ int objid,
+ int generation,
+ QPDFObjectHandle stream_dict,
+ qpdf_offset_t offset,
+ size_t length)
+{
+ return do_create(
+ new QPDF_Stream(qpdf, objid, generation, stream_dict, offset,length));
+}
+
+std::shared_ptr<QPDFObject>
+QPDF_Stream::shallowCopy()
+{
+ throw std::logic_error("stream objects cannot be cloned");
+}
+
void
QPDF_Stream::registerStreamFilter(
std::string const& filter_name,
diff --git a/libqpdf/QPDF_String.cc b/libqpdf/QPDF_String.cc
index 4d45d851..b038366b 100644
--- a/libqpdf/QPDF_String.cc
+++ b/libqpdf/QPDF_String.cc
@@ -1,6 +1,5 @@
#include <qpdf/QPDF_String.hh>
-#include <qpdf/QTC.hh>
#include <qpdf/QUtil.hh>
// DO NOT USE ctype -- it is locale dependent for some things, and
@@ -26,14 +25,26 @@ QPDF_String::QPDF_String(std::string const& val) :
{
}
-QPDF_String*
-QPDF_String::new_utf16(std::string const& utf8_val)
+std::shared_ptr<QPDFObject>
+QPDF_String::create(std::string const& val)
+{
+ return do_create(new QPDF_String(val));
+}
+
+std::shared_ptr<QPDFObject>
+QPDF_String::create_utf16(std::string const& utf8_val)
{
std::string result;
if (!QUtil::utf8_to_pdf_doc(utf8_val, result, '?')) {
result = QUtil::utf8_to_utf16(utf8_val);
}
- return new QPDF_String(result);
+ return do_create(new QPDF_String(result));
+}
+
+std::shared_ptr<QPDFObject>
+QPDF_String::shallowCopy()
+{
+ return create(val);
}
std::string
diff --git a/libqpdf/qpdf/QPDF_Array.hh b/libqpdf/qpdf/QPDF_Array.hh
index ac5d98be..e718c6e0 100644
--- a/libqpdf/qpdf/QPDF_Array.hh
+++ b/libqpdf/qpdf/QPDF_Array.hh
@@ -10,9 +10,10 @@
class QPDF_Array: public QPDFObject
{
public:
- QPDF_Array(std::vector<QPDFObjectHandle> const& items);
- QPDF_Array(SparseOHArray const& items);
virtual ~QPDF_Array() = default;
+ static std::shared_ptr<QPDFObject> create(std::vector<QPDFObjectHandle> const& items);
+ static std::shared_ptr<QPDFObject> create(SparseOHArray const& items);
+ virtual std::shared_ptr<QPDFObject> shallowCopy();
virtual std::string unparse();
virtual JSON getJSON(int json_version);
virtual QPDFObject::object_type_e getTypeCode() const;
@@ -31,13 +32,14 @@ class QPDF_Array: public QPDFObject
// Helper methods for QPDF and QPDFObjectHandle -- these are
// public methods since the whole class is not part of the public
// API. Otherwise, these would be wrapped in accessor classes.
- SparseOHArray const& getElementsForShallowCopy() const;
void addExplicitElementsToList(std::list<QPDFObjectHandle>&) const;
protected:
virtual void releaseResolved();
private:
+ QPDF_Array(std::vector<QPDFObjectHandle> const& items);
+ QPDF_Array(SparseOHArray const& items);
SparseOHArray elements;
};
diff --git a/libqpdf/qpdf/QPDF_Bool.hh b/libqpdf/qpdf/QPDF_Bool.hh
index 576b1505..dbedc70a 100644
--- a/libqpdf/qpdf/QPDF_Bool.hh
+++ b/libqpdf/qpdf/QPDF_Bool.hh
@@ -6,8 +6,9 @@
class QPDF_Bool: public QPDFObject
{
public:
- QPDF_Bool(bool val);
virtual ~QPDF_Bool() = default;
+ static std::shared_ptr<QPDFObject> create(bool val);
+ virtual std::shared_ptr<QPDFObject> shallowCopy();
virtual std::string unparse();
virtual JSON getJSON(int json_version);
virtual QPDFObject::object_type_e getTypeCode() const;
@@ -15,6 +16,7 @@ class QPDF_Bool: public QPDFObject
bool getVal() const;
private:
+ QPDF_Bool(bool val);
bool val;
};
diff --git a/libqpdf/qpdf/QPDF_Dictionary.hh b/libqpdf/qpdf/QPDF_Dictionary.hh
index be1c8733..3cd00c1e 100644
--- a/libqpdf/qpdf/QPDF_Dictionary.hh
+++ b/libqpdf/qpdf/QPDF_Dictionary.hh
@@ -11,8 +11,9 @@
class QPDF_Dictionary: public QPDFObject
{
public:
- QPDF_Dictionary(std::map<std::string, QPDFObjectHandle> const& items);
virtual ~QPDF_Dictionary() = default;
+ static std::shared_ptr<QPDFObject> create(std::map<std::string, QPDFObjectHandle> const& items);
+ virtual std::shared_ptr<QPDFObject> shallowCopy();
virtual std::string unparse();
virtual JSON getJSON(int json_version);
virtual QPDFObject::object_type_e getTypeCode() const;
@@ -36,6 +37,7 @@ class QPDF_Dictionary: public QPDFObject
virtual void releaseResolved();
private:
+ QPDF_Dictionary(std::map<std::string, QPDFObjectHandle> const& items);
std::map<std::string, QPDFObjectHandle> items;
};
diff --git a/libqpdf/qpdf/QPDF_InlineImage.hh b/libqpdf/qpdf/QPDF_InlineImage.hh
index 32b25093..caaeaf87 100644
--- a/libqpdf/qpdf/QPDF_InlineImage.hh
+++ b/libqpdf/qpdf/QPDF_InlineImage.hh
@@ -6,8 +6,9 @@
class QPDF_InlineImage: public QPDFObject
{
public:
- QPDF_InlineImage(std::string const& val);
virtual ~QPDF_InlineImage() = default;
+ static std::shared_ptr<QPDFObject> create(std::string const& val);
+ virtual std::shared_ptr<QPDFObject> shallowCopy();
virtual std::string unparse();
virtual JSON getJSON(int json_version);
virtual QPDFObject::object_type_e getTypeCode() const;
@@ -15,6 +16,7 @@ class QPDF_InlineImage: public QPDFObject
std::string getVal() const;
private:
+ QPDF_InlineImage(std::string const& val);
std::string val;
};
diff --git a/libqpdf/qpdf/QPDF_Integer.hh b/libqpdf/qpdf/QPDF_Integer.hh
index 36001a14..2c17daf0 100644
--- a/libqpdf/qpdf/QPDF_Integer.hh
+++ b/libqpdf/qpdf/QPDF_Integer.hh
@@ -6,8 +6,9 @@
class QPDF_Integer: public QPDFObject
{
public:
- QPDF_Integer(long long val);
virtual ~QPDF_Integer() = default;
+ static std::shared_ptr<QPDFObject> create(long long value);
+ virtual std::shared_ptr<QPDFObject> shallowCopy();
virtual std::string unparse();
virtual JSON getJSON(int json_version);
virtual QPDFObject::object_type_e getTypeCode() const;
@@ -15,6 +16,7 @@ class QPDF_Integer: public QPDFObject
long long getVal() const;
private:
+ QPDF_Integer(long long val);
long long val;
};
diff --git a/libqpdf/qpdf/QPDF_Name.hh b/libqpdf/qpdf/QPDF_Name.hh
index 5ee65d02..cf653b2e 100644
--- a/libqpdf/qpdf/QPDF_Name.hh
+++ b/libqpdf/qpdf/QPDF_Name.hh
@@ -6,8 +6,9 @@
class QPDF_Name: public QPDFObject
{
public:
- QPDF_Name(std::string const& name);
virtual ~QPDF_Name() = default;
+ static std::shared_ptr<QPDFObject> create(std::string const& name);
+ virtual std::shared_ptr<QPDFObject> shallowCopy();
virtual std::string unparse();
virtual JSON getJSON(int json_version);
virtual QPDFObject::object_type_e getTypeCode() const;
@@ -18,6 +19,7 @@ class QPDF_Name: public QPDFObject
static std::string normalizeName(std::string const& name);
private:
+ QPDF_Name(std::string const& name);
std::string name;
};
diff --git a/libqpdf/qpdf/QPDF_Null.hh b/libqpdf/qpdf/QPDF_Null.hh
index 9d2d6223..8051e238 100644
--- a/libqpdf/qpdf/QPDF_Null.hh
+++ b/libqpdf/qpdf/QPDF_Null.hh
@@ -7,10 +7,14 @@ class QPDF_Null: public QPDFObject
{
public:
virtual ~QPDF_Null() = default;
+ static std::shared_ptr<QPDFObject> create();
+ virtual std::shared_ptr<QPDFObject> shallowCopy();
virtual std::string unparse();
virtual JSON getJSON(int json_version);
virtual QPDFObject::object_type_e getTypeCode() const;
virtual char const* getTypeName() const;
+ private:
+ QPDF_Null() = default;
};
#endif // QPDF_NULL_HH
diff --git a/libqpdf/qpdf/QPDF_Operator.hh b/libqpdf/qpdf/QPDF_Operator.hh
index 672da728..1da43d72 100644
--- a/libqpdf/qpdf/QPDF_Operator.hh
+++ b/libqpdf/qpdf/QPDF_Operator.hh
@@ -6,8 +6,9 @@
class QPDF_Operator: public QPDFObject
{
public:
- QPDF_Operator(std::string const& val);
virtual ~QPDF_Operator() = default;
+ static std::shared_ptr<QPDFObject> create(std::string const& val);
+ virtual std::shared_ptr<QPDFObject> shallowCopy();
virtual std::string unparse();
virtual JSON getJSON(int json_version);
virtual QPDFObject::object_type_e getTypeCode() const;
@@ -15,6 +16,7 @@ class QPDF_Operator: public QPDFObject
std::string getVal() const;
private:
+ QPDF_Operator(std::string const& val);
std::string val;
};
diff --git a/libqpdf/qpdf/QPDF_Real.hh b/libqpdf/qpdf/QPDF_Real.hh
index 1b9878c7..bf61091c 100644
--- a/libqpdf/qpdf/QPDF_Real.hh
+++ b/libqpdf/qpdf/QPDF_Real.hh
@@ -6,9 +6,11 @@
class QPDF_Real: public QPDFObject
{
public:
- QPDF_Real(std::string const& val);
- QPDF_Real(double value, int decimal_places, bool trim_trailing_zeroes);
virtual ~QPDF_Real() = default;
+ static std::shared_ptr<QPDFObject> create(std::string const& val);
+ static std::shared_ptr<QPDFObject> create(
+ double value, int decimal_places, bool trim_trailing_zeroes);
+ virtual std::shared_ptr<QPDFObject> shallowCopy();
virtual std::string unparse();
virtual JSON getJSON(int json_version);
virtual QPDFObject::object_type_e getTypeCode() const;
@@ -16,6 +18,8 @@ class QPDF_Real: public QPDFObject
std::string getVal();
private:
+ QPDF_Real(std::string const& val);
+ QPDF_Real(double value, int decimal_places, bool trim_trailing_zeroes);
// Store reals as strings to avoid roundoff errors.
std::string val;
};
diff --git a/libqpdf/qpdf/QPDF_Reserved.hh b/libqpdf/qpdf/QPDF_Reserved.hh
index a198f645..1a40447d 100644
--- a/libqpdf/qpdf/QPDF_Reserved.hh
+++ b/libqpdf/qpdf/QPDF_Reserved.hh
@@ -7,10 +7,14 @@ class QPDF_Reserved: public QPDFObject
{
public:
virtual ~QPDF_Reserved() = default;
+ static std::shared_ptr<QPDFObject> create();
+ virtual std::shared_ptr<QPDFObject> shallowCopy();
virtual std::string unparse();
virtual JSON getJSON(int json_version);
virtual QPDFObject::object_type_e getTypeCode() const;
virtual char const* getTypeName() const;
+ private:
+ QPDF_Reserved() = default;
};
#endif // QPDF_RESERVED_HH
diff --git a/libqpdf/qpdf/QPDF_Stream.hh b/libqpdf/qpdf/QPDF_Stream.hh
index 4aaee0a2..3b7cf358 100644
--- a/libqpdf/qpdf/QPDF_Stream.hh
+++ b/libqpdf/qpdf/QPDF_Stream.hh
@@ -16,14 +16,15 @@ class QPDF;
class QPDF_Stream: public QPDFObject
{
public:
- QPDF_Stream(
+ virtual ~QPDF_Stream() = default;
+ static std::shared_ptr<QPDFObject> create(
QPDF*,
int objid,
int generation,
QPDFObjectHandle stream_dict,
qpdf_offset_t offset,
size_t length);
- virtual ~QPDF_Stream() = default;
+ virtual std::shared_ptr<QPDFObject> shallowCopy();
virtual std::string unparse();
virtual JSON getJSON(int json_version);
virtual QPDFObject::object_type_e getTypeCode() const;
@@ -83,6 +84,13 @@ class QPDF_Stream: public QPDFObject
virtual void releaseResolved();
private:
+ QPDF_Stream(
+ QPDF*,
+ int objid,
+ int generation,
+ QPDFObjectHandle stream_dict,
+ qpdf_offset_t offset,
+ size_t length);
static std::map<std::string, std::string> filter_abbreviations;
static std::
map<std::string, std::function<std::shared_ptr<QPDFStreamFilter>()>>
diff --git a/libqpdf/qpdf/QPDF_String.hh b/libqpdf/qpdf/QPDF_String.hh
index 6fd1b0e9..fc11d3ba 100644
--- a/libqpdf/qpdf/QPDF_String.hh
+++ b/libqpdf/qpdf/QPDF_String.hh
@@ -7,10 +7,13 @@
class QPDF_String: public QPDFObject
{
+ friend class QPDFWriter;
+
public:
- QPDF_String(std::string const& val);
- static QPDF_String* new_utf16(std::string const& utf8_val);
virtual ~QPDF_String() = default;
+ static std::shared_ptr<QPDFObject> create(std::string const& val);
+ static std::shared_ptr<QPDFObject> create_utf16(std::string const& utf8_val);
+ virtual std::shared_ptr<QPDFObject> shallowCopy();
virtual std::string unparse();
virtual QPDFObject::object_type_e getTypeCode() const;
virtual char const* getTypeName() const;
@@ -20,6 +23,7 @@ class QPDF_String: public QPDFObject
std::string getUTF8Val() const;
private:
+ QPDF_String(std::string const& val);
bool useHexString() const;
std::string val;
};
diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov
index 93c658bb..bc4c2128 100644
--- a/qpdf/qpdf.testcov
+++ b/qpdf/qpdf.testcov
@@ -70,14 +70,6 @@ QPDFTokenizer null in name 0
QPDFTokenizer bad name 0
QPDF_Stream invalid filter 0
QPDF UseOutlines but no Outlines 0
-QPDFObjectHandle clone bool 0
-QPDFObjectHandle clone null 0
-QPDFObjectHandle clone integer 0
-QPDFObjectHandle clone real 0
-QPDFObjectHandle clone name 0
-QPDFObjectHandle clone string 0
-QPDFObjectHandle clone array 0
-QPDFObjectHandle clone dictionary 0
QPDFObjectHandle makeDirect loop 0
QPDFObjectHandle copy stream 1
QPDF default for xref stream field 0 0
@@ -199,9 +191,6 @@ QPDF updateAllPagesCache 0
QPDF insert non-indirect page 0
QPDF insert indirect page 0
QPDFObjectHandle ERR shallow copy stream 0
-QPDFObjectHandle shallow copy array 0
-QPDFObjectHandle shallow copy dictionary 0
-QPDFObjectHandle shallow copy scalar 0
QPDFObjectHandle newStream with string 0
QPDF unknown key not inherited 0
QPDF_Stream provider length not provided 0