Commit c36b76be772aaf3ed02e4a8d1b097bf0fdc94f9d
1 parent
eb629671
Add new methods BaseHandle::id_gen, indirect, qpdf and raw_typecode
Showing
5 changed files
with
72 additions
and
55 deletions
include/qpdf/ObjectHandle.hh
| @@ -28,6 +28,7 @@ | @@ -28,6 +28,7 @@ | ||
| 28 | #include <cstdint> | 28 | #include <cstdint> |
| 29 | #include <memory> | 29 | #include <memory> |
| 30 | 30 | ||
| 31 | +class QPDF; | ||
| 31 | class QPDF_Dictionary; | 32 | class QPDF_Dictionary; |
| 32 | class QPDFObject; | 33 | class QPDFObject; |
| 33 | class QPDFObjectHandle; | 34 | class QPDFObjectHandle; |
| @@ -53,7 +54,11 @@ namespace qpdf | @@ -53,7 +54,11 @@ namespace qpdf | ||
| 53 | 54 | ||
| 54 | // The rest of the header file is for qpdf internal use only. | 55 | // The rest of the header file is for qpdf internal use only. |
| 55 | 56 | ||
| 57 | + inline QPDFObjGen id_gen() const; | ||
| 58 | + inline bool indirect() const; | ||
| 56 | inline bool null() const; | 59 | inline bool null() const; |
| 60 | + inline QPDF* qpdf() const; | ||
| 61 | + inline qpdf_object_type_e raw_type_code() const; | ||
| 57 | inline qpdf_object_type_e type_code() const; | 62 | inline qpdf_object_type_e type_code() const; |
| 58 | 63 | ||
| 59 | protected: | 64 | protected: |
libqpdf/QPDFObjectHandle.cc
| @@ -319,20 +319,16 @@ QPDFObject::copy(bool shallow) | @@ -319,20 +319,16 @@ QPDFObject::copy(bool shallow) | ||
| 319 | QPDF_Array result; | 319 | QPDF_Array result; |
| 320 | result.sp = std::make_unique<QPDF_Array::Sparse>(); | 320 | result.sp = std::make_unique<QPDF_Array::Sparse>(); |
| 321 | result.sp->size = a.sp->size; | 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.getObj()->getObjGen().isIndirect() ? obj : obj.getObj()->copy(); | 322 | + for (auto const& [idx, oh]: a.sp->elements) { |
| 323 | + result.sp->elements[idx] = oh.indirect() ? oh : oh.getObj()->copy(); | ||
| 326 | } | 324 | } |
| 327 | return QPDFObject::create<QPDF_Array>(std::move(result)); | 325 | return QPDFObject::create<QPDF_Array>(std::move(result)); |
| 328 | } else { | 326 | } else { |
| 329 | std::vector<QPDFObjectHandle> result; | 327 | std::vector<QPDFObjectHandle> result; |
| 330 | result.reserve(a.elements.size()); | 328 | result.reserve(a.elements.size()); |
| 331 | for (auto const& element: a.elements) { | 329 | for (auto const& element: a.elements) { |
| 332 | - result.push_back( | ||
| 333 | - element ? (element.getObj()->getObjGen().isIndirect() | ||
| 334 | - ? element | ||
| 335 | - : element.getObj()->copy()) | 330 | + result.emplace_back( |
| 331 | + element ? (element.indirect() ? element : element.getObj()->copy()) | ||
| 336 | : element); | 332 | : element); |
| 337 | } | 333 | } |
| 338 | return QPDFObject::create<QPDF_Array>(std::move(result), false); | 334 | return QPDFObject::create<QPDF_Array>(std::move(result), false); |
| @@ -347,7 +343,7 @@ QPDFObject::copy(bool shallow) | @@ -347,7 +343,7 @@ QPDFObject::copy(bool shallow) | ||
| 347 | } else { | 343 | } else { |
| 348 | std::map<std::string, QPDFObjectHandle> new_items; | 344 | std::map<std::string, QPDFObjectHandle> new_items; |
| 349 | for (auto const& [key, val]: d.items) { | 345 | for (auto const& [key, val]: d.items) { |
| 350 | - new_items[key] = val.isIndirect() ? val : val.getObj()->copy(); | 346 | + new_items[key] = val.indirect() ? val : val.getObj()->copy(); |
| 351 | } | 347 | } |
| 352 | return QPDFObject::create<QPDF_Dictionary>(new_items); | 348 | return QPDFObject::create<QPDF_Dictionary>(new_items); |
| 353 | } | 349 | } |
| @@ -405,7 +401,7 @@ QPDFObject::unparse() | @@ -405,7 +401,7 @@ QPDFObject::unparse() | ||
| 405 | for (int j = next; j < key; ++j) { | 401 | for (int j = next; j < key; ++j) { |
| 406 | result += "null "; | 402 | result += "null "; |
| 407 | } | 403 | } |
| 408 | - auto item_og = item.second.getObj()->resolved_object()->getObjGen(); | 404 | + auto item_og = item.second.id_gen(); |
| 409 | result += item_og.isIndirect() ? item_og.unparse(' ') + " R " | 405 | result += item_og.isIndirect() ? item_og.unparse(' ') + " R " |
| 410 | : item.second.getObj()->unparse() + " "; | 406 | : item.second.getObj()->unparse() + " "; |
| 411 | next = ++key; | 407 | next = ++key; |
| @@ -415,7 +411,7 @@ QPDFObject::unparse() | @@ -415,7 +411,7 @@ QPDFObject::unparse() | ||
| 415 | } | 411 | } |
| 416 | } else { | 412 | } else { |
| 417 | for (auto const& item: a.elements) { | 413 | for (auto const& item: a.elements) { |
| 418 | - auto item_og = item.getObj()->resolved_object()->getObjGen(); | 414 | + auto item_og = item.id_gen(); |
| 419 | result += item_og.isIndirect() ? item_og.unparse(' ') + " R " | 415 | result += item_og.isIndirect() ? item_og.unparse(' ') + " R " |
| 420 | : item.getObj()->unparse() + " "; | 416 | : item.getObj()->unparse() + " "; |
| 421 | } | 417 | } |
| @@ -428,7 +424,7 @@ QPDFObject::unparse() | @@ -428,7 +424,7 @@ QPDFObject::unparse() | ||
| 428 | auto const& items = std::get<QPDF_Dictionary>(value).items; | 424 | auto const& items = std::get<QPDF_Dictionary>(value).items; |
| 429 | std::string result = "<< "; | 425 | std::string result = "<< "; |
| 430 | for (auto& iter: items) { | 426 | for (auto& iter: items) { |
| 431 | - if (!iter.second.isNull()) { | 427 | + if (!iter.second.null()) { |
| 432 | result += Name::normalize(iter.first) + " " + iter.second.unparse() + " "; | 428 | result += Name::normalize(iter.first) + " " + iter.second.unparse() + " "; |
| 433 | } | 429 | } |
| 434 | } | 430 | } |
| @@ -555,7 +551,7 @@ QPDFObject::write_json(int json_version, JSON::Writer& p) | @@ -555,7 +551,7 @@ QPDFObject::write_json(int json_version, JSON::Writer& p) | ||
| 555 | auto const& d = std::get<QPDF_Dictionary>(value); | 551 | auto const& d = std::get<QPDF_Dictionary>(value); |
| 556 | p.writeStart('{'); | 552 | p.writeStart('{'); |
| 557 | for (auto& iter: d.items) { | 553 | for (auto& iter: d.items) { |
| 558 | - if (!iter.second.isNull()) { | 554 | + if (!iter.second.null()) { |
| 559 | p.writeNext(); | 555 | p.writeNext(); |
| 560 | if (json_version == 1) { | 556 | if (json_version == 1) { |
| 561 | p << "\"" << JSON::Writer::encode_string(Name::normalize(iter.first)) | 557 | p << "\"" << JSON::Writer::encode_string(Name::normalize(iter.first)) |
| @@ -599,13 +595,13 @@ QPDFObject::disconnect() | @@ -599,13 +595,13 @@ QPDFObject::disconnect() | ||
| 599 | if (a.sp) { | 595 | if (a.sp) { |
| 600 | for (auto& item: a.sp->elements) { | 596 | for (auto& item: a.sp->elements) { |
| 601 | auto& obj = item.second; | 597 | auto& obj = item.second; |
| 602 | - if (!obj.getObj()->getObjGen().isIndirect()) { | 598 | + if (!obj.indirect()) { |
| 603 | obj.getObj()->disconnect(); | 599 | obj.getObj()->disconnect(); |
| 604 | } | 600 | } |
| 605 | } | 601 | } |
| 606 | } else { | 602 | } else { |
| 607 | for (auto& obj: a.elements) { | 603 | for (auto& obj: a.elements) { |
| 608 | - if (!obj.getObj()->getObjGen().isIndirect()) { | 604 | + if (!obj.indirect()) { |
| 609 | obj.getObj()->disconnect(); | 605 | obj.getObj()->disconnect(); |
| 610 | } | 606 | } |
| 611 | } | 607 | } |
| @@ -701,13 +697,13 @@ QPDFObjectHandle::getTypeName() const | @@ -701,13 +697,13 @@ QPDFObjectHandle::getTypeName() const | ||
| 701 | bool | 697 | bool |
| 702 | QPDFObjectHandle::isDestroyed() const | 698 | QPDFObjectHandle::isDestroyed() const |
| 703 | { | 699 | { |
| 704 | - return obj && obj->getResolvedTypeCode() == ::ot_destroyed; | 700 | + return type_code() == ::ot_destroyed; |
| 705 | } | 701 | } |
| 706 | 702 | ||
| 707 | bool | 703 | bool |
| 708 | QPDFObjectHandle::isBool() const | 704 | QPDFObjectHandle::isBool() const |
| 709 | { | 705 | { |
| 710 | - return obj && obj->getResolvedTypeCode() == ::ot_boolean; | 706 | + return type_code() == ::ot_boolean; |
| 711 | } | 707 | } |
| 712 | 708 | ||
| 713 | bool | 709 | bool |
| @@ -715,25 +711,25 @@ QPDFObjectHandle::isDirectNull() const | @@ -715,25 +711,25 @@ QPDFObjectHandle::isDirectNull() const | ||
| 715 | { | 711 | { |
| 716 | // Don't call dereference() -- this is a const method, and we know | 712 | // Don't call dereference() -- this is a const method, and we know |
| 717 | // objid == 0, so there's nothing to resolve. | 713 | // objid == 0, so there's nothing to resolve. |
| 718 | - return (obj && getObjectID() == 0 && obj->getTypeCode() == ::ot_null); | 714 | + return !indirect() && raw_type_code() == ::ot_null; |
| 719 | } | 715 | } |
| 720 | 716 | ||
| 721 | bool | 717 | bool |
| 722 | QPDFObjectHandle::isNull() const | 718 | QPDFObjectHandle::isNull() const |
| 723 | { | 719 | { |
| 724 | - return obj && obj->getResolvedTypeCode() == ::ot_null; | 720 | + return type_code() == ::ot_null; |
| 725 | } | 721 | } |
| 726 | 722 | ||
| 727 | bool | 723 | bool |
| 728 | QPDFObjectHandle::isInteger() const | 724 | QPDFObjectHandle::isInteger() const |
| 729 | { | 725 | { |
| 730 | - return obj && obj->getResolvedTypeCode() == ::ot_integer; | 726 | + return type_code() == ::ot_integer; |
| 731 | } | 727 | } |
| 732 | 728 | ||
| 733 | bool | 729 | bool |
| 734 | QPDFObjectHandle::isReal() const | 730 | QPDFObjectHandle::isReal() const |
| 735 | { | 731 | { |
| 736 | - return obj && obj->getResolvedTypeCode() == ::ot_real; | 732 | + return type_code() == ::ot_real; |
| 737 | } | 733 | } |
| 738 | 734 | ||
| 739 | bool | 735 | bool |
| @@ -769,49 +765,49 @@ QPDFObjectHandle::getValueAsNumber(double& value) const | @@ -769,49 +765,49 @@ QPDFObjectHandle::getValueAsNumber(double& value) const | ||
| 769 | bool | 765 | bool |
| 770 | QPDFObjectHandle::isName() const | 766 | QPDFObjectHandle::isName() const |
| 771 | { | 767 | { |
| 772 | - return obj && obj->getResolvedTypeCode() == ::ot_name; | 768 | + return type_code() == ::ot_name; |
| 773 | } | 769 | } |
| 774 | 770 | ||
| 775 | bool | 771 | bool |
| 776 | QPDFObjectHandle::isString() const | 772 | QPDFObjectHandle::isString() const |
| 777 | { | 773 | { |
| 778 | - return obj && obj->getResolvedTypeCode() == ::ot_string; | 774 | + return type_code() == ::ot_string; |
| 779 | } | 775 | } |
| 780 | 776 | ||
| 781 | bool | 777 | bool |
| 782 | QPDFObjectHandle::isOperator() const | 778 | QPDFObjectHandle::isOperator() const |
| 783 | { | 779 | { |
| 784 | - return obj && obj->getResolvedTypeCode() == ::ot_operator; | 780 | + return type_code() == ::ot_operator; |
| 785 | } | 781 | } |
| 786 | 782 | ||
| 787 | bool | 783 | bool |
| 788 | QPDFObjectHandle::isInlineImage() const | 784 | QPDFObjectHandle::isInlineImage() const |
| 789 | { | 785 | { |
| 790 | - return obj && obj->getResolvedTypeCode() == ::ot_inlineimage; | 786 | + return type_code() == ::ot_inlineimage; |
| 791 | } | 787 | } |
| 792 | 788 | ||
| 793 | bool | 789 | bool |
| 794 | QPDFObjectHandle::isArray() const | 790 | QPDFObjectHandle::isArray() const |
| 795 | { | 791 | { |
| 796 | - return obj && obj->getResolvedTypeCode() == ::ot_array; | 792 | + return type_code() == ::ot_array; |
| 797 | } | 793 | } |
| 798 | 794 | ||
| 799 | bool | 795 | bool |
| 800 | QPDFObjectHandle::isDictionary() const | 796 | QPDFObjectHandle::isDictionary() const |
| 801 | { | 797 | { |
| 802 | - return obj && obj->getResolvedTypeCode() == ::ot_dictionary; | 798 | + return type_code() == ::ot_dictionary; |
| 803 | } | 799 | } |
| 804 | 800 | ||
| 805 | bool | 801 | bool |
| 806 | QPDFObjectHandle::isStream() const | 802 | QPDFObjectHandle::isStream() const |
| 807 | { | 803 | { |
| 808 | - return obj && obj->getResolvedTypeCode() == ::ot_stream; | 804 | + return type_code() == ::ot_stream; |
| 809 | } | 805 | } |
| 810 | 806 | ||
| 811 | bool | 807 | bool |
| 812 | QPDFObjectHandle::isReserved() const | 808 | QPDFObjectHandle::isReserved() const |
| 813 | { | 809 | { |
| 814 | - return obj && obj->getResolvedTypeCode() == ::ot_reserved; | 810 | + return type_code() == ::ot_reserved; |
| 815 | } | 811 | } |
| 816 | 812 | ||
| 817 | bool | 813 | bool |
libqpdf/QPDF_Array.cc
| @@ -10,28 +10,22 @@ static const QPDFObjectHandle null_oh = QPDFObjectHandle::newNull(); | @@ -10,28 +10,22 @@ static const QPDFObjectHandle null_oh = QPDFObjectHandle::newNull(); | ||
| 10 | inline void | 10 | inline void |
| 11 | Array::checkOwnership(QPDFObjectHandle const& item) const | 11 | Array::checkOwnership(QPDFObjectHandle const& item) const |
| 12 | { | 12 | { |
| 13 | - if (auto o = item.getObjectPtr()) { | ||
| 14 | - if (auto pdf = obj->getQPDF()) { | ||
| 15 | - if (auto item_qpdf = o->getQPDF()) { | ||
| 16 | - if (pdf != item_qpdf) { | ||
| 17 | - throw std::logic_error( | ||
| 18 | - "Attempting to add an object from a different QPDF. Use " | ||
| 19 | - "QPDF::copyForeignObject to add objects from another file."); | ||
| 20 | - } | ||
| 21 | - } | ||
| 22 | - } | ||
| 23 | - } else { | 13 | + if (!item) { |
| 24 | throw std::logic_error("Attempting to add an uninitialized object to a QPDF_Array."); | 14 | throw std::logic_error("Attempting to add an uninitialized object to a QPDF_Array."); |
| 25 | } | 15 | } |
| 16 | + if (qpdf() && item.qpdf() && qpdf() != item.qpdf()) { | ||
| 17 | + throw std::logic_error( | ||
| 18 | + "Attempting to add an object from a different QPDF. Use " | ||
| 19 | + "QPDF::copyForeignObject to add objects from another file."); | ||
| 20 | + } | ||
| 26 | } | 21 | } |
| 27 | 22 | ||
| 28 | QPDF_Array::QPDF_Array(std::vector<QPDFObjectHandle>&& v, bool sparse) | 23 | QPDF_Array::QPDF_Array(std::vector<QPDFObjectHandle>&& v, bool sparse) |
| 29 | { | 24 | { |
| 30 | if (sparse) { | 25 | if (sparse) { |
| 31 | sp = std::make_unique<Sparse>(); | 26 | sp = std::make_unique<Sparse>(); |
| 32 | - for (auto&& item: v) { | ||
| 33 | - if (item.getObj()->getTypeCode() != ::ot_null || | ||
| 34 | - item.getObj()->getObjGen().isIndirect()) { | 27 | + for (auto& item: v) { |
| 28 | + if (item.raw_type_code() != ::ot_null || item.indirect()) { | ||
| 35 | sp->elements[sp->size] = std::move(item); | 29 | sp->elements[sp->size] = std::move(item); |
| 36 | } | 30 | } |
| 37 | ++sp->size; | 31 | ++sp->size; |
libqpdf/qpdf/QPDFObjectHandle_private.hh
| @@ -325,16 +325,49 @@ namespace qpdf | @@ -325,16 +325,49 @@ namespace qpdf | ||
| 325 | return nullptr; | 325 | return nullptr; |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | + inline QPDFObjGen | ||
| 329 | + BaseHandle::id_gen() const | ||
| 330 | + { | ||
| 331 | + return obj ? obj->og : QPDFObjGen(); | ||
| 332 | + } | ||
| 333 | + | ||
| 334 | + inline bool | ||
| 335 | + BaseHandle::indirect() const | ||
| 336 | + { | ||
| 337 | + return obj ? obj->og.isIndirect() : false; | ||
| 338 | + } | ||
| 339 | + | ||
| 328 | inline bool | 340 | inline bool |
| 329 | BaseHandle::null() const | 341 | BaseHandle::null() const |
| 330 | { | 342 | { |
| 331 | return !obj || obj->getResolvedTypeCode() == ::ot_null; | 343 | return !obj || obj->getResolvedTypeCode() == ::ot_null; |
| 332 | } | 344 | } |
| 333 | 345 | ||
| 346 | + inline QPDF* | ||
| 347 | + BaseHandle::qpdf() const | ||
| 348 | + { | ||
| 349 | + return obj ? obj->qpdf : nullptr; | ||
| 350 | + } | ||
| 351 | + | ||
| 352 | + inline qpdf_object_type_e | ||
| 353 | + BaseHandle::raw_type_code() const | ||
| 354 | + { | ||
| 355 | + return obj ? static_cast<qpdf_object_type_e>(obj->value.index()) : ::ot_uninitialized; | ||
| 356 | + } | ||
| 357 | + | ||
| 334 | inline qpdf_object_type_e | 358 | inline qpdf_object_type_e |
| 335 | BaseHandle::type_code() const | 359 | BaseHandle::type_code() const |
| 336 | { | 360 | { |
| 337 | - return obj ? obj->getResolvedTypeCode() : ::ot_uninitialized; | 361 | + if (!obj) { |
| 362 | + return ::ot_uninitialized; | ||
| 363 | + } | ||
| 364 | + if (raw_type_code() == ::ot_unresolved) { | ||
| 365 | + return QPDF::Resolver::resolved(obj->qpdf, obj->og)->getTypeCode(); | ||
| 366 | + } | ||
| 367 | + if (raw_type_code() == ::ot_reference) { | ||
| 368 | + return std::get<QPDF_Reference>(obj->value).obj->getResolvedTypeCode(); | ||
| 369 | + } | ||
| 370 | + return raw_type_code(); | ||
| 338 | } | 371 | } |
| 339 | 372 | ||
| 340 | } // namespace qpdf | 373 | } // namespace qpdf |
libqpdf/qpdf/QPDFObject_private.hh
| @@ -308,17 +308,6 @@ class QPDFObject | @@ -308,17 +308,6 @@ class QPDFObject | ||
| 308 | { | 308 | { |
| 309 | return static_cast<qpdf_object_type_e>(value.index()); | 309 | return static_cast<qpdf_object_type_e>(value.index()); |
| 310 | } | 310 | } |
| 311 | - | ||
| 312 | - QPDF* | ||
| 313 | - getQPDF() const | ||
| 314 | - { | ||
| 315 | - return qpdf; | ||
| 316 | - } | ||
| 317 | - QPDFObjGen | ||
| 318 | - getObjGen() const | ||
| 319 | - { | ||
| 320 | - return og; | ||
| 321 | - } | ||
| 322 | void | 311 | void |
| 323 | assign_null() | 312 | assign_null() |
| 324 | { | 313 | { |