Coverage Report

Created: 2024-05-20 06:28

/src/qpdf/libqpdf/QPDFNumberTreeObjectHelper.cc
Line
Count
Source (jump to first uncovered line)
1
#include <qpdf/QPDFNumberTreeObjectHelper.hh>
2
3
#include <qpdf/NNTree.hh>
4
#include <qpdf/QIntC.hh>
5
6
namespace
7
{
8
    class NumberTreeDetails: public NNTreeDetails
9
    {
10
      public:
11
        std::string const&
12
        itemsKey() const override
13
1.48M
        {
14
1.48M
            static std::string k("/Nums");
15
1.48M
            return k;
16
1.48M
        }
17
        bool
18
        keyValid(QPDFObjectHandle oh) const override
19
1.81M
        {
20
1.81M
            return oh.isInteger();
21
1.81M
        }
22
        int
23
        compareKeys(QPDFObjectHandle a, QPDFObjectHandle b) const override
24
528k
        {
25
528k
            if (!(keyValid(a) && keyValid(b))) {
26
                // We don't call this without calling keyValid first
27
0
                throw std::logic_error("comparing invalid keys");
28
0
            }
29
528k
            auto as = a.getIntValue();
30
528k
            auto bs = b.getIntValue();
31
528k
            return ((as < bs) ? -1 : (as > bs) ? 1 : 0);
32
528k
        }
33
    };
34
} // namespace
35
36
static NumberTreeDetails number_tree_details;
37
38
QPDFNumberTreeObjectHelper::~QPDFNumberTreeObjectHelper() // NOLINT (modernize-use-equals-default)
39
578
{
40
    // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer. For this specific
41
    // class, see github issue #745.
42
578
}
43
44
QPDFNumberTreeObjectHelper::Members::Members(QPDFObjectHandle& oh, QPDF& q, bool auto_repair) :
45
    impl(std::make_shared<NNTreeImpl>(number_tree_details, q, oh, auto_repair))
46
578
{
47
578
}
48
49
QPDFNumberTreeObjectHelper::QPDFNumberTreeObjectHelper(
50
    QPDFObjectHandle oh, QPDF& q, bool auto_repair) :
51
    QPDFObjectHelper(oh),
52
    m(new Members(oh, q, auto_repair))
53
578
{
54
578
}
55
56
QPDFNumberTreeObjectHelper
57
QPDFNumberTreeObjectHelper::newEmpty(QPDF& qpdf, bool auto_repair)
58
0
{
59
0
    return {qpdf.makeIndirectObject("<< /Nums [] >>"_qpdf), qpdf, auto_repair};
60
0
}
61
62
QPDFNumberTreeObjectHelper::iterator::iterator(std::shared_ptr<NNTreeIterator> const& i) :
63
    impl(i)
