Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svl/source/items/itemprop.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
#include <sal/config.h>
21
22
#include <o3tl/any.hxx>
23
#include <svl/itemprop.hxx>
24
#include <svl/itempool.hxx>
25
#include <svl/itemset.hxx>
26
#include <com/sun/star/beans/PropertyAttribute.hpp>
27
#include <com/sun/star/beans/PropertyState.hpp>
28
#include <com/sun/star/lang/IllegalArgumentException.hpp>
29
#include <memory>
30
31
/*
32
 * UNO III Implementation
33
 */
34
using namespace com::sun::star;
35
using namespace com::sun::star::beans;
36
using namespace com::sun::star::lang;
37
using namespace com::sun::star::uno;
38
39
SfxItemPropertyMap::SfxItemPropertyMap( std::span<const SfxItemPropertyMapEntry> pEntries )
40
71.9k
{
41
71.9k
    m_aMap.reserve(pEntries.size());
42
71.9k
    for (const auto & pEntry : pEntries)
43
3.06M
    {
44
3.06M
        assert(!pEntry.aName.isEmpty() && "empty name? might be something left an empty entry at the end of this array");
45
3.06M
        m_aMap.insert( &pEntry );
46
3.06M
    }
47
71.9k
}
48
49
198
SfxItemPropertyMap::SfxItemPropertyMap( const SfxItemPropertyMap& rSource ) = default;
50
51
SfxItemPropertyMap::~SfxItemPropertyMap()
52
72.0k
{
53
72.0k
}
54
55
const SfxItemPropertyMapEntry* SfxItemPropertyMap::getByName( std::u16string_view rName ) const
56
67.7M
{
57
67.7M
    struct Compare
58
67.7M
    {
59
67.7M
        bool operator() ( const SfxItemPropertyMapEntry* lhs, std::u16string_view rhs ) const
60
501M
        {
61
501M
            return lhs->aName < rhs;
62
501M
        }
63
67.7M
        bool operator() ( std::u16string_view lhs, const SfxItemPropertyMapEntry* rhs ) const
64
67.7M
        {
65
67.5M
            return lhs < rhs->aName;
66
67.5M
        }
67
67.7M
    };
68
67.7M
    auto it = std::lower_bound(m_aMap.begin(), m_aMap.end(), rName, Compare());
69
67.7M
    if (it == m_aMap.end() || Compare()(rName, *it))
70
14.5M
        return nullptr;
71
53.1M
    return *it;
72
67.7M
}
73
74
uno::Sequence<beans::Property> const & SfxItemPropertyMap::getProperties() const
75
34.6k
{
76
34.6k
    if( !m_aPropSeq.hasElements() )
77
81
    {
78
81
        m_aPropSeq.realloc( m_aMap.size() );
79
81
        beans::Property* pPropArray = m_aPropSeq.getArray();
80
81
        sal_uInt32 n = 0;
81
81
        for( const SfxItemPropertyMapEntry* pEntry : m_aMap )
82
12.9k
        {
83
12.9k
            pPropArray[n].Name = pEntry->aName;
84
12.9k
            pPropArray[n].Handle = pEntry->nWID;
85
12.9k
            pPropArray[n].Type = pEntry->aType;
86
12.9k
            pPropArray[n].Attributes =
87
12.9k
                sal::static_int_cast< sal_Int16 >(pEntry->nFlags);
88
12.9k
            n++;
89
12.9k
        }
90
81
    }
91
92
34.6k
    return m_aPropSeq;
93
34.6k
}
94
95
beans::Property SfxItemPropertyMap::getPropertyByName( const OUString& rName ) const
96
0
{
97
0
    const SfxItemPropertyMapEntry* pEntry = getByName(rName);
98
0
    if( !pEntry )
99
0
        throw UnknownPropertyException(rName);
100
0
    beans::Property aProp;
101
0
    aProp.Name = rName;
102
0
    aProp.Handle = pEntry->nWID;
103
0
    aProp.Type = pEntry->aType;
104
0
    aProp.Attributes = sal::static_int_cast< sal_Int16 >(pEntry->nFlags);
105
0
    return aProp;
106
0
}
107
108
bool SfxItemPropertyMap::hasPropertyByName( std::u16string_view rName ) const
109
26.7M
{
110
26.7M
    return getByName(rName) != nullptr;
111
26.7M
}
112
113
SfxItemPropertySet::~SfxItemPropertySet()
114
70.0k
{
115
70.0k
}
116
117
// static
118
void SfxItemPropertySet::getPropertyValue( const SfxItemPropertyMapEntry& rEntry,
119
            const SfxItemSet& rSet, Any& rAny )
