Commit b1eb1a958438025efbf90f7a7f45dbe33c746d91
Committed by
Jay Berkenbilt
1 parent
3e3b79a7
Refactor QPDFObjectHandle::copyObject1
Showing
8 changed files
with
38 additions
and
32 deletions
libqpdf/QPDFObjectHandle.cc
| ... | ... | @@ -2211,8 +2211,7 @@ QPDFObjectHandle::shallowCopyInternal1(QPDFObjectHandle& new_obj) |
| 2211 | 2211 | assertInitialized(); |
| 2212 | 2212 | |
| 2213 | 2213 | if (isStream()) { |
| 2214 | - QTC::TC("qpdf", "QPDFObjectHandle ERR shallow copy stream"); | |
| 2215 | - throw std::runtime_error("attempt to make a shallow copy of a stream"); | |
| 2214 | + // Handled bt QPDF_Stream::copy() | |
| 2216 | 2215 | } |
| 2217 | 2216 | new_obj = QPDFObjectHandle(obj->copy(true)); |
| 2218 | 2217 | |
| ... | ... | @@ -2225,9 +2224,10 @@ QPDFObjectHandle::copyObject1(std::set<QPDFObjGen>& visited) |
| 2225 | 2224 | { |
| 2226 | 2225 | assertInitialized(); |
| 2227 | 2226 | |
| 2227 | + std::shared_ptr<QPDFObject> new_obj; | |
| 2228 | + | |
| 2228 | 2229 | if (isStream()) { |
| 2229 | - throw std::runtime_error( | |
| 2230 | - "attempt to make a stream into a direct object"); | |
| 2230 | + new_obj = obj->copy(); | |
| 2231 | 2231 | } |
| 2232 | 2232 | |
| 2233 | 2233 | auto cur_og = getObjGen(); |
| ... | ... | @@ -2241,36 +2241,17 @@ QPDFObjectHandle::copyObject1(std::set<QPDFObjGen>& visited) |
| 2241 | 2241 | } |
| 2242 | 2242 | |
| 2243 | 2243 | if (isReserved()) { |
| 2244 | - throw std::logic_error("QPDFObjectHandle: attempting to make a" | |
| 2245 | - " reserved object handle direct"); | |
| 2244 | + new_obj = obj->copy(); | |
| 2246 | 2245 | } |
| 2247 | 2246 | |
| 2248 | - std::shared_ptr<QPDFObject> new_obj; | |
| 2249 | - | |
| 2250 | 2247 | if (isBool() || isInteger() || isName() || isNull() || isReal() || |
| 2251 | 2248 | isString()) { |
| 2252 | - new_obj = obj->copy(true); | |
| 2249 | + // copy(true) and copy(false) are the same | |
| 2250 | + new_obj = obj->copy(); | |
| 2253 | 2251 | } else if (isArray()) { |
| 2254 | - std::vector<QPDFObjectHandle> items; | |
| 2255 | - auto array = asArray(); | |
| 2256 | - int n = array->getNItems(); | |
| 2257 | - for (int i = 0; i < n; ++i) { | |
| 2258 | - items.push_back(array->getItem(i)); | |
| 2259 | - if (!items.back().isIndirect()) { | |
| 2260 | - items.back().copyObject1(visited); | |
| 2261 | - } | |
| 2262 | - } | |
| 2263 | - new_obj = QPDF_Array::create(items); | |
| 2252 | + new_obj = obj->copy(); | |
| 2264 | 2253 | } else if (isDictionary()) { |
| 2265 | - std::map<std::string, QPDFObjectHandle> items; | |
| 2266 | - auto dict = asDictionary(); | |
| 2267 | - for (auto const& key: getKeys()) { | |
| 2268 | - items[key] = dict->getKey(key); | |
| 2269 | - if (!items[key].isIndirect()) { | |
| 2270 | - items[key].copyObject1(visited); | |
| 2271 | - } | |
| 2272 | - } | |
| 2273 | - new_obj = QPDF_Dictionary::create(items); | |
| 2254 | + new_obj = obj->copy(); | |
| 2274 | 2255 | } else { |
| 2275 | 2256 | throw std::logic_error("QPDFObjectHandle::makeDirectInternal: " |
| 2276 | 2257 | "unknown object type"); | ... | ... |
libqpdf/QPDF_Array.cc
libqpdf/QPDF_Dictionary.cc
| ... | ... | @@ -18,7 +18,17 @@ QPDF_Dictionary::create(std::map<std::string, QPDFObjectHandle> const& items) |
| 18 | 18 | std::shared_ptr<QPDFObject> |
| 19 | 19 | QPDF_Dictionary::copy(bool shallow) |
| 20 | 20 | { |
| 21 | - return create(items); | |
| 21 | + if (shallow) { | |
| 22 | + return create(items); | |
| 23 | + } else { | |
| 24 | + std::map<std::string, QPDFObjectHandle> new_items; | |
| 25 | + for (auto const& item: this->items) { | |
| 26 | + auto value = item.second; | |
| 27 | + new_items[item.first] = | |
| 28 | + value.isIndirect() ? value : value.shallowCopy(); | |
| 29 | + } | |
| 30 | + return create(new_items); | |
| 31 | + } | |
| 22 | 32 | } |
| 23 | 33 | |
| 24 | 34 | void | ... | ... |
libqpdf/QPDF_Stream.cc
libqpdf/SparseOHArray.cc
| ... | ... | @@ -110,6 +110,19 @@ SparseOHArray::insert(size_t idx, QPDFObjectHandle oh) |
| 110 | 110 | } |
| 111 | 111 | } |
| 112 | 112 | |
| 113 | +SparseOHArray | |
| 114 | +SparseOHArray::copy() | |
| 115 | +{ | |
| 116 | + SparseOHArray result; | |
| 117 | + result.n_elements = this->n_elements; | |
| 118 | + for (auto const& element: this->elements) { | |
| 119 | + auto value = element.second; | |
| 120 | + result.elements[element.first] = | |
| 121 | + value.isIndirect() ? value : value.shallowCopy(); | |
| 122 | + } | |
| 123 | + return result; | |
| 124 | +} | |
| 125 | + | |
| 113 | 126 | SparseOHArray::const_iterator |
| 114 | 127 | SparseOHArray::begin() const |
| 115 | 128 | { | ... | ... |
libqpdf/qpdf/SparseOHArray.hh
| ... | ... | @@ -15,6 +15,7 @@ class SparseOHArray |
| 15 | 15 | void setAt(size_t idx, QPDFObjectHandle oh); |
| 16 | 16 | void erase(size_t idx); |
| 17 | 17 | void insert(size_t idx, QPDFObjectHandle oh); |
| 18 | + SparseOHArray copy(); | |
| 18 | 19 | void disconnect(); |
| 19 | 20 | |
| 20 | 21 | typedef std::unordered_map<size_t, QPDFObjectHandle>::const_iterator | ... | ... |
qpdf/qpdf.testcov
| ... | ... | @@ -192,7 +192,7 @@ QPDF insert page 2 |
| 192 | 192 | QPDF updateAllPagesCache 0 |
| 193 | 193 | QPDF insert non-indirect page 0 |
| 194 | 194 | QPDF insert indirect page 0 |
| 195 | -QPDFObjectHandle ERR shallow copy stream 0 | |
| 195 | +QPDF_Stream ERR shallow copy stream 0 | |
| 196 | 196 | QPDFObjectHandle newStream with string 0 |
| 197 | 197 | QPDF unknown key not inherited 0 |
| 198 | 198 | QPDF_Stream provider length not provided 0 | ... | ... |
qpdf/qtest/qpdf/shallow_stream.out