Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
cpdf_numbertree.cpp
Go to the documentation of this file.
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 <optional>
10#include <utility>
11
12#include "core/fpdfapi/parser/cpdf_array.h"
13#include "core/fpdfapi/parser/cpdf_dictionary.h"
14
15namespace {
16
17RetainPtr<const CPDF_Object> FindNumberNode(const CPDF_Dictionary* node_dict,
18 int num) {
19 RetainPtr<const CPDF_Array> limits_array = node_dict->GetArrayFor("Limits");
20 if (limits_array && (num < limits_array->GetIntegerAt(0) ||
21 num > limits_array->GetIntegerAt(1))) {
22 return nullptr;
23 }
24 RetainPtr<const CPDF_Array> numbers_array = node_dict->GetArrayFor("Nums");
25 if (numbers_array) {
26 for (size_t i = 0; i < numbers_array->size() / 2; i++) {
27 int index = numbers_array->GetIntegerAt(i * 2);
28 if (num == index) {
29 return numbers_array->GetDirectObjectAt(i * 2 + 1);
30 }
31 if (index > num) {
32 break;
33 }
34 }
35 return nullptr;
36 }
37
38 RetainPtr<const CPDF_Array> kids_array = node_dict->GetArrayFor("Kids");
39 if (!kids_array) {
40 return nullptr;
41 }
42
43 for (size_t i = 0; i < kids_array->size(); i++) {
44 RetainPtr<const CPDF_Dictionary> kid_dict = kids_array->GetDictAt(i);
45 if (!kid_dict) {
46 continue;
47 }
48
49 RetainPtr<const CPDF_Object> result = FindNumberNode(kid_dict.Get(), num);
50 if (result) {
51 return result;
52 }
53 }
54 return nullptr;
55}
56
57std::optional<CPDF_NumberTree::KeyValue> FindLowerBound(
58 const CPDF_Dictionary* node_dict,
59 int num) {
60 RetainPtr<const CPDF_Array> limits_array = node_dict->GetArrayFor("Limits");
61 if (limits_array) {
62 if (num < limits_array->GetIntegerAt(0)) {
63 return std::nullopt;
64 }
65 const int max_value = limits_array->GetIntegerAt(1);
66 if (num >= max_value) {
67 return CPDF_NumberTree::KeyValue(max_value,
68 FindNumberNode(node_dict, max_value));
69 }
70 }
71
72 RetainPtr<const CPDF_Array> numbers_array = node_dict->GetArrayFor("Nums");
73 if (numbers_array) {
74 for (size_t i = numbers_array->size() / 2; i > 0; --i) {
75 const size_t key_index = (i - 1) * 2;
76 const int key = numbers_array->GetIntegerAt(key_index);
77 if (num >= key) {
78 const size_t value_index = key_index + 1;
80 key, numbers_array->GetDirectObjectAt(value_index));
81 }
82 }
83 return std::nullopt;
84 }
85
86 RetainPtr<const CPDF_Array> kids_array = node_dict->GetArrayFor("Kids");
87 if (!kids_array) {
88 return std::nullopt;
89 }
90
91 for (size_t i = kids_array->size(); i > 0; --i) {
92 RetainPtr<const CPDF_Dictionary> kid_dict = kids_array->GetDictAt(i - 1);
93 if (!kid_dict) {
94 continue;
95 }
96
97 std::optional<CPDF_NumberTree::KeyValue> result =
98 FindLowerBound(kid_dict.Get(), num);
99 if (result.has_value()) {
100 return result;
101 }
102 }
103 return std::nullopt;
104}
105
106} // namespace
107
110
111CPDF_NumberTree::~CPDF_NumberTree() = default;
112
114 return FindNumberNode(root_.Get(), num);
115}
116
118 int num) const {
119 return FindLowerBound(root_.Get(), num);
120}
121
123 : key(key), value(std::move(value)) {}
124
126 default;
127
129 CPDF_NumberTree::KeyValue&&) noexcept = default;
130
131CPDF_NumberTree::KeyValue::~KeyValue() = default;
std::vector< RetainPtr< CPDF_Object > >::const_iterator const_iterator
Definition cpdf_array.h:29
std::map< ByteString, RetainPtr< CPDF_Object >, std::less<> > DictMap
CPDF_NumberTree(RetainPtr< const CPDF_Dictionary > root)
std::optional< KeyValue > GetLowerBound(int num) const
RetainPtr< const CPDF_Object > LookupValue(int num) const
KeyValue(KeyValue &&) noexcept
KeyValue & operator=(KeyValue &&) noexcept
KeyValue(int key, RetainPtr< const CPDF_Object > value)