120
563k
{
121
    // get the SfxPoolItem
122
563k
    const SfxPoolItem* pItem = nullptr;
123
563k
    SfxItemState eState = rSet.GetItemState( rEntry.nWID, true, &pItem );
124
563k
    if (SfxItemState::SET != eState && SfxItemPool::IsWhich(rEntry.nWID) )
125
61.2k
        pItem = &rSet.GetPool()->GetUserOrPoolDefaultItem(rEntry.nWID);
126
    // return item values as uno::Any
127
563k
    if(eState >= SfxItemState::DEFAULT && pItem)
128
563k
    {
129
563k
        pItem->QueryValue( rAny, rEntry.nMemberId );
130
563k
    }
131
0
    else if(0 == (rEntry.nFlags & PropertyAttribute::MAYBEVOID))
132
0
    {
133
0
        throw RuntimeException(
134
0
            u"Property not found in ItemSet but not MAYBEVOID?"_ustr, nullptr);
135
0
    }
136
137
    // convert general SfxEnumItem values to specific values
138
563k
    if (rEntry.aType.getTypeClass() == TypeClass_ENUM
139
15.8k
        && rEntry.aType.getTypeClass() != rAny.getValueTypeClass())
140
47
    {
141
47
        if (sal_Int32 nTmp; rAny >>= nTmp)
142
47
            rAny.setValue(&nTmp, rEntry.aType);
143
47
    }
144
563k
}
145
146
void SfxItemPropertySet::getPropertyValue( const OUString &rName,
147
                                           const SfxItemSet& rSet, Any& rAny ) const
148
24.8k
{
149
    // detect which-id
150
24.8k
    const SfxItemPropertyMapEntry* pEntry = m_aMap.getByName( rName );
151
24.8k
    if ( !pEntry )
152
0
        throw UnknownPropertyException(rName);
153
24.8k
    getPropertyValue( *pEntry,rSet, rAny );
154
24.8k
}
155
156
Any SfxItemPropertySet::getPropertyValue( const OUString &rName,
157
                                          const SfxItemSet& rSet ) const
158
0
{
159
0
    Any aVal;
160
0
    getPropertyValue( rName,rSet, aVal );
161
0
    return aVal;
162
0
}
163
164
// static
165
void SfxItemPropertySet::setPropertyValue( const SfxItemPropertyMapEntry& rEntry,
166
                                           const Any& aVal,
167
                                           SfxItemSet& rSet, bool bIgnoreUnknownProperty )
168
2.41M
{
169
    // get the SfxPoolItem
170
2.41M
    const SfxPoolItem* pItem = nullptr;
171
2.41M
    SfxItemState eState = rSet.GetItemState( rEntry.nWID, true, &pItem );
172
2.41M
    if (SfxItemState::SET != eState && SfxItemPool::IsWhich(rEntry.nWID))
173
1.16M
        pItem = &rSet.GetPool()->GetUserOrPoolDefaultItem(rEntry.nWID);
174
2.41M
    if (!pItem)
175
38.9k
        return;
176
2.37M
    std::unique_ptr<SfxPoolItem> pNewItem(pItem->Clone());
177
2.37M
    if(!pNewItem)
178
0
        return;
179
2.37M
    if( !pNewItem->PutValue( aVal, rEntry.nMemberId ) )
180
4.52k
    {
181
4.52k
        if (bIgnoreUnknownProperty)
182
191
            return;
183
4.33k
        throw IllegalArgumentException();
184
4.52k
    }
185
    // apply new item
186
2.36M
    rSet.Put( std::move(pNewItem) );
187
2.36M
}
188
189
void SfxItemPropertySet::setPropertyValue( const OUString &rName,
190
                                           const Any& aVal,
191
                                           SfxItemSet& rSet, bool bIgnoreUnknownProperty ) const