64
33.7k
{
65
33.7k
}
66
67
bool
68
QPDFNumberTreeObjectHelper::iterator::valid() const
69
0
{
70
0
    return impl->valid();
71
0
}
72
73
QPDFNumberTreeObjectHelper::iterator&
74
QPDFNumberTreeObjectHelper::iterator::operator++()
75
0
{
76
0
    ++(*impl);
77
0
    updateIValue();
78
0
    return *this;
79
0
}
80
81
QPDFNumberTreeObjectHelper::iterator&
82
QPDFNumberTreeObjectHelper::iterator::operator--()
83
0
{
84
0
    --(*impl);
85
0
    updateIValue();
86
0
    return *this;
87
0
}
88
89
void
90
QPDFNumberTreeObjectHelper::iterator::updateIValue()
91
41.4k
{
92
41.4k
    if (impl->valid()) {
93
41.4k
        auto p = *impl;
94
41.4k
        this->ivalue.first = p->first.getIntValue();
95
41.4k
        this->ivalue.second = p->second;
96
41.4k
    } else {
97
0
        this->ivalue.first = 0;
98
0
        this->ivalue.second = QPDFObjectHandle();
99
0
    }
100
41.4k
}
101
102
QPDFNumberTreeObjectHelper::iterator::reference
103
QPDFNumberTreeObjectHelper::iterator::operator*()
104
0
{
105
0
    updateIValue();
106
0
    return this->ivalue;
107
0
}
108
109
QPDFNumberTreeObjectHelper::iterator::pointer
110
QPDFNumberTreeObjectHelper::iterator::operator->()
111
41.4k
{
112
41.4k
    updateIValue();
113
41.4k
    return &this->ivalue;
114
41.4k
}
115
116
bool
117
QPDFNumberTreeObjectHelper::iterator::operator==(iterator const& other) const
118
16.8k
{
119
16.8k
    return *(impl) == *(other.impl);
120
16.8k
}
121
122
void
123
QPDFNumberTreeObjectHelper::iterator::insertAfter(numtree_number key, QPDFObjectHandle value)
124
0
{
125
0
    impl->insertAfter(QPDFObjectHandle::newInteger(key), value);
126
0
    updateIValue();
127
0
}
128
129
void
130
QPDFNumberTreeObjectHelper::iterator::remove()
131
0
{
132
0
    impl->remove();
133
0
    updateIValue();
134
0
}
135
136
QPDFNumberTreeObjectHelper::iterator
137
QPDFNumberTreeObjectHelper::begin() const
138
0
{
139
0
    return {std::make_shared<NNTreeIterator>(m->impl->begin())};
140
0
}
141
142
QPDFNumberTreeObjectHelper::iterator
143
QPDFNumberTreeObjectHelper::end() const
144
16.8k
{
145
16.8k
    return {std::make_shared<NNTreeIterator>(m->impl->end())};
146
16.8k
}
147
148
QPDFNumberTreeObjectHelper::iterator
149
QPDFNumberTreeObjectHelper::last() const
150
0
{
151
0
    return {std::make_shared<NNTreeIterator>(m->impl->last())};
152
0
}
153
154
QPDFNumberTreeObjectHelper::iterator
155
QPDFNumberTreeObjectHelper::find(numtree_number key, bool return_prev_if_not_found)
156
19.8k
{
157
19.8k
    auto i = m->impl->find(QPDFObjectHandle::newInteger(key), return_prev_if_not_found);
158
19.8k
    return {std::make_shared<NNTreeIterator>(i)};
159
19.8k
}
160
161
QPDFNumberTreeObjectHelper::iterator
162
QPDFNumberTreeObjectHelper::insert(numtree_number key, QPDFObjectHandle value)
163
0
{
164
0
    auto i = m->impl->insert(QPDFObjectHandle::newInteger(key), value);
165
0
    return {std::make_shared<NNTreeIterator>(i)};
166
0
}
167
168
bool
169
QPDFNumberTreeObjectHelper::remove(numtree_number key, QPDFObjectHandle* value)
170
0
{
171
0
    return m->impl->remove(QPDFObjectHandle::newInteger(key), value);
172
0
}
173
174
QPDFNumberTreeObjectHelper::numtree_number
175
QPDFNumberTreeObjectHelper::getMin()
176
0
{
177
0
    auto i = begin();
178
0
    if (i == end()) {
179
0
        return 0;
180
0
    }
181
0
    return i->first;
182
0
}
183
184
QPDFNumberTreeObjectHelper::numtree_number
185
QPDFNumberTreeObjectHelper::getMax()
186
0
{
187
0
    auto i = last();
188
0
    if (i == end()) {
189
0
        return 0;
190
0
    }
191
0
    return i->first;
192
0
}
193
194
bool
195
QPDFNumberTreeObjectHelper::hasIndex(numtree_number idx)
196
0
{
197
0
    auto i = find(idx);
198
0
    return (i != this->end());
199
0
}
200
201
bool
202
QPDFNumberTreeObjectHelper::findObject(numtree_number idx, QPDFObjectHandle& oh)
203
0
{
204
0
    auto i = find(idx);
205
0
    if (i == end()) {
206
0
        return false;
207
0
    }
208
0
    oh = i->second;
209
0
    return true;
210
0
}
211
212
bool
213
QPDFNumberTreeObjectHelper::findObjectAtOrBelow(
214
    numtree_number idx, QPDFObjectHandle& oh, numtree_number& offset)
215
19.8k
{
216
19.8k
    auto i = find(idx, true);
217
19.8k
    if (i == end()) {
218
3.05k
        return false;
219
3.05k
    }
220
16.8k
    oh = i->second;
221
16.8k
    QIntC::range_check_substract(idx, i->first);
222
16.8k
    offset = idx - i->first;
223
16.8k
    return true;
224
19.8k
}
225
226
void
227
QPDFNumberTreeObjectHelper::setSplitThreshold(int t)
228
0
{
229
0
    m->impl->setSplitThreshold(t);
230
0
}
231
232
std::map<QPDFNumberTreeObjectHelper::numtree_number, QPDFObjectHandle>
233
QPDFNumberTreeObjectHelper::getAsMap() const
234
0
{
235
0
    std::map<numtree_number, QPDFObjectHandle> result;
236
0
    result.insert(begin(), end());
237
0
    return result;
238
0
}