Coverage Report

Created: 2025-07-01 06:14

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