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