1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_i18npool.hxx" 30 31 #include <rtl/ustrbuf.hxx> 32 #include <indexentrysupplier_asian.hxx> 33 #include <data/indexdata_alphanumeric.h> 34 35 using namespace ::com::sun::star::uno; 36 using namespace ::com::sun::star::lang; 37 using namespace ::rtl; 38 39 namespace com { namespace sun { namespace star { namespace i18n { 40 41 extern "C" { static void SAL_CALL thisModule() {} } 42 43 IndexEntrySupplier_asian::IndexEntrySupplier_asian( 44 const Reference < XMultiServiceFactory >& rxMSF ) : IndexEntrySupplier_Common(rxMSF) 45 { 46 implementationName = "com.sun.star.i18n.IndexEntrySupplier_asian"; 47 #ifdef SAL_DLLPREFIX 48 OUString lib=OUString::createFromAscii(SAL_DLLPREFIX"index_data"SAL_DLLEXTENSION); 49 #else 50 OUString lib=OUString::createFromAscii("index_data"SAL_DLLEXTENSION); 51 #endif 52 hModule = osl_loadModuleRelative( 53 &thisModule, lib.pData, SAL_LOADMODULE_DEFAULT ); 54 } 55 56 IndexEntrySupplier_asian::~IndexEntrySupplier_asian() 57 { 58 if (hModule) osl_unloadModule(hModule); 59 } 60 61 OUString SAL_CALL 62 IndexEntrySupplier_asian::getIndexCharacter( const OUString& rIndexEntry, 63 const Locale& rLocale, const OUString& rAlgorithm ) throw (RuntimeException) 64 { 65 sal_Int32 i=0; 66 sal_uInt32 ch = rIndexEntry.iterateCodePoints(&i, 0); 67 if (hModule) { 68 OUString get=OUString::createFromAscii("get_indexdata_"); 69 sal_uInt16** (*func)(sal_Int16*)=NULL; 70 if (rLocale.Language.equalsAscii("zh") && OUString::createFromAscii("TW HK MO").indexOf(rLocale.Country) >= 0) 71 func=(sal_uInt16** (*)(sal_Int16*))osl_getFunctionSymbol(hModule, (get+rLocale.Language+OUString::createFromAscii("_TW_")+rAlgorithm).pData); 72 if (!func) 73 func=(sal_uInt16** (*)(sal_Int16*))osl_getFunctionSymbol(hModule, (get+rLocale.Language+OUString('_')+rAlgorithm).pData); 74 if (func) { 75 sal_Int16 max_index; 76 sal_uInt16** idx=func(&max_index); 77 if (((sal_Int16)(ch >> 8)) <= max_index) { 78 sal_uInt16 address=idx[0][ch >> 8]; 79 if (address != 0xFFFF) { 80 address=idx[1][address+(ch & 0xFF)]; 81 return idx[2] ? OUString(&idx[2][address]) : OUString(address); 82 } 83 } 84 } 85 } 86 // using alphanumeric index for non-define stirng 87 return OUString(&idxStr[(ch & 0xFFFFFF00) ? 0 : ch], 1); 88 } 89 90 OUString SAL_CALL 91 IndexEntrySupplier_asian::getIndexKey( const OUString& rIndexEntry, 92 const OUString& rPhoneticEntry, const Locale& rLocale) throw (RuntimeException) 93 { 94 return getIndexCharacter(getEntry(rIndexEntry, rPhoneticEntry, rLocale), rLocale, aAlgorithm); 95 } 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 throw (RuntimeException) 102 { 103 sal_Int32 result = collator->compareString(getEntry(rIndexEntry1, rPhoneticEntry1, rLocale1), 104 getEntry(rIndexEntry2, rPhoneticEntry2, rLocale2)); 105 106 // equivalent of phonetic entries does not mean equivalent of index entries. 107 // we have to continue comparing index entry here. 108 if (result == 0 && usePhonetic && rPhoneticEntry1.getLength() > 0 && 109 rLocale1.Language == rLocale2.Language && rLocale1.Country == rLocale2.Country && 110 rLocale1.Variant == rLocale2.Variant) 111 result = collator->compareString(rIndexEntry1, rIndexEntry2); 112 return sal::static_int_cast< sal_Int16 >(result); // result in { -1, 0, 1 } 113 } 114 115 OUString SAL_CALL 116 IndexEntrySupplier_asian::getPhoneticCandidate( const OUString& rIndexEntry, 117 const Locale& rLocale ) throw (RuntimeException) 118 { 119 if (hModule) { 120 sal_uInt16 **(*func)(sal_Int16*)=NULL; 121 const sal_Char *func_name=NULL; 122 if (rLocale.Language.equalsAscii("zh")) 123 func_name=(OUString::createFromAscii("TW HK MO").indexOf(rLocale.Country) >= 0) ? "get_zh_zhuyin" : "get_zh_pinyin"; 124 else if (rLocale.Language.equalsAscii("ko")) 125 func_name="get_ko_phonetic"; 126 if (func_name) 127 func=(sal_uInt16 **(*)(sal_Int16*))osl_getFunctionSymbol(hModule, OUString::createFromAscii(func_name).pData); 128 if (func) { 129 OUStringBuffer candidate; 130 sal_Int16 max_index; 131 sal_uInt16** idx=func(&max_index); 132 OUString aIndexEntry=rIndexEntry; 133 for (sal_Int32 i=0,j=0; i < rIndexEntry.getLength(); i=j) { 134 sal_uInt32 ch = rIndexEntry.iterateCodePoints(&j, 1); 135 if (((sal_Int16)(ch>>8)) <= max_index) { 136 sal_uInt16 address = idx[0][ch>>8]; 137 if (address != 0xFFFF) { 138 address = idx[1][address + (ch & 0xFF)]; 139 if (i > 0 && rLocale.Language.equalsAscii("zh")) 140 candidate.appendAscii(" "); 141 if (idx[2]) 142 candidate.append(&idx[2][address]); 143 else 144 candidate.append(address); 145 } else 146 candidate.appendAscii(" "); 147 } 148 } 149 return candidate.makeStringAndClear(); 150 } 151 } 152 return OUString(); 153 } 154 } } } } 155