Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/i18npool/source/numberformatcode/numberformatcode.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 <numberformatcode.hxx>
21
#include <com/sun/star/i18n/KNumberFormatUsage.hpp>
22
#include <com/sun/star/i18n/KNumberFormatType.hpp>
23
#include <com/sun/star/i18n/LocaleData2.hpp>
24
#include <comphelper/sequence.hxx>
25
#include <cppuhelper/supportsservice.hxx>
26
27
NumberFormatCodeMapper::NumberFormatCodeMapper(
28
            const css::uno::Reference < css::uno::XComponentContext >& rxContext )
29
460k
{
30
460k
        m_xLocaleData.set( css::i18n::LocaleData2::create( rxContext ) );
31
460k
}
32
33
34
NumberFormatCodeMapper::~NumberFormatCodeMapper()
35
460k
{
36
460k
}
37
38
39
css::i18n::NumberFormatCode SAL_CALL
40
NumberFormatCodeMapper::getDefault( sal_Int16 formatType, sal_Int16 formatUsage, const css::lang::Locale& rLocale )
41
0
{
42
43
0
    OUString elementType = mapElementTypeShortToString(formatType);
44
0
    OUString elementUsage = mapElementUsageShortToString(formatUsage);
45
46
0
    std::scoped_lock g(maMutex);
47
0
    const css::uno::Sequence< css::i18n::FormatElement > &aFormatSeq = getFormats( rLocale );
48
49
0
    auto pFormat = std::find_if(aFormatSeq.begin(), aFormatSeq.end(),
50
0
        [&elementType, &elementUsage](const css::i18n::FormatElement& rFormat) {
51
0
            return rFormat.isDefault
52
0
                && rFormat.formatType == elementType
53
0
                && rFormat.formatUsage == elementUsage; });
54
0
    if (pFormat != aFormatSeq.end())
55
0
        return css::i18n::NumberFormatCode(formatType,
56
0
                                           formatUsage,
57
0
                                           pFormat->formatCode,
58
0
                                           pFormat->formatName,
59
0
                                           pFormat->formatKey,
60
0
                                           pFormat->formatIndex,
61
0
                                           true);
62
0
    css::i18n::NumberFormatCode defaultNumberFormatCode;
63
0
    return defaultNumberFormatCode;
64
0
}
65
66
67
css::i18n::NumberFormatCode SAL_CALL
68
NumberFormatCodeMapper::getFormatCode( sal_Int16 formatIndex, const css::lang::Locale& rLocale )
69
1.47M
{
70
1.47M
    std::scoped_lock g(maMutex);
71
1.47M
    const css::uno::Sequence< css::i18n::FormatElement > &aFormatSeq = getFormats( rLocale );
72
73
1.47M
    auto pFormat = std::find_if(aFormatSeq.begin(), aFormatSeq.end(),
74
2.66M
        [formatIndex](const css::i18n::FormatElement& rFormat) { return rFormat.formatIndex == formatIndex; });
75
1.47M
    if (pFormat != aFormatSeq.end())
76
1.47M
        return css::i18n::NumberFormatCode(mapElementTypeStringToShort(pFormat->formatType),
77
1.47M
                                           mapElementUsageStringToShort(pFormat->formatUsage),
78
1.47M
                                           pFormat->formatCode,
79
1.47M
                                           pFormat->formatName,
80
1.47M
                                           pFormat->formatKey,
81
1.47M
                                           pFormat->formatIndex,
82
1.47M
                                           pFormat->isDefault);
83
0
    css::i18n::NumberFormatCode defaultNumberFormatCode;
84
0
    return defaultNumberFormatCode;
85
1.47M
}
86
87
88
css::uno::Sequence< css::i18n::NumberFormatCode > SAL_CALL
89
NumberFormatCodeMapper::getAllFormatCode( sal_Int16 formatUsage, const css::lang::Locale& rLocale )
90
1.87M
{
91
1.87M
    std::scoped_lock g(maMutex);
92
1.87M
    const css::uno::Sequence< css::i18n::FormatElement > &aFormatSeq = getFormats( rLocale );
93
94
1.87M
    std::vector<css::i18n::NumberFormatCode> aVec;
95
1.87M
    aVec.reserve(aFormatSeq.getLength());
96
97
131M
    for (const auto& rFormat : aFormatSeq) {
98
131M
        sal_Int16 elementUsage = mapElementUsageStringToShort(rFormat.formatUsage);
99
131M
        if ( elementUsage == formatUsage ) {
100
19.3M
            aVec.emplace_back(mapElementTypeStringToShort(rFormat.formatType),
101
19.3M
                              formatUsage,
102
19.3M
                              rFormat.formatCode,
103
19.3M
                              rFormat.formatName,
104
19.3M
                              rFormat.formatKey,
105
19.3M
                              rFormat.formatIndex,
106
19.3M
                              rFormat.isDefault);
107
19.3M
        }
108
131M
    }
109
1.87M
    return comphelper::containerToSequence(aVec);
110
1.87M
}
111
112
113
css::uno::Sequence< css::i18n::NumberFormatCode > SAL_CALL
114
NumberFormatCodeMapper::getAllFormatCodes( const css::lang::Locale& rLocale )
115
232k
{
116
232k
    std::scoped_lock g(maMutex);
117
232k
    const css::uno::Sequence< css::i18n::FormatElement > &aFormatSeq = getFormats( rLocale );
118
119
232k
    std::vector<css::i18n::NumberFormatCode> aVec;
120
232k
    aVec.reserve(aFormatSeq.getLength());
121
122
232k
    std::transform(aFormatSeq.begin(), aFormatSeq.end(), std::back_inserter(aVec),
123
16.2M
        [](const css::i18n::FormatElement& rFormat) -> css::i18n::NumberFormatCode {
124
16.2M
            return { mapElementTypeStringToShort(rFormat.formatType),
125
16.2M
                     mapElementUsageStringToShort(rFormat.formatUsage),
126
16.2M
                     rFormat.formatCode,
127
16.2M
                     rFormat.formatName,
128
16.2M
                     rFormat.formatKey,
129
16.2M
                     rFormat.formatIndex,
130
16.2M
                     rFormat.isDefault };
131
16.2M
        });
132
232k
    return comphelper::containerToSequence(aVec);
133
232k
}
134
135
136
// --- private implementation -----------------------------------------
137
138
const css::uno::Sequence< css::i18n::FormatElement >& NumberFormatCodeMapper::getFormats( const css::lang::Locale& rLocale )
139
3.58M
{
140
    /* Find the FormatElement Sequence in the cache */
141
3.58M
    for (const FormatElementCacheItem& item : m_aFormatElementCache)
142
3.50M
    {
143
3.50M
        if ( item.first == rLocale )
144
3.13M
            return item.second;
145
3.50M
    }
146
147
    /* Not found; Get the FormatElement Sequence for the given Locale */
148
446k
    css::uno::Sequence< css::i18n::FormatElement > aFormatElementSequence;
149
446k
    if ( m_xLocaleData.is() )
150
446k
        aFormatElementSequence = m_xLocaleData->getAllFormats( rLocale );
151
152
    /* Add the FormatElement Sequence to the cache */
153
446k
    const int FORMATELEMENTCACHE_SIZE = 3;
154
446k
    if ( m_aFormatElementCache.size() > FORMATELEMENTCACHE_SIZE )
155
40.0k
        m_aFormatElementCache.pop_front();
156
446k
    m_aFormatElementCache.emplace_back( rLocale, aFormatElementSequence );
157
446k
    return m_aFormatElementCache.back().second;
158
3.58M
}
159
160
161
OUString
162
NumberFormatCodeMapper::mapElementTypeShortToString(sal_Int16 formatType)
163
0
{
164
165
0
    switch ( formatType )
166
0
    {
167
0
        case css::i18n::KNumberFormatType::SHORT :
168
0
            return u"short"_ustr;
169
0
        case css::i18n::KNumberFormatType::MEDIUM :
170
0
            return u"medium"_ustr;
171
0
        case css::i18n::KNumberFormatType::LONG :
172
0
            return u"long"_ustr;
173
0
    }
174
0
    return OUString();
175
0
}
176
177
sal_Int16
178
NumberFormatCodeMapper::mapElementTypeStringToShort(std::u16string_view formatType)
179
37.1M
{
180
37.1M
    if ( formatType == u"short" )
181
5.59M
        return css::i18n::KNumberFormatType::SHORT;
182
31.5M
    if ( formatType == u"medium" )
183
24.4M
        return css::i18n::KNumberFormatType::MEDIUM;
184
7.07M
    if ( formatType == u"long" )
185
7.07M
        return css::i18n::KNumberFormatType::LONG;
186
187
0
    return css::i18n::KNumberFormatType::SHORT;
188
7.07M
}
189
190
OUString
191
NumberFormatCodeMapper::mapElementUsageShortToString(sal_Int16 formatUsage)
192
0
{
193
0
    switch ( formatUsage )
194
0
    {
195
0
        case css::i18n::KNumberFormatUsage::DATE :
196
0
            return u"DATE"_ustr;
197
0
        case css::i18n::KNumberFormatUsage::TIME :
198
0
            return u"TIME"_ustr;
199
0
        case css::i18n::KNumberFormatUsage::DATE_TIME :
200
0
            return u"DATE_TIME"_ustr;
201
0
        case css::i18n::KNumberFormatUsage::FIXED_NUMBER :
202
0
            return u"FIXED_NUMBER"_ustr;
203
0
        case css::i18n::KNumberFormatUsage::FRACTION_NUMBER :
204
0
            return u"FRACTION_NUMBER"_ustr;
205
0
        case css::i18n::KNumberFormatUsage::PERCENT_NUMBER :
206
0
            return u"PERCENT_NUMBER"_ustr;
207
0
        case css::i18n::KNumberFormatUsage::CURRENCY :
208
0
            return u"CURRENCY"_ustr;
209
0
        case css::i18n::KNumberFormatUsage::SCIENTIFIC_NUMBER :
210
0
            return u"SCIENTIFIC_NUMBER"_ustr;
211
0
    }
212
0
    return OUString();
213
0
}
214
215
216
sal_Int16
217
NumberFormatCodeMapper::mapElementUsageStringToShort(std::u16string_view formatUsage)
218
148M
{
219
148M
    if ( formatUsage == u"DATE" )
220
65.3M
        return css::i18n::KNumberFormatUsage::DATE;
221
83.5M
    if ( formatUsage == u"TIME" )
222
14.7M
        return css::i18n::KNumberFormatUsage::TIME;
223
68.8M
    if ( formatUsage == u"DATE_TIME" )
224
6.34M
        return css::i18n::KNumberFormatUsage::DATE_TIME;
225
62.4M
    if ( formatUsage == u"FIXED_NUMBER" )
226
26.7M
        return css::i18n::KNumberFormatUsage::FIXED_NUMBER;
227
35.7M
    if ( formatUsage == u"FRACTION_NUMBER" )
228
0
        return css::i18n::KNumberFormatUsage::FRACTION_NUMBER;
229
35.7M
    if ( formatUsage == u"PERCENT_NUMBER" )
230
4.21M
        return  css::i18n::KNumberFormatUsage::PERCENT_NUMBER;
231
31.5M
    if ( formatUsage == u"CURRENCY" )
232
25.1M
        return css::i18n::KNumberFormatUsage::CURRENCY;
233
6.32M
    if ( formatUsage == u"SCIENTIFIC_NUMBER" )
234
6.32M
        return css::i18n::KNumberFormatUsage::SCIENTIFIC_NUMBER;
235
236
0
    return 0;
237
6.32M
}
238
239
240
OUString SAL_CALL
241
NumberFormatCodeMapper::getImplementationName()
242
0
{
243
0
    return u"com.sun.star.i18n.NumberFormatCodeMapper"_ustr;
244
0
}
245
246
sal_Bool SAL_CALL NumberFormatCodeMapper::supportsService(const OUString& rServiceName)
247
0
{
248
0
    return cppu::supportsService(this, rServiceName);
249
0
}
250
251
css::uno::Sequence< OUString > SAL_CALL
252
NumberFormatCodeMapper::getSupportedServiceNames()
253
0
{
254
0
    return { u"com.sun.star.i18n.NumberFormatMapper"_ustr };
255
0
}
256
257
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
258
com_sun_star_i18n_NumberFormatCodeMapper_get_implementation(
259
    css::uno::XComponentContext *context,
260
    css::uno::Sequence<css::uno::Any> const &)
261
460k
{
262
460k
    return cppu::acquire(new NumberFormatCodeMapper(context));
263
460k
}
264
265
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */