1 // Copyright 2016 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #ifndef CORE_FPDFAPI_PARSER_CPDF_ARRAY_H_
8 #define CORE_FPDFAPI_PARSER_CPDF_ARRAY_H_
9
10 #include <memory>
11 #include <set>
12 #include <type_traits>
13 #include <utility>
14 #include <vector>
15
16 #include "core/fpdfapi/parser/cpdf_indirect_object_holder.h"
17 #include "core/fpdfapi/parser/cpdf_object.h"
18 #include "core/fxcrt/fx_basic.h"
19 #include "core/fxcrt/fx_coordinates.h"
20 #include "third_party/base/ptr_util.h"
21
22 class CPDF_Array : public CPDF_Object {
23 public:
24 using const_iterator =
25 std::vector<std::unique_ptr<CPDF_Object>>::const_iterator;
26
27 CPDF_Array();
28 explicit CPDF_Array(const CFX_WeakPtr<CFX_ByteStringPool>& pPool);
29 ~CPDF_Array() override;
30
31 // CPDF_Object:
32 Type GetType() const override;
33 std::unique_ptr<CPDF_Object> Clone() const override;
34 bool IsArray() const override;
35 CPDF_Array* AsArray() override;
36 const CPDF_Array* AsArray() const override;
37
IsEmpty()38 bool IsEmpty() const { return m_Objects.empty(); }
GetCount()39 size_t GetCount() const { return m_Objects.size(); }
40 CPDF_Object* GetObjectAt(size_t index) const;
41 CPDF_Object* GetDirectObjectAt(size_t index) const;
42 CFX_ByteString GetStringAt(size_t index) const;
43 int GetIntegerAt(size_t index) const;
44 FX_FLOAT GetNumberAt(size_t index) const;
45 CPDF_Dictionary* GetDictAt(size_t index) const;
46 CPDF_Stream* GetStreamAt(size_t index) const;
47 CPDF_Array* GetArrayAt(size_t index) const;
GetFloatAt(size_t index)48 FX_FLOAT GetFloatAt(size_t index) const { return GetNumberAt(index); }
49 CFX_Matrix GetMatrix();
50 CFX_FloatRect GetRect();
51
52 // Takes ownership of |pObj|, returns unowned pointer to it.
53 CPDF_Object* Add(std::unique_ptr<CPDF_Object> pObj);
54 CPDF_Object* SetAt(size_t index, std::unique_ptr<CPDF_Object> pObj);
55 CPDF_Object* InsertAt(size_t index, std::unique_ptr<CPDF_Object> pObj);
56
57 // Creates object owned by the array, returns unowned pointer to it.
58 // We have special cases for objects that can intern strings from
59 // a ByteStringPool.
60 template <typename T, typename... Args>
AddNew(Args &&...args)61 typename std::enable_if<!CanInternStrings<T>::value, T*>::type AddNew(
62 Args&&... args) {
63 return static_cast<T*>(
64 Add(pdfium::MakeUnique<T>(std::forward<Args>(args)...)));
65 }
66 template <typename T, typename... Args>
AddNew(Args &&...args)67 typename std::enable_if<CanInternStrings<T>::value, T*>::type AddNew(
68 Args&&... args) {
69 return static_cast<T*>(
70 Add(pdfium::MakeUnique<T>(m_pPool, std::forward<Args>(args)...)));
71 }
72 template <typename T, typename... Args>
SetNewAt(size_t index,Args &&...args)73 typename std::enable_if<!CanInternStrings<T>::value, T*>::type SetNewAt(
74 size_t index,
75 Args&&... args) {
76 return static_cast<T*>(
77 SetAt(index, pdfium::MakeUnique<T>(std::forward<Args>(args)...)));
78 }
79 template <typename T, typename... Args>
SetNewAt(size_t index,Args &&...args)80 typename std::enable_if<CanInternStrings<T>::value, T*>::type SetNewAt(
81 size_t index,
82 Args&&... args) {
83 return static_cast<T*>(SetAt(
84 index, pdfium::MakeUnique<T>(m_pPool, std::forward<Args>(args)...)));
85 }
86 template <typename T, typename... Args>
InsertNewAt(size_t index,Args &&...args)87 typename std::enable_if<!CanInternStrings<T>::value, T*>::type InsertNewAt(
88 size_t index,
89 Args&&... args) {
90 return static_cast<T*>(
91 InsertAt(index, pdfium::MakeUnique<T>(std::forward<Args>(args)...)));
92 }
93 template <typename T, typename... Args>
InsertNewAt(size_t index,Args &&...args)94 typename std::enable_if<CanInternStrings<T>::value, T*>::type InsertNewAt(
95 size_t index,
96 Args&&... args) {
97 return static_cast<T*>(InsertAt(
98 index, pdfium::MakeUnique<T>(m_pPool, std::forward<Args>(args)...)));
99 }
100
101 void RemoveAt(size_t index, size_t nCount = 1);
102 void ConvertToIndirectObjectAt(size_t index, CPDF_IndirectObjectHolder* pDoc);
103
begin()104 const_iterator begin() const { return m_Objects.begin(); }
end()105 const_iterator end() const { return m_Objects.end(); }
106
107 protected:
108 std::unique_ptr<CPDF_Object> CloneNonCyclic(
109 bool bDirect,
110 std::set<const CPDF_Object*>* pVisited) const override;
111
112 std::vector<std::unique_ptr<CPDF_Object>> m_Objects;
113 CFX_WeakPtr<CFX_ByteStringPool> m_pPool;
114 };
115
ToArray(CPDF_Object * obj)116 inline CPDF_Array* ToArray(CPDF_Object* obj) {
117 return obj ? obj->AsArray() : nullptr;
118 }
119
ToArray(const CPDF_Object * obj)120 inline const CPDF_Array* ToArray(const CPDF_Object* obj) {
121 return obj ? obj->AsArray() : nullptr;
122 }
123
ToArray(std::unique_ptr<CPDF_Object> obj)124 inline std::unique_ptr<CPDF_Array> ToArray(std::unique_ptr<CPDF_Object> obj) {
125 CPDF_Array* pArray = ToArray(obj.get());
126 if (!pArray)
127 return nullptr;
128 obj.release();
129 return std::unique_ptr<CPDF_Array>(pArray);
130 }
131
132 #endif // CORE_FPDFAPI_PARSER_CPDF_ARRAY_H_
133