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 // prevent internal compiler error with MSVC6SP3 28 #include <utility> 29 30 #include <chaptercollator.hxx> 31 #include <com/sun/star/i18n/KCharacterType.hpp> 32 #include <com/sun/star/i18n/ParseResult.hpp> 33 34 using namespace ::com::sun::star::lang; 35 using namespace ::com::sun::star::uno; 36 using namespace ::com::sun::star::i18n; 37 using namespace ::rtl; 38 39 ChapterCollator::ChapterCollator( const Reference < XMultiServiceFactory >& rxMSF ) : CollatorImpl(rxMSF) 40 { 41 if ( rxMSF.is()) { 42 Reference < XInterface > xI = 43 rxMSF->createInstance( OUString::createFromAscii("com.sun.star.i18n.CharacterClassification")); 44 if ( xI.is() ) 45 xI->queryInterface(::getCppuType((const Reference< XCharacterClassification>*)0)) >>= cclass; 46 } 47 } 48 49 ChapterCollator::~ChapterCollator() 50 { 51 } 52 53 sal_Int32 SAL_CALL 54 ChapterCollator::compareString( const OUString& s1, const OUString& s2) throw(RuntimeException) 55 { 56 return compareSubstring(s1, 0, s1.getLength(), s2, 0, s2.getLength()); 57 } 58 59 #define DIGIT KCharacterType::DIGIT 60 61 sal_Int32 SAL_CALL 62 ChapterCollator::compareSubstring( const OUString& str1, sal_Int32 off1, sal_Int32 len1, 63 const OUString& str2, sal_Int32 off2, sal_Int32 len2) throw(RuntimeException) 64 { 65 if( len1 <= 1 || len2 <= 1 || ! cclass.is() ) 66 return CollatorImpl::compareSubstring( str1, off1, len1, str2, off2, len2 ); 67 68 sal_Int32 i1, i2; 69 for (i1 = len1; i1 && (cclass->getCharacterType(str1, off1+i1-1, nLocale) & DIGIT); i1--) ; 70 for (i2 = len2; i2 && (cclass->getCharacterType(str2, off2+i2-1, nLocale) & DIGIT); i2--) ; 71 72 sal_Int32 ans = CollatorImpl::compareSubstring(str1, off1, i1, str2, off2, i2); 73 if( ans != 0 ) 74 return ans; 75 76 const OUString &aAddAllowed = OUString::createFromAscii("?"); 77 ParseResult res1, res2; 78 // Bug #100323#, since parseAnyToken does not take length as parameter, we have to copy 79 // it to a temp. string. 80 OUString s1 = str1.copy(off1+i1, len1-i1), s2 = str2.copy(off2+i2, len2-i2); 81 res1 = cclass->parseAnyToken( s1, 0, nLocale, DIGIT, aAddAllowed, DIGIT, aAddAllowed ); 82 res2 = cclass->parseAnyToken( s2, 0, nLocale, DIGIT, aAddAllowed, DIGIT, aAddAllowed ); 83 84 return res1.Value == res2.Value ? 0 : res1.Value > res2.Value ? 1 : -1; 85 } 86 87 const sal_Char *cChapCollator = "com.sun.star.i18n.ChapterCollator"; 88 89 OUString SAL_CALL 90 ChapterCollator::getImplementationName() throw( RuntimeException ) 91 { 92 return OUString::createFromAscii(cChapCollator); 93 } 94 95 sal_Bool SAL_CALL 96 ChapterCollator::supportsService(const rtl::OUString& rServiceName) throw( RuntimeException ) 97 { 98 return !rServiceName.compareToAscii(cChapCollator); 99 } 100 101 Sequence< OUString > SAL_CALL 102 ChapterCollator::getSupportedServiceNames() throw( RuntimeException ) 103 { 104 Sequence< OUString > aRet(1); 105 aRet[0] = OUString::createFromAscii(cChapCollator); 106 return aRet; 107 } 108