• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_coordinates.h"
19 #include "third_party/base/ptr_util.h"
20 
21 class CPDF_Array : public CPDF_Object {
22  public:
23   using const_iterator =
24       std::vector<std::unique_ptr<CPDF_Object>>::const_iterator;
25 
26   CPDF_Array();
27   explicit CPDF_Array(const WeakPtr<ByteStringPool>& pPool);
28   ~CPDF_Array() override;
29 
30   // CPDF_Object:
31   Type GetType() const override;
32   std::unique_ptr<CPDF_Object> Clone() const override;
33   bool IsArray() const override;
34   CPDF_Array* AsArray() override;
35   const CPDF_Array* AsArray() const override;
36   bool WriteTo(IFX_ArchiveStream* archive) 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   ByteString GetStringAt(size_t index) const;
43   WideString GetUnicodeTextAt(size_t index) const;
44   int GetIntegerAt(size_t index) const;
45   float GetNumberAt(size_t index) const;
46   CPDF_Dictionary* GetDictAt(size_t index) const;
47   CPDF_Stream* GetStreamAt(size_t index) const;
48   CPDF_Array* GetArrayAt(size_t index) const;
GetFloatAt(size_t index)49   float GetFloatAt(size_t index) const { return GetNumberAt(index); }
50   CFX_Matrix GetMatrix();
51   CFX_FloatRect GetRect();
52 
53   // Takes ownership of |pObj|, returns unowned pointer to it.
54   CPDF_Object* Add(std::unique_ptr<CPDF_Object> pObj);
55   CPDF_Object* SetAt(size_t index, std::unique_ptr<CPDF_Object> pObj);
56   CPDF_Object* InsertAt(size_t index, std::unique_ptr<CPDF_Object> pObj);
57 
58   // Creates object owned by the array, returns unowned pointer to it.
59   // We have special cases for objects that can intern strings from
60   // a ByteStringPool.
61   template <typename T, typename... Args>
AddNew(Args &&...args)62   typename std::enable_if<!CanInternStrings<T>::value, T*>::type AddNew(
63       Args&&... args) {
64     return static_cast<T*>(
65         Add(pdfium::MakeUnique<T>(std::forward<Args>(args)...)));
66   }
67   template <typename T, typename... Args>
AddNew(Args &&...args)68   typename std::enable_if<CanInternStrings<T>::value, T*>::type AddNew(
69       Args&&... args) {
70     return static_cast<T*>(
71         Add(pdfium::MakeUnique<T>(m_pPool, std::forward<Args>(args)...)));
72   }
73   template <typename T, typename... Args>
SetNewAt(size_t index,Args &&...args)74   typename std::enable_if<!CanInternStrings<T>::value, T*>::type SetNewAt(
75       size_t index,
76       Args&&... args) {
77     return static_cast<T*>(
78         SetAt(index, pdfium::MakeUnique<T>(std::forward<Args>(args)...)));
79   }
80   template <typename T, typename... Args>
SetNewAt(size_t index,Args &&...args)81   typename std::enable_if<CanInternStrings<T>::value, T*>::type SetNewAt(
82       size_t index,
83       Args&&... args) {
84     return static_cast<T*>(SetAt(
85         index, pdfium::MakeUnique<T>(m_pPool, std::forward<Args>(args)...)));
86   }
87   template <typename T, typename... Args>
InsertNewAt(size_t index,Args &&...args)88   typename std::enable_if<!CanInternStrings<T>::value, T*>::type InsertNewAt(
89       size_t index,
90       Args&&... args) {
91     return static_cast<T*>(
92         InsertAt(index, pdfium::MakeUnique<T>(std::forward<Args>(args)...)));
93   }
94   template <typename T, typename... Args>
InsertNewAt(size_t index,Args &&...args)95   typename std::enable_if<CanInternStrings<T>::value, T*>::type InsertNewAt(
96       size_t index,
97       Args&&... args) {
98     return static_cast<T*>(InsertAt(
99         index, pdfium::MakeUnique<T>(m_pPool, std::forward<Args>(args)...)));
100   }
101 
102   void Clear();
103   void RemoveAt(size_t index);
104   void ConvertToIndirectObjectAt(size_t index, CPDF_IndirectObjectHolder* pDoc);
105 
begin()106   const_iterator begin() const { return m_Objects.begin(); }
end()107   const_iterator end() const { return m_Objects.end(); }
108 
109  protected:
110   std::unique_ptr<CPDF_Object> CloneNonCyclic(
111       bool bDirect,
112       std::set<const CPDF_Object*>* pVisited) const override;
113 
114   std::vector<std::unique_ptr<CPDF_Object>> m_Objects;
115   WeakPtr<ByteStringPool> m_pPool;
116 };
117 
ToArray(CPDF_Object * obj)118 inline CPDF_Array* ToArray(CPDF_Object* obj) {
119   return obj ? obj->AsArray() : nullptr;
120 }
121 
ToArray(const CPDF_Object * obj)122 inline const CPDF_Array* ToArray(const CPDF_Object* obj) {
123   return obj ? obj->AsArray() : nullptr;
124 }
125 
ToArray(std::unique_ptr<CPDF_Object> obj)126 inline std::unique_ptr<CPDF_Array> ToArray(std::unique_ptr<CPDF_Object> obj) {
127   CPDF_Array* pArray = ToArray(obj.get());
128   if (!pArray)
129     return nullptr;
130   obj.release();
131   return std::unique_ptr<CPDF_Array>(pArray);
132 }
133 
134 #endif  // CORE_FPDFAPI_PARSER_CPDF_ARRAY_H_
135