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 801 QPDFObjectHandle
802 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 808 objectWarning("returning null for out of bounds array access");
810 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 819 bool
822 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 833 bool
837 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 847 QPDFObjectHandle::Rectangle
852 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 869 QPDFObjectHandle::Matrix
874 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 888 std::vector<QPDFObjectHandle>
... ... @@ -991,8 +989,8 @@ QPDFObjectHandle
991 989 QPDFObjectHandle::eraseItemAndGetOld(int at)
992 990 {
993 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 994 eraseItem(at);
997 995 return result;
998 996 }
... ... @@ -1515,7 +1513,7 @@ QPDFObjectHandle::arrayOrStreamToStreamArray(
1515 1513 if (auto array = asArray()) {
1516 1514 int n_items = array->size();
1517 1515 for (int i = 0; i < n_items; ++i) {
1518   - QPDFObjectHandle item = array->getItem(i);
  1516 + QPDFObjectHandle item = array->at(i);
1519 1517 if (item.isStream()) {
1520 1518 result.push_back(item);
1521 1519 } else {
... ... @@ -2215,7 +2213,7 @@ QPDFObjectHandle::makeDirect(
2215 2213 auto array = asArray();
2216 2214 int n = array->size();
2217 2215 for (int i = 0; i < n; ++i) {
2218   - items.push_back(array->getItem(i));
  2216 + items.push_back(array->at(i));
2219 2217 items.back().makeDirect(visited, stop_at_streams);
2220 2218 }
2221 2219 this->obj = QPDF_Array::create(items);
... ...
libqpdf/QPDF_Array.cc
... ... @@ -105,7 +105,7 @@ QPDF_Array::unparse()
105 105 std::string result = "[ ";
106 106 int size = sp_elements.size();
107 107 for (int i = 0; i < size; ++i) {
108   - result += sp_elements.at(i).unparse();
  108 + result += at(i).unparse();
109 109 result += " ";
110 110 }
111 111 result += "]";
... ... @@ -114,7 +114,7 @@ QPDF_Array::unparse()
114 114 std::string result = "[ ";
115 115 auto size = elements.size();
116 116 for (int i = 0; i < int(size); ++i) {
117   - result += getItem(i).unparse();
  117 + result += at(i).unparse();
118 118 result += " ";
119 119 }
120 120 result += "]";
... ... @@ -129,35 +129,29 @@ QPDF_Array::getJSON(int json_version)
129 129 JSON j = JSON::makeArray();
130 130 int size = sp_elements.size();
131 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 134 return j;
135 135 } else {
136 136 JSON j = JSON::makeArray();
137 137 size_t size = elements.size();
138 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 141 return j;
142 142 }
143 143 }
144 144  
145 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 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 161 if (sparse) {
168 162 int size = sp_elements.size();
169 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 166 } else {
173 167 v = std::vector<QPDFObjectHandle>(elements.cbegin(), elements.cend());
... ...
libqpdf/SparseOHArray.cc
... ... @@ -2,6 +2,8 @@
2 2  
3 3 #include <stdexcept>
4 4  
  5 +static const QPDFObjectHandle null_oh = QPDFObjectHandle::newNull();
  6 +
5 7 void
6 8 SparseOHArray::append(QPDFObjectHandle oh)
7 9 {
... ... @@ -23,16 +25,8 @@ SparseOHArray::append(std::shared_ptr&lt;QPDFObject&gt;&amp;&amp; obj)
23 25 QPDFObjectHandle
24 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 32 void
... ...
libqpdf/qpdf/QPDF_Array.hh
... ... @@ -27,7 +27,7 @@ class QPDF_Array: public QPDFValue
27 27 {
28 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 31 void getAsVector(std::vector<QPDFObjectHandle>&) const;
32 32  
33 33 void setItem(int, QPDFObjectHandle const&);
... ...
libqpdf/qpdf/SparseOHArray.hh
... ... @@ -12,7 +12,7 @@ class SparseOHArray
12 12 public:
13 13 SparseOHArray() = default;
14 14 int
15   - size() const
  15 + size() const noexcept
16 16 {
17 17 return n_elements;
18 18 }
... ...