xref: /aosp_15_r20/external/pdfium/core/fpdfdoc/cpdf_numbertree.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2016 The PDFium Authors
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_numbertree.h"
8 
9 #include <utility>
10 
11 #include "core/fpdfapi/parser/cpdf_array.h"
12 #include "core/fpdfapi/parser/cpdf_dictionary.h"
13 
14 namespace {
15 
SearchNumberNode(const CPDF_Dictionary * pNode,int num)16 RetainPtr<const CPDF_Object> SearchNumberNode(const CPDF_Dictionary* pNode,
17                                               int num) {
18   RetainPtr<const CPDF_Array> pLimits = pNode->GetArrayFor("Limits");
19   if (pLimits &&
20       (num < pLimits->GetIntegerAt(0) || num > pLimits->GetIntegerAt(1))) {
21     return nullptr;
22   }
23   RetainPtr<const CPDF_Array> pNumbers = pNode->GetArrayFor("Nums");
24   if (pNumbers) {
25     for (size_t i = 0; i < pNumbers->size() / 2; i++) {
26       int index = pNumbers->GetIntegerAt(i * 2);
27       if (num == index)
28         return pNumbers->GetDirectObjectAt(i * 2 + 1);
29       if (index > num)
30         break;
31     }
32     return nullptr;
33   }
34 
35   RetainPtr<const CPDF_Array> pKids = pNode->GetArrayFor("Kids");
36   if (!pKids)
37     return nullptr;
38 
39   for (size_t i = 0; i < pKids->size(); i++) {
40     RetainPtr<const CPDF_Dictionary> pKid = pKids->GetDictAt(i);
41     if (!pKid)
42       continue;
43 
44     RetainPtr<const CPDF_Object> pFound = SearchNumberNode(pKid.Get(), num);
45     if (pFound)
46       return pFound;
47   }
48   return nullptr;
49 }
50 
51 }  // namespace
52 
CPDF_NumberTree(RetainPtr<const CPDF_Dictionary> pRoot)53 CPDF_NumberTree::CPDF_NumberTree(RetainPtr<const CPDF_Dictionary> pRoot)
54     : m_pRoot(std::move(pRoot)) {}
55 
56 CPDF_NumberTree::~CPDF_NumberTree() = default;
57 
LookupValue(int num) const58 RetainPtr<const CPDF_Object> CPDF_NumberTree::LookupValue(int num) const {
59   return SearchNumberNode(m_pRoot.Get(), num);
60 }
61