1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_i18npool.hxx"
26
27 #include <rtl/ustrbuf.hxx>
28 #include <indexentrysupplier_asian.hxx>
29 #include <data/indexdata_alphanumeric.h>
30
31 using namespace ::com::sun::star::uno;
32 using namespace ::com::sun::star::lang;
33 using namespace ::rtl;
34
35 namespace com { namespace sun { namespace star { namespace i18n {
36
thisModule()37 extern "C" { static void SAL_CALL thisModule() {} }
38
IndexEntrySupplier_asian(const Reference<XMultiServiceFactory> & rxMSF)39 IndexEntrySupplier_asian::IndexEntrySupplier_asian(
40 const Reference < XMultiServiceFactory >& rxMSF ) : IndexEntrySupplier_Common(rxMSF)
41 {
42 implementationName = "com.sun.star.i18n.IndexEntrySupplier_asian";
43 #ifdef SAL_DLLPREFIX
44 OUString lib=OUString::createFromAscii( SAL_DLLPREFIX "index_data" SAL_DLLEXTENSION);
45 #else
46 OUString lib=OUString::createFromAscii("index_data" SAL_DLLEXTENSION);
47 #endif
48 hModule = osl_loadModuleRelative(
49 &thisModule, lib.pData, SAL_LOADMODULE_DEFAULT );
50 }
51
~IndexEntrySupplier_asian()52 IndexEntrySupplier_asian::~IndexEntrySupplier_asian()
53 {
54 if (hModule) osl_unloadModule(hModule);
55 }
56
57 OUString SAL_CALL
getIndexCharacter(const OUString & rIndexEntry,const Locale & rLocale,const OUString & rAlgorithm)58 IndexEntrySupplier_asian::getIndexCharacter( const OUString& rIndexEntry,
59 const Locale& rLocale, const OUString& rAlgorithm ) throw (RuntimeException)
60 {
61 sal_Int32 i=0;
62 sal_uInt32 ch = rIndexEntry.iterateCodePoints(&i, 0);
63 if (hModule) {
64 OUString get=OUString::createFromAscii("get_indexdata_");
65 sal_uInt16** (*func)(sal_Int16*)=NULL;
66 if (rLocale.Language.equalsAscii("zh") && OUString::createFromAscii("TW HK MO").indexOf(rLocale.Country) >= 0)
67 func=(sal_uInt16** (*)(sal_Int16*))osl_getFunctionSymbol(hModule, (get+rLocale.Language+OUString::createFromAscii("_TW_")+rAlgorithm).pData);
68 if (!func)
69 func=(sal_uInt16** (*)(sal_Int16*))osl_getFunctionSymbol(hModule, (get+rLocale.Language+OUString('_')+rAlgorithm).pData);
70 if (func) {
71 sal_Int16 max_index;
72 sal_uInt16** idx=func(&max_index);
73 if (((sal_Int16)(ch >> 8)) <= max_index) {
74 sal_uInt16 address=idx[0][ch >> 8];
75 if (address != 0xFFFF) {
76 address=idx[1][address+(ch & 0xFF)];
77 return idx[2] ? OUString(&idx[2][address]) : OUString(address);
78 }
79 }
80 }
81 }
82 // using alphanumeric index for non-define stirng
83 return OUString(&idxStr[(ch & 0xFFFFFF00) ? 0 : ch], 1);
84 }
85
86 OUString SAL_CALL
getIndexKey(const OUString & rIndexEntry,const OUString & rPhoneticEntry,const Locale & rLocale)87 IndexEntrySupplier_asian::getIndexKey( const OUString& rIndexEntry,
88 const OUString& rPhoneticEntry, const Locale& rLocale) throw (RuntimeException)
89 {
90 return getIndexCharacter(getEntry(rIndexEntry, rPhoneticEntry, rLocale), rLocale, aAlgorithm);
91 }
92
93 sal_Int16 SAL_CALL
compareIndexEntry(const OUString & rIndexEntry1,const OUString & rPhoneticEntry1,const Locale & rLocale1,const OUString & rIndexEntry2,const OUString & rPhoneticEntry2,const Locale & rLocale2)94 IndexEntrySupplier_asian::compareIndexEntry(
95 const OUString& rIndexEntry1, const OUString& rPhoneticEntry1, const Locale& rLocale1,
96 const OUString& rIndexEntry2, const OUString& rPhoneticEntry2, const Locale& rLocale2 )
97 throw (RuntimeException)
98 {
99 sal_Int32 result = collator->compareString(getEntry(rIndexEntry1, rPhoneticEntry1, rLocale1),
100 getEntry(rIndexEntry2, rPhoneticEntry2, rLocale2));
101
102 // equivalent of phonetic entries does not mean equivalent of index entries.
103 // we have to continue comparing index entry here.
104 if (result == 0 && usePhonetic && rPhoneticEntry1.getLength() > 0 &&
105 rLocale1.Language == rLocale2.Language && rLocale1.Country == rLocale2.Country &&
106 rLocale1.Variant == rLocale2.Variant)
107 result = collator->compareString(rIndexEntry1, rIndexEntry2);
108 return sal::static_int_cast< sal_Int16 >(result); // result in { -1, 0, 1 }
109 }
110
111 OUString SAL_CALL
getPhoneticCandidate(const OUString & rIndexEntry,const Locale & rLocale)112 IndexEntrySupplier_asian::getPhoneticCandidate( const OUString& rIndexEntry,
113 const Locale& rLocale ) throw (RuntimeException)
114 {
115 if (hModule) {
116 sal_uInt16 **(*func)(sal_Int16*)=NULL;
117 const sal_Char *func_name=NULL;
118 if (rLocale.Language.equalsAscii("zh"))
119 func_name=(OUString::createFromAscii("TW HK MO").indexOf(rLocale.Country) >= 0) ? "get_zh_zhuyin" : "get_zh_pinyin";
120 else if (rLocale.Language.equalsAscii("ko"))
121 func_name="get_ko_phonetic";
122 if (func_name)
123 func=(sal_uInt16 **(*)(sal_Int16*))osl_getFunctionSymbol(hModule, OUString::createFromAscii(func_name).pData);
124 if (func) {
125 OUStringBuffer candidate;
126 sal_Int16 max_index;
127 sal_uInt16** idx=func(&max_index);
128 OUString aIndexEntry=rIndexEntry;
129 for (sal_Int32 i=0,j=0; i < rIndexEntry.getLength(); i=j) {
130 sal_uInt32 ch = rIndexEntry.iterateCodePoints(&j, 1);
131 if (((sal_Int16)(ch>>8)) <= max_index) {
132 sal_uInt16 address = idx[0][ch>>8];
133 if (address != 0xFFFF) {
134 address = idx[1][address + (ch & 0xFF)];
135 if (i > 0 && rLocale.Language.equalsAscii("zh"))
136 candidate.appendAscii(" ");
137 if (idx[2])
138 candidate.append(&idx[2][address]);
139 else
140 candidate.append(address);
141 } else
142 candidate.appendAscii(" ");
143 }
144 }
145 return candidate.makeStringAndClear();
146 }
147 }
148 return OUString();
149 }
150 } } } }
151