You need to sign in before continuing.
Commit 8d7ed7644e4ac27ccdf456ad779540f73612bd6a
1 parent
3b90f899
Refactor QPDFObject to use std::variant instead of std::shared_pointer
Showing
46 changed files
with
1066 additions
and
1728 deletions
include/qpdf/Constants.h
include/qpdf/QPDF.hh
| ... | ... | @@ -1087,7 +1087,8 @@ class QPDF |
| 1087 | 1087 | QPDFObjGen og, |
| 1088 | 1088 | std::shared_ptr<QPDFObject> const& object, |
| 1089 | 1089 | qpdf_offset_t end_before_space, |
| 1090 | - qpdf_offset_t end_after_space); | |
| 1090 | + qpdf_offset_t end_after_space, | |
| 1091 | + bool destroy = true); | |
| 1091 | 1092 | static QPDFExc damagedPDF( |
| 1092 | 1093 | InputSource& input, |
| 1093 | 1094 | std::string const& object, | ... | ... |
include/qpdf/QPDFObjectHandle.hh
| ... | ... | @@ -1254,8 +1254,7 @@ class QPDFObjectHandle final: public qpdf::BaseHandle |
| 1254 | 1254 | // Provide access to specific classes for recursive disconnected(). |
| 1255 | 1255 | class DisconnectAccess |
| 1256 | 1256 | { |
| 1257 | - friend class QPDF_Dictionary; | |
| 1258 | - friend class QPDF_Stream; | |
| 1257 | + friend class QPDFObject; | |
| 1259 | 1258 | |
| 1260 | 1259 | private: |
| 1261 | 1260 | static void | ... | ... |
include/qpdf/QPDFObjectHandle_future.hh deleted
libqpdf/CMakeLists.txt
| ... | ... | @@ -86,23 +86,12 @@ set(libqpdf_SOURCES |
| 86 | 86 | QPDFSystemError.cc |
| 87 | 87 | QPDFTokenizer.cc |
| 88 | 88 | QPDFUsage.cc |
| 89 | - QPDFValue.cc | |
| 90 | 89 | QPDFWriter.cc |
| 91 | 90 | QPDFXRefEntry.cc |
| 92 | 91 | QPDF_Array.cc |
| 93 | - QPDF_Bool.cc | |
| 94 | - QPDF_Destroyed.cc | |
| 95 | 92 | QPDF_Dictionary.cc |
| 96 | - QPDF_InlineImage.cc | |
| 97 | - QPDF_Integer.cc | |
| 98 | - QPDF_Name.cc | |
| 99 | - QPDF_Null.cc | |
| 100 | - QPDF_Operator.cc | |
| 101 | - QPDF_Real.cc | |
| 102 | - QPDF_Reserved.cc | |
| 103 | 93 | QPDF_Stream.cc |
| 104 | 94 | QPDF_String.cc |
| 105 | - QPDF_Unresolved.cc | |
| 106 | 95 | QPDF_encryption.cc |
| 107 | 96 | QPDF_json.cc |
| 108 | 97 | QPDF_linearization.cc | ... | ... |
libqpdf/QPDF.cc
| ... | ... | @@ -20,11 +20,6 @@ |
| 20 | 20 | #include <qpdf/QPDFObjectHandle_private.hh> |
| 21 | 21 | #include <qpdf/QPDFObject_private.hh> |
| 22 | 22 | #include <qpdf/QPDFParser.hh> |
| 23 | -#include <qpdf/QPDF_Dictionary.hh> | |
| 24 | -#include <qpdf/QPDF_Null.hh> | |
| 25 | -#include <qpdf/QPDF_Reserved.hh> | |
| 26 | -#include <qpdf/QPDF_Stream.hh> | |
| 27 | -#include <qpdf/QPDF_Unresolved.hh> | |
| 28 | 23 | #include <qpdf/QTC.hh> |
| 29 | 24 | #include <qpdf/QUtil.hh> |
| 30 | 25 | |
| ... | ... | @@ -1565,7 +1560,7 @@ QPDF::readStream(QPDFObjectHandle& object, QPDFObjGen og, qpdf_offset_t offset) |
| 1565 | 1560 | throw; |
| 1566 | 1561 | } |
| 1567 | 1562 | } |
| 1568 | - object = {QPDF_Stream::create(this, og, object, stream_offset, length)}; | |
| 1563 | + object = QPDFObjectHandle(qpdf::Stream(*this, og, object, stream_offset, length)); | |
| 1569 | 1564 | } |
| 1570 | 1565 | |
| 1571 | 1566 | void |
| ... | ... | @@ -1884,7 +1879,7 @@ QPDF::resolve(QPDFObjGen og) |
| 1884 | 1879 | // has to be resolved during object parsing, such as stream length. |
| 1885 | 1880 | QTC::TC("qpdf", "QPDF recursion loop in resolve"); |
| 1886 | 1881 | warn(damagedPDF("", "loop detected resolving object " + og.unparse(' '))); |
| 1887 | - updateCache(og, QPDF_Null::create(), -1, -1); | |
| 1882 | + updateCache(og, QPDFObject::create<QPDF_Null>(), -1, -1); | |
| 1888 | 1883 | return m->obj_cache[og].object.get(); |
| 1889 | 1884 | } |
| 1890 | 1885 | ResolveRecorder rr(this, og); |
| ... | ... | @@ -1921,7 +1916,7 @@ QPDF::resolve(QPDFObjGen og) |
| 1921 | 1916 | if (isUnresolved(og)) { |
| 1922 | 1917 | // PDF spec says unknown objects resolve to the null object. |
| 1923 | 1918 | QTC::TC("qpdf", "QPDF resolve failure to null"); |
| 1924 | - updateCache(og, QPDF_Null::create(), -1, -1); | |
| 1919 | + updateCache(og, QPDFObject::create<QPDF_Null>(), -1, -1); | |
| 1925 | 1920 | } |
| 1926 | 1921 | |
| 1927 | 1922 | auto result(m->obj_cache[og].object); |
| ... | ... | @@ -2034,12 +2029,13 @@ QPDF::updateCache( |
| 2034 | 2029 | QPDFObjGen og, |
| 2035 | 2030 | std::shared_ptr<QPDFObject> const& object, |
| 2036 | 2031 | qpdf_offset_t end_before_space, |
| 2037 | - qpdf_offset_t end_after_space) | |
| 2032 | + qpdf_offset_t end_after_space, | |
| 2033 | + bool destroy) | |
| 2038 | 2034 | { |
| 2039 | 2035 | object->setObjGen(this, og); |
| 2040 | 2036 | if (isCached(og)) { |
| 2041 | 2037 | auto& cache = m->obj_cache[og]; |
| 2042 | - cache.object->assign(object); | |
| 2038 | + object->move_to(cache.object, destroy); | |
| 2043 | 2039 | cache.end_before_space = end_before_space; |
| 2044 | 2040 | cache.end_after_space = end_after_space; |
| 2045 | 2041 | } else { |
| ... | ... | @@ -2089,20 +2085,20 @@ QPDF::makeIndirectObject(QPDFObjectHandle oh) |
| 2089 | 2085 | QPDFObjectHandle |
| 2090 | 2086 | QPDF::newReserved() |
| 2091 | 2087 | { |
| 2092 | - return makeIndirectFromQPDFObject(QPDF_Reserved::create()); | |
| 2088 | + return makeIndirectFromQPDFObject(QPDFObject::create<QPDF_Reserved>()); | |
| 2093 | 2089 | } |
| 2094 | 2090 | |
| 2095 | 2091 | QPDFObjectHandle |
| 2096 | 2092 | QPDF::newIndirectNull() |
| 2097 | 2093 | { |
| 2098 | - return makeIndirectFromQPDFObject(QPDF_Null::create()); | |
| 2094 | + return makeIndirectFromQPDFObject(QPDFObject::create<QPDF_Null>()); | |
| 2099 | 2095 | } |
| 2100 | 2096 | |
| 2101 | 2097 | QPDFObjectHandle |
| 2102 | 2098 | QPDF::newStream() |
| 2103 | 2099 | { |
| 2104 | - return makeIndirectFromQPDFObject( | |
| 2105 | - QPDF_Stream::create(this, nextObjGen(), QPDFObjectHandle::newDictionary(), 0, 0)); | |
| 2100 | + return makeIndirectObject( | |
| 2101 | + qpdf::Stream(*this, nextObjGen(), QPDFObjectHandle::newDictionary(), 0, 0)); | |
| 2106 | 2102 | } |
| 2107 | 2103 | |
| 2108 | 2104 | QPDFObjectHandle |
| ... | ... | @@ -2130,12 +2126,13 @@ QPDF::getObjectForParser(int id, int gen, bool parse_pdf) |
| 2130 | 2126 | return iter->second.object; |
| 2131 | 2127 | } |
| 2132 | 2128 | if (m->xref_table.count(og) || !m->parsed) { |
| 2133 | - return m->obj_cache.insert({og, QPDF_Unresolved::create(this, og)}).first->second.object; | |
| 2129 | + return m->obj_cache.insert({og, QPDFObject::create<QPDF_Unresolved>(this, og)}) | |
| 2130 | + .first->second.object; | |
| 2134 | 2131 | } |
| 2135 | 2132 | if (parse_pdf) { |
| 2136 | - return QPDF_Null::create(); | |
| 2133 | + return QPDFObject::create<QPDF_Null>(); | |
| 2137 | 2134 | } |
| 2138 | - return m->obj_cache.insert({og, QPDF_Null::create(this, og)}).first->second.object; | |
| 2135 | + return m->obj_cache.insert({og, QPDFObject::create<QPDF_Null>(this, og)}).first->second.object; | |
| 2139 | 2136 | } |
| 2140 | 2137 | |
| 2141 | 2138 | std::shared_ptr<QPDFObject> |
| ... | ... | @@ -2145,8 +2142,9 @@ QPDF::getObjectForJSON(int id, int gen) |
| 2145 | 2142 | auto [it, inserted] = m->obj_cache.try_emplace(og); |
| 2146 | 2143 | auto& obj = it->second.object; |
| 2147 | 2144 | if (inserted) { |
| 2148 | - obj = (m->parsed && !m->xref_table.count(og)) ? QPDF_Null::create(this, og) | |
| 2149 | - : QPDF_Unresolved::create(this, og); | |
| 2145 | + obj = (m->parsed && !m->xref_table.count(og)) | |
| 2146 | + ? QPDFObject::create<QPDF_Null>(this, og) | |
| 2147 | + : QPDFObject::create<QPDF_Unresolved>(this, og); | |
| 2150 | 2148 | } |
| 2151 | 2149 | return obj; |
| 2152 | 2150 | } |
| ... | ... | @@ -2157,9 +2155,10 @@ QPDF::getObject(QPDFObjGen og) |
| 2157 | 2155 | if (auto it = m->obj_cache.find(og); it != m->obj_cache.end()) { |
| 2158 | 2156 | return {it->second.object}; |
| 2159 | 2157 | } else if (m->parsed && !m->xref_table.count(og)) { |
| 2160 | - return QPDF_Null::create(); | |
| 2158 | + return QPDFObject::create<QPDF_Null>(); | |
| 2161 | 2159 | } else { |
| 2162 | - auto result = m->obj_cache.try_emplace(og, QPDF_Unresolved::create(this, og), -1, -1); | |
| 2160 | + auto result = | |
| 2161 | + m->obj_cache.try_emplace(og, QPDFObject::create<QPDF_Unresolved>(this, og), -1, -1); | |
| 2163 | 2162 | return {result.first->second.object}; |
| 2164 | 2163 | } |
| 2165 | 2164 | } |
| ... | ... | @@ -2195,7 +2194,7 @@ QPDF::replaceObject(QPDFObjGen og, QPDFObjectHandle oh) |
| 2195 | 2194 | QTC::TC("qpdf", "QPDF replaceObject called with indirect object"); |
| 2196 | 2195 | throw std::logic_error("QPDF::replaceObject called with indirect object handle"); |
| 2197 | 2196 | } |
| 2198 | - updateCache(og, oh.getObj(), -1, -1); | |
| 2197 | + updateCache(og, oh.getObj(), -1, -1, false); | |
| 2199 | 2198 | } |
| 2200 | 2199 | |
| 2201 | 2200 | void |
| ... | ... | @@ -2204,7 +2203,7 @@ QPDF::removeObject(QPDFObjGen og) |
| 2204 | 2203 | m->xref_table.erase(og); |
| 2205 | 2204 | if (auto cached = m->obj_cache.find(og); cached != m->obj_cache.end()) { |
| 2206 | 2205 | // Take care of any object handles that may be floating around. |
| 2207 | - cached->second.object->assign(QPDF_Null::create()); | |
| 2206 | + cached->second.object->assign_null(); | |
| 2208 | 2207 | cached->second.object->setObjGen(nullptr, QPDFObjGen()); |
| 2209 | 2208 | m->obj_cache.erase(cached); |
| 2210 | 2209 | } | ... | ... |
libqpdf/QPDFObject.cc
| 1 | 1 | #include <qpdf/QPDFObject_private.hh> |
| 2 | 2 | |
| 3 | -#include <qpdf/QPDF.hh> | |
| 4 | -#include <qpdf/QPDF_Destroyed.hh> | |
| 5 | - | |
| 6 | -void | |
| 7 | -QPDFObject::destroy() | |
| 3 | +std::string | |
| 4 | +QPDFObject::getDescription() | |
| 8 | 5 | { |
| 9 | - value = QPDF_Destroyed::getInstance(); | |
| 6 | + if (object_description) { | |
| 7 | + switch (object_description->index()) { | |
| 8 | + case 0: | |
| 9 | + { | |
| 10 | + // Simple template string | |
| 11 | + auto description = std::get<0>(*object_description); | |
| 12 | + | |
| 13 | + if (auto pos = description.find("$OG"); pos != std::string::npos) { | |
| 14 | + description.replace(pos, 3, og.unparse(' ')); | |
| 15 | + } | |
| 16 | + if (auto pos = description.find("$PO"); pos != std::string::npos) { | |
| 17 | + qpdf_offset_t shift = (getTypeCode() == ::ot_dictionary) ? 2 | |
| 18 | + : (getTypeCode() == ::ot_array) ? 1 | |
| 19 | + : 0; | |
| 20 | + | |
| 21 | + description.replace(pos, 3, std::to_string(parsed_offset + shift)); | |
| 22 | + } | |
| 23 | + return description; | |
| 24 | + } | |
| 25 | + case 1: | |
| 26 | + { | |
| 27 | + // QPDF::JSONReactor generated description | |
| 28 | + auto j_descr = std::get<1>(*object_description); | |
| 29 | + return ( | |
| 30 | + *j_descr.input + (j_descr.object.empty() ? "" : ", " + j_descr.object) + | |
| 31 | + " at offset " + std::to_string(parsed_offset)); | |
| 32 | + } | |
| 33 | + case 2: | |
| 34 | + { | |
| 35 | + // Child object description | |
| 36 | + auto j_descr = std::get<2>(*object_description); | |
| 37 | + std::string result; | |
| 38 | + if (auto p = j_descr.parent.lock()) { | |
| 39 | + result = p->getDescription(); | |
| 40 | + } | |
| 41 | + result += j_descr.static_descr; | |
| 42 | + if (auto pos = result.find("$VD"); pos != std::string::npos) { | |
| 43 | + result.replace(pos, 3, j_descr.var_descr); | |
| 44 | + } | |
| 45 | + return result; | |
| 46 | + } | |
| 47 | + } | |
| 48 | + } else if (og.isIndirect()) { | |
| 49 | + return "object " + og.unparse(' '); | |
| 50 | + } | |
| 51 | + return {}; | |
| 10 | 52 | } | ... | ... |
libqpdf/QPDFObjectHandle.cc
| ... | ... | @@ -11,19 +11,6 @@ |
| 11 | 11 | #include <qpdf/QPDFObject_private.hh> |
| 12 | 12 | #include <qpdf/QPDFPageObjectHelper.hh> |
| 13 | 13 | #include <qpdf/QPDFParser.hh> |
| 14 | -#include <qpdf/QPDF_Array.hh> | |
| 15 | -#include <qpdf/QPDF_Bool.hh> | |
| 16 | -#include <qpdf/QPDF_Dictionary.hh> | |
| 17 | -#include <qpdf/QPDF_InlineImage.hh> | |
| 18 | -#include <qpdf/QPDF_Integer.hh> | |
| 19 | -#include <qpdf/QPDF_Name.hh> | |
| 20 | -#include <qpdf/QPDF_Null.hh> | |
| 21 | -#include <qpdf/QPDF_Operator.hh> | |
| 22 | -#include <qpdf/QPDF_Real.hh> | |
| 23 | -#include <qpdf/QPDF_Reserved.hh> | |
| 24 | -#include <qpdf/QPDF_Stream.hh> | |
| 25 | -#include <qpdf/QPDF_String.hh> | |
| 26 | -#include <qpdf/QPDF_Unresolved.hh> | |
| 27 | 14 | |
| 28 | 15 | #include <qpdf/QIntC.hh> |
| 29 | 16 | #include <qpdf/QTC.hh> |
| ... | ... | @@ -228,6 +215,443 @@ LastChar::getLastChar() |
| 228 | 215 | return this->last_char; |
| 229 | 216 | } |
| 230 | 217 | |
| 218 | +std::pair<bool, bool> | |
| 219 | +Name::analyzeJSONEncoding(const std::string& name) | |
| 220 | +{ | |
| 221 | + int tail = 0; // Number of continuation characters expected. | |
| 222 | + bool tail2 = false; // Potential overlong 3 octet utf-8. | |
| 223 | + bool tail3 = false; // potential overlong 4 octet | |
| 224 | + bool needs_escaping = false; | |
| 225 | + for (auto const& it: name) { | |
| 226 | + auto c = static_cast<unsigned char>(it); | |
| 227 | + if (tail) { | |
| 228 | + if ((c & 0xc0) != 0x80) { | |
| 229 | + return {false, false}; | |
| 230 | + } | |
| 231 | + if (tail2) { | |
| 232 | + if ((c & 0xe0) == 0x80) { | |
| 233 | + return {false, false}; | |
| 234 | + } | |
| 235 | + tail2 = false; | |
| 236 | + } else if (tail3) { | |
| 237 | + if ((c & 0xf0) == 0x80) { | |
| 238 | + return {false, false}; | |
| 239 | + } | |
| 240 | + tail3 = false; | |
| 241 | + } | |
| 242 | + tail--; | |
| 243 | + } else if (c < 0x80) { | |
| 244 | + if (!needs_escaping) { | |
| 245 | + needs_escaping = !((c > 34 && c != '\\') || c == ' ' || c == 33); | |
| 246 | + } | |
| 247 | + } else if ((c & 0xe0) == 0xc0) { | |
| 248 | + if ((c & 0xfe) == 0xc0) { | |
| 249 | + return {false, false}; | |
| 250 | + } | |
| 251 | + tail = 1; | |
| 252 | + } else if ((c & 0xf0) == 0xe0) { | |
| 253 | + tail2 = (c == 0xe0); | |
| 254 | + tail = 2; | |
| 255 | + } else if ((c & 0xf8) == 0xf0) { | |
| 256 | + tail3 = (c == 0xf0); | |
| 257 | + tail = 3; | |
| 258 | + } else { | |
| 259 | + return {false, false}; | |
| 260 | + } | |
| 261 | + } | |
| 262 | + return {tail == 0, !needs_escaping}; | |
| 263 | +} | |
| 264 | + | |
| 265 | +std::string | |
| 266 | +Name::normalize(std::string const& name) | |
| 267 | +{ | |
| 268 | + if (name.empty()) { | |
| 269 | + return name; | |
| 270 | + } | |
| 271 | + std::string result; | |
| 272 | + result += name.at(0); | |
| 273 | + for (size_t i = 1; i < name.length(); ++i) { | |
| 274 | + char ch = name.at(i); | |
| 275 | + // Don't use locale/ctype here; follow PDF spec guidelines. | |
| 276 | + if (ch == '\0') { | |
| 277 | + // QPDFTokenizer embeds a null character to encode an invalid #. | |
| 278 | + result += "#"; | |
| 279 | + } else if ( | |
| 280 | + ch < 33 || ch == '#' || ch == '/' || ch == '(' || ch == ')' || ch == '{' || ch == '}' || | |
| 281 | + ch == '<' || ch == '>' || ch == '[' || ch == ']' || ch == '%' || ch > 126) { | |
| 282 | + result += QUtil::hex_encode_char(ch); | |
| 283 | + } else { | |
| 284 | + result += ch; | |
| 285 | + } | |
| 286 | + } | |
| 287 | + return result; | |
| 288 | +} | |
| 289 | + | |
| 290 | +std::shared_ptr<QPDFObject> | |
| 291 | +QPDFObject::copy(bool shallow) | |
| 292 | +{ | |
| 293 | + switch (getResolvedTypeCode()) { | |
| 294 | + case ::ot_uninitialized: | |
| 295 | + throw std::logic_error("QPDFObjectHandle: attempting to copy an uninitialized object"); | |
| 296 | + return {}; // does not return | |
| 297 | + case ::ot_reserved: | |
| 298 | + return create<QPDF_Reserved>(); | |
| 299 | + case ::ot_null: | |
| 300 | + return create<QPDF_Null>(); | |
| 301 | + case ::ot_boolean: | |
| 302 | + return create<QPDF_Bool>(std::get<QPDF_Bool>(value).val); | |
| 303 | + case ::ot_integer: | |
| 304 | + return create<QPDF_Integer>(std::get<QPDF_Integer>(value).val); | |
| 305 | + case ::ot_real: | |
| 306 | + return create<QPDF_Real>(std::get<QPDF_Real>(value).val); | |
| 307 | + case ::ot_string: | |
| 308 | + return create<QPDF_String>(std::get<QPDF_String>(value).val); | |
| 309 | + case ::ot_name: | |
| 310 | + return create<QPDF_Name>(std::get<QPDF_Name>(value).name); | |
| 311 | + case ::ot_array: | |
| 312 | + { | |
| 313 | + auto const& a = std::get<QPDF_Array>(value); | |
| 314 | + if (shallow) { | |
| 315 | + return QPDFObject::create<QPDF_Array>(a); | |
| 316 | + } else { | |
| 317 | + QTC::TC("qpdf", "QPDF_Array copy", a.sp ? 0 : 1); | |
| 318 | + if (a.sp) { | |
| 319 | + QPDF_Array result; | |
| 320 | + result.sp = std::make_unique<QPDF_Array::Sparse>(); | |
| 321 | + result.sp->size = a.sp->size; | |
| 322 | + for (auto const& element: a.sp->elements) { | |
| 323 | + auto const& obj = element.second; | |
| 324 | + result.sp->elements[element.first] = | |
| 325 | + obj->getObjGen().isIndirect() ? obj : obj->copy(); | |
| 326 | + } | |
| 327 | + return QPDFObject::create<QPDF_Array>(std::move(result)); | |
| 328 | + } else { | |
| 329 | + std::vector<std::shared_ptr<QPDFObject>> result; | |
| 330 | + result.reserve(a.elements.size()); | |
| 331 | + for (auto const& element: a.elements) { | |
| 332 | + result.push_back( | |
| 333 | + element | |
| 334 | + ? (element->getObjGen().isIndirect() ? element : element->copy()) | |
| 335 | + : element); | |
| 336 | + } | |
| 337 | + return QPDFObject::create<QPDF_Array>(std::move(result), false); | |
| 338 | + } | |
| 339 | + } | |
| 340 | + } | |
| 341 | + case ::ot_dictionary: | |
| 342 | + { | |
| 343 | + auto const& d = std::get<QPDF_Dictionary>(value); | |
| 344 | + if (shallow) { | |
| 345 | + return QPDFObject::create<QPDF_Dictionary>(d.items); | |
| 346 | + } else { | |
| 347 | + std::map<std::string, QPDFObjectHandle> new_items; | |
| 348 | + for (auto const& [key, val]: d.items) { | |
| 349 | + new_items[key] = val.isIndirect() ? val : val.getObj()->copy(); | |
| 350 | + } | |
| 351 | + return QPDFObject::create<QPDF_Dictionary>(new_items); | |
| 352 | + } | |
| 353 | + } | |
| 354 | + case ::ot_stream: | |
| 355 | + QTC::TC("qpdf", "QPDF_Stream ERR shallow copy stream"); | |
| 356 | + throw std::runtime_error("stream objects cannot be cloned"); | |
| 357 | + return {}; // does not return | |
| 358 | + case ::ot_operator: | |
| 359 | + return create<QPDF_Operator>(std::get<QPDF_Operator>(value).val); | |
| 360 | + case ::ot_inlineimage: | |
| 361 | + return create<QPDF_InlineImage>(std::get<QPDF_InlineImage>(value).val); | |
| 362 | + case ::ot_unresolved: | |
| 363 | + throw std::logic_error("QPDFObjectHandle: attempting to unparse a reserved object"); | |
| 364 | + return {}; // does not return | |
| 365 | + case ::ot_destroyed: | |
| 366 | + throw std::logic_error("attempted to shallow copy QPDFObjectHandle from destroyed QPDF"); | |
| 367 | + return {}; // does not return | |
| 368 | + case ::ot_reference: | |
| 369 | + return qpdf->getObject(og).getObj(); | |
| 370 | + } | |
| 371 | + return {}; // does not return | |
| 372 | +} | |
| 373 | + | |
| 374 | +std::string | |
| 375 | +QPDFObject::unparse() | |
| 376 | +{ | |
| 377 | + switch (getResolvedTypeCode()) { | |
| 378 | + case ::ot_uninitialized: | |
| 379 | + throw std::logic_error("QPDFObjectHandle: attempting to unparse an uninitialized object"); | |
| 380 | + return ""; // does not return | |
| 381 | + case ::ot_reserved: | |
| 382 | + throw std::logic_error("QPDFObjectHandle: attempting to unparse a reserved object"); | |
| 383 | + return ""; // does not return | |
| 384 | + case ::ot_null: | |
| 385 | + return "null"; | |
| 386 | + case ::ot_boolean: | |
| 387 | + return std::get<QPDF_Bool>(value).val ? "true" : "false"; | |
| 388 | + case ::ot_integer: | |
| 389 | + return std::to_string(std::get<QPDF_Integer>(value).val); | |
| 390 | + case ::ot_real: | |
| 391 | + return std::get<QPDF_Real>(value).val; | |
| 392 | + case ::ot_string: | |
| 393 | + return std::get<QPDF_String>(value).unparse(false); | |
| 394 | + case ::ot_name: | |
| 395 | + return Name::normalize(std::get<QPDF_Name>(value).name); | |
| 396 | + case ::ot_array: | |
| 397 | + { | |
| 398 | + auto const& a = std::get<QPDF_Array>(value); | |
| 399 | + std::string result = "[ "; | |
| 400 | + if (a.sp) { | |
| 401 | + int next = 0; | |
| 402 | + for (auto& item: a.sp->elements) { | |
| 403 | + int key = item.first; | |
| 404 | + for (int j = next; j < key; ++j) { | |
| 405 | + result += "null "; | |
| 406 | + } | |
| 407 | + auto item_og = item.second->resolved_object()->getObjGen(); | |
| 408 | + result += item_og.isIndirect() ? item_og.unparse(' ') + " R " | |
| 409 | + : item.second->unparse() + " "; | |
| 410 | + next = ++key; | |
| 411 | + } | |
| 412 | + for (int j = next; j < a.sp->size; ++j) { | |
| 413 | + result += "null "; | |
| 414 | + } | |
| 415 | + } else { | |
| 416 | + for (auto const& item: a.elements) { | |
| 417 | + auto item_og = item->resolved_object()->getObjGen(); | |
| 418 | + result += | |
| 419 | + item_og.isIndirect() ? item_og.unparse(' ') + " R " : item->unparse() + " "; | |
| 420 | + } | |
| 421 | + } | |
| 422 | + result += "]"; | |
| 423 | + return result; | |
| 424 | + } | |
| 425 | + case ::ot_dictionary: | |
| 426 | + { | |
| 427 | + auto const& items = std::get<QPDF_Dictionary>(value).items; | |
| 428 | + std::string result = "<< "; | |
| 429 | + for (auto& iter: items) { | |
| 430 | + if (!iter.second.isNull()) { | |
| 431 | + result += Name::normalize(iter.first) + " " + iter.second.unparse() + " "; | |
| 432 | + } | |
| 433 | + } | |
| 434 | + result += ">>"; | |
| 435 | + return result; | |
| 436 | + } | |
| 437 | + case ::ot_stream: | |
| 438 | + return og.unparse(' ') + " R"; | |
| 439 | + case ::ot_operator: | |
| 440 | + return std::get<QPDF_Operator>(value).val; | |
| 441 | + case ::ot_inlineimage: | |
| 442 | + return std::get<QPDF_InlineImage>(value).val; | |
| 443 | + case ::ot_unresolved: | |
| 444 | + throw std::logic_error("QPDFObjectHandle: attempting to unparse a unresolved object"); | |
| 445 | + return ""; // does not return | |
| 446 | + case ::ot_destroyed: | |
| 447 | + throw std::logic_error("attempted to unparse a QPDFObjectHandle from a destroyed QPDF"); | |
| 448 | + return ""; // does not return | |
| 449 | + case ::ot_reference: | |
| 450 | + return og.unparse(' ') + " R"; | |
| 451 | + } | |
| 452 | + return {}; // does not return | |
| 453 | +} | |
| 454 | + | |
| 455 | +void | |
| 456 | +QPDFObject::write_json(int json_version, JSON::Writer& p) | |
| 457 | +{ | |
| 458 | + switch (getResolvedTypeCode()) { | |
| 459 | + case ::ot_uninitialized: | |
| 460 | + throw std::logic_error( | |
| 461 | + "QPDFObjectHandle: attempting to get JSON from a uninitialized object"); | |
| 462 | + break; // unreachable | |
| 463 | + case ::ot_null: | |
| 464 | + case ::ot_operator: | |
| 465 | + case ::ot_inlineimage: | |
| 466 | + p << "null"; | |
| 467 | + break; | |
| 468 | + case ::ot_boolean: | |
| 469 | + p << std::get<QPDF_Bool>(value).val; | |
| 470 | + break; | |
| 471 | + case ::ot_integer: | |
| 472 | + p << std::to_string(std::get<QPDF_Integer>(value).val); | |
| 473 | + break; | |
| 474 | + case ::ot_real: | |
| 475 | + { | |
| 476 | + auto const& val = std::get<QPDF_Real>(value).val; | |
| 477 | + if (val.length() == 0) { | |
| 478 | + // Can't really happen... | |
| 479 | + p << "0"; | |
| 480 | + } else if (val.at(0) == '.') { | |
| 481 | + p << "0" << val; | |
| 482 | + } else if (val.length() >= 2 && val.at(0) == '-' && val.at(1) == '.') { | |
| 483 | + p << "-0." << val.substr(2); | |
| 484 | + } else { | |
| 485 | + p << val; | |
| 486 | + } | |
| 487 | + if (val.back() == '.') { | |
| 488 | + p << "0"; | |
| 489 | + } | |
| 490 | + } | |
| 491 | + break; | |
| 492 | + case ::ot_string: | |
| 493 | + std::get<QPDF_String>(value).writeJSON(json_version, p); | |
| 494 | + break; | |
| 495 | + case ::ot_name: | |
| 496 | + { | |
| 497 | + auto const& n = std::get<QPDF_Name>(value); | |
| 498 | + // For performance reasons this code is duplicated in QPDF_Dictionary::writeJSON. When | |
| 499 | + // updating this method make sure QPDF_Dictionary is also update. | |
| 500 | + if (json_version == 1) { | |
| 501 | + p << "\"" << JSON::Writer::encode_string(Name::normalize(n.name)) << "\""; | |
| 502 | + } else { | |
| 503 | + if (auto res = Name::analyzeJSONEncoding(n.name); res.first) { | |
| 504 | + if (res.second) { | |
| 505 | + p << "\"" << n.name << "\""; | |
| 506 | + } else { | |
| 507 | + p << "\"" << JSON::Writer::encode_string(n.name) << "\""; | |
| 508 | + } | |
| 509 | + } else { | |
| 510 | + p << "\"n:" << JSON::Writer::encode_string(Name::normalize(n.name)) << "\""; | |
| 511 | + } | |
| 512 | + } | |
| 513 | + } | |
| 514 | + break; | |
| 515 | + case ::ot_array: | |
| 516 | + { | |
| 517 | + auto const& a = std::get<QPDF_Array>(value); | |
| 518 | + p.writeStart('['); | |
| 519 | + if (a.sp) { | |
| 520 | + int next = 0; | |
| 521 | + for (auto& item: a.sp->elements) { | |
| 522 | + int key = item.first; | |
| 523 | + for (int j = next; j < key; ++j) { | |
| 524 | + p.writeNext() << "null"; | |
| 525 | + } | |
| 526 | + p.writeNext(); | |
| 527 | + auto item_og = item.second->getObjGen(); | |
| 528 | + if (item_og.isIndirect()) { | |
| 529 | + p << "\"" << item_og.unparse(' ') << " R\""; | |
| 530 | + } else { | |
| 531 | + item.second->write_json(json_version, p); | |
| 532 | + } | |
| 533 | + next = ++key; | |
| 534 | + } | |
| 535 | + for (int j = next; j < a.sp->size; ++j) { | |
| 536 | + p.writeNext() << "null"; | |
| 537 | + } | |
| 538 | + } else { | |
| 539 | + for (auto const& item: a.elements) { | |
| 540 | + p.writeNext(); | |
| 541 | + auto item_og = item->getObjGen(); | |
| 542 | + if (item_og.isIndirect()) { | |
| 543 | + p << "\"" << item_og.unparse(' ') << " R\""; | |
| 544 | + } else { | |
| 545 | + item->write_json(json_version, p); | |
| 546 | + } | |
| 547 | + } | |
| 548 | + } | |
| 549 | + p.writeEnd(']'); | |
| 550 | + } | |
| 551 | + break; | |
| 552 | + case ::ot_dictionary: | |
| 553 | + { | |
| 554 | + auto const& d = std::get<QPDF_Dictionary>(value); | |
| 555 | + p.writeStart('{'); | |
| 556 | + for (auto& iter: d.items) { | |
| 557 | + if (!iter.second.isNull()) { | |
| 558 | + p.writeNext(); | |
| 559 | + if (json_version == 1) { | |
| 560 | + p << "\"" << JSON::Writer::encode_string(Name::normalize(iter.first)) | |
| 561 | + << "\": "; | |
| 562 | + } else if (auto res = Name::analyzeJSONEncoding(iter.first); res.first) { | |
| 563 | + if (res.second) { | |
| 564 | + p << "\"" << iter.first << "\": "; | |
| 565 | + } else { | |
| 566 | + p << "\"" << JSON::Writer::encode_string(iter.first) << "\": "; | |
| 567 | + } | |
| 568 | + } else { | |
| 569 | + p << "\"n:" << JSON::Writer::encode_string(Name::normalize(iter.first)) | |
| 570 | + << "\": "; | |
| 571 | + } | |
| 572 | + iter.second.writeJSON(json_version, p); | |
| 573 | + } | |
| 574 | + } | |
| 575 | + p.writeEnd('}'); | |
| 576 | + } | |
| 577 | + break; | |
| 578 | + case ::ot_stream: | |
| 579 | + std::get<QPDF_Stream>(value).m->stream_dict.writeJSON(json_version, p); | |
| 580 | + break; | |
| 581 | + case ::ot_reference: | |
| 582 | + p << "\"" << getObjGen().unparse(' ') << " R\""; | |
| 583 | + break; | |
| 584 | + default: | |
| 585 | + throw std::logic_error("attempted to write an unsuitable object as JSON"); | |
| 586 | + } | |
| 587 | +} | |
| 588 | + | |
| 589 | +void | |
| 590 | +QPDFObject::disconnect() | |
| 591 | +{ | |
| 592 | + // Disconnect an object from its owning QPDF. This is called by QPDF's destructor. | |
| 593 | + | |
| 594 | + switch (getTypeCode()) { | |
| 595 | + case ::ot_array: | |
| 596 | + { | |
| 597 | + auto& a = std::get<QPDF_Array>(value); | |
| 598 | + if (a.sp) { | |
| 599 | + for (auto& item: a.sp->elements) { | |
| 600 | + auto& obj = item.second; | |
| 601 | + if (!obj->getObjGen().isIndirect()) { | |
| 602 | + obj->disconnect(); | |
| 603 | + } | |
| 604 | + } | |
| 605 | + } else { | |
| 606 | + for (auto& obj: a.elements) { | |
| 607 | + if (!obj->getObjGen().isIndirect()) { | |
| 608 | + obj->disconnect(); | |
| 609 | + } | |
| 610 | + } | |
| 611 | + } | |
| 612 | + } | |
| 613 | + break; | |
| 614 | + case ::ot_dictionary: | |
| 615 | + for (auto& iter: std::get<QPDF_Dictionary>(value).items) { | |
| 616 | + QPDFObjectHandle::DisconnectAccess::disconnect(iter.second); | |
| 617 | + } | |
| 618 | + break; | |
| 619 | + case ::ot_stream: | |
| 620 | + { | |
| 621 | + auto& s = std::get<QPDF_Stream>(value); | |
| 622 | + s.m->stream_provider = nullptr; | |
| 623 | + QPDFObjectHandle::DisconnectAccess::disconnect(s.m->stream_dict); | |
| 624 | + } | |
| 625 | + break; | |
| 626 | + default: | |
| 627 | + break; | |
| 628 | + } | |
| 629 | + qpdf = nullptr; | |
| 630 | + og = QPDFObjGen(); | |
| 631 | +} | |
| 632 | +std::string | |
| 633 | +QPDFObject::getStringValue() const | |
| 634 | +{ | |
| 635 | + switch (getResolvedTypeCode()) { | |
| 636 | + case ::ot_real: | |
| 637 | + return std::get<QPDF_Real>(value).val; | |
| 638 | + case ::ot_string: | |
| 639 | + return std::get<QPDF_String>(value).val; | |
| 640 | + case ::ot_name: | |
| 641 | + return std::get<QPDF_Name>(value).name; | |
| 642 | + case ::ot_operator: | |
| 643 | + return std::get<QPDF_Operator>(value).val; | |
| 644 | + case ::ot_inlineimage: | |
| 645 | + return std::get<QPDF_InlineImage>(value).val; | |
| 646 | + case ::ot_reference: | |
| 647 | + return std::get<QPDF_Reference>(value).obj->getStringValue(); | |
| 648 | + default: | |
| 649 | + throw std::logic_error("Internal error in QPDFObject::getStringValue"); | |
| 650 | + return ""; // does not return | |
| 651 | + } | |
| 652 | + return {}; // does not return | |
| 653 | +} | |
| 654 | + | |
| 231 | 655 | bool |
| 232 | 656 | QPDFObjectHandle::isSameObjectAs(QPDFObjectHandle const& rhs) const |
| 233 | 657 | { |
| ... | ... | @@ -253,7 +677,7 @@ QPDFObjectHandle::getTypeCode() const |
| 253 | 677 | char const* |
| 254 | 678 | QPDFObjectHandle::getTypeName() const |
| 255 | 679 | { |
| 256 | - static constexpr std::array<char const*, 15> tn{ | |
| 680 | + static constexpr std::array<char const*, 16> tn{ | |
| 257 | 681 | "uninitialized", |
| 258 | 682 | "reserved", |
| 259 | 683 | "null", |
| ... | ... | @@ -268,84 +692,23 @@ QPDFObjectHandle::getTypeName() const |
| 268 | 692 | "operator", |
| 269 | 693 | "inline-image", |
| 270 | 694 | "unresolved", |
| 271 | - "destroyed"}; | |
| 695 | + "destroyed", | |
| 696 | + "reference"}; | |
| 272 | 697 | return obj ? tn[getTypeCode()] : "uninitialized"; |
| 273 | 698 | } |
| 274 | 699 | |
| 275 | -QPDF_Array* | |
| 276 | -QPDFObjectHandle::asArray() const | |
| 277 | -{ | |
| 278 | - return obj ? obj->as<QPDF_Array>() : nullptr; | |
| 279 | -} | |
| 280 | - | |
| 281 | 700 | QPDF_Bool* |
| 282 | 701 | QPDFObjectHandle::asBool() const |
| 283 | 702 | { |
| 284 | 703 | return obj ? obj->as<QPDF_Bool>() : nullptr; |
| 285 | 704 | } |
| 286 | 705 | |
| 287 | -QPDF_Dictionary* | |
| 288 | -QPDFObjectHandle::asDictionary() const | |
| 289 | -{ | |
| 290 | - return obj ? obj->as<QPDF_Dictionary>() : nullptr; | |
| 291 | -} | |
| 292 | - | |
| 293 | -QPDF_InlineImage* | |
| 294 | -QPDFObjectHandle::asInlineImage() const | |
| 295 | -{ | |
| 296 | - return obj ? obj->as<QPDF_InlineImage>() : nullptr; | |
| 297 | -} | |
| 298 | - | |
| 299 | 706 | QPDF_Integer* |
| 300 | 707 | QPDFObjectHandle::asInteger() const |
| 301 | 708 | { |
| 302 | 709 | return obj ? obj->as<QPDF_Integer>() : nullptr; |
| 303 | 710 | } |
| 304 | 711 | |
| 305 | -QPDF_Name* | |
| 306 | -QPDFObjectHandle::asName() const | |
| 307 | -{ | |
| 308 | - return obj ? obj->as<QPDF_Name>() : nullptr; | |
| 309 | -} | |
| 310 | - | |
| 311 | -QPDF_Null* | |
| 312 | -QPDFObjectHandle::asNull() const | |
| 313 | -{ | |
| 314 | - return obj ? obj->as<QPDF_Null>() : nullptr; | |
| 315 | -} | |
| 316 | - | |
| 317 | -QPDF_Operator* | |
| 318 | -QPDFObjectHandle::asOperator() const | |
| 319 | -{ | |
| 320 | - return obj ? obj->as<QPDF_Operator>() : nullptr; | |
| 321 | -} | |
| 322 | - | |
| 323 | -QPDF_Real* | |
| 324 | -QPDFObjectHandle::asReal() const | |
| 325 | -{ | |
| 326 | - return obj ? obj->as<QPDF_Real>() : nullptr; | |
| 327 | -} | |
| 328 | - | |
| 329 | -QPDF_Reserved* | |
| 330 | -QPDFObjectHandle::asReserved() const | |
| 331 | -{ | |
| 332 | - return obj ? obj->as<QPDF_Reserved>() : nullptr; | |
| 333 | -} | |
| 334 | - | |
| 335 | -QPDF_Stream* | |
| 336 | -QPDFObjectHandle::asStream() const | |
| 337 | -{ | |
| 338 | - return obj ? obj->as<QPDF_Stream>() : nullptr; | |
| 339 | -} | |
| 340 | - | |
| 341 | -QPDF_Stream* | |
| 342 | -QPDFObjectHandle::asStreamWithAssert() const | |
| 343 | -{ | |
| 344 | - auto stream = asStream(); | |
| 345 | - assertType("stream", stream); | |
| 346 | - return stream; | |
| 347 | -} | |
| 348 | - | |
| 349 | 712 | QPDF_String* |
| 350 | 713 | QPDFObjectHandle::asString() const |
| 351 | 714 | { |
| ... | ... | @@ -500,7 +863,7 @@ QPDFObjectHandle::getBoolValue() const |
| 500 | 863 | { |
| 501 | 864 | auto boolean = asBool(); |
| 502 | 865 | if (boolean) { |
| 503 | - return boolean->getVal(); | |
| 866 | + return boolean->val; | |
| 504 | 867 | } else { |
| 505 | 868 | typeWarning("boolean", "returning false"); |
| 506 | 869 | QTC::TC("qpdf", "QPDFObjectHandle boolean returning false"); |
| ... | ... | @@ -515,7 +878,7 @@ QPDFObjectHandle::getValueAsBool(bool& value) const |
| 515 | 878 | if (boolean == nullptr) { |
| 516 | 879 | return false; |
| 517 | 880 | } |
| 518 | - value = boolean->getVal(); | |
| 881 | + value = boolean->val; | |
| 519 | 882 | return true; |
| 520 | 883 | } |
| 521 | 884 | |
| ... | ... | @@ -526,7 +889,7 @@ QPDFObjectHandle::getIntValue() const |
| 526 | 889 | { |
| 527 | 890 | auto integer = asInteger(); |
| 528 | 891 | if (integer) { |
| 529 | - return integer->getVal(); | |
| 892 | + return integer->val; | |
| 530 | 893 | } else { |
| 531 | 894 | typeWarning("integer", "returning 0"); |
| 532 | 895 | QTC::TC("qpdf", "QPDFObjectHandle integer returning 0"); |
| ... | ... | @@ -541,7 +904,7 @@ QPDFObjectHandle::getValueAsInt(long long& value) const |
| 541 | 904 | if (integer == nullptr) { |
| 542 | 905 | return false; |
| 543 | 906 | } |
| 544 | - value = integer->getVal(); | |
| 907 | + value = integer->val; | |
| 545 | 908 | return true; |
| 546 | 909 | } |
| 547 | 910 | |
| ... | ... | @@ -1155,7 +1518,7 @@ QPDFObjectHandle::writeJSON(int json_version, JSON::Writer& p, bool dereference_ |
| 1155 | 1518 | } else if (!obj) { |
| 1156 | 1519 | throw std::logic_error("attempted to dereference an uninitialized QPDFObjectHandle"); |
| 1157 | 1520 | } else { |
| 1158 | - obj->writeJSON(json_version, p); | |
| 1521 | + obj->write_json(json_version, p); | |
| 1159 | 1522 | } |
| 1160 | 1523 | } |
| 1161 | 1524 | |
| ... | ... | @@ -1392,43 +1755,43 @@ QPDFObjectHandle::getParsedOffset() const |
| 1392 | 1755 | QPDFObjectHandle |
| 1393 | 1756 | QPDFObjectHandle::newBool(bool value) |
| 1394 | 1757 | { |
| 1395 | - return {QPDF_Bool::create(value)}; | |
| 1758 | + return {QPDFObject::create<QPDF_Bool>(value)}; | |
| 1396 | 1759 | } |
| 1397 | 1760 | |
| 1398 | 1761 | QPDFObjectHandle |
| 1399 | 1762 | QPDFObjectHandle::newNull() |
| 1400 | 1763 | { |
| 1401 | - return {QPDF_Null::create()}; | |
| 1764 | + return {QPDFObject::create<QPDF_Null>()}; | |
| 1402 | 1765 | } |
| 1403 | 1766 | |
| 1404 | 1767 | QPDFObjectHandle |
| 1405 | 1768 | QPDFObjectHandle::newInteger(long long value) |
| 1406 | 1769 | { |
| 1407 | - return {QPDF_Integer::create(value)}; | |
| 1770 | + return {QPDFObject::create<QPDF_Integer>(value)}; | |
| 1408 | 1771 | } |
| 1409 | 1772 | |
| 1410 | 1773 | QPDFObjectHandle |
| 1411 | 1774 | QPDFObjectHandle::newReal(std::string const& value) |
| 1412 | 1775 | { |
| 1413 | - return {QPDF_Real::create(value)}; | |
| 1776 | + return {QPDFObject::create<QPDF_Real>(value)}; | |
| 1414 | 1777 | } |
| 1415 | 1778 | |
| 1416 | 1779 | QPDFObjectHandle |
| 1417 | 1780 | QPDFObjectHandle::newReal(double value, int decimal_places, bool trim_trailing_zeroes) |
| 1418 | 1781 | { |
| 1419 | - return {QPDF_Real::create(value, decimal_places, trim_trailing_zeroes)}; | |
| 1782 | + return {QPDFObject::create<QPDF_Real>(value, decimal_places, trim_trailing_zeroes)}; | |
| 1420 | 1783 | } |
| 1421 | 1784 | |
| 1422 | 1785 | QPDFObjectHandle |
| 1423 | 1786 | QPDFObjectHandle::newName(std::string const& name) |
| 1424 | 1787 | { |
| 1425 | - return {QPDF_Name::create(name)}; | |
| 1788 | + return {QPDFObject::create<QPDF_Name>(name)}; | |
| 1426 | 1789 | } |
| 1427 | 1790 | |
| 1428 | 1791 | QPDFObjectHandle |
| 1429 | 1792 | QPDFObjectHandle::newString(std::string const& str) |
| 1430 | 1793 | { |
| 1431 | - return {QPDF_String::create(str)}; | |
| 1794 | + return {QPDFObject::create<QPDF_String>(str)}; | |
| 1432 | 1795 | } |
| 1433 | 1796 | |
| 1434 | 1797 | QPDFObjectHandle |
| ... | ... | @@ -1440,13 +1803,13 @@ QPDFObjectHandle::newUnicodeString(std::string const& utf8_str) |
| 1440 | 1803 | QPDFObjectHandle |
| 1441 | 1804 | QPDFObjectHandle::newOperator(std::string const& value) |
| 1442 | 1805 | { |
| 1443 | - return {QPDF_Operator::create(value)}; | |
| 1806 | + return {QPDFObject::create<QPDF_Operator>(value)}; | |
| 1444 | 1807 | } |
| 1445 | 1808 | |
| 1446 | 1809 | QPDFObjectHandle |
| 1447 | 1810 | QPDFObjectHandle::newInlineImage(std::string const& value) |
| 1448 | 1811 | { |
| 1449 | - return {QPDF_InlineImage::create(value)}; | |
| 1812 | + return {QPDFObject::create<QPDF_InlineImage>(value)}; | |
| 1450 | 1813 | } |
| 1451 | 1814 | |
| 1452 | 1815 | QPDFObjectHandle |
| ... | ... | @@ -1458,7 +1821,7 @@ QPDFObjectHandle::newArray() |
| 1458 | 1821 | QPDFObjectHandle |
| 1459 | 1822 | QPDFObjectHandle::newArray(std::vector<QPDFObjectHandle> const& items) |
| 1460 | 1823 | { |
| 1461 | - return {QPDF_Array::create(items)}; | |
| 1824 | + return {QPDFObject::create<QPDF_Array>(items)}; | |
| 1462 | 1825 | } |
| 1463 | 1826 | |
| 1464 | 1827 | QPDFObjectHandle |
| ... | ... | @@ -1518,7 +1881,7 @@ QPDFObjectHandle::newDictionary() |
| 1518 | 1881 | QPDFObjectHandle |
| 1519 | 1882 | QPDFObjectHandle::newDictionary(std::map<std::string, QPDFObjectHandle> const& items) |
| 1520 | 1883 | { |
| 1521 | - return {QPDF_Dictionary::create(items)}; | |
| 1884 | + return {QPDFObject::create<QPDF_Dictionary>(items)}; | |
| 1522 | 1885 | } |
| 1523 | 1886 | |
| 1524 | 1887 | QPDFObjectHandle |
| ... | ... | @@ -1564,7 +1927,7 @@ void |
| 1564 | 1927 | QPDFObjectHandle::setObjectDescription(QPDF* owning_qpdf, std::string const& object_description) |
| 1565 | 1928 | { |
| 1566 | 1929 | if (obj) { |
| 1567 | - auto descr = std::make_shared<QPDFValue::Description>(object_description); | |
| 1930 | + auto descr = std::make_shared<QPDFObject::Description>(object_description); | |
| 1568 | 1931 | obj->setDescription(owning_qpdf, descr); |
| 1569 | 1932 | } |
| 1570 | 1933 | } |
| ... | ... | @@ -1614,7 +1977,7 @@ QPDFObjectHandle::makeDirect(QPDFObjGen::set& visited, bool stop_at_streams) |
| 1614 | 1977 | items.emplace_back(array.at(i).second); |
| 1615 | 1978 | items.back().makeDirect(visited, stop_at_streams); |
| 1616 | 1979 | } |
| 1617 | - this->obj = QPDF_Array::create(items); | |
| 1980 | + this->obj = QPDFObject::create<QPDF_Array>(items); | |
| 1618 | 1981 | } else if (isDictionary()) { |
| 1619 | 1982 | std::map<std::string, QPDFObjectHandle> items; |
| 1620 | 1983 | auto dict = as_dictionary(strict); |
| ... | ... | @@ -1622,7 +1985,7 @@ QPDFObjectHandle::makeDirect(QPDFObjGen::set& visited, bool stop_at_streams) |
| 1622 | 1985 | items[key] = dict.getKey(key); |
| 1623 | 1986 | items[key].makeDirect(visited, stop_at_streams); |
| 1624 | 1987 | } |
| 1625 | - this->obj = QPDF_Dictionary::create(items); | |
| 1988 | + this->obj = QPDFObject::create<QPDF_Dictionary>(items); | |
| 1626 | 1989 | } else if (isStream()) { |
| 1627 | 1990 | QTC::TC("qpdf", "QPDFObjectHandle copy stream", stop_at_streams ? 0 : 1); |
| 1628 | 1991 | if (!stop_at_streams) { | ... | ... |
libqpdf/QPDFParser.cc
| ... | ... | @@ -4,18 +4,6 @@ |
| 4 | 4 | #include <qpdf/QPDFObjGen.hh> |
| 5 | 5 | #include <qpdf/QPDFObjectHandle.hh> |
| 6 | 6 | #include <qpdf/QPDFObject_private.hh> |
| 7 | -#include <qpdf/QPDF_Array.hh> | |
| 8 | -#include <qpdf/QPDF_Bool.hh> | |
| 9 | -#include <qpdf/QPDF_Dictionary.hh> | |
| 10 | -#include <qpdf/QPDF_InlineImage.hh> | |
| 11 | -#include <qpdf/QPDF_Integer.hh> | |
| 12 | -#include <qpdf/QPDF_Name.hh> | |
| 13 | -#include <qpdf/QPDF_Null.hh> | |
| 14 | -#include <qpdf/QPDF_Operator.hh> | |
| 15 | -#include <qpdf/QPDF_Real.hh> | |
| 16 | -#include <qpdf/QPDF_Reserved.hh> | |
| 17 | -#include <qpdf/QPDF_Stream.hh> | |
| 18 | -#include <qpdf/QPDF_String.hh> | |
| 19 | 7 | #include <qpdf/QTC.hh> |
| 20 | 8 | #include <qpdf/QUtil.hh> |
| 21 | 9 | |
| ... | ... | @@ -47,27 +35,27 @@ QPDFParser::parse(bool& empty, bool content_stream) |
| 47 | 35 | } |
| 48 | 36 | QTC::TC("qpdf", "QPDFParser eof in parse"); |
| 49 | 37 | warn("unexpected EOF"); |
| 50 | - return {QPDF_Null::create()}; | |
| 38 | + return {QPDFObject::create<QPDF_Null>()}; | |
| 51 | 39 | |
| 52 | 40 | case QPDFTokenizer::tt_bad: |
| 53 | 41 | QTC::TC("qpdf", "QPDFParser bad token in parse"); |
| 54 | - return {QPDF_Null::create()}; | |
| 42 | + return {QPDFObject::create<QPDF_Null>()}; | |
| 55 | 43 | |
| 56 | 44 | case QPDFTokenizer::tt_brace_open: |
| 57 | 45 | case QPDFTokenizer::tt_brace_close: |
| 58 | 46 | QTC::TC("qpdf", "QPDFParser bad brace"); |
| 59 | 47 | warn("treating unexpected brace token as null"); |
| 60 | - return {QPDF_Null::create()}; | |
| 48 | + return {QPDFObject::create<QPDF_Null>()}; | |
| 61 | 49 | |
| 62 | 50 | case QPDFTokenizer::tt_array_close: |
| 63 | 51 | QTC::TC("qpdf", "QPDFParser bad array close"); |
| 64 | 52 | warn("treating unexpected array close token as null"); |
| 65 | - return {QPDF_Null::create()}; | |
| 53 | + return {QPDFObject::create<QPDF_Null>()}; | |
| 66 | 54 | |
| 67 | 55 | case QPDFTokenizer::tt_dict_close: |
| 68 | 56 | QTC::TC("qpdf", "QPDFParser bad dictionary close"); |
| 69 | 57 | warn("unexpected dictionary close token"); |
| 70 | - return {QPDF_Null::create()}; | |
| 58 | + return {QPDFObject::create<QPDF_Null>()}; | |
| 71 | 59 | |
| 72 | 60 | case QPDFTokenizer::tt_array_open: |
| 73 | 61 | case QPDFTokenizer::tt_dict_open: |
| ... | ... | @@ -82,7 +70,7 @@ QPDFParser::parse(bool& empty, bool content_stream) |
| 82 | 70 | return withDescription<QPDF_Bool>(tokenizer.getValue() == "true"); |
| 83 | 71 | |
| 84 | 72 | case QPDFTokenizer::tt_null: |
| 85 | - return {QPDF_Null::create()}; | |
| 73 | + return {QPDFObject::create<QPDF_Null>()}; | |
| 86 | 74 | |
| 87 | 75 | case QPDFTokenizer::tt_integer: |
| 88 | 76 | return withDescription<QPDF_Integer>(QUtil::string_to_ll(tokenizer.getValue().c_str())); |
| ... | ... | @@ -103,7 +91,7 @@ QPDFParser::parse(bool& empty, bool content_stream) |
| 103 | 91 | // not move the input source's offset. |
| 104 | 92 | input.seek(input.getLastOffset(), SEEK_SET); |
| 105 | 93 | empty = true; |
| 106 | - return {QPDF_Null::create()}; | |
| 94 | + return {QPDFObject::create<QPDF_Null>()}; | |
| 107 | 95 | } else { |
| 108 | 96 | QTC::TC("qpdf", "QPDFParser treat word as string"); |
| 109 | 97 | warn("unknown token while reading object; treating as string"); |
| ... | ... | @@ -122,7 +110,7 @@ QPDFParser::parse(bool& empty, bool content_stream) |
| 122 | 110 | |
| 123 | 111 | default: |
| 124 | 112 | warn("treating unknown token type as null while reading object"); |
| 125 | - return {QPDF_Null::create()}; | |
| 113 | + return {QPDFObject::create<QPDF_Null>()}; | |
| 126 | 114 | } |
| 127 | 115 | } |
| 128 | 116 | |
| ... | ... | @@ -194,12 +182,12 @@ QPDFParser::parseRemainder(bool content_stream) |
| 194 | 182 | } |
| 195 | 183 | QTC::TC("qpdf", "QPDFParser eof in parseRemainder"); |
| 196 | 184 | warn("unexpected EOF"); |
| 197 | - return {QPDF_Null::create()}; | |
| 185 | + return {QPDFObject::create<QPDF_Null>()}; | |
| 198 | 186 | |
| 199 | 187 | case QPDFTokenizer::tt_bad: |
| 200 | 188 | QTC::TC("qpdf", "QPDFParser bad token in parseRemainder"); |
| 201 | 189 | if (tooManyBadTokens()) { |
| 202 | - return {QPDF_Null::create()}; | |
| 190 | + return {QPDFObject::create<QPDF_Null>()}; | |
| 203 | 191 | } |
| 204 | 192 | addNull(); |
| 205 | 193 | continue; |
| ... | ... | @@ -209,7 +197,7 @@ QPDFParser::parseRemainder(bool content_stream) |
| 209 | 197 | QTC::TC("qpdf", "QPDFParser bad brace in parseRemainder"); |
| 210 | 198 | warn("treating unexpected brace token as null"); |
| 211 | 199 | if (tooManyBadTokens()) { |
| 212 | - return {QPDF_Null::create()}; | |
| 200 | + return {QPDFObject::create<QPDF_Null>()}; | |
| 213 | 201 | } |
| 214 | 202 | addNull(); |
| 215 | 203 | continue; |
| ... | ... | @@ -218,10 +206,11 @@ QPDFParser::parseRemainder(bool content_stream) |
| 218 | 206 | if (bad_count && !max_bad_count) { |
| 219 | 207 | // Trigger warning. |
| 220 | 208 | (void)tooManyBadTokens(); |
| 221 | - return {QPDF_Null::create()}; | |
| 209 | + return {QPDFObject::create<QPDF_Null>()}; | |
| 222 | 210 | } |
| 223 | 211 | if (frame->state == st_array) { |
| 224 | - auto object = QPDF_Array::create(std::move(frame->olist), frame->null_count > 100); | |
| 212 | + auto object = QPDFObject::create<QPDF_Array>( | |
| 213 | + std::move(frame->olist), frame->null_count > 100); | |
| 225 | 214 | setDescription(object, frame->offset - 1); |
| 226 | 215 | // The `offset` points to the next of "[". Set the rewind offset to point to the |
| 227 | 216 | // beginning of "[". This has been explicitly tested with whitespace surrounding the |
| ... | ... | @@ -237,7 +226,7 @@ QPDFParser::parseRemainder(bool content_stream) |
| 237 | 226 | QTC::TC("qpdf", "QPDFParser bad array close in parseRemainder"); |
| 238 | 227 | warn("treating unexpected array close token as null"); |
| 239 | 228 | if (tooManyBadTokens()) { |
| 240 | - return {QPDF_Null::create()}; | |
| 229 | + return {QPDFObject::create<QPDF_Null>()}; | |
| 241 | 230 | } |
| 242 | 231 | addNull(); |
| 243 | 232 | } |
| ... | ... | @@ -247,7 +236,7 @@ QPDFParser::parseRemainder(bool content_stream) |
| 247 | 236 | if (bad_count && !max_bad_count) { |
| 248 | 237 | // Trigger warning. |
| 249 | 238 | (void)tooManyBadTokens(); |
| 250 | - return {QPDF_Null::create()}; | |
| 239 | + return {QPDFObject::create<QPDF_Null>()}; | |
| 251 | 240 | } |
| 252 | 241 | if (frame->state <= st_dictionary_value) { |
| 253 | 242 | // Attempt to recover more or less gracefully from invalid dictionaries. |
| ... | ... | @@ -258,7 +247,7 @@ QPDFParser::parseRemainder(bool content_stream) |
| 258 | 247 | warn( |
| 259 | 248 | frame->offset, |
| 260 | 249 | "dictionary ended prematurely; using null as value for last key"); |
| 261 | - dict[frame->key] = QPDF_Null::create(); | |
| 250 | + dict[frame->key] = QPDFObject::create<QPDF_Null>(); | |
| 262 | 251 | } |
| 263 | 252 | |
| 264 | 253 | if (!frame->olist.empty()) { |
| ... | ... | @@ -271,7 +260,7 @@ QPDFParser::parseRemainder(bool content_stream) |
| 271 | 260 | dict["/Contents"] = QPDFObjectHandle::newString(frame->contents_string); |
| 272 | 261 | dict["/Contents"].setParsedOffset(frame->contents_offset); |
| 273 | 262 | } |
| 274 | - auto object = QPDF_Dictionary::create(std::move(dict)); | |
| 263 | + auto object = QPDFObject::create<QPDF_Dictionary>(std::move(dict)); | |
| 275 | 264 | setDescription(object, frame->offset - 2); |
| 276 | 265 | // The `offset` points to the next of "<<". Set the rewind offset to point to the |
| 277 | 266 | // beginning of "<<". This has been explicitly tested with whitespace surrounding |
| ... | ... | @@ -287,7 +276,7 @@ QPDFParser::parseRemainder(bool content_stream) |
| 287 | 276 | QTC::TC("qpdf", "QPDFParser bad dictionary close in parseRemainder"); |
| 288 | 277 | warn("unexpected dictionary close token"); |
| 289 | 278 | if (tooManyBadTokens()) { |
| 290 | - return {QPDF_Null::create()}; | |
| 279 | + return {QPDFObject::create<QPDF_Null>()}; | |
| 291 | 280 | } |
| 292 | 281 | addNull(); |
| 293 | 282 | } |
| ... | ... | @@ -298,7 +287,7 @@ QPDFParser::parseRemainder(bool content_stream) |
| 298 | 287 | if (stack.size() > 499) { |
| 299 | 288 | QTC::TC("qpdf", "QPDFParser too deep"); |
| 300 | 289 | warn("ignoring excessively deeply nested data structure"); |
| 301 | - return {QPDF_Null::create()}; | |
| 290 | + return {QPDFObject::create<QPDF_Null>()}; | |
| 302 | 291 | } else { |
| 303 | 292 | b_contents = false; |
| 304 | 293 | stack.emplace_back( |
| ... | ... | @@ -350,7 +339,7 @@ QPDFParser::parseRemainder(bool content_stream) |
| 350 | 339 | QTC::TC("qpdf", "QPDFParser treat word as string in parseRemainder"); |
| 351 | 340 | warn("unknown token while reading object; treating as string"); |
| 352 | 341 | if (tooManyBadTokens()) { |
| 353 | - return {QPDF_Null::create()}; | |
| 342 | + return {QPDFObject::create<QPDF_Null>()}; | |
| 354 | 343 | } |
| 355 | 344 | addScalar<QPDF_String>(tokenizer.getValue()); |
| 356 | 345 | } |
| ... | ... | @@ -377,7 +366,7 @@ QPDFParser::parseRemainder(bool content_stream) |
| 377 | 366 | default: |
| 378 | 367 | warn("treating unknown token type as null while reading object"); |
| 379 | 368 | if (tooManyBadTokens()) { |
| 380 | - return {QPDF_Null::create()}; | |
| 369 | + return {QPDFObject::create<QPDF_Null>()}; | |
| 381 | 370 | } |
| 382 | 371 | addNull(); |
| 383 | 372 | } |
| ... | ... | @@ -402,7 +391,7 @@ QPDFParser::add(std::shared_ptr<QPDFObject>&& obj) |
| 402 | 391 | void |
| 403 | 392 | QPDFParser::addNull() |
| 404 | 393 | { |
| 405 | - const static ObjectPtr null_obj = QPDF_Null::create(); | |
| 394 | + const static ObjectPtr null_obj = QPDFObject::create<QPDF_Null>(); | |
| 406 | 395 | |
| 407 | 396 | if (frame->state != st_dictionary_value) { |
| 408 | 397 | // If state is st_dictionary_key then there is a missing key. Push onto olist for |
| ... | ... | @@ -420,7 +409,7 @@ QPDFParser::addNull() |
| 420 | 409 | void |
| 421 | 410 | QPDFParser::addInt(int count) |
| 422 | 411 | { |
| 423 | - auto obj = QPDF_Integer::create(int_buffer[count % 2]); | |
| 412 | + auto obj = QPDFObject::create<QPDF_Integer>(int_buffer[count % 2]); | |
| 424 | 413 | obj->setDescription(context, description, last_offset_buffer[count % 2]); |
| 425 | 414 | add(std::move(obj)); |
| 426 | 415 | } |
| ... | ... | @@ -435,7 +424,7 @@ QPDFParser::addScalar(Args&&... args) |
| 435 | 424 | max_bad_count = 0; |
| 436 | 425 | return; |
| 437 | 426 | } |
| 438 | - auto obj = T::create(args...); | |
| 427 | + auto obj = QPDFObject::create<T>(std::forward<Args>(args)...); | |
| 439 | 428 | obj->setDescription(context, description, input.getLastOffset()); |
| 440 | 429 | add(std::move(obj)); |
| 441 | 430 | } |
| ... | ... | @@ -444,7 +433,7 @@ template <typename T, typename... Args> |
| 444 | 433 | QPDFObjectHandle |
| 445 | 434 | QPDFParser::withDescription(Args&&... args) |
| 446 | 435 | { |
| 447 | - auto obj = T::create(args...); | |
| 436 | + auto obj = QPDFObject::create<T>(std::forward<Args>(args)...); | |
| 448 | 437 | obj->setDescription(context, description, start); |
| 449 | 438 | return {obj}; |
| 450 | 439 | } | ... | ... |
libqpdf/QPDFValue.cc deleted
| 1 | -#include <qpdf/QPDFValue.hh> | |
| 2 | - | |
| 3 | -#include <qpdf/QPDFObject_private.hh> | |
| 4 | - | |
| 5 | -std::shared_ptr<QPDFObject> | |
| 6 | -QPDFValue::do_create(QPDFValue* object) | |
| 7 | -{ | |
| 8 | - std::shared_ptr<QPDFObject> obj(new QPDFObject()); | |
| 9 | - obj->value = std::shared_ptr<QPDFValue>(object); | |
| 10 | - return obj; | |
| 11 | -} | |
| 12 | - | |
| 13 | -std::string | |
| 14 | -QPDFValue::getDescription() | |
| 15 | -{ | |
| 16 | - if (object_description) { | |
| 17 | - switch (object_description->index()) { | |
| 18 | - case 0: | |
| 19 | - { | |
| 20 | - // Simple template string | |
| 21 | - auto description = std::get<0>(*object_description); | |
| 22 | - | |
| 23 | - if (auto pos = description.find("$OG"); pos != std::string::npos) { | |
| 24 | - description.replace(pos, 3, og.unparse(' ')); | |
| 25 | - } | |
| 26 | - if (auto pos = description.find("$PO"); pos != std::string::npos) { | |
| 27 | - qpdf_offset_t shift = (type_code == ::ot_dictionary) ? 2 | |
| 28 | - : (type_code == ::ot_array) ? 1 | |
| 29 | - : 0; | |
| 30 | - | |
| 31 | - description.replace(pos, 3, std::to_string(parsed_offset + shift)); | |
| 32 | - } | |
| 33 | - return description; | |
| 34 | - } | |
| 35 | - case 1: | |
| 36 | - { | |
| 37 | - // QPDF::JSONReactor generated description | |
| 38 | - auto j_descr = std::get<1>(*object_description); | |
| 39 | - return ( | |
| 40 | - *j_descr.input + (j_descr.object.empty() ? "" : ", " + j_descr.object) + | |
| 41 | - " at offset " + std::to_string(parsed_offset)); | |
| 42 | - } | |
| 43 | - case 2: | |
| 44 | - { | |
| 45 | - // Child object description | |
| 46 | - auto j_descr = std::get<2>(*object_description); | |
| 47 | - std::string result; | |
| 48 | - if (auto p = j_descr.parent.lock()) { | |
| 49 | - result = p->getDescription(); | |
| 50 | - } | |
| 51 | - result += j_descr.static_descr; | |
| 52 | - if (auto pos = result.find("$VD"); pos != std::string::npos) { | |
| 53 | - result.replace(pos, 3, j_descr.var_descr); | |
| 54 | - } | |
| 55 | - return result; | |
| 56 | - } | |
| 57 | - } | |
| 58 | - } else if (og.isIndirect()) { | |
| 59 | - return "object " + og.unparse(' '); | |
| 60 | - } | |
| 61 | - return {}; | |
| 62 | -} |
libqpdf/QPDFWriter.cc
| ... | ... | @@ -16,8 +16,7 @@ |
| 16 | 16 | #include <qpdf/QIntC.hh> |
| 17 | 17 | #include <qpdf/QPDF.hh> |
| 18 | 18 | #include <qpdf/QPDFObjectHandle_private.hh> |
| 19 | -#include <qpdf/QPDF_Name.hh> | |
| 20 | -#include <qpdf/QPDF_String.hh> | |
| 19 | +#include <qpdf/QPDFObject_private.hh> | |
| 21 | 20 | #include <qpdf/QTC.hh> |
| 22 | 21 | #include <qpdf/QUtil.hh> |
| 23 | 22 | #include <qpdf/RC4.hh> | ... | ... |
libqpdf/QPDF_Array.cc
| 1 | -#include <qpdf/QPDF_Array.hh> | |
| 2 | - | |
| 3 | -#include <qpdf/JSON_writer.hh> | |
| 4 | 1 | #include <qpdf/QPDFObjectHandle_private.hh> |
| 5 | -#include <qpdf/QPDFObject_private.hh> | |
| 6 | -#include <qpdf/QPDF_Null.hh> | |
| 2 | + | |
| 7 | 3 | #include <qpdf/QTC.hh> |
| 8 | 4 | |
| 9 | 5 | using namespace std::literals; |
| ... | ... | @@ -40,25 +36,12 @@ Array::checkOwnership(QPDFObjectHandle const& item) const |
| 40 | 36 | } |
| 41 | 37 | } |
| 42 | 38 | |
| 43 | -QPDF_Array::QPDF_Array() : | |
| 44 | - QPDFValue(::ot_array) | |
| 45 | -{ | |
| 46 | -} | |
| 47 | - | |
| 48 | -QPDF_Array::QPDF_Array(QPDF_Array const& other) : | |
| 49 | - QPDFValue(::ot_array), | |
| 50 | - sp(other.sp ? std::make_unique<Sparse>(*other.sp) : nullptr) | |
| 51 | -{ | |
| 52 | -} | |
| 53 | - | |
| 54 | -QPDF_Array::QPDF_Array(std::vector<QPDFObjectHandle> const& v) : | |
| 55 | - QPDFValue(::ot_array) | |
| 39 | +QPDF_Array::QPDF_Array(std::vector<QPDFObjectHandle> const& v) | |
| 56 | 40 | { |
| 57 | 41 | setFromVector(v); |
| 58 | 42 | } |
| 59 | 43 | |
| 60 | -QPDF_Array::QPDF_Array(std::vector<std::shared_ptr<QPDFObject>>&& v, bool sparse) : | |
| 61 | - QPDFValue(::ot_array) | |
| 44 | +QPDF_Array::QPDF_Array(std::vector<std::shared_ptr<QPDFObject>>&& v, bool sparse) | |
| 62 | 45 | { |
| 63 | 46 | if (sparse) { |
| 64 | 47 | sp = std::make_unique<Sparse>(); |
| ... | ... | @@ -73,132 +56,6 @@ QPDF_Array::QPDF_Array(std::vector<std::shared_ptr<QPDFObject>>&& v, bool sparse |
| 73 | 56 | } |
| 74 | 57 | } |
| 75 | 58 | |
| 76 | -std::shared_ptr<QPDFObject> | |
| 77 | -QPDF_Array::create(std::vector<QPDFObjectHandle> const& items) | |
| 78 | -{ | |
| 79 | - return do_create(new QPDF_Array(items)); | |
| 80 | -} | |
| 81 | - | |
| 82 | -std::shared_ptr<QPDFObject> | |
| 83 | -QPDF_Array::create(std::vector<std::shared_ptr<QPDFObject>>&& items, bool sparse) | |
| 84 | -{ | |
| 85 | - return do_create(new QPDF_Array(std::move(items), sparse)); | |
| 86 | -} | |
| 87 | - | |
| 88 | -std::shared_ptr<QPDFObject> | |
| 89 | -QPDF_Array::copy(bool shallow) | |
| 90 | -{ | |
| 91 | - if (shallow) { | |
| 92 | - return do_create(new QPDF_Array(*this)); | |
| 93 | - } else { | |
| 94 | - QTC::TC("qpdf", "QPDF_Array copy", sp ? 0 : 1); | |
| 95 | - if (sp) { | |
| 96 | - auto* result = new QPDF_Array(); | |
| 97 | - result->sp = std::make_unique<Sparse>(); | |
| 98 | - result->sp->size = sp->size; | |
| 99 | - for (auto const& element: sp->elements) { | |
| 100 | - auto const& obj = element.second; | |
| 101 | - result->sp->elements[element.first] = | |
| 102 | - obj->getObjGen().isIndirect() ? obj : obj->copy(); | |
| 103 | - } | |
| 104 | - return do_create(result); | |
| 105 | - } else { | |
| 106 | - std::vector<std::shared_ptr<QPDFObject>> result; | |
| 107 | - result.reserve(elements.size()); | |
| 108 | - for (auto const& element: elements) { | |
| 109 | - result.push_back( | |
| 110 | - element ? (element->getObjGen().isIndirect() ? element : element->copy()) | |
| 111 | - : element); | |
| 112 | - } | |
| 113 | - return create(std::move(result), false); | |
| 114 | - } | |
| 115 | - } | |
| 116 | -} | |
| 117 | - | |
| 118 | -void | |
| 119 | -QPDF_Array::disconnect() | |
| 120 | -{ | |
| 121 | - if (sp) { | |
| 122 | - for (auto& item: sp->elements) { | |
| 123 | - auto& obj = item.second; | |
| 124 | - if (!obj->getObjGen().isIndirect()) { | |
| 125 | - obj->disconnect(); | |
| 126 | - } | |
| 127 | - } | |
| 128 | - } else { | |
| 129 | - for (auto& obj: elements) { | |
| 130 | - if (!obj->getObjGen().isIndirect()) { | |
| 131 | - obj->disconnect(); | |
| 132 | - } | |
| 133 | - } | |
| 134 | - } | |
| 135 | -} | |
| 136 | - | |
| 137 | -std::string | |
| 138 | -QPDF_Array::unparse() | |
| 139 | -{ | |
| 140 | - std::string result = "[ "; | |
| 141 | - if (sp) { | |
| 142 | - int next = 0; | |
| 143 | - for (auto& item: sp->elements) { | |
| 144 | - int key = item.first; | |
| 145 | - for (int j = next; j < key; ++j) { | |
| 146 | - result += "null "; | |
| 147 | - } | |
| 148 | - auto og = item.second->resolved_object()->getObjGen(); | |
| 149 | - result += og.isIndirect() ? og.unparse(' ') + " R " : item.second->unparse() + " "; | |
| 150 | - next = ++key; | |
| 151 | - } | |
| 152 | - for (int j = next; j < sp->size; ++j) { | |
| 153 | - result += "null "; | |
| 154 | - } | |
| 155 | - } else { | |
| 156 | - for (auto const& item: elements) { | |
| 157 | - auto og = item->resolved_object()->getObjGen(); | |
| 158 | - result += og.isIndirect() ? og.unparse(' ') + " R " : item->unparse() + " "; | |
| 159 | - } | |
| 160 | - } | |
| 161 | - result += "]"; | |
| 162 | - return result; | |
| 163 | -} | |
| 164 | - | |
| 165 | -void | |
| 166 | -QPDF_Array::writeJSON(int json_version, JSON::Writer& p) | |
| 167 | -{ | |
| 168 | - p.writeStart('['); | |
| 169 | - if (sp) { | |
| 170 | - int next = 0; | |
| 171 | - for (auto& item: sp->elements) { | |
| 172 | - int key = item.first; | |
| 173 | - for (int j = next; j < key; ++j) { | |
| 174 | - p.writeNext() << "null"; | |
| 175 | - } | |
| 176 | - p.writeNext(); | |
| 177 | - auto og = item.second->getObjGen(); | |
| 178 | - if (og.isIndirect()) { | |
| 179 | - p << "\"" << og.unparse(' ') << " R\""; | |
| 180 | - } else { | |
| 181 | - item.second->writeJSON(json_version, p); | |
| 182 | - } | |
| 183 | - next = ++key; | |
| 184 | - } | |
| 185 | - for (int j = next; j < sp->size; ++j) { | |
| 186 | - p.writeNext() << "null"; | |
| 187 | - } | |
| 188 | - } else { | |
| 189 | - for (auto const& item: elements) { | |
| 190 | - p.writeNext(); | |
| 191 | - auto og = item->getObjGen(); | |
| 192 | - if (og.isIndirect()) { | |
| 193 | - p << "\"" << og.unparse(' ') << " R\""; | |
| 194 | - } else { | |
| 195 | - item->writeJSON(json_version, p); | |
| 196 | - } | |
| 197 | - } | |
| 198 | - } | |
| 199 | - p.writeEnd(']'); | |
| 200 | -} | |
| 201 | - | |
| 202 | 59 | QPDF_Array* |
| 203 | 60 | Array::array() const |
| 204 | 61 | { | ... | ... |
libqpdf/QPDF_Bool.cc deleted
| 1 | -#include <qpdf/QPDF_Bool.hh> | |
| 2 | - | |
| 3 | -#include <qpdf/JSON_writer.hh> | |
| 4 | - | |
| 5 | -QPDF_Bool::QPDF_Bool(bool val) : | |
| 6 | - QPDFValue(::ot_boolean), | |
| 7 | - val(val) | |
| 8 | -{ | |
| 9 | -} | |
| 10 | - | |
| 11 | -std::shared_ptr<QPDFObject> | |
| 12 | -QPDF_Bool::create(bool value) | |
| 13 | -{ | |
| 14 | - return do_create(new QPDF_Bool(value)); | |
| 15 | -} | |
| 16 | - | |
| 17 | -std::shared_ptr<QPDFObject> | |
| 18 | -QPDF_Bool::copy(bool shallow) | |
| 19 | -{ | |
| 20 | - return create(val); | |
| 21 | -} | |
| 22 | - | |
| 23 | -std::string | |
| 24 | -QPDF_Bool::unparse() | |
| 25 | -{ | |
| 26 | - return (val ? "true" : "false"); | |
| 27 | -} | |
| 28 | - | |
| 29 | -void | |
| 30 | -QPDF_Bool::writeJSON(int json_version, JSON::Writer& p) | |
| 31 | -{ | |
| 32 | - p << val; | |
| 33 | -} | |
| 34 | - | |
| 35 | -bool | |
| 36 | -QPDF_Bool::getVal() const | |
| 37 | -{ | |
| 38 | - return this->val; | |
| 39 | -} |
libqpdf/QPDF_Destroyed.cc deleted
| 1 | -#include <qpdf/QPDF_Destroyed.hh> | |
| 2 | - | |
| 3 | -#include <stdexcept> | |
| 4 | - | |
| 5 | -QPDF_Destroyed::QPDF_Destroyed() : | |
| 6 | - QPDFValue(::ot_destroyed) | |
| 7 | -{ | |
| 8 | -} | |
| 9 | - | |
| 10 | -std::shared_ptr<QPDFValue> | |
| 11 | -QPDF_Destroyed::getInstance() | |
| 12 | -{ | |
| 13 | - static std::shared_ptr<QPDFValue> instance(new QPDF_Destroyed()); | |
| 14 | - return instance; | |
| 15 | -} | |
| 16 | - | |
| 17 | -std::shared_ptr<QPDFObject> | |
| 18 | -QPDF_Destroyed::copy(bool shallow) | |
| 19 | -{ | |
| 20 | - throw std::logic_error("attempted to shallow copy QPDFObjectHandle from destroyed QPDF"); | |
| 21 | - return nullptr; | |
| 22 | -} | |
| 23 | - | |
| 24 | -std::string | |
| 25 | -QPDF_Destroyed::unparse() | |
| 26 | -{ | |
| 27 | - throw std::logic_error("attempted to unparse a QPDFObjectHandle from a destroyed QPDF"); | |
| 28 | - return ""; | |
| 29 | -} | |
| 30 | - | |
| 31 | -void | |
| 32 | -QPDF_Destroyed::writeJSON(int json_version, JSON::Writer& p) | |
| 33 | -{ | |
| 34 | - throw std::logic_error("attempted to get JSON from a QPDFObjectHandle from a destroyed QPDF"); | |
| 35 | -} | |
| 36 | 0 | \ No newline at end of file |
libqpdf/QPDF_Dictionary.cc
| 1 | -#include <qpdf/QPDF_Dictionary.hh> | |
| 2 | - | |
| 3 | -#include <qpdf/JSON_writer.hh> | |
| 4 | 1 | #include <qpdf/QPDFObjectHandle_private.hh> |
| 2 | + | |
| 5 | 3 | #include <qpdf/QPDFObject_private.hh> |
| 6 | -#include <qpdf/QPDF_Name.hh> | |
| 7 | 4 | #include <qpdf/QTC.hh> |
| 8 | -#include <qpdf/QUtil.hh> | |
| 9 | 5 | |
| 10 | 6 | using namespace std::literals; |
| 11 | 7 | using namespace qpdf; |
| 12 | 8 | |
| 13 | -QPDF_Dictionary::QPDF_Dictionary(std::map<std::string, QPDFObjectHandle> const& items) : | |
| 14 | - QPDFValue(::ot_dictionary), | |
| 15 | - items(items) | |
| 16 | -{ | |
| 17 | -} | |
| 18 | - | |
| 19 | -QPDF_Dictionary::QPDF_Dictionary(std::map<std::string, QPDFObjectHandle>&& items) : | |
| 20 | - QPDFValue(::ot_dictionary), | |
| 21 | - items(items) | |
| 22 | -{ | |
| 23 | -} | |
| 24 | - | |
| 25 | -std::shared_ptr<QPDFObject> | |
| 26 | -QPDF_Dictionary::create(std::map<std::string, QPDFObjectHandle> const& items) | |
| 27 | -{ | |
| 28 | - return do_create(new QPDF_Dictionary(items)); | |
| 29 | -} | |
| 30 | - | |
| 31 | -std::shared_ptr<QPDFObject> | |
| 32 | -QPDF_Dictionary::create(std::map<std::string, QPDFObjectHandle>&& items) | |
| 33 | -{ | |
| 34 | - return do_create(new QPDF_Dictionary(items)); | |
| 35 | -} | |
| 36 | - | |
| 37 | -std::shared_ptr<QPDFObject> | |
| 38 | -QPDF_Dictionary::copy(bool shallow) | |
| 39 | -{ | |
| 40 | - if (shallow) { | |
| 41 | - return create(items); | |
| 42 | - } else { | |
| 43 | - std::map<std::string, QPDFObjectHandle> new_items; | |
| 44 | - for (auto const& item: this->items) { | |
| 45 | - auto value = item.second; | |
| 46 | - new_items[item.first] = value.isIndirect() ? value : value.shallowCopy(); | |
| 47 | - } | |
| 48 | - return create(new_items); | |
| 49 | - } | |
| 50 | -} | |
| 51 | - | |
| 52 | -void | |
| 53 | -QPDF_Dictionary::disconnect() | |
| 54 | -{ | |
| 55 | - for (auto& iter: this->items) { | |
| 56 | - QPDFObjectHandle::DisconnectAccess::disconnect(iter.second); | |
| 57 | - } | |
| 58 | -} | |
| 59 | - | |
| 60 | -std::string | |
| 61 | -QPDF_Dictionary::unparse() | |
| 62 | -{ | |
| 63 | - std::string result = "<< "; | |
| 64 | - for (auto& iter: this->items) { | |
| 65 | - if (!iter.second.isNull()) { | |
| 66 | - result += Name::normalize(iter.first) + " " + iter.second.unparse() + " "; | |
| 67 | - } | |
| 68 | - } | |
| 69 | - result += ">>"; | |
| 70 | - return result; | |
| 71 | -} | |
| 72 | - | |
| 73 | -void | |
| 74 | -QPDF_Dictionary::writeJSON(int json_version, JSON::Writer& p) | |
| 75 | -{ | |
| 76 | - p.writeStart('{'); | |
| 77 | - for (auto& iter: this->items) { | |
| 78 | - if (!iter.second.isNull()) { | |
| 79 | - p.writeNext(); | |
| 80 | - if (json_version == 1) { | |
| 81 | - p << "\"" << JSON::Writer::encode_string(Name::normalize(iter.first)) << "\": "; | |
| 82 | - } else if (auto res = Name::analyzeJSONEncoding(iter.first); res.first) { | |
| 83 | - if (res.second) { | |
| 84 | - p << "\"" << iter.first << "\": "; | |
| 85 | - } else { | |
| 86 | - p << "\"" << JSON::Writer::encode_string(iter.first) << "\": "; | |
| 87 | - } | |
| 88 | - } else { | |
| 89 | - p << "\"n:" << JSON::Writer::encode_string(Name::normalize(iter.first)) << "\": "; | |
| 90 | - } | |
| 91 | - iter.second.writeJSON(json_version, p); | |
| 92 | - } | |
| 93 | - } | |
| 94 | - p.writeEnd('}'); | |
| 95 | -} | |
| 96 | - | |
| 97 | 9 | QPDF_Dictionary* |
| 98 | 10 | BaseDictionary::dict() const |
| 99 | 11 | { | ... | ... |
libqpdf/QPDF_InlineImage.cc deleted
| 1 | -#include <qpdf/QPDF_InlineImage.hh> | |
| 2 | - | |
| 3 | -#include <qpdf/JSON_writer.hh> | |
| 4 | - | |
| 5 | -QPDF_InlineImage::QPDF_InlineImage(std::string const& val) : | |
| 6 | - QPDFValue(::ot_inlineimage), | |
| 7 | - val(val) | |
| 8 | -{ | |
| 9 | -} | |
| 10 | - | |
| 11 | -std::shared_ptr<QPDFObject> | |
| 12 | -QPDF_InlineImage::create(std::string const& val) | |
| 13 | -{ | |
| 14 | - return do_create(new QPDF_InlineImage(val)); | |
| 15 | -} | |
| 16 | - | |
| 17 | -std::shared_ptr<QPDFObject> | |
| 18 | -QPDF_InlineImage::copy(bool shallow) | |
| 19 | -{ | |
| 20 | - return create(val); | |
| 21 | -} | |
| 22 | - | |
| 23 | -std::string | |
| 24 | -QPDF_InlineImage::unparse() | |
| 25 | -{ | |
| 26 | - return this->val; | |
| 27 | -} | |
| 28 | - | |
| 29 | -void | |
| 30 | -QPDF_InlineImage::writeJSON(int json_version, JSON::Writer& p) | |
| 31 | -{ | |
| 32 | - p << "null"; | |
| 33 | -} |
libqpdf/QPDF_Integer.cc deleted
| 1 | -#include <qpdf/QPDF_Integer.hh> | |
| 2 | - | |
| 3 | -#include <qpdf/JSON_writer.hh> | |
| 4 | -#include <qpdf/QUtil.hh> | |
| 5 | - | |
| 6 | -QPDF_Integer::QPDF_Integer(long long val) : | |
| 7 | - QPDFValue(::ot_integer), | |
| 8 | - val(val) | |
| 9 | -{ | |
| 10 | -} | |
| 11 | - | |
| 12 | -std::shared_ptr<QPDFObject> | |
| 13 | -QPDF_Integer::create(long long value) | |
| 14 | -{ | |
| 15 | - return do_create(new QPDF_Integer(value)); | |
| 16 | -} | |
| 17 | - | |
| 18 | -std::shared_ptr<QPDFObject> | |
| 19 | -QPDF_Integer::copy(bool shallow) | |
| 20 | -{ | |
| 21 | - return create(val); | |
| 22 | -} | |
| 23 | - | |
| 24 | -std::string | |
| 25 | -QPDF_Integer::unparse() | |
| 26 | -{ | |
| 27 | - return std::to_string(this->val); | |
| 28 | -} | |
| 29 | - | |
| 30 | -void | |
| 31 | -QPDF_Integer::writeJSON(int json_version, JSON::Writer& p) | |
| 32 | -{ | |
| 33 | - p << std::to_string(this->val); | |
| 34 | -} | |
| 35 | - | |
| 36 | -long long | |
| 37 | -QPDF_Integer::getVal() const | |
| 38 | -{ | |
| 39 | - return this->val; | |
| 40 | -} |
libqpdf/QPDF_Name.cc
| 1 | -#include <qpdf/QPDF_Name.hh> | |
| 2 | - | |
| 3 | -#include <qpdf/JSON_writer.hh> | |
| 4 | -#include <qpdf/QPDFObjectHandle_private.hh> | |
| 5 | -#include <qpdf/QUtil.hh> | |
| 6 | - | |
| 7 | -using namespace qpdf; | |
| 8 | - | |
| 9 | -QPDF_Name::QPDF_Name(std::string const& name) : | |
| 10 | - QPDFValue(::ot_name), | |
| 11 | - name(name) | |
| 12 | -{ | |
| 13 | -} | |
| 14 | - | |
| 15 | -std::shared_ptr<QPDFObject> | |
| 16 | -QPDF_Name::create(std::string const& name) | |
| 17 | -{ | |
| 18 | - return do_create(new QPDF_Name(name)); | |
| 19 | -} | |
| 20 | - | |
| 21 | -std::shared_ptr<QPDFObject> | |
| 22 | -QPDF_Name::copy(bool shallow) | |
| 23 | -{ | |
| 24 | - return create(name); | |
| 25 | -} | |
| 26 | - | |
| 27 | -std::string | |
| 28 | -Name::normalize(std::string const& name) | |
| 29 | -{ | |
| 30 | - if (name.empty()) { | |
| 31 | - return name; | |
| 32 | - } | |
| 33 | - std::string result; | |
| 34 | - result += name.at(0); | |
| 35 | - for (size_t i = 1; i < name.length(); ++i) { | |
| 36 | - char ch = name.at(i); | |
| 37 | - // Don't use locale/ctype here; follow PDF spec guidelines. | |
| 38 | - if (ch == '\0') { | |
| 39 | - // QPDFTokenizer embeds a null character to encode an invalid #. | |
| 40 | - result += "#"; | |
| 41 | - } else if ( | |
| 42 | - ch < 33 || ch == '#' || ch == '/' || ch == '(' || ch == ')' || ch == '{' || ch == '}' || | |
| 43 | - ch == '<' || ch == '>' || ch == '[' || ch == ']' || ch == '%' || ch > 126) { | |
| 44 | - result += QUtil::hex_encode_char(ch); | |
| 45 | - } else { | |
| 46 | - result += ch; | |
| 47 | - } | |
| 48 | - } | |
| 49 | - return result; | |
| 50 | -} | |
| 51 | - | |
| 52 | -std::string | |
| 53 | -QPDF_Name::unparse() | |
| 54 | -{ | |
| 55 | - return Name::normalize(name); | |
| 56 | -} | |
| 57 | - | |
| 58 | -std::pair<bool, bool> | |
| 59 | -Name::analyzeJSONEncoding(const std::string& name) | |
| 60 | -{ | |
| 61 | - int tail = 0; // Number of continuation characters expected. | |
| 62 | - bool tail2 = false; // Potential overlong 3 octet utf-8. | |
| 63 | - bool tail3 = false; // potential overlong 4 octet | |
| 64 | - bool needs_escaping = false; | |
| 65 | - for (auto const& it: name) { | |
| 66 | - auto c = static_cast<unsigned char>(it); | |
| 67 | - if (tail) { | |
| 68 | - if ((c & 0xc0) != 0x80) { | |
| 69 | - return {false, false}; | |
| 70 | - } | |
| 71 | - if (tail2) { | |
| 72 | - if ((c & 0xe0) == 0x80) { | |
| 73 | - return {false, false}; | |
| 74 | - } | |
| 75 | - tail2 = false; | |
| 76 | - } else if (tail3) { | |
| 77 | - if ((c & 0xf0) == 0x80) { | |
| 78 | - return {false, false}; | |
| 79 | - } | |
| 80 | - tail3 = false; | |
| 81 | - } | |
| 82 | - tail--; | |
| 83 | - } else if (c < 0x80) { | |
| 84 | - if (!needs_escaping) { | |
| 85 | - needs_escaping = !((c > 34 && c != '\\') || c == ' ' || c == 33); | |
| 86 | - } | |
| 87 | - } else if ((c & 0xe0) == 0xc0) { | |
| 88 | - if ((c & 0xfe) == 0xc0) { | |
| 89 | - return {false, false}; | |
| 90 | - } | |
| 91 | - tail = 1; | |
| 92 | - } else if ((c & 0xf0) == 0xe0) { | |
| 93 | - tail2 = (c == 0xe0); | |
| 94 | - tail = 2; | |
| 95 | - } else if ((c & 0xf8) == 0xf0) { | |
| 96 | - tail3 = (c == 0xf0); | |
| 97 | - tail = 3; | |
| 98 | - } else { | |
| 99 | - return {false, false}; | |
| 100 | - } | |
| 101 | - } | |
| 102 | - return {tail == 0, !needs_escaping}; | |
| 103 | -} | |
| 104 | - | |
| 105 | -void | |
| 106 | -QPDF_Name::writeJSON(int json_version, JSON::Writer& p) | |
| 107 | -{ | |
| 108 | - // For performance reasons this code is duplicated in QPDF_Dictionary::writeJSON. When updating | |
| 109 | - // this method make sure QPDF_Dictionary is also update. | |
| 110 | - if (json_version == 1) { | |
| 111 | - p << "\"" << JSON::Writer::encode_string(Name::normalize(name)) << "\""; | |
| 112 | - } else { | |
| 113 | - if (auto res = Name::analyzeJSONEncoding(name); res.first) { | |
| 114 | - if (res.second) { | |
| 115 | - p << "\"" << name << "\""; | |
| 116 | - } else { | |
| 117 | - p << "\"" << JSON::Writer::encode_string(name) << "\""; | |
| 118 | - } | |
| 119 | - } else { | |
| 120 | - p << "\"n:" << JSON::Writer::encode_string(Name::normalize(name)) << "\""; | |
| 121 | - } | |
| 122 | - } | |
| 123 | -} |
libqpdf/QPDF_Null.cc deleted
| 1 | -#include <qpdf/QPDF_Null.hh> | |
| 2 | - | |
| 3 | -#include <qpdf/JSON_writer.hh> | |
| 4 | -#include <qpdf/QPDFObject_private.hh> | |
| 5 | - | |
| 6 | -QPDF_Null::QPDF_Null(QPDF* qpdf, QPDFObjGen og) : | |
| 7 | - QPDFValue(::ot_null, qpdf, og) | |
| 8 | -{ | |
| 9 | -} | |
| 10 | - | |
| 11 | -std::shared_ptr<QPDFObject> | |
| 12 | -QPDF_Null::create(QPDF* qpdf, QPDFObjGen og) | |
| 13 | -{ | |
| 14 | - return do_create(new QPDF_Null(qpdf, og)); | |
| 15 | -} | |
| 16 | - | |
| 17 | -std::shared_ptr<QPDFObject> | |
| 18 | -QPDF_Null::create( | |
| 19 | - std::shared_ptr<QPDFObject> parent, std::string_view const& static_descr, std::string var_descr) | |
| 20 | -{ | |
| 21 | - auto n = do_create(new QPDF_Null()); | |
| 22 | - n->setChildDescription(parent, static_descr, var_descr); | |
| 23 | - return n; | |
| 24 | -} | |
| 25 | - | |
| 26 | -std::shared_ptr<QPDFObject> | |
| 27 | -QPDF_Null::create( | |
| 28 | - std::shared_ptr<QPDFValue> parent, std::string_view const& static_descr, std::string var_descr) | |
| 29 | -{ | |
| 30 | - auto n = do_create(new QPDF_Null()); | |
| 31 | - n->setChildDescription(parent, static_descr, var_descr); | |
| 32 | - return n; | |
| 33 | -} | |
| 34 | - | |
| 35 | -std::shared_ptr<QPDFObject> | |
| 36 | -QPDF_Null::copy(bool shallow) | |
| 37 | -{ | |
| 38 | - return create(); | |
| 39 | -} | |
| 40 | - | |
| 41 | -std::string | |
| 42 | -QPDF_Null::unparse() | |
| 43 | -{ | |
| 44 | - return "null"; | |
| 45 | -} | |
| 46 | - | |
| 47 | -void | |
| 48 | -QPDF_Null::writeJSON(int json_version, JSON::Writer& p) | |
| 49 | -{ | |
| 50 | - p << "null"; | |
| 51 | -} |
libqpdf/QPDF_Operator.cc deleted
| 1 | -#include <qpdf/QPDF_Operator.hh> | |
| 2 | - | |
| 3 | -#include <qpdf/JSON_writer.hh> | |
| 4 | - | |
| 5 | -QPDF_Operator::QPDF_Operator(std::string const& val) : | |
| 6 | - QPDFValue(::ot_operator), | |
| 7 | - val(val) | |
| 8 | -{ | |
| 9 | -} | |
| 10 | - | |
| 11 | -std::shared_ptr<QPDFObject> | |
| 12 | -QPDF_Operator::create(std::string const& val) | |
| 13 | -{ | |
| 14 | - return do_create(new QPDF_Operator(val)); | |
| 15 | -} | |
| 16 | - | |
| 17 | -std::shared_ptr<QPDFObject> | |
| 18 | -QPDF_Operator::copy(bool shallow) | |
| 19 | -{ | |
| 20 | - return create(val); | |
| 21 | -} | |
| 22 | - | |
| 23 | -std::string | |
| 24 | -QPDF_Operator::unparse() | |
| 25 | -{ | |
| 26 | - return val; | |
| 27 | -} | |
| 28 | - | |
| 29 | -void | |
| 30 | -QPDF_Operator::writeJSON(int json_version, JSON::Writer& p) | |
| 31 | -{ | |
| 32 | - p << "null"; | |
| 33 | -} |
libqpdf/QPDF_Real.cc deleted
| 1 | -#include <qpdf/QPDF_Real.hh> | |
| 2 | - | |
| 3 | -#include <qpdf/JSON_writer.hh> | |
| 4 | -#include <qpdf/QUtil.hh> | |
| 5 | - | |
| 6 | -QPDF_Real::QPDF_Real(std::string const& val) : | |
| 7 | - QPDFValue(::ot_real), | |
| 8 | - val(val) | |
| 9 | -{ | |
| 10 | -} | |
| 11 | - | |
| 12 | -QPDF_Real::QPDF_Real(double value, int decimal_places, bool trim_trailing_zeroes) : | |
| 13 | - QPDFValue(::ot_real), | |
| 14 | - val(QUtil::double_to_string(value, decimal_places, trim_trailing_zeroes)) | |
| 15 | -{ | |
| 16 | -} | |
| 17 | - | |
| 18 | -std::shared_ptr<QPDFObject> | |
| 19 | -QPDF_Real::create(std::string const& val) | |
| 20 | -{ | |
| 21 | - return do_create(new QPDF_Real(val)); | |
| 22 | -} | |
| 23 | - | |
| 24 | -std::shared_ptr<QPDFObject> | |
| 25 | -QPDF_Real::create(double value, int decimal_places, bool trim_trailing_zeroes) | |
| 26 | -{ | |
| 27 | - return do_create(new QPDF_Real(value, decimal_places, trim_trailing_zeroes)); | |
| 28 | -} | |
| 29 | - | |
| 30 | -std::shared_ptr<QPDFObject> | |
| 31 | -QPDF_Real::copy(bool shallow) | |
| 32 | -{ | |
| 33 | - return create(val); | |
| 34 | -} | |
| 35 | - | |
| 36 | -std::string | |
| 37 | -QPDF_Real::unparse() | |
| 38 | -{ | |
| 39 | - return this->val; | |
| 40 | -} | |
| 41 | - | |
| 42 | -void | |
| 43 | -QPDF_Real::writeJSON(int json_version, JSON::Writer& p) | |
| 44 | -{ | |
| 45 | - if (this->val.length() == 0) { | |
| 46 | - // Can't really happen... | |
| 47 | - p << "0"; | |
| 48 | - } else if (this->val.at(0) == '.') { | |
| 49 | - p << "0" << this->val; | |
| 50 | - } else if (this->val.length() >= 2 && this->val.at(0) == '-' && this->val.at(1) == '.') { | |
| 51 | - p << "-0." << this->val.substr(2); | |
| 52 | - } else { | |
| 53 | - p << this->val; | |
| 54 | - } | |
| 55 | - if (val.back() == '.') { | |
| 56 | - p << "0"; | |
| 57 | - } | |
| 58 | -} |
libqpdf/QPDF_Reserved.cc deleted
| 1 | -#include <qpdf/QPDF_Reserved.hh> | |
| 2 | - | |
| 3 | -#include <stdexcept> | |
| 4 | - | |
| 5 | -QPDF_Reserved::QPDF_Reserved() : | |
| 6 | - QPDFValue(::ot_reserved) | |
| 7 | -{ | |
| 8 | -} | |
| 9 | - | |
| 10 | -std::shared_ptr<QPDFObject> | |
| 11 | -QPDF_Reserved::create() | |
| 12 | -{ | |
| 13 | - return do_create(new QPDF_Reserved()); | |
| 14 | -} | |
| 15 | - | |
| 16 | -std::shared_ptr<QPDFObject> | |
| 17 | -QPDF_Reserved::copy(bool shallow) | |
| 18 | -{ | |
| 19 | - return create(); | |
| 20 | -} | |
| 21 | - | |
| 22 | -std::string | |
| 23 | -QPDF_Reserved::unparse() | |
| 24 | -{ | |
| 25 | - throw std::logic_error("QPDFObjectHandle: attempting to unparse a reserved object"); | |
| 26 | - return ""; | |
| 27 | -} | |
| 28 | - | |
| 29 | -void | |
| 30 | -QPDF_Reserved::writeJSON(int json_version, JSON::Writer& p) | |
| 31 | -{ | |
| 32 | - throw std::logic_error("QPDFObjectHandle: attempting to get JSON from a reserved object"); | |
| 33 | -} |
libqpdf/QPDF_Stream.cc
| 1 | -#include <qpdf/QPDF_Stream.hh> | |
| 1 | +#include <qpdf/QPDFObjectHandle_private.hh> | |
| 2 | 2 | |
| 3 | 3 | #include <qpdf/ContentNormalizer.hh> |
| 4 | 4 | #include <qpdf/JSON_writer.hh> |
| ... | ... | @@ -12,7 +12,6 @@ |
| 12 | 12 | #include <qpdf/QIntC.hh> |
| 13 | 13 | #include <qpdf/QPDF.hh> |
| 14 | 14 | #include <qpdf/QPDFExc.hh> |
| 15 | -#include <qpdf/QPDFObjectHandle_private.hh> | |
| 16 | 15 | #include <qpdf/QTC.hh> |
| 17 | 16 | #include <qpdf/QUtil.hh> |
| 18 | 17 | #include <qpdf/SF_ASCII85Decode.hh> |
| ... | ... | @@ -105,34 +104,14 @@ std::map<std::string, std::function<std::shared_ptr<QPDFStreamFilter>()>> Stream |
| 105 | 104 | {"/ASCIIHexDecode", SF_ASCIIHexDecode::factory}, |
| 106 | 105 | }; |
| 107 | 106 | |
| 108 | -QPDF_Stream::QPDF_Stream( | |
| 109 | - QPDF* qpdf, QPDFObjGen og, QPDFObjectHandle stream_dict, qpdf_offset_t offset, size_t length) : | |
| 110 | - QPDFValue(::ot_stream, qpdf, og), | |
| 111 | - filter_on_write(true), | |
| 112 | - stream_dict(stream_dict), | |
| 113 | - length(length) | |
| 114 | -{ | |
| 115 | - if (!stream_dict.isDictionary()) { | |
| 116 | - throw std::logic_error( | |
| 117 | - "stream object instantiated with non-dictionary object for dictionary"); | |
| 118 | - } | |
| 119 | - auto descr = std::make_shared<QPDFValue::Description>( | |
| 120 | - qpdf->getFilename() + ", stream object " + og.unparse(' ')); | |
| 121 | - setDescription(qpdf, descr, offset); | |
| 122 | -} | |
| 123 | - | |
| 124 | -std::shared_ptr<QPDFObject> | |
| 125 | -QPDF_Stream::create( | |
| 126 | - QPDF* qpdf, QPDFObjGen og, QPDFObjectHandle stream_dict, qpdf_offset_t offset, size_t length) | |
| 107 | +Stream::Stream( | |
| 108 | + QPDF& qpdf, QPDFObjGen og, QPDFObjectHandle stream_dict, qpdf_offset_t offset, size_t length) : | |
| 109 | + BaseHandle(QPDFObject::create<QPDF_Stream>(&qpdf, og, std::move(stream_dict), length)) | |
| 127 | 110 | { |
| 128 | - return do_create(new QPDF_Stream(qpdf, og, stream_dict, offset, length)); | |
| 129 | -} | |
| 130 | - | |
| 131 | -std::shared_ptr<QPDFObject> | |
| 132 | -QPDF_Stream::copy(bool shallow) | |
| 133 | -{ | |
| 134 | - QTC::TC("qpdf", "QPDF_Stream ERR shallow copy stream"); | |
| 135 | - throw std::runtime_error("stream objects cannot be cloned"); | |
| 111 | + auto descr = std::make_shared<QPDFObject::Description>( | |
| 112 | + qpdf.getFilename() + ", stream object " + og.unparse(' ')); | |
| 113 | + obj->setDescription(&qpdf, descr, offset); | |
| 114 | + setDictDescription(); | |
| 136 | 115 | } |
| 137 | 116 | |
| 138 | 117 | void |
| ... | ... | @@ -142,26 +121,6 @@ Stream::registerStreamFilter( |
| 142 | 121 | filter_factories[filter_name] = factory; |
| 143 | 122 | } |
| 144 | 123 | |
| 145 | -void | |
| 146 | -QPDF_Stream::disconnect() | |
| 147 | -{ | |
| 148 | - this->stream_provider = nullptr; | |
| 149 | - QPDFObjectHandle::DisconnectAccess::disconnect(this->stream_dict); | |
| 150 | -} | |
| 151 | - | |
| 152 | -std::string | |
| 153 | -QPDF_Stream::unparse() | |
| 154 | -{ | |
| 155 | - // Unparse stream objects as indirect references | |
| 156 | - return og.unparse(' ') + " R"; | |
| 157 | -} | |
| 158 | - | |
| 159 | -void | |
| 160 | -QPDF_Stream::writeJSON(int json_version, JSON::Writer& jw) | |
| 161 | -{ | |
| 162 | - stream_dict.writeJSON(json_version, jw); | |
| 163 | -} | |
| 164 | - | |
| 165 | 124 | JSON |
| 166 | 125 | Stream::getStreamJSON( |
| 167 | 126 | int json_version, |
| ... | ... | @@ -278,34 +237,27 @@ Stream::writeStreamJSON( |
| 278 | 237 | } |
| 279 | 238 | |
| 280 | 239 | void |
| 281 | -QPDF_Stream::setDescription( | |
| 282 | - QPDF* qpdf, std::shared_ptr<QPDFValue::Description>& description, qpdf_offset_t offset) | |
| 240 | +qpdf::Stream::setDictDescription() | |
| 283 | 241 | { |
| 284 | - this->QPDFValue::setDescription(qpdf, description, offset); | |
| 285 | - setDictDescription(); | |
| 286 | -} | |
| 287 | - | |
| 288 | -void | |
| 289 | -QPDF_Stream::setDictDescription() | |
| 290 | -{ | |
| 291 | - if (!this->stream_dict.hasObjectDescription()) { | |
| 292 | - this->stream_dict.setObjectDescription(qpdf, getDescription() + " -> stream dictionary"); | |
| 242 | + auto s = stream(); | |
| 243 | + if (!s->stream_dict.hasObjectDescription()) { | |
| 244 | + s->stream_dict.setObjectDescription( | |
| 245 | + obj->getQPDF(), obj->getDescription() + " -> stream dictionary"); | |
| 293 | 246 | } |
| 294 | 247 | } |
| 295 | 248 | |
| 296 | 249 | std::shared_ptr<Buffer> |
| 297 | 250 | Stream::getStreamData(qpdf_stream_decode_level_e decode_level) |
| 298 | 251 | { |
| 299 | - auto s = stream(); | |
| 300 | 252 | Pl_Buffer buf("stream data buffer"); |
| 301 | 253 | bool filtered; |
| 302 | 254 | pipeStreamData(&buf, &filtered, 0, decode_level, false, false); |
| 303 | 255 | if (!filtered) { |
| 304 | 256 | throw QPDFExc( |
| 305 | 257 | qpdf_e_unsupported, |
| 306 | - s->qpdf->getFilename(), | |
| 258 | + obj->getQPDF()->getFilename(), | |
| 307 | 259 | "", |
| 308 | - s->parsed_offset, | |
| 260 | + obj->getParsedOffset(), | |
| 309 | 261 | "getStreamData called on unfilterable stream"); |
| 310 | 262 | } |
| 311 | 263 | QTC::TC("qpdf", "QPDF_Stream getStreamData"); |
| ... | ... | @@ -315,14 +267,13 @@ Stream::getStreamData(qpdf_stream_decode_level_e decode_level) |
| 315 | 267 | std::shared_ptr<Buffer> |
| 316 | 268 | Stream::getRawStreamData() |
| 317 | 269 | { |
| 318 | - auto s = stream(); | |
| 319 | 270 | Pl_Buffer buf("stream data buffer"); |
| 320 | 271 | if (!pipeStreamData(&buf, nullptr, 0, qpdf_dl_none, false, false)) { |
| 321 | 272 | throw QPDFExc( |
| 322 | 273 | qpdf_e_unsupported, |
| 323 | - s->qpdf->getFilename(), | |
| 274 | + obj->getQPDF()->getFilename(), | |
| 324 | 275 | "", |
| 325 | - s->parsed_offset, | |
| 276 | + obj->getParsedOffset(), | |
| 326 | 277 | "error getting raw stream data"); |
| 327 | 278 | } |
| 328 | 279 | QTC::TC("qpdf", "QPDF_Stream getRawStreamData"); |
| ... | ... | @@ -532,12 +483,12 @@ Stream::pipeStreamData( |
| 532 | 483 | Pl_Count count("stream provider count", pipeline); |
| 533 | 484 | if (s->stream_provider->supportsRetry()) { |
| 534 | 485 | if (!s->stream_provider->provideStreamData( |
| 535 | - s->og, &count, suppress_warnings, will_retry)) { | |
| 486 | + obj->getObjGen(), &count, suppress_warnings, will_retry)) { | |
| 536 | 487 | filter = false; |
| 537 | 488 | success = false; |
| 538 | 489 | } |
| 539 | 490 | } else { |
| 540 | - s->stream_provider->provideStreamData(s->og, &count); | |
| 491 | + s->stream_provider->provideStreamData(obj->getObjGen(), &count); | |
| 541 | 492 | } |
| 542 | 493 | qpdf_offset_t actual_length = count.getCount(); |
| 543 | 494 | qpdf_offset_t desired_length = 0; |
| ... | ... | @@ -550,7 +501,7 @@ Stream::pipeStreamData( |
| 550 | 501 | // This would be caused by programmer error on the part of a library user, not by |
| 551 | 502 | // invalid input data. |
| 552 | 503 | throw std::runtime_error( |
| 553 | - "stream data provider for " + s->og.unparse(' ') + " provided " + | |
| 504 | + "stream data provider for " + obj->getObjGen().unparse(' ') + " provided " + | |
| 554 | 505 | std::to_string(actual_length) + " bytes instead of expected " + |
| 555 | 506 | std::to_string(desired_length) + " bytes"); |
| 556 | 507 | } |
| ... | ... | @@ -558,15 +509,15 @@ Stream::pipeStreamData( |
| 558 | 509 | QTC::TC("qpdf", "QPDF_Stream provider length not provided"); |
| 559 | 510 | s->stream_dict.replaceKey("/Length", QPDFObjectHandle::newInteger(actual_length)); |
| 560 | 511 | } |
| 561 | - } else if (s->parsed_offset == 0) { | |
| 512 | + } else if (obj->getParsedOffset() == 0) { | |
| 562 | 513 | QTC::TC("qpdf", "QPDF_Stream pipe no stream data"); |
| 563 | 514 | throw std::logic_error("pipeStreamData called for stream with no data"); |
| 564 | 515 | } else { |
| 565 | 516 | QTC::TC("qpdf", "QPDF_Stream pipe original stream data"); |
| 566 | 517 | if (!QPDF::Pipe::pipeStreamData( |
| 567 | - s->qpdf, | |
| 568 | - s->og, | |
| 569 | - s->parsed_offset, | |
| 518 | + obj->getQPDF(), | |
| 519 | + obj->getObjGen(), | |
| 520 | + obj->getParsedOffset(), | |
| 570 | 521 | s->length, |
| 571 | 522 | s->stream_dict, |
| 572 | 523 | pipeline, |
| ... | ... | @@ -642,8 +593,7 @@ Stream::replaceFilterData( |
| 642 | 593 | void |
| 643 | 594 | Stream::warn(std::string const& message) |
| 644 | 595 | { |
| 645 | - auto s = stream(); | |
| 646 | - s->qpdf->warn(qpdf_e_damaged_pdf, "", s->parsed_offset, message); | |
| 596 | + obj->getQPDF()->warn(qpdf_e_damaged_pdf, "", obj->getParsedOffset(), message); | |
| 647 | 597 | } |
| 648 | 598 | |
| 649 | 599 | QPDFObjectHandle | ... | ... |
libqpdf/QPDF_String.cc
| 1 | -#include <qpdf/QPDF_String.hh> | |
| 1 | +#include <qpdf/QPDFObject_private.hh> | |
| 2 | 2 | |
| 3 | -#include <qpdf/JSON_writer.hh> | |
| 3 | +#include <qpdf/QPDFObjectHandle_private.hh> | |
| 4 | 4 | #include <qpdf/QUtil.hh> |
| 5 | 5 | |
| 6 | 6 | // DO NOT USE ctype -- it is locale dependent for some things, and it's not worth the risk of |
| ... | ... | @@ -12,18 +12,6 @@ is_iso_latin1_printable(char ch) |
| 12 | 12 | return (((ch >= 32) && (ch <= 126)) || (static_cast<unsigned char>(ch) >= 160)); |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | -QPDF_String::QPDF_String(std::string const& val) : | |
| 16 | - QPDFValue(::ot_string), | |
| 17 | - val(val) | |
| 18 | -{ | |
| 19 | -} | |
| 20 | - | |
| 21 | -std::shared_ptr<QPDFObject> | |
| 22 | -QPDF_String::create(std::string const& val) | |
| 23 | -{ | |
| 24 | - return do_create(new QPDF_String(val)); | |
| 25 | -} | |
| 26 | - | |
| 27 | 15 | std::shared_ptr<QPDFObject> |
| 28 | 16 | QPDF_String::create_utf16(std::string const& utf8_val) |
| 29 | 17 | { |
| ... | ... | @@ -31,19 +19,7 @@ QPDF_String::create_utf16(std::string const& utf8_val) |
| 31 | 19 | if (!QUtil::utf8_to_pdf_doc(utf8_val, result, '?')) { |
| 32 | 20 | result = QUtil::utf8_to_utf16(utf8_val); |
| 33 | 21 | } |
| 34 | - return do_create(new QPDF_String(result)); | |
| 35 | -} | |
| 36 | - | |
| 37 | -std::shared_ptr<QPDFObject> | |
| 38 | -QPDF_String::copy(bool shallow) | |
| 39 | -{ | |
| 40 | - return create(val); | |
| 41 | -} | |
| 42 | - | |
| 43 | -std::string | |
| 44 | -QPDF_String::unparse() | |
| 45 | -{ | |
| 46 | - return unparse(false); | |
| 22 | + return QPDFObject::create<QPDF_String>(result); | |
| 47 | 23 | } |
| 48 | 24 | |
| 49 | 25 | void | ... | ... |
libqpdf/QPDF_Unresolved.cc deleted
| 1 | -#include <qpdf/QPDF_Unresolved.hh> | |
| 2 | - | |
| 3 | -#include <qpdf/QPDF.hh> | |
| 4 | -#include <qpdf/QPDFObject_private.hh> | |
| 5 | - | |
| 6 | -QPDF_Unresolved::QPDF_Unresolved(QPDF* qpdf, QPDFObjGen og) : | |
| 7 | - QPDFValue(::ot_unresolved, qpdf, og) | |
| 8 | -{ | |
| 9 | -} | |
| 10 | - | |
| 11 | -std::shared_ptr<QPDFObject> | |
| 12 | -QPDF_Unresolved::create(QPDF* qpdf, QPDFObjGen og) | |
| 13 | -{ | |
| 14 | - return do_create(new QPDF_Unresolved(qpdf, og)); | |
| 15 | -} | |
| 16 | - | |
| 17 | -std::shared_ptr<QPDFObject> | |
| 18 | -QPDF_Unresolved::copy(bool shallow) | |
| 19 | -{ | |
| 20 | - return QPDF::Resolver::resolved(qpdf, og)->copy(shallow); | |
| 21 | -} | |
| 22 | - | |
| 23 | -std::string | |
| 24 | -QPDF_Unresolved::unparse() | |
| 25 | -{ | |
| 26 | - return QPDF::Resolver::resolved(qpdf, og)->unparse(); | |
| 27 | -} | |
| 28 | - | |
| 29 | -void | |
| 30 | -QPDF_Unresolved::writeJSON(int json_version, JSON::Writer& p) | |
| 31 | -{ | |
| 32 | - QPDF::Resolver::resolved(qpdf, og)->writeJSON(json_version, p); | |
| 33 | -} | |
| 34 | - | |
| 35 | -std::string | |
| 36 | -QPDF_Unresolved::getStringValue() const | |
| 37 | -{ | |
| 38 | - return QPDF::Resolver::resolved(qpdf, og)->getStringValue(); | |
| 39 | -} |
libqpdf/QPDF_json.cc
| ... | ... | @@ -7,9 +7,6 @@ |
| 7 | 7 | #include <qpdf/QIntC.hh> |
| 8 | 8 | #include <qpdf/QPDFObjectHandle_private.hh> |
| 9 | 9 | #include <qpdf/QPDFObject_private.hh> |
| 10 | -#include <qpdf/QPDFValue.hh> | |
| 11 | -#include <qpdf/QPDF_Null.hh> | |
| 12 | -#include <qpdf/QPDF_Stream.hh> | |
| 13 | 10 | #include <qpdf/QTC.hh> |
| 14 | 11 | #include <qpdf/QUtil.hh> |
| 15 | 12 | #include <algorithm> |
| ... | ... | @@ -239,8 +236,8 @@ class QPDF::JSONReactor: public JSON::Reactor |
| 239 | 236 | is(is), |
| 240 | 237 | must_be_complete(must_be_complete), |
| 241 | 238 | descr( |
| 242 | - std::make_shared<QPDFValue::Description>( | |
| 243 | - QPDFValue::JSON_Descr(std::make_shared<std::string>(is->getName()), ""))) | |
| 239 | + std::make_shared<QPDFObject::Description>( | |
| 240 | + QPDFObject::JSON_Descr(std::make_shared<std::string>(is->getName()), ""))) | |
| 244 | 241 | { |
| 245 | 242 | } |
| 246 | 243 | ~JSONReactor() override = default; |
| ... | ... | @@ -287,7 +284,7 @@ class QPDF::JSONReactor: public JSON::Reactor |
| 287 | 284 | QPDF& pdf; |
| 288 | 285 | std::shared_ptr<InputSource> is; |
| 289 | 286 | bool must_be_complete{true}; |
| 290 | - std::shared_ptr<QPDFValue::Description> descr; | |
| 287 | + std::shared_ptr<QPDFObject::Description> descr; | |
| 291 | 288 | bool errors{false}; |
| 292 | 289 | bool saw_qpdf{false}; |
| 293 | 290 | bool saw_qpdf_meta{false}; |
| ... | ... | @@ -577,8 +574,8 @@ QPDF::JSONReactor::dictionaryItem(std::string const& key, JSON const& value) |
| 577 | 574 | } else { |
| 578 | 575 | this_stream_needs_data = true; |
| 579 | 576 | replaceObject( |
| 580 | - QPDF_Stream::create( | |
| 581 | - &pdf, tos.object.getObjGen(), QPDFObjectHandle::newDictionary(), 0, 0), | |
| 577 | + qpdf::Stream( | |
| 578 | + pdf, tos.object.getObjGen(), QPDFObjectHandle::newDictionary(), 0, 0), | |
| 582 | 579 | value); |
| 583 | 580 | } |
| 584 | 581 | next_obj = tos.object; |
| ... | ... | @@ -707,10 +704,10 @@ QPDF::JSONReactor::arrayItem(JSON const& value) |
| 707 | 704 | void |
| 708 | 705 | QPDF::JSONReactor::setObjectDescription(QPDFObjectHandle& oh, JSON const& value) |
| 709 | 706 | { |
| 710 | - auto j_descr = std::get<QPDFValue::JSON_Descr>(*descr); | |
| 707 | + auto j_descr = std::get<QPDFObject::JSON_Descr>(*descr); | |
| 711 | 708 | if (j_descr.object != cur_object) { |
| 712 | - descr = std::make_shared<QPDFValue::Description>( | |
| 713 | - QPDFValue::JSON_Descr(j_descr.input, cur_object)); | |
| 709 | + descr = std::make_shared<QPDFObject::Description>( | |
| 710 | + QPDFObject::JSON_Descr(j_descr.input, cur_object)); | |
| 714 | 711 | } |
| 715 | 712 | |
| 716 | 713 | oh.getObjectPtr()->setDescription(&pdf, descr, value.getStart()); | ... | ... |
libqpdf/QPDF_optimization.cc
| ... | ... | @@ -5,9 +5,8 @@ |
| 5 | 5 | #include <qpdf/QPDF.hh> |
| 6 | 6 | |
| 7 | 7 | #include <qpdf/QPDFExc.hh> |
| 8 | +#include <qpdf/QPDFObjectHandle_private.hh> | |
| 8 | 9 | #include <qpdf/QPDFWriter_private.hh> |
| 9 | -#include <qpdf/QPDF_Array.hh> | |
| 10 | -#include <qpdf/QPDF_Dictionary.hh> | |
| 11 | 10 | #include <qpdf/QTC.hh> |
| 12 | 11 | |
| 13 | 12 | QPDF::ObjUser::ObjUser() : | ... | ... |
libqpdf/qpdf/QPDFObjectHandle_private.hh
| ... | ... | @@ -4,9 +4,7 @@ |
| 4 | 4 | #include <qpdf/QPDFObjectHandle.hh> |
| 5 | 5 | |
| 6 | 6 | #include <qpdf/QPDFObject_private.hh> |
| 7 | -#include <qpdf/QPDF_Array.hh> | |
| 8 | -#include <qpdf/QPDF_Dictionary.hh> | |
| 9 | -#include <qpdf/QPDF_Stream.hh> | |
| 7 | +#include <qpdf/QUtil.hh> | |
| 10 | 8 | |
| 11 | 9 | namespace qpdf |
| 12 | 10 | { |
| ... | ... | @@ -106,6 +104,13 @@ namespace qpdf |
| 106 | 104 | { |
| 107 | 105 | } |
| 108 | 106 | |
| 107 | + Stream( | |
| 108 | + QPDF& qpdf, | |
| 109 | + QPDFObjGen og, | |
| 110 | + QPDFObjectHandle stream_dict, | |
| 111 | + qpdf_offset_t offset, | |
| 112 | + size_t length); | |
| 113 | + | |
| 109 | 114 | QPDFObjectHandle |
| 110 | 115 | getDict() const |
| 111 | 116 | { |
| ... | ... | @@ -186,20 +191,22 @@ namespace qpdf |
| 186 | 191 | { |
| 187 | 192 | auto s = stream(); |
| 188 | 193 | s->stream_dict = new_dict; |
| 189 | - s->setDictDescription(); | |
| 194 | + setDictDescription(); | |
| 190 | 195 | } |
| 191 | 196 | |
| 197 | + void setDictDescription(); | |
| 198 | + | |
| 192 | 199 | static void registerStreamFilter( |
| 193 | 200 | std::string const& filter_name, |
| 194 | 201 | std::function<std::shared_ptr<QPDFStreamFilter>()> factory); |
| 195 | 202 | |
| 196 | 203 | private: |
| 197 | - QPDF_Stream* | |
| 204 | + QPDF_Stream::Members* | |
| 198 | 205 | stream() const |
| 199 | 206 | { |
| 200 | 207 | if (obj) { |
| 201 | 208 | if (auto s = obj->as<QPDF_Stream>()) { |
| 202 | - return s; | |
| 209 | + return s->m.get(); | |
| 203 | 210 | } |
| 204 | 211 | } |
| 205 | 212 | throw std::runtime_error("operation for stream attempted on object of type dictionary"); |
| ... | ... | @@ -227,6 +234,32 @@ namespace qpdf |
| 227 | 234 | |
| 228 | 235 | } // namespace qpdf |
| 229 | 236 | |
| 237 | +inline QPDF_Dictionary::QPDF_Dictionary(std::map<std::string, QPDFObjectHandle>&& items) : | |
| 238 | + items(std::move(items)) | |
| 239 | +{ | |
| 240 | +} | |
| 241 | + | |
| 242 | +inline std::shared_ptr<QPDFObject> | |
| 243 | +QPDF_Null::create( | |
| 244 | + std::shared_ptr<QPDFObject> parent, std::string_view const& static_descr, std::string var_descr) | |
| 245 | +{ | |
| 246 | + auto n = QPDFObject::create<QPDF_Null>(); | |
| 247 | + n->setChildDescription(parent->getQPDF(), parent, static_descr, var_descr); | |
| 248 | + return n; | |
| 249 | +} | |
| 250 | + | |
| 251 | +inline QPDF_Real::QPDF_Real(double value, int decimal_places, bool trim_trailing_zeroes) : | |
| 252 | + val(QUtil::double_to_string(value, decimal_places, trim_trailing_zeroes)) | |
| 253 | +{ | |
| 254 | +} | |
| 255 | + | |
| 256 | +template <typename T, typename... Args> | |
| 257 | +inline std::shared_ptr<QPDFObject> | |
| 258 | +QPDFObject::create(Args&&... args) | |
| 259 | +{ | |
| 260 | + return std::make_shared<QPDFObject>(std::forward<T>(T(std::forward<Args>(args)...))); | |
| 261 | +} | |
| 262 | + | |
| 230 | 263 | inline qpdf::Array |
| 231 | 264 | QPDFObjectHandle::as_array(qpdf::typed options) const |
| 232 | 265 | { | ... | ... |
libqpdf/qpdf/QPDFObject_private.hh
| ... | ... | @@ -6,182 +6,508 @@ |
| 6 | 6 | |
| 7 | 7 | #include <qpdf/Constants.h> |
| 8 | 8 | #include <qpdf/JSON.hh> |
| 9 | +#include <qpdf/JSON_writer.hh> | |
| 9 | 10 | #include <qpdf/QPDF.hh> |
| 10 | -#include <qpdf/QPDFValue.hh> | |
| 11 | +#include <qpdf/QPDFObjGen.hh> | |
| 11 | 12 | #include <qpdf/Types.h> |
| 12 | 13 | |
| 14 | +#include <map> | |
| 15 | +#include <memory> | |
| 13 | 16 | #include <string> |
| 14 | 17 | #include <string_view> |
| 18 | +#include <variant> | |
| 19 | +#include <vector> | |
| 15 | 20 | |
| 16 | -class QPDF; | |
| 21 | +class QPDFObject; | |
| 17 | 22 | class QPDFObjectHandle; |
| 18 | 23 | |
| 19 | -class QPDFObject | |
| 24 | +namespace qpdf | |
| 25 | +{ | |
| 26 | + class Array; | |
| 27 | + class BaseDictionary; | |
| 28 | + class Dictionary; | |
| 29 | + class Stream; | |
| 30 | +} // namespace qpdf | |
| 31 | + | |
| 32 | +class QPDF_Array final | |
| 20 | 33 | { |
| 21 | - friend class QPDFValue; | |
| 34 | + private: | |
| 35 | + struct Sparse | |
| 36 | + { | |
| 37 | + int size{0}; | |
| 38 | + std::map<int, std::shared_ptr<QPDFObject>> elements; | |
| 39 | + }; | |
| 22 | 40 | |
| 23 | 41 | public: |
| 24 | - QPDFObject() = default; | |
| 42 | + QPDF_Array() = default; | |
| 43 | + QPDF_Array(QPDF_Array const& other) : | |
| 44 | + sp(other.sp ? std::make_unique<Sparse>(*other.sp) : nullptr) | |
| 45 | + { | |
| 46 | + } | |
| 47 | + | |
| 48 | + QPDF_Array(QPDF_Array&&) = default; | |
| 49 | + QPDF_Array& operator=(QPDF_Array&&) = default; | |
| 50 | + | |
| 51 | + private: | |
| 52 | + friend class QPDFObject; | |
| 53 | + friend class qpdf::Array; | |
| 54 | + QPDF_Array(std::vector<QPDFObjectHandle> const& items); | |
| 55 | + QPDF_Array(std::vector<std::shared_ptr<QPDFObject>>&& items, bool sparse); | |
| 25 | 56 | |
| 26 | - std::shared_ptr<QPDFObject> | |
| 27 | - copy(bool shallow = false) | |
| 57 | + int | |
| 58 | + size() const | |
| 28 | 59 | { |
| 29 | - return value->copy(shallow); | |
| 60 | + return sp ? sp->size : int(elements.size()); | |
| 30 | 61 | } |
| 31 | - std::string | |
| 32 | - unparse() | |
| 62 | + void setFromVector(std::vector<QPDFObjectHandle> const& items); | |
| 63 | + void checkOwnership(QPDFObjectHandle const& item) const; | |
| 64 | + | |
| 65 | + std::unique_ptr<Sparse> sp; | |
| 66 | + std::vector<std::shared_ptr<QPDFObject>> elements; | |
| 67 | +}; | |
| 68 | + | |
| 69 | +class QPDF_Bool final | |
| 70 | +{ | |
| 71 | + friend class QPDFObject; | |
| 72 | + friend class QPDFObjectHandle; | |
| 73 | + | |
| 74 | + explicit QPDF_Bool(bool val) : | |
| 75 | + val(val) | |
| 33 | 76 | { |
| 34 | - return value->unparse(); | |
| 35 | 77 | } |
| 36 | - void | |
| 37 | - writeJSON(int json_version, JSON::Writer& p) | |
| 78 | + bool val; | |
| 79 | +}; | |
| 80 | + | |
| 81 | +class QPDF_Destroyed final | |
| 82 | +{ | |
| 83 | +}; | |
| 84 | + | |
| 85 | +class QPDF_Dictionary final | |
| 86 | +{ | |
| 87 | + friend class QPDFObject; | |
| 88 | + friend class qpdf::BaseDictionary; | |
| 89 | + | |
| 90 | + QPDF_Dictionary(std::map<std::string, QPDFObjectHandle> const& items) : | |
| 91 | + items(items) | |
| 38 | 92 | { |
| 39 | - return value->writeJSON(json_version, p); | |
| 40 | 93 | } |
| 41 | - std::string | |
| 42 | - getStringValue() const | |
| 94 | + inline QPDF_Dictionary(std::map<std::string, QPDFObjectHandle>&& items); | |
| 95 | + | |
| 96 | + std::map<std::string, QPDFObjectHandle> items; | |
| 97 | +}; | |
| 98 | + | |
| 99 | +class QPDF_InlineImage final | |
| 100 | +{ | |
| 101 | + friend class QPDFObject; | |
| 102 | + | |
| 103 | + explicit QPDF_InlineImage(std::string val) : | |
| 104 | + val(std::move(val)) | |
| 105 | + { | |
| 106 | + } | |
| 107 | + std::string val; | |
| 108 | +}; | |
| 109 | + | |
| 110 | +class QPDF_Integer final | |
| 111 | +{ | |
| 112 | + friend class QPDFObject; | |
| 113 | + friend class QPDFObjectHandle; | |
| 114 | + | |
| 115 | + QPDF_Integer(long long val) : | |
| 116 | + val(val) | |
| 117 | + { | |
| 118 | + } | |
| 119 | + long long val; | |
| 120 | +}; | |
| 121 | + | |
| 122 | +class QPDF_Name final | |
| 123 | +{ | |
| 124 | + friend class QPDFObject; | |
| 125 | + | |
| 126 | + explicit QPDF_Name(std::string name) : | |
| 127 | + name(std::move(name)) | |
| 128 | + { | |
| 129 | + } | |
| 130 | + std::string name; | |
| 131 | +}; | |
| 132 | + | |
| 133 | +class QPDF_Null final | |
| 134 | +{ | |
| 135 | + friend class QPDFObject; | |
| 136 | + | |
| 137 | + public: | |
| 138 | + static inline std::shared_ptr<QPDFObject> create( | |
| 139 | + std::shared_ptr<QPDFObject> parent, | |
| 140 | + std::string_view const& static_descr, | |
| 141 | + std::string var_descr); | |
| 142 | +}; | |
| 143 | + | |
| 144 | +class QPDF_Operator final | |
| 145 | +{ | |
| 146 | + friend class QPDFObject; | |
| 147 | + | |
| 148 | + QPDF_Operator(std::string val) : | |
| 149 | + val(std::move(val)) | |
| 150 | + { | |
| 151 | + } | |
| 152 | + | |
| 153 | + std::string val; | |
| 154 | +}; | |
| 155 | + | |
| 156 | +class QPDF_Real final | |
| 157 | +{ | |
| 158 | + friend class QPDFObject; | |
| 159 | + | |
| 160 | + QPDF_Real(std::string val) : | |
| 161 | + val(std::move(val)) | |
| 162 | + { | |
| 163 | + } | |
| 164 | + inline QPDF_Real(double value, int decimal_places, bool trim_trailing_zeroes); | |
| 165 | + // Store reals as strings to avoid roundoff errors. | |
| 166 | + std::string val; | |
| 167 | +}; | |
| 168 | + | |
| 169 | +class QPDF_Reference | |
| 170 | +{ | |
| 171 | + // This is a minimal implementation to support QPDF::replaceObject. Once we support parsing of | |
| 172 | + // objects that are an indirect reference we will need to support multiple levels of | |
| 173 | + // indirection, including the possibility of circular references. | |
| 174 | + friend class QPDFObject; | |
| 175 | + | |
| 176 | + QPDF_Reference(std::shared_ptr<QPDFObject> obj) : | |
| 177 | + obj(std::move(obj)) | |
| 178 | + { | |
| 179 | + } | |
| 180 | + | |
| 181 | + std::shared_ptr<QPDFObject> obj; | |
| 182 | +}; | |
| 183 | + | |
| 184 | +class QPDF_Reserved final | |
| 185 | +{ | |
| 186 | +}; | |
| 187 | + | |
| 188 | +class QPDF_Stream final | |
| 189 | +{ | |
| 190 | + class Members | |
| 191 | + { | |
| 192 | + friend class QPDF_Stream; | |
| 193 | + friend class QPDFObject; | |
| 194 | + friend class qpdf::Stream; | |
| 195 | + | |
| 196 | + public: | |
| 197 | + Members(QPDFObjectHandle stream_dict, size_t length) : | |
| 198 | + stream_dict(std::move(stream_dict)), | |
| 199 | + length(length) | |
| 200 | + { | |
| 201 | + } | |
| 202 | + | |
| 203 | + private: | |
| 204 | + void replaceFilterData( | |
| 205 | + QPDFObjectHandle const& filter, QPDFObjectHandle const& decode_parms, size_t length); | |
| 206 | + | |
| 207 | + bool filter_on_write{true}; | |
| 208 | + QPDFObjectHandle stream_dict; | |
| 209 | + size_t length{0}; | |
| 210 | + std::shared_ptr<Buffer> stream_data; | |
| 211 | + std::shared_ptr<QPDFObjectHandle::StreamDataProvider> stream_provider; | |
| 212 | + std::vector<std::shared_ptr<QPDFObjectHandle::TokenFilter>> token_filters; | |
| 213 | + }; | |
| 214 | + | |
| 215 | + friend class QPDFObject; | |
| 216 | + friend class qpdf::Stream; | |
| 217 | + | |
| 218 | + QPDF_Stream(QPDFObjectHandle stream_dict, size_t length) : | |
| 219 | + m(std::make_unique<Members>(stream_dict, length)) | |
| 220 | + { | |
| 221 | + if (!stream_dict.isDictionary()) { | |
| 222 | + throw std::logic_error( | |
| 223 | + "stream object instantiated with non-dictionary object for dictionary"); | |
| 224 | + } | |
| 225 | + } | |
| 226 | + | |
| 227 | + std::unique_ptr<Members> m; | |
| 228 | +}; | |
| 229 | + | |
| 230 | +// QPDF_Strings may included embedded null characters. | |
| 231 | +class QPDF_String final | |
| 232 | +{ | |
| 233 | + friend class QPDFObject; | |
| 234 | + friend class QPDFWriter; | |
| 235 | + | |
| 236 | + public: | |
| 237 | + static std::shared_ptr<QPDFObject> create_utf16(std::string const& utf8_val); | |
| 238 | + std::string unparse(bool force_binary = false); | |
| 239 | + void writeJSON(int json_version, JSON::Writer& p); | |
| 240 | + std::string getUTF8Val() const; | |
| 241 | + | |
| 242 | + private: | |
| 243 | + QPDF_String(std::string val) : | |
| 244 | + val(std::move(val)) | |
| 43 | 245 | { |
| 44 | - return value->getStringValue(); | |
| 45 | 246 | } |
| 247 | + bool useHexString() const; | |
| 248 | + std::string val; | |
| 249 | +}; | |
| 250 | + | |
| 251 | +class QPDF_Unresolved final | |
| 252 | +{ | |
| 253 | +}; | |
| 254 | + | |
| 255 | +class QPDFObject | |
| 256 | +{ | |
| 257 | + public: | |
| 258 | + template <typename T> | |
| 259 | + QPDFObject(T&& value) : | |
| 260 | + value(std::forward<T>(value)) | |
| 261 | + { | |
| 262 | + } | |
| 263 | + | |
| 264 | + template <typename T> | |
| 265 | + QPDFObject(QPDF* qpdf, QPDFObjGen og, T&& value) : | |
| 266 | + value(std::forward<T>(value)), | |
| 267 | + qpdf(qpdf), | |
| 268 | + og(og) | |
| 269 | + { | |
| 270 | + } | |
| 271 | + | |
| 272 | + template <typename T, typename... Args> | |
| 273 | + inline static std::shared_ptr<QPDFObject> create(Args&&... args); | |
| 274 | + | |
| 275 | + template <typename T, typename... Args> | |
| 276 | + inline static std::shared_ptr<QPDFObject> | |
| 277 | + create(QPDF* qpdf, QPDFObjGen og, Args&&... args) | |
| 278 | + { | |
| 279 | + return std::make_shared<QPDFObject>( | |
| 280 | + qpdf, og, std::forward<T>(T(std::forward<Args>(args)...))); | |
| 281 | + } | |
| 282 | + | |
| 283 | + std::shared_ptr<QPDFObject> copy(bool shallow = false); | |
| 284 | + std::string unparse(); | |
| 285 | + void write_json(int json_version, JSON::Writer& p); | |
| 286 | + void disconnect(); | |
| 287 | + std::string getStringValue() const; | |
| 288 | + | |
| 46 | 289 | // Return a unique type code for the resolved object |
| 47 | 290 | qpdf_object_type_e |
| 48 | 291 | getResolvedTypeCode() const |
| 49 | 292 | { |
| 50 | - auto tc = value->type_code; | |
| 51 | - return tc == ::ot_unresolved | |
| 52 | - ? QPDF::Resolver::resolved(value->qpdf, value->og)->value->type_code | |
| 53 | - : tc; | |
| 293 | + if (getTypeCode() == ::ot_unresolved) { | |
| 294 | + return QPDF::Resolver::resolved(qpdf, og)->getTypeCode(); | |
| 295 | + } | |
| 296 | + if (getTypeCode() == ::ot_reference) { | |
| 297 | + return std::get<QPDF_Reference>(value).obj->getResolvedTypeCode(); | |
| 298 | + } | |
| 299 | + return getTypeCode(); | |
| 54 | 300 | } |
| 55 | 301 | // Return a unique type code for the object |
| 56 | 302 | qpdf_object_type_e |
| 57 | - getTypeCode() const noexcept | |
| 303 | + getTypeCode() const | |
| 58 | 304 | { |
| 59 | - return value->type_code; | |
| 305 | + return static_cast<qpdf_object_type_e>(value.index()); | |
| 60 | 306 | } |
| 61 | 307 | |
| 62 | 308 | QPDF* |
| 63 | 309 | getQPDF() const |
| 64 | 310 | { |
| 65 | - return value->qpdf; | |
| 311 | + return qpdf; | |
| 66 | 312 | } |
| 67 | 313 | QPDFObjGen |
| 68 | 314 | getObjGen() const |
| 69 | 315 | { |
| 70 | - return value->og; | |
| 316 | + return og; | |
| 71 | 317 | } |
| 72 | 318 | void |
| 73 | - setDescription( | |
| 74 | - QPDF* qpdf, std::shared_ptr<QPDFValue::Description>& description, qpdf_offset_t offset = -1) | |
| 319 | + assign_null() | |
| 75 | 320 | { |
| 76 | - return value->setDescription(qpdf, description, offset); | |
| 321 | + value = QPDF_Null(); | |
| 322 | + qpdf = nullptr; | |
| 323 | + og = QPDFObjGen(); | |
| 324 | + object_description = nullptr; | |
| 325 | + parsed_offset = -1; | |
| 77 | 326 | } |
| 78 | 327 | void |
| 79 | - setChildDescription( | |
| 80 | - std::shared_ptr<QPDFObject> parent, | |
| 81 | - std::string_view const& static_descr, | |
| 82 | - std::string var_descr) | |
| 328 | + move_to(std::shared_ptr<QPDFObject>& o, bool destroy) | |
| 83 | 329 | { |
| 84 | - auto qpdf = parent ? parent->value->qpdf : nullptr; | |
| 85 | - value->setChildDescription(qpdf, parent->value, static_descr, var_descr); | |
| 330 | + o->value = std::move(value); | |
| 331 | + o->qpdf = qpdf; | |
| 332 | + o->og = og; | |
| 333 | + o->object_description = object_description; | |
| 334 | + o->parsed_offset = parsed_offset; | |
| 335 | + if (!destroy) { | |
| 336 | + value = QPDF_Reference(o); | |
| 337 | + } | |
| 86 | 338 | } |
| 87 | 339 | void |
| 88 | - setChildDescription( | |
| 89 | - std::shared_ptr<QPDFValue> parent, | |
| 90 | - std::string_view const& static_descr, | |
| 91 | - std::string var_descr) | |
| 340 | + swapWith(std::shared_ptr<QPDFObject> o) | |
| 92 | 341 | { |
| 93 | - auto qpdf = parent ? parent->qpdf : nullptr; | |
| 94 | - value->setChildDescription(qpdf, parent, static_descr, var_descr); | |
| 342 | + std::swap(value, o->value); | |
| 343 | + std::swap(qpdf, o->qpdf); | |
| 344 | + std::swap(object_description, o->object_description); | |
| 345 | + std::swap(parsed_offset, o->parsed_offset); | |
| 95 | 346 | } |
| 96 | - bool | |
| 97 | - getDescription(QPDF*& qpdf, std::string& description) | |
| 347 | + | |
| 348 | + void | |
| 349 | + setObjGen(QPDF* a_qpdf, QPDFObjGen a_og) | |
| 98 | 350 | { |
| 99 | - qpdf = value->qpdf; | |
| 100 | - description = value->getDescription(); | |
| 101 | - return qpdf != nullptr; | |
| 351 | + qpdf = a_qpdf; | |
| 352 | + og = a_og; | |
| 102 | 353 | } |
| 103 | - bool | |
| 104 | - hasDescription() | |
| 354 | + // Mark an object as destroyed. Used by QPDF's destructor for its indirect objects. | |
| 355 | + void | |
| 356 | + destroy() | |
| 105 | 357 | { |
| 106 | - return value->hasDescription(); | |
| 358 | + value = QPDF_Destroyed(); | |
| 107 | 359 | } |
| 108 | - void | |
| 109 | - setParsedOffset(qpdf_offset_t offset) | |
| 360 | + | |
| 361 | + bool | |
| 362 | + isUnresolved() const | |
| 110 | 363 | { |
| 111 | - value->setParsedOffset(offset); | |
| 364 | + return getTypeCode() == ::ot_unresolved; | |
| 112 | 365 | } |
| 113 | - qpdf_offset_t | |
| 114 | - getParsedOffset() | |
| 366 | + const QPDFObject* | |
| 367 | + resolved_object() const | |
| 115 | 368 | { |
| 116 | - return value->getParsedOffset(); | |
| 369 | + return isUnresolved() ? QPDF::Resolver::resolved(qpdf, og) : this; | |
| 117 | 370 | } |
| 371 | + | |
| 372 | + struct JSON_Descr | |
| 373 | + { | |
| 374 | + JSON_Descr(std::shared_ptr<std::string> input, std::string const& object) : | |
| 375 | + input(input), | |
| 376 | + object(object) | |
| 377 | + { | |
| 378 | + } | |
| 379 | + | |
| 380 | + std::shared_ptr<std::string> input; | |
| 381 | + std::string object; | |
| 382 | + }; | |
| 383 | + | |
| 384 | + struct ChildDescr | |
| 385 | + { | |
| 386 | + ChildDescr( | |
| 387 | + std::shared_ptr<QPDFObject> parent, | |
| 388 | + std::string_view const& static_descr, | |
| 389 | + std::string var_descr) : | |
| 390 | + parent(parent), | |
| 391 | + static_descr(static_descr), | |
| 392 | + var_descr(var_descr) | |
| 393 | + { | |
| 394 | + } | |
| 395 | + | |
| 396 | + std::weak_ptr<QPDFObject> parent; | |
| 397 | + std::string_view const& static_descr; | |
| 398 | + std::string var_descr; | |
| 399 | + }; | |
| 400 | + | |
| 401 | + using Description = std::variant<std::string, JSON_Descr, ChildDescr>; | |
| 402 | + | |
| 118 | 403 | void |
| 119 | - assign(std::shared_ptr<QPDFObject> o) | |
| 404 | + setDescription( | |
| 405 | + QPDF* qpdf_p, std::shared_ptr<Description>& description, qpdf_offset_t offset = -1) | |
| 120 | 406 | { |
| 121 | - value = o->value; | |
| 407 | + qpdf = qpdf_p; | |
| 408 | + object_description = description; | |
| 409 | + setParsedOffset(offset); | |
| 122 | 410 | } |
| 123 | 411 | void |
| 124 | - swapWith(std::shared_ptr<QPDFObject> o) | |
| 412 | + setDefaultDescription(QPDF* a_qpdf, QPDFObjGen const& a_og) | |
| 125 | 413 | { |
| 126 | - auto v = value; | |
| 127 | - value = o->value; | |
| 128 | - o->value = v; | |
| 129 | - auto og = value->og; | |
| 130 | - value->og = o->value->og; | |
| 131 | - o->value->og = og; | |
| 414 | + qpdf = a_qpdf; | |
| 415 | + og = a_og; | |
| 132 | 416 | } |
| 133 | - | |
| 134 | 417 | void |
| 135 | - setDefaultDescription(QPDF* qpdf, QPDFObjGen og) | |
| 418 | + setChildDescription( | |
| 419 | + QPDF* a_qpdf, | |
| 420 | + std::shared_ptr<QPDFObject> parent, | |
| 421 | + std::string_view const& static_descr, | |
| 422 | + std::string var_descr) | |
| 136 | 423 | { |
| 137 | - // Intended for use by the QPDF class | |
| 138 | - value->setDefaultDescription(qpdf, og); | |
| 424 | + object_description = | |
| 425 | + std::make_shared<Description>(ChildDescr(parent, static_descr, var_descr)); | |
| 426 | + qpdf = a_qpdf; | |
| 139 | 427 | } |
| 140 | - void | |
| 141 | - setObjGen(QPDF* qpdf, QPDFObjGen og) | |
| 428 | + std::string getDescription(); | |
| 429 | + bool | |
| 430 | + hasDescription() | |
| 142 | 431 | { |
| 143 | - value->qpdf = qpdf; | |
| 144 | - value->og = og; | |
| 432 | + return object_description || og.isIndirect(); | |
| 145 | 433 | } |
| 146 | 434 | void |
| 147 | - disconnect() | |
| 435 | + setParsedOffset(qpdf_offset_t offset) | |
| 148 | 436 | { |
| 149 | - // Disconnect an object from its owning QPDF. This is called by QPDF's destructor. | |
| 150 | - value->disconnect(); | |
| 151 | - value->qpdf = nullptr; | |
| 152 | - value->og = QPDFObjGen(); | |
| 437 | + if (parsed_offset < 0) { | |
| 438 | + parsed_offset = offset; | |
| 439 | + } | |
| 153 | 440 | } |
| 154 | - // Mark an object as destroyed. Used by QPDF's destructor for its indirect objects. | |
| 155 | - void destroy(); | |
| 156 | - | |
| 157 | 441 | bool |
| 158 | - isUnresolved() const | |
| 442 | + getDescription(QPDF*& a_qpdf, std::string& description) | |
| 159 | 443 | { |
| 160 | - return value->type_code == ::ot_unresolved; | |
| 444 | + a_qpdf = qpdf; | |
| 445 | + description = getDescription(); | |
| 446 | + return qpdf != nullptr; | |
| 161 | 447 | } |
| 162 | - const QPDFObject* | |
| 163 | - resolved_object() const | |
| 448 | + qpdf_offset_t | |
| 449 | + getParsedOffset() | |
| 164 | 450 | { |
| 165 | - return isUnresolved() ? QPDF::Resolver::resolved(value->qpdf, value->og) : this; | |
| 451 | + return parsed_offset; | |
| 452 | + } | |
| 453 | + QPDF* | |
| 454 | + getQPDF() | |
| 455 | + { | |
| 456 | + return qpdf; | |
| 457 | + } | |
| 458 | + QPDFObjGen | |
| 459 | + getObjGen() | |
| 460 | + { | |
| 461 | + return og; | |
| 166 | 462 | } |
| 167 | 463 | |
| 168 | 464 | template <typename T> |
| 169 | 465 | T* |
| 170 | - as() const | |
| 171 | - { | |
| 172 | - if (auto result = dynamic_cast<T*>(value.get())) { | |
| 173 | - return result; | |
| 174 | - } else { | |
| 175 | - return isUnresolved() | |
| 176 | - ? dynamic_cast<T*>(QPDF::Resolver::resolved(value->qpdf, value->og)->value.get()) | |
| 177 | - : nullptr; | |
| 466 | + as() | |
| 467 | + { | |
| 468 | + if (std::holds_alternative<T>(value)) { | |
| 469 | + return &std::get<T>(value); | |
| 178 | 470 | } |
| 471 | + if (std::holds_alternative<QPDF_Unresolved>(value)) { | |
| 472 | + return QPDF::Resolver::resolved(qpdf, og)->as<T>(); | |
| 473 | + } | |
| 474 | + if (std::holds_alternative<QPDF_Reference>(value)) { | |
| 475 | + // see comment in QPDF_Reference. | |
| 476 | + return std::get<QPDF_Reference>(value).obj->as<T>(); | |
| 477 | + } | |
| 478 | + return nullptr; | |
| 179 | 479 | } |
| 180 | 480 | |
| 181 | 481 | private: |
| 482 | + friend class QPDF_Stream; | |
| 483 | + typedef std::variant< | |
| 484 | + std::monostate, | |
| 485 | + QPDF_Reserved, | |
| 486 | + QPDF_Null, | |
| 487 | + QPDF_Bool, | |
| 488 | + QPDF_Integer, | |
| 489 | + QPDF_Real, | |
| 490 | + QPDF_String, | |
| 491 | + QPDF_Name, | |
| 492 | + QPDF_Array, | |
| 493 | + QPDF_Dictionary, | |
| 494 | + QPDF_Stream, | |
| 495 | + QPDF_Operator, | |
| 496 | + QPDF_InlineImage, | |
| 497 | + QPDF_Unresolved, | |
| 498 | + QPDF_Destroyed, | |
| 499 | + QPDF_Reference> | |
| 500 | + Value; | |
| 501 | + Value value; | |
| 502 | + | |
| 182 | 503 | QPDFObject(QPDFObject const&) = delete; |
| 183 | 504 | QPDFObject& operator=(QPDFObject const&) = delete; |
| 184 | - std::shared_ptr<QPDFValue> value; | |
| 505 | + | |
| 506 | + std::shared_ptr<Description> object_description; | |
| 507 | + | |
| 508 | + QPDF* qpdf{nullptr}; | |
| 509 | + QPDFObjGen og{}; | |
| 510 | + qpdf_offset_t parsed_offset{-1}; | |
| 185 | 511 | }; |
| 186 | 512 | |
| 187 | 513 | #endif // QPDFOBJECT_HH | ... | ... |
libqpdf/qpdf/QPDFParser.hh
| 1 | 1 | #ifndef QPDFPARSER_HH |
| 2 | 2 | #define QPDFPARSER_HH |
| 3 | 3 | |
| 4 | -#include <qpdf/QPDFObjectHandle.hh> | |
| 5 | -#include <qpdf/QPDFValue.hh> | |
| 4 | +#include <qpdf/QPDFObjectHandle_private.hh> | |
| 5 | +#include <qpdf/QPDFObject_private.hh> | |
| 6 | 6 | |
| 7 | 7 | #include <memory> |
| 8 | 8 | #include <string> |
| ... | ... | @@ -24,7 +24,7 @@ class QPDFParser |
| 24 | 24 | decrypter(decrypter), |
| 25 | 25 | context(context), |
| 26 | 26 | description( |
| 27 | - std::make_shared<QPDFValue::Description>( | |
| 27 | + std::make_shared<QPDFObject::Description>( | |
| 28 | 28 | std::string(input.getName() + ", " + object_description + " at offset $PO"))), |
| 29 | 29 | parse_pdf(parse_pdf) |
| 30 | 30 | { |
| ... | ... | @@ -78,7 +78,7 @@ class QPDFParser |
| 78 | 78 | QPDFTokenizer& tokenizer; |
| 79 | 79 | QPDFObjectHandle::StringDecrypter* decrypter; |
| 80 | 80 | QPDF* context; |
| 81 | - std::shared_ptr<QPDFValue::Description> description; | |
| 81 | + std::shared_ptr<QPDFObject::Description> description; | |
| 82 | 82 | bool parse_pdf; |
| 83 | 83 | |
| 84 | 84 | std::vector<StackFrame> stack; | ... | ... |
libqpdf/qpdf/QPDFValue.hh deleted
| 1 | -#ifndef QPDFVALUE_HH | |
| 2 | -#define QPDFVALUE_HH | |
| 3 | - | |
| 4 | -#include <qpdf/Constants.h> | |
| 5 | -#include <qpdf/DLL.h> | |
| 6 | -#include <qpdf/JSON.hh> | |
| 7 | -#include <qpdf/QPDFObjGen.hh> | |
| 8 | -#include <qpdf/Types.h> | |
| 9 | - | |
| 10 | -#include <string> | |
| 11 | -#include <string_view> | |
| 12 | -#include <variant> | |
| 13 | - | |
| 14 | -class QPDF; | |
| 15 | -class QPDFObjectHandle; | |
| 16 | -class QPDFObject; | |
| 17 | - | |
| 18 | -class QPDFValue: public std::enable_shared_from_this<QPDFValue> | |
| 19 | -{ | |
| 20 | - friend class QPDFObject; | |
| 21 | - | |
| 22 | - public: | |
| 23 | - virtual ~QPDFValue() = default; | |
| 24 | - | |
| 25 | - virtual std::shared_ptr<QPDFObject> copy(bool shallow = false) = 0; | |
| 26 | - virtual std::string unparse() = 0; | |
| 27 | - virtual void writeJSON(int json_version, JSON::Writer& p) = 0; | |
| 28 | - | |
| 29 | - struct JSON_Descr | |
| 30 | - { | |
| 31 | - JSON_Descr(std::shared_ptr<std::string> input, std::string const& object) : | |
| 32 | - input(input), | |
| 33 | - object(object) | |
| 34 | - { | |
| 35 | - } | |
| 36 | - | |
| 37 | - std::shared_ptr<std::string> input; | |
| 38 | - std::string object; | |
| 39 | - }; | |
| 40 | - | |
| 41 | - struct ChildDescr | |
| 42 | - { | |
| 43 | - ChildDescr( | |
| 44 | - std::shared_ptr<QPDFValue> parent, | |
| 45 | - std::string_view const& static_descr, | |
| 46 | - std::string var_descr) : | |
| 47 | - parent(parent), | |
| 48 | - static_descr(static_descr), | |
| 49 | - var_descr(var_descr) | |
| 50 | - { | |
| 51 | - } | |
| 52 | - | |
| 53 | - std::weak_ptr<QPDFValue> parent; | |
| 54 | - std::string_view const& static_descr; | |
| 55 | - std::string var_descr; | |
| 56 | - }; | |
| 57 | - | |
| 58 | - using Description = std::variant<std::string, JSON_Descr, ChildDescr>; | |
| 59 | - | |
| 60 | - virtual void | |
| 61 | - setDescription(QPDF* qpdf_p, std::shared_ptr<Description>& description, qpdf_offset_t offset) | |
| 62 | - { | |
| 63 | - qpdf = qpdf_p; | |
| 64 | - object_description = description; | |
| 65 | - setParsedOffset(offset); | |
| 66 | - } | |
| 67 | - void | |
| 68 | - setDefaultDescription(QPDF* a_qpdf, QPDFObjGen a_og) | |
| 69 | - { | |
| 70 | - qpdf = a_qpdf; | |
| 71 | - og = a_og; | |
| 72 | - } | |
| 73 | - void | |
| 74 | - setChildDescription( | |
| 75 | - QPDF* a_qpdf, | |
| 76 | - std::shared_ptr<QPDFValue> parent, | |
| 77 | - std::string_view const& static_descr, | |
| 78 | - std::string var_descr) | |
| 79 | - { | |
| 80 | - object_description = | |
| 81 | - std::make_shared<Description>(ChildDescr(parent, static_descr, var_descr)); | |
| 82 | - qpdf = a_qpdf; | |
| 83 | - } | |
| 84 | - std::string getDescription(); | |
| 85 | - bool | |
| 86 | - hasDescription() | |
| 87 | - { | |
| 88 | - return object_description || og.isIndirect(); | |
| 89 | - } | |
| 90 | - void | |
| 91 | - setParsedOffset(qpdf_offset_t offset) | |
| 92 | - { | |
| 93 | - if (parsed_offset < 0) { | |
| 94 | - parsed_offset = offset; | |
| 95 | - } | |
| 96 | - } | |
| 97 | - qpdf_offset_t | |
| 98 | - getParsedOffset() | |
| 99 | - { | |
| 100 | - return parsed_offset; | |
| 101 | - } | |
| 102 | - QPDF* | |
| 103 | - getQPDF() | |
| 104 | - { | |
| 105 | - return qpdf; | |
| 106 | - } | |
| 107 | - QPDFObjGen | |
| 108 | - getObjGen() | |
| 109 | - { | |
| 110 | - return og; | |
| 111 | - } | |
| 112 | - virtual void | |
| 113 | - disconnect() | |
| 114 | - { | |
| 115 | - } | |
| 116 | - virtual std::string | |
| 117 | - getStringValue() const | |
| 118 | - { | |
| 119 | - return ""; | |
| 120 | - } | |
| 121 | - | |
| 122 | - protected: | |
| 123 | - QPDFValue() = default; | |
| 124 | - | |
| 125 | - QPDFValue(qpdf_object_type_e type_code) : | |
| 126 | - type_code(type_code) | |
| 127 | - { | |
| 128 | - } | |
| 129 | - QPDFValue(qpdf_object_type_e type_code, QPDF* qpdf, QPDFObjGen og) : | |
| 130 | - type_code(type_code), | |
| 131 | - qpdf(qpdf), | |
| 132 | - og(og) | |
| 133 | - { | |
| 134 | - } | |
| 135 | - | |
| 136 | - static std::shared_ptr<QPDFObject> do_create(QPDFValue*); | |
| 137 | - | |
| 138 | - private: | |
| 139 | - QPDFValue(QPDFValue const&) = delete; | |
| 140 | - QPDFValue& operator=(QPDFValue const&) = delete; | |
| 141 | - std::shared_ptr<Description> object_description; | |
| 142 | - | |
| 143 | - const qpdf_object_type_e type_code{::ot_uninitialized}; | |
| 144 | - | |
| 145 | - protected: | |
| 146 | - QPDF* qpdf{nullptr}; | |
| 147 | - QPDFObjGen og{}; | |
| 148 | - qpdf_offset_t parsed_offset{-1}; | |
| 149 | -}; | |
| 150 | - | |
| 151 | -#endif // QPDFVALUE_HH |
libqpdf/qpdf/QPDF_Array.hh deleted
| 1 | -#ifndef QPDF_ARRAY_HH | |
| 2 | -#define QPDF_ARRAY_HH | |
| 3 | - | |
| 4 | -#include <qpdf/QPDFObjectHandle.hh> | |
| 5 | -#include <qpdf/QPDFObject_private.hh> | |
| 6 | -#include <qpdf/QPDFValue.hh> | |
| 7 | - | |
| 8 | -#include <map> | |
| 9 | -#include <vector> | |
| 10 | - | |
| 11 | -class QPDF_Array: public QPDFValue | |
| 12 | -{ | |
| 13 | - private: | |
| 14 | - struct Sparse | |
| 15 | - { | |
| 16 | - int size{0}; | |
| 17 | - std::map<int, std::shared_ptr<QPDFObject>> elements; | |
| 18 | - }; | |
| 19 | - | |
| 20 | - public: | |
| 21 | - ~QPDF_Array() override = default; | |
| 22 | - static std::shared_ptr<QPDFObject> create(std::vector<QPDFObjectHandle> const& items); | |
| 23 | - static std::shared_ptr<QPDFObject> | |
| 24 | - create(std::vector<std::shared_ptr<QPDFObject>>&& items, bool sparse); | |
| 25 | - std::shared_ptr<QPDFObject> copy(bool shallow = false) override; | |
| 26 | - std::string unparse() override; | |
| 27 | - void writeJSON(int json_version, JSON::Writer& p) override; | |
| 28 | - void disconnect() override; | |
| 29 | - | |
| 30 | - private: | |
| 31 | - friend class qpdf::Array; | |
| 32 | - QPDF_Array(); | |
| 33 | - QPDF_Array(QPDF_Array const&); | |
| 34 | - QPDF_Array(std::vector<QPDFObjectHandle> const& items); | |
| 35 | - QPDF_Array(std::vector<std::shared_ptr<QPDFObject>>&& items, bool sparse); | |
| 36 | - | |
| 37 | - int | |
| 38 | - size() const | |
| 39 | - { | |
| 40 | - return sp ? sp->size : int(elements.size()); | |
| 41 | - } | |
| 42 | - void setFromVector(std::vector<QPDFObjectHandle> const& items); | |
| 43 | - | |
| 44 | - void checkOwnership(QPDFObjectHandle const& item) const; | |
| 45 | - | |
| 46 | - std::unique_ptr<Sparse> sp; | |
| 47 | - std::vector<std::shared_ptr<QPDFObject>> elements; | |
| 48 | -}; | |
| 49 | - | |
| 50 | -#endif // QPDF_ARRAY_HH |
libqpdf/qpdf/QPDF_Bool.hh deleted
| 1 | -#ifndef QPDF_BOOL_HH | |
| 2 | -#define QPDF_BOOL_HH | |
| 3 | - | |
| 4 | -#include <qpdf/QPDFValue.hh> | |
| 5 | - | |
| 6 | -class QPDF_Bool: public QPDFValue | |
| 7 | -{ | |
| 8 | - public: | |
| 9 | - ~QPDF_Bool() override = default; | |
| 10 | - static std::shared_ptr<QPDFObject> create(bool val); | |
| 11 | - std::shared_ptr<QPDFObject> copy(bool shallow = false) override; | |
| 12 | - std::string unparse() override; | |
| 13 | - void writeJSON(int json_version, JSON::Writer& p) override; | |
| 14 | - | |
| 15 | - bool getVal() const; | |
| 16 | - | |
| 17 | - private: | |
| 18 | - QPDF_Bool(bool val); | |
| 19 | - bool val; | |
| 20 | -}; | |
| 21 | - | |
| 22 | -#endif // QPDF_BOOL_HH |
libqpdf/qpdf/QPDF_Destroyed.hh deleted
| 1 | -#ifndef QPDF_DESTROYED_HH | |
| 2 | -#define QPDF_DESTROYED_HH | |
| 3 | - | |
| 4 | -#include <qpdf/QPDFValue.hh> | |
| 5 | - | |
| 6 | -class QPDF_Destroyed: public QPDFValue | |
| 7 | -{ | |
| 8 | - public: | |
| 9 | - ~QPDF_Destroyed() override = default; | |
| 10 | - std::shared_ptr<QPDFObject> copy(bool shallow = false) override; | |
| 11 | - std::string unparse() override; | |
| 12 | - void writeJSON(int json_version, JSON::Writer& p) override; | |
| 13 | - static std::shared_ptr<QPDFValue> getInstance(); | |
| 14 | - | |
| 15 | - private: | |
| 16 | - QPDF_Destroyed(); | |
| 17 | -}; | |
| 18 | - | |
| 19 | -#endif // QPDF_DESTROYED_HH |
libqpdf/qpdf/QPDF_Dictionary.hh deleted
| 1 | -#ifndef QPDF_DICTIONARY_HH | |
| 2 | -#define QPDF_DICTIONARY_HH | |
| 3 | - | |
| 4 | -#include <qpdf/QPDFValue.hh> | |
| 5 | - | |
| 6 | -#include <map> | |
| 7 | -#include <set> | |
| 8 | - | |
| 9 | -#include <qpdf/QPDFExc.hh> | |
| 10 | -#include <qpdf/QPDFObjectHandle.hh> | |
| 11 | -#include <qpdf/QPDFObject_private.hh> | |
| 12 | -#include <qpdf/QPDF_Null.hh> | |
| 13 | - | |
| 14 | -class QPDF_Dictionary: public QPDFValue | |
| 15 | -{ | |
| 16 | - public: | |
| 17 | - ~QPDF_Dictionary() override = default; | |
| 18 | - static std::shared_ptr<QPDFObject> create(std::map<std::string, QPDFObjectHandle> const& items); | |
| 19 | - static std::shared_ptr<QPDFObject> create(std::map<std::string, QPDFObjectHandle>&& items); | |
| 20 | - std::shared_ptr<QPDFObject> copy(bool shallow = false) override; | |
| 21 | - std::string unparse() override; | |
| 22 | - void writeJSON(int json_version, JSON::Writer& p) override; | |
| 23 | - void disconnect() override; | |
| 24 | - | |
| 25 | - private: | |
| 26 | - friend class qpdf::BaseDictionary; | |
| 27 | - | |
| 28 | - QPDF_Dictionary(std::map<std::string, QPDFObjectHandle> const& items); | |
| 29 | - QPDF_Dictionary(std::map<std::string, QPDFObjectHandle>&& items); | |
| 30 | - | |
| 31 | - std::map<std::string, QPDFObjectHandle> items; | |
| 32 | -}; | |
| 33 | - | |
| 34 | -#endif // QPDF_DICTIONARY_HH |
libqpdf/qpdf/QPDF_InlineImage.hh deleted
| 1 | -#ifndef QPDF_INLINEIMAGE_HH | |
| 2 | -#define QPDF_INLINEIMAGE_HH | |
| 3 | - | |
| 4 | -#include <qpdf/QPDFValue.hh> | |
| 5 | - | |
| 6 | -class QPDF_InlineImage: public QPDFValue | |
| 7 | -{ | |
| 8 | - public: | |
| 9 | - ~QPDF_InlineImage() override = default; | |
| 10 | - static std::shared_ptr<QPDFObject> create(std::string const& val); | |
| 11 | - std::shared_ptr<QPDFObject> copy(bool shallow = false) override; | |
| 12 | - std::string unparse() override; | |
| 13 | - void writeJSON(int json_version, JSON::Writer& p) override; | |
| 14 | - std::string | |
| 15 | - getStringValue() const override | |
| 16 | - { | |
| 17 | - return val; | |
| 18 | - } | |
| 19 | - | |
| 20 | - private: | |
| 21 | - QPDF_InlineImage(std::string const& val); | |
| 22 | - std::string val; | |
| 23 | -}; | |
| 24 | - | |
| 25 | -#endif // QPDF_INLINEIMAGE_HH |
libqpdf/qpdf/QPDF_Integer.hh deleted
| 1 | -#ifndef QPDF_INTEGER_HH | |
| 2 | -#define QPDF_INTEGER_HH | |
| 3 | - | |
| 4 | -#include <qpdf/QPDFValue.hh> | |
| 5 | - | |
| 6 | -class QPDF_Integer: public QPDFValue | |
| 7 | -{ | |
| 8 | - public: | |
| 9 | - ~QPDF_Integer() override = default; | |
| 10 | - static std::shared_ptr<QPDFObject> create(long long value); | |
| 11 | - std::shared_ptr<QPDFObject> copy(bool shallow = false) override; | |
| 12 | - std::string unparse() override; | |
| 13 | - void writeJSON(int json_version, JSON::Writer& p) override; | |
| 14 | - long long getVal() const; | |
| 15 | - | |
| 16 | - private: | |
| 17 | - QPDF_Integer(long long val); | |
| 18 | - long long val; | |
| 19 | -}; | |
| 20 | - | |
| 21 | -#endif // QPDF_INTEGER_HH |
libqpdf/qpdf/QPDF_Name.hh
| 1 | -#ifndef QPDF_NAME_HH | |
| 2 | -#define QPDF_NAME_HH | |
| 3 | - | |
| 4 | -#include <qpdf/QPDFValue.hh> | |
| 5 | - | |
| 6 | -class QPDF_Name: public QPDFValue | |
| 7 | -{ | |
| 8 | - public: | |
| 9 | - ~QPDF_Name() override = default; | |
| 10 | - static std::shared_ptr<QPDFObject> create(std::string const& name); | |
| 11 | - std::shared_ptr<QPDFObject> copy(bool shallow = false) override; | |
| 12 | - std::string unparse() override; | |
| 13 | - void writeJSON(int json_version, JSON::Writer& p) override; | |
| 14 | - std::string | |
| 15 | - getStringValue() const override | |
| 16 | - { | |
| 17 | - return name; | |
| 18 | - } | |
| 19 | - | |
| 20 | - private: | |
| 21 | - QPDF_Name(std::string const& name); | |
| 22 | - std::string name; | |
| 23 | -}; | |
| 24 | - | |
| 25 | -#endif // QPDF_NAME_HH |
libqpdf/qpdf/QPDF_Null.hh deleted
| 1 | -#ifndef QPDF_NULL_HH | |
| 2 | -#define QPDF_NULL_HH | |
| 3 | - | |
| 4 | -#include <qpdf/QPDFValue.hh> | |
| 5 | - | |
| 6 | -class QPDF_Null: public QPDFValue | |
| 7 | -{ | |
| 8 | - public: | |
| 9 | - ~QPDF_Null() override = default; | |
| 10 | - static std::shared_ptr<QPDFObject> create(QPDF* qpdf = nullptr, QPDFObjGen og = QPDFObjGen()); | |
| 11 | - static std::shared_ptr<QPDFObject> create( | |
| 12 | - std::shared_ptr<QPDFObject> parent, | |
| 13 | - std::string_view const& static_descr, | |
| 14 | - std::string var_descr); | |
| 15 | - static std::shared_ptr<QPDFObject> create( | |
| 16 | - std::shared_ptr<QPDFValue> parent, | |
| 17 | - std::string_view const& static_descr, | |
| 18 | - std::string var_descr); | |
| 19 | - std::shared_ptr<QPDFObject> copy(bool shallow = false) override; | |
| 20 | - std::string unparse() override; | |
| 21 | - void writeJSON(int json_version, JSON::Writer& p) override; | |
| 22 | - | |
| 23 | - private: | |
| 24 | - QPDF_Null(QPDF* qpdf = nullptr, QPDFObjGen og = QPDFObjGen()); | |
| 25 | -}; | |
| 26 | - | |
| 27 | -#endif // QPDF_NULL_HH |
libqpdf/qpdf/QPDF_Operator.hh deleted
| 1 | -#ifndef QPDF_OPERATOR_HH | |
| 2 | -#define QPDF_OPERATOR_HH | |
| 3 | - | |
| 4 | -#include <qpdf/QPDFValue.hh> | |
| 5 | - | |
| 6 | -class QPDF_Operator: public QPDFValue | |
| 7 | -{ | |
| 8 | - public: | |
| 9 | - ~QPDF_Operator() override = default; | |
| 10 | - static std::shared_ptr<QPDFObject> create(std::string const& val); | |
| 11 | - std::shared_ptr<QPDFObject> copy(bool shallow = false) override; | |
| 12 | - std::string unparse() override; | |
| 13 | - void writeJSON(int json_version, JSON::Writer& p) override; | |
| 14 | - std::string | |
| 15 | - getStringValue() const override | |
| 16 | - { | |
| 17 | - return val; | |
| 18 | - } | |
| 19 | - | |
| 20 | - private: | |
| 21 | - QPDF_Operator(std::string const& val); | |
| 22 | - std::string val; | |
| 23 | -}; | |
| 24 | - | |
| 25 | -#endif // QPDF_OPERATOR_HH |
libqpdf/qpdf/QPDF_Real.hh deleted
| 1 | -#ifndef QPDF_REAL_HH | |
| 2 | -#define QPDF_REAL_HH | |
| 3 | - | |
| 4 | -#include <qpdf/QPDFValue.hh> | |
| 5 | - | |
| 6 | -class QPDF_Real: public QPDFValue | |
| 7 | -{ | |
| 8 | - public: | |
| 9 | - ~QPDF_Real() override = default; | |
| 10 | - static std::shared_ptr<QPDFObject> create(std::string const& val); | |
| 11 | - static std::shared_ptr<QPDFObject> | |
| 12 | - create(double value, int decimal_places, bool trim_trailing_zeroes); | |
| 13 | - std::shared_ptr<QPDFObject> copy(bool shallow = false) override; | |
| 14 | - std::string unparse() override; | |
| 15 | - void writeJSON(int json_version, JSON::Writer& p) override; | |
| 16 | - std::string | |
| 17 | - getStringValue() const override | |
| 18 | - { | |
| 19 | - return val; | |
| 20 | - } | |
| 21 | - | |
| 22 | - private: | |
| 23 | - QPDF_Real(std::string const& val); | |
| 24 | - QPDF_Real(double value, int decimal_places, bool trim_trailing_zeroes); | |
| 25 | - // Store reals as strings to avoid roundoff errors. | |
| 26 | - std::string val; | |
| 27 | -}; | |
| 28 | - | |
| 29 | -#endif // QPDF_REAL_HH |
libqpdf/qpdf/QPDF_Reserved.hh deleted
| 1 | -#ifndef QPDF_RESERVED_HH | |
| 2 | -#define QPDF_RESERVED_HH | |
| 3 | - | |
| 4 | -#include <qpdf/QPDFValue.hh> | |
| 5 | - | |
| 6 | -class QPDF_Reserved: public QPDFValue | |
| 7 | -{ | |
| 8 | - public: | |
| 9 | - ~QPDF_Reserved() override = default; | |
| 10 | - static std::shared_ptr<QPDFObject> create(); | |
| 11 | - std::shared_ptr<QPDFObject> copy(bool shallow = false) override; | |
| 12 | - std::string unparse() override; | |
| 13 | - void writeJSON(int json_version, JSON::Writer& p) override; | |
| 14 | - | |
| 15 | - private: | |
| 16 | - QPDF_Reserved(); | |
| 17 | -}; | |
| 18 | - | |
| 19 | -#endif // QPDF_RESERVED_HH |
libqpdf/qpdf/QPDF_Stream.hh deleted
| 1 | -#ifndef QPDF_STREAM_HH | |
| 2 | -#define QPDF_STREAM_HH | |
| 3 | - | |
| 4 | -#include <qpdf/Types.h> | |
| 5 | - | |
| 6 | -#include <qpdf/QPDFObjectHandle.hh> | |
| 7 | -#include <qpdf/QPDFObject_private.hh> | |
| 8 | -#include <qpdf/QPDFStreamFilter.hh> | |
| 9 | -#include <qpdf/QPDFValue.hh> | |
| 10 | - | |
| 11 | -#include <functional> | |
| 12 | -#include <memory> | |
| 13 | - | |
| 14 | -class Pipeline; | |
| 15 | -class QPDF; | |
| 16 | - | |
| 17 | -class QPDF_Stream final: public QPDFValue | |
| 18 | -{ | |
| 19 | - public: | |
| 20 | - ~QPDF_Stream() final = default; | |
| 21 | - static std::shared_ptr<QPDFObject> | |
| 22 | - create(QPDF*, QPDFObjGen og, QPDFObjectHandle stream_dict, qpdf_offset_t offset, size_t length); | |
| 23 | - std::shared_ptr<QPDFObject> copy(bool shallow = false) final; | |
| 24 | - std::string unparse() final; | |
| 25 | - void writeJSON(int json_version, JSON::Writer& p) final; | |
| 26 | - void setDescription( | |
| 27 | - QPDF*, std::shared_ptr<QPDFValue::Description>& description, qpdf_offset_t offset) final; | |
| 28 | - void disconnect() final; | |
| 29 | - | |
| 30 | - private: | |
| 31 | - friend class qpdf::Stream; | |
| 32 | - | |
| 33 | - QPDF_Stream( | |
| 34 | - QPDF*, QPDFObjGen og, QPDFObjectHandle stream_dict, qpdf_offset_t offset, size_t length); | |
| 35 | - | |
| 36 | - void replaceFilterData( | |
| 37 | - QPDFObjectHandle const& filter, QPDFObjectHandle const& decode_parms, size_t length); | |
| 38 | - void setDictDescription(); | |
| 39 | - | |
| 40 | - bool filter_on_write; | |
| 41 | - QPDFObjectHandle stream_dict; | |
| 42 | - size_t length; | |
| 43 | - std::shared_ptr<Buffer> stream_data; | |
| 44 | - std::shared_ptr<QPDFObjectHandle::StreamDataProvider> stream_provider; | |
| 45 | - std::vector<std::shared_ptr<QPDFObjectHandle::TokenFilter>> token_filters; | |
| 46 | -}; | |
| 47 | - | |
| 48 | -#endif // QPDF_STREAM_HH |
libqpdf/qpdf/QPDF_String.hh deleted
| 1 | -#ifndef QPDF_STRING_HH | |
| 2 | -#define QPDF_STRING_HH | |
| 3 | - | |
| 4 | -#include <qpdf/QPDFValue.hh> | |
| 5 | - | |
| 6 | -// QPDF_Strings may included embedded null characters. | |
| 7 | - | |
| 8 | -class QPDF_String: public QPDFValue | |
| 9 | -{ | |
| 10 | - friend class QPDFWriter; | |
| 11 | - | |
| 12 | - public: | |
| 13 | - ~QPDF_String() override = default; | |
| 14 | - static std::shared_ptr<QPDFObject> create(std::string const& val); | |
| 15 | - static std::shared_ptr<QPDFObject> create_utf16(std::string const& utf8_val); | |
| 16 | - std::shared_ptr<QPDFObject> copy(bool shallow = false) override; | |
| 17 | - std::string unparse() override; | |
| 18 | - std::string unparse(bool force_binary); | |
| 19 | - void writeJSON(int json_version, JSON::Writer& p) override; | |
| 20 | - std::string getUTF8Val() const; | |
| 21 | - std::string | |
| 22 | - getStringValue() const override | |
| 23 | - { | |
| 24 | - return val; | |
| 25 | - } | |
| 26 | - | |
| 27 | - private: | |
| 28 | - QPDF_String(std::string const& val); | |
| 29 | - bool useHexString() const; | |
| 30 | - std::string val; | |
| 31 | -}; | |
| 32 | - | |
| 33 | -#endif // QPDF_STRING_HH |
libqpdf/qpdf/QPDF_Unresolved.hh deleted
| 1 | -#ifndef QPDF_UNRESOLVED_HH | |
| 2 | -#define QPDF_UNRESOLVED_HH | |
| 3 | - | |
| 4 | -#include <qpdf/QPDFValue.hh> | |
| 5 | - | |
| 6 | -class QPDF_Unresolved: public QPDFValue | |
| 7 | -{ | |
| 8 | - public: | |
| 9 | - ~QPDF_Unresolved() override = default; | |
| 10 | - static std::shared_ptr<QPDFObject> create(QPDF* qpdf, QPDFObjGen og); | |
| 11 | - std::shared_ptr<QPDFObject> copy(bool shallow = false) override; | |
| 12 | - std::string unparse() override; | |
| 13 | - void writeJSON(int json_version, JSON::Writer& p) override; | |
| 14 | - std::string getStringValue() const override; | |
| 15 | - | |
| 16 | - private: | |
| 17 | - QPDF_Unresolved(QPDF* qpdf, QPDFObjGen og); | |
| 18 | -}; | |
| 19 | - | |
| 20 | -#endif // QPDF_UNRESOLVED_HH |
libtests/sparse_array.cc
| ... | ... | @@ -3,14 +3,13 @@ |
| 3 | 3 | #include <qpdf/QPDF.hh> |
| 4 | 4 | #include <qpdf/QPDFObjectHandle_private.hh> |
| 5 | 5 | #include <qpdf/QPDFObject_private.hh> |
| 6 | -#include <qpdf/QPDF_Array.hh> | |
| 7 | 6 | |
| 8 | 7 | #include <iostream> |
| 9 | 8 | |
| 10 | 9 | int |
| 11 | 10 | main() |
| 12 | 11 | { |
| 13 | - auto obj = QPDF_Array::create({}, true); | |
| 12 | + auto obj = QPDFObject::create<QPDF_Array>(std::vector<std::shared_ptr<QPDFObject>>(), true); | |
| 14 | 13 | auto a = qpdf::Array(obj); |
| 15 | 14 | |
| 16 | 15 | assert(a.size() == 0); |
| ... | ... | @@ -88,7 +87,8 @@ main() |
| 88 | 87 | QPDF pdf; |
| 89 | 88 | pdf.emptyPDF(); |
| 90 | 89 | |
| 91 | - obj = QPDF_Array::create({10, "null"_qpdf.getObj()}, true); | |
| 90 | + obj = QPDFObject::create<QPDF_Array>( | |
| 91 | + std::vector<std::shared_ptr<QPDFObject>>{10, "null"_qpdf.getObj()}, true); | |
| 92 | 92 | auto b = qpdf::Array(obj); |
| 93 | 93 | b.setAt(5, pdf.newIndirectNull()); |
| 94 | 94 | b.setAt(7, "[0 1 2 3]"_qpdf); | ... | ... |