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 #include "core/fpdfdoc/cpdf_actionfields.h"
8 
9 #include "core/fpdfapi/parser/cpdf_array.h"
10 #include "core/fpdfapi/parser/cpdf_dictionary.h"
11 #include "core/fpdfdoc/cpdf_action.h"
12 
GetFieldsCount() const13 size_t CPDF_ActionFields::GetFieldsCount() const {
14   if (!m_pAction)
15     return 0;
16 
17   CPDF_Dictionary* pDict = m_pAction->GetDict();
18   if (!pDict)
19     return 0;
20 
21   CFX_ByteString csType = pDict->GetStringFor("S");
22   CPDF_Object* pFields = nullptr;
23   if (csType == "Hide")
24     pFields = pDict->GetDirectObjectFor("T");
25   else
26     pFields = pDict->GetArrayFor("Fields");
27 
28   if (!pFields)
29     return 0;
30   if (pFields->IsDictionary())
31     return 1;
32   if (pFields->IsString())
33     return 1;
34   if (CPDF_Array* pArray = pFields->AsArray())
35     return pArray->GetCount();
36   return 0;
37 }
38 
GetAllFields() const39 std::vector<CPDF_Object*> CPDF_ActionFields::GetAllFields() const {
40   std::vector<CPDF_Object*> fields;
41   if (!m_pAction)
42     return fields;
43 
44   CPDF_Dictionary* pDict = m_pAction->GetDict();
45   if (!pDict)
46     return fields;
47 
48   CFX_ByteString csType = pDict->GetStringFor("S");
49   CPDF_Object* pFields;
50   if (csType == "Hide")
51     pFields = pDict->GetDirectObjectFor("T");
52   else
53     pFields = pDict->GetArrayFor("Fields");
54 
55   if (!pFields)
56     return fields;
57 
58   if (pFields->IsDictionary() || pFields->IsString()) {
59     fields.push_back(pFields);
60   } else if (CPDF_Array* pArray = pFields->AsArray()) {
61     for (size_t i = 0; i < pArray->GetCount(); ++i) {
62       CPDF_Object* pObj = pArray->GetDirectObjectAt(i);
63       if (pObj)
64         fields.push_back(pObj);
65     }
66   }
67   return fields;
68 }
69 
GetField(size_t iIndex) const70 CPDF_Object* CPDF_ActionFields::GetField(size_t iIndex) const {
71   if (!m_pAction)
72     return nullptr;
73 
74   CPDF_Dictionary* pDict = m_pAction->GetDict();
75   if (!pDict)
76     return nullptr;
77 
78   CFX_ByteString csType = pDict->GetStringFor("S");
79   CPDF_Object* pFields = nullptr;
80   if (csType == "Hide")
81     pFields = pDict->GetDirectObjectFor("T");
82   else
83     pFields = pDict->GetArrayFor("Fields");
84 
85   if (!pFields)
86     return nullptr;
87 
88   CPDF_Object* pFindObj = nullptr;
89   if (pFields->IsDictionary() || pFields->IsString()) {
90     if (iIndex == 0)
91       pFindObj = pFields;
92   } else if (CPDF_Array* pArray = pFields->AsArray()) {
93     pFindObj = pArray->GetDirectObjectAt(iIndex);
94   }
95   return pFindObj;
96 }
97