mirror of
https://github.com/qpdf/qpdf.git
synced 2025-01-03 07:12:28 +00:00
Add QPDFObjectHandle::unsafeShallowCopy
This commit is contained in:
parent
07afb668b1
commit
38afdcea7b
@ -1,5 +1,9 @@
|
|||||||
2020-04-02 Jay Berkenbilt <ejb@ql.org>
|
2020-04-02 Jay Berkenbilt <ejb@ql.org>
|
||||||
|
|
||||||
|
* Add method QPDFObjectHandle::unsafeShallowCopy for copying only
|
||||||
|
top-level dictionary keys or array items. See comments in
|
||||||
|
QPDFObjectHandle.hh for when this should be used.
|
||||||
|
|
||||||
* Remove Members class indirection for QPDFObjectHandle. Those are
|
* Remove Members class indirection for QPDFObjectHandle. Those are
|
||||||
copied and assigned too often, and that change caused a very
|
copied and assigned too often, and that change caused a very
|
||||||
substantial performance hit.
|
substantial performance hit.
|
||||||
|
@ -670,10 +670,24 @@ class QPDFObjectHandle
|
|||||||
// traverse across indirect object boundaries. That means that,
|
// traverse across indirect object boundaries. That means that,
|
||||||
// for dictionaries and arrays, any keys or items that were
|
// for dictionaries and arrays, any keys or items that were
|
||||||
// indirect objects will still be indirect objects that point to
|
// indirect objects will still be indirect objects that point to
|
||||||
// the same place.
|
// the same place. In the strictest sense, this is not a shallow
|
||||||
|
// copy because it recursively descends arrays and dictionaries;
|
||||||
|
// it just doesn't cross over indirect objects. See also
|
||||||
|
// unsafeShallowCopy().
|
||||||
QPDF_DLL
|
QPDF_DLL
|
||||||
QPDFObjectHandle shallowCopy();
|
QPDFObjectHandle shallowCopy();
|
||||||
|
|
||||||
|
// Create a true shallow copy of an array or dictionary, just
|
||||||
|
// copying the immediate items (array) or keys (dictionary). This
|
||||||
|
// is "unsafe" because, if you *modify* any of the items in the
|
||||||
|
// copy, you are modifying the original, which is almost never
|
||||||
|
// what you want. However, if your intention is merely to
|
||||||
|
// *replace* top-level items or keys and not to modify lower-level
|
||||||
|
// items in the copy, this method is much faster than
|
||||||
|
// shallowCopy().
|
||||||
|
QPDF_DLL
|
||||||
|
QPDFObjectHandle unsafeShallowCopy();
|
||||||
|
|
||||||
// Mutator methods. Use with caution.
|
// Mutator methods. Use with caution.
|
||||||
|
|
||||||
// Recursively copy this object, making it direct. Throws an
|
// Recursively copy this object, making it direct. Throws an
|
||||||
@ -1053,7 +1067,9 @@ class QPDFObjectHandle
|
|||||||
void objectWarning(std::string const& warning);
|
void objectWarning(std::string const& warning);
|
||||||
void assertType(char const* type_name, bool istype);
|
void assertType(char const* type_name, bool istype);
|
||||||
void dereference();
|
void dereference();
|
||||||
void copyObject(std::set<QPDFObjGen>& visited, bool cross_indirect);
|
void copyObject(std::set<QPDFObjGen>& visited, bool cross_indirect,
|
||||||
|
bool first_level_only);
|
||||||
|
void shallowCopyInternal(QPDFObjectHandle& oh, bool first_level_only);
|
||||||
void releaseResolved();
|
void releaseResolved();
|
||||||
static void setObjectDescriptionFromInput(
|
static void setObjectDescriptionFromInput(
|
||||||
QPDFObjectHandle, QPDF*, std::string const&,
|
QPDFObjectHandle, QPDF*, std::string const&,
|
||||||
|
@ -2460,6 +2460,23 @@ QPDFObjectHandle::hasObjectDescription()
|
|||||||
|
|
||||||
QPDFObjectHandle
|
QPDFObjectHandle
|
||||||
QPDFObjectHandle::shallowCopy()
|
QPDFObjectHandle::shallowCopy()
|
||||||
|
{
|
||||||
|
QPDFObjectHandle result;
|
||||||
|
shallowCopyInternal(result, false);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPDFObjectHandle
|
||||||
|
QPDFObjectHandle::unsafeShallowCopy()
|
||||||
|
{
|
||||||
|
QPDFObjectHandle result;
|
||||||
|
shallowCopyInternal(result, true);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QPDFObjectHandle::shallowCopyInternal(QPDFObjectHandle& new_obj,
|
||||||
|
bool first_level_only)
|
||||||
{
|
{
|
||||||
assertInitialized();
|
assertInitialized();
|
||||||
|
|
||||||
@ -2470,7 +2487,6 @@ QPDFObjectHandle::shallowCopy()
|
|||||||
"attempt to make a shallow copy of a stream");
|
"attempt to make a shallow copy of a stream");
|
||||||
}
|
}
|
||||||
|
|
||||||
QPDFObjectHandle new_obj;
|
|
||||||
if (isArray())
|
if (isArray())
|
||||||
{
|
{
|
||||||
QTC::TC("qpdf", "QPDFObjectHandle shallow copy array");
|
QTC::TC("qpdf", "QPDFObjectHandle shallow copy array");
|
||||||
@ -2491,13 +2507,12 @@ QPDFObjectHandle::shallowCopy()
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::set<QPDFObjGen> visited;
|
std::set<QPDFObjGen> visited;
|
||||||
new_obj.copyObject(visited, false);
|
new_obj.copyObject(visited, false, first_level_only);
|
||||||
return new_obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
QPDFObjectHandle::copyObject(std::set<QPDFObjGen>& visited,
|
QPDFObjectHandle::copyObject(std::set<QPDFObjGen>& visited,
|
||||||
bool cross_indirect)
|
bool cross_indirect, bool first_level_only)
|
||||||
{
|
{
|
||||||
assertInitialized();
|
assertInitialized();
|
||||||
|
|
||||||
@ -2573,9 +2588,11 @@ QPDFObjectHandle::copyObject(std::set<QPDFObjGen>& visited,
|
|||||||
for (int i = 0; i < n; ++i)
|
for (int i = 0; i < n; ++i)
|
||||||
{
|
{
|
||||||
items.push_back(getArrayItem(i));
|
items.push_back(getArrayItem(i));
|
||||||
if (cross_indirect || (! items.back().isIndirect()))
|
if ((! first_level_only) &&
|
||||||
|
(cross_indirect || (! items.back().isIndirect())))
|
||||||
{
|
{
|
||||||
items.back().copyObject(visited, cross_indirect);
|
items.back().copyObject(
|
||||||
|
visited, cross_indirect, first_level_only);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
new_obj = new QPDF_Array(items);
|
new_obj = new QPDF_Array(items);
|
||||||
@ -2589,9 +2606,11 @@ QPDFObjectHandle::copyObject(std::set<QPDFObjGen>& visited,
|
|||||||
iter != keys.end(); ++iter)
|
iter != keys.end(); ++iter)
|
||||||
{
|
{
|
||||||
items[*iter] = getKey(*iter);
|
items[*iter] = getKey(*iter);
|
||||||
if (cross_indirect || (! items[*iter].isIndirect()))
|
if ((! first_level_only) &&
|
||||||
|
(cross_indirect || (! items[*iter].isIndirect())))
|
||||||
{
|
{
|
||||||
items[*iter].copyObject(visited, cross_indirect);
|
items[*iter].copyObject(
|
||||||
|
visited, cross_indirect, first_level_only);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
new_obj = new QPDF_Dictionary(items);
|
new_obj = new QPDF_Dictionary(items);
|
||||||
@ -2614,7 +2633,7 @@ void
|
|||||||
QPDFObjectHandle::makeDirect()
|
QPDFObjectHandle::makeDirect()
|
||||||
{
|
{
|
||||||
std::set<QPDFObjGen> visited;
|
std::set<QPDFObjGen> visited;
|
||||||
copyObject(visited, true);
|
copyObject(visited, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user