Coverage Report

Created: 2025-12-08 09:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/i18npool/source/indexentry/indexentrysupplier_asian.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/temporary.hxx>
23
#include <rtl/ustrbuf.hxx>
24
#include <collatorImpl.hxx>
25
#include <indexentrysupplier_asian.hxx>
26
#include "data/indexdata_alphanumeric.h"
27
28
using namespace ::com::sun::star::uno;
29
using namespace ::com::sun::star::lang;
30
31
namespace i18npool {
32
33
IndexEntrySupplier_asian::IndexEntrySupplier_asian(
34
0
    const Reference < XComponentContext >& rxContext ) : IndexEntrySupplier_Common(rxContext)
35
0
{
36
0
    implementationName = "com.sun.star.i18n.IndexEntrySupplier_asian";
37
0
}
38
39
IndexEntrySupplier_asian::~IndexEntrySupplier_asian()
40
0
{
41
0
}
42
43
OUString SAL_CALL
44
IndexEntrySupplier_asian::getIndexCharacter( const OUString& rIndexEntry,
45
    const Locale& rLocale, const OUString& rAlgorithm )
46
0
{
47
0
    sal_uInt32 ch = rIndexEntry.iterateCodePoints(&o3tl::temporary(sal_Int32(0)), 0);
48
49
0
    const sal_uInt16** (*func)(sal_Int16&)=nullptr;
50
0
    if ( rLocale.Language == "zh" && u"TW HK MO"_ustr.indexOf(rLocale.Country) >= 0 ) {
51
0
        if ( rAlgorithm == "radical" )
52
0
            func = get_indexdata_zh_TW_radical;
53
0
        else if ( rAlgorithm == "stroke" )
54
0
            func = get_indexdata_zh_TW_stroke;
55
0
    }
56
0
    if (!func) {
57
0
        if ( rLocale.Language == "ko" ) {
58
0
            if ( rAlgorithm == "dict" )
59
0
                func = get_indexdata_ko_dict;
60
0
        } else if ( rLocale.Language == "zh" ) {
61
0
            if ( rAlgorithm == "pinyin" )
62
0
                func = get_indexdata_zh_pinyin;
63
0
            else if ( rAlgorithm == "radical" )
64
0
                func = get_indexdata_zh_radical;
65
0
            else if ( rAlgorithm == "stroke" )
66
0
                func = get_indexdata_zh_stroke;
67
0
            else if ( rAlgorithm == "zhuyin" )
68
0
                func = get_indexdata_zh_zhuyin;
69
0
        }
70
0
    }
71
0
    if (func) {
72
0
        sal_Int16 max_index;
73
0
        const sal_uInt16** idx=func(max_index);
74
0
        if (static_cast<sal_Int16>(ch >> 8) <= max_index) {
75
0
            sal_uInt16 address=idx[0][ch >> 8];
76
0
            if (address != 0xFFFF) {
77
0
                address=idx[1][address+(ch & 0xFF)];
78
0
                return idx[2]
79
0
                    ? OUString(
80
0
                        reinterpret_cast<const sal_Unicode *>(&idx[2][address]))
81
0
                    : OUString(sal_Unicode(address));
82
0
            }
83
0
        }
84
0
    }
85
86
    // using alphanumeric index for non-define string
87
0
    return OUString(&idxStr[(ch & 0xFFFFFF00) ? 0 : ch], 1);
88
0
}
89
90
OUString SAL_CALL
91
IndexEntrySupplier_asian::getIndexKey( const OUString& rIndexEntry,
92
    const OUString& rPhoneticEntry, const Locale& rLocale)
93
0
{
94
0
    return getIndexCharacter(getEntry(rIndexEntry, rPhoneticEntry, rLocale), rLocale, aAlgorithm);
95
0
}
96
97
sal_Int16 SAL_CALL
98
IndexEntrySupplier_asian::compareIndexEntry(
99
    const OUString& rIndexEntry1, const OUString& rPhoneticEntry1, const Locale& rLocale1,
100
    const OUString& rIndexEntry2, const OUString& rPhoneticEntry2, const Locale& rLocale2 )
101
0
{
102
0
    sal_Int32 result = collator->compareString(getEntry(rIndexEntry1, rPhoneticEntry1, rLocale1),
103
0
                                    getEntry(rIndexEntry2, rPhoneticEntry2, rLocale2));
104
105
    // equivalent of phonetic entries does not mean equivalent of index entries.
106
    // we have to continue comparing index entry here.
107
0
    if (result == 0 && usePhonetic && !rPhoneticEntry1.isEmpty() &&
108
0
            rLocale1.Language == rLocale2.Language && rLocale1.Country == rLocale2.Country &&
109
0
            rLocale1.Variant == rLocale2.Variant)
110
0
        result = collator->compareString(rIndexEntry1, rIndexEntry2);
111
0
    return sal::static_int_cast< sal_Int16 >(result); // result in { -1, 0, 1 }
112
0
}
113
114
OUString SAL_CALL
115
IndexEntrySupplier_asian::getPhoneticCandidate( const OUString& rIndexEntry,
116
        const Locale& rLocale )
117
0
{
118
0
    sal_uInt16 const **(*func)(sal_Int16&)=nullptr;
119
0
    if ( rLocale.Language == "zh" )
120
0
        func = (u"TW HK MO"_ustr.indexOf(rLocale.Country) >= 0) ?  get_zh_zhuyin : get_zh_pinyin;
121
0
    else if ( rLocale.Language == "ko" )
122
0
        func = get_ko_phonetic;
123
124
0
    if (func) {
125
0
        OUStringBuffer candidate;
126
0
        sal_Int16 max_index;
127
0
        sal_uInt16 const ** idx=func(max_index);
128
0
        for (sal_Int32 i=0,j=0; i < rIndexEntry.getLength(); i=j) {
129
0
            sal_uInt32 ch = rIndexEntry.iterateCodePoints(&j);
130
0
            if (static_cast<sal_Int16>(ch>>8) <= max_index) {
131
0
                sal_uInt16 address = idx[0][ch>>8];
132
0
                if (address != 0xFFFF) {
133
0
                    address = idx[1][address + (ch & 0xFF)];
134
0
                    if ( i > 0 && rLocale.Language == "zh" )
135
0
                        candidate.append(" ");
136
0
                    if (idx[2])
137
0
                        candidate.append(
138
0
                            reinterpret_cast<const sal_Unicode *>(&idx[2][address]));
139
0
                    else
140
0
                        candidate.append(sal_Unicode(address));
141
0
                } else
142
0
                    candidate.append(" ");
143
0
            }
144
0
        }
145
0
        return candidate.makeStringAndClear();
146
0
    }
147
0
    return OUString();
148
0
}
149
150
}
151
152
153
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */