Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svx/source/unodraw/UnoNamespaceMap.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
21
#include <climits>
22
#include <set>
23
24
#include <svx/UnoNamespaceMap.hxx>
25
#include <com/sun/star/container/XNameAccess.hpp>
26
#include <com/sun/star/lang/XServiceInfo.hpp>
27
28
#include <comphelper/sequence.hxx>
29
#include <cppuhelper/implbase.hxx>
30
#include <cppuhelper/supportsservice.hxx>
31
#include <svl/itempool.hxx>
32
#include <editeng/xmlcnitm.hxx>
33
34
using namespace ::cppu;
35
using namespace ::com::sun::star;
36
using namespace ::com::sun::star::uno;
37
using namespace ::com::sun::star::container;
38
using namespace ::com::sun::star::lang;
39
40
namespace svx
41
{
42
    namespace {
43
44
    /** implements a component to export namespaces of all SvXMLAttrContainerItem inside
45
        one or two pools with a variable count of which ids.
46
    */
47
    class NamespaceMap : public WeakImplHelper< XNameAccess, XServiceInfo >
48
    {
49
    private:
50
        const sal_uInt16* mpWhichIds;
51
        SfxItemPool* mpPool;
52
53
    public:
54
        NamespaceMap( const sal_uInt16* pWhichIds, SfxItemPool* pPool );
55
56
        // XNameAccess
57
        virtual Any SAL_CALL getByName( const OUString& aName ) override;
58
        virtual Sequence< OUString > SAL_CALL getElementNames(  ) override;
59
        virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override;
60
61
        // XElementAccess
62
        virtual Type SAL_CALL getElementType(  ) override;
63
        virtual sal_Bool SAL_CALL hasElements(  ) override;
64
65
        // XServiceInfo
66
        virtual OUString SAL_CALL getImplementationName(  ) override;
67
        virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
68
        virtual Sequence< OUString > SAL_CALL getSupportedServiceNames(  ) override;
69
    };
70
71
    }
72
73
    Reference< XInterface > NamespaceMap_createInstance( const sal_uInt16* pWhichIds, SfxItemPool* pPool )
74
0
    {
75
0
        return getXWeak(new NamespaceMap( pWhichIds, pPool ));
76
0
    }
77
78
    static Sequence< OUString > NamespaceMap_getSupportedServiceNames()
79
        noexcept
80
0
    {
81
0
        Sequence<OUString> aSupportedServiceNames { u"com.sun.star.xml.NamespaceMap"_ustr };
82
0
        return aSupportedServiceNames;
83
0
    }
84
85
    static OUString NamespaceMap_getImplementationName()
86
        noexcept
87
0
    {
88
0
        return u"com.sun.star.comp.Svx.NamespaceMap"_ustr;
89
0
    }
90
91
    namespace {
92
93
    class NamespaceIteratorImpl
94
    {
95
    private:
96
        SfxItemPool* mpPool;
97
98
        const sal_uInt16* mpWhichId;
99
100
        std::vector<const SvXMLAttrContainerItem*> mvItems;
101
        sal_Int32 mnItem;
102
103
        const SvXMLAttrContainerItem* mpCurrentAttr;
104
        sal_uInt16 mnCurrentAttr;
105
106
    public:
107
108
        NamespaceIteratorImpl( const sal_uInt16* pWhichIds, SfxItemPool* pPool );
109
110
        bool next( OUString& rPrefix, OUString& rURL );
111
    };
112
113
    }
114
}
115
116
using namespace ::svx;
117
118
119
NamespaceIteratorImpl::NamespaceIteratorImpl( const sal_uInt16* pWhichIds, SfxItemPool* pPool )
120
0
{
121
0
    mpPool = pPool;
122
0
    mpCurrentAttr = nullptr;
123
0
    mnCurrentAttr = 0;
124
125
0
    mpWhichId = pWhichIds;
126
127
0
    mnItem = -1;
128
0
    if (mpWhichId && (0 != *mpWhichId) && mpPool)
129
0
    {
130
0
        ItemSurrogates aSurrogates = mpPool->GetItemSurrogates(*mpWhichId);
131
0
        mvItems.reserve(aSurrogates.size());
132
0
        for (const SfxPoolItem* pItem : aSurrogates)
133
0
            mvItems.push_back(static_cast<const SvXMLAttrContainerItem*>(pItem));
134
0
    }
135
0
}
136
137
bool NamespaceIteratorImpl::next( OUString& rPrefix, OUString& rURL )
138
0
{
139
    // we still need to process the current attribute
140
0
    if( mpCurrentAttr && (mnCurrentAttr != USHRT_MAX) )
141
0
    {
142
0
        rPrefix = mpCurrentAttr->GetPrefix( mnCurrentAttr );
143
0
        rURL = mpCurrentAttr->GetNamespace( mnCurrentAttr );
144
145
0
        mnCurrentAttr = mpCurrentAttr->GetNextNamespaceIndex( mnCurrentAttr );
146
0
        return true;
147
0
    }
148
149
    // we need the next namespace item
150
0
    mpCurrentAttr = nullptr;
151
0
    mnItem++;
152
153
    // are we finished with the current whichid?
154
0
    if( mnItem == static_cast<sal_Int32>(mvItems.size()) )
155
0
    {
156
0
        mpWhichId++;
157
158
        // are we finished with the current pool?
159
0
        if( 0 == *mpWhichId )
160
0
            return false;
161
162
0
        mnItem = -1;
163
0
        mvItems.clear();
164
0
        if (mpPool)
165
0
        {
166
0
            ItemSurrogates aSurrogates = mpPool->GetItemSurrogates(*mpWhichId);
167
0
            mvItems.reserve(aSurrogates.size());
168
0
            for (const SfxPoolItem* pItem2 : aSurrogates)
169
0
                mvItems.push_back(static_cast<const SvXMLAttrContainerItem*>(pItem2));
170
0
        }
171
0
        return next( rPrefix, rURL );
172
0
    }
173
174
0
    auto pItem = mvItems[mnItem];
175
    // get that item and see if there namespaces inside
176
0
    if( pItem->GetAttrCount() > 0 )
177
0
    {
178
0
        mpCurrentAttr = pItem;
179
0
        mnCurrentAttr = pItem->GetFirstNamespaceIndex();
180
0
    }
181
0
    return next( rPrefix, rURL );
182
0
}
183
184
185
NamespaceMap::NamespaceMap( const sal_uInt16* pWhichIds, SfxItemPool* pPool )
186
0
: mpWhichIds( pWhichIds ), mpPool( pPool )
187
0
{
188
0
}
189
190
// XNameAccess
191
Any SAL_CALL NamespaceMap::getByName( const OUString& aName )
192
0
{
193
0
    NamespaceIteratorImpl aIter( mpWhichIds, mpPool );
194
195
0
    OUString aPrefix;
196
0
    OUString aURL;
197
198
0
    bool bFound;
199
200
0
    do
201
0
    {
202
0
        bFound = aIter.next( aPrefix, aURL );
203
0
    }
204
0
    while( bFound && (aPrefix != aName ) );
205
206
0
    if( !bFound )
207
0
        throw NoSuchElementException();
208
209
0
    return Any( aURL );
210
0
}
211
212
Sequence< OUString > SAL_CALL NamespaceMap::getElementNames()
213
0
{
214
0
    NamespaceIteratorImpl aIter( mpWhichIds, mpPool );
215
216
0
    OUString aPrefix;
217
0
    OUString aURL;
218
219
0
    std::set< OUString > aPrefixSet;
220
221
0
    while( aIter.next( aPrefix, aURL ) )
222
0
        aPrefixSet.insert( aPrefix );
223
224
0
    return comphelper::containerToSequence(aPrefixSet);
225
0
}
226
227
sal_Bool SAL_CALL NamespaceMap::hasByName( const OUString& aName )
228
0
{
229
0
    NamespaceIteratorImpl aIter( mpWhichIds, mpPool );
230
231
0
    OUString aPrefix;
232
0
    OUString aURL;
233
234
0
    bool bFound;
235
236
0
    do
237
0
    {
238
0
        bFound = aIter.next( aPrefix, aURL );
239
0
    }
240
0
    while( bFound && (aPrefix != aName ) );
241
242
0
    return bFound;
243
0
}
244
245
// XElementAccess
246
Type SAL_CALL NamespaceMap::getElementType()
247
0
{
248
0
    return ::cppu::UnoType<OUString>::get();
249
0
}
250
251
sal_Bool SAL_CALL NamespaceMap::hasElements()
252
0
{
253
0
    NamespaceIteratorImpl aIter( mpWhichIds, mpPool );
254
255
0
    OUString aPrefix;
256
0
    OUString aURL;
257
258
0
    return aIter.next( aPrefix, aURL );
259
0
}
260
261
// XServiceInfo
262
OUString SAL_CALL NamespaceMap::getImplementationName(  )
263
0
{
264
0
    return NamespaceMap_getImplementationName();
265
0
}
266
267
sal_Bool SAL_CALL NamespaceMap::supportsService( const OUString& serviceName )
268
0
{
269
0
    return cppu::supportsService( this, serviceName );
270
0
}
271
272
Sequence< OUString > SAL_CALL NamespaceMap::getSupportedServiceNames(  )
273
0
{
274
0
    return NamespaceMap_getSupportedServiceNames();
275
0
}
276
277
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */