Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/unotools/source/i18n/transliterationwrapper.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 <unotools/transliterationwrapper.hxx>
23
#include <i18nlangtag/languagetag.hxx>
24
#include <i18nutil/transliteration.hxx>
25
#include <comphelper/diagnose_ex.hxx>
26
27
#include <com/sun/star/i18n/Transliteration.hpp>
28
29
using namespace ::com::sun::star::lang;
30
using namespace ::com::sun::star::i18n;
31
using namespace ::com::sun::star::uno;
32
using namespace ::utl;
33
34
TransliterationWrapper::TransliterationWrapper(
35
                    const Reference< XComponentContext > & rxContext,
36
                    TransliterationFlags nTyp )
37
7.19k
    : xTrans( Transliteration::create(rxContext) ),
38
7.19k
      aLanguageTag( LANGUAGE_SYSTEM ), nType( nTyp ), bFirstCall( true )
39
7.19k
{
40
7.19k
}
41
42
TransliterationWrapper::~TransliterationWrapper()
43
7.19k
{
44
7.19k
}
45
46
OUString TransliterationWrapper::transliterate(const OUString& rStr, LanguageType nLang,
47
                                               sal_Int32 nStart, sal_Int32 nLen,
48
                                               Sequence <sal_Int32>* pOffset )
49
0
{
50
0
    OUString sRet;
51
0
    if( xTrans.is() )
52
0
    {
53
0
        try
54
0
        {
55
0
            loadModuleIfNeeded( nLang );
56
57
0
            if ( pOffset )
58
0
                sRet = xTrans->transliterate( rStr, nStart, nLen, *pOffset );
59
0
            else
60
0
                sRet = xTrans->transliterateString2String( rStr, nStart, nLen);
61
0
        }
62
0
        catch( Exception&  )
63
0
        {
64
0
            TOOLS_WARN_EXCEPTION("unotools.i18n", "" );
65
0
        }
66
0
    }
67
0
    return sRet;
68
0
}
69
70
OUString TransliterationWrapper::transliterate( const OUString& rStr,
71
                                                sal_Int32 nStart, sal_Int32 nLen ) const
72
0
{
73
0
    OUString sRet( rStr );
74
0
    if( xTrans.is() )
75
0
    {
76
0
        try
77
0
        {
78
0
            sRet = xTrans->transliterateString2String( rStr, nStart, nLen);
79
0
        }
80
0
        catch( Exception&  )
81
0
        {
82
0
            TOOLS_WARN_EXCEPTION("unotools.i18n", "" );
83
0
        }
84
0
    }
85
0
    return sRet;
86
0
}
87
88
bool TransliterationWrapper::needLanguageForTheMode() const
89
118k
{
90
118k
    return TransliterationFlags::UPPERCASE_LOWERCASE == nType ||
91
118k
           TransliterationFlags::LOWERCASE_UPPERCASE == nType ||
92
118k
           TransliterationFlags::IGNORE_CASE == nType ||
93
0
           TransliterationFlags::SENTENCE_CASE == nType ||
94
0
           TransliterationFlags::TITLE_CASE    == nType ||
95
0
           TransliterationFlags::TOGGLE_CASE   == nType;
96
118k
}
97
98
void TransliterationWrapper::setLanguageLocaleImpl( LanguageType nLang )
99
125k
{
100
125k
    if( LANGUAGE_NONE == nLang )
101
942
        nLang = LANGUAGE_SYSTEM;
102
125k
    aLanguageTag.reset( nLang);
103
125k
}
104
105
void TransliterationWrapper::loadModuleIfNeeded( LanguageType nLang )
106
142k
{
107
142k
    bool bLoad = bFirstCall;
108
142k
    bFirstCall = false;
109
110
142k
    if( nType == TransliterationFlags::SENTENCE_CASE )
111
0
    {
112
0
        if( bLoad )
113
0
            loadModuleByImplName(u"SENTENCE_CASE"_ustr, nLang);
114
0
    }
115
142k
    else if( nType == TransliterationFlags::TITLE_CASE )
116
0
    {
117
0
        if( bLoad )
118
0
            loadModuleByImplName(u"TITLE_CASE"_ustr, nLang);
119
0
    }
120
142k
    else if( nType == TransliterationFlags::TOGGLE_CASE )
121
0
    {
122
0
        if( bLoad )
123
0
            loadModuleByImplName(u"TOGGLE_CASE"_ustr, nLang);
124
0
    }
125
142k
    else
126
142k
    {
127
142k
        if( aLanguageTag.getLanguageType() != nLang )
128
125k
        {
129
125k
            setLanguageLocaleImpl( nLang );
130
125k
            if( !bLoad )
131
118k
                bLoad = needLanguageForTheMode();
132
125k
        }
133
142k
        if( bLoad )
134
125k
            loadModuleImpl();
135
142k
    }
136
142k
}
137
138
void TransliterationWrapper::loadModuleImpl() const
139
125k
{
140
125k
    if ( bFirstCall )
141
0
        const_cast<TransliterationWrapper*>(this)->setLanguageLocaleImpl( LANGUAGE_SYSTEM );
142
143
125k
    try
144
125k
    {
145
125k
        if ( xTrans.is() )
146
125k
            xTrans->loadModule( static_cast<TransliterationModules>(nType), aLanguageTag.getLocale() );
147
125k
    }
148
125k
    catch ( const Exception& )
149
125k
    {
150
62.6k
        TOOLS_WARN_EXCEPTION( "unotools.i18n", "loadModuleImpl" );
151
62.6k
    }
152
153
125k
    bFirstCall = false;
154
125k
}
155
156
void TransliterationWrapper::loadModuleByImplName(const OUString& rModuleName,
157
                                                  LanguageType nLang )
