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_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 
     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   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;
     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>
     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>
     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>
     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>
     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>
     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>
     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 
    106   const_iterator begin() const { return m_Objects.begin(); }
    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 
    118 inline CPDF_Array* ToArray(CPDF_Object* obj) {
    119   return obj ? obj->AsArray() : nullptr;
    120 }
    121 
    122 inline const CPDF_Array* ToArray(const CPDF_Object* obj) {
    123   return obj ? obj->AsArray() : nullptr;
    124 }
    125 
    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