192
434k
{
193
434k
    const SfxItemPropertyMapEntry* pEntry = m_aMap.getByName( rName );
194
434k
    if ( !pEntry )
195
0
    {
196
0
        if (bIgnoreUnknownProperty)
197
0
            return;
198
0
        throw UnknownPropertyException(rName);
199
0
    }
200
434k
    setPropertyValue(*pEntry, aVal, rSet, bIgnoreUnknownProperty);
201
434k
}
202
203
// static
204
PropertyState SfxItemPropertySet::getPropertyState(const SfxItemPropertyMapEntry& rEntry, const SfxItemSet& rSet)
205
    noexcept
206
2.12M
{
207
2.12M
    PropertyState eRet = PropertyState_DIRECT_VALUE;
208
2.12M
    sal_uInt16 nWhich = rEntry.nWID;
209
210
    // Get item state
211
2.12M
    SfxItemState eState = rSet.GetItemState( nWhich, false );
212
    // Return item value as UnoAny
213
2.12M
    if(eState == SfxItemState::DEFAULT)
214
1.87M
        eRet = PropertyState_DEFAULT_VALUE;
215
245k
    else if(eState < SfxItemState::DEFAULT)
216
61.3k
        eRet = PropertyState_AMBIGUOUS_VALUE;
217
2.12M
    return eRet;
218
2.12M
}
219
220
PropertyState   SfxItemPropertySet::getPropertyState(const OUString& rName, const SfxItemSet& rSet) const
221
0
{
222
0
    PropertyState eRet = PropertyState_DIRECT_VALUE;
223
224
    // Get WhichId
225
0
    const SfxItemPropertyMapEntry* pEntry = m_aMap.getByName( rName );
226
0
    if( !pEntry || !pEntry->nWID )
227
0
    {
228
0
        throw UnknownPropertyException(rName);
229
0
    }
230
0
    sal_uInt16 nWhich = pEntry->nWID;
231
232
    // Get item state
233
0
    SfxItemState eState = rSet.GetItemState(nWhich, false);
234
    // Return item value as UnoAny
235
0
    if(eState == SfxItemState::DEFAULT)
236
0
        eRet = PropertyState_DEFAULT_VALUE;
237
0
    else if(eState < SfxItemState::DEFAULT)
238
0
        eRet = PropertyState_AMBIGUOUS_VALUE;
239
0
    return eRet;
240
0
}
241
242
rtl::Reference<SfxItemPropertySetInfo> const & SfxItemPropertySet::getPropertySetInfo() const
243
130k
{
244
130k
    if( !m_xInfo.is() )
245
97
        m_xInfo = new SfxItemPropertySetInfo( m_aMap );
246
130k
    return m_xInfo;
247
130k
}
248
249
SfxItemPropertySetInfo::SfxItemPropertySetInfo(const SfxItemPropertyMap &rMap )
250
198
    : m_aOwnMap( rMap )
251
198
{
252
198
}
253
254
SfxItemPropertySetInfo::SfxItemPropertySetInfo(std::span<const SfxItemPropertyMapEntry> pEntries )
255
6
    : m_aOwnMap( pEntries )
256
6
{
257
6
}
258
259
Sequence< Property > SAL_CALL SfxItemPropertySetInfo::getProperties(  )
260
34.6k
{
261
34.6k
    return m_aOwnMap.getProperties();
262
34.6k
}
263
264
SfxItemPropertySetInfo::~SfxItemPropertySetInfo()
265
204
{
266
204
}
267
268
Property SAL_CALL SfxItemPropertySetInfo::getPropertyByName( const OUString& rName )
269
0
{
270
0
    return m_aOwnMap.getPropertyByName( rName );
271
0
}
272
273
sal_Bool SAL_CALL SfxItemPropertySetInfo::hasPropertyByName( const OUString& rName )
274
26.6M
{
275
26.6M
    return m_aOwnMap.hasPropertyByName( rName );
276
26.6M
}
277
278
SfxExtItemPropertySetInfo::SfxExtItemPropertySetInfo( std::span<const SfxItemPropertyMapEntry> pEntries,
279
                                                      const Sequence<Property>& rPropSeq )
