Coverage Report

Created: 2025-07-11 06:59

/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
195k
        {
13
195k
            static std::string k("/Names");
14
195k
            return k;
15
195k
        }
16
        bool
17
        keyValid(QPDFObjectHandle oh) const override
18
237k
        {
19
237k
            return oh.isString();
20
237k
        }
21
        int
22
        compareKeys(QPDFObjectHandle a, QPDFObjectHandle b) const override
23
74.0k
        {
24
74.0k
            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
74.0k
            auto as = a.getUTF8Value();
29
74.0k
            auto bs = b.getUTF8Value();
30
74.0k
            return ((as < bs) ? -1 : (as > bs) ? 1 : 0);
31
74.0k
        }
32
    };
33
} // namespace
34
35
static NameTreeDetails name_tree_details;
36
37
QPDFNameTreeObjectHelper::~QPDFNameTreeObjectHelper() // NOLINT (modernize-use-equals-default)
38
923
{
39
    // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer. For this specific
40
    // class, see github issue #745.
41
923
}
42
43
QPDFNameTreeObjectHelper::Members::Members(QPDFObjectHandle& oh, QPDF& q, bool auto_repair) :
44
923
    impl(std::make_shared<NNTreeImpl>(name_tree_details, q, oh, auto_repair))
45
923
{
46
923
}
47
48
QPDFNameTreeObjectHelper::QPDFNameTreeObjectHelper(QPDFObjectHandle oh, QPDF& q, bool auto_repair) :
49
923
    QPDFObjectHelper(oh),
50
923
    m(new Members(oh, q, auto_repair))
51
923
{
52
923
}
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
4.02k
    impl(i)
62
4.02k
{
63
4.02k
}
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
220
{
90
220
    if (impl->valid()) {
91
220
        auto p = *impl;
92
220
        ivalue.first = p->first.getUTF8Value();
93
220
        ivalue.second = p->second;
94
220
    } else {
95
0
        ivalue.first = "";
96
0
        ivalue.second = QPDFObjectHandle();
97
0
    }
98
220
}
99
100
QPDFNameTreeObjectHelper::iterator::reference
101
QPDFNameTreeObjectHelper::iterator::operator*()
102
0
{
103
0
    updateIValue();
104
0
    return ivalue;
105
0
}
106
107
QPDFNameTreeObjectHelper::iterator::pointer
108
QPDFNameTreeObjectHelper::iterator::operator->()
109
220
{
110
220
    updateIValue();
111
220
    return &ivalue;
112
220
}
113
114
bool
115
QPDFNameTreeObjectHelper::iterator::operator==(iterator const& other) const
116
2.01k
{
117
2.01k
    return *(impl) == *(other.impl);
118
2.01k
}
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
2.01k
{
143
2.01k
    return {std::make_shared<NNTreeIterator>(m->impl->end())};
144
2.01k
}
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
2.13k
{
155
2.13k
    auto i = m->impl->find(QPDFObjectHandle::newUnicodeString(key), return_prev_if_not_found);
156
2.13k
    return {std::make_shared<NNTreeIterator>(i)};
157
2.13k
}
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
2.13k
{
182
2.13k
    auto i = find(name);
183
2.13k
    if (i == end()) {
184
1.79k
        return false;
185
1.79k
    }
186
341
    oh = i->second;
187
341
    return true;
188
2.13k
}
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
}