Commit c36b76be772aaf3ed02e4a8d1b097bf0fdc94f9d

Authored by m-holger
1 parent eb629671

Add new methods BaseHandle::id_gen, indirect, qpdf and raw_typecode

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&amp; p) @@ -555,7 +551,7 @@ QPDFObject::write_json(int json_version, JSON::Writer&amp; 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&amp; value) const @@ -769,49 +765,49 @@ QPDFObjectHandle::getValueAsNumber(double&amp; 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 {