1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 #include <com/sun/star/i18n/TransliterationType.hpp> 21 22 #include <transliteration_Ignore.hxx> 23 #include <i18nutil/oneToOneMapping.hxx> 24 25 using namespace com::sun::star::i18n; 26 using namespace com::sun::star::uno; 27 28 namespace i18npool { 29 30 sal_Bool SAL_CALL 31 transliteration_Ignore::equals(const OUString& str1, sal_Int32 pos1, sal_Int32 nCount1, sal_Int32& nMatch1, 32 const OUString& str2, sal_Int32 pos2, sal_Int32 nCount2, sal_Int32& nMatch2 ) 33 { 34 Sequence< sal_Int32 > offset1; 35 Sequence< sal_Int32 > offset2; 36 37 // The method folding is defined in a sub class. 38 OUString s1 = folding( str1, pos1, nCount1, offset1); 39 OUString s2 = folding( str2, pos2, nCount2, offset2); 40 41 const sal_Unicode * p1 = s1.getStr(); 42 const sal_Unicode * p2 = s2.getStr(); 43 sal_Int32 length = std::min(s1.getLength(), s2.getLength()); 44 sal_Int32 nmatch; 45 46 for ( nmatch = 0; nmatch < length; nmatch++) 47 if (*p1++ != *p2++) 48 break; 49 50 if (nmatch > 0) { 51 nMatch1 = offset1[ nmatch - 1 ] + 1; // Subtract 1 from nmatch because the index starts from zero. 52 nMatch2 = offset2[ nmatch - 1 ] + 1; // And then, add 1 to position because it means the number of character matched. 53 } 54 else { 55 nMatch1 = 0; // No character was matched. 56 nMatch2 = 0; 57 } 58 59 return (nmatch == s1.getLength()) && (nmatch == s2.getLength()); 60 } 61 62 63 Sequence< OUString > SAL_CALL 64 transliteration_Ignore::transliterateRange( const OUString& str1, const OUString& str2 ) 65 { 66 if (str1.isEmpty() || str2.isEmpty()) 67 throw RuntimeException(); 68 69 Sequence< OUString > r(2); 70 r[0] = str1.copy(0, 1); 71 r[1] = str2.copy(0, 1); 72 return r; 73 } 74 75 76 sal_Int16 SAL_CALL 77 transliteration_Ignore::getType() 78 { 79 // The type is also defined in com/sun/star/util/TransliterationType.hdl 80 return TransliterationType::IGNORE; 81 } 82 83 84 OUString 85 transliteration_Ignore::transliterateImpl( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount, 86 Sequence< sal_Int32 >& offset, bool useOffset) 87 { 88 // The method folding is defined in a sub class. 89 return foldingImpl( inStr, startPos, nCount, offset, useOffset); 90 } 91 92 Sequence< OUString > 93 transliteration_Ignore::transliterateRange( const OUString& str1, const OUString& str2, 94 XTransliteration& t1, XTransliteration& t2 ) 95 { 96 if (str1.isEmpty() || str2.isEmpty()) 97 throw RuntimeException(); 98 99 Sequence< sal_Int32 > offset; 100 OUString s11 = t1.transliterate( str1, 0, 1, offset ); 101 OUString s12 = t1.transliterate( str2, 0, 1, offset ); 102 OUString s21 = t2.transliterate( str1, 0, 1, offset ); 103 OUString s22 = t2.transliterate( str2, 0, 1, offset ); 104 105 if ( (s11 == s21) && (s12 == s22) ) { 106 Sequence< OUString > r(2); 107 r[0] = s11; 108 r[1] = s12; 109 return r; 110 } 111 112 Sequence< OUString > r(4); 113 r[0] = s11; 114 r[1] = s12; 115 r[2] = s21; 116 r[3] = s22; 117 return r; 118 } 119 120 OUString 121 transliteration_Ignore::foldingImpl( const OUString& inStr, sal_Int32 startPos, 122 sal_Int32 nCount, Sequence< sal_Int32 >& offset, bool useOffset) 123 { 124 // Create a string buffer which can hold nCount + 1 characters. 125 // The reference count is 1 now. 126 rtl_uString * newStr = rtl_uString_alloc(nCount); 127 sal_Unicode * dst = newStr->buffer; 128 const sal_Unicode * src = inStr.getStr() + startPos; 129 130 // Allocate nCount length to offset argument. 131 sal_Int32 *p = nullptr; 132 sal_Int32 position = 0; 133 if (useOffset) { 134 offset.realloc( nCount ); 135 p = offset.getArray(); 136 position = startPos; 137 } 138 139 if (map) { 140 sal_Unicode previousChar = *src ++; 141 sal_Unicode currentChar; 142 143 // Translation 144 while (-- nCount > 0) { 145 currentChar = *src ++; 146 147 const Mapping *m; 148 for (m = map; m->replaceChar; m++) { 149 if (previousChar == m->previousChar && currentChar == m->currentChar ) { 150 if (useOffset) { 151 if (! m->two2one) 152 *p++ = position; 153 position++; 154 *p++ = position++; 155 } 156 *dst++ = m->replaceChar; 157 if (!m->two2one) 158 *dst++ = currentChar; 159 previousChar = *src++; 160 nCount--; 161 break; 162 } 163 } 164 165 if (! m->replaceChar) { 166 if (useOffset) 167 *p ++ = position ++; 168 *dst ++ = previousChar; 169 previousChar = currentChar; 170 } 171 } 172 173 if (nCount == 0) { 174 if (useOffset) 175 *p = position; 176 *dst ++ = previousChar; 177 } 178 } else { 179 // Translation 180 while (nCount -- > 0) { 181 sal_Unicode c = *src++; 182 c = func ? func( c) : (*table)[ c ]; 183 if (c != 0xffff) 184 *dst ++ = c; 185 if (useOffset) { 186 if (c != 0xffff) 187 *p ++ = position; 188 position++; 189 } 190 } 191 } 192 newStr->length = sal_Int32(dst - newStr->buffer); 193 if (useOffset) 194 offset.realloc(newStr->length); 195 *dst = u'\0'; 196 197 return OUString(newStr, SAL_NO_ACQUIRE); // take ownership 198 } 199 200 sal_Unicode SAL_CALL 201 transliteration_Ignore::transliterateChar2Char( sal_Unicode inChar) 202 { 203 return func ? func( inChar) : table ? (*table)[ inChar ] : inChar; 204 } 205 206 } 207 208 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 209
