Commit a1a8f35b63bcad7e0cac31a205e109d6a0d70622

Authored by m-holger
1 parent 51d350c9

Refactor QPDF_Array::getItem and rename to at

libqpdf/QPDFObjectHandle.cc
@@ -801,90 +801,88 @@ QPDFObjectHandle::getArrayNItems() @@ -801,90 +801,88 @@ QPDFObjectHandle::getArrayNItems()
801 QPDFObjectHandle 801 QPDFObjectHandle
802 QPDFObjectHandle::getArrayItem(int n) 802 QPDFObjectHandle::getArrayItem(int n)
803 { 803 {
804 - auto array = asArray();  
805 - if (array && n < array->size() && n >= 0) {  
806 - return array->getItem(n);  
807 - } else {  
808 - if (array) { 804 + if (auto array = asArray()) {
  805 + if (auto result = array->at(n); result.obj != nullptr) {
  806 + return result;
  807 + } else {
809 objectWarning("returning null for out of bounds array access"); 808 objectWarning("returning null for out of bounds array access");
810 QTC::TC("qpdf", "QPDFObjectHandle array bounds"); 809 QTC::TC("qpdf", "QPDFObjectHandle array bounds");
811 - } else {  
812 - typeWarning("array", "returning null");  
813 - QTC::TC("qpdf", "QPDFObjectHandle array null for non-array");  
814 } 810 }
815 - static auto constexpr msg =  
816 - " -> null returned from invalid array access"sv;  
817 - return QPDF_Null::create(obj, msg, ""); 811 + } else {
  812 + typeWarning("array", "returning null");
  813 + QTC::TC("qpdf", "QPDFObjectHandle array null for non-array");
818 } 814 }
  815 + static auto constexpr msg = " -> null returned from invalid array access"sv;
  816 + return QPDF_Null::create(obj, msg, "");
819 } 817 }
820 818
821 bool 819 bool
822 QPDFObjectHandle::isRectangle() 820 QPDFObjectHandle::isRectangle()
823 { 821 {
824 - auto array = asArray();  
825 - if (array == nullptr || array->size() != 4) {  
826 - return false;  
827 - }  
828 - for (int i = 0; i < 4; ++i) {  
829 - if (!array->getItem(i).isNumber()) {  
830 - return false; 822 + if (auto array = asArray()) {
  823 + for (int i = 0; i < 4; ++i) {
  824 + if (auto item = array->at(i); !(item.obj && item.isNumber())) {
  825 + return false;
  826 + }
831 } 827 }
  828 + return array->size() == 4;
832 } 829 }
833 - return true; 830 + return false;
834 } 831 }
835 832
836 bool 833 bool
837 QPDFObjectHandle::isMatrix() 834 QPDFObjectHandle::isMatrix()
838 { 835 {
839 - auto array = asArray();  
840 - if (array == nullptr || array->size() != 6) {  
841 - return false;  
842 - }  
843 - for (int i = 0; i < 6; ++i) {  
844 - if (!array->getItem(i).isNumber()) {  
845 - return false; 836 + if (auto array = asArray()) {
  837 + for (int i = 0; i < 6; ++i) {
  838 + if (auto item = array->at(i); !(item.obj && item.isNumber())) {
  839 + return false;
  840 + }
846 } 841 }
  842 + return array->size() == 6;
847 } 843 }
848 - return true; 844 + return false;
849 } 845 }
850 846
851 QPDFObjectHandle::Rectangle 847 QPDFObjectHandle::Rectangle
852 QPDFObjectHandle::getArrayAsRectangle() 848 QPDFObjectHandle::getArrayAsRectangle()
853 { 849 {
854 - Rectangle result;  
855 - if (isRectangle()) {  
856 - auto array = asArray();  
857 - // Rectangle coordinates are always supposed to be llx, lly,  
858 - // urx, ury, but files have been found in the wild where  
859 - // llx > urx or lly > ury.  
860 - double i0 = array->getItem(0).getNumericValue();  
861 - double i1 = array->getItem(1).getNumericValue();  
862 - double i2 = array->getItem(2).getNumericValue();  
863 - double i3 = array->getItem(3).getNumericValue();  
864 - result = Rectangle(  
865 - std::min(i0, i2),  
866 - std::min(i1, i3),  
867 - std::max(i0, i2),  
868 - std::max(i1, i3)); 850 + if (auto array = asArray()) {
  851 + if (array->size() != 4) {
  852 + return {};
  853 + }
  854 + double items[4];
  855 + for (int i = 0; i < 4; ++i) {
  856 + if (!array->at(i).getValueAsNumber(items[i])) {
  857 + return {};
  858 + }
  859 + }
  860 + return Rectangle(
  861 + std::min(items[0], items[2]),
  862 + std::min(items[1], items[3]),
  863 + std::max(items[0], items[2]),
  864 + std::max(items[1], items[3]));
869 } 865 }
870 - return result; 866 + return {};
871 } 867 }
872 868
873 QPDFObjectHandle::Matrix 869 QPDFObjectHandle::Matrix
874 QPDFObjectHandle::getArrayAsMatrix() 870 QPDFObjectHandle::getArrayAsMatrix()
875 { 871 {
876 - Matrix result;  
877 - if (isMatrix()) {  
878 - auto array = asArray();  
879 - result = Matrix(  
880 - array->getItem(0).getNumericValue(),  
881 - array->getItem(1).getNumericValue(),  
882 - array->getItem(2).getNumericValue(),  
883 - array->getItem(3).getNumericValue(),  
884 - array->getItem(4).getNumericValue(),  
885 - array->getItem(5).getNumericValue()); 872 + if (auto array = asArray()) {
  873 + if (array->size() != 6) {
  874 + return {};
  875 + }
  876 + double items[6];
  877 + for (int i = 0; i < 6; ++i) {
  878 + if (!array->at(i).getValueAsNumber(items[i])) {
  879 + return {};
  880 + }
  881 + }
  882 + return Matrix(
  883 + items[0], items[1], items[2], items[3], items[4], items[5]);
886 } 884 }
887 - return result; 885 + return {};
888 } 886 }
889 887
890 std::vector<QPDFObjectHandle> 888 std::vector<QPDFObjectHandle>
@@ -991,8 +989,8 @@ QPDFObjectHandle @@ -991,8 +989,8 @@ QPDFObjectHandle
991 QPDFObjectHandle::eraseItemAndGetOld(int at) 989 QPDFObjectHandle::eraseItemAndGetOld(int at)
992 { 990 {
993 auto array = asArray(); 991 auto array = asArray();
994 - auto result = (array && at < array->size() && at >= 0) ? array->getItem(at)  
995 - : newNull(); 992 + auto result =
  993 + (array && at < array->size() && at >= 0) ? array->at(at) : newNull();
996 eraseItem(at); 994 eraseItem(at);
997 return result; 995 return result;
998 } 996 }
@@ -1515,7 +1513,7 @@ QPDFObjectHandle::arrayOrStreamToStreamArray( @@ -1515,7 +1513,7 @@ QPDFObjectHandle::arrayOrStreamToStreamArray(
1515 if (auto array = asArray()) { 1513 if (auto array = asArray()) {
1516 int n_items = array->size(); 1514 int n_items = array->size();
1517 for (int i = 0; i < n_items; ++i) { 1515 for (int i = 0; i < n_items; ++i) {
1518 - QPDFObjectHandle item = array->getItem(i); 1516 + QPDFObjectHandle item = array->at(i);
1519 if (item.isStream()) { 1517 if (item.isStream()) {
1520 result.push_back(item); 1518 result.push_back(item);
1521 } else { 1519 } else {
@@ -2215,7 +2213,7 @@ QPDFObjectHandle::makeDirect( @@ -2215,7 +2213,7 @@ QPDFObjectHandle::makeDirect(
2215 auto array = asArray(); 2213 auto array = asArray();
2216 int n = array->size(); 2214 int n = array->size();
2217 for (int i = 0; i < n; ++i) { 2215 for (int i = 0; i < n; ++i) {
2218 - items.push_back(array->getItem(i)); 2216 + items.push_back(array->at(i));
2219 items.back().makeDirect(visited, stop_at_streams); 2217 items.back().makeDirect(visited, stop_at_streams);
2220 } 2218 }
2221 this->obj = QPDF_Array::create(items); 2219 this->obj = QPDF_Array::create(items);
libqpdf/QPDF_Array.cc
@@ -105,7 +105,7 @@ QPDF_Array::unparse() @@ -105,7 +105,7 @@ QPDF_Array::unparse()
105 std::string result = "[ "; 105 std::string result = "[ ";
106 int size = sp_elements.size(); 106 int size = sp_elements.size();
107 for (int i = 0; i < size; ++i) { 107 for (int i = 0; i < size; ++i) {
108 - result += sp_elements.at(i).unparse(); 108 + result += at(i).unparse();
109 result += " "; 109 result += " ";
110 } 110 }
111 result += "]"; 111 result += "]";
@@ -114,7 +114,7 @@ QPDF_Array::unparse() @@ -114,7 +114,7 @@ QPDF_Array::unparse()
114 std::string result = "[ "; 114 std::string result = "[ ";
115 auto size = elements.size(); 115 auto size = elements.size();
116 for (int i = 0; i < int(size); ++i) { 116 for (int i = 0; i < int(size); ++i) {
117 - result += getItem(i).unparse(); 117 + result += at(i).unparse();
118 result += " "; 118 result += " ";
119 } 119 }
120 result += "]"; 120 result += "]";
@@ -129,35 +129,29 @@ QPDF_Array::getJSON(int json_version) @@ -129,35 +129,29 @@ QPDF_Array::getJSON(int json_version)
129 JSON j = JSON::makeArray(); 129 JSON j = JSON::makeArray();
130 int size = sp_elements.size(); 130 int size = sp_elements.size();
131 for (int i = 0; i < size; ++i) { 131 for (int i = 0; i < size; ++i) {
132 - j.addArrayElement(sp_elements.at(i).getJSON(json_version)); 132 + j.addArrayElement(at(i).getJSON(json_version));
133 } 133 }
134 return j; 134 return j;
135 } else { 135 } else {
136 JSON j = JSON::makeArray(); 136 JSON j = JSON::makeArray();
137 size_t size = elements.size(); 137 size_t size = elements.size();
138 for (int i = 0; i < int(size); ++i) { 138 for (int i = 0; i < int(size); ++i) {
139 - j.addArrayElement(getItem(i).getJSON(json_version)); 139 + j.addArrayElement(at(i).getJSON(json_version));
140 } 140 }
141 return j; 141 return j;
142 } 142 }
143 } 143 }
144 144
145 QPDFObjectHandle 145 QPDFObjectHandle
146 -QPDF_Array::getItem(int n) const 146 +QPDF_Array::at(int n) const noexcept
147 { 147 {
148 - if (sparse) {  
149 - if ((n < 0) || (n >= QIntC::to_int(sp_elements.size()))) {  
150 - throw std::logic_error(  
151 - "INTERNAL ERROR: bounds error accessing QPDF_Array element");  
152 - }  
153 - return sp_elements.at(n); 148 + if (n < 0 || n >= size()) {
  149 + return {};
  150 + } else if (sparse) {
  151 + auto const& iter = sp_elements.elements.find(n);
  152 + return iter == sp_elements.elements.end() ? null_oh : (*iter).second;
154 } else { 153 } else {
155 - if ((n < 0) || (n >= QIntC::to_int(elements.size()))) {  
156 - throw std::logic_error(  
157 - "INTERNAL ERROR: bounds error accessing QPDF_Array element");  
158 - }  
159 - auto const& obj = elements.at(size_t(n));  
160 - return obj ? obj : null_oh; 154 + return elements[size_t(n)];
161 } 155 }
162 } 156 }
163 157
@@ -167,7 +161,7 @@ QPDF_Array::getAsVector(std::vector&lt;QPDFObjectHandle&gt;&amp; v) const @@ -167,7 +161,7 @@ QPDF_Array::getAsVector(std::vector&lt;QPDFObjectHandle&gt;&amp; v) const
167 if (sparse) { 161 if (sparse) {
168 int size = sp_elements.size(); 162 int size = sp_elements.size();
169 for (int i = 0; i < size; ++i) { 163 for (int i = 0; i < size; ++i) {
170 - v.push_back(sp_elements.at(i)); 164 + v.push_back(at(i));
171 } 165 }
172 } else { 166 } else {
173 v = std::vector<QPDFObjectHandle>(elements.cbegin(), elements.cend()); 167 v = std::vector<QPDFObjectHandle>(elements.cbegin(), elements.cend());
libqpdf/SparseOHArray.cc
@@ -2,6 +2,8 @@ @@ -2,6 +2,8 @@
2 2
3 #include <stdexcept> 3 #include <stdexcept>
4 4
  5 +static const QPDFObjectHandle null_oh = QPDFObjectHandle::newNull();
  6 +
5 void 7 void
6 SparseOHArray::append(QPDFObjectHandle oh) 8 SparseOHArray::append(QPDFObjectHandle oh)
7 { 9 {
@@ -23,16 +25,8 @@ SparseOHArray::append(std::shared_ptr&lt;QPDFObject&gt;&amp;&amp; obj) @@ -23,16 +25,8 @@ SparseOHArray::append(std::shared_ptr&lt;QPDFObject&gt;&amp;&amp; obj)
23 QPDFObjectHandle 25 QPDFObjectHandle
24 SparseOHArray::at(int idx) const 26 SparseOHArray::at(int idx) const
25 { 27 {
26 - if (idx < 0 || idx >= this->n_elements) {  
27 - throw std::logic_error(  
28 - "INTERNAL ERROR: bounds error accessing SparseOHArray element");  
29 - }  
30 - auto const& iter = this->elements.find(idx);  
31 - if (iter == this->elements.end()) {  
32 - return QPDFObjectHandle::newNull();  
33 - } else {  
34 - return (*iter).second;  
35 - } 28 + auto const& iter = elements.find(idx);
  29 + return iter == elements.end() ? null_oh : (*iter).second;
36 } 30 }
37 31
38 void 32 void
libqpdf/qpdf/QPDF_Array.hh
@@ -27,7 +27,7 @@ class QPDF_Array: public QPDFValue @@ -27,7 +27,7 @@ class QPDF_Array: public QPDFValue
27 { 27 {
28 return sparse ? sp_elements.size() : int(elements.size()); 28 return sparse ? sp_elements.size() : int(elements.size());
29 } 29 }
30 - QPDFObjectHandle getItem(int n) const; 30 + QPDFObjectHandle at(int n) const noexcept;
31 void getAsVector(std::vector<QPDFObjectHandle>&) const; 31 void getAsVector(std::vector<QPDFObjectHandle>&) const;
32 32
33 void setItem(int, QPDFObjectHandle const&); 33 void setItem(int, QPDFObjectHandle const&);
libqpdf/qpdf/SparseOHArray.hh
@@ -12,7 +12,7 @@ class SparseOHArray @@ -12,7 +12,7 @@ class SparseOHArray
12 public: 12 public:
13 SparseOHArray() = default; 13 SparseOHArray() = default;
14 int 14 int
15 - size() const 15 + size() const noexcept
16 { 16 {
17 return n_elements; 17 return n_elements;
18 } 18 }