Coverage Report

Created: 2026-06-30 11:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/comphelper/source/property/propertybag.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 <comphelper/propertybag.hxx>
21
#include <osl/diagnose.h>
22
23
#include <com/sun/star/beans/IllegalTypeException.hpp>
24
#include <com/sun/star/beans/PropertyExistException.hpp>
25
#include <com/sun/star/container/ElementExistException.hpp>
26
#include <com/sun/star/lang/IllegalArgumentException.hpp>
27
#include <com/sun/star/beans/PropertyAttribute.hpp>
28
#include <com/sun/star/beans/NotRemoveableException.hpp>
29
#include <com/sun/star/beans/UnknownPropertyException.hpp>
30
31
#include <map>
32
#include <string_view>
33
34
namespace comphelper
35
{
36
37
38
    using ::com::sun::star::uno::Any;
39
    using ::com::sun::star::uno::Type;
40
    using ::com::sun::star::uno::TypeClass_VOID;
41
    using ::com::sun::star::beans::IllegalTypeException;
42
    using ::com::sun::star::beans::PropertyExistException;
43
    using ::com::sun::star::container::ElementExistException;
44
    using ::com::sun::star::lang::IllegalArgumentException;
45
    using ::com::sun::star::beans::Property;
46
    using ::com::sun::star::beans::NotRemoveableException;
47
    using ::com::sun::star::beans::UnknownPropertyException;
48
49
    namespace PropertyAttribute = ::com::sun::star::beans::PropertyAttribute;
50
51
    PropertyBag::PropertyBag()
52
9.81k
        : m_bAllowEmptyPropertyName(false)
53
9.81k
    {
54
9.81k
    }
55
56
    PropertyBag::~PropertyBag()
57
9.81k
    {
58
9.81k
    }
59
60
61
    void PropertyBag::setAllowEmptyPropertyName( bool i_isAllowed )
62
9.81k
    {
63
9.81k
        m_bAllowEmptyPropertyName = i_isAllowed;
64
9.81k
    }
65
66
67
    namespace
68
    {
69
        void    lcl_checkForEmptyName( const bool _allowEmpty, std::u16string_view _name )
70
47.7k
        {
71
47.7k
            if ( !_allowEmpty && _name.empty() )
72
0
                throw IllegalArgumentException(
73
0
                        u"The property name must not be empty."_ustr,
74
                        // TODO: resource
75
0
                        nullptr,
76
0
                        1
77
0
                      );
78
47.7k
        }
79
80
        void    lcl_checkNameAndHandle_PropertyExistException( const OUString& _name, const sal_Int32 _handle, const PropertyBag& _container )
81
47.7k
        {
82
47.7k
            if ( _container.hasPropertyByName( _name ) || _container.hasPropertyByHandle( _handle ) )
83
26.4k
                throw PropertyExistException(
84
26.4k
                    u"Property name or handle already used."_ustr,
85
26.4k
                    nullptr );
86
87
47.7k
        }
88
89
        void    lcl_checkNameAndHandle_ElementExistException( const OUString& _name, const sal_Int32 _handle, const PropertyBag& _container )
90
0
        {
91
0
            if ( _container.hasPropertyByName( _name ) || _container.hasPropertyByHandle( _handle ) )
92
0
                throw ElementExistException(
93
0
                    u"Property name or handle already used."_ustr,
94
0
                    nullptr );
95
96
0
        }
97
98
    }
99
100
101
    void PropertyBag::addVoidProperty( const OUString& _rName, const Type& _rType, sal_Int32 _nHandle, sal_Int32 _nAttributes )
102
0
    {
103
0
        if ( _rType.getTypeClass() == TypeClass_VOID )
104
0
            throw IllegalArgumentException(
105
0
                    u"Illegal property type: VOID"_ustr,
106
                        // TODO: resource
107
0
                    nullptr,
108
0
                    1
109
0
                  );
110
111
        // check name/handle sanity
112
0
        lcl_checkForEmptyName( m_bAllowEmptyPropertyName, _rName );
113
0
        lcl_checkNameAndHandle_ElementExistException( _rName, _nHandle, *this );
114
115
        // register the property
116
0
        OSL_ENSURE( _nAttributes & PropertyAttribute::MAYBEVOID, "PropertyBag::addVoidProperty: this is for default-void properties only!" );
117
0
        registerPropertyNoMember( _rName, _nHandle, _nAttributes | PropertyAttribute::MAYBEVOID, _rType, css::uno::Any() );
118
119
        // remember the default
120
0
        aDefaults.emplace( _nHandle, Any() );
121
0
    }
122
123
124
    void PropertyBag::addProperty( const OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, const Any& _rInitialValue )
125
47.7k
    {
126
        // check type sanity
127
47.7k
        const Type& aPropertyType = _rInitialValue.getValueType();
128
47.7k
        if ( aPropertyType.getTypeClass() == TypeClass_VOID )
129
0
            throw IllegalTypeException(
130
0
                u"The initial value must be non-NULL to determine the property type."_ustr,
131
                // TODO: resource
132
0
                nullptr );
133
134
        // check name/handle sanity
135
47.7k
        lcl_checkForEmptyName( m_bAllowEmptyPropertyName, _rName );
136
47.7k
        lcl_checkNameAndHandle_PropertyExistException( _rName, _nHandle, *this );
137
138
        // register the property
139
47.7k
        registerPropertyNoMember( _rName, _nHandle, _nAttributes, aPropertyType,
140
47.7k
            _rInitialValue );
141
142
        // remember the default
143
47.7k
        aDefaults.emplace( _nHandle, _rInitialValue );
144
47.7k
    }
145
146
147
    void PropertyBag::removeProperty( const OUString& _rName )
148
0
    {
149
0
        const Property& rProp = getProperty( _rName );
150
            // will throw an UnknownPropertyException if necessary
151
0
        if ( ( rProp.Attributes & PropertyAttribute::REMOVABLE ) == 0 )
152
0
            throw NotRemoveableException( OUString(), nullptr );
153
0
        const sal_Int32 nHandle = rProp.Handle;
154
155
0
        revokeProperty( nHandle );
156
157
0
        aDefaults.erase( nHandle );
158
0
    }
159
160
161
    void PropertyBag::getFastPropertyValue( sal_Int32 _nHandle, Any& _out_rValue ) const
162
19.5k
    {
163
19.5k
        if ( !hasPropertyByHandle( _nHandle ) )
164
0
            throw UnknownPropertyException(OUString::number(_nHandle));
165
166
19.5k
        OPropertyContainerHelper::getFastPropertyValue( _out_rValue, _nHandle );
167
19.5k
    }
168
169
170
    bool PropertyBag::convertFastPropertyValue( sal_Int32 _nHandle, const Any& _rNewValue, Any& _out_rConvertedValue, Any& _out_rCurrentValue ) const
171
0
    {
172
0
        if ( !hasPropertyByHandle( _nHandle ) )
173
0
            throw UnknownPropertyException(OUString::number(_nHandle));
174
175
0
        return const_cast< PropertyBag*  >( this )->OPropertyContainerHelper::convertFastPropertyValue(
176
0
            _out_rConvertedValue, _out_rCurrentValue, _nHandle, _rNewValue );
177
0
    }
178
179
180
    void PropertyBag::setFastPropertyValue( sal_Int32 _nHandle, const Any& _rValue )
181
0
    {
182
0
        if ( !hasPropertyByHandle( _nHandle ) )
183
0
            throw UnknownPropertyException(OUString::number(_nHandle));
184
185
0
        OPropertyContainerHelper::setFastPropertyValue( _nHandle, _rValue );
186
0
    }
187
188
189
    void PropertyBag::getPropertyDefaultByHandle( sal_Int32 _nHandle, Any& _out_rValue ) const
190
0
    {
191
0
        if ( !hasPropertyByHandle( _nHandle ) )
192
0
            throw UnknownPropertyException(OUString::number(_nHandle));
193
194
0
        auto pos = aDefaults.find( _nHandle );
195
0
        OSL_ENSURE( pos != aDefaults.end(), "PropertyBag::getPropertyDefaultByHandle: inconsistency!" );
196
0
        if ( pos != aDefaults.end() )
197
0
            _out_rValue = pos->second;
198
0
        else
199
0
            _out_rValue.clear();
200
0
    }
201
202
203
} // namespace comphelper
204
205
206
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */