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 // generated list of languages 32 #include "lrl_include.hxx" 33 34 #include <rtl/ustrbuf.hxx> 35 #include <collator_unicode.hxx> 36 #include <localedata.hxx> 37 #include <com/sun/star/i18n/CollatorOptions.hpp> 38 39 using namespace ::com::sun::star; 40 using namespace ::com::sun::star::lang; 41 using namespace ::com::sun::star::uno; 42 using namespace ::rtl; 43 44 namespace com { namespace sun { namespace star { namespace i18n { 45 46 Collator_Unicode::Collator_Unicode() 47 { 48 implementationName = "com.sun.star.i18n.Collator_Unicode"; 49 collator = NULL; 50 uca_base = NULL; 51 hModule = NULL; 52 } 53 54 Collator_Unicode::~Collator_Unicode() 55 { 56 if (collator) delete collator; 57 if (uca_base) delete uca_base; 58 if (hModule) osl_unloadModule(hModule); 59 } 60 61 sal_Int32 SAL_CALL 62 Collator_Unicode::compareSubstring( const OUString& str1, sal_Int32 off1, sal_Int32 len1, 63 const OUString& str2, sal_Int32 off2, sal_Int32 len2) throw(RuntimeException) 64 { 65 return collator->compare(reinterpret_cast<const UChar *>(str1.getStr()) + off1, len1, reinterpret_cast<const UChar *>(str2.getStr()) + off2, len2); // UChar != sal_Unicode in MinGW 66 } 67 68 sal_Int32 SAL_CALL 69 Collator_Unicode::compareString( const OUString& str1, const OUString& str2) throw(RuntimeException) 70 { 71 return collator->compare(reinterpret_cast<const UChar *>(str1.getStr()), reinterpret_cast<const UChar *>(str2.getStr())); // UChar != sal_Unicode in MinGW 72 } 73 74 extern "C" { static void SAL_CALL thisModule() {} } 75 76 sal_Int32 SAL_CALL 77 Collator_Unicode::loadCollatorAlgorithm(const OUString& rAlgorithm, const lang::Locale& rLocale, sal_Int32 options) 78 throw(RuntimeException) 79 { 80 if (!collator) { 81 UErrorCode status = U_ZERO_ERROR; 82 OUString rule = LocaleData().getCollatorRuleByAlgorithm(rLocale, rAlgorithm); 83 if (rule.getLength() > 0) { 84 collator = new RuleBasedCollator(reinterpret_cast<const UChar *>(rule.getStr()), status); // UChar != sal_Unicode in MinGW 85 if (! U_SUCCESS(status)) throw RuntimeException(); 86 } 87 if (!collator && OUString::createFromAscii(LOCAL_RULE_LANGS).indexOf(rLocale.Language) >= 0) { 88 OUStringBuffer aBuf; 89 #ifdef SAL_DLLPREFIX 90 aBuf.appendAscii(SAL_DLLPREFIX); 91 #endif 92 aBuf.appendAscii( "collator_data" ).appendAscii( SAL_DLLEXTENSION ); 93 hModule = osl_loadModuleRelative( &thisModule, aBuf.makeStringAndClear().pData, SAL_LOADMODULE_DEFAULT ); 94 if (hModule) { 95 const sal_uInt8* (*func)() = NULL; 96 aBuf.appendAscii("get_").append(rLocale.Language).appendAscii("_"); 97 if (rLocale.Language.equalsAscii("zh")) { 98 OUString func_base = aBuf.makeStringAndClear(); 99 if (OUString::createFromAscii("TW HK MO").indexOf(rLocale.Country) >= 0) 100 func=(const sal_uInt8* (*)()) osl_getFunctionSymbol(hModule, 101 (func_base + OUString::createFromAscii("TW_") + rAlgorithm).pData); 102 if (!func) 103 func=(const sal_uInt8* (*)()) osl_getFunctionSymbol(hModule, (func_base + rAlgorithm).pData); 104 } else { 105 if (rLocale.Language.equalsAscii("ja")) { 106 // replace algrithm name to implementation name. 107 if (rAlgorithm.equalsAscii("phonetic (alphanumeric first)") ) 108 aBuf.appendAscii("phonetic_alphanumeric_first"); 109 else if (rAlgorithm.equalsAscii("phonetic (alphanumeric last)")) 110 aBuf.appendAscii("phonetic_alphanumeric_last"); 111 else 112 aBuf.append(rAlgorithm); 113 } else { 114 aBuf.append(rAlgorithm); 115 } 116 func=(const sal_uInt8* (*)()) osl_getFunctionSymbol(hModule, aBuf.makeStringAndClear().pData); 117 } 118 if (func) { 119 const sal_uInt8* ruleImage=func(); 120 uca_base = new RuleBasedCollator(static_cast<UChar*>(NULL), status); 121 if (! U_SUCCESS(status)) throw RuntimeException(); 122 collator = new RuleBasedCollator(reinterpret_cast<const uint8_t*>(ruleImage), -1, uca_base, status); 123 if (! U_SUCCESS(status)) throw RuntimeException(); 124 } 125 } 126 } 127 if (!collator) { 128 /** ICU collators are loaded using a locale only. 129 ICU uses Variant as collation algorithm name (like de__PHONEBOOK 130 locale), note the empty territory (Country) designator in this special 131 case here. The icu::Locale contructor changes the algorithm name to 132 uppercase itself, so we don't have to bother with that. 133 */ 134 icu::Locale icuLocale( 135 OUStringToOString(rLocale.Language, RTL_TEXTENCODING_ASCII_US).getStr(), 136 OUStringToOString(rLocale.Country, RTL_TEXTENCODING_ASCII_US).getStr(), 137 OUStringToOString(rAlgorithm, RTL_TEXTENCODING_ASCII_US).getStr()); 138 // load ICU collator 139 collator = (RuleBasedCollator*) icu::Collator::createInstance(icuLocale, status); 140 if (! U_SUCCESS(status)) throw RuntimeException(); 141 } 142 } 143 144 if (options & CollatorOptions::CollatorOptions_IGNORE_CASE_ACCENT) 145 collator->setStrength(Collator::PRIMARY); 146 else if (options & CollatorOptions::CollatorOptions_IGNORE_CASE) 147 collator->setStrength(Collator::SECONDARY); 148 else 149 collator->setStrength(Collator::TERTIARY); 150 151 return(0); 152 } 153 154 155 OUString SAL_CALL 156 Collator_Unicode::getImplementationName() throw( RuntimeException ) 157 { 158 return OUString::createFromAscii(implementationName); 159 } 160 161 sal_Bool SAL_CALL 162 Collator_Unicode::supportsService(const rtl::OUString& rServiceName) throw( RuntimeException ) 163 { 164 return !rServiceName.compareToAscii(implementationName); 165 } 166 167 Sequence< OUString > SAL_CALL 168 Collator_Unicode::getSupportedServiceNames() throw( RuntimeException ) 169 { 170 Sequence< OUString > aRet(1); 171 aRet[0] = OUString::createFromAscii(implementationName); 172 return aRet; 173 } 174 175 } } } } 176 177