Refactor QPDFObjectHandle::copyObject1

This commit is contained in:
m-holger 2022-11-14 22:06:04 +00:00 committed by Jay Berkenbilt
parent 3e3b79a774
commit b1eb1a9584
8 changed files with 38 additions and 32 deletions

View File

@ -2211,8 +2211,7 @@ QPDFObjectHandle::shallowCopyInternal1(QPDFObjectHandle& new_obj)
assertInitialized();
if (isStream()) {
QTC::TC("qpdf", "QPDFObjectHandle ERR shallow copy stream");
throw std::runtime_error("attempt to make a shallow copy of a stream");
// Handled bt QPDF_Stream::copy()
}
new_obj = QPDFObjectHandle(obj->copy(true));
@ -2225,9 +2224,10 @@ QPDFObjectHandle::copyObject1(std::set<QPDFObjGen>& visited)
{
assertInitialized();
std::shared_ptr<QPDFObject> new_obj;
if (isStream()) {
throw std::runtime_error(
"attempt to make a stream into a direct object");
new_obj = obj->copy();
}
auto cur_og = getObjGen();
@ -2241,36 +2241,17 @@ QPDFObjectHandle::copyObject1(std::set<QPDFObjGen>& visited)
}
if (isReserved()) {
throw std::logic_error("QPDFObjectHandle: attempting to make a"
" reserved object handle direct");
new_obj = obj->copy();
}
std::shared_ptr<QPDFObject> new_obj;
if (isBool() || isInteger() || isName() || isNull() || isReal() ||
isString()) {
new_obj = obj->copy(true);
// copy(true) and copy(false) are the same
new_obj = obj->copy();
} else if (isArray()) {
std::vector<QPDFObjectHandle> items;
auto array = asArray();
int n = array->getNItems();
for (int i = 0; i < n; ++i) {
items.push_back(array->getItem(i));
if (!items.back().isIndirect()) {
items.back().copyObject1(visited);
}
}
new_obj = QPDF_Array::create(items);
new_obj = obj->copy();
} else if (isDictionary()) {
std::map<std::string, QPDFObjectHandle> items;
auto dict = asDictionary();
for (auto const& key: getKeys()) {
items[key] = dict->getKey(key);
if (!items[key].isIndirect()) {
items[key].copyObject1(visited);
}
}
new_obj = QPDF_Dictionary::create(items);
new_obj = obj->copy();
} else {
throw std::logic_error("QPDFObjectHandle::makeDirectInternal: "
"unknown object type");

View File

@ -31,7 +31,7 @@ QPDF_Array::create(SparseOHArray const& items)
std::shared_ptr<QPDFObject>
QPDF_Array::copy(bool shallow)
{
return create(elements);
return create(shallow ? elements : elements.copy());
}
void

View File

@ -18,7 +18,17 @@ QPDF_Dictionary::create(std::map<std::string, QPDFObjectHandle> const& items)
std::shared_ptr<QPDFObject>
QPDF_Dictionary::copy(bool shallow)
{
return create(items);
if (shallow) {
return create(items);
} else {
std::map<std::string, QPDFObjectHandle> new_items;
for (auto const& item: this->items) {
auto value = item.second;
new_items[item.first] =
value.isIndirect() ? value : value.shallowCopy();
}
return create(new_items);
}
}
void

View File

@ -142,6 +142,7 @@ QPDF_Stream::create(
std::shared_ptr<QPDFObject>
QPDF_Stream::copy(bool shallow)
{
QTC::TC("qpdf", "QPDF_Stream ERR shallow copy stream");
throw std::runtime_error("stream objects cannot be cloned");
}

View File

@ -110,6 +110,19 @@ SparseOHArray::insert(size_t idx, QPDFObjectHandle oh)
}
}
SparseOHArray
SparseOHArray::copy()
{
SparseOHArray result;
result.n_elements = this->n_elements;
for (auto const& element: this->elements) {
auto value = element.second;
result.elements[element.first] =
value.isIndirect() ? value : value.shallowCopy();
}
return result;
}
SparseOHArray::const_iterator
SparseOHArray::begin() const
{

View File

@ -15,6 +15,7 @@ class SparseOHArray
void setAt(size_t idx, QPDFObjectHandle oh);
void erase(size_t idx);
void insert(size_t idx, QPDFObjectHandle oh);
SparseOHArray copy();
void disconnect();
typedef std::unordered_map<size_t, QPDFObjectHandle>::const_iterator

View File

@ -192,7 +192,7 @@ QPDF insert page 2
QPDF updateAllPagesCache 0
QPDF insert non-indirect page 0
QPDF insert indirect page 0
QPDFObjectHandle ERR shallow copy stream 0
QPDF_Stream ERR shallow copy stream 0
QPDFObjectHandle newStream with string 0
QPDF unknown key not inherited 0
QPDF_Stream provider length not provided 0

View File

@ -1 +1 @@
attempt to make a shallow copy of a stream
stream objects cannot be cloned