280
13.1k
{
281
13.1k
    maMap.reserve(pEntries.size() + rPropSeq.getLength());
282
13.1k
    for (const auto & rEntry : pEntries )
283
346k
    {
284
346k
        assert(!rEntry.aName.isEmpty() && "empty name? might be something left an empty entry at the end of this array");
285
346k
        maMap.insert( rEntry );
286
346k
    }
287
13.1k
    for( const auto & rProp : rPropSeq )
288
1.91M
    {
289
1.91M
        SfxItemPropertyMapEntry aTemp(
290
1.91M
            rProp.Name,
291
1.91M
            sal::static_int_cast< sal_Int16 >( rProp.Handle ), //nWID
292
1.91M
            rProp.Type, //aType
293
1.91M
            rProp.Attributes,
294
1.91M
            0); //nFlags
295
1.91M
        maMap.insert( aTemp );
296
1.91M
    }
297
13.1k
}
298
299
SfxExtItemPropertySetInfo::~SfxExtItemPropertySetInfo()
300
13.1k
{
301
13.1k
}
302
303
Sequence< Property > SAL_CALL SfxExtItemPropertySetInfo::getProperties(  )
304
0
{
305
0
    if( !m_aPropSeq.hasElements() )
306
0
    {
307
0
        m_aPropSeq.realloc( maMap.size() );
308
0
        beans::Property* pPropArray = m_aPropSeq.getArray();
309
0
        sal_uInt32 n = 0;
310
0
        for( const SfxItemPropertyMapEntry& rEntry : maMap )
311
0
        {
312
0
            pPropArray[n].Name = rEntry.aName;
313
0
            pPropArray[n].Handle = rEntry.nWID;
314
0
            pPropArray[n].Type = rEntry.aType;
315
0
            pPropArray[n].Attributes =
316
0
                sal::static_int_cast< sal_Int16 >(rEntry.nFlags);
317
0
            n++;
318
0
        }
319
0
    }
320
321
0
    return m_aPropSeq;
322
0
}
323
324
Property SAL_CALL SfxExtItemPropertySetInfo::getPropertyByName( const OUString& rPropertyName )
325
0
{
326
0
    const SfxItemPropertyMapEntry* pEntry = getByName(rPropertyName);
327
0
    if( !pEntry )
328
0
        throw UnknownPropertyException(rPropertyName);
329
0
    beans::Property aProp;
330
0
    aProp.Name = rPropertyName;
331
0
    aProp.Handle = pEntry->nWID;
332
0
    aProp.Type = pEntry->aType;
333
0
    aProp.Attributes = sal::static_int_cast< sal_Int16 >(pEntry->nFlags);
334
0
    return aProp;
335
0
}
336
337
sal_Bool SAL_CALL SfxExtItemPropertySetInfo::hasPropertyByName( const OUString& rPropertyName )
338
836k
{
339
836k
    return getByName(rPropertyName) != nullptr;
340
836k
}
341
342
const SfxItemPropertyMapEntry* SfxExtItemPropertySetInfo::getByName( std::u16string_view rName ) const
343
836k
{
344
836k
    struct Compare
345
836k
    {
346
836k
        bool operator() ( const SfxItemPropertyMapEntry& lhs, std::u16string_view rhs ) const
347
6.57M
        {
348
6.57M
            return lhs.aName < rhs;
349
6.57M
        }
350
836k
        bool operator() ( std::u16string_view lhs, const SfxItemPropertyMapEntry& rhs ) const
351
836k
        {
352
836k
            return lhs < rhs.aName;
353
836k
        }
354
836k
    };
355
836k
    auto it = std::lower_bound(maMap.begin(), maMap.end(), rName, Compare());
356
836k
    if (it == maMap.end() || Compare()(rName, *it))
357
96.2k
        return nullptr;
358
740k
    return &*it;
359
836k
}
360
361
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */