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 37 extern "C" { static void SAL_CALL thisModule() {} } 38 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 52 IndexEntrySupplier_asian::~IndexEntrySupplier_asian() 53 { 54 if (hModule) osl_unloadModule(hModule); 55 } 56 57 OUString SAL_CALL 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 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 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 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