Home | History | Annotate | Download | only in parser
      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 
     38   bool IsEmpty() const { return m_Objects.empty(); }
     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;
     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>
     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>
     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>
     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>
     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>
     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>
     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 
    104   const_iterator begin() const { return m_Objects.begin(); }
    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 
    116 inline CPDF_Array* ToArray(CPDF_Object* obj) {
    117   return obj ? obj->AsArray() : nullptr;
    118 }
    119 
    120 inline const CPDF_Array* ToArray(const CPDF_Object* obj) {
    121   return obj ? obj->AsArray() : nullptr;
    122 }
    123 
    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