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