OLD | NEW |
1 // Copyright 2016 PDFium Authors. All rights reserved. | 1 // Copyright 2016 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "core/fpdfdoc/include/cpdf_nametree.h" | 7 #include "core/fpdfdoc/include/cpdf_nametree.h" |
8 | 8 |
9 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" | 9 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" |
10 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" | 10 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" |
11 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" | 11 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" |
12 | 12 |
13 namespace { | 13 namespace { |
14 | 14 |
15 const int nMaxRecursion = 32; | 15 const int nMaxRecursion = 32; |
16 | 16 |
17 CPDF_Object* SearchNameNode(CPDF_Dictionary* pNode, | 17 CPDF_Object* SearchNameNode(CPDF_Dictionary* pNode, |
18 const CFX_ByteString& csName, | 18 const CFX_ByteString& csName, |
19 size_t& nIndex, | 19 size_t& nIndex, |
20 CPDF_Array** ppFind, | 20 CPDF_Array** ppFind, |
21 int nLevel = 0) { | 21 int nLevel = 0) { |
22 if (nLevel > nMaxRecursion) | 22 if (nLevel > nMaxRecursion) |
23 return nullptr; | 23 return nullptr; |
24 | 24 |
25 CPDF_Array* pLimits = pNode->GetArrayBy("Limits"); | 25 CPDF_Array* pLimits = pNode->GetArrayFor("Limits"); |
26 if (pLimits) { | 26 if (pLimits) { |
27 CFX_ByteString csLeft = pLimits->GetStringAt(0); | 27 CFX_ByteString csLeft = pLimits->GetStringAt(0); |
28 CFX_ByteString csRight = pLimits->GetStringAt(1); | 28 CFX_ByteString csRight = pLimits->GetStringAt(1); |
29 if (csLeft.Compare(csRight.AsStringC()) > 0) { | 29 if (csLeft.Compare(csRight.AsStringC()) > 0) { |
30 CFX_ByteString csTmp = csRight; | 30 CFX_ByteString csTmp = csRight; |
31 csRight = csLeft; | 31 csRight = csLeft; |
32 csLeft = csTmp; | 32 csLeft = csTmp; |
33 } | 33 } |
34 if (csName.Compare(csLeft.AsStringC()) < 0 || | 34 if (csName.Compare(csLeft.AsStringC()) < 0 || |
35 csName.Compare(csRight.AsStringC()) > 0) { | 35 csName.Compare(csRight.AsStringC()) > 0) { |
36 return nullptr; | 36 return nullptr; |
37 } | 37 } |
38 } | 38 } |
39 | 39 |
40 CPDF_Array* pNames = pNode->GetArrayBy("Names"); | 40 CPDF_Array* pNames = pNode->GetArrayFor("Names"); |
41 if (pNames) { | 41 if (pNames) { |
42 size_t dwCount = pNames->GetCount() / 2; | 42 size_t dwCount = pNames->GetCount() / 2; |
43 for (size_t i = 0; i < dwCount; i++) { | 43 for (size_t i = 0; i < dwCount; i++) { |
44 CFX_ByteString csValue = pNames->GetStringAt(i * 2); | 44 CFX_ByteString csValue = pNames->GetStringAt(i * 2); |
45 int32_t iCompare = csValue.Compare(csName.AsStringC()); | 45 int32_t iCompare = csValue.Compare(csName.AsStringC()); |
46 if (iCompare <= 0) { | 46 if (iCompare <= 0) { |
47 if (ppFind) | 47 if (ppFind) |
48 *ppFind = pNames; | 48 *ppFind = pNames; |
49 if (iCompare < 0) | 49 if (iCompare < 0) |
50 continue; | 50 continue; |
51 } else { | 51 } else { |
52 break; | 52 break; |
53 } | 53 } |
54 nIndex += i; | 54 nIndex += i; |
55 return pNames->GetDirectObjectAt(i * 2 + 1); | 55 return pNames->GetDirectObjectAt(i * 2 + 1); |
56 } | 56 } |
57 nIndex += dwCount; | 57 nIndex += dwCount; |
58 return nullptr; | 58 return nullptr; |
59 } | 59 } |
60 | 60 |
61 CPDF_Array* pKids = pNode->GetArrayBy("Kids"); | 61 CPDF_Array* pKids = pNode->GetArrayFor("Kids"); |
62 if (!pKids) | 62 if (!pKids) |
63 return nullptr; | 63 return nullptr; |
64 | 64 |
65 for (size_t i = 0; i < pKids->GetCount(); i++) { | 65 for (size_t i = 0; i < pKids->GetCount(); i++) { |
66 CPDF_Dictionary* pKid = pKids->GetDictAt(i); | 66 CPDF_Dictionary* pKid = pKids->GetDictAt(i); |
67 if (!pKid) | 67 if (!pKid) |
68 continue; | 68 continue; |
69 | 69 |
70 CPDF_Object* pFound = | 70 CPDF_Object* pFound = |
71 SearchNameNode(pKid, csName, nIndex, ppFind, nLevel + 1); | 71 SearchNameNode(pKid, csName, nIndex, ppFind, nLevel + 1); |
72 if (pFound) | 72 if (pFound) |
73 return pFound; | 73 return pFound; |
74 } | 74 } |
75 return nullptr; | 75 return nullptr; |
76 } | 76 } |
77 | 77 |
78 CPDF_Object* SearchNameNode(CPDF_Dictionary* pNode, | 78 CPDF_Object* SearchNameNode(CPDF_Dictionary* pNode, |
79 size_t nIndex, | 79 size_t nIndex, |
80 size_t& nCurIndex, | 80 size_t& nCurIndex, |
81 CFX_ByteString& csName, | 81 CFX_ByteString& csName, |
82 CPDF_Array** ppFind, | 82 CPDF_Array** ppFind, |
83 int nLevel = 0) { | 83 int nLevel = 0) { |
84 if (nLevel > nMaxRecursion) | 84 if (nLevel > nMaxRecursion) |
85 return nullptr; | 85 return nullptr; |
86 | 86 |
87 CPDF_Array* pNames = pNode->GetArrayBy("Names"); | 87 CPDF_Array* pNames = pNode->GetArrayFor("Names"); |
88 if (pNames) { | 88 if (pNames) { |
89 size_t nCount = pNames->GetCount() / 2; | 89 size_t nCount = pNames->GetCount() / 2; |
90 if (nIndex >= nCurIndex + nCount) { | 90 if (nIndex >= nCurIndex + nCount) { |
91 nCurIndex += nCount; | 91 nCurIndex += nCount; |
92 return nullptr; | 92 return nullptr; |
93 } | 93 } |
94 if (ppFind) | 94 if (ppFind) |
95 *ppFind = pNames; | 95 *ppFind = pNames; |
96 csName = pNames->GetStringAt((nIndex - nCurIndex) * 2); | 96 csName = pNames->GetStringAt((nIndex - nCurIndex) * 2); |
97 return pNames->GetDirectObjectAt((nIndex - nCurIndex) * 2 + 1); | 97 return pNames->GetDirectObjectAt((nIndex - nCurIndex) * 2 + 1); |
98 } | 98 } |
99 CPDF_Array* pKids = pNode->GetArrayBy("Kids"); | 99 CPDF_Array* pKids = pNode->GetArrayFor("Kids"); |
100 if (!pKids) | 100 if (!pKids) |
101 return nullptr; | 101 return nullptr; |
102 for (size_t i = 0; i < pKids->GetCount(); i++) { | 102 for (size_t i = 0; i < pKids->GetCount(); i++) { |
103 CPDF_Dictionary* pKid = pKids->GetDictAt(i); | 103 CPDF_Dictionary* pKid = pKids->GetDictAt(i); |
104 if (!pKid) | 104 if (!pKid) |
105 continue; | 105 continue; |
106 CPDF_Object* pFound = | 106 CPDF_Object* pFound = |
107 SearchNameNode(pKid, nIndex, nCurIndex, csName, ppFind, nLevel + 1); | 107 SearchNameNode(pKid, nIndex, nCurIndex, csName, ppFind, nLevel + 1); |
108 if (pFound) | 108 if (pFound) |
109 return pFound; | 109 return pFound; |
110 } | 110 } |
111 return nullptr; | 111 return nullptr; |
112 } | 112 } |
113 | 113 |
114 size_t CountNames(CPDF_Dictionary* pNode, int nLevel = 0) { | 114 size_t CountNames(CPDF_Dictionary* pNode, int nLevel = 0) { |
115 if (nLevel > nMaxRecursion) | 115 if (nLevel > nMaxRecursion) |
116 return 0; | 116 return 0; |
117 | 117 |
118 CPDF_Array* pNames = pNode->GetArrayBy("Names"); | 118 CPDF_Array* pNames = pNode->GetArrayFor("Names"); |
119 if (pNames) | 119 if (pNames) |
120 return pNames->GetCount() / 2; | 120 return pNames->GetCount() / 2; |
121 | 121 |
122 CPDF_Array* pKids = pNode->GetArrayBy("Kids"); | 122 CPDF_Array* pKids = pNode->GetArrayFor("Kids"); |
123 if (!pKids) | 123 if (!pKids) |
124 return 0; | 124 return 0; |
125 | 125 |
126 size_t nCount = 0; | 126 size_t nCount = 0; |
127 for (size_t i = 0; i < pKids->GetCount(); i++) { | 127 for (size_t i = 0; i < pKids->GetCount(); i++) { |
128 CPDF_Dictionary* pKid = pKids->GetDictAt(i); | 128 CPDF_Dictionary* pKid = pKids->GetDictAt(i); |
129 if (!pKid) | 129 if (!pKid) |
130 continue; | 130 continue; |
131 | 131 |
132 nCount += CountNames(pKid, nLevel + 1); | 132 nCount += CountNames(pKid, nLevel + 1); |
133 } | 133 } |
134 return nCount; | 134 return nCount; |
135 } | 135 } |
136 | 136 |
137 } // namespace | 137 } // namespace |
138 | 138 |
139 CPDF_NameTree::CPDF_NameTree(CPDF_Document* pDoc, | 139 CPDF_NameTree::CPDF_NameTree(CPDF_Document* pDoc, |
140 const CFX_ByteString& category) | 140 const CFX_ByteString& category) |
141 : m_pRoot(nullptr) { | 141 : m_pRoot(nullptr) { |
142 CPDF_Dictionary* pRoot = pDoc->GetRoot(); | 142 CPDF_Dictionary* pRoot = pDoc->GetRoot(); |
143 if (!pRoot) | 143 if (!pRoot) |
144 return; | 144 return; |
145 | 145 |
146 CPDF_Dictionary* pNames = pRoot->GetDictBy("Names"); | 146 CPDF_Dictionary* pNames = pRoot->GetDictFor("Names"); |
147 if (!pNames) | 147 if (!pNames) |
148 return; | 148 return; |
149 | 149 |
150 m_pRoot = pNames->GetDictBy(category); | 150 m_pRoot = pNames->GetDictFor(category); |
151 } | 151 } |
152 | 152 |
153 size_t CPDF_NameTree::GetCount() const { | 153 size_t CPDF_NameTree::GetCount() const { |
154 return m_pRoot ? ::CountNames(m_pRoot) : 0; | 154 return m_pRoot ? ::CountNames(m_pRoot) : 0; |
155 } | 155 } |
156 | 156 |
157 int CPDF_NameTree::GetIndex(const CFX_ByteString& csName) const { | 157 int CPDF_NameTree::GetIndex(const CFX_ByteString& csName) const { |
158 if (!m_pRoot) | 158 if (!m_pRoot) |
159 return -1; | 159 return -1; |
160 | 160 |
(...skipping 15 matching lines...) Expand all Loading... |
176 if (!m_pRoot) | 176 if (!m_pRoot) |
177 return nullptr; | 177 return nullptr; |
178 size_t nIndex = 0; | 178 size_t nIndex = 0; |
179 return SearchNameNode(m_pRoot, csName, nIndex, nullptr); | 179 return SearchNameNode(m_pRoot, csName, nIndex, nullptr); |
180 } | 180 } |
181 | 181 |
182 CPDF_Array* CPDF_NameTree::LookupNamedDest(CPDF_Document* pDoc, | 182 CPDF_Array* CPDF_NameTree::LookupNamedDest(CPDF_Document* pDoc, |
183 const CFX_ByteString& sName) { | 183 const CFX_ByteString& sName) { |
184 CPDF_Object* pValue = LookupValue(sName); | 184 CPDF_Object* pValue = LookupValue(sName); |
185 if (!pValue) { | 185 if (!pValue) { |
186 CPDF_Dictionary* pDests = pDoc->GetRoot()->GetDictBy("Dests"); | 186 CPDF_Dictionary* pDests = pDoc->GetRoot()->GetDictFor("Dests"); |
187 if (!pDests) | 187 if (!pDests) |
188 return nullptr; | 188 return nullptr; |
189 pValue = pDests->GetDirectObjectBy(sName); | 189 pValue = pDests->GetDirectObjectFor(sName); |
190 } | 190 } |
191 if (!pValue) | 191 if (!pValue) |
192 return nullptr; | 192 return nullptr; |
193 if (CPDF_Array* pArray = pValue->AsArray()) | 193 if (CPDF_Array* pArray = pValue->AsArray()) |
194 return pArray; | 194 return pArray; |
195 if (CPDF_Dictionary* pDict = pValue->AsDictionary()) | 195 if (CPDF_Dictionary* pDict = pValue->AsDictionary()) |
196 return pDict->GetArrayBy("D"); | 196 return pDict->GetArrayFor("D"); |
197 return nullptr; | 197 return nullptr; |
198 } | 198 } |
OLD | NEW |