158
0
{
159
0
    try
160
0
    {
161
0
        setLanguageLocaleImpl( nLang );
162
0
        css::lang::Locale aLocale( aLanguageTag.getLocale());
163
        // Reset LanguageTag, so the next call to loadModuleIfNeeded() forces
164
        // new settings.
165
0
        aLanguageTag.reset( LANGUAGE_DONTKNOW);
166
0
        if ( xTrans.is() )
167
0
            xTrans->loadModuleByImplName( rModuleName, aLocale );
168
0
    }
169
0
    catch ( const Exception& )
170
0
    {
171
0
        TOOLS_WARN_EXCEPTION( "unotools.i18n", "loadModuleByImplName" );
172
0
    }
173
174
0
    bFirstCall = false;
175
0
}
176
177
bool TransliterationWrapper::equals(
178
    const OUString& rStr1, sal_Int32 nPos1, sal_Int32 nCount1, sal_Int32& nMatch1,
179
    const OUString& rStr2, sal_Int32 nPos2, sal_Int32 nCount2, sal_Int32& nMatch2 ) const
180
5.76M
{
181
5.76M
    try
182
5.76M
    {
183
5.76M
        if( bFirstCall )
184
0
            loadModuleImpl();
185
5.76M
        if ( xTrans.is() )
186
5.76M
            return xTrans->equals( rStr1, nPos1, nCount1, nMatch1, rStr2, nPos2, nCount2, nMatch2 );
187
5.76M
    }
188
5.76M
    catch ( const Exception& )
189
5.76M
    {
190
0
        TOOLS_WARN_EXCEPTION( "unotools.i18n", "equals" );
191
0
    }
192
0
    return false;
193
5.76M
}
194
195
sal_Int32 TransliterationWrapper::compareString( const OUString& rStr1, const OUString& rStr2 ) const
196
662
{
197
662
    try
198
662
    {
199
662
        if( bFirstCall )
200
0
            loadModuleImpl();
201
662
        if ( xTrans.is() )
202
662
            return xTrans->compareString( rStr1, rStr2 );
203
662
    }
204
662
    catch (const Exception&)
205
662
    {
206
0
        TOOLS_WARN_EXCEPTION( "unotools.i18n", "compareString" );
207
0
    }
208
0
    return 0;
209
662
}
210
211
// --- helpers --------------------------------------------------------
212
213
bool TransliterationWrapper::isEqual( const OUString& rStr1, const OUString& rStr2 ) const
214
5.76M
{
215
5.76M
    sal_Int32 nMatch1(0), nMatch2(0);
216
5.76M
    bool bMatch = equals(
217
5.76M
        rStr1, 0, rStr1.getLength(), nMatch1,
218
5.76M
        rStr2, 0, rStr2.getLength(), nMatch2 );
219
5.76M
    return bMatch;
220
5.76M
}
221
222
bool TransliterationWrapper::isMatch( const OUString& rStr1, const OUString& rStr2 ) const
223
0
{
224
0
    sal_Int32 nMatch1(0), nMatch2(0);
225
0
    equals(
226
0
        rStr1, 0, rStr1.getLength(), nMatch1,
227
0
        rStr2, 0, rStr2.getLength(), nMatch2 );
228
0
    return (nMatch1 <= nMatch2) && (nMatch1 == rStr1.getLength());
229
0
}
230
231
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */