Commit 306f0efa56b3227e9015bdf3b0d84b68bb9687a3

Authored by m-holger
1 parent a03c6863

Refactor QPDF_Array

Move all array-specific methods to new class qpdf::Array.
include/qpdf/ObjectHandle.hh
... ... @@ -26,6 +26,7 @@
26 26 #include <qpdf/Types.h>
27 27  
28 28 #include <cstdint>
  29 +#include <memory>
29 30  
30 31 class QPDF_Dictionary;
31 32 class QPDFObject;
... ... @@ -33,6 +34,7 @@ class QPDFObjectHandle;
33 34  
34 35 namespace qpdf
35 36 {
  37 + class Array;
36 38 class Dictionary;
37 39 class BaseDictionary;
38 40  
... ...
include/qpdf/QPDFObjectHandle.hh
... ... @@ -1355,6 +1355,7 @@ class QPDFObjectHandle final: public qpdf::BaseHandle
1355 1355  
1356 1356 void writeJSON(int json_version, JSON::Writer& p, bool dereference_indirect = false) const;
1357 1357  
  1358 + inline qpdf::Array as_array(qpdf::typed options = qpdf::typed::any) const;
1358 1359 inline qpdf::Dictionary as_dictionary(qpdf::typed options = qpdf::typed::any) const;
1359 1360  
1360 1361 private:
... ...
libqpdf/QPDFObjectHandle.cc
... ... @@ -777,22 +777,20 @@ QPDFObjectHandle::aitems()
777 777 int
778 778 QPDFObjectHandle::getArrayNItems() const
779 779 {
780   - if (auto array = asArray()) {
781   - return array->size();
782   - } else {
783   - typeWarning("array", "treating as empty");
784   - QTC::TC("qpdf", "QPDFObjectHandle array treating as empty");
785   - return 0;
  780 + if (auto array = as_array(strict)) {
  781 + return array.size();
786 782 }
  783 + typeWarning("array", "treating as empty");
  784 + QTC::TC("qpdf", "QPDFObjectHandle array treating as empty");
  785 + return 0;
787 786 }
788 787  
789 788 QPDFObjectHandle
790 789 QPDFObjectHandle::getArrayItem(int n) const
791 790 {
792   - if (auto array = asArray()) {
793   - auto result = array->at(n);
794   - if (result.first) {
795   - return result.second;
  791 + if (auto array = as_array(strict)) {
  792 + if (auto const [success, oh] = array.at(n); success) {
  793 + return oh;
796 794 } else {
797 795 objectWarning("returning null for out of bounds array access");
798 796 QTC::TC("qpdf", "QPDFObjectHandle array bounds");
... ... @@ -808,13 +806,13 @@ QPDFObjectHandle::getArrayItem(int n) const
808 806 bool
809 807 QPDFObjectHandle::isRectangle() const
810 808 {
811   - if (auto array = asArray()) {
  809 + if (auto array = as_array(strict)) {
812 810 for (int i = 0; i < 4; ++i) {
813   - if (auto item = array->at(i).second; !item.isNumber()) {
  811 + if (auto item = array.at(i).second; !item.isNumber()) {
814 812 return false;
815 813 }
816 814 }
817   - return array->size() == 4;
  815 + return array.size() == 4;
818 816 }
819 817 return false;
820 818 }
... ... @@ -822,13 +820,13 @@ QPDFObjectHandle::isRectangle() const
822 820 bool
823 821 QPDFObjectHandle::isMatrix() const
824 822 {
825   - if (auto array = asArray()) {
  823 + if (auto array = as_array(strict)) {
826 824 for (int i = 0; i < 6; ++i) {
827   - if (auto item = array->at(i).second; !item.isNumber()) {
  825 + if (auto item = array.at(i).second; !item.isNumber()) {
828 826 return false;
829 827 }
830 828 }
831   - return array->size() == 6;
  829 + return array.size() == 6;
832 830 }
833 831 return false;
834 832 }
... ... @@ -836,13 +834,13 @@ QPDFObjectHandle::isMatrix() const
836 834 QPDFObjectHandle::Rectangle
837 835 QPDFObjectHandle::getArrayAsRectangle() const
838 836 {
839   - if (auto array = asArray()) {
840   - if (array->size() != 4) {
  837 + if (auto array = as_array(strict)) {
  838 + if (array.size() != 4) {
841 839 return {};
842 840 }
843 841 double items[4];
844 842 for (int i = 0; i < 4; ++i) {
845   - if (auto item = array->at(i).second; !item.getValueAsNumber(items[i])) {
  843 + if (auto item = array.at(i).second; !item.getValueAsNumber(items[i])) {
846 844 return {};
847 845 }
848 846 }
... ... @@ -858,13 +856,13 @@ QPDFObjectHandle::getArrayAsRectangle() const
858 856 QPDFObjectHandle::Matrix
859 857 QPDFObjectHandle::getArrayAsMatrix() const
860 858 {
861   - if (auto array = asArray()) {
862   - if (array->size() != 6) {
  859 + if (auto array = as_array(strict)) {
  860 + if (array.size() != 6) {
863 861 return {};
864 862 }
865 863 double items[6];
866 864 for (int i = 0; i < 6; ++i) {
867   - if (auto item = array->at(i).second; !item.getValueAsNumber(items[i])) {
  865 + if (auto item = array.at(i).second; !item.getValueAsNumber(items[i])) {
868 866 return {};
869 867 }
870 868 }
... ... @@ -876,13 +874,11 @@ QPDFObjectHandle::getArrayAsMatrix() const
876 874 std::vector<QPDFObjectHandle>
877 875 QPDFObjectHandle::getArrayAsVector() const
878 876 {
879   - auto array = asArray();
880   - if (array) {
881   - return array->getAsVector();
882   - } else {
883   - typeWarning("array", "treating as empty");
884   - QTC::TC("qpdf", "QPDFObjectHandle array treating as empty vector");
  877 + if (auto array = as_array(strict)) {
  878 + return array.getAsVector();
885 879 }
  880 + typeWarning("array", "treating as empty");
  881 + QTC::TC("qpdf", "QPDFObjectHandle array treating as empty vector");
886 882 return {};
887 883 }
888 884  
... ... @@ -891,8 +887,8 @@ QPDFObjectHandle::getArrayAsVector() const
891 887 void
892 888 QPDFObjectHandle::setArrayItem(int n, QPDFObjectHandle const& item)
893 889 {
894   - if (auto array = asArray()) {
895   - if (!array->setAt(n, item)) {
  890 + if (auto array = as_array(strict)) {
  891 + if (!array.setAt(n, item)) {
896 892 objectWarning("ignoring attempt to set out of bounds array item");
897 893 QTC::TC("qpdf", "QPDFObjectHandle set array bounds");
898 894 }
... ... @@ -904,8 +900,8 @@ QPDFObjectHandle::setArrayItem(int n, QPDFObjectHandle const&amp; item)
904 900 void
905 901 QPDFObjectHandle::setArrayFromVector(std::vector<QPDFObjectHandle> const& items)
906 902 {
907   - if (auto array = asArray()) {
908   - array->setFromVector(items);
  903 + if (auto array = as_array(strict)) {
  904 + array.setFromVector(items);
909 905 } else {
910 906 typeWarning("array", "ignoring attempt to replace items");
911 907 QTC::TC("qpdf", "QPDFObjectHandle array ignoring replace items");
... ... @@ -915,8 +911,8 @@ QPDFObjectHandle::setArrayFromVector(std::vector&lt;QPDFObjectHandle&gt; const&amp; items)
915 911 void
916 912 QPDFObjectHandle::insertItem(int at, QPDFObjectHandle const& item)
917 913 {
918   - if (auto array = asArray()) {
919   - if (!array->insert(at, item)) {
  914 + if (auto array = as_array(strict)) {
  915 + if (!array.insert(at, item)) {
920 916 objectWarning("ignoring attempt to insert out of bounds array item");
921 917 QTC::TC("qpdf", "QPDFObjectHandle insert array bounds");
922 918 }
... ... @@ -936,8 +932,8 @@ QPDFObjectHandle::insertItemAndGetNew(int at, QPDFObjectHandle const&amp; item)
936 932 void
937 933 QPDFObjectHandle::appendItem(QPDFObjectHandle const& item)
938 934 {
939   - if (auto array = asArray()) {
940   - array->push_back(item);
  935 + if (auto array = as_array(strict)) {
  936 + array.push_back(item);
941 937 } else {
942 938 typeWarning("array", "ignoring attempt to append item");
943 939 QTC::TC("qpdf", "QPDFObjectHandle array ignoring append item");
... ... @@ -954,8 +950,8 @@ QPDFObjectHandle::appendItemAndGetNew(QPDFObjectHandle const&amp; item)
954 950 void
955 951 QPDFObjectHandle::eraseItem(int at)
956 952 {
957   - if (auto array = asArray()) {
958   - if (!array->erase(at)) {
  953 + if (auto array = as_array(strict)) {
  954 + if (!array.erase(at)) {
959 955 objectWarning("ignoring attempt to erase out of bounds array item");
960 956 QTC::TC("qpdf", "QPDFObjectHandle erase array bounds");
961 957 }
... ... @@ -968,8 +964,8 @@ QPDFObjectHandle::eraseItem(int at)
968 964 QPDFObjectHandle
969 965 QPDFObjectHandle::eraseItemAndGetOld(int at)
970 966 {
971   - auto array = asArray();
972   - auto result = (array && at < array->size() && at >= 0) ? array->at(at).second : newNull();
  967 + auto array = as_array(strict);
  968 + auto result = (array && at < array.size() && at >= 0) ? array.at(at).second : newNull();
973 969 eraseItem(at);
974 970 return result;
975 971 }
... ... @@ -1344,12 +1340,12 @@ QPDFObjectHandle::arrayOrStreamToStreamArray(
1344 1340 {
1345 1341 all_description = description;
1346 1342 std::vector<QPDFObjectHandle> result;
1347   - if (auto array = asArray()) {
1348   - int n_items = array->size();
  1343 + if (auto array = as_array(strict)) {
  1344 + int n_items = array.size();
1349 1345 for (int i = 0; i < n_items; ++i) {
1350   - QPDFObjectHandle item = array->at(i).second;
  1346 + QPDFObjectHandle item = array.at(i).second;
1351 1347 if (item.isStream()) {
1352   - result.push_back(item);
  1348 + result.emplace_back(item);
1353 1349 } else {
1354 1350 QTC::TC("qpdf", "QPDFObjectHandle non-stream in stream array");
1355 1351 warn(
... ... @@ -1363,7 +1359,7 @@ QPDFObjectHandle::arrayOrStreamToStreamArray(
1363 1359 }
1364 1360 }
1365 1361 } else if (isStream()) {
1366   - result.push_back(*this);
  1362 + result.emplace_back(*this);
1367 1363 } else if (!isNull()) {
1368 1364 warn(
1369 1365 getOwningQPDF(),
... ... @@ -1993,10 +1989,10 @@ QPDFObjectHandle::makeDirect(QPDFObjGen::set&amp; visited, bool stop_at_streams)
1993 1989 this->obj = obj->copy(true);
1994 1990 } else if (isArray()) {
1995 1991 std::vector<QPDFObjectHandle> items;
1996   - auto array = asArray();
1997   - int n = array->size();
  1992 + auto array = as_array(strict);
  1993 + int n = array.size();
1998 1994 for (int i = 0; i < n; ++i) {
1999   - items.push_back(array->at(i).second);
  1995 + items.emplace_back(array.at(i).second);
2000 1996 items.back().makeDirect(visited, stop_at_streams);
2001 1997 }
2002 1998 this->obj = QPDF_Array::create(items);
... ...
libqpdf/QPDF_Array.cc
1 1 #include <qpdf/QPDF_Array.hh>
2 2  
3 3 #include <qpdf/JSON_writer.hh>
4   -#include <qpdf/QPDFObjectHandle.hh>
  4 +#include <qpdf/QPDFObjectHandle_private.hh>
5 5 #include <qpdf/QPDFObject_private.hh>
6 6 #include <qpdf/QTC.hh>
7 7  
  8 +using namespace qpdf;
  9 +
8 10 static const QPDFObjectHandle null_oh = QPDFObjectHandle::newNull();
9 11  
10 12 inline void
11 13 QPDF_Array::checkOwnership(QPDFObjectHandle const& item) const
12 14 {
13   - if (auto obj = item.getObjectPtr()) {
14   - if (qpdf) {
15   - if (auto item_qpdf = obj->getQPDF()) {
16   - if (qpdf != item_qpdf) {
  15 + // This is only called from QPDF_Array::setFromVector, which in turn is only called from create.
  16 + // At his point qpdf is a nullptr and therefore the ownership check reduces to an uninitialized
  17 + // check
  18 + if (!item.getObjectPtr()) {
  19 + throw std::logic_error("Attempting to add an uninitialized object to a QPDF_Array.");
  20 + }
  21 +}
  22 +
  23 +inline void
  24 +Array::checkOwnership(QPDFObjectHandle const& item) const
  25 +{
  26 + if (auto o = item.getObjectPtr()) {
  27 + if (auto pdf = obj->getQPDF()) {
  28 + if (auto item_qpdf = o->getQPDF()) {
  29 + if (pdf != item_qpdf) {
17 30 throw std::logic_error(
18 31 "Attempting to add an object from a different QPDF. Use "
19 32 "QPDF::copyForeignObject to add objects from another file.");
... ... @@ -184,47 +197,75 @@ QPDF_Array::writeJSON(int json_version, JSON::Writer&amp; p)
184 197 p.writeEnd(']');
185 198 }
186 199  
  200 +QPDF_Array*
  201 +Array::array() const
  202 +{
  203 + if (obj) {
  204 + if (auto a = obj->as<QPDF_Array>()) {
  205 + return a;
  206 + }
  207 + }
  208 + throw std::runtime_error("Expected an array but found a non-array object");
  209 + return nullptr; // unreachable
  210 +}
  211 +
  212 +QPDFObjectHandle
  213 +Array::null() const
  214 +{
  215 + return null_oh;
  216 +}
  217 +
  218 +int
  219 +Array::size() const
  220 +{
  221 + auto a = array();
  222 + return a->sp ? a->sp->size : int(a->elements.size());
  223 +}
  224 +
187 225 std::pair<bool, QPDFObjectHandle>
188   -QPDF_Array::at(int n) const noexcept
  226 +Array::at(int n) const
189 227 {
  228 + auto a = array();
190 229 if (n < 0 || n >= size()) {
191 230 return {false, {}};
192   - } else if (sp) {
193   - auto const& iter = sp->elements.find(n);
194   - return {true, iter == sp->elements.end() ? null_oh : (*iter).second};
195   - } else {
196   - return {true, elements[size_t(n)]};
197 231 }
  232 + if (!a->sp) {
  233 + return {true, a->elements[size_t(n)]};
  234 + }
  235 + auto const& iter = a->sp->elements.find(n);
  236 + return {true, iter == a->sp->elements.end() ? null() : iter->second};
198 237 }
199 238  
200 239 std::vector<QPDFObjectHandle>
201   -QPDF_Array::getAsVector() const
  240 +Array::getAsVector() const
202 241 {
203   - if (sp) {
  242 + auto a = array();
  243 + if (a->sp) {
204 244 std::vector<QPDFObjectHandle> v;
205 245 v.reserve(size_t(size()));
206   - for (auto const& item: sp->elements) {
  246 + for (auto const& item: a->sp->elements) {
207 247 v.resize(size_t(item.first), null_oh);
208 248 v.emplace_back(item.second);
209 249 }
210 250 v.resize(size_t(size()), null_oh);
211 251 return v;
212 252 } else {
213   - return {elements.cbegin(), elements.cend()};
  253 + return {a->elements.cbegin(), a->elements.cend()};
214 254 }
215 255 }
216 256  
217 257 bool
218   -QPDF_Array::setAt(int at, QPDFObjectHandle const& oh)
  258 +Array::setAt(int at, QPDFObjectHandle const& oh)
219 259 {
220 260 if (at < 0 || at >= size()) {
221 261 return false;
222 262 }
  263 + auto a = array();
223 264 checkOwnership(oh);
224   - if (sp) {
225   - sp->elements[at] = oh.getObj();
  265 + if (a->sp) {
  266 + a->sp->elements[at] = oh.getObj();
226 267 } else {
227   - elements[size_t(at)] = oh.getObj();
  268 + a->elements[size_t(at)] = oh.getObj();
228 269 }
229 270 return true;
230 271 }
... ... @@ -240,9 +281,22 @@ QPDF_Array::setFromVector(std::vector&lt;QPDFObjectHandle&gt; const&amp; v)
240 281 }
241 282 }
242 283  
  284 +void
  285 +Array::setFromVector(std::vector<QPDFObjectHandle> const& v)
  286 +{
  287 + auto a = array();
  288 + a->elements.resize(0);
  289 + a->elements.reserve(v.size());
  290 + for (auto const& item: v) {
  291 + checkOwnership(item);
  292 + a->elements.push_back(item.getObj());
  293 + }
  294 +}
  295 +
243 296 bool
244   -QPDF_Array::insert(int at, QPDFObjectHandle const& item)
  297 +Array::insert(int at, QPDFObjectHandle const& item)
245 298 {
  299 + auto a = array();
246 300 int sz = size();
247 301 if (at < 0 || at > sz) {
248 302 // As special case, also allow insert beyond the end
... ... @@ -251,61 +305,63 @@ QPDF_Array::insert(int at, QPDFObjectHandle const&amp; item)
251 305 push_back(item);
252 306 } else {
253 307 checkOwnership(item);
254   - if (sp) {
255   - auto iter = sp->elements.crbegin();
256   - while (iter != sp->elements.crend()) {
  308 + if (a->sp) {
  309 + auto iter = a->sp->elements.crbegin();
  310 + while (iter != a->sp->elements.crend()) {
257 311 auto key = (iter++)->first;
258 312 if (key >= at) {
259   - auto nh = sp->elements.extract(key);
  313 + auto nh = a->sp->elements.extract(key);
260 314 ++nh.key();
261   - sp->elements.insert(std::move(nh));
  315 + a->sp->elements.insert(std::move(nh));
262 316 } else {
263 317 break;
264 318 }
265 319 }
266   - sp->elements[at] = item.getObj();
267   - ++sp->size;
  320 + a->sp->elements[at] = item.getObj();
  321 + ++a->sp->size;
268 322 } else {
269   - elements.insert(elements.cbegin() + at, item.getObj());
  323 + a->elements.insert(a->elements.cbegin() + at, item.getObj());
270 324 }
271 325 }
272 326 return true;
273 327 }
274 328  
275 329 void
276   -QPDF_Array::push_back(QPDFObjectHandle const& item)
  330 +Array::push_back(QPDFObjectHandle const& item)
277 331 {
  332 + auto a = array();
278 333 checkOwnership(item);
279   - if (sp) {
280   - sp->elements[(sp->size)++] = item.getObj();
  334 + if (a->sp) {
  335 + a->sp->elements[(a->sp->size)++] = item.getObj();
281 336 } else {
282   - elements.push_back(item.getObj());
  337 + a->elements.push_back(item.getObj());
283 338 }
284 339 }
285 340  
286 341 bool
287   -QPDF_Array::erase(int at)
  342 +Array::erase(int at)
288 343 {
  344 + auto a = array();
289 345 if (at < 0 || at >= size()) {
290 346 return false;
291 347 }
292   - if (sp) {
293   - auto end = sp->elements.end();
294   - if (auto iter = sp->elements.lower_bound(at); iter != end) {
  348 + if (a->sp) {
  349 + auto end = a->sp->elements.end();
  350 + if (auto iter = a->sp->elements.lower_bound(at); iter != end) {
295 351 if (iter->first == at) {
296 352 iter++;
297   - sp->elements.erase(at);
  353 + a->sp->elements.erase(at);
298 354 }
299 355  
300 356 while (iter != end) {
301   - auto nh = sp->elements.extract(iter++);
  357 + auto nh = a->sp->elements.extract(iter++);
302 358 --nh.key();
303   - sp->elements.insert(std::move(nh));
  359 + a->sp->elements.insert(std::move(nh));
304 360 }
305 361 }
306   - --(sp->size);
  362 + --(a->sp->size);
307 363 } else {
308   - elements.erase(elements.cbegin() + at);
  364 + a->elements.erase(a->elements.cbegin() + at);
309 365 }
310 366 return true;
311 367 }
... ...
libqpdf/qpdf/QPDFObjectHandle_private.hh
... ... @@ -4,10 +4,40 @@
4 4 #include <qpdf/QPDFObjectHandle.hh>
5 5  
6 6 #include <qpdf/QPDFObject_private.hh>
  7 +#include <qpdf/QPDF_Array.hh>
7 8 #include <qpdf/QPDF_Dictionary.hh>
8 9  
9 10 namespace qpdf
10 11 {
  12 + class Array final: public BaseHandle
  13 + {
  14 + public:
  15 + explicit Array(std::shared_ptr<QPDFObject> const& obj) :
  16 + BaseHandle(obj)
  17 + {
  18 + }
  19 +
  20 + explicit Array(std::shared_ptr<QPDFObject>&& obj) :
  21 + BaseHandle(std::move(obj))
  22 + {
  23 + }
  24 +
  25 + int size() const;
  26 + std::pair<bool, QPDFObjectHandle> at(int n) const;
  27 + bool setAt(int at, QPDFObjectHandle const& oh);
  28 + bool insert(int at, QPDFObjectHandle const& item);
  29 + void push_back(QPDFObjectHandle const& item);
  30 + bool erase(int at);
  31 +
  32 + std::vector<QPDFObjectHandle> getAsVector() const;
  33 + void setFromVector(std::vector<QPDFObjectHandle> const& items);
  34 +
  35 + private:
  36 + QPDF_Array* array() const;
  37 + void checkOwnership(QPDFObjectHandle const& item) const;
  38 + QPDFObjectHandle null() const;
  39 + };
  40 +
11 41 // BaseDictionary is only used as a base class. It does not contain any methods exposed in the
12 42 // public API.
13 43 class BaseDictionary: public BaseHandle
... ... @@ -58,6 +88,19 @@ namespace qpdf
58 88  
59 89 } // namespace qpdf
60 90  
  91 +inline qpdf::Array
  92 +QPDFObjectHandle::as_array(qpdf::typed options) const
  93 +{
  94 + if (options & qpdf::error) {
  95 + assertType("array", false);
  96 + }
  97 + if (options & qpdf::any_flag || type_code() == ::ot_array ||
  98 + (options & qpdf::optional && type_code() == ::ot_null)) {
  99 + return qpdf::Array(obj);
  100 + }
  101 + return qpdf::Array({});
  102 +}
  103 +
61 104 inline qpdf::Dictionary
62 105 QPDFObjectHandle::as_dictionary(qpdf::typed options) const
63 106 {
... ...
libqpdf/qpdf/QPDF_Array.hh
1 1 #ifndef QPDF_ARRAY_HH
2 2 #define QPDF_ARRAY_HH
3 3  
  4 +#include <qpdf/QPDFObjectHandle.hh>
  5 +#include <qpdf/QPDFObject_private.hh>
4 6 #include <qpdf/QPDFValue.hh>
5 7  
6 8 #include <map>
... ... @@ -25,25 +27,20 @@ class QPDF_Array: public QPDFValue
25 27 void writeJSON(int json_version, JSON::Writer& p) override;
26 28 void disconnect() override;
27 29  
28   - int
29   - size() const noexcept
30   - {
31   - return sp ? sp->size : int(elements.size());
32   - }
33   - std::pair<bool, QPDFObjectHandle> at(int n) const noexcept;
34   - bool setAt(int n, QPDFObjectHandle const& oh);
35   - std::vector<QPDFObjectHandle> getAsVector() const;
36   - void setFromVector(std::vector<QPDFObjectHandle> const& items);
37   - bool insert(int at, QPDFObjectHandle const& item);
38   - void push_back(QPDFObjectHandle const& item);
39   - bool erase(int at);
40   -
41 30 private:
  31 + friend class qpdf::Array;
42 32 QPDF_Array();
43 33 QPDF_Array(QPDF_Array const&);
44 34 QPDF_Array(std::vector<QPDFObjectHandle> const& items);
45 35 QPDF_Array(std::vector<std::shared_ptr<QPDFObject>>&& items, bool sparse);
46 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 +
47 44 void checkOwnership(QPDFObjectHandle const& item) const;
48 45  
49 46 std::unique_ptr<Sparse> sp;
... ...
libtests/sparse_array.cc
1 1 #include <qpdf/assert_test.h>
2 2  
3 3 #include <qpdf/QPDF.hh>
4   -#include <qpdf/QPDFObjectHandle.hh>
  4 +#include <qpdf/QPDFObjectHandle_private.hh>
5 5 #include <qpdf/QPDFObject_private.hh>
6 6 #include <qpdf/QPDF_Array.hh>
7 7  
... ... @@ -11,7 +11,7 @@ int
11 11 main()
12 12 {
13 13 auto obj = QPDF_Array::create({}, true);
14   - QPDF_Array& a = *obj->as<QPDF_Array>();
  14 + auto a = qpdf::Array(obj);
15 15  
16 16 assert(a.size() == 0);
17 17  
... ... @@ -89,15 +89,15 @@ main()
89 89 pdf.emptyPDF();
90 90  
91 91 obj = QPDF_Array::create({10, "null"_qpdf.getObj()}, true);
92   - QPDF_Array& b = *obj->as<QPDF_Array>();
  92 + auto b = qpdf::Array(obj);
93 93 b.setAt(5, pdf.newIndirectNull());
94 94 b.setAt(7, "[0 1 2 3]"_qpdf);
95 95 assert(b.at(3).second.isNull());
96 96 assert(b.at(8).second.isNull());
97 97 assert(b.at(5).second.isIndirect());
98   - assert(b.unparse() == "[ null null null null null 3 0 R null [ 0 1 2 3 ] null null ]");
99   - auto c = b.copy(true);
100   - auto d = b.copy(false);
  98 + assert(obj->unparse() == "[ null null null null null 3 0 R null [ 0 1 2 3 ] null null ]");
  99 + auto c = obj->copy(true);
  100 + auto d = obj->copy(false);
101 101 b.at(7).second.setArrayItem(2, "42"_qpdf);
102 102 assert(c->unparse() == "[ null null null null null 3 0 R null [ 0 1 42 3 ] null null ]");
103 103 assert(d->unparse() == "[ null null null null null 3 0 R null [ 0 1 2 3 ] null null ]");
... ...