File: | home/maarten/src/libreoffice/core/i18npool/source/nativenumber/nativenumbersupplier.cxx |
Warning: | line 913, column 24 Assigned value is garbage or undefined |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 <i18nlangtag/languagetag.hxx> | |||
21 | #include <i18nlangtag/mslangid.hxx> | |||
22 | #include <rtl/ustrbuf.hxx> | |||
23 | #include <sal/macros.h> | |||
24 | #include <nativenumbersupplier.hxx> | |||
25 | #include <localedata.hxx> | |||
26 | #include "data/numberchar.h" | |||
27 | #include <comphelper/processfactory.hxx> | |||
28 | #include <cppuhelper/supportsservice.hxx> | |||
29 | #include <map> | |||
30 | #include <memory> | |||
31 | #include <string_view> | |||
32 | #include <unordered_map> | |||
33 | #include <com/sun/star/i18n/CharacterClassification.hpp> | |||
34 | #include <com/sun/star/i18n/NativeNumberMode.hpp> | |||
35 | #include <com/sun/star/linguistic2/NumberText.hpp> | |||
36 | ||||
37 | using namespace ::com::sun::star::uno; | |||
38 | using namespace ::com::sun::star::i18n; | |||
39 | using namespace ::com::sun::star::lang; | |||
40 | ||||
41 | namespace { | |||
42 | ||||
43 | struct Number { | |||
44 | sal_Int16 number; | |||
45 | const sal_Unicode *multiplierChar; | |||
46 | sal_Int16 numberFlag; | |||
47 | sal_Int16 exponentCount; | |||
48 | const sal_Int16 *multiplierExponent; | |||
49 | }; | |||
50 | ||||
51 | } | |||
52 | ||||
53 | #define NUMBER_OMIT_ZERO(1 << 0) (1 << 0) | |||
54 | #define NUMBER_OMIT_ONLY_ZERO(1 << 1) (1 << 1) | |||
55 | #define NUMBER_OMIT_ONE_1(1 << 2) (1 << 2) | |||
56 | #define NUMBER_OMIT_ONE_2(1 << 3) (1 << 3) | |||
57 | #define NUMBER_OMIT_ONE_3(1 << 4) (1 << 4) | |||
58 | #define NUMBER_OMIT_ONE_4(1 << 5) (1 << 5) | |||
59 | #define NUMBER_OMIT_ONE_5(1 << 6) (1 << 6) | |||
60 | #define NUMBER_OMIT_ONE_6(1 << 7) (1 << 7) | |||
61 | #define NUMBER_OMIT_ONE_7(1 << 8) (1 << 8) | |||
62 | #define NUMBER_OMIT_ONE((1 << 2)|(1 << 3)|(1 << 4)|(1 << 5)| (1 << 6)|(1 << 7)|(1 << 8)) (NUMBER_OMIT_ONE_1(1 << 2)|NUMBER_OMIT_ONE_2(1 << 3)|NUMBER_OMIT_ONE_3(1 << 4)|NUMBER_OMIT_ONE_4(1 << 5)|NUMBER_OMIT_ONE_5(1 << 6)|NUMBER_OMIT_ONE_6(1 << 7)|NUMBER_OMIT_ONE_7(1 << 8)) | |||
63 | #define NUMBER_OMIT_ONE_CHECK(bit)(1 << (2 + bit)) (1 << (2 + bit)) | |||
64 | #define NUMBER_OMIT_ALL( (1 << 0)|((1 << 2)|(1 << 3)|(1 << 4 )|(1 << 5)|(1 << 6)|(1 << 7)|(1 << 8) )|(1 << 1) ) ( NUMBER_OMIT_ZERO(1 << 0)|NUMBER_OMIT_ONE((1 << 2)|(1 << 3)|(1 << 4)|(1 << 5)| (1 << 6)|(1 << 7)|(1 << 8))|NUMBER_OMIT_ONLY_ZERO(1 << 1) ) | |||
65 | #define NUMBER_OMIT_ZERO_ONE( (1 << 0)|((1 << 2)|(1 << 3)|(1 << 4 )|(1 << 5)|(1 << 6)|(1 << 7)|(1 << 8) ) ) ( NUMBER_OMIT_ZERO(1 << 0)|NUMBER_OMIT_ONE((1 << 2)|(1 << 3)|(1 << 4)|(1 << 5)| (1 << 6)|(1 << 7)|(1 << 8)) ) | |||
66 | #define NUMBER_OMIT_ONE_67((1 << 7)|(1 << 8)) (NUMBER_OMIT_ONE_6(1 << 7)|NUMBER_OMIT_ONE_7(1 << 8)) | |||
67 | #define NUMBER_OMIT_ZERO_ONE_67( (1 << 0)|((1 << 7)|(1 << 8)) ) ( NUMBER_OMIT_ZERO(1 << 0)|NUMBER_OMIT_ONE_67((1 << 7)|(1 << 8)) ) | |||
68 | ||||
69 | namespace i18npool { | |||
70 | ||||
71 | namespace { | |||
72 | ||||
73 | struct theNatNumMutex : public rtl::Static<osl::Mutex, theNatNumMutex> {}; | |||
74 | ||||
75 | } | |||
76 | ||||
77 | static OUString getHebrewNativeNumberString(const OUString& aNumberString, bool useGeresh); | |||
78 | ||||
79 | static OUString getCyrillicNativeNumberString(const OUString& aNumberString); | |||
80 | ||||
81 | /// @throws RuntimeException | |||
82 | static OUString AsciiToNativeChar( const OUString& inStr, sal_Int32 nCount, | |||
83 | Sequence< sal_Int32 >& offset, bool useOffset, sal_Int16 number ) | |||
84 | { | |||
85 | const sal_Unicode *src = inStr.getStr(); | |||
86 | rtl_uString *newStr = rtl_uString_alloc(nCount); | |||
87 | if (useOffset) | |||
88 | offset.realloc(nCount); | |||
89 | ||||
90 | for (sal_Int32 i = 0; i < nCount; i++) | |||
91 | { | |||
92 | sal_Unicode ch = src[i]; | |||
93 | if (isNumber(ch)( NumberChar[NumberChar_HalfWidth][0] <= ch && ch <= NumberChar[NumberChar_HalfWidth][9] )) | |||
94 | newStr->buffer[i] = NumberChar[number][ ch - NUMBER_ZERONumberChar[NumberChar_HalfWidth][0] ]; | |||
95 | else if (i+1 < nCount && isNumber(src[i+1])( NumberChar[NumberChar_HalfWidth][0] <= src[i+1] && src[i+1] <= NumberChar[NumberChar_HalfWidth][9] )) { | |||
96 | if (i > 0 && isNumber(src[i-1])( NumberChar[NumberChar_HalfWidth][0] <= src[i-1] && src[i-1] <= NumberChar[NumberChar_HalfWidth][9] ) && isSeparator(ch)( ch == SeparatorChar[NumberChar_HalfWidth] )) | |||
97 | newStr->buffer[i] = SeparatorChar[number] ? SeparatorChar[number] : ch; | |||
98 | else | |||
99 | newStr->buffer[i] = isDecimal(ch)( ch == DecimalChar[NumberChar_HalfWidth] ) ? (DecimalChar[number] ? DecimalChar[number] : ch) : | |||
100 | isMinus(ch)( ch == MinusChar[NumberChar_HalfWidth] ) ? (MinusChar[number] ? MinusChar[number] : ch) : ch; | |||
101 | } | |||
102 | else | |||
103 | newStr->buffer[i] = ch; | |||
104 | if (useOffset) | |||
105 | offset[i] = i; | |||
106 | } | |||
107 | return OUString(newStr, SAL_NO_ACQUIRE); // take ownership | |||
108 | } | |||
109 | ||||
110 | static bool AsciiToNative_numberMaker(const sal_Unicode *str, sal_Int32 begin, sal_Int32 len, | |||
111 | sal_Unicode *dst, sal_Int32& count, sal_Int16 multiChar_index, Sequence< sal_Int32 >& offset, bool useOffset, sal_Int32 startPos, | |||
112 | const Number *number, const sal_Unicode* numberChar) | |||
113 | { | |||
114 | sal_Unicode multiChar = (multiChar_index == -1 ? 0 : number->multiplierChar[multiChar_index]); | |||
115 | if ( len <= number->multiplierExponent[number->exponentCount-1] ) { | |||
116 | if (number->multiplierExponent[number->exponentCount-1] > 1) { | |||
117 | bool bNotZero = false; | |||
118 | for (const sal_Int32 end = begin+len; begin < end; begin++) { | |||
119 | if (bNotZero || str[begin] != NUMBER_ZERONumberChar[NumberChar_HalfWidth][0]) { | |||
120 | dst[count] = numberChar[str[begin] - NUMBER_ZERONumberChar[NumberChar_HalfWidth][0]]; | |||
121 | if (useOffset) | |||
122 | offset[count] = begin + startPos; | |||
123 | count++; | |||
124 | bNotZero = true; | |||
125 | } | |||
126 | } | |||
127 | if (bNotZero && multiChar > 0) { | |||
128 | dst[count] = multiChar; | |||
129 | if (useOffset) | |||
130 | offset[count] = begin + startPos; | |||
131 | count++; | |||
132 | } | |||
133 | return bNotZero; | |||
134 | } else if (str[begin] != NUMBER_ZERONumberChar[NumberChar_HalfWidth][0]) { | |||
135 | if (!(number->numberFlag & (multiChar_index < 0 ? 0 : NUMBER_OMIT_ONE_CHECK(multiChar_index)(1 << (2 + multiChar_index)))) || str[begin] != NUMBER_ONENumberChar[NumberChar_HalfWidth][1]) { | |||
136 | dst[count] = numberChar[str[begin] - NUMBER_ZERONumberChar[NumberChar_HalfWidth][0]]; | |||
137 | if (useOffset) | |||
138 | offset[count] = begin + startPos; | |||
139 | count++; | |||
140 | } | |||
141 | if (multiChar > 0) { | |||
142 | dst[count] = multiChar; | |||
143 | if (useOffset) | |||
144 | offset[count] = begin + startPos; | |||
145 | count++; | |||
146 | } | |||
147 | } else if (!(number->numberFlag & NUMBER_OMIT_ZERO(1 << 0)) && count > 0 && dst[count-1] != numberChar[0]) { | |||
148 | dst[count] = numberChar[0]; | |||
149 | if (useOffset) | |||
150 | offset[count] = begin + startPos; | |||
151 | count++; | |||
152 | } | |||
153 | return str[begin] != NUMBER_ZERONumberChar[NumberChar_HalfWidth][0]; | |||
154 | } else { | |||
155 | bool bPrintPower = false; | |||
156 | // sal_Int16 last = 0; | |||
157 | for (sal_Int16 i = 1; i <= number->exponentCount; i++) { | |||
158 | sal_Int32 tmp = len - (i == number->exponentCount ? 0 : number->multiplierExponent[i]); | |||
159 | if (tmp > 0) { | |||
160 | bPrintPower |= AsciiToNative_numberMaker(str, begin, tmp, dst, count, | |||
161 | (i == number->exponentCount ? -1 : i), offset, useOffset, startPos, number, numberChar); | |||
162 | begin += tmp; | |||
163 | len -= tmp; | |||
164 | } | |||
165 | } | |||
166 | if (bPrintPower) { | |||
167 | if (count > 0 && number->multiplierExponent[number->exponentCount-1] == 1 && | |||
168 | dst[count-1] == numberChar[0]) | |||
169 | count--; | |||
170 | if (multiChar > 0) { | |||
171 | dst[count] = multiChar; | |||
172 | if (useOffset) | |||
173 | offset[count] = begin + startPos; | |||
174 | count++; | |||
175 | } | |||
176 | } | |||
177 | return bPrintPower; | |||
178 | } | |||
179 | } | |||
180 | ||||
181 | /// @throws RuntimeException | |||
182 | static OUString AsciiToNative( const OUString& inStr, sal_Int32 nCount, | |||
183 | Sequence< sal_Int32 >& offset, bool useOffset, const Number* number ) | |||
184 | { | |||
185 | OUString aRet; | |||
186 | ||||
187 | sal_Int32 strLen = inStr.getLength(); | |||
188 | const sal_Unicode *numberChar = NumberChar[number->number]; | |||
189 | ||||
190 | if (nCount > strLen) | |||
191 | nCount = strLen; | |||
192 | ||||
193 | if (nCount > 0) | |||
194 | { | |||
195 | const sal_Unicode *str = inStr.getStr(); | |||
196 | std::unique_ptr<sal_Unicode[]> newStr(new sal_Unicode[nCount * 2 + 1]); | |||
197 | std::unique_ptr<sal_Unicode[]> srcStr(new sal_Unicode[nCount + 1]); // for keeping number without comma | |||
198 | sal_Int32 i, len = 0, count = 0; | |||
199 | ||||
200 | if (useOffset) | |||
201 | offset.realloc( nCount * 2 ); | |||
202 | bool bDoDecimal = false; | |||
203 | ||||
204 | for (i = 0; i <= nCount; i++) | |||
205 | { | |||
206 | if (i < nCount && isNumber(str[i])( NumberChar[NumberChar_HalfWidth][0] <= str[i] && str[i] <= NumberChar[NumberChar_HalfWidth][9] )) { | |||
207 | if (bDoDecimal) { | |||
208 | newStr[count] = numberChar[str[i] - NUMBER_ZERONumberChar[NumberChar_HalfWidth][0]]; | |||
209 | if (useOffset) | |||
210 | offset[count] = i; | |||
211 | count++; | |||
212 | } | |||
213 | else | |||
214 | srcStr[len++] = str[i]; | |||
215 | } else { | |||
216 | if (len > 0) { | |||
217 | if (i < nCount-1 && isSeparator(str[i])( str[i] == SeparatorChar[NumberChar_HalfWidth] ) && isNumber(str[i+1])( NumberChar[NumberChar_HalfWidth][0] <= str[i+1] && str[i+1] <= NumberChar[NumberChar_HalfWidth][9] )) | |||
218 | continue; // skip comma inside number string | |||
219 | bool bNotZero = false; | |||
220 | for (sal_Int32 begin = 0, end = len % number->multiplierExponent[0]; | |||
221 | end <= len; begin = end, end += number->multiplierExponent[0]) { | |||
222 | if (end == 0) continue; | |||
223 | sal_Int32 _count = count; | |||
224 | bNotZero |= AsciiToNative_numberMaker(srcStr.get(), begin, end - begin, newStr.get(), count, | |||
225 | end == len ? -1 : 0, offset, useOffset, i - len, number, numberChar); | |||
226 | if (count > 0 && number->multiplierExponent[number->exponentCount-1] == 1 && | |||
227 | newStr[count-1] == numberChar[0]) | |||
228 | count--; | |||
229 | if (bNotZero && _count == count && end != len) { | |||
230 | newStr[count] = number->multiplierChar[0]; | |||
231 | if (useOffset) | |||
232 | offset[count] = i - len; | |||
233 | count++; | |||
234 | } | |||
235 | } | |||
236 | if (! bNotZero && ! (number->numberFlag & NUMBER_OMIT_ONLY_ZERO(1 << 1))) { | |||
237 | newStr[count] = numberChar[0]; | |||
238 | if (useOffset) | |||
239 | offset[count] = i - len; | |||
240 | count++; | |||
241 | } | |||
242 | len = 0; | |||
243 | } | |||
244 | if (i < nCount) { | |||
245 | bDoDecimal = (!bDoDecimal && i < nCount-1 && isDecimal(str[i])( str[i] == DecimalChar[NumberChar_HalfWidth] ) && isNumber(str[i+1])( NumberChar[NumberChar_HalfWidth][0] <= str[i+1] && str[i+1] <= NumberChar[NumberChar_HalfWidth][9] )); | |||
246 | if (bDoDecimal) | |||
247 | newStr[count] = (DecimalChar[number->number] ? DecimalChar[number->number] : str[i]); | |||
248 | else if (i < nCount-1 && isMinus(str[i])( str[i] == MinusChar[NumberChar_HalfWidth] ) && isNumber(str[i+1])( NumberChar[NumberChar_HalfWidth][0] <= str[i+1] && str[i+1] <= NumberChar[NumberChar_HalfWidth][9] )) | |||
249 | newStr[count] = (MinusChar[number->number] ? MinusChar[number->number] : str[i]); | |||
250 | else if (i < nCount-1 && isSeparator(str[i])( str[i] == SeparatorChar[NumberChar_HalfWidth] ) && isNumber(str[i+1])( NumberChar[NumberChar_HalfWidth][0] <= str[i+1] && str[i+1] <= NumberChar[NumberChar_HalfWidth][9] )) | |||
251 | newStr[count] = (SeparatorChar[number->number] ? SeparatorChar[number->number] : str[i]); | |||
252 | else | |||
253 | newStr[count] = str[i]; | |||
254 | if (useOffset) | |||
255 | offset[count] = i; | |||
256 | count++; | |||
257 | } | |||
258 | } | |||
259 | } | |||
260 | ||||
261 | if (useOffset) | |||
262 | offset.realloc(count); | |||
263 | aRet = OUString(newStr.get(), count); | |||
264 | } | |||
265 | return aRet; | |||
266 | } | |||
267 | ||||
268 | namespace | |||
269 | { | |||
270 | void NativeToAscii_numberMaker(sal_Int16 max, sal_Int16 prev, const sal_Unicode *str, | |||
271 | sal_Int32& i, sal_Int32 nCount, sal_Unicode *dst, sal_Int32& count, Sequence< sal_Int32 >& offset, bool useOffset, | |||
272 | OUString& numberChar, OUString& multiplierChar) | |||
273 | { | |||
274 | sal_Int16 curr = 0, num = 0, end = 0, shift = 0; | |||
275 | while (++i < nCount) { | |||
276 | if ((curr = sal::static_int_cast<sal_Int16>( numberChar.indexOf(str[i]) )) >= 0) { | |||
277 | if (num > 0) | |||
278 | break; | |||
279 | num = curr % 10; | |||
280 | } else if ((curr = sal::static_int_cast<sal_Int16>( multiplierChar.indexOf(str[i]) )) >= 0) { | |||
281 | curr = MultiplierExponent_7_CJK[curr % ExponentCount_7_CJK]; | |||
282 | if (prev > curr && num == 0) num = 1; // One may be omitted in informal format | |||
283 | shift = end = 0; | |||
284 | if (curr >= max) | |||
285 | max = curr; | |||
286 | else if (curr > prev) | |||
287 | shift = max - curr; | |||
288 | else | |||
289 | end = curr; | |||
290 | while (end++ < prev) { | |||
291 | dst[count] = NUMBER_ZERONumberChar[NumberChar_HalfWidth][0] + (end == prev ? num : 0); | |||
292 | if (useOffset) | |||
293 | offset[count] = i; | |||
294 | count++; | |||
295 | } | |||
296 | if (shift) { | |||
297 | count -= max; | |||
298 | for (const sal_Int32 countEnd = count+shift; count < countEnd; count++) { | |||
299 | dst[count] = dst[count + curr]; | |||
300 | if (useOffset) | |||
301 | offset[count] = offset[count + curr]; | |||
302 | } | |||
303 | max = curr; | |||
304 | } | |||
305 | NativeToAscii_numberMaker(max, curr, str, i, nCount, dst, | |||
306 | count, offset, useOffset, numberChar, multiplierChar); | |||
307 | return; | |||
308 | } else | |||
309 | break; | |||
310 | } | |||
311 | while (end++ < prev) { | |||
312 | dst[count] = NUMBER_ZERONumberChar[NumberChar_HalfWidth][0] + (end == prev ? num : 0); | |||
313 | if (useOffset) | |||
314 | offset[count] = i - 1; | |||
315 | count++; | |||
316 | } | |||
317 | } | |||
318 | ||||
319 | /// @throws RuntimeException | |||
320 | OUString NativeToAscii(const OUString& inStr, | |||
321 | sal_Int32 nCount, Sequence< sal_Int32 >& offset, bool useOffset ) | |||
322 | { | |||
323 | OUString aRet; | |||
324 | ||||
325 | sal_Int32 strLen = inStr.getLength(); | |||
326 | ||||
327 | if (nCount > strLen) | |||
328 | nCount = strLen; | |||
329 | ||||
330 | if (nCount > 0) { | |||
331 | const sal_Unicode *str = inStr.getStr(); | |||
332 | std::unique_ptr<sal_Unicode[]> newStr(new sal_Unicode[nCount * MultiplierExponent_7_CJK[0] + 2]); | |||
333 | if (useOffset) | |||
334 | offset.realloc( nCount * MultiplierExponent_7_CJK[0] + 1 ); | |||
335 | sal_Int32 count = 0, index; | |||
336 | sal_Int32 i; | |||
337 | ||||
338 | OUString numberChar, multiplierChar, decimalChar, minusChar, separatorChar; | |||
339 | numberChar = OUString(NumberChar[0], 10*NumberChar_Count); | |||
340 | multiplierChar = OUString(MultiplierChar_7_CJK[0], ExponentCount_7_CJK*Multiplier_Count); | |||
341 | decimalChar = OUString(DecimalChar, NumberChar_Count); | |||
342 | minusChar = OUString(MinusChar, NumberChar_Count); | |||
343 | separatorChar = OUString( | |||
344 | reinterpret_cast<sal_Unicode *>(SeparatorChar), NumberChar_Count); | |||
345 | ||||
346 | for ( i = 0; i < nCount; i++) { | |||
347 | if ((index = multiplierChar.indexOf(str[i])) >= 0) { | |||
348 | if (count == 0 || !isNumber(newStr[count-1])( NumberChar[NumberChar_HalfWidth][0] <= newStr[count-1] && newStr[count-1] <= NumberChar[NumberChar_HalfWidth][9] )) { // add 1 in front of multiplier | |||
349 | newStr[count] = NUMBER_ONENumberChar[NumberChar_HalfWidth][1]; | |||
350 | if (useOffset) | |||
351 | offset[count] = i; | |||
352 | count++; | |||
353 | } | |||
354 | index = MultiplierExponent_7_CJK[index % ExponentCount_7_CJK]; | |||
355 | NativeToAscii_numberMaker( | |||
356 | sal::static_int_cast<sal_Int16>( index ), sal::static_int_cast<sal_Int16>( index ), | |||
357 | str, i, nCount, newStr.get(), count, offset, useOffset, | |||
358 | numberChar, multiplierChar); | |||
359 | } else { | |||
360 | if ((index = numberChar.indexOf(str[i])) >= 0) | |||
361 | newStr[count] = sal::static_int_cast<sal_Unicode>( (index % 10) + NUMBER_ZERONumberChar[NumberChar_HalfWidth][0] ); | |||
362 | else if (separatorChar.indexOf(str[i]) >= 0 && | |||
363 | (i < nCount-1 && (numberChar.indexOf(str[i+1]) >= 0 || | |||
364 | multiplierChar.indexOf(str[i+1]) >= 0))) | |||
365 | newStr[count] = SeparatorChar[NumberChar_HalfWidth]; | |||
366 | else if (decimalChar.indexOf(str[i]) >= 0 && | |||
367 | (i < nCount-1 && (numberChar.indexOf(str[i+1]) >= 0 || | |||
368 | multiplierChar.indexOf(str[i+1]) >= 0))) | |||
369 | // Only when decimal point is followed by numbers, | |||
370 | // it will be convert to ASCII decimal point | |||
371 | newStr[count] = DecimalChar[NumberChar_HalfWidth]; | |||
372 | else if (minusChar.indexOf(str[i]) >= 0 && | |||
373 | (i < nCount-1 && (numberChar.indexOf(str[i+1]) >= 0 || | |||
374 | multiplierChar.indexOf(str[i+1]) >= 0))) | |||
375 | // Only when minus is followed by numbers, | |||
376 | // it will be convert to ASCII minus sign | |||
377 | newStr[count] = MinusChar[NumberChar_HalfWidth]; | |||
378 | else | |||
379 | newStr[count] = str[i]; | |||
380 | if (useOffset) | |||
381 | offset[count] = i; | |||
382 | count++; | |||
383 | } | |||
384 | } | |||
385 | ||||
386 | if (useOffset) { | |||
387 | offset.realloc(count); | |||
388 | } | |||
389 | aRet = OUString(newStr.get(), count); | |||
390 | } | |||
391 | return aRet; | |||
392 | } | |||
393 | ||||
394 | const Number natnum4[4] = { | |||
395 | { NumberChar_Lower_zh, MultiplierChar_6_CJK[Multiplier_Lower_zh], 0, | |||
396 | ExponentCount_6_CJK, MultiplierExponent_6_CJK }, | |||
397 | { NumberChar_Lower_zh, MultiplierChar_6_CJK[Multiplier_Lower_zh_TW], 0, | |||
398 | ExponentCount_6_CJK, MultiplierExponent_6_CJK }, | |||
399 | { NumberChar_Modern_ja, MultiplierChar_7_CJK[Multiplier_Modern_ja], NUMBER_OMIT_ZERO_ONE_67( (1 << 0)|((1 << 7)|(1 << 8)) ), | |||
400 | ExponentCount_7_CJK, MultiplierExponent_7_CJK }, | |||
401 | { NumberChar_Lower_ko, MultiplierChar_6_CJK[Multiplier_Lower_ko], NUMBER_OMIT_ZERO(1 << 0), | |||
402 | ExponentCount_6_CJK, MultiplierExponent_6_CJK }, | |||
403 | }; | |||
404 | ||||
405 | const Number natnum5[4] = { | |||
406 | { NumberChar_Upper_zh, MultiplierChar_6_CJK[Multiplier_Upper_zh], 0, | |||
407 | ExponentCount_6_CJK, MultiplierExponent_6_CJK }, | |||
408 | { NumberChar_Upper_zh_TW, MultiplierChar_6_CJK[Multiplier_Upper_zh_TW], 0, | |||
409 | ExponentCount_6_CJK, MultiplierExponent_6_CJK }, | |||
410 | { NumberChar_Traditional_ja, MultiplierChar_7_CJK[Multiplier_Traditional_ja], NUMBER_OMIT_ZERO_ONE_67( (1 << 0)|((1 << 7)|(1 << 8)) ), | |||
411 | ExponentCount_7_CJK, MultiplierExponent_7_CJK }, | |||
412 | { NumberChar_Upper_ko, MultiplierChar_6_CJK[Multiplier_Upper_ko], 0, | |||
413 | ExponentCount_6_CJK, MultiplierExponent_6_CJK }, | |||
414 | }; | |||
415 | ||||
416 | const Number natnum6[4] = { | |||
417 | { NumberChar_FullWidth, MultiplierChar_6_CJK[Multiplier_Lower_zh], 0, | |||
418 | ExponentCount_6_CJK, MultiplierExponent_6_CJK }, | |||
419 | { NumberChar_FullWidth, MultiplierChar_6_CJK[Multiplier_Lower_zh_TW], 0, | |||
420 | ExponentCount_6_CJK, MultiplierExponent_6_CJK }, | |||
421 | { NumberChar_FullWidth, MultiplierChar_7_CJK[Multiplier_Modern_ja], NUMBER_OMIT_ZERO_ONE_67( (1 << 0)|((1 << 7)|(1 << 8)) ), | |||
422 | ExponentCount_7_CJK, MultiplierExponent_7_CJK }, | |||
423 | { NumberChar_FullWidth, MultiplierChar_6_CJK[Multiplier_Hangul_ko], NUMBER_OMIT_ZERO(1 << 0), | |||
424 | ExponentCount_6_CJK, MultiplierExponent_6_CJK }, | |||
425 | }; | |||
426 | ||||
427 | const Number natnum7[4] = { | |||
428 | { NumberChar_Lower_zh, MultiplierChar_6_CJK[Multiplier_Lower_zh], NUMBER_OMIT_ALL( (1 << 0)|((1 << 2)|(1 << 3)|(1 << 4 )|(1 << 5)|(1 << 6)|(1 << 7)|(1 << 8) )|(1 << 1) ), | |||
429 | ExponentCount_6_CJK, MultiplierExponent_6_CJK }, | |||
430 | { NumberChar_Lower_zh, MultiplierChar_6_CJK[Multiplier_Lower_zh_TW], NUMBER_OMIT_ALL( (1 << 0)|((1 << 2)|(1 << 3)|(1 << 4 )|(1 << 5)|(1 << 6)|(1 << 7)|(1 << 8) )|(1 << 1) ), | |||
431 | ExponentCount_6_CJK, MultiplierExponent_6_CJK }, | |||
432 | { NumberChar_Modern_ja, MultiplierChar_2_CJK[Multiplier_Modern_ja], NUMBER_OMIT_ZERO_ONE( (1 << 0)|((1 << 2)|(1 << 3)|(1 << 4 )|(1 << 5)|(1 << 6)|(1 << 7)|(1 << 8) ) ), | |||
433 | ExponentCount_2_CJK, MultiplierExponent_2_CJK }, | |||
434 | { NumberChar_Lower_ko, MultiplierChar_6_CJK[Multiplier_Lower_ko], NUMBER_OMIT_ALL( (1 << 0)|((1 << 2)|(1 << 3)|(1 << 4 )|(1 << 5)|(1 << 6)|(1 << 7)|(1 << 8) )|(1 << 1) ), | |||
435 | ExponentCount_6_CJK, MultiplierExponent_6_CJK }, | |||
436 | }; | |||
437 | ||||
438 | const Number natnum8[4] = { | |||
439 | { NumberChar_Upper_zh, MultiplierChar_6_CJK[Multiplier_Upper_zh], NUMBER_OMIT_ALL( (1 << 0)|((1 << 2)|(1 << 3)|(1 << 4 )|(1 << 5)|(1 << 6)|(1 << 7)|(1 << 8) )|(1 << 1) ), | |||
440 | ExponentCount_6_CJK, MultiplierExponent_6_CJK }, | |||
441 | { NumberChar_Upper_zh_TW, MultiplierChar_6_CJK[Multiplier_Upper_zh_TW], NUMBER_OMIT_ALL( (1 << 0)|((1 << 2)|(1 << 3)|(1 << 4 )|(1 << 5)|(1 << 6)|(1 << 7)|(1 << 8) )|(1 << 1) ), | |||
442 | ExponentCount_6_CJK, MultiplierExponent_6_CJK }, | |||
443 | { NumberChar_Traditional_ja, MultiplierChar_2_CJK[Multiplier_Traditional_ja], NUMBER_OMIT_ZERO_ONE( (1 << 0)|((1 << 2)|(1 << 3)|(1 << 4 )|(1 << 5)|(1 << 6)|(1 << 7)|(1 << 8) ) ), | |||
444 | ExponentCount_2_CJK, MultiplierExponent_2_CJK }, | |||
445 | { NumberChar_Upper_ko, MultiplierChar_6_CJK[Multiplier_Upper_ko], NUMBER_OMIT_ALL( (1 << 0)|((1 << 2)|(1 << 3)|(1 << 4 )|(1 << 5)|(1 << 6)|(1 << 7)|(1 << 8) )|(1 << 1) ), | |||
446 | ExponentCount_6_CJK, MultiplierExponent_6_CJK }, | |||
447 | }; | |||
448 | ||||
449 | const Number natnum10 = { NumberChar_Hangul_ko, MultiplierChar_6_CJK[Multiplier_Hangul_ko], NUMBER_OMIT_ZERO(1 << 0), | |||
450 | ExponentCount_6_CJK, MultiplierExponent_6_CJK }; | |||
451 | const Number natnum11 = { NumberChar_Hangul_ko, MultiplierChar_6_CJK[Multiplier_Hangul_ko], NUMBER_OMIT_ALL( (1 << 0)|((1 << 2)|(1 << 3)|(1 << 4 )|(1 << 5)|(1 << 6)|(1 << 7)|(1 << 8) )|(1 << 1) ), | |||
452 | ExponentCount_6_CJK, MultiplierExponent_6_CJK }; | |||
453 | ||||
454 | //! ATTENTION: Do not change order of elements! | |||
455 | //! Append new languages to the end of the list! | |||
456 | const char *natnum1Locales[] = { | |||
457 | "zh_CN", | |||
458 | "zh_TW", | |||
459 | "ja", | |||
460 | "ko", | |||
461 | "he", | |||
462 | "ar", | |||
463 | "th", | |||
464 | "hi", | |||
465 | "or", | |||
466 | "mr", | |||
467 | "bn", | |||
468 | "pa", | |||
469 | "gu", | |||
470 | "ta", | |||
471 | "te", | |||
472 | "kn", | |||
473 | "ml", | |||
474 | "lo", | |||
475 | "bo", | |||
476 | "my", | |||
477 | "km", | |||
478 | "mn", | |||
479 | "ne", | |||
480 | "dz", | |||
481 | "fa", | |||
482 | "cu" | |||
483 | }; | |||
484 | const sal_Int16 nbOfLocale = SAL_N_ELEMENTS(natnum1Locales)(sizeof(sal_n_array_size(natnum1Locales))); | |||
485 | ||||
486 | //! ATTENTION: Do not change order of elements! | |||
487 | //! Number and order must match elements of natnum1Locales! | |||
488 | const sal_Int16 natnum1[] = { | |||
489 | NumberChar_Lower_zh, | |||
490 | NumberChar_Lower_zh, | |||
491 | NumberChar_Modern_ja, | |||
492 | NumberChar_Lower_ko, | |||
493 | NumberChar_he, | |||
494 | NumberChar_Indic_ar, | |||
495 | NumberChar_th, | |||
496 | NumberChar_hi, | |||
497 | NumberChar_or, | |||
498 | NumberChar_mr, | |||
499 | NumberChar_bn, | |||
500 | NumberChar_pa, | |||
501 | NumberChar_gu, | |||
502 | NumberChar_ta, | |||
503 | NumberChar_te, | |||
504 | NumberChar_kn, | |||
505 | NumberChar_ml, | |||
506 | NumberChar_lo, | |||
507 | NumberChar_bo, | |||
508 | NumberChar_my, | |||
509 | NumberChar_km, | |||
510 | NumberChar_mn, | |||
511 | NumberChar_ne, | |||
512 | NumberChar_dz, | |||
513 | NumberChar_EastIndic_ar, | |||
514 | NumberChar_cu | |||
515 | }; | |||
516 | const sal_Int16 sizeof_natnum1 = SAL_N_ELEMENTS(natnum1)(sizeof(sal_n_array_size(natnum1))); | |||
517 | ||||
518 | //! ATTENTION: Do not change order of elements! | |||
519 | //! Order must match first elements of natnum1Locales! | |||
520 | const sal_Int16 natnum2[] = { | |||
521 | NumberChar_Upper_zh, | |||
522 | NumberChar_Upper_zh_TW, | |||
523 | NumberChar_Traditional_ja, | |||
524 | NumberChar_Upper_ko, | |||
525 | NumberChar_he | |||
526 | }; | |||
527 | const sal_Int16 sizeof_natnum2 = SAL_N_ELEMENTS(natnum2)(sizeof(sal_n_array_size(natnum2))); | |||
528 | ||||
529 | sal_Int16 getLanguageNumber( const Locale& rLocale) | |||
530 | { | |||
531 | // return zh_TW for TW, HK and MO, return zh_CN for other zh locales. | |||
532 | if (rLocale.Language == "zh") return MsLangId::isTraditionalChinese(rLocale) ? 1 : 0; | |||
533 | ||||
534 | for (sal_Int16 i = 2; i < nbOfLocale; i++) | |||
535 | if (rLocale.Language.equalsAsciiL(natnum1Locales[i], 2)) | |||
536 | return i; | |||
537 | ||||
538 | return -1; | |||
539 | } | |||
540 | ||||
541 | struct Separators | |||
542 | { | |||
543 | sal_Unicode DecimalSeparator; | |||
544 | sal_Unicode ThousandSeparator; | |||
545 | Separators(const Locale& rLocale) | |||
546 | { | |||
547 | LocaleDataItem aLocaleItem = LocaleDataImpl::get()->getLocaleItem(rLocale); | |||
548 | DecimalSeparator = aLocaleItem.decimalSeparator.toChar(); | |||
549 | ThousandSeparator = aLocaleItem.thousandSeparator.toChar(); | |||
550 | } | |||
551 | }; | |||
552 | ||||
553 | Separators getLocaleSeparators(const Locale& rLocale, const OUString& rLocStr) | |||
554 | { | |||
555 | // Guard the static variable below. | |||
556 | osl::MutexGuard aGuard(theNatNumMutex::get()); | |||
557 | // Maximum a couple hundred of pairs with 4-byte structs - so no need for smart managing | |||
558 | static std::unordered_map<OUString, Separators> aLocaleSeparatorsBuf; | |||
559 | auto it = aLocaleSeparatorsBuf.find(rLocStr); | |||
560 | if (it == aLocaleSeparatorsBuf.end()) | |||
561 | { | |||
562 | it = aLocaleSeparatorsBuf.emplace(rLocStr, Separators(rLocale)).first; | |||
563 | } | |||
564 | return it->second; | |||
565 | } | |||
566 | ||||
567 | OUString getNumberText(const Locale& rLocale, const OUString& rNumberString, | |||
568 | const OUString& sNumberTextParams) | |||
569 | { | |||
570 | sal_Int32 i, count = 0; | |||
571 | const sal_Int32 len = rNumberString.getLength(); | |||
572 | const sal_Unicode* src = rNumberString.getStr(); | |||
573 | ||||
574 | OUString aLoc = LanguageTag::convertToBcp47(rLocale); | |||
575 | Separators aSeparators = getLocaleSeparators(rLocale, aLoc); | |||
576 | ||||
577 | OUStringBuffer sBuf(len); | |||
578 | for (i = 0; i < len; i++) | |||
579 | { | |||
580 | sal_Unicode ch = src[i]; | |||
581 | if (isNumber(ch)( NumberChar[NumberChar_HalfWidth][0] <= ch && ch <= NumberChar[NumberChar_HalfWidth][9] )) | |||
582 | { | |||
583 | ++count; | |||
584 | sBuf.append(ch); | |||
585 | } | |||
586 | else if (ch == aSeparators.DecimalSeparator) | |||
587 | // Convert any decimal separator to point - in case libnumbertext has a different one | |||
588 | // for this locale (it seems that point is supported for all locales in libnumbertext) | |||
589 | sBuf.append('.'); | |||
590 | else if (ch == aSeparators.ThousandSeparator && count > 0) | |||
591 | continue; | |||
592 | else if (isMinus(ch)( ch == MinusChar[NumberChar_HalfWidth] ) && count == 0) | |||
593 | sBuf.append(ch); | |||
594 | else | |||
595 | break; | |||
596 | } | |||
597 | ||||
598 | // Handle also month and day names for NatNum12 date formatting | |||
599 | const OUString& rNumberStr = (count == 0) ? rNumberString : sBuf.makeStringAndClear(); | |||
600 | ||||
601 | // Guard the static variables below. | |||
602 | osl::MutexGuard aGuard( theNatNumMutex::get()); | |||
603 | ||||
604 | static auto xNumberText | |||
605 | = css::linguistic2::NumberText::create(comphelper::getProcessComponentContext()); | |||
606 | OUString numbertext_prefix; | |||
607 | // default "cardinal" gets empty prefix | |||
608 | if (!sNumberTextParams.isEmpty() && sNumberTextParams != "cardinal") | |||
609 | numbertext_prefix = sNumberTextParams + " "; | |||
610 | // Several hundreds of headings could result typing lags because | |||
611 | // of the continuous update of the multiple number names during typing. | |||
612 | // We fix this by buffering the result of the conversion. | |||
613 | static std::unordered_map<OUString, std::map<OUString, OUString>> aBuff; | |||
614 | auto& rItems = aBuff[rNumberStr]; | |||
615 | auto& rItem = rItems[numbertext_prefix + aLoc]; | |||
616 | if (rItem.isEmpty()) | |||
617 | { | |||
618 | rItem = xNumberText->getNumberText(numbertext_prefix + rNumberStr, rLocale); | |||
619 | // use number at missing number to text conversion | |||
620 | if (rItem.isEmpty()) | |||
621 | rItem = rNumberStr; | |||
622 | } | |||
623 | OUString sResult = rItem; | |||
624 | if (i != 0 && i < len) | |||
625 | sResult += rNumberString.copy(i); | |||
626 | return sResult; | |||
627 | } | |||
628 | } | |||
629 | ||||
630 | OUString NativeNumberSupplierService::getNativeNumberString(const OUString& aNumberString, const Locale& rLocale, | |||
631 | sal_Int16 nNativeNumberMode, | |||
632 | Sequence<sal_Int32>& offset, | |||
633 | const OUString& rNativeNumberParams) | |||
634 | { | |||
635 | if (!isValidNatNum(rLocale, nNativeNumberMode)) | |||
636 | return aNumberString; | |||
637 | ||||
638 | if (nNativeNumberMode == NativeNumberMode::NATNUM12) | |||
639 | { | |||
640 | // handle capitalization prefixes "capitalize", "upper" and "title" | |||
641 | ||||
642 | enum WhichCasing | |||
643 | { | |||
644 | CAPITALIZE, | |||
645 | UPPER, | |||
646 | TITLE | |||
647 | }; | |||
648 | ||||
649 | struct CasingEntry | |||
650 | { | |||
651 | std::u16string_view aLiteral; | |||
652 | WhichCasing eCasing; | |||
653 | }; | |||
654 | ||||
655 | static const CasingEntry Casings[] = | |||
656 | { | |||
657 | { std::u16string_view(u"capitalize"), CAPITALIZE }, | |||
658 | { std::u16string_view(u"upper"), UPPER }, | |||
659 | { std::u16string_view(u"title"), TITLE } | |||
660 | }; | |||
661 | ||||
662 | sal_Int32 nStripCase = 0; | |||
663 | size_t nCasing; | |||
664 | for (nCasing = 0; nCasing < SAL_N_ELEMENTS(Casings)(sizeof(sal_n_array_size(Casings))); ++nCasing) | |||
665 | { | |||
666 | if (rNativeNumberParams.startsWith( Casings[nCasing].aLiteral)) | |||
667 | { | |||
668 | nStripCase = Casings[nCasing].aLiteral.size(); | |||
669 | break; | |||
670 | } | |||
671 | } | |||
672 | ||||
673 | if (nStripCase > 0 && (rNativeNumberParams.getLength() == nStripCase || | |||
674 | rNativeNumberParams[nStripCase++] == ' ')) | |||
675 | { | |||
676 | OUString aStr = getNumberText(rLocale, aNumberString, rNativeNumberParams.copy(nStripCase)); | |||
677 | ||||
678 | if (!xCharClass.is()) | |||
679 | xCharClass = CharacterClassification::create(comphelper::getProcessComponentContext()); | |||
680 | ||||
681 | switch (Casings[nCasing].eCasing) | |||
682 | { | |||
683 | case CAPITALIZE: | |||
684 | return xCharClass->toTitle(aStr, 0, 1, aLocale) + | |||
685 | (aStr.getLength() > 1 ? aStr.copy(1) : OUString()); | |||
686 | case UPPER: | |||
687 | return xCharClass->toUpper(aStr, 0, aStr.getLength(), aLocale); | |||
688 | case TITLE: | |||
689 | return xCharClass->toTitle(aStr, 0, aStr.getLength(), aLocale); | |||
690 | } | |||
691 | } | |||
692 | else | |||
693 | { | |||
694 | return getNumberText(rLocale, aNumberString, rNativeNumberParams); | |||
695 | } | |||
696 | } | |||
697 | ||||
698 | sal_Int16 langnum = getLanguageNumber(rLocale); | |||
699 | if (langnum == -1) | |||
700 | return aNumberString; | |||
701 | ||||
702 | const Number *number = nullptr; | |||
703 | sal_Int16 num = -1; | |||
704 | ||||
705 | switch (nNativeNumberMode) | |||
706 | { | |||
707 | case NativeNumberMode::NATNUM0: // Ascii | |||
708 | return NativeToAscii(aNumberString, aNumberString.getLength(), offset, useOffset); | |||
709 | case NativeNumberMode::NATNUM1: // Char, Lower | |||
710 | num = natnum1[langnum]; | |||
711 | break; | |||
712 | case NativeNumberMode::NATNUM2: // Char, Upper | |||
713 | num = natnum2[langnum]; | |||
714 | break; | |||
715 | case NativeNumberMode::NATNUM3: // Char, FullWidth | |||
716 | num = NumberChar_FullWidth; | |||
717 | break; | |||
718 | case NativeNumberMode::NATNUM4: // Text, Lower, Long | |||
719 | number = &natnum4[langnum]; | |||
720 | break; | |||
721 | case NativeNumberMode::NATNUM5: // Text, Upper, Long | |||
722 | number = &natnum5[langnum]; | |||
723 | break; | |||
724 | case NativeNumberMode::NATNUM6: // Text, FullWidth | |||
725 | number = &natnum6[langnum]; | |||
726 | break; | |||
727 | case NativeNumberMode::NATNUM7: // Text. Lower, Short | |||
728 | number = &natnum7[langnum]; | |||
729 | break; | |||
730 | case NativeNumberMode::NATNUM8: // Text, Upper, Short | |||
731 | number = &natnum8[langnum]; | |||
732 | break; | |||
733 | case NativeNumberMode::NATNUM9: // Char, Hangul | |||
734 | num = NumberChar_Hangul_ko; | |||
735 | break; | |||
736 | case NativeNumberMode::NATNUM10: // Text, Hangul, Long | |||
737 | number = &natnum10; | |||
738 | break; | |||
739 | case NativeNumberMode::NATNUM11: // Text, Hangul, Short | |||
740 | number = &natnum11; | |||
741 | break; | |||
742 | default: | |||
743 | break; | |||
744 | } | |||
745 | ||||
746 | if (number || num >= 0) { | |||
747 | if (aLocale.Language != rLocale.Language || | |||
748 | aLocale.Country != rLocale.Country || | |||
749 | aLocale.Variant != rLocale.Variant) { | |||
750 | LocaleDataItem item = LocaleDataImpl::get()->getLocaleItem( rLocale ); | |||
751 | aLocale = rLocale; | |||
752 | DecimalChar[NumberChar_HalfWidth]=item.decimalSeparator.toChar(); | |||
753 | if (DecimalChar[NumberChar_HalfWidth] > 0x7E || DecimalChar[NumberChar_HalfWidth] < 0x21) | |||
754 | DecimalChar[NumberChar_FullWidth]=0xFF0E; | |||
755 | else | |||
756 | DecimalChar[NumberChar_FullWidth]=DecimalChar[NumberChar_HalfWidth]+0xFEE0; | |||
757 | SeparatorChar[NumberChar_HalfWidth]=item.thousandSeparator.toChar(); | |||
758 | if (SeparatorChar[NumberChar_HalfWidth] > 0x7E || SeparatorChar[NumberChar_HalfWidth] < 0x21) | |||
759 | SeparatorChar[NumberChar_FullWidth]=0xFF0C; | |||
760 | else | |||
761 | SeparatorChar[NumberChar_FullWidth]=SeparatorChar[NumberChar_HalfWidth]+0xFEE0; | |||
762 | } | |||
763 | if (number) | |||
764 | return AsciiToNative( aNumberString, aNumberString.getLength(), offset, useOffset, number ); | |||
765 | else if (num == NumberChar_he) | |||
766 | return getHebrewNativeNumberString(aNumberString, | |||
767 | nNativeNumberMode == NativeNumberMode::NATNUM2); | |||
768 | else if (num == NumberChar_cu) | |||
769 | return getCyrillicNativeNumberString(aNumberString); | |||
770 | else | |||
771 | return AsciiToNativeChar(aNumberString, aNumberString.getLength(), offset, useOffset, num); | |||
772 | } | |||
773 | else | |||
774 | return aNumberString; | |||
775 | } | |||
776 | ||||
777 | OUString SAL_CALL NativeNumberSupplierService::getNativeNumberString(const OUString& aNumberString, const Locale& rLocale, | |||
778 | sal_Int16 nNativeNumberMode) | |||
779 | { | |||
780 | Sequence< sal_Int32 > offset; | |||
781 | return getNativeNumberString(aNumberString, rLocale, nNativeNumberMode, offset); | |||
782 | } | |||
783 | ||||
784 | OUString SAL_CALL NativeNumberSupplierService::getNativeNumberStringParams( | |||
785 | const OUString& rNumberString, const css::lang::Locale& rLocale, sal_Int16 nNativeNumberMode, | |||
786 | const OUString& rNativeNumberParams) | |||
787 | { | |||
788 | Sequence<sal_Int32> offset; | |||
789 | return getNativeNumberString(rNumberString, rLocale, nNativeNumberMode, offset, rNativeNumberParams); | |||
790 | } | |||
791 | ||||
792 | sal_Unicode NativeNumberSupplierService::getNativeNumberChar( const sal_Unicode inChar, const Locale& rLocale, sal_Int16 nNativeNumberMode ) | |||
793 | { | |||
794 | if (nNativeNumberMode == NativeNumberMode::NATNUM0) { // Ascii | |||
795 | for (const auto & i : NumberChar) | |||
796 | for (sal_Int16 j = 0; j < 10; j++) | |||
797 | if (inChar == i[j]) | |||
798 | return j; | |||
799 | return inChar; | |||
800 | } | |||
801 | ||||
802 | if (!isNumber(inChar)( NumberChar[NumberChar_HalfWidth][0] <= inChar && inChar <= NumberChar[NumberChar_HalfWidth][9] )) | |||
803 | return inChar; | |||
804 | ||||
805 | if (!isValidNatNum(rLocale, nNativeNumberMode)) | |||
806 | return inChar; | |||
807 | ||||
808 | sal_Int16 langnum = getLanguageNumber(rLocale); | |||
809 | if (langnum == -1) | |||
810 | return inChar; | |||
811 | ||||
812 | switch (nNativeNumberMode) | |||
813 | { | |||
814 | case NativeNumberMode::NATNUM1: // Char, Lower | |||
815 | case NativeNumberMode::NATNUM4: // Text, Lower, Long | |||
816 | case NativeNumberMode::NATNUM7: // Text. Lower, Short | |||
817 | return NumberChar[natnum1[langnum]][inChar - NUMBER_ZERONumberChar[NumberChar_HalfWidth][0]]; | |||
818 | case NativeNumberMode::NATNUM2: // Char, Upper | |||
819 | case NativeNumberMode::NATNUM5: // Text, Upper, Long | |||
820 | case NativeNumberMode::NATNUM8: // Text, Upper, Short | |||
821 | return NumberChar[natnum2[langnum]][inChar - NUMBER_ZERONumberChar[NumberChar_HalfWidth][0]]; | |||
822 | case NativeNumberMode::NATNUM3: // Char, FullWidth | |||
823 | case NativeNumberMode::NATNUM6: // Text, FullWidth | |||
824 | return NumberChar[NumberChar_FullWidth][inChar - NUMBER_ZERONumberChar[NumberChar_HalfWidth][0]]; | |||
825 | case NativeNumberMode::NATNUM9: // Char, Hangul | |||
826 | case NativeNumberMode::NATNUM10: // Text, Hangul, Long | |||
827 | case NativeNumberMode::NATNUM11: // Text, Hangul, Short | |||
828 | return NumberChar[NumberChar_Hangul_ko][inChar - NUMBER_ZERONumberChar[NumberChar_HalfWidth][0]]; | |||
829 | default: | |||
830 | break; | |||
831 | } | |||
832 | ||||
833 | return inChar; | |||
834 | } | |||
835 | ||||
836 | sal_Bool SAL_CALL NativeNumberSupplierService::isValidNatNum( const Locale& rLocale, sal_Int16 nNativeNumberMode ) | |||
837 | { | |||
838 | sal_Int16 langnum = getLanguageNumber(rLocale); | |||
839 | ||||
840 | switch (nNativeNumberMode) { | |||
841 | case NativeNumberMode::NATNUM0: // Ascii | |||
842 | case NativeNumberMode::NATNUM3: // Char, FullWidth | |||
843 | case NativeNumberMode::NATNUM12: // spell out numbers, dates and money amounts | |||
844 | return true; | |||
845 | case NativeNumberMode::NATNUM1: // Char, Lower | |||
846 | return (langnum >= 0); | |||
847 | case NativeNumberMode::NATNUM2: // Char, Upper | |||
848 | if (langnum == 4) // Hebrew numbering | |||
849 | return true; | |||
850 | [[fallthrough]]; | |||
851 | case NativeNumberMode::NATNUM4: // Text, Lower, Long | |||
852 | case NativeNumberMode::NATNUM5: // Text, Upper, Long | |||
853 | case NativeNumberMode::NATNUM6: // Text, FullWidth | |||
854 | case NativeNumberMode::NATNUM7: // Text. Lower, Short | |||
855 | case NativeNumberMode::NATNUM8: // Text, Upper, Short | |||
856 | return (langnum >= 0 && langnum < 4); // CJK numbering | |||
857 | case NativeNumberMode::NATNUM9: // Char, Hangul | |||
858 | case NativeNumberMode::NATNUM10: // Text, Hangul, Long | |||
859 | case NativeNumberMode::NATNUM11: // Text, Hangul, Short | |||
860 | return (langnum == 3); // Korean numbering | |||
861 | } | |||
862 | return false; | |||
863 | } | |||
864 | ||||
865 | NativeNumberXmlAttributes SAL_CALL NativeNumberSupplierService::convertToXmlAttributes( const Locale& rLocale, sal_Int16 nNativeNumberMode ) | |||
866 | { | |||
867 | static const sal_Int16 attShort = 0; | |||
868 | static const sal_Int16 attMedium = 1; | |||
869 | static const sal_Int16 attLong = 2; | |||
870 | static const char *attType[] = { "short", "medium", "long" }; | |||
871 | ||||
872 | sal_Int16 number = NumberChar_HalfWidth, type = attShort; | |||
873 | ||||
874 | sal_Int16 langnum = -1; | |||
875 | if (isValidNatNum(rLocale, nNativeNumberMode)) { | |||
| ||||
876 | langnum = getLanguageNumber(rLocale); | |||
877 | } | |||
878 | if (langnum != -1) { | |||
879 | switch (nNativeNumberMode) { | |||
880 | case NativeNumberMode::NATNUM0: // Ascii | |||
881 | number = NumberChar_HalfWidth; | |||
882 | type = attShort; | |||
883 | break; | |||
884 | case NativeNumberMode::NATNUM1: // Char, Lower | |||
885 | number = natnum1[langnum]; | |||
886 | type = attShort; | |||
887 | break; | |||
888 | case NativeNumberMode::NATNUM2: // Char, Upper | |||
889 | number = natnum2[langnum]; | |||
890 | type = number == NumberChar_he ? attMedium : attShort; | |||
891 | break; | |||
892 | case NativeNumberMode::NATNUM3: // Char, FullWidth | |||
893 | number = NumberChar_FullWidth; | |||
894 | type = attShort; | |||
895 | break; | |||
896 | case NativeNumberMode::NATNUM4: // Text, Lower, Long | |||
897 | number = natnum1[langnum]; | |||
898 | type = attLong; | |||
899 | break; | |||
900 | case NativeNumberMode::NATNUM5: // Text, Upper, Long | |||
901 | number = natnum2[langnum]; | |||
902 | type = attLong; | |||
903 | break; | |||
904 | case NativeNumberMode::NATNUM6: // Text, FullWidth | |||
905 | number = NumberChar_FullWidth; | |||
906 | type = attLong; | |||
907 | break; | |||
908 | case NativeNumberMode::NATNUM7: // Text. Lower, Short | |||
909 | number = natnum1[langnum]; | |||
910 | type = attMedium; | |||
911 | break; | |||
912 | case NativeNumberMode::NATNUM8: // Text, Upper, Short | |||
913 | number = natnum2[langnum]; | |||
| ||||
914 | type = attMedium; | |||
915 | break; | |||
916 | case NativeNumberMode::NATNUM9: // Char, Hangul | |||
917 | number = NumberChar_Hangul_ko; | |||
918 | type = attShort; | |||
919 | break; | |||
920 | case NativeNumberMode::NATNUM10: // Text, Hangul, Long | |||
921 | number = NumberChar_Hangul_ko; | |||
922 | type = attLong; | |||
923 | break; | |||
924 | case NativeNumberMode::NATNUM11: // Text, Hangul, Short | |||
925 | number = NumberChar_Hangul_ko; | |||
926 | type = attMedium; | |||
927 | break; | |||
928 | default: | |||
929 | break; | |||
930 | } | |||
931 | } | |||
932 | return NativeNumberXmlAttributes(rLocale, OUString(&NumberChar[number][1], 1), | |||
933 | OUString::createFromAscii(attType[type])); | |||
934 | } | |||
935 | ||||
936 | static bool natNumIn(sal_Int16 num, const sal_Int16 natnum[], sal_Int16 len) | |||
937 | { | |||
938 | for (sal_Int16 i = 0; i < len; i++) | |||
939 | if (natnum[i] == num) | |||
940 | return true; | |||
941 | return false; | |||
942 | } | |||
943 | ||||
944 | sal_Int16 SAL_CALL NativeNumberSupplierService::convertFromXmlAttributes( const NativeNumberXmlAttributes& aAttr ) | |||
945 | { | |||
946 | sal_Unicode numberChar[NumberChar_Count]; | |||
947 | for (sal_Int16 i = 0; i < NumberChar_Count; i++) | |||
948 | numberChar[i] = NumberChar[i][1]; | |||
949 | OUString number(numberChar, NumberChar_Count); | |||
950 | ||||
951 | sal_Int16 num = sal::static_int_cast<sal_Int16>( number.indexOf(aAttr.Format) ); | |||
952 | ||||
953 | if ( aAttr.Style == "short" ) { | |||
954 | if (num == NumberChar_FullWidth) | |||
955 | return NativeNumberMode::NATNUM3; | |||
956 | else if (num == NumberChar_Hangul_ko) | |||
957 | return NativeNumberMode::NATNUM9; | |||
958 | else if (natNumIn(num, natnum1, sizeof_natnum1)) | |||
959 | return NativeNumberMode::NATNUM1; | |||
960 | else if (natNumIn(num, natnum2, sizeof_natnum2)) | |||
961 | return NativeNumberMode::NATNUM2; | |||
962 | } else if ( aAttr.Style == "medium" ) { | |||
963 | if (num == NumberChar_Hangul_ko) | |||
964 | return NativeNumberMode::NATNUM11; | |||
965 | else if (num == NumberChar_he) | |||
966 | return NativeNumberMode::NATNUM2; | |||
967 | else if (natNumIn(num, natnum1, sizeof_natnum1)) | |||
968 | return NativeNumberMode::NATNUM7; | |||
969 | else if (natNumIn(num, natnum2, sizeof_natnum2)) | |||
970 | return NativeNumberMode::NATNUM8; | |||
971 | } else if ( aAttr.Style == "long" ) { | |||
972 | if (num == NumberChar_FullWidth) | |||
973 | return NativeNumberMode::NATNUM6; | |||
974 | else if (num == NumberChar_Hangul_ko) | |||
975 | return NativeNumberMode::NATNUM10; | |||
976 | else if (natNumIn(num, natnum1, sizeof_natnum1)) | |||
977 | return NativeNumberMode::NATNUM4; | |||
978 | else if (natNumIn(num, natnum2, sizeof_natnum2)) | |||
979 | return NativeNumberMode::NATNUM5; | |||
980 | } else { | |||
981 | throw RuntimeException(); | |||
982 | } | |||
983 | return NativeNumberMode::NATNUM0; | |||
984 | } | |||
985 | ||||
986 | ||||
987 | // Following code generates Hebrew Number, | |||
988 | // see numerical system in the Hebrew Numbering System in following link for details, | |||
989 | // http://smontagu.org/writings/HebrewNumbers.html | |||
990 | ||||
991 | namespace { | |||
992 | ||||
993 | struct HebrewNumberChar { | |||
994 | sal_Unicode code; | |||
995 | sal_Int16 value; | |||
996 | }; | |||
997 | ||||
998 | } | |||
999 | ||||
1000 | HebrewNumberChar const HebrewNumberCharArray[] = { | |||
1001 | { 0x05ea, 400 }, | |||
1002 | { 0x05ea, 400 }, | |||
1003 | { 0x05e9, 300 }, | |||
1004 | { 0x05e8, 200 }, | |||
1005 | { 0x05e7, 100 }, | |||
1006 | { 0x05e6, 90 }, | |||
1007 | { 0x05e4, 80 }, | |||
1008 | { 0x05e2, 70 }, | |||
1009 | { 0x05e1, 60 }, | |||
1010 | { 0x05e0, 50 }, | |||
1011 | { 0x05de, 40 }, | |||
1012 | { 0x05dc, 30 }, | |||
1013 | { 0x05db, 20 }, | |||
1014 | { 0x05d9, 10 }, | |||
1015 | { 0x05d8, 9 }, | |||
1016 | { 0x05d7, 8 }, | |||
1017 | { 0x05d6, 7 }, | |||
1018 | { 0x05d5, 6 }, | |||
1019 | { 0x05d4, 5 }, | |||
1020 | { 0x05d3, 4 }, | |||
1021 | { 0x05d2, 3 }, | |||
1022 | { 0x05d1, 2 }, | |||
1023 | { 0x05d0, 1 } | |||
1024 | }; | |||
1025 | ||||
1026 | const sal_Unicode thousand[] = {0x05d0, 0x05dc, 0x05e3, 0x0}; | |||
1027 | const sal_Unicode thousands[] = {0x05d0, 0x05dc, 0x05e4, 0x05d9, 0x0}; | |||
1028 | const sal_Unicode thousands_last[] = {0x05d0, 0x05dc, 0x05e4, 0x05d9, 0x05dd, 0x0}; | |||
1029 | const sal_Unicode geresh = 0x05f3; | |||
1030 | const sal_Unicode gershayim = 0x05f4; | |||
1031 | ||||
1032 | static void makeHebrewNumber(sal_Int64 value, OUStringBuffer& output, bool isLast, bool useGeresh) | |||
1033 | { | |||
1034 | sal_Int16 num = sal::static_int_cast<sal_Int16>(value % 1000); | |||
1035 | ||||
1036 | if (value > 1000) { | |||
1037 | makeHebrewNumber(value / 1000, output, num != 0, useGeresh); | |||
1038 | output.append(" "); | |||
1039 | } | |||
1040 | if (num == 0) { | |||
1041 | output.append(value == 1000 ? thousand : isLast ? thousands_last : thousands); | |||
1042 | } else { | |||
1043 | sal_Int16 nbOfChar = 0; | |||
1044 | for (sal_Int32 j = 0; num > 0 && j < sal_Int32(SAL_N_ELEMENTS(HebrewNumberCharArray)(sizeof(sal_n_array_size(HebrewNumberCharArray)))); j++) { | |||
1045 | if (num - HebrewNumberCharArray[j].value >= 0) { | |||
1046 | nbOfChar++; | |||
1047 | // https://en.wikipedia.org/wiki/Hebrew_numerals#Key_exceptions | |||
1048 | // By convention, the numbers 15 and 16 are represented as 9 + 6 and 9 + 7 | |||
1049 | if (num == 15 || num == 16) // substitution for 15 and 16 | |||
1050 | j++; | |||
1051 | assert(j < sal_Int32(SAL_N_ELEMENTS(HebrewNumberCharArray)))(static_cast <bool> (j < sal_Int32((sizeof(sal_n_array_size (HebrewNumberCharArray))))) ? void (0) : __assert_fail ("j < sal_Int32(SAL_N_ELEMENTS(HebrewNumberCharArray))" , "/home/maarten/src/libreoffice/core/i18npool/source/nativenumber/nativenumbersupplier.cxx" , 1051, __extension__ __PRETTY_FUNCTION__)); | |||
1052 | num = sal::static_int_cast<sal_Int16>( num - HebrewNumberCharArray[j].value ); | |||
1053 | output.append(HebrewNumberCharArray[j].code); | |||
1054 | } | |||
1055 | } | |||
1056 | if (useGeresh) { | |||
1057 | if (nbOfChar > 1) // a number is written as more than one character | |||
1058 | output.insert(output.getLength() - 1, gershayim); | |||
1059 | else if (nbOfChar == 1) // a number is written as a single character | |||
1060 | output.append(geresh); | |||
1061 | } | |||
1062 | } | |||
1063 | } | |||
1064 | ||||
1065 | OUString getHebrewNativeNumberString(const OUString& aNumberString, bool useGeresh) | |||
1066 | { | |||
1067 | sal_Int64 value = 0; | |||
1068 | sal_Int32 i, count = 0, len = aNumberString.getLength(); | |||
1069 | const sal_Unicode *src = aNumberString.getStr(); | |||
1070 | ||||
1071 | for (i = 0; i < len; i++) { | |||
1072 | sal_Unicode ch = src[i]; | |||
1073 | if (isNumber(ch)( NumberChar[NumberChar_HalfWidth][0] <= ch && ch <= NumberChar[NumberChar_HalfWidth][9] )) { | |||
1074 | if (++count >= 20) // Number is too long, could not be handled. | |||
1075 | return aNumberString; | |||
1076 | value = value * 10 + (ch - NUMBER_ZERONumberChar[NumberChar_HalfWidth][0]); | |||
1077 | } | |||
1078 | else if (isSeparator(ch)( ch == SeparatorChar[NumberChar_HalfWidth] ) && count > 0) continue; | |||
1079 | else if (isMinus(ch)( ch == MinusChar[NumberChar_HalfWidth] ) && count == 0) continue; | |||
1080 | else break; | |||
1081 | } | |||
1082 | ||||
1083 | if (value > 0) { | |||
1084 | OUStringBuffer output(count*2 + 2 + len - i); | |||
1085 | ||||
1086 | makeHebrewNumber(value, output, true, useGeresh); | |||
1087 | ||||
1088 | if (i < len) | |||
1089 | output.append(std::u16string_view(aNumberString).substr(i)); | |||
1090 | ||||
1091 | return output.makeStringAndClear(); | |||
1092 | } | |||
1093 | else | |||
1094 | return aNumberString; | |||
1095 | } | |||
1096 | ||||
1097 | // Support for Cyrillic Numerals | |||
1098 | // See UTN 41 for implementation information | |||
1099 | // http://www.unicode.org/notes/tn41/ | |||
1100 | ||||
1101 | const sal_Unicode cyrillicThousandsMark = 0x0482; | |||
1102 | const sal_Unicode cyrillicTitlo = 0x0483; | |||
1103 | const sal_Unicode cyrillicTen = 0x0456; | |||
1104 | ||||
1105 | namespace { | |||
1106 | ||||
1107 | struct CyrillicNumberChar { | |||
1108 | sal_Unicode code; | |||
1109 | sal_Int16 value; | |||
1110 | }; | |||
1111 | ||||
1112 | } | |||
1113 | ||||
1114 | CyrillicNumberChar const CyrillicNumberCharArray[] = { | |||
1115 | { 0x0446, 900 }, | |||
1116 | { 0x047f, 800 }, | |||
1117 | { 0x0471, 700 }, | |||
1118 | { 0x0445, 600 }, | |||
1119 | { 0x0444, 500 }, | |||
1120 | { 0x0443, 400 }, | |||
1121 | { 0x0442, 300 }, | |||
1122 | { 0x0441, 200 }, | |||
1123 | { 0x0440, 100 }, | |||
1124 | { 0x0447, 90 }, | |||
1125 | { 0x043f, 80 }, | |||
1126 | { 0x047b, 70 }, | |||
1127 | { 0x046f, 60 }, | |||
1128 | { 0x043d, 50 }, | |||
1129 | { 0x043c, 40 }, | |||
1130 | { 0x043b, 30 }, | |||
1131 | { 0x043a, 20 }, | |||
1132 | { 0x0456, 10 }, | |||
1133 | { 0x0473, 9 }, | |||
1134 | { 0x0438, 8 }, | |||
1135 | { 0x0437, 7 }, | |||
1136 | { 0x0455, 6 }, | |||
1137 | { 0x0454, 5 }, | |||
1138 | { 0x0434, 4 }, | |||
1139 | { 0x0433, 3 }, | |||
1140 | { 0x0432, 2 }, | |||
1141 | { 0x0430, 1 } | |||
1142 | }; | |||
1143 | ||||
1144 | static void makeCyrillicNumber(sal_Int64 value, OUStringBuffer& output, bool addTitlo) | |||
1145 | { | |||
1146 | sal_Int16 num = sal::static_int_cast<sal_Int16>(value % 1000); | |||
1147 | if (value >= 1000) { | |||
1148 | output.append(cyrillicThousandsMark); | |||
1149 | makeCyrillicNumber(value / 1000, output, false); | |||
1150 | if (value >= 10000 && (value - 10000) % 1000 != 0) { | |||
1151 | output.append(" "); | |||
1152 | } | |||
1153 | if (value % 1000 == 0) | |||
1154 | addTitlo = false; | |||
1155 | } | |||
1156 | ||||
1157 | for (sal_Int32 j = 0; num > 0 && j < sal_Int32(SAL_N_ELEMENTS(CyrillicNumberCharArray)(sizeof(sal_n_array_size(CyrillicNumberCharArray)))); j++) { | |||
1158 | if (num < 20 && num > 10) { | |||
1159 | num -= 10; | |||
1160 | makeCyrillicNumber(num, output, false); | |||
1161 | output.append(cyrillicTen); | |||
1162 | break; | |||
1163 | } | |||
1164 | ||||
1165 | if (CyrillicNumberCharArray[j].value <= num) { | |||
1166 | output.append(CyrillicNumberCharArray[j].code); | |||
1167 | num = sal::static_int_cast<sal_Int16>( num - CyrillicNumberCharArray[j].value ); | |||
1168 | } | |||
1169 | } | |||
1170 | ||||
1171 | if (!addTitlo) | |||
1172 | return; | |||
1173 | ||||
1174 | if (output.getLength() == 1) { | |||
1175 | output.append(cyrillicTitlo); | |||
1176 | } else if (output.getLength() == 2) { | |||
1177 | if (value > 800 && value < 900) { | |||
1178 | output.append(cyrillicTitlo); | |||
1179 | } else { | |||
1180 | output.insert(1, cyrillicTitlo); | |||
1181 | } | |||
1182 | } else if (output.getLength() > 2) { | |||
1183 | if (output.indexOf(" ") == output.getLength() - 2) { | |||
1184 | output.append(cyrillicTitlo); | |||
1185 | } else { | |||
1186 | output.insert(output.getLength() - 1, cyrillicTitlo); | |||
1187 | } | |||
1188 | } | |||
1189 | } | |||
1190 | ||||
1191 | OUString getCyrillicNativeNumberString(const OUString& aNumberString) | |||
1192 | { | |||
1193 | sal_Int64 value = 0; | |||
1194 | sal_Int32 i, count = 0, len = aNumberString.getLength(); | |||
1195 | const sal_Unicode *src = aNumberString.getStr(); | |||
1196 | ||||
1197 | for (i = 0; i < len; i++) { | |||
1198 | sal_Unicode ch = src[i]; | |||
1199 | if (isNumber(ch)( NumberChar[NumberChar_HalfWidth][0] <= ch && ch <= NumberChar[NumberChar_HalfWidth][9] )) { | |||
1200 | if (++count >= 8) // Number is too long, could not be handled. | |||
1201 | return aNumberString; | |||
1202 | value = value * 10 + (ch - NUMBER_ZERONumberChar[NumberChar_HalfWidth][0]); | |||
1203 | } | |||
1204 | else if (isSeparator(ch)( ch == SeparatorChar[NumberChar_HalfWidth] ) && count > 0) continue; | |||
1205 | else if (isMinus(ch)( ch == MinusChar[NumberChar_HalfWidth] ) && count == 0) continue; | |||
1206 | else break; | |||
1207 | } | |||
1208 | ||||
1209 | if (value > 0) { | |||
1210 | OUStringBuffer output(count*2 + 2 + len - i); | |||
1211 | ||||
1212 | makeCyrillicNumber(value, output, true); | |||
1213 | ||||
1214 | if (i < len) | |||
1215 | output.append(std::u16string_view(aNumberString).substr(i)); | |||
1216 | ||||
1217 | return output.makeStringAndClear(); | |||
1218 | } | |||
1219 | else | |||
1220 | return aNumberString; | |||
1221 | } | |||
1222 | ||||
1223 | const char implementationName[] = "com.sun.star.i18n.NativeNumberSupplier"; | |||
1224 | ||||
1225 | OUString SAL_CALL NativeNumberSupplierService::getImplementationName() | |||
1226 | { | |||
1227 | return implementationName; | |||
1228 | } | |||
1229 | ||||
1230 | sal_Bool SAL_CALL | |||
1231 | NativeNumberSupplierService::supportsService(const OUString& rServiceName) | |||
1232 | { | |||
1233 | return cppu::supportsService(this, rServiceName); | |||
1234 | } | |||
1235 | ||||
1236 | Sequence< OUString > SAL_CALL | |||
1237 | NativeNumberSupplierService::getSupportedServiceNames() | |||
1238 | { | |||
1239 | return {implementationName, "com.sun.star.i18n.NativeNumberSupplier2"}; | |||
1240 | } | |||
1241 | ||||
1242 | } | |||
1243 | ||||
1244 | extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface * | |||
1245 | com_sun_star_i18n_NativeNumberSupplier_get_implementation( | |||
1246 | css::uno::XComponentContext *, | |||
1247 | css::uno::Sequence<css::uno::Any> const &) | |||
1248 | { | |||
1249 | return cppu::acquire(new i18npool::NativeNumberSupplierService()); | |||
1250 | } | |||
1251 | ||||
1252 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | #ifndef INCLUDED_RTL_USTRING_HXX | ||||||||||||||||
21 | #define INCLUDED_RTL_USTRING_HXX | ||||||||||||||||
22 | |||||||||||||||||
23 | #include "sal/config.h" | ||||||||||||||||
24 | |||||||||||||||||
25 | #include <cassert> | ||||||||||||||||
26 | #include <cstddef> | ||||||||||||||||
27 | #include <cstdlib> | ||||||||||||||||
28 | #include <limits> | ||||||||||||||||
29 | #include <new> | ||||||||||||||||
30 | #include <ostream> | ||||||||||||||||
31 | #include <utility> | ||||||||||||||||
32 | |||||||||||||||||
33 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
34 | #include <string_view> | ||||||||||||||||
35 | #include <type_traits> | ||||||||||||||||
36 | #endif | ||||||||||||||||
37 | |||||||||||||||||
38 | #include "rtl/ustring.h" | ||||||||||||||||
39 | #include "rtl/string.hxx" | ||||||||||||||||
40 | #include "rtl/stringutils.hxx" | ||||||||||||||||
41 | #include "rtl/textenc.h" | ||||||||||||||||
42 | |||||||||||||||||
43 | #ifdef LIBO_INTERNAL_ONLY1 // "RTL_FAST_STRING" | ||||||||||||||||
44 | #include "config_global.h" | ||||||||||||||||
45 | #include "rtl/stringconcat.hxx" | ||||||||||||||||
46 | #endif | ||||||||||||||||
47 | |||||||||||||||||
48 | #ifdef RTL_STRING_UNITTEST | ||||||||||||||||
49 | extern bool rtl_string_unittest_invalid_conversion; | ||||||||||||||||
50 | #endif | ||||||||||||||||
51 | |||||||||||||||||
52 | // The unittest uses slightly different code to help check that the proper | ||||||||||||||||
53 | // calls are made. The class is put into a different namespace to make | ||||||||||||||||
54 | // sure the compiler generates a different (if generating also non-inline) | ||||||||||||||||
55 | // copy of the function and does not merge them together. The class | ||||||||||||||||
56 | // is "brought" into the proper rtl namespace by a typedef below. | ||||||||||||||||
57 | #ifdef RTL_STRING_UNITTEST | ||||||||||||||||
58 | #define rtl rtlunittest | ||||||||||||||||
59 | #endif | ||||||||||||||||
60 | |||||||||||||||||
61 | namespace rtl | ||||||||||||||||
62 | { | ||||||||||||||||
63 | |||||||||||||||||
64 | class OUStringBuffer; | ||||||||||||||||
65 | |||||||||||||||||
66 | #ifdef RTL_STRING_UNITTEST | ||||||||||||||||
67 | #undef rtl | ||||||||||||||||
68 | #endif | ||||||||||||||||
69 | |||||||||||||||||
70 | #if defined LIBO_INTERNAL_ONLY1 // "RTL_FAST_STRING" | ||||||||||||||||
71 | /// @cond INTERNAL | ||||||||||||||||
72 | |||||||||||||||||
73 | /** | ||||||||||||||||
74 | A wrapper dressing a string literal as a static-refcount rtl_uString. | ||||||||||||||||
75 | |||||||||||||||||
76 | This class is not part of public API and is meant to be used only in LibreOffice code. | ||||||||||||||||
77 | @since LibreOffice 4.0 | ||||||||||||||||
78 | */ | ||||||||||||||||
79 | template<std::size_t N> class SAL_WARN_UNUSED__attribute__((warn_unused)) OUStringLiteral { | ||||||||||||||||
80 | static_assert(N != 0); | ||||||||||||||||
81 | static_assert(N - 1 <= std::numeric_limits<sal_Int32>::max(), "literal too long"); | ||||||||||||||||
82 | |||||||||||||||||
83 | public: | ||||||||||||||||
84 | #if HAVE_CPP_CONSTEVAL0 | ||||||||||||||||
85 | consteval | ||||||||||||||||
86 | #else | ||||||||||||||||
87 | constexpr | ||||||||||||||||
88 | #endif | ||||||||||||||||
89 | OUStringLiteral(char16_t const (&literal)[N]) { | ||||||||||||||||
90 | assertLayout(); | ||||||||||||||||
91 | assert(literal[N - 1] == '\0')(static_cast <bool> (literal[N - 1] == '\0') ? void (0) : __assert_fail ("literal[N - 1] == '\\0'", "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 91, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
92 | //TODO: Use C++20 constexpr std::copy_n (P0202R3): | ||||||||||||||||
93 | for (std::size_t i = 0; i != N; ++i) { | ||||||||||||||||
94 | buffer[i] = literal[i]; | ||||||||||||||||
95 | } | ||||||||||||||||
96 | } | ||||||||||||||||
97 | |||||||||||||||||
98 | constexpr sal_Int32 getLength() const { return length; } | ||||||||||||||||
99 | |||||||||||||||||
100 | constexpr sal_Unicode const * getStr() const SAL_RETURNS_NONNULL__attribute__((returns_nonnull)) { return buffer; } | ||||||||||||||||
101 | |||||||||||||||||
102 | constexpr operator std::u16string_view() const { return {buffer, sal_uInt32(length)}; } | ||||||||||||||||
103 | |||||||||||||||||
104 | private: | ||||||||||||||||
105 | static constexpr void assertLayout() { | ||||||||||||||||
106 | // These static_asserts verifying the layout compatibility with rtl_uString cannot be class | ||||||||||||||||
107 | // member declarations, as offsetof requires a complete type, so defer them to here: | ||||||||||||||||
108 | static_assert(offsetof(OUStringLiteral, refCount)__builtin_offsetof(OUStringLiteral, refCount) == offsetof(rtl_uString, refCount)__builtin_offsetof(rtl_uString, refCount)); | ||||||||||||||||
109 | static_assert(std::is_same_v<decltype(refCount), decltype(rtl_uString::refCount)>); | ||||||||||||||||
110 | static_assert(offsetof(OUStringLiteral, length)__builtin_offsetof(OUStringLiteral, length) == offsetof(rtl_uString, length)__builtin_offsetof(rtl_uString, length)); | ||||||||||||||||
111 | static_assert(std::is_same_v<decltype(length), decltype(rtl_uString::length)>); | ||||||||||||||||
112 | static_assert(offsetof(OUStringLiteral, buffer)__builtin_offsetof(OUStringLiteral, buffer) == offsetof(rtl_uString, buffer)__builtin_offsetof(rtl_uString, buffer)); | ||||||||||||||||
113 | static_assert( | ||||||||||||||||
114 | std::is_same_v< | ||||||||||||||||
115 | std::remove_extent_t<decltype(buffer)>, | ||||||||||||||||
116 | std::remove_extent_t<decltype(rtl_uString::buffer)>>); | ||||||||||||||||
117 | } | ||||||||||||||||
118 | |||||||||||||||||
119 | // Same layout as rtl_uString (include/rtl/ustring.h): | ||||||||||||||||
120 | oslInterlockedCount refCount = 0x40000000; // SAL_STRING_STATIC_FLAG (sal/rtl/strimp.hxx) | ||||||||||||||||
121 | sal_Int32 length = N - 1; | ||||||||||||||||
122 | sal_Unicode buffer[N] = {}; //TODO: drop initialization for C++20 (P1331R2) | ||||||||||||||||
123 | }; | ||||||||||||||||
124 | |||||||||||||||||
125 | #if defined RTL_STRING_UNITTEST | ||||||||||||||||
126 | namespace libreoffice_internal { | ||||||||||||||||
127 | template<std::size_t N> struct ExceptConstCharArrayDetector<OUStringLiteral<N>> {}; | ||||||||||||||||
128 | template<std::size_t N> struct ExceptCharArrayDetector<OUStringLiteral<N>> {}; | ||||||||||||||||
129 | } | ||||||||||||||||
130 | #endif | ||||||||||||||||
131 | |||||||||||||||||
132 | /// @endcond | ||||||||||||||||
133 | #endif | ||||||||||||||||
134 | |||||||||||||||||
135 | /* ======================================================================= */ | ||||||||||||||||
136 | |||||||||||||||||
137 | /** | ||||||||||||||||
138 | This String class provides base functionality for C++ like Unicode | ||||||||||||||||
139 | character array handling. The advantage of this class is that it | ||||||||||||||||
140 | handles all the memory management for you - and it does it | ||||||||||||||||
141 | more efficiently. If you assign a string to another string, the | ||||||||||||||||
142 | data of both strings are shared (without any copy operation or | ||||||||||||||||
143 | memory allocation) as long as you do not change the string. This class | ||||||||||||||||
144 | also stores the length of the string, so that many operations are | ||||||||||||||||
145 | faster than the C-str-functions. | ||||||||||||||||
146 | |||||||||||||||||
147 | This class provides only readonly string handling. So you could create | ||||||||||||||||
148 | a string and you could only query the content from this string. | ||||||||||||||||
149 | It provides also functionality to change the string, but this results | ||||||||||||||||
150 | in every case in a new string instance (in the most cases with a | ||||||||||||||||
151 | memory allocation). You don't have functionality to change the | ||||||||||||||||
152 | content of the string. If you want to change the string content, then | ||||||||||||||||
153 | you should use the OStringBuffer class, which provides these | ||||||||||||||||
154 | functionalities and avoids too much memory allocation. | ||||||||||||||||
155 | |||||||||||||||||
156 | The design of this class is similar to the string classes in Java so | ||||||||||||||||
157 | less people should have understanding problems when they use this class. | ||||||||||||||||
158 | */ | ||||||||||||||||
159 | |||||||||||||||||
160 | class SAL_WARN_UNUSED__attribute__((warn_unused)) SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) OUString | ||||||||||||||||
161 | { | ||||||||||||||||
162 | public: | ||||||||||||||||
163 | /// @cond INTERNAL | ||||||||||||||||
164 | rtl_uString * pData; | ||||||||||||||||
165 | /// @endcond | ||||||||||||||||
166 | |||||||||||||||||
167 | /** | ||||||||||||||||
168 | New string containing no characters. | ||||||||||||||||
169 | */ | ||||||||||||||||
170 | OUString() | ||||||||||||||||
171 | { | ||||||||||||||||
172 | pData = NULL__null; | ||||||||||||||||
173 | rtl_uString_new( &pData ); | ||||||||||||||||
174 | } | ||||||||||||||||
175 | |||||||||||||||||
176 | /** | ||||||||||||||||
177 | New string from OUString. | ||||||||||||||||
178 | |||||||||||||||||
179 | @param str an OUString. | ||||||||||||||||
180 | */ | ||||||||||||||||
181 | OUString( const OUString & str ) | ||||||||||||||||
182 | { | ||||||||||||||||
183 | pData = str.pData; | ||||||||||||||||
184 | rtl_uString_acquire( pData ); | ||||||||||||||||
185 | } | ||||||||||||||||
186 | |||||||||||||||||
187 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
188 | /** | ||||||||||||||||
189 | Move constructor. | ||||||||||||||||
190 | |||||||||||||||||
191 | @param str an OUString. | ||||||||||||||||
192 | @since LibreOffice 5.2 | ||||||||||||||||
193 | */ | ||||||||||||||||
194 | OUString( OUString && str ) noexcept | ||||||||||||||||
195 | { | ||||||||||||||||
196 | pData = str.pData; | ||||||||||||||||
197 | str.pData = nullptr; | ||||||||||||||||
198 | rtl_uString_new( &str.pData ); | ||||||||||||||||
199 | } | ||||||||||||||||
200 | #endif | ||||||||||||||||
201 | |||||||||||||||||
202 | /** | ||||||||||||||||
203 | New string from OUString data. | ||||||||||||||||
204 | |||||||||||||||||
205 | @param str an OUString data. | ||||||||||||||||
206 | */ | ||||||||||||||||
207 | OUString( rtl_uString * str ) | ||||||||||||||||
208 | { | ||||||||||||||||
209 | pData = str; | ||||||||||||||||
210 | rtl_uString_acquire( pData ); | ||||||||||||||||
211 | } | ||||||||||||||||
212 | |||||||||||||||||
213 | /** New OUString from OUString data without acquiring it. Takeover of ownership. | ||||||||||||||||
214 | |||||||||||||||||
215 | The SAL_NO_ACQUIRE dummy parameter is only there to distinguish this | ||||||||||||||||
216 | from other constructors. | ||||||||||||||||
217 | |||||||||||||||||
218 | @param str | ||||||||||||||||
219 | OUString data | ||||||||||||||||
220 | */ | ||||||||||||||||
221 | OUString( rtl_uString * str, __sal_NoAcquire ) | ||||||||||||||||
222 | { pData = str; } | ||||||||||||||||
223 | |||||||||||||||||
224 | /** | ||||||||||||||||
225 | New string from a single Unicode character. | ||||||||||||||||
226 | |||||||||||||||||
227 | @param value a Unicode character. | ||||||||||||||||
228 | */ | ||||||||||||||||
229 | explicit OUString( sal_Unicode value ) | ||||||||||||||||
230 | : pData (NULL__null) | ||||||||||||||||
231 | { | ||||||||||||||||
232 | rtl_uString_newFromStr_WithLength( &pData, &value, 1 ); | ||||||||||||||||
233 | } | ||||||||||||||||
234 | |||||||||||||||||
235 | #if defined LIBO_INTERNAL_ONLY1 && !defined RTL_STRING_UNITTEST_CONCAT | ||||||||||||||||
236 | /// @cond INTERNAL | ||||||||||||||||
237 | // Catch inadvertent conversions to the above ctor (but still allow | ||||||||||||||||
238 | // construction from char literals): | ||||||||||||||||
239 | OUString(int) = delete; | ||||||||||||||||
240 | explicit OUString(char c): | ||||||||||||||||
241 | OUString(sal_Unicode(static_cast<unsigned char>(c))) | ||||||||||||||||
242 | {} | ||||||||||||||||
243 | /// @endcond | ||||||||||||||||
244 | #endif | ||||||||||||||||
245 | |||||||||||||||||
246 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
247 | |||||||||||||||||
248 | template<typename T> explicit OUString( | ||||||||||||||||
249 | T const & value, | ||||||||||||||||
250 | typename libreoffice_internal::CharPtrDetector<T, libreoffice_internal::Dummy>::TypeUtf16 | ||||||||||||||||
251 | = libreoffice_internal::Dummy()): | ||||||||||||||||
252 | pData(nullptr) | ||||||||||||||||
253 | { rtl_uString_newFromStr(&pData, value); } | ||||||||||||||||
254 | |||||||||||||||||
255 | template<typename T> explicit OUString( | ||||||||||||||||
256 | T & value, | ||||||||||||||||
257 | typename | ||||||||||||||||
258 | libreoffice_internal::NonConstCharArrayDetector<T, libreoffice_internal::Dummy>::TypeUtf16 | ||||||||||||||||
259 | = libreoffice_internal::Dummy()): | ||||||||||||||||
260 | pData(nullptr) | ||||||||||||||||
261 | { rtl_uString_newFromStr(&pData, value); } | ||||||||||||||||
262 | |||||||||||||||||
263 | #else | ||||||||||||||||
264 | |||||||||||||||||
265 | /** | ||||||||||||||||
266 | New string from a Unicode character buffer array. | ||||||||||||||||
267 | |||||||||||||||||
268 | @param value a NULL-terminated Unicode character array. | ||||||||||||||||
269 | */ | ||||||||||||||||
270 | OUString( const sal_Unicode * value ) | ||||||||||||||||
271 | { | ||||||||||||||||
272 | pData = NULL__null; | ||||||||||||||||
273 | rtl_uString_newFromStr( &pData, value ); | ||||||||||||||||
274 | } | ||||||||||||||||
275 | |||||||||||||||||
276 | #endif | ||||||||||||||||
277 | |||||||||||||||||
278 | /** | ||||||||||||||||
279 | New string from a Unicode character buffer array. | ||||||||||||||||
280 | |||||||||||||||||
281 | @param value a Unicode character array. | ||||||||||||||||
282 | @param length the number of character which should be copied. | ||||||||||||||||
283 | The character array length must be greater than | ||||||||||||||||
284 | or equal to this value. | ||||||||||||||||
285 | */ | ||||||||||||||||
286 | OUString( const sal_Unicode * value, sal_Int32 length ) | ||||||||||||||||
287 | { | ||||||||||||||||
288 | pData = NULL__null; | ||||||||||||||||
289 | rtl_uString_newFromStr_WithLength( &pData, value, length ); | ||||||||||||||||
290 | } | ||||||||||||||||
291 | |||||||||||||||||
292 | /** | ||||||||||||||||
293 | New string from an 8-Bit string literal that is expected to contain only | ||||||||||||||||
294 | characters in the ASCII set (i.e. first 128 characters). This constructor | ||||||||||||||||
295 | allows an efficient and convenient way to create OUString | ||||||||||||||||
296 | instances from ASCII literals. When creating strings from data that | ||||||||||||||||
297 | is not pure ASCII, it needs to be converted to OUString by explicitly | ||||||||||||||||
298 | providing the encoding to use for the conversion. | ||||||||||||||||
299 | |||||||||||||||||
300 | If there are any embedded \0's in the string literal, the result is undefined. | ||||||||||||||||
301 | Use the overload that explicitly accepts length. | ||||||||||||||||
302 | |||||||||||||||||
303 | @param literal the 8-bit ASCII string literal | ||||||||||||||||
304 | |||||||||||||||||
305 | @since LibreOffice 3.6 | ||||||||||||||||
306 | */ | ||||||||||||||||
307 | template< typename T > | ||||||||||||||||
308 | OUString( T& literal, typename libreoffice_internal::ConstCharArrayDetector< T, libreoffice_internal::Dummy >::Type = libreoffice_internal::Dummy() ) | ||||||||||||||||
309 | { | ||||||||||||||||
310 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 311, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||||||
311 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 311, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
312 | pData = NULL__null; | ||||||||||||||||
313 | if (libreoffice_internal::ConstCharArrayDetector<T>::length == 0) { | ||||||||||||||||
314 | rtl_uString_new(&pData); | ||||||||||||||||
315 | } else { | ||||||||||||||||
316 | rtl_uString_newFromLiteral( | ||||||||||||||||
317 | &pData, | ||||||||||||||||
318 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( | ||||||||||||||||
319 | literal), | ||||||||||||||||
320 | libreoffice_internal::ConstCharArrayDetector<T>::length, 0); | ||||||||||||||||
321 | } | ||||||||||||||||
322 | #ifdef RTL_STRING_UNITTEST | ||||||||||||||||
323 | rtl_string_unittest_const_literal = true; | ||||||||||||||||
324 | #endif | ||||||||||||||||
325 | } | ||||||||||||||||
326 | |||||||||||||||||
327 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
328 | /** @overload @since LibreOffice 5.3 */ | ||||||||||||||||
329 | template<typename T> OUString( | ||||||||||||||||
330 | T & literal, | ||||||||||||||||
331 | typename libreoffice_internal::ConstCharArrayDetector< | ||||||||||||||||
332 | T, libreoffice_internal::Dummy>::TypeUtf16 | ||||||||||||||||
333 | = libreoffice_internal::Dummy()): | ||||||||||||||||
334 | pData(nullptr) | ||||||||||||||||
335 | { | ||||||||||||||||
336 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 337, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||||||
337 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 337, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
338 | if (libreoffice_internal::ConstCharArrayDetector<T>::length == 0) { | ||||||||||||||||
339 | rtl_uString_new(&pData); | ||||||||||||||||
340 | } else { | ||||||||||||||||
341 | rtl_uString_newFromStr_WithLength( | ||||||||||||||||
342 | &pData, | ||||||||||||||||
343 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( | ||||||||||||||||
344 | literal), | ||||||||||||||||
345 | libreoffice_internal::ConstCharArrayDetector<T>::length); | ||||||||||||||||
346 | } | ||||||||||||||||
347 | } | ||||||||||||||||
348 | #endif | ||||||||||||||||
349 | |||||||||||||||||
350 | #if defined LIBO_INTERNAL_ONLY1 && defined RTL_STRING_UNITTEST | ||||||||||||||||
351 | /// @cond INTERNAL | ||||||||||||||||
352 | /** | ||||||||||||||||
353 | * Only used by unittests to detect incorrect conversions. | ||||||||||||||||
354 | * @internal | ||||||||||||||||
355 | */ | ||||||||||||||||
356 | template< typename T > | ||||||||||||||||
357 | OUString( T&, typename libreoffice_internal::ExceptConstCharArrayDetector< T >::Type = libreoffice_internal::Dummy() ) | ||||||||||||||||
358 | { | ||||||||||||||||
359 | pData = NULL__null; | ||||||||||||||||
360 | rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage | ||||||||||||||||
361 | rtl_string_unittest_invalid_conversion = true; | ||||||||||||||||
362 | } | ||||||||||||||||
363 | /** | ||||||||||||||||
364 | * Only used by unittests to detect incorrect conversions. | ||||||||||||||||
365 | * @internal | ||||||||||||||||
366 | */ | ||||||||||||||||
367 | template< typename T > | ||||||||||||||||
368 | OUString( const T&, typename libreoffice_internal::ExceptCharArrayDetector< T >::Type = libreoffice_internal::Dummy() ) | ||||||||||||||||
369 | { | ||||||||||||||||
370 | pData = NULL__null; | ||||||||||||||||
371 | rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage | ||||||||||||||||
372 | rtl_string_unittest_invalid_conversion = true; | ||||||||||||||||
373 | } | ||||||||||||||||
374 | /// @endcond | ||||||||||||||||
375 | #endif | ||||||||||||||||
376 | |||||||||||||||||
377 | #ifdef LIBO_INTERNAL_ONLY1 // "RTL_FAST_STRING" | ||||||||||||||||
378 | /// @cond INTERNAL | ||||||||||||||||
379 | /** | ||||||||||||||||
380 | New string from a string literal. | ||||||||||||||||
381 | |||||||||||||||||
382 | @since LibreOffice 5.0 | ||||||||||||||||
383 | */ | ||||||||||||||||
384 | template<std::size_t N> OUString(OUStringLiteral<N> const & literal): | ||||||||||||||||
385 | pData(const_cast<rtl_uString *>(reinterpret_cast<rtl_uString const *>(&literal))) {} | ||||||||||||||||
386 | template<std::size_t N> OUString(OUStringLiteral<N> &&) = delete; | ||||||||||||||||
387 | /// @endcond | ||||||||||||||||
388 | #endif | ||||||||||||||||
389 | |||||||||||||||||
390 | /** | ||||||||||||||||
391 | New string from an 8-Bit character buffer array. | ||||||||||||||||
392 | |||||||||||||||||
393 | @param value An 8-Bit character array. | ||||||||||||||||
394 | @param length The number of character which should be converted. | ||||||||||||||||
395 | The 8-Bit character array length must be | ||||||||||||||||
396 | greater than or equal to this value. | ||||||||||||||||
397 | @param encoding The text encoding from which the 8-Bit character | ||||||||||||||||
398 | sequence should be converted. | ||||||||||||||||
399 | @param convertFlags Flags which control the conversion. | ||||||||||||||||
400 | see RTL_TEXTTOUNICODE_FLAGS_... | ||||||||||||||||
401 | |||||||||||||||||
402 | @exception std::bad_alloc is thrown if an out-of-memory condition occurs | ||||||||||||||||
403 | */ | ||||||||||||||||
404 | OUString( const char * value, sal_Int32 length, | ||||||||||||||||
405 | rtl_TextEncoding encoding, | ||||||||||||||||
406 | sal_uInt32 convertFlags = OSTRING_TO_OUSTRING_CVTFLAGS(((sal_uInt32)0x0003) | ((sal_uInt32)0x0030) | ((sal_uInt32)0x0300 )) ) | ||||||||||||||||
407 | { | ||||||||||||||||
408 | pData = NULL__null; | ||||||||||||||||
409 | rtl_string2UString( &pData, value, length, encoding, convertFlags ); | ||||||||||||||||
410 | if (pData == NULL__null) { | ||||||||||||||||
411 | throw std::bad_alloc(); | ||||||||||||||||
412 | } | ||||||||||||||||
413 | } | ||||||||||||||||
414 | |||||||||||||||||
415 | /** Create a new string from an array of Unicode code points. | ||||||||||||||||
416 | |||||||||||||||||
417 | @param codePoints | ||||||||||||||||
418 | an array of at least codePointCount code points, which each must be in | ||||||||||||||||
419 | the range from 0 to 0x10FFFF, inclusive. May be null if codePointCount | ||||||||||||||||
420 | is zero. | ||||||||||||||||
421 | |||||||||||||||||
422 | @param codePointCount | ||||||||||||||||
423 | the non-negative number of code points. | ||||||||||||||||
424 | |||||||||||||||||
425 | @exception std::bad_alloc | ||||||||||||||||
426 | is thrown if either an out-of-memory condition occurs or the resulting | ||||||||||||||||
427 | number of UTF-16 code units would have been larger than SAL_MAX_INT32. | ||||||||||||||||
428 | |||||||||||||||||
429 | @since UDK 3.2.7 | ||||||||||||||||
430 | */ | ||||||||||||||||
431 | explicit OUString( | ||||||||||||||||
432 | sal_uInt32 const * codePoints, sal_Int32 codePointCount): | ||||||||||||||||
433 | pData(NULL__null) | ||||||||||||||||
434 | { | ||||||||||||||||
435 | rtl_uString_newFromCodePoints(&pData, codePoints, codePointCount); | ||||||||||||||||
436 | if (pData == NULL__null) { | ||||||||||||||||
437 | throw std::bad_alloc(); | ||||||||||||||||
438 | } | ||||||||||||||||
439 | } | ||||||||||||||||
440 | |||||||||||||||||
441 | #ifdef LIBO_INTERNAL_ONLY1 // "RTL_FAST_STRING" | ||||||||||||||||
442 | /** | ||||||||||||||||
443 | @overload | ||||||||||||||||
444 | @internal | ||||||||||||||||
445 | */ | ||||||||||||||||
446 | template< typename T1, typename T2 > | ||||||||||||||||
447 | OUString( OUStringConcat< T1, T2 >&& c ) | ||||||||||||||||
448 | { | ||||||||||||||||
449 | const sal_Int32 l = c.length(); | ||||||||||||||||
450 | pData = rtl_uString_alloc( l ); | ||||||||||||||||
451 | if (l != 0) | ||||||||||||||||
452 | { | ||||||||||||||||
453 | sal_Unicode* end = c.addData( pData->buffer ); | ||||||||||||||||
454 | pData->length = l; | ||||||||||||||||
455 | *end = '\0'; | ||||||||||||||||
456 | // TODO realloc in case pData->length is noticeably smaller than l? | ||||||||||||||||
457 | } | ||||||||||||||||
458 | } | ||||||||||||||||
459 | |||||||||||||||||
460 | /** | ||||||||||||||||
461 | @overload | ||||||||||||||||
462 | @internal | ||||||||||||||||
463 | */ | ||||||||||||||||
464 | template< typename T > | ||||||||||||||||
465 | OUString( OUStringNumber< T >&& n ) | ||||||||||||||||
466 | : OUString( n.buf, n.length ) | ||||||||||||||||
467 | {} | ||||||||||||||||
468 | #endif | ||||||||||||||||
469 | |||||||||||||||||
470 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
471 | OUString(std::u16string_view sv) { | ||||||||||||||||
472 | if (sv.size() > sal_uInt32(std::numeric_limits<sal_Int32>::max())) { | ||||||||||||||||
473 | throw std::bad_alloc(); | ||||||||||||||||
474 | } | ||||||||||||||||
475 | pData = nullptr; | ||||||||||||||||
476 | rtl_uString_newFromStr_WithLength(&pData, sv.data(), sv.size()); | ||||||||||||||||
477 | } | ||||||||||||||||
478 | #endif | ||||||||||||||||
479 | |||||||||||||||||
480 | /** | ||||||||||||||||
481 | Release the string data. | ||||||||||||||||
482 | */ | ||||||||||||||||
483 | ~OUString() | ||||||||||||||||
484 | { | ||||||||||||||||
485 | rtl_uString_release( pData ); | ||||||||||||||||
486 | } | ||||||||||||||||
487 | |||||||||||||||||
488 | /** Provides an OUString const & passing a storage pointer of an | ||||||||||||||||
489 | rtl_uString * handle. | ||||||||||||||||
490 | It is more convenient to use C++ OUString member functions when dealing | ||||||||||||||||
491 | with rtl_uString * handles. Using this function avoids unnecessary | ||||||||||||||||
492 | acquire()/release() calls for a temporary OUString object. | ||||||||||||||||
493 | |||||||||||||||||
494 | @param ppHandle | ||||||||||||||||
495 | pointer to storage | ||||||||||||||||
496 | @return | ||||||||||||||||
497 | OUString const & based on given storage | ||||||||||||||||
498 | */ | ||||||||||||||||
499 | static OUString const & unacquired( rtl_uString * const * ppHandle ) | ||||||||||||||||
500 | { return * reinterpret_cast< OUString const * >( ppHandle ); } | ||||||||||||||||
501 | |||||||||||||||||
502 | /** | ||||||||||||||||
503 | Assign a new string. | ||||||||||||||||
504 | |||||||||||||||||
505 | @param str an OUString. | ||||||||||||||||
506 | */ | ||||||||||||||||
507 | OUString & operator=( const OUString & str ) | ||||||||||||||||
508 | { | ||||||||||||||||
509 | rtl_uString_assign( &pData, str.pData ); | ||||||||||||||||
510 | return *this; | ||||||||||||||||
511 | } | ||||||||||||||||
512 | |||||||||||||||||
513 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
514 | /** | ||||||||||||||||
515 | Move assign a new string. | ||||||||||||||||
516 | |||||||||||||||||
517 | @param str an OUString. | ||||||||||||||||
518 | @since LibreOffice 5.2 | ||||||||||||||||
519 | */ | ||||||||||||||||
520 | OUString & operator=( OUString && str ) noexcept | ||||||||||||||||
521 | { | ||||||||||||||||
522 | rtl_uString_release( pData ); | ||||||||||||||||
523 | pData = str.pData; | ||||||||||||||||
524 | str.pData = nullptr; | ||||||||||||||||
525 | rtl_uString_new( &str.pData ); | ||||||||||||||||
526 | return *this; | ||||||||||||||||
527 | } | ||||||||||||||||
528 | #endif | ||||||||||||||||
529 | |||||||||||||||||
530 | /** | ||||||||||||||||
531 | Assign a new string from an 8-Bit string literal that is expected to contain only | ||||||||||||||||
532 | characters in the ASCII set (i.e. first 128 characters). This operator | ||||||||||||||||
533 | allows an efficient and convenient way to assign OUString | ||||||||||||||||
534 | instances from ASCII literals. When assigning strings from data that | ||||||||||||||||
535 | is not pure ASCII, it needs to be converted to OUString by explicitly | ||||||||||||||||
536 | providing the encoding to use for the conversion. | ||||||||||||||||
537 | |||||||||||||||||
538 | @param literal the 8-bit ASCII string literal | ||||||||||||||||
539 | |||||||||||||||||
540 | @since LibreOffice 3.6 | ||||||||||||||||
541 | */ | ||||||||||||||||
542 | template< typename T > | ||||||||||||||||
543 | typename libreoffice_internal::ConstCharArrayDetector< T, OUString& >::Type operator=( T& literal ) | ||||||||||||||||
544 | { | ||||||||||||||||
545 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 546, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||||||
546 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 546, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
547 | if (libreoffice_internal::ConstCharArrayDetector<T>::length == 0) { | ||||||||||||||||
548 | rtl_uString_new(&pData); | ||||||||||||||||
549 | } else { | ||||||||||||||||
550 | rtl_uString_newFromLiteral( | ||||||||||||||||
551 | &pData, | ||||||||||||||||
552 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( | ||||||||||||||||
553 | literal), | ||||||||||||||||
554 | libreoffice_internal::ConstCharArrayDetector<T>::length, 0); | ||||||||||||||||
555 | } | ||||||||||||||||
556 | return *this; | ||||||||||||||||
557 | } | ||||||||||||||||
558 | |||||||||||||||||
559 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
560 | /** @overload @since LibreOffice 5.3 */ | ||||||||||||||||
561 | template<typename T> | ||||||||||||||||
562 | typename | ||||||||||||||||
563 | libreoffice_internal::ConstCharArrayDetector<T, OUString &>::TypeUtf16 | ||||||||||||||||
564 | operator =(T & literal) { | ||||||||||||||||
565 | if (libreoffice_internal::ConstCharArrayDetector<T>::length == 0) { | ||||||||||||||||
566 | rtl_uString_new(&pData); | ||||||||||||||||
567 | } else { | ||||||||||||||||
568 | rtl_uString_newFromStr_WithLength( | ||||||||||||||||
569 | &pData, | ||||||||||||||||
570 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( | ||||||||||||||||
571 | literal), | ||||||||||||||||
572 | libreoffice_internal::ConstCharArrayDetector<T>::length); | ||||||||||||||||
573 | } | ||||||||||||||||
574 | return *this; | ||||||||||||||||
575 | } | ||||||||||||||||
576 | |||||||||||||||||
577 | /** @overload @since LibreOffice 5.4 */ | ||||||||||||||||
578 | template<std::size_t N> OUString & operator =(OUStringLiteral<N> const & literal) { | ||||||||||||||||
579 | if (literal.getLength() == 0) { | ||||||||||||||||
580 | rtl_uString_new(&pData); | ||||||||||||||||
581 | } else { | ||||||||||||||||
582 | rtl_uString_newFromStr_WithLength(&pData, literal.getStr(), literal.getLength()); | ||||||||||||||||
583 | } | ||||||||||||||||
584 | return *this; | ||||||||||||||||
585 | } | ||||||||||||||||
586 | |||||||||||||||||
587 | template<typename T> | ||||||||||||||||
588 | OUString & operator =(OUStringNumber<T> && n) { | ||||||||||||||||
589 | // n.length should never be zero, so no need to add an optimization for that case | ||||||||||||||||
590 | rtl_uString_newFromStr_WithLength(&pData, n.buf, n.length); | ||||||||||||||||
591 | return *this; | ||||||||||||||||
592 | } | ||||||||||||||||
593 | |||||||||||||||||
594 | OUString & operator =(std::u16string_view sv) { | ||||||||||||||||
595 | if (sv.empty()) { | ||||||||||||||||
596 | rtl_uString_new(&pData); | ||||||||||||||||
597 | } else { | ||||||||||||||||
598 | rtl_uString_newFromStr_WithLength(&pData, sv.data(), sv.size()); | ||||||||||||||||
599 | } | ||||||||||||||||
600 | return *this; | ||||||||||||||||
601 | } | ||||||||||||||||
602 | #endif | ||||||||||||||||
603 | |||||||||||||||||
604 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
605 | /** | ||||||||||||||||
606 | Append the contents of an OUStringBuffer to this string. | ||||||||||||||||
607 | |||||||||||||||||
608 | @param str an OUStringBuffer. | ||||||||||||||||
609 | |||||||||||||||||
610 | @exception std::bad_alloc is thrown if an out-of-memory condition occurs | ||||||||||||||||
611 | @since LibreOffice 6.2 | ||||||||||||||||
612 | */ | ||||||||||||||||
613 | inline OUString & operator+=( const OUStringBuffer & str ) &; | ||||||||||||||||
614 | #endif | ||||||||||||||||
615 | |||||||||||||||||
616 | /** | ||||||||||||||||
617 | Append a string to this string. | ||||||||||||||||
618 | |||||||||||||||||
619 | @param str an OUString. | ||||||||||||||||
620 | |||||||||||||||||
621 | @exception std::bad_alloc is thrown if an out-of-memory condition occurs | ||||||||||||||||
622 | */ | ||||||||||||||||
623 | OUString & operator+=( const OUString & str ) | ||||||||||||||||
624 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
625 | & | ||||||||||||||||
626 | #endif | ||||||||||||||||
627 | { | ||||||||||||||||
628 | return internalAppend(str.pData); | ||||||||||||||||
629 | } | ||||||||||||||||
630 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
631 | void operator+=(OUString const &) && = delete; | ||||||||||||||||
632 | #endif | ||||||||||||||||
633 | |||||||||||||||||
634 | /** Append an ASCII string literal to this string. | ||||||||||||||||
635 | |||||||||||||||||
636 | @param literal an 8-bit ASCII-only string literal | ||||||||||||||||
637 | |||||||||||||||||
638 | @since LibreOffice 5.1 | ||||||||||||||||
639 | */ | ||||||||||||||||
640 | template<typename T> | ||||||||||||||||
641 | typename libreoffice_internal::ConstCharArrayDetector<T, OUString &>::Type | ||||||||||||||||
642 | operator +=(T & literal) | ||||||||||||||||
643 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
644 | & | ||||||||||||||||
645 | #endif | ||||||||||||||||
646 | { | ||||||||||||||||
647 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 648, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||||||
648 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 648, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
649 | rtl_uString_newConcatAsciiL( | ||||||||||||||||
650 | &pData, pData, | ||||||||||||||||
651 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), | ||||||||||||||||
652 | libreoffice_internal::ConstCharArrayDetector<T>::length); | ||||||||||||||||
653 | return *this; | ||||||||||||||||
654 | } | ||||||||||||||||
655 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
656 | template<typename T> | ||||||||||||||||
657 | typename libreoffice_internal::ConstCharArrayDetector<T, OUString &>::Type | ||||||||||||||||
658 | operator +=(T &) && = delete; | ||||||||||||||||
659 | #endif | ||||||||||||||||
660 | |||||||||||||||||
661 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
662 | /** @overload @since LibreOffice 5.3 */ | ||||||||||||||||
663 | template<typename T> | ||||||||||||||||
664 | typename | ||||||||||||||||
665 | libreoffice_internal::ConstCharArrayDetector<T, OUString &>::TypeUtf16 | ||||||||||||||||
666 | operator +=(T & literal) & { | ||||||||||||||||
667 | rtl_uString_newConcatUtf16L( | ||||||||||||||||
668 | &pData, pData, | ||||||||||||||||
669 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), | ||||||||||||||||
670 | libreoffice_internal::ConstCharArrayDetector<T>::length); | ||||||||||||||||
671 | return *this; | ||||||||||||||||
672 | } | ||||||||||||||||
673 | template<typename T> | ||||||||||||||||
674 | typename | ||||||||||||||||
675 | libreoffice_internal::ConstCharArrayDetector<T, OUString &>::TypeUtf16 | ||||||||||||||||
676 | operator +=(T &) && = delete; | ||||||||||||||||
677 | |||||||||||||||||
678 | /** @overload @since LibreOffice 5.4 */ | ||||||||||||||||
679 | template<std::size_t N> OUString & operator +=(OUStringLiteral<N> const & literal) & { | ||||||||||||||||
680 | rtl_uString_newConcatUtf16L(&pData, pData, literal.getStr(), literal.getLength()); | ||||||||||||||||
681 | return *this; | ||||||||||||||||
682 | } | ||||||||||||||||
683 | template<std::size_t N> void operator +=(OUStringLiteral<N> const &) && = delete; | ||||||||||||||||
684 | |||||||||||||||||
685 | OUString & operator +=(std::u16string_view sv) & { | ||||||||||||||||
686 | if (sv.size() > sal_uInt32(std::numeric_limits<sal_Int32>::max())) { | ||||||||||||||||
687 | throw std::bad_alloc(); | ||||||||||||||||
688 | } | ||||||||||||||||
689 | rtl_uString_newConcatUtf16L(&pData, pData, sv.data(), sv.size()); | ||||||||||||||||
690 | return *this; | ||||||||||||||||
691 | } | ||||||||||||||||
692 | void operator +=(std::u16string_view) && = delete; | ||||||||||||||||
693 | #endif | ||||||||||||||||
694 | |||||||||||||||||
695 | #ifdef LIBO_INTERNAL_ONLY1 // "RTL_FAST_STRING" | ||||||||||||||||
696 | /** | ||||||||||||||||
697 | @overload | ||||||||||||||||
698 | @internal | ||||||||||||||||
699 | */ | ||||||||||||||||
700 | template< typename T1, typename T2 > | ||||||||||||||||
701 | OUString& operator+=( OUStringConcat< T1, T2 >&& c ) & { | ||||||||||||||||
702 | sal_Int32 l = c.length(); | ||||||||||||||||
703 | if( l == 0 ) | ||||||||||||||||
704 | return *this; | ||||||||||||||||
705 | l += pData->length; | ||||||||||||||||
706 | rtl_uString_ensureCapacity( &pData, l ); | ||||||||||||||||
707 | sal_Unicode* end = c.addData( pData->buffer + pData->length ); | ||||||||||||||||
708 | *end = '\0'; | ||||||||||||||||
709 | pData->length = l; | ||||||||||||||||
710 | return *this; | ||||||||||||||||
711 | } | ||||||||||||||||
712 | template<typename T1, typename T2> void operator +=( | ||||||||||||||||
713 | OUStringConcat<T1, T2> &&) && = delete; | ||||||||||||||||
714 | |||||||||||||||||
715 | /** | ||||||||||||||||
716 | @overload | ||||||||||||||||
717 | @internal | ||||||||||||||||
718 | */ | ||||||||||||||||
719 | template< typename T > | ||||||||||||||||
720 | OUString& operator+=( OUStringNumber< T >&& n ) & { | ||||||||||||||||
721 | sal_Int32 l = n.length; | ||||||||||||||||
722 | if( l == 0 ) | ||||||||||||||||
723 | return *this; | ||||||||||||||||
724 | l += pData->length; | ||||||||||||||||
725 | rtl_uString_ensureCapacity( &pData, l ); | ||||||||||||||||
726 | sal_Unicode* end = addDataHelper( pData->buffer + pData->length, n.buf, n.length ); | ||||||||||||||||
727 | *end = '\0'; | ||||||||||||||||
728 | pData->length = l; | ||||||||||||||||
729 | return *this; | ||||||||||||||||
730 | } | ||||||||||||||||
731 | template<typename T> void operator +=( | ||||||||||||||||
732 | OUStringNumber<T> &&) && = delete; | ||||||||||||||||
733 | #endif | ||||||||||||||||
734 | |||||||||||||||||
735 | /** | ||||||||||||||||
736 | Clears the string, i.e, makes a zero-character string | ||||||||||||||||
737 | @since LibreOffice 4.4 | ||||||||||||||||
738 | */ | ||||||||||||||||
739 | void clear() | ||||||||||||||||
740 | { | ||||||||||||||||
741 | rtl_uString_new( &pData ); | ||||||||||||||||
742 | } | ||||||||||||||||
743 | |||||||||||||||||
744 | /** | ||||||||||||||||
745 | Returns the length of this string. | ||||||||||||||||
746 | |||||||||||||||||
747 | The length is equal to the number of Unicode characters in this string. | ||||||||||||||||
748 | |||||||||||||||||
749 | @return the length of the sequence of characters represented by this | ||||||||||||||||
750 | object. | ||||||||||||||||
751 | */ | ||||||||||||||||
752 | sal_Int32 getLength() const { return pData->length; } | ||||||||||||||||
753 | |||||||||||||||||
754 | /** | ||||||||||||||||
755 | Checks if a string is empty. | ||||||||||||||||
756 | |||||||||||||||||
757 | @return true if the string is empty; | ||||||||||||||||
758 | false, otherwise. | ||||||||||||||||
759 | |||||||||||||||||
760 | @since LibreOffice 3.4 | ||||||||||||||||
761 | */ | ||||||||||||||||
762 | bool isEmpty() const | ||||||||||||||||
763 | { | ||||||||||||||||
764 | return pData->length == 0; | ||||||||||||||||
765 | } | ||||||||||||||||
766 | |||||||||||||||||
767 | /** | ||||||||||||||||
768 | Returns a pointer to the Unicode character buffer for this string. | ||||||||||||||||
769 | |||||||||||||||||
770 | It isn't necessarily NULL terminated. | ||||||||||||||||
771 | |||||||||||||||||
772 | @return a pointer to the Unicode characters buffer for this object. | ||||||||||||||||
773 | */ | ||||||||||||||||
774 | const sal_Unicode * getStr() const SAL_RETURNS_NONNULL__attribute__((returns_nonnull)) { return pData->buffer; } | ||||||||||||||||
775 | |||||||||||||||||
776 | /** | ||||||||||||||||
777 | Access to individual characters. | ||||||||||||||||
778 | |||||||||||||||||
779 | @param index must be non-negative and less than length. | ||||||||||||||||
780 | |||||||||||||||||
781 | @return the character at the given index. | ||||||||||||||||
782 | |||||||||||||||||
783 | @since LibreOffice 3.5 | ||||||||||||||||
784 | */ | ||||||||||||||||
785 | sal_Unicode operator [](sal_Int32 index) const { | ||||||||||||||||
786 | // silence spurious -Werror=strict-overflow warnings from GCC 4.8.2 | ||||||||||||||||
787 | assert(index >= 0 && static_cast<sal_uInt32>(index) < static_cast<sal_uInt32>(getLength()))(static_cast <bool> (index >= 0 && static_cast <sal_uInt32>(index) < static_cast<sal_uInt32>( getLength())) ? void (0) : __assert_fail ("index >= 0 && static_cast<sal_uInt32>(index) < static_cast<sal_uInt32>(getLength())" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 787, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
788 | return getStr()[index]; | ||||||||||||||||
789 | } | ||||||||||||||||
790 | |||||||||||||||||
791 | /** | ||||||||||||||||
792 | Compares two strings. | ||||||||||||||||
793 | |||||||||||||||||
794 | The comparison is based on the numeric value of each character in | ||||||||||||||||
795 | the strings and return a value indicating their relationship. | ||||||||||||||||
796 | This function can't be used for language specific sorting. | ||||||||||||||||
797 | |||||||||||||||||
798 | @param str the object to be compared. | ||||||||||||||||
799 | @return 0 - if both strings are equal | ||||||||||||||||
800 | < 0 - if this string is less than the string argument | ||||||||||||||||
801 | > 0 - if this string is greater than the string argument | ||||||||||||||||
802 | */ | ||||||||||||||||
803 | sal_Int32 compareTo( const OUString & str ) const | ||||||||||||||||
804 | { | ||||||||||||||||
805 | return rtl_ustr_compare_WithLength( pData->buffer, pData->length, | ||||||||||||||||
806 | str.pData->buffer, str.pData->length ); | ||||||||||||||||
807 | } | ||||||||||||||||
808 | |||||||||||||||||
809 | /** | ||||||||||||||||
810 | Compares two strings with a maximum count of characters. | ||||||||||||||||
811 | |||||||||||||||||
812 | The comparison is based on the numeric value of each character in | ||||||||||||||||
813 | the strings and return a value indicating their relationship. | ||||||||||||||||
814 | This function can't be used for language specific sorting. | ||||||||||||||||
815 | |||||||||||||||||
816 | @param str the object to be compared. | ||||||||||||||||
817 | @param maxLength the maximum count of characters to be compared. | ||||||||||||||||
818 | @return 0 - if both strings are equal | ||||||||||||||||
819 | < 0 - if this string is less than the string argument | ||||||||||||||||
820 | > 0 - if this string is greater than the string argument | ||||||||||||||||
821 | |||||||||||||||||
822 | @since UDK 3.2.7 | ||||||||||||||||
823 | */ | ||||||||||||||||
824 | sal_Int32 compareTo( const OUString & str, sal_Int32 maxLength ) const | ||||||||||||||||
825 | { | ||||||||||||||||
826 | return rtl_ustr_shortenedCompare_WithLength( pData->buffer, pData->length, | ||||||||||||||||
827 | str.pData->buffer, str.pData->length, maxLength ); | ||||||||||||||||
828 | } | ||||||||||||||||
829 | |||||||||||||||||
830 | /** | ||||||||||||||||
831 | Compares two strings in reverse order. | ||||||||||||||||
832 | |||||||||||||||||
833 | The comparison is based on the numeric value of each character in | ||||||||||||||||
834 | the strings and return a value indicating their relationship. | ||||||||||||||||
835 | This function can't be used for language specific sorting. | ||||||||||||||||
836 | |||||||||||||||||
837 | @param str the object to be compared. | ||||||||||||||||
838 | @return 0 - if both strings are equal | ||||||||||||||||
839 | < 0 - if this string is less than the string argument | ||||||||||||||||
840 | > 0 - if this string is greater than the string argument | ||||||||||||||||
841 | */ | ||||||||||||||||
842 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
843 | sal_Int32 reverseCompareTo(std::u16string_view sv) const { | ||||||||||||||||
844 | return rtl_ustr_reverseCompare_WithLength( | ||||||||||||||||
845 | pData->buffer, pData->length, sv.data(), sv.size()); | ||||||||||||||||
846 | } | ||||||||||||||||
847 | #else | ||||||||||||||||
848 | sal_Int32 reverseCompareTo( const OUString & str ) const | ||||||||||||||||
849 | { | ||||||||||||||||
850 | return rtl_ustr_reverseCompare_WithLength( pData->buffer, pData->length, | ||||||||||||||||
851 | str.pData->buffer, str.pData->length ); | ||||||||||||||||
852 | } | ||||||||||||||||
853 | #endif | ||||||||||||||||
854 | |||||||||||||||||
855 | /** | ||||||||||||||||
856 | @overload | ||||||||||||||||
857 | This function accepts an ASCII string literal as its argument. | ||||||||||||||||
858 | @since LibreOffice 4.1 | ||||||||||||||||
859 | */ | ||||||||||||||||
860 | template< typename T > | ||||||||||||||||
861 | typename libreoffice_internal::ConstCharArrayDetector< T, sal_Int32 >::Type reverseCompareTo( T& literal ) const | ||||||||||||||||
862 | { | ||||||||||||||||
863 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 864, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||||||
864 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 864, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
865 | return rtl_ustr_asciil_reverseCompare_WithLength( | ||||||||||||||||
866 | pData->buffer, pData->length, | ||||||||||||||||
867 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), | ||||||||||||||||
868 | libreoffice_internal::ConstCharArrayDetector<T>::length); | ||||||||||||||||
869 | } | ||||||||||||||||
870 | |||||||||||||||||
871 | /** | ||||||||||||||||
872 | Perform a comparison of two strings. | ||||||||||||||||
873 | |||||||||||||||||
874 | The result is true if and only if second string | ||||||||||||||||
875 | represents the same sequence of characters as the first string. | ||||||||||||||||
876 | This function can't be used for language specific comparison. | ||||||||||||||||
877 | |||||||||||||||||
878 | @param str the object to be compared. | ||||||||||||||||
879 | @return true if the strings are equal; | ||||||||||||||||
880 | false, otherwise. | ||||||||||||||||
881 | */ | ||||||||||||||||
882 | bool equals( const OUString & str ) const | ||||||||||||||||
883 | { | ||||||||||||||||
884 | if ( pData->length != str.pData->length ) | ||||||||||||||||
885 | return false; | ||||||||||||||||
886 | if ( pData == str.pData ) | ||||||||||||||||
887 | return true; | ||||||||||||||||
888 | return rtl_ustr_reverseCompare_WithLength( pData->buffer, pData->length, | ||||||||||||||||
889 | str.pData->buffer, str.pData->length ) == 0; | ||||||||||||||||
890 | } | ||||||||||||||||
891 | |||||||||||||||||
892 | /** | ||||||||||||||||
893 | Perform an ASCII lowercase comparison of two strings. | ||||||||||||||||
894 | |||||||||||||||||
895 | The result is true if and only if second string | ||||||||||||||||
896 | represents the same sequence of characters as the first string, | ||||||||||||||||
897 | ignoring the case. | ||||||||||||||||
898 | Character values between 65 and 90 (ASCII A-Z) are interpreted as | ||||||||||||||||
899 | values between 97 and 122 (ASCII a-z). | ||||||||||||||||
900 | This function can't be used for language specific comparison. | ||||||||||||||||
901 | |||||||||||||||||
902 | @param str the object to be compared. | ||||||||||||||||
903 | @return true if the strings are equal; | ||||||||||||||||
904 | false, otherwise. | ||||||||||||||||
905 | */ | ||||||||||||||||
906 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
907 | bool equalsIgnoreAsciiCase(std::u16string_view sv) const { | ||||||||||||||||
908 | return | ||||||||||||||||
909 | rtl_ustr_compareIgnoreAsciiCase_WithLength( | ||||||||||||||||
910 | pData->buffer, pData->length, sv.data(), sv.size()) | ||||||||||||||||
911 | == 0; | ||||||||||||||||
912 | } | ||||||||||||||||
913 | #else | ||||||||||||||||
914 | bool equalsIgnoreAsciiCase( const OUString & str ) const | ||||||||||||||||
915 | { | ||||||||||||||||
916 | if ( pData->length != str.pData->length ) | ||||||||||||||||
917 | return false; | ||||||||||||||||
918 | if ( pData == str.pData ) | ||||||||||||||||
919 | return true; | ||||||||||||||||
920 | return rtl_ustr_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, | ||||||||||||||||
921 | str.pData->buffer, str.pData->length ) == 0; | ||||||||||||||||
922 | } | ||||||||||||||||
923 | #endif | ||||||||||||||||
924 | |||||||||||||||||
925 | /** | ||||||||||||||||
926 | Perform an ASCII lowercase comparison of two strings. | ||||||||||||||||
927 | |||||||||||||||||
928 | Compare the two strings with uppercase ASCII | ||||||||||||||||
929 | character values between 65 and 90 (ASCII A-Z) interpreted as | ||||||||||||||||
930 | values between 97 and 122 (ASCII a-z). | ||||||||||||||||
931 | This function can't be used for language specific comparison. | ||||||||||||||||
932 | |||||||||||||||||
933 | @param str the object to be compared. | ||||||||||||||||
934 | @return 0 - if both strings are equal | ||||||||||||||||
935 | < 0 - if this string is less than the string argument | ||||||||||||||||
936 | > 0 - if this string is greater than the string argument | ||||||||||||||||
937 | |||||||||||||||||
938 | @since LibreOffice 4.0 | ||||||||||||||||
939 | */ | ||||||||||||||||
940 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
941 | sal_Int32 compareToIgnoreAsciiCase(std::u16string_view sv) const { | ||||||||||||||||
942 | return rtl_ustr_compareIgnoreAsciiCase_WithLength( | ||||||||||||||||
943 | pData->buffer, pData->length, sv.data(), sv.size()); | ||||||||||||||||
944 | } | ||||||||||||||||
945 | #else | ||||||||||||||||
946 | sal_Int32 compareToIgnoreAsciiCase( const OUString & str ) const | ||||||||||||||||
947 | { | ||||||||||||||||
948 | return rtl_ustr_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, | ||||||||||||||||
949 | str.pData->buffer, str.pData->length ); | ||||||||||||||||
950 | } | ||||||||||||||||
951 | #endif | ||||||||||||||||
952 | |||||||||||||||||
953 | /** | ||||||||||||||||
954 | @overload | ||||||||||||||||
955 | This function accepts an ASCII string literal as its argument. | ||||||||||||||||
956 | @since LibreOffice 3.6 | ||||||||||||||||
957 | */ | ||||||||||||||||
958 | template< typename T > | ||||||||||||||||
959 | typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type equalsIgnoreAsciiCase( T& literal ) const | ||||||||||||||||
960 | { | ||||||||||||||||
961 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 962, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||||||
962 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 962, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
963 | return | ||||||||||||||||
964 | (pData->length | ||||||||||||||||
965 | == libreoffice_internal::ConstCharArrayDetector<T>::length) | ||||||||||||||||
966 | && (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( | ||||||||||||||||
967 | pData->buffer, pData->length, | ||||||||||||||||
968 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( | ||||||||||||||||
969 | literal)) | ||||||||||||||||
970 | == 0); | ||||||||||||||||
971 | } | ||||||||||||||||
972 | |||||||||||||||||
973 | /** | ||||||||||||||||
974 | Match against a substring appearing in this string. | ||||||||||||||||
975 | |||||||||||||||||
976 | The result is true if and only if the second string appears as a substring | ||||||||||||||||
977 | of this string, at the given position. | ||||||||||||||||
978 | This function can't be used for language specific comparison. | ||||||||||||||||
979 | |||||||||||||||||
980 | @param str the object (substring) to be compared. | ||||||||||||||||
981 | @param fromIndex the index to start the comparison from. | ||||||||||||||||
982 | The index must be greater than or equal to 0 | ||||||||||||||||
983 | and less or equal as the string length. | ||||||||||||||||
984 | @return true if str match with the characters in the string | ||||||||||||||||
985 | at the given position; | ||||||||||||||||
986 | false, otherwise. | ||||||||||||||||
987 | */ | ||||||||||||||||
988 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
989 | bool match(std::u16string_view sv, sal_Int32 fromIndex = 0) const { | ||||||||||||||||
990 | return | ||||||||||||||||
991 | rtl_ustr_shortenedCompare_WithLength( | ||||||||||||||||
992 | pData->buffer + fromIndex, pData->length - fromIndex, sv.data(), sv.size(), | ||||||||||||||||
993 | sv.size()) | ||||||||||||||||
994 | == 0; | ||||||||||||||||
995 | } | ||||||||||||||||
996 | #else | ||||||||||||||||
997 | bool match( const OUString & str, sal_Int32 fromIndex = 0 ) const | ||||||||||||||||
998 | { | ||||||||||||||||
999 | return rtl_ustr_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, | ||||||||||||||||
1000 | str.pData->buffer, str.pData->length, str.pData->length ) == 0; | ||||||||||||||||
1001 | } | ||||||||||||||||
1002 | #endif | ||||||||||||||||
1003 | |||||||||||||||||
1004 | /** | ||||||||||||||||
1005 | @overload | ||||||||||||||||
1006 | This function accepts an ASCII string literal as its argument. | ||||||||||||||||
1007 | @since LibreOffice 3.6 | ||||||||||||||||
1008 | */ | ||||||||||||||||
1009 | template< typename T > | ||||||||||||||||
1010 | typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type match( T& literal, sal_Int32 fromIndex = 0 ) const | ||||||||||||||||
1011 | { | ||||||||||||||||
1012 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1013, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||||||
1013 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1013, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
1014 | return | ||||||||||||||||
1015 | rtl_ustr_ascii_shortenedCompare_WithLength( | ||||||||||||||||
1016 | pData->buffer+fromIndex, pData->length-fromIndex, | ||||||||||||||||
1017 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( | ||||||||||||||||
1018 | literal), | ||||||||||||||||
1019 | libreoffice_internal::ConstCharArrayDetector<T>::length) | ||||||||||||||||
1020 | == 0; | ||||||||||||||||
1021 | } | ||||||||||||||||
1022 | |||||||||||||||||
1023 | /** | ||||||||||||||||
1024 | Match against a substring appearing in this string, ignoring the case of | ||||||||||||||||
1025 | ASCII letters. | ||||||||||||||||
1026 | |||||||||||||||||
1027 | The result is true if and only if the second string appears as a substring | ||||||||||||||||
1028 | of this string, at the given position. | ||||||||||||||||
1029 | Character values between 65 and 90 (ASCII A-Z) are interpreted as | ||||||||||||||||
1030 | values between 97 and 122 (ASCII a-z). | ||||||||||||||||
1031 | This function can't be used for language specific comparison. | ||||||||||||||||
1032 | |||||||||||||||||
1033 | @param str the object (substring) to be compared. | ||||||||||||||||
1034 | @param fromIndex the index to start the comparison from. | ||||||||||||||||
1035 | The index must be greater than or equal to 0 | ||||||||||||||||
1036 | and less than or equal to the string length. | ||||||||||||||||
1037 | @return true if str match with the characters in the string | ||||||||||||||||
1038 | at the given position; | ||||||||||||||||
1039 | false, otherwise. | ||||||||||||||||
1040 | */ | ||||||||||||||||
1041 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
1042 | bool matchIgnoreAsciiCase(std::u16string_view sv, sal_Int32 fromIndex = 0) const { | ||||||||||||||||
1043 | return | ||||||||||||||||
1044 | rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( | ||||||||||||||||
1045 | pData->buffer + fromIndex, pData->length - fromIndex, sv.data(), sv.size(), | ||||||||||||||||
1046 | sv.size()) | ||||||||||||||||
1047 | == 0; | ||||||||||||||||
1048 | } | ||||||||||||||||
1049 | #else | ||||||||||||||||
1050 | bool matchIgnoreAsciiCase( const OUString & str, sal_Int32 fromIndex = 0 ) const | ||||||||||||||||
1051 | { | ||||||||||||||||
1052 | return rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, | ||||||||||||||||
1053 | str.pData->buffer, str.pData->length, | ||||||||||||||||
1054 | str.pData->length ) == 0; | ||||||||||||||||
1055 | } | ||||||||||||||||
1056 | #endif | ||||||||||||||||
1057 | |||||||||||||||||
1058 | /** | ||||||||||||||||
1059 | @overload | ||||||||||||||||
1060 | This function accepts an ASCII string literal as its argument. | ||||||||||||||||
1061 | @since LibreOffice 3.6 | ||||||||||||||||
1062 | */ | ||||||||||||||||
1063 | template< typename T > | ||||||||||||||||
1064 | typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type matchIgnoreAsciiCase( T& literal, sal_Int32 fromIndex = 0 ) const | ||||||||||||||||
1065 | { | ||||||||||||||||
1066 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1067, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||||||
1067 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1067, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
1068 | return | ||||||||||||||||
1069 | rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( | ||||||||||||||||
1070 | pData->buffer+fromIndex, pData->length-fromIndex, | ||||||||||||||||
1071 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( | ||||||||||||||||
1072 | literal), | ||||||||||||||||
1073 | libreoffice_internal::ConstCharArrayDetector<T>::length) | ||||||||||||||||
1074 | == 0; | ||||||||||||||||
1075 | } | ||||||||||||||||
1076 | |||||||||||||||||
1077 | /** | ||||||||||||||||
1078 | Compares two strings. | ||||||||||||||||
1079 | |||||||||||||||||
1080 | The comparison is based on the numeric value of each character in | ||||||||||||||||
1081 | the strings and return a value indicating their relationship. | ||||||||||||||||
1082 | Since this method is optimized for performance, the ASCII character | ||||||||||||||||
1083 | values are not converted in any way. The caller has to make sure that | ||||||||||||||||
1084 | all ASCII characters are in the allowed range between 0 and 127. | ||||||||||||||||
1085 | The ASCII string must be NULL-terminated. | ||||||||||||||||
1086 | This function can't be used for language specific sorting. | ||||||||||||||||
1087 | |||||||||||||||||
1088 | @param asciiStr the 8-Bit ASCII character string to be compared. | ||||||||||||||||
1089 | @return 0 - if both strings are equal | ||||||||||||||||
1090 | < 0 - if this string is less than the string argument | ||||||||||||||||
1091 | > 0 - if this string is greater than the string argument | ||||||||||||||||
1092 | */ | ||||||||||||||||
1093 | sal_Int32 compareToAscii( const char* asciiStr ) const | ||||||||||||||||
1094 | { | ||||||||||||||||
1095 | return rtl_ustr_ascii_compare_WithLength( pData->buffer, pData->length, asciiStr ); | ||||||||||||||||
1096 | } | ||||||||||||||||
1097 | |||||||||||||||||
1098 | /** | ||||||||||||||||
1099 | Compares two strings with a maximum count of characters. | ||||||||||||||||
1100 | |||||||||||||||||
1101 | The comparison is based on the numeric value of each character in | ||||||||||||||||
1102 | the strings and return a value indicating their relationship. | ||||||||||||||||
1103 | Since this method is optimized for performance, the ASCII character | ||||||||||||||||
1104 | values are not converted in any way. The caller has to make sure that | ||||||||||||||||
1105 | all ASCII characters are in the allowed range between 0 and 127. | ||||||||||||||||
1106 | The ASCII string must be NULL-terminated. | ||||||||||||||||
1107 | This function can't be used for language specific sorting. | ||||||||||||||||
1108 | |||||||||||||||||
1109 | @deprecated This is a confusing overload with unexpectedly different | ||||||||||||||||
1110 | semantics from the one-parameter form, so it is marked as deprecated. | ||||||||||||||||
1111 | Practically all uses compare the return value against zero and can thus | ||||||||||||||||
1112 | be replaced with uses of startsWith. | ||||||||||||||||
1113 | |||||||||||||||||
1114 | @param asciiStr the 8-Bit ASCII character string to be compared. | ||||||||||||||||
1115 | @param maxLength the maximum count of characters to be compared. | ||||||||||||||||
1116 | @return 0 - if both strings are equal | ||||||||||||||||
1117 | < 0 - if this string is less than the string argument | ||||||||||||||||
1118 | > 0 - if this string is greater than the string argument | ||||||||||||||||
1119 | */ | ||||||||||||||||
1120 | SAL_DEPRECATED(__attribute__((deprecated("replace s1.compareToAscii(s2, strlen(s2)) == 0 with s1.startsWith(s2)" ))) | ||||||||||||||||
1121 | "replace s1.compareToAscii(s2, strlen(s2)) == 0 with s1.startsWith(s2)")__attribute__((deprecated("replace s1.compareToAscii(s2, strlen(s2)) == 0 with s1.startsWith(s2)" ))) | ||||||||||||||||
1122 | sal_Int32 compareToAscii( const char * asciiStr, sal_Int32 maxLength ) const | ||||||||||||||||
1123 | { | ||||||||||||||||
1124 | return rtl_ustr_ascii_shortenedCompare_WithLength( pData->buffer, pData->length, | ||||||||||||||||
1125 | asciiStr, maxLength ); | ||||||||||||||||
1126 | } | ||||||||||||||||
1127 | |||||||||||||||||
1128 | /** | ||||||||||||||||
1129 | Compares two strings in reverse order. | ||||||||||||||||
1130 | |||||||||||||||||
1131 | This could be useful, if normally both strings start with the same | ||||||||||||||||
1132 | content. The comparison is based on the numeric value of each character | ||||||||||||||||
1133 | in the strings and return a value indicating their relationship. | ||||||||||||||||
1134 | Since this method is optimized for performance, the ASCII character | ||||||||||||||||
1135 | values are not converted in any way. The caller has to make sure that | ||||||||||||||||
1136 | all ASCII characters are in the allowed range between 0 and 127. | ||||||||||||||||
1137 | The ASCII string must be NULL-terminated and must be greater than | ||||||||||||||||
1138 | or equal to asciiStrLength. | ||||||||||||||||
1139 | This function can't be used for language specific sorting. | ||||||||||||||||
1140 | |||||||||||||||||
1141 | @param asciiStr the 8-Bit ASCII character string to be compared. | ||||||||||||||||
1142 | @param asciiStrLength the length of the ascii string | ||||||||||||||||
1143 | @return 0 - if both strings are equal | ||||||||||||||||
1144 | < 0 - if this string is less than the string argument | ||||||||||||||||
1145 | > 0 - if this string is greater than the string argument | ||||||||||||||||
1146 | */ | ||||||||||||||||
1147 | sal_Int32 reverseCompareToAsciiL( const char * asciiStr, sal_Int32 asciiStrLength ) const | ||||||||||||||||
1148 | { | ||||||||||||||||
1149 | return rtl_ustr_asciil_reverseCompare_WithLength( pData->buffer, pData->length, | ||||||||||||||||
1150 | asciiStr, asciiStrLength ); | ||||||||||||||||
1151 | } | ||||||||||||||||
1152 | |||||||||||||||||
1153 | /** | ||||||||||||||||
1154 | Perform a comparison of two strings. | ||||||||||||||||
1155 | |||||||||||||||||
1156 | The result is true if and only if second string | ||||||||||||||||
1157 | represents the same sequence of characters as the first string. | ||||||||||||||||
1158 | Since this method is optimized for performance, the ASCII character | ||||||||||||||||
1159 | values are not converted in any way. The caller has to make sure that | ||||||||||||||||
1160 | all ASCII characters are in the allowed range between 0 and 127. | ||||||||||||||||
1161 | The ASCII string must be NULL-terminated. | ||||||||||||||||
1162 | This function can't be used for language specific comparison. | ||||||||||||||||
1163 | |||||||||||||||||
1164 | @param asciiStr the 8-Bit ASCII character string to be compared. | ||||||||||||||||
1165 | @return true if the strings are equal; | ||||||||||||||||
1166 | false, otherwise. | ||||||||||||||||
1167 | */ | ||||||||||||||||
1168 | bool equalsAscii( const char* asciiStr ) const | ||||||||||||||||
1169 | { | ||||||||||||||||
1170 | return rtl_ustr_ascii_compare_WithLength( pData->buffer, pData->length, | ||||||||||||||||
1171 | asciiStr ) == 0; | ||||||||||||||||
1172 | } | ||||||||||||||||
1173 | |||||||||||||||||
1174 | /** | ||||||||||||||||
1175 | Perform a comparison of two strings. | ||||||||||||||||
1176 | |||||||||||||||||
1177 | The result is true if and only if second string | ||||||||||||||||
1178 | represents the same sequence of characters as the first string. | ||||||||||||||||
1179 | Since this method is optimized for performance, the ASCII character | ||||||||||||||||
1180 | values are not converted in any way. The caller has to make sure that | ||||||||||||||||
1181 | all ASCII characters are in the allowed range between 0 and 127. | ||||||||||||||||
1182 | The ASCII string must be NULL-terminated and must be greater than | ||||||||||||||||
1183 | or equal to asciiStrLength. | ||||||||||||||||
1184 | This function can't be used for language specific comparison. | ||||||||||||||||
1185 | |||||||||||||||||
1186 | @param asciiStr the 8-Bit ASCII character string to be compared. | ||||||||||||||||
1187 | @param asciiStrLength the length of the ascii string | ||||||||||||||||
1188 | @return true if the strings are equal; | ||||||||||||||||
1189 | false, otherwise. | ||||||||||||||||
1190 | */ | ||||||||||||||||
1191 | bool equalsAsciiL( const char* asciiStr, sal_Int32 asciiStrLength ) const | ||||||||||||||||
1192 | { | ||||||||||||||||
1193 | if ( pData->length != asciiStrLength
| ||||||||||||||||
1194 | return false; | ||||||||||||||||
1195 | |||||||||||||||||
1196 | return rtl_ustr_asciil_reverseEquals_WithLength( | ||||||||||||||||
1197 | pData->buffer, asciiStr, asciiStrLength ); | ||||||||||||||||
1198 | } | ||||||||||||||||
1199 | |||||||||||||||||
1200 | /** | ||||||||||||||||
1201 | Perform an ASCII lowercase comparison of two strings. | ||||||||||||||||
1202 | |||||||||||||||||
1203 | The result is true if and only if second string | ||||||||||||||||
1204 | represents the same sequence of characters as the first string, | ||||||||||||||||
1205 | ignoring the case. | ||||||||||||||||
1206 | Character values between 65 and 90 (ASCII A-Z) are interpreted as | ||||||||||||||||
1207 | values between 97 and 122 (ASCII a-z). | ||||||||||||||||
1208 | Since this method is optimized for performance, the ASCII character | ||||||||||||||||
1209 | values are not converted in any way. The caller has to make sure that | ||||||||||||||||
1210 | all ASCII characters are in the allowed range between 0 and 127. | ||||||||||||||||
1211 | The ASCII string must be NULL-terminated. | ||||||||||||||||
1212 | This function can't be used for language specific comparison. | ||||||||||||||||
1213 | |||||||||||||||||
1214 | @param asciiStr the 8-Bit ASCII character string to be compared. | ||||||||||||||||
1215 | @return true if the strings are equal; | ||||||||||||||||
1216 | false, otherwise. | ||||||||||||||||
1217 | */ | ||||||||||||||||
1218 | bool equalsIgnoreAsciiCaseAscii( const char * asciiStr ) const | ||||||||||||||||
1219 | { | ||||||||||||||||
1220 | return rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, asciiStr ) == 0; | ||||||||||||||||
1221 | } | ||||||||||||||||
1222 | |||||||||||||||||
1223 | /** | ||||||||||||||||
1224 | Compares two ASCII strings ignoring case | ||||||||||||||||
1225 | |||||||||||||||||
1226 | The comparison is based on the numeric value of each character in | ||||||||||||||||
1227 | the strings and return a value indicating their relationship. | ||||||||||||||||
1228 | Since this method is optimized for performance, the ASCII character | ||||||||||||||||
1229 | values are not converted in any way. The caller has to make sure that | ||||||||||||||||
1230 | all ASCII characters are in the allowed range between 0 and 127. | ||||||||||||||||
1231 | The ASCII string must be NULL-terminated. | ||||||||||||||||
1232 | This function can't be used for language specific sorting. | ||||||||||||||||
1233 | |||||||||||||||||
1234 | @param asciiStr the 8-Bit ASCII character string to be compared. | ||||||||||||||||
1235 | @return 0 - if both strings are equal | ||||||||||||||||
1236 | < 0 - if this string is less than the string argument | ||||||||||||||||
1237 | > 0 - if this string is greater than the string argument | ||||||||||||||||
1238 | |||||||||||||||||
1239 | @since LibreOffice 3.5 | ||||||||||||||||
1240 | */ | ||||||||||||||||
1241 | sal_Int32 compareToIgnoreAsciiCaseAscii( const char * asciiStr ) const | ||||||||||||||||
1242 | { | ||||||||||||||||
1243 | return rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, asciiStr ); | ||||||||||||||||
1244 | } | ||||||||||||||||
1245 | |||||||||||||||||
1246 | /** | ||||||||||||||||
1247 | Perform an ASCII lowercase comparison of two strings. | ||||||||||||||||
1248 | |||||||||||||||||
1249 | The result is true if and only if second string | ||||||||||||||||
1250 | represents the same sequence of characters as the first string, | ||||||||||||||||
1251 | ignoring the case. | ||||||||||||||||
1252 | Character values between 65 and 90 (ASCII A-Z) are interpreted as | ||||||||||||||||
1253 | values between 97 and 122 (ASCII a-z). | ||||||||||||||||
1254 | Since this method is optimized for performance, the ASCII character | ||||||||||||||||
1255 | values are not converted in any way. The caller has to make sure that | ||||||||||||||||
1256 | all ASCII characters are in the allowed range between 0 and 127. | ||||||||||||||||
1257 | The ASCII string must be NULL-terminated and must be greater than | ||||||||||||||||
1258 | or equal to asciiStrLength. | ||||||||||||||||
1259 | This function can't be used for language specific comparison. | ||||||||||||||||
1260 | |||||||||||||||||
1261 | @param asciiStr the 8-Bit ASCII character string to be compared. | ||||||||||||||||
1262 | @param asciiStrLength the length of the ascii string | ||||||||||||||||
1263 | @return true if the strings are equal; | ||||||||||||||||
1264 | false, otherwise. | ||||||||||||||||
1265 | */ | ||||||||||||||||
1266 | bool equalsIgnoreAsciiCaseAsciiL( const char * asciiStr, sal_Int32 asciiStrLength ) const | ||||||||||||||||
1267 | { | ||||||||||||||||
1268 | if ( pData->length != asciiStrLength ) | ||||||||||||||||
1269 | return false; | ||||||||||||||||
1270 | |||||||||||||||||
1271 | return rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, asciiStr ) == 0; | ||||||||||||||||
1272 | } | ||||||||||||||||
1273 | |||||||||||||||||
1274 | /** | ||||||||||||||||
1275 | Match against a substring appearing in this string. | ||||||||||||||||
1276 | |||||||||||||||||
1277 | The result is true if and only if the second string appears as a substring | ||||||||||||||||
1278 | of this string, at the given position. | ||||||||||||||||
1279 | Since this method is optimized for performance, the ASCII character | ||||||||||||||||
1280 | values are not converted in any way. The caller has to make sure that | ||||||||||||||||
1281 | all ASCII characters are in the allowed range between 0 and 127. | ||||||||||||||||
1282 | The ASCII string must be NULL-terminated and must be greater than or | ||||||||||||||||
1283 | equal to asciiStrLength. | ||||||||||||||||
1284 | This function can't be used for language specific comparison. | ||||||||||||||||
1285 | |||||||||||||||||
1286 | @param asciiStr the object (substring) to be compared. | ||||||||||||||||
1287 | @param asciiStrLength the length of asciiStr. | ||||||||||||||||
1288 | @param fromIndex the index to start the comparison from. | ||||||||||||||||
1289 | The index must be greater than or equal to 0 | ||||||||||||||||
1290 | and less than or equal to the string length. | ||||||||||||||||
1291 | @return true if str match with the characters in the string | ||||||||||||||||
1292 | at the given position; | ||||||||||||||||
1293 | false, otherwise. | ||||||||||||||||
1294 | */ | ||||||||||||||||
1295 | bool matchAsciiL( const char* asciiStr, sal_Int32 asciiStrLength, sal_Int32 fromIndex = 0 ) const | ||||||||||||||||
1296 | { | ||||||||||||||||
1297 | return rtl_ustr_ascii_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, | ||||||||||||||||
1298 | asciiStr, asciiStrLength ) == 0; | ||||||||||||||||
1299 | } | ||||||||||||||||
1300 | |||||||||||||||||
1301 | // This overload is left undefined, to detect calls of matchAsciiL that | ||||||||||||||||
1302 | // erroneously use RTL_CONSTASCII_USTRINGPARAM instead of | ||||||||||||||||
1303 | // RTL_CONSTASCII_STRINGPARAM (but would lead to ambiguities on 32 bit | ||||||||||||||||
1304 | // platforms): | ||||||||||||||||
1305 | #if SAL_TYPES_SIZEOFLONG8 == 8 | ||||||||||||||||
1306 | void matchAsciiL(char const *, sal_Int32, rtl_TextEncoding) const; | ||||||||||||||||
1307 | #endif | ||||||||||||||||
1308 | |||||||||||||||||
1309 | /** | ||||||||||||||||
1310 | Match against a substring appearing in this string, ignoring the case of | ||||||||||||||||
1311 | ASCII letters. | ||||||||||||||||
1312 | |||||||||||||||||
1313 | The result is true if and only if the second string appears as a substring | ||||||||||||||||
1314 | of this string, at the given position. | ||||||||||||||||
1315 | Character values between 65 and 90 (ASCII A-Z) are interpreted as | ||||||||||||||||
1316 | values between 97 and 122 (ASCII a-z). | ||||||||||||||||
1317 | Since this method is optimized for performance, the ASCII character | ||||||||||||||||
1318 | values are not converted in any way. The caller has to make sure that | ||||||||||||||||
1319 | all ASCII characters are in the allowed range between 0 and 127. | ||||||||||||||||
1320 | The ASCII string must be NULL-terminated and must be greater than or | ||||||||||||||||
1321 | equal to asciiStrLength. | ||||||||||||||||
1322 | This function can't be used for language specific comparison. | ||||||||||||||||
1323 | |||||||||||||||||
1324 | @param asciiStr the 8-Bit ASCII character string to be compared. | ||||||||||||||||
1325 | @param asciiStrLength the length of the ascii string | ||||||||||||||||
1326 | @param fromIndex the index to start the comparison from. | ||||||||||||||||
1327 | The index must be greater than or equal to 0 | ||||||||||||||||
1328 | and less than or equal to the string length. | ||||||||||||||||
1329 | @return true if str match with the characters in the string | ||||||||||||||||
1330 | at the given position; | ||||||||||||||||
1331 | false, otherwise. | ||||||||||||||||
1332 | */ | ||||||||||||||||
1333 | bool matchIgnoreAsciiCaseAsciiL( const char* asciiStr, sal_Int32 asciiStrLength, sal_Int32 fromIndex = 0 ) const | ||||||||||||||||
1334 | { | ||||||||||||||||
1335 | return rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, | ||||||||||||||||
1336 | asciiStr, asciiStrLength ) == 0; | ||||||||||||||||
1337 | } | ||||||||||||||||
1338 | |||||||||||||||||
1339 | // This overload is left undefined, to detect calls of | ||||||||||||||||
1340 | // matchIgnoreAsciiCaseAsciiL that erroneously use | ||||||||||||||||
1341 | // RTL_CONSTASCII_USTRINGPARAM instead of RTL_CONSTASCII_STRINGPARAM (but | ||||||||||||||||
1342 | // would lead to ambiguities on 32 bit platforms): | ||||||||||||||||
1343 | #if SAL_TYPES_SIZEOFLONG8 == 8 | ||||||||||||||||
1344 | void matchIgnoreAsciiCaseAsciiL(char const *, sal_Int32, rtl_TextEncoding) | ||||||||||||||||
1345 | const; | ||||||||||||||||
1346 | #endif | ||||||||||||||||
1347 | |||||||||||||||||
1348 | /** | ||||||||||||||||
1349 | Check whether this string starts with a given substring. | ||||||||||||||||
1350 | |||||||||||||||||
1351 | @param str the substring to be compared | ||||||||||||||||
1352 | |||||||||||||||||
1353 | @param rest if non-null, and this function returns true, then assign a | ||||||||||||||||
1354 | copy of the remainder of this string to *rest. Available since | ||||||||||||||||
1355 | LibreOffice 4.2 | ||||||||||||||||
1356 | |||||||||||||||||
1357 | @return true if and only if the given str appears as a substring at the | ||||||||||||||||
1358 | start of this string | ||||||||||||||||
1359 | |||||||||||||||||
1360 | @since LibreOffice 4.0 | ||||||||||||||||
1361 | */ | ||||||||||||||||
1362 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
1363 | bool startsWith(std::u16string_view sv, OUString * rest = nullptr) const { | ||||||||||||||||
1364 | auto const b = match(sv); | ||||||||||||||||
1365 | if (b && rest != nullptr) { | ||||||||||||||||
1366 | *rest = copy(sv.size()); | ||||||||||||||||
1367 | } | ||||||||||||||||
1368 | return b; | ||||||||||||||||
1369 | } | ||||||||||||||||
1370 | #else | ||||||||||||||||
1371 | bool startsWith(OUString const & str, OUString * rest = NULL__null) const { | ||||||||||||||||
1372 | bool b = match(str); | ||||||||||||||||
1373 | if (b && rest != NULL__null) { | ||||||||||||||||
1374 | *rest = copy(str.getLength()); | ||||||||||||||||
1375 | } | ||||||||||||||||
1376 | return b; | ||||||||||||||||
1377 | } | ||||||||||||||||
1378 | #endif | ||||||||||||||||
1379 | |||||||||||||||||
1380 | /** | ||||||||||||||||
1381 | @overload | ||||||||||||||||
1382 | This function accepts an ASCII string literal as its argument. | ||||||||||||||||
1383 | @since LibreOffice 4.0 | ||||||||||||||||
1384 | */ | ||||||||||||||||
1385 | template< typename T > | ||||||||||||||||
1386 | typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type startsWith( | ||||||||||||||||
1387 | T & literal, OUString * rest = NULL__null) const | ||||||||||||||||
1388 | { | ||||||||||||||||
1389 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1390, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||||||
1390 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1390, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
1391 | bool b | ||||||||||||||||
1392 | = (libreoffice_internal::ConstCharArrayDetector<T>::length | ||||||||||||||||
1393 | <= sal_uInt32(pData->length)) | ||||||||||||||||
1394 | && rtl_ustr_asciil_reverseEquals_WithLength( | ||||||||||||||||
1395 | pData->buffer, | ||||||||||||||||
1396 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( | ||||||||||||||||
1397 | literal), | ||||||||||||||||
1398 | libreoffice_internal::ConstCharArrayDetector<T>::length); | ||||||||||||||||
1399 | if (b && rest != NULL__null) { | ||||||||||||||||
1400 | *rest = copy( | ||||||||||||||||
1401 | libreoffice_internal::ConstCharArrayDetector<T>::length); | ||||||||||||||||
1402 | } | ||||||||||||||||
1403 | return b; | ||||||||||||||||
1404 | } | ||||||||||||||||
1405 | |||||||||||||||||
1406 | /** | ||||||||||||||||
1407 | Check whether this string starts with a given string, ignoring the case of | ||||||||||||||||
1408 | ASCII letters. | ||||||||||||||||
1409 | |||||||||||||||||
1410 | Character values between 65 and 90 (ASCII A-Z) are interpreted as | ||||||||||||||||
1411 | values between 97 and 122 (ASCII a-z). | ||||||||||||||||
1412 | This function can't be used for language specific comparison. | ||||||||||||||||
1413 | |||||||||||||||||
1414 | @param str the substring to be compared | ||||||||||||||||
1415 | |||||||||||||||||
1416 | @param rest if non-null, and this function returns true, then assign a | ||||||||||||||||
1417 | copy of the remainder of this string to *rest. Available since | ||||||||||||||||
1418 | LibreOffice 4.2 | ||||||||||||||||
1419 | |||||||||||||||||
1420 | @return true if and only if the given str appears as a substring at the | ||||||||||||||||
1421 | start of this string, ignoring the case of ASCII letters ("A"--"Z" and | ||||||||||||||||
1422 | "a"--"z") | ||||||||||||||||
1423 | |||||||||||||||||
1424 | @since LibreOffice 4.0 | ||||||||||||||||
1425 | */ | ||||||||||||||||
1426 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
1427 | bool startsWithIgnoreAsciiCase(std::u16string_view sv, OUString * rest = nullptr) const { | ||||||||||||||||
1428 | auto const b = matchIgnoreAsciiCase(sv); | ||||||||||||||||
1429 | if (b && rest != nullptr) { | ||||||||||||||||
1430 | *rest = copy(sv.size()); | ||||||||||||||||
1431 | } | ||||||||||||||||
1432 | return b; | ||||||||||||||||
1433 | } | ||||||||||||||||
1434 | #else | ||||||||||||||||
1435 | bool startsWithIgnoreAsciiCase(OUString const & str, OUString * rest = NULL__null) | ||||||||||||||||
1436 | const | ||||||||||||||||
1437 | { | ||||||||||||||||
1438 | bool b = matchIgnoreAsciiCase(str); | ||||||||||||||||
1439 | if (b && rest != NULL__null) { | ||||||||||||||||
1440 | *rest = copy(str.getLength()); | ||||||||||||||||
1441 | } | ||||||||||||||||
1442 | return b; | ||||||||||||||||
1443 | } | ||||||||||||||||
1444 | #endif | ||||||||||||||||
1445 | |||||||||||||||||
1446 | /** | ||||||||||||||||
1447 | @overload | ||||||||||||||||
1448 | This function accepts an ASCII string literal as its argument. | ||||||||||||||||
1449 | @since LibreOffice 4.0 | ||||||||||||||||
1450 | */ | ||||||||||||||||
1451 | template< typename T > | ||||||||||||||||
1452 | typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type | ||||||||||||||||
1453 | startsWithIgnoreAsciiCase(T & literal, OUString * rest = NULL__null) const | ||||||||||||||||
1454 | { | ||||||||||||||||
1455 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1456, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||||||
1456 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1456, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
1457 | bool b | ||||||||||||||||
1458 | = (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths( | ||||||||||||||||
1459 | pData->buffer, | ||||||||||||||||
1460 | libreoffice_internal::ConstCharArrayDetector<T>::length, | ||||||||||||||||
1461 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( | ||||||||||||||||
1462 | literal), | ||||||||||||||||
1463 | libreoffice_internal::ConstCharArrayDetector<T>::length) | ||||||||||||||||
1464 | == 0); | ||||||||||||||||
1465 | if (b && rest != NULL__null) { | ||||||||||||||||
1466 | *rest = copy( | ||||||||||||||||
1467 | libreoffice_internal::ConstCharArrayDetector<T>::length); | ||||||||||||||||
1468 | } | ||||||||||||||||
1469 | return b; | ||||||||||||||||
1470 | } | ||||||||||||||||
1471 | |||||||||||||||||
1472 | /** | ||||||||||||||||
1473 | Check whether this string ends with a given substring. | ||||||||||||||||
1474 | |||||||||||||||||
1475 | @param str the substring to be compared | ||||||||||||||||
1476 | |||||||||||||||||
1477 | @param rest if non-null, and this function returns true, then assign a | ||||||||||||||||
1478 | copy of the remainder of this string to *rest. Available since | ||||||||||||||||
1479 | LibreOffice 4.2 | ||||||||||||||||
1480 | |||||||||||||||||
1481 | @return true if and only if the given str appears as a substring at the | ||||||||||||||||
1482 | end of this string | ||||||||||||||||
1483 | |||||||||||||||||
1484 | @since LibreOffice 3.6 | ||||||||||||||||
1485 | */ | ||||||||||||||||
1486 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
1487 | bool endsWith(std::u16string_view sv, OUString * rest = nullptr) const { | ||||||||||||||||
1488 | auto const b = sv.size() <= sal_uInt32(pData->length) | ||||||||||||||||
1489 | && match(sv, pData->length - sv.size()); | ||||||||||||||||
1490 | if (b && rest != nullptr) { | ||||||||||||||||
1491 | *rest = copy(0, (pData->length - sv.size())); | ||||||||||||||||
1492 | } | ||||||||||||||||
1493 | return b; | ||||||||||||||||
1494 | } | ||||||||||||||||
1495 | #else | ||||||||||||||||
1496 | bool endsWith(OUString const & str, OUString * rest = NULL__null) const { | ||||||||||||||||
1497 | bool b = str.getLength() <= getLength() | ||||||||||||||||
1498 | && match(str, getLength() - str.getLength()); | ||||||||||||||||
1499 | if (b && rest != NULL__null) { | ||||||||||||||||
1500 | *rest = copy(0, getLength() - str.getLength()); | ||||||||||||||||
1501 | } | ||||||||||||||||
1502 | return b; | ||||||||||||||||
1503 | } | ||||||||||||||||
1504 | #endif | ||||||||||||||||
1505 | |||||||||||||||||
1506 | /** | ||||||||||||||||
1507 | @overload | ||||||||||||||||
1508 | This function accepts an ASCII string literal as its argument. | ||||||||||||||||
1509 | @since LibreOffice 3.6 | ||||||||||||||||
1510 | */ | ||||||||||||||||
1511 | template< typename T > | ||||||||||||||||
1512 | typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type | ||||||||||||||||
1513 | endsWith(T & literal, OUString * rest = NULL__null) const | ||||||||||||||||
1514 | { | ||||||||||||||||
1515 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1516, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||||||
1516 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1516, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
1517 | bool b | ||||||||||||||||
1518 | = (libreoffice_internal::ConstCharArrayDetector<T>::length | ||||||||||||||||
1519 | <= sal_uInt32(pData->length)) | ||||||||||||||||
1520 | && rtl_ustr_asciil_reverseEquals_WithLength( | ||||||||||||||||
1521 | (pData->buffer + pData->length | ||||||||||||||||
1522 | - libreoffice_internal::ConstCharArrayDetector<T>::length), | ||||||||||||||||
1523 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( | ||||||||||||||||
1524 | literal), | ||||||||||||||||
1525 | libreoffice_internal::ConstCharArrayDetector<T>::length); | ||||||||||||||||
1526 | if (b && rest != NULL__null) { | ||||||||||||||||
1527 | *rest = copy( | ||||||||||||||||
1528 | 0, | ||||||||||||||||
1529 | (getLength() | ||||||||||||||||
1530 | - libreoffice_internal::ConstCharArrayDetector<T>::length)); | ||||||||||||||||
1531 | } | ||||||||||||||||
1532 | return b; | ||||||||||||||||
1533 | } | ||||||||||||||||
1534 | |||||||||||||||||
1535 | /** | ||||||||||||||||
1536 | Check whether this string ends with a given ASCII string. | ||||||||||||||||
1537 | |||||||||||||||||
1538 | @param asciiStr a sequence of at least asciiStrLength ASCII characters | ||||||||||||||||
1539 | (bytes in the range 0x00--0x7F) | ||||||||||||||||
1540 | @param asciiStrLength the length of asciiStr; must be non-negative | ||||||||||||||||
1541 | @return true if this string ends with asciiStr; otherwise, false is | ||||||||||||||||
1542 | returned | ||||||||||||||||
1543 | |||||||||||||||||
1544 | @since UDK 3.2.7 | ||||||||||||||||
1545 | */ | ||||||||||||||||
1546 | bool endsWithAsciiL(char const * asciiStr, sal_Int32 asciiStrLength) | ||||||||||||||||
1547 | const | ||||||||||||||||
1548 | { | ||||||||||||||||
1549 | return asciiStrLength <= pData->length | ||||||||||||||||
1550 | && rtl_ustr_asciil_reverseEquals_WithLength( | ||||||||||||||||
1551 | pData->buffer + pData->length - asciiStrLength, asciiStr, | ||||||||||||||||
1552 | asciiStrLength); | ||||||||||||||||
1553 | } | ||||||||||||||||
1554 | |||||||||||||||||
1555 | /** | ||||||||||||||||
1556 | Check whether this string ends with a given string, ignoring the case of | ||||||||||||||||
1557 | ASCII letters. | ||||||||||||||||
1558 | |||||||||||||||||
1559 | Character values between 65 and 90 (ASCII A-Z) are interpreted as | ||||||||||||||||
1560 | values between 97 and 122 (ASCII a-z). | ||||||||||||||||
1561 | This function can't be used for language specific comparison. | ||||||||||||||||
1562 | |||||||||||||||||
1563 | @param str the substring to be compared | ||||||||||||||||
1564 | |||||||||||||||||
1565 | @param rest if non-null, and this function returns true, then assign a | ||||||||||||||||
1566 | copy of the remainder of this string to *rest. Available since | ||||||||||||||||
1567 | LibreOffice 4.2 | ||||||||||||||||
1568 | |||||||||||||||||
1569 | @return true if and only if the given str appears as a substring at the | ||||||||||||||||
1570 | end of this string, ignoring the case of ASCII letters ("A"--"Z" and | ||||||||||||||||
1571 | "a"--"z") | ||||||||||||||||
1572 | |||||||||||||||||
1573 | @since LibreOffice 3.6 | ||||||||||||||||
1574 | */ | ||||||||||||||||
1575 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
1576 | bool endsWithIgnoreAsciiCase(std::u16string_view sv, OUString * rest = nullptr) const { | ||||||||||||||||
1577 | auto const b = sv.size() <= sal_uInt32(pData->length) | ||||||||||||||||
1578 | && matchIgnoreAsciiCase(sv, pData->length - sv.size()); | ||||||||||||||||
1579 | if (b && rest != nullptr) { | ||||||||||||||||
1580 | *rest = copy(0, pData->length - sv.size()); | ||||||||||||||||
1581 | } | ||||||||||||||||
1582 | return b; | ||||||||||||||||
1583 | } | ||||||||||||||||
1584 | #else | ||||||||||||||||
1585 | bool endsWithIgnoreAsciiCase(OUString const & str, OUString * rest = NULL__null) const | ||||||||||||||||
1586 | { | ||||||||||||||||
1587 | bool b = str.getLength() <= getLength() | ||||||||||||||||
1588 | && matchIgnoreAsciiCase(str, getLength() - str.getLength()); | ||||||||||||||||
1589 | if (b && rest != NULL__null) { | ||||||||||||||||
1590 | *rest = copy(0, getLength() - str.getLength()); | ||||||||||||||||
1591 | } | ||||||||||||||||
1592 | return b; | ||||||||||||||||
1593 | } | ||||||||||||||||
1594 | #endif | ||||||||||||||||
1595 | |||||||||||||||||
1596 | /** | ||||||||||||||||
1597 | @overload | ||||||||||||||||
1598 | This function accepts an ASCII string literal as its argument. | ||||||||||||||||
1599 | @since LibreOffice 3.6 | ||||||||||||||||
1600 | */ | ||||||||||||||||
1601 | template< typename T > | ||||||||||||||||
1602 | typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type | ||||||||||||||||
1603 | endsWithIgnoreAsciiCase(T & literal, OUString * rest = NULL__null) const | ||||||||||||||||
1604 | { | ||||||||||||||||
1605 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1606, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||||||
1606 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1606, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
1607 | bool b | ||||||||||||||||
1608 | = (libreoffice_internal::ConstCharArrayDetector<T>::length | ||||||||||||||||
1609 | <= sal_uInt32(pData->length)) | ||||||||||||||||
1610 | && (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths( | ||||||||||||||||
1611 | (pData->buffer + pData->length | ||||||||||||||||
1612 | - libreoffice_internal::ConstCharArrayDetector<T>::length), | ||||||||||||||||
1613 | libreoffice_internal::ConstCharArrayDetector<T>::length, | ||||||||||||||||
1614 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( | ||||||||||||||||
1615 | literal), | ||||||||||||||||
1616 | libreoffice_internal::ConstCharArrayDetector<T>::length) | ||||||||||||||||
1617 | == 0); | ||||||||||||||||
1618 | if (b && rest != NULL__null) { | ||||||||||||||||
1619 | *rest = copy( | ||||||||||||||||
1620 | 0, | ||||||||||||||||
1621 | (getLength() | ||||||||||||||||
1622 | - libreoffice_internal::ConstCharArrayDetector<T>::length)); | ||||||||||||||||
1623 | } | ||||||||||||||||
1624 | return b; | ||||||||||||||||
1625 | } | ||||||||||||||||
1626 | |||||||||||||||||
1627 | /** | ||||||||||||||||
1628 | Check whether this string ends with a given ASCII string, ignoring the | ||||||||||||||||
1629 | case of ASCII letters. | ||||||||||||||||
1630 | |||||||||||||||||
1631 | @param asciiStr a sequence of at least asciiStrLength ASCII characters | ||||||||||||||||
1632 | (bytes in the range 0x00--0x7F) | ||||||||||||||||
1633 | @param asciiStrLength the length of asciiStr; must be non-negative | ||||||||||||||||
1634 | @return true if this string ends with asciiStr, ignoring the case of ASCII | ||||||||||||||||
1635 | letters ("A"--"Z" and "a"--"z"); otherwise, false is returned | ||||||||||||||||
1636 | */ | ||||||||||||||||
1637 | bool endsWithIgnoreAsciiCaseAsciiL( | ||||||||||||||||
1638 | char const * asciiStr, sal_Int32 asciiStrLength) const | ||||||||||||||||
1639 | { | ||||||||||||||||
1640 | return asciiStrLength <= pData->length | ||||||||||||||||
1641 | && (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths( | ||||||||||||||||
1642 | pData->buffer + pData->length - asciiStrLength, | ||||||||||||||||
1643 | asciiStrLength, asciiStr, asciiStrLength) | ||||||||||||||||
1644 | == 0); | ||||||||||||||||
1645 | } | ||||||||||||||||
1646 | |||||||||||||||||
1647 | friend bool operator == ( const OUString& rStr1, const OUString& rStr2 ) | ||||||||||||||||
1648 | { return rStr1.equals(rStr2); } | ||||||||||||||||
1649 | |||||||||||||||||
1650 | friend bool operator != ( const OUString& rStr1, const OUString& rStr2 ) | ||||||||||||||||
1651 | { return !(operator == ( rStr1, rStr2 )); } | ||||||||||||||||
1652 | |||||||||||||||||
1653 | friend bool operator < ( const OUString& rStr1, const OUString& rStr2 ) | ||||||||||||||||
1654 | { return rStr1.compareTo( rStr2 ) < 0; } | ||||||||||||||||
1655 | friend bool operator > ( const OUString& rStr1, const OUString& rStr2 ) | ||||||||||||||||
1656 | { return rStr1.compareTo( rStr2 ) > 0; } | ||||||||||||||||
1657 | friend bool operator <= ( const OUString& rStr1, const OUString& rStr2 ) | ||||||||||||||||
1658 | { return rStr1.compareTo( rStr2 ) <= 0; } | ||||||||||||||||
1659 | friend bool operator >= ( const OUString& rStr1, const OUString& rStr2 ) | ||||||||||||||||
1660 | { return rStr1.compareTo( rStr2 ) >= 0; } | ||||||||||||||||
1661 | |||||||||||||||||
1662 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
1663 | |||||||||||||||||
1664 | template<typename T> friend typename libreoffice_internal::CharPtrDetector<T, bool>::TypeUtf16 | ||||||||||||||||
1665 | operator ==(OUString const & s1, T const & s2) { | ||||||||||||||||
1666 | return rtl_ustr_compare_WithLength(s1.getStr(), s1.getLength(), s2, rtl_ustr_getLength(s2)) | ||||||||||||||||
1667 | == 0; | ||||||||||||||||
1668 | } | ||||||||||||||||
1669 | |||||||||||||||||
1670 | template<typename T> | ||||||||||||||||
1671 | friend typename libreoffice_internal::NonConstCharArrayDetector<T, bool>::TypeUtf16 | ||||||||||||||||
1672 | operator ==(OUString const & s1, T & s2) { | ||||||||||||||||
1673 | return rtl_ustr_compare_WithLength(s1.getStr(), s1.getLength(), s2, rtl_ustr_getLength(s2)) | ||||||||||||||||
1674 | == 0; | ||||||||||||||||
1675 | } | ||||||||||||||||
1676 | |||||||||||||||||
1677 | template<typename T> friend typename libreoffice_internal::CharPtrDetector<T, bool>::TypeUtf16 | ||||||||||||||||
1678 | operator ==(T const & s1, OUString const & s2) { | ||||||||||||||||
1679 | return rtl_ustr_compare_WithLength(s1, rtl_ustr_getLength(s1), s2.getStr(), s2.getLength()) | ||||||||||||||||
1680 | == 0; | ||||||||||||||||
1681 | } | ||||||||||||||||
1682 | |||||||||||||||||
1683 | template<typename T> | ||||||||||||||||
1684 | friend typename libreoffice_internal::NonConstCharArrayDetector<T, bool>::TypeUtf16 | ||||||||||||||||
1685 | operator ==(T & s1, OUString const & s2) { | ||||||||||||||||
1686 | return rtl_ustr_compare_WithLength(s1, rtl_ustr_getLength(s1), s2.getStr(), s2.getLength()) | ||||||||||||||||
1687 | == 0; | ||||||||||||||||
1688 | } | ||||||||||||||||
1689 | |||||||||||||||||
1690 | template<typename T> friend typename libreoffice_internal::CharPtrDetector<T, bool>::TypeUtf16 | ||||||||||||||||
1691 | operator !=(OUString const & s1, T const & s2) { return !(s1 == s2); } | ||||||||||||||||
1692 | |||||||||||||||||
1693 | template<typename T> | ||||||||||||||||
1694 | friend typename libreoffice_internal::NonConstCharArrayDetector<T, bool>::TypeUtf16 | ||||||||||||||||
1695 | operator !=(OUString const & s1, T & s2) { return !(s1 == s2); } | ||||||||||||||||
1696 | |||||||||||||||||
1697 | template<typename T> friend typename libreoffice_internal::CharPtrDetector<T, bool>::TypeUtf16 | ||||||||||||||||
1698 | operator !=(T const & s1, OUString const & s2) { return !(s1 == s2); } | ||||||||||||||||
1699 | |||||||||||||||||
1700 | template<typename T> | ||||||||||||||||
1701 | friend typename libreoffice_internal::NonConstCharArrayDetector<T, bool>::TypeUtf16 | ||||||||||||||||
1702 | operator !=(T & s1, OUString const & s2) { return !(s1 == s2); } | ||||||||||||||||
1703 | |||||||||||||||||
1704 | #else | ||||||||||||||||
1705 | |||||||||||||||||
1706 | friend bool operator == ( const OUString& rStr1, const sal_Unicode * pStr2 ) | ||||||||||||||||
1707 | { return rStr1.compareTo( pStr2 ) == 0; } | ||||||||||||||||
1708 | friend bool operator == ( const sal_Unicode * pStr1, const OUString& rStr2 ) | ||||||||||||||||
1709 | { return OUString( pStr1 ).compareTo( rStr2 ) == 0; } | ||||||||||||||||
1710 | |||||||||||||||||
1711 | friend bool operator != ( const OUString& rStr1, const sal_Unicode * pStr2 ) | ||||||||||||||||
1712 | { return !(operator == ( rStr1, pStr2 )); } | ||||||||||||||||
1713 | friend bool operator != ( const sal_Unicode * pStr1, const OUString& rStr2 ) | ||||||||||||||||
1714 | { return !(operator == ( pStr1, rStr2 )); } | ||||||||||||||||
1715 | |||||||||||||||||
1716 | #endif | ||||||||||||||||
1717 | |||||||||||||||||
1718 | /** | ||||||||||||||||
1719 | * Compare string to an ASCII string literal. | ||||||||||||||||
1720 | * | ||||||||||||||||
1721 | * This operator is equal to calling equalsAsciiL(). | ||||||||||||||||
1722 | * | ||||||||||||||||
1723 | * @since LibreOffice 3.6 | ||||||||||||||||
1724 | */ | ||||||||||||||||
1725 | template< typename T > | ||||||||||||||||
1726 | friend typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type operator==( const OUString& rString, T& literal ) | ||||||||||||||||
1727 | { | ||||||||||||||||
1728 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1729, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||||||
1729 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1729, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
1730 | return rString.equalsAsciiL( | ||||||||||||||||
1731 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), | ||||||||||||||||
1732 | libreoffice_internal::ConstCharArrayDetector<T>::length); | ||||||||||||||||
1733 | } | ||||||||||||||||
1734 | /** | ||||||||||||||||
1735 | * Compare string to an ASCII string literal. | ||||||||||||||||
1736 | * | ||||||||||||||||
1737 | * This operator is equal to calling equalsAsciiL(). | ||||||||||||||||
1738 | * | ||||||||||||||||
1739 | * @since LibreOffice 3.6 | ||||||||||||||||
1740 | */ | ||||||||||||||||
1741 | template< typename T > | ||||||||||||||||
1742 | friend typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type operator==( T& literal, const OUString& rString ) | ||||||||||||||||
1743 | { | ||||||||||||||||
1744 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1745, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||||||
1745 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1745, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
1746 | return rString.equalsAsciiL( | ||||||||||||||||
1747 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), | ||||||||||||||||
1748 | libreoffice_internal::ConstCharArrayDetector<T>::length); | ||||||||||||||||
1749 | } | ||||||||||||||||
1750 | /** | ||||||||||||||||
1751 | * Compare string to an ASCII string literal. | ||||||||||||||||
1752 | * | ||||||||||||||||
1753 | * This operator is equal to calling !equalsAsciiL(). | ||||||||||||||||
1754 | * | ||||||||||||||||
1755 | * @since LibreOffice 3.6 | ||||||||||||||||
1756 | */ | ||||||||||||||||
1757 | template< typename T > | ||||||||||||||||
1758 | friend typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type operator!=( const OUString& rString, T& literal ) | ||||||||||||||||
1759 | { | ||||||||||||||||
1760 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1761, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||||||
1761 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1761, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
1762 | return !rString.equalsAsciiL( | ||||||||||||||||
1763 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), | ||||||||||||||||
1764 | libreoffice_internal::ConstCharArrayDetector<T>::length); | ||||||||||||||||
1765 | } | ||||||||||||||||
1766 | /** | ||||||||||||||||
1767 | * Compare string to an ASCII string literal. | ||||||||||||||||
1768 | * | ||||||||||||||||
1769 | * This operator is equal to calling !equalsAsciiL(). | ||||||||||||||||
1770 | * | ||||||||||||||||
1771 | * @since LibreOffice 3.6 | ||||||||||||||||
1772 | */ | ||||||||||||||||
1773 | template< typename T > | ||||||||||||||||
1774 | friend typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type operator!=( T& literal, const OUString& rString ) | ||||||||||||||||
1775 | { | ||||||||||||||||
1776 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1777, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||||||
1777 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 1777, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
1778 | return !rString.equalsAsciiL( | ||||||||||||||||
1779 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), | ||||||||||||||||
1780 | libreoffice_internal::ConstCharArrayDetector<T>::length); | ||||||||||||||||
1781 | } | ||||||||||||||||
1782 | |||||||||||||||||
1783 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
1784 | /** @overload @since LibreOffice 5.3 */ | ||||||||||||||||
1785 | template<typename T> friend typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16 | ||||||||||||||||
1786 | operator ==(OUString const & string, T & literal) { | ||||||||||||||||
1787 | return | ||||||||||||||||
1788 | rtl_ustr_reverseCompare_WithLength( | ||||||||||||||||
1789 | string.pData->buffer, string.pData->length, | ||||||||||||||||
1790 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( | ||||||||||||||||
1791 | literal), | ||||||||||||||||
1792 | libreoffice_internal::ConstCharArrayDetector<T>::length) | ||||||||||||||||
1793 | == 0; | ||||||||||||||||
1794 | } | ||||||||||||||||
1795 | /** @overload @since LibreOffice 5.3 */ | ||||||||||||||||
1796 | template<typename T> friend typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16 | ||||||||||||||||
1797 | operator ==(T & literal, OUString const & string) { | ||||||||||||||||
1798 | return | ||||||||||||||||
1799 | rtl_ustr_reverseCompare_WithLength( | ||||||||||||||||
1800 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( | ||||||||||||||||
1801 | literal), | ||||||||||||||||
1802 | libreoffice_internal::ConstCharArrayDetector<T>::length, | ||||||||||||||||
1803 | string.pData->buffer, string.pData->length) | ||||||||||||||||
1804 | == 0; | ||||||||||||||||
1805 | } | ||||||||||||||||
1806 | /** @overload @since LibreOffice 5.3 */ | ||||||||||||||||
1807 | template<typename T> friend typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16 | ||||||||||||||||
1808 | operator !=(OUString const & string, T & literal) { | ||||||||||||||||
1809 | return | ||||||||||||||||
1810 | rtl_ustr_reverseCompare_WithLength( | ||||||||||||||||
1811 | string.pData->buffer, string.pData->length, | ||||||||||||||||
1812 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( | ||||||||||||||||
1813 | literal), | ||||||||||||||||
1814 | libreoffice_internal::ConstCharArrayDetector<T>::length) | ||||||||||||||||
1815 | != 0; | ||||||||||||||||
1816 | } | ||||||||||||||||
1817 | /** @overload @since LibreOffice 5.3 */ | ||||||||||||||||
1818 | template<typename T> friend typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16 | ||||||||||||||||
1819 | operator !=(T & literal, OUString const & string) { | ||||||||||||||||
1820 | return | ||||||||||||||||
1821 | rtl_ustr_reverseCompare_WithLength( | ||||||||||||||||
1822 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer( | ||||||||||||||||
1823 | literal), | ||||||||||||||||
1824 | libreoffice_internal::ConstCharArrayDetector<T>::length, | ||||||||||||||||
1825 | string.pData->buffer, string.pData->length) | ||||||||||||||||
1826 | != 0; | ||||||||||||||||
1827 | } | ||||||||||||||||
1828 | #endif | ||||||||||||||||
1829 | |||||||||||||||||
1830 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
1831 | /// @cond INTERNAL | ||||||||||||||||
1832 | |||||||||||||||||
1833 | /* Comparison between OUString and OUStringLiteral. | ||||||||||||||||
1834 | |||||||||||||||||
1835 | @since LibreOffice 5.0 | ||||||||||||||||
1836 | */ | ||||||||||||||||
1837 | |||||||||||||||||
1838 | template<std::size_t N> | ||||||||||||||||
1839 | friend bool operator ==(OUString const & lhs, OUStringLiteral<N> const & rhs) { | ||||||||||||||||
1840 | return | ||||||||||||||||
1841 | rtl_ustr_reverseCompare_WithLength( | ||||||||||||||||
1842 | lhs.pData->buffer, lhs.pData->length, rhs.getStr(), rhs.getLength()) | ||||||||||||||||
1843 | == 0; | ||||||||||||||||
1844 | } | ||||||||||||||||
1845 | |||||||||||||||||
1846 | template<std::size_t N> | ||||||||||||||||
1847 | friend bool operator !=(OUString const & lhs, OUStringLiteral<N> const & rhs) { | ||||||||||||||||
1848 | return | ||||||||||||||||
1849 | rtl_ustr_reverseCompare_WithLength( | ||||||||||||||||
1850 | lhs.pData->buffer, lhs.pData->length, rhs.getStr(), rhs.getLength()) | ||||||||||||||||
1851 | != 0; | ||||||||||||||||
1852 | } | ||||||||||||||||
1853 | |||||||||||||||||
1854 | template<std::size_t N> | ||||||||||||||||
1855 | friend bool operator <(OUString const & lhs, OUStringLiteral<N> const & rhs) { | ||||||||||||||||
1856 | return | ||||||||||||||||
1857 | (rtl_ustr_compare_WithLength( | ||||||||||||||||
1858 | lhs.pData->buffer, lhs.pData->length, rhs.getStr(), rhs.getLength())) | ||||||||||||||||
1859 | < 0; | ||||||||||||||||
1860 | } | ||||||||||||||||
1861 | |||||||||||||||||
1862 | template<std::size_t N> | ||||||||||||||||
1863 | friend bool operator <=(OUString const & lhs, OUStringLiteral<N> const & rhs) { | ||||||||||||||||
1864 | return | ||||||||||||||||
1865 | (rtl_ustr_compare_WithLength( | ||||||||||||||||
1866 | lhs.pData->buffer, lhs.pData->length, rhs.getStr(), rhs.getLength())) | ||||||||||||||||
1867 | <= 0; | ||||||||||||||||
1868 | } | ||||||||||||||||
1869 | |||||||||||||||||
1870 | template<std::size_t N> | ||||||||||||||||
1871 | friend bool operator >(OUString const & lhs, OUStringLiteral<N> const & rhs) { | ||||||||||||||||
1872 | return | ||||||||||||||||
1873 | (rtl_ustr_compare_WithLength( | ||||||||||||||||
1874 | lhs.pData->buffer, lhs.pData->length, rhs.getStr(), rhs.getLength())) | ||||||||||||||||
1875 | > 0; | ||||||||||||||||
1876 | } | ||||||||||||||||
1877 | |||||||||||||||||
1878 | template<std::size_t N> | ||||||||||||||||
1879 | friend bool operator >=(OUString const & lhs, OUStringLiteral<N> const & rhs) { | ||||||||||||||||
1880 | return | ||||||||||||||||
1881 | (rtl_ustr_compare_WithLength( | ||||||||||||||||
1882 | lhs.pData->buffer, lhs.pData->length, rhs.getStr(), rhs.getLength())) | ||||||||||||||||
1883 | >= 0; | ||||||||||||||||
1884 | } | ||||||||||||||||
1885 | |||||||||||||||||
1886 | template<std::size_t N> | ||||||||||||||||
1887 | friend bool operator ==(OUStringLiteral<N> const & lhs, OUString const & rhs) { | ||||||||||||||||
1888 | return | ||||||||||||||||
1889 | rtl_ustr_reverseCompare_WithLength( | ||||||||||||||||
1890 | lhs.getStr(), lhs.getLength(), rhs.pData->buffer, rhs.pData->length) | ||||||||||||||||
1891 | == 0; | ||||||||||||||||
1892 | } | ||||||||||||||||
1893 | |||||||||||||||||
1894 | template<std::size_t N> | ||||||||||||||||
1895 | friend bool operator !=(OUStringLiteral<N> const & lhs, OUString const & rhs) { | ||||||||||||||||
1896 | return | ||||||||||||||||
1897 | rtl_ustr_reverseCompare_WithLength( | ||||||||||||||||
1898 | lhs.getStr(), lhs.getLength(), rhs.pData->buffer, rhs.pData->length) | ||||||||||||||||
1899 | != 0; | ||||||||||||||||
1900 | } | ||||||||||||||||
1901 | |||||||||||||||||
1902 | template<std::size_t N> | ||||||||||||||||
1903 | friend bool operator <(OUStringLiteral<N> const & lhs, OUString const & rhs) { | ||||||||||||||||
1904 | return | ||||||||||||||||
1905 | (rtl_ustr_compare_WithLength( | ||||||||||||||||
1906 | lhs.getStr(), lhs.getLength(), rhs.pData->buffer, rhs.pData->length)) | ||||||||||||||||
1907 | < 0; | ||||||||||||||||
1908 | } | ||||||||||||||||
1909 | |||||||||||||||||
1910 | template<std::size_t N> | ||||||||||||||||
1911 | friend bool operator <=(OUStringLiteral<N> const & lhs, OUString const & rhs) { | ||||||||||||||||
1912 | return | ||||||||||||||||
1913 | (rtl_ustr_compare_WithLength( | ||||||||||||||||
1914 | lhs.getStr(), lhs.getLength(), rhs.pData->buffer, rhs.pData->length)) | ||||||||||||||||
1915 | <= 0; | ||||||||||||||||
1916 | } | ||||||||||||||||
1917 | |||||||||||||||||
1918 | template<std::size_t N> | ||||||||||||||||
1919 | friend bool operator >(OUStringLiteral<N> const & lhs, OUString const & rhs) { | ||||||||||||||||
1920 | return | ||||||||||||||||
1921 | (rtl_ustr_compare_WithLength( | ||||||||||||||||
1922 | lhs.getStr(), lhs.getLength(), rhs.pData->buffer, rhs.pData->length)) | ||||||||||||||||
1923 | > 0; | ||||||||||||||||
1924 | } | ||||||||||||||||
1925 | |||||||||||||||||
1926 | template<std::size_t N> | ||||||||||||||||
1927 | friend bool operator >=(OUStringLiteral<N> const & lhs, OUString const & rhs) { | ||||||||||||||||
1928 | return | ||||||||||||||||
1929 | (rtl_ustr_compare_WithLength( | ||||||||||||||||
1930 | lhs.getStr(), lhs.getLength(), rhs.pData->buffer, rhs.pData->length)) | ||||||||||||||||
1931 | >= 0; | ||||||||||||||||
1932 | } | ||||||||||||||||
1933 | |||||||||||||||||
1934 | /// @endcond | ||||||||||||||||
1935 | #endif | ||||||||||||||||
1936 | |||||||||||||||||
1937 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
1938 | friend bool operator ==(OUString const & lhs, std::u16string_view rhs) { | ||||||||||||||||
1939 | return | ||||||||||||||||
1940 | rtl_ustr_reverseCompare_WithLength( | ||||||||||||||||
1941 | lhs.pData->buffer, lhs.pData->length, rhs.data(), rhs.size()) | ||||||||||||||||
1942 | == 0; | ||||||||||||||||
1943 | } | ||||||||||||||||
1944 | |||||||||||||||||
1945 | friend bool operator !=(OUString const & lhs, std::u16string_view rhs) { | ||||||||||||||||
1946 | return | ||||||||||||||||
1947 | rtl_ustr_reverseCompare_WithLength( | ||||||||||||||||
1948 | lhs.pData->buffer, lhs.pData->length, rhs.data(), rhs.size()) | ||||||||||||||||
1949 | != 0; | ||||||||||||||||
1950 | } | ||||||||||||||||
1951 | |||||||||||||||||
1952 | friend bool operator <(OUString const & lhs, std::u16string_view rhs) { | ||||||||||||||||
1953 | return | ||||||||||||||||
1954 | (rtl_ustr_compare_WithLength( | ||||||||||||||||
1955 | lhs.pData->buffer, lhs.pData->length, rhs.data(), rhs.size())) | ||||||||||||||||
1956 | < 0; | ||||||||||||||||
1957 | } | ||||||||||||||||
1958 | |||||||||||||||||
1959 | friend bool operator <=(OUString const & lhs, std::u16string_view rhs) { | ||||||||||||||||
1960 | return | ||||||||||||||||
1961 | (rtl_ustr_compare_WithLength( | ||||||||||||||||
1962 | lhs.pData->buffer, lhs.pData->length, rhs.data(), rhs.size())) | ||||||||||||||||
1963 | <= 0; | ||||||||||||||||
1964 | } | ||||||||||||||||
1965 | |||||||||||||||||
1966 | friend bool operator >(OUString const & lhs, std::u16string_view rhs) { | ||||||||||||||||
1967 | return | ||||||||||||||||
1968 | (rtl_ustr_compare_WithLength( | ||||||||||||||||
1969 | lhs.pData->buffer, lhs.pData->length, rhs.data(), rhs.size())) | ||||||||||||||||
1970 | > 0; | ||||||||||||||||
1971 | } | ||||||||||||||||
1972 | |||||||||||||||||
1973 | friend bool operator >=(OUString const & lhs, std::u16string_view rhs) { | ||||||||||||||||
1974 | return | ||||||||||||||||
1975 | (rtl_ustr_compare_WithLength( | ||||||||||||||||
1976 | lhs.pData->buffer, lhs.pData->length, rhs.data(), rhs.size())) | ||||||||||||||||
1977 | >= 0; | ||||||||||||||||
1978 | } | ||||||||||||||||
1979 | |||||||||||||||||
1980 | friend bool operator ==(std::u16string_view lhs, OUString const & rhs) { | ||||||||||||||||
1981 | return | ||||||||||||||||
1982 | rtl_ustr_reverseCompare_WithLength( | ||||||||||||||||
1983 | lhs.data(), lhs.size(), rhs.pData->buffer, rhs.pData->length) | ||||||||||||||||
1984 | == 0; | ||||||||||||||||
1985 | } | ||||||||||||||||
1986 | |||||||||||||||||
1987 | friend bool operator !=(std::u16string_view lhs, OUString const & rhs) { | ||||||||||||||||
1988 | return | ||||||||||||||||
1989 | rtl_ustr_reverseCompare_WithLength( | ||||||||||||||||
1990 | lhs.data(), lhs.size(), rhs.pData->buffer, rhs.pData->length) | ||||||||||||||||
1991 | != 0; | ||||||||||||||||
1992 | } | ||||||||||||||||
1993 | |||||||||||||||||
1994 | friend bool operator <(std::u16string_view lhs, OUString const & rhs) { | ||||||||||||||||
1995 | return | ||||||||||||||||
1996 | (rtl_ustr_compare_WithLength( | ||||||||||||||||
1997 | lhs.data(), lhs.size(), rhs.pData->buffer, rhs.pData->length)) | ||||||||||||||||
1998 | < 0; | ||||||||||||||||
1999 | } | ||||||||||||||||
2000 | |||||||||||||||||
2001 | friend bool operator <=(std::u16string_view lhs, OUString const & rhs) { | ||||||||||||||||
2002 | return | ||||||||||||||||
2003 | (rtl_ustr_compare_WithLength( | ||||||||||||||||
2004 | lhs.data(), lhs.size(), rhs.pData->buffer, rhs.pData->length)) | ||||||||||||||||
2005 | <= 0; | ||||||||||||||||
2006 | } | ||||||||||||||||
2007 | |||||||||||||||||
2008 | friend bool operator >(std::u16string_view lhs, OUString const & rhs) { | ||||||||||||||||
2009 | return | ||||||||||||||||
2010 | (rtl_ustr_compare_WithLength( | ||||||||||||||||
2011 | lhs.data(), lhs.size(), rhs.pData->buffer, rhs.pData->length)) | ||||||||||||||||
2012 | > 0; | ||||||||||||||||
2013 | } | ||||||||||||||||
2014 | |||||||||||||||||
2015 | friend bool operator >=(std::u16string_view lhs, OUString const & rhs) { | ||||||||||||||||
2016 | return | ||||||||||||||||
2017 | (rtl_ustr_compare_WithLength( | ||||||||||||||||
2018 | lhs.data(), lhs.size(), rhs.pData->buffer, rhs.pData->length)) | ||||||||||||||||
2019 | >= 0; | ||||||||||||||||
2020 | } | ||||||||||||||||
2021 | #endif | ||||||||||||||||
2022 | |||||||||||||||||
2023 | /** | ||||||||||||||||
2024 | Returns a hashcode for this string. | ||||||||||||||||
2025 | |||||||||||||||||
2026 | @return a hash code value for this object. | ||||||||||||||||
2027 | |||||||||||||||||
2028 | @see rtl::OUStringHash for convenient use of std::unordered_map | ||||||||||||||||
2029 | */ | ||||||||||||||||
2030 | sal_Int32 hashCode() const | ||||||||||||||||
2031 | { | ||||||||||||||||
2032 | return rtl_ustr_hashCode_WithLength( pData->buffer, pData->length ); | ||||||||||||||||
2033 | } | ||||||||||||||||
2034 | |||||||||||||||||
2035 | /** | ||||||||||||||||
2036 | Returns the index within this string of the first occurrence of the | ||||||||||||||||
2037 | specified character, starting the search at the specified index. | ||||||||||||||||
2038 | |||||||||||||||||
2039 | @param ch character to be located. | ||||||||||||||||
2040 | @param fromIndex the index to start the search from. | ||||||||||||||||
2041 | The index must be greater than or equal to 0 | ||||||||||||||||
2042 | and less than or equal to the string length. | ||||||||||||||||
2043 | @return the index of the first occurrence of the character in the | ||||||||||||||||
2044 | character sequence represented by this string that is | ||||||||||||||||
2045 | greater than or equal to fromIndex, or | ||||||||||||||||
2046 | -1 if the character does not occur. | ||||||||||||||||
2047 | */ | ||||||||||||||||
2048 | sal_Int32 indexOf( sal_Unicode ch, sal_Int32 fromIndex = 0 ) const | ||||||||||||||||
2049 | { | ||||||||||||||||
2050 | sal_Int32 ret = rtl_ustr_indexOfChar_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, ch ); | ||||||||||||||||
2051 | return (ret < 0 ? ret : ret+fromIndex); | ||||||||||||||||
2052 | } | ||||||||||||||||
2053 | |||||||||||||||||
2054 | /** | ||||||||||||||||
2055 | Returns the index within this string of the last occurrence of the | ||||||||||||||||
2056 | specified character, searching backward starting at the end. | ||||||||||||||||
2057 | |||||||||||||||||
2058 | @param ch character to be located. | ||||||||||||||||
2059 | @return the index of the last occurrence of the character in the | ||||||||||||||||
2060 | character sequence represented by this string, or | ||||||||||||||||
2061 | -1 if the character does not occur. | ||||||||||||||||
2062 | */ | ||||||||||||||||
2063 | sal_Int32 lastIndexOf( sal_Unicode ch ) const | ||||||||||||||||
2064 | { | ||||||||||||||||
2065 | return rtl_ustr_lastIndexOfChar_WithLength( pData->buffer, pData->length, ch ); | ||||||||||||||||
2066 | } | ||||||||||||||||
2067 | |||||||||||||||||
2068 | /** | ||||||||||||||||
2069 | Returns the index within this string of the last occurrence of the | ||||||||||||||||
2070 | specified character, searching backward starting before the specified | ||||||||||||||||
2071 | index. | ||||||||||||||||
2072 | |||||||||||||||||
2073 | @param ch character to be located. | ||||||||||||||||
2074 | @param fromIndex the index before which to start the search. | ||||||||||||||||
2075 | @return the index of the last occurrence of the character in the | ||||||||||||||||
2076 | character sequence represented by this string that | ||||||||||||||||
2077 | is less than fromIndex, or -1 | ||||||||||||||||
2078 | if the character does not occur before that point. | ||||||||||||||||
2079 | */ | ||||||||||||||||
2080 | sal_Int32 lastIndexOf( sal_Unicode ch, sal_Int32 fromIndex ) const | ||||||||||||||||
2081 | { | ||||||||||||||||
2082 | return rtl_ustr_lastIndexOfChar_WithLength( pData->buffer, fromIndex, ch ); | ||||||||||||||||
2083 | } | ||||||||||||||||
2084 | |||||||||||||||||
2085 | /** | ||||||||||||||||
2086 | Returns the index within this string of the first occurrence of the | ||||||||||||||||
2087 | specified substring, starting at the specified index. | ||||||||||||||||
2088 | |||||||||||||||||
2089 | If str doesn't include any character, always -1 is | ||||||||||||||||
2090 | returned. This is also the case, if both strings are empty. | ||||||||||||||||
2091 | |||||||||||||||||
2092 | @param str the substring to search for. | ||||||||||||||||
2093 | @param fromIndex the index to start the search from. | ||||||||||||||||
2094 | @return If the string argument occurs one or more times as a substring | ||||||||||||||||
2095 | within this string at the starting index, then the index | ||||||||||||||||
2096 | of the first character of the first such substring is | ||||||||||||||||
2097 | returned. If it does not occur as a substring starting | ||||||||||||||||
2098 | at fromIndex or beyond, -1 is returned. | ||||||||||||||||
2099 | */ | ||||||||||||||||
2100 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
2101 | sal_Int32 indexOf(std::u16string_view sv, sal_Int32 fromIndex = 0) const { | ||||||||||||||||
2102 | auto const n = rtl_ustr_indexOfStr_WithLength( | ||||||||||||||||
2103 | pData->buffer + fromIndex, pData->length - fromIndex, sv.data(), sv.size()); | ||||||||||||||||
2104 | return n < 0 ? n : n + fromIndex; | ||||||||||||||||
2105 | } | ||||||||||||||||
2106 | #else | ||||||||||||||||
2107 | sal_Int32 indexOf( const OUString & str, sal_Int32 fromIndex = 0 ) const | ||||||||||||||||
2108 | { | ||||||||||||||||
2109 | sal_Int32 ret = rtl_ustr_indexOfStr_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, | ||||||||||||||||
2110 | str.pData->buffer, str.pData->length ); | ||||||||||||||||
2111 | return (ret < 0 ? ret : ret+fromIndex); | ||||||||||||||||
2112 | } | ||||||||||||||||
2113 | #endif | ||||||||||||||||
2114 | |||||||||||||||||
2115 | /** | ||||||||||||||||
2116 | @overload | ||||||||||||||||
2117 | This function accepts an ASCII string literal as its argument. | ||||||||||||||||
2118 | @since LibreOffice 3.6 | ||||||||||||||||
2119 | */ | ||||||||||||||||
2120 | template< typename T > | ||||||||||||||||
2121 | typename libreoffice_internal::ConstCharArrayDetector< T, sal_Int32 >::Type indexOf( T& literal, sal_Int32 fromIndex = 0 ) const | ||||||||||||||||
2122 | { | ||||||||||||||||
2123 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2124, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||||||
2124 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2124, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
2125 | sal_Int32 n = rtl_ustr_indexOfAscii_WithLength( | ||||||||||||||||
2126 | pData->buffer + fromIndex, pData->length - fromIndex, | ||||||||||||||||
2127 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), | ||||||||||||||||
2128 | libreoffice_internal::ConstCharArrayDetector<T>::length); | ||||||||||||||||
2129 | return n < 0 ? n : n + fromIndex; | ||||||||||||||||
2130 | } | ||||||||||||||||
2131 | |||||||||||||||||
2132 | /** | ||||||||||||||||
2133 | Returns the index within this string of the first occurrence of the | ||||||||||||||||
2134 | specified ASCII substring, starting at the specified index. | ||||||||||||||||
2135 | |||||||||||||||||
2136 | @param str | ||||||||||||||||
2137 | the substring to be searched for. Need not be null-terminated, but must | ||||||||||||||||
2138 | be at least as long as the specified len. Must only contain characters | ||||||||||||||||
2139 | in the ASCII range 0x00--7F. | ||||||||||||||||
2140 | |||||||||||||||||
2141 | @param len | ||||||||||||||||
2142 | the length of the substring; must be non-negative. | ||||||||||||||||
2143 | |||||||||||||||||
2144 | @param fromIndex | ||||||||||||||||
2145 | the index to start the search from. Must be in the range from zero to | ||||||||||||||||
2146 | the length of this string, inclusive. | ||||||||||||||||
2147 | |||||||||||||||||
2148 | @return | ||||||||||||||||
2149 | the index (starting at 0) of the first character of the first occurrence | ||||||||||||||||
2150 | of the substring within this string starting at the given fromIndex, or | ||||||||||||||||
2151 | -1 if the substring does not occur. If len is zero, -1 is returned. | ||||||||||||||||
2152 | |||||||||||||||||
2153 | @since UDK 3.2.7 | ||||||||||||||||
2154 | */ | ||||||||||||||||
2155 | sal_Int32 indexOfAsciiL( | ||||||||||||||||
2156 | char const * str, sal_Int32 len, sal_Int32 fromIndex = 0) const | ||||||||||||||||
2157 | { | ||||||||||||||||
2158 | sal_Int32 ret = rtl_ustr_indexOfAscii_WithLength( | ||||||||||||||||
2159 | pData->buffer + fromIndex, pData->length - fromIndex, str, len); | ||||||||||||||||
2160 | return ret < 0 ? ret : ret + fromIndex; | ||||||||||||||||
2161 | } | ||||||||||||||||
2162 | |||||||||||||||||
2163 | // This overload is left undefined, to detect calls of indexOfAsciiL that | ||||||||||||||||
2164 | // erroneously use RTL_CONSTASCII_USTRINGPARAM instead of | ||||||||||||||||
2165 | // RTL_CONSTASCII_STRINGPARAM (but would lead to ambiguities on 32 bit | ||||||||||||||||
2166 | // platforms): | ||||||||||||||||
2167 | #if SAL_TYPES_SIZEOFLONG8 == 8 | ||||||||||||||||
2168 | void indexOfAsciiL(char const *, sal_Int32 len, rtl_TextEncoding) const; | ||||||||||||||||
2169 | #endif | ||||||||||||||||
2170 | |||||||||||||||||
2171 | /** | ||||||||||||||||
2172 | Returns the index within this string of the last occurrence of | ||||||||||||||||
2173 | the specified substring, searching backward starting at the end. | ||||||||||||||||
2174 | |||||||||||||||||
2175 | The returned index indicates the starting index of the substring | ||||||||||||||||
2176 | in this string. | ||||||||||||||||
2177 | If str doesn't include any character, always -1 is | ||||||||||||||||
2178 | returned. This is also the case, if both strings are empty. | ||||||||||||||||
2179 | |||||||||||||||||
2180 | @param str the substring to search for. | ||||||||||||||||
2181 | @return If the string argument occurs one or more times as a substring | ||||||||||||||||
2182 | within this string, then the index of the first character of | ||||||||||||||||
2183 | the last such substring is returned. If it does not occur as | ||||||||||||||||
2184 | a substring, -1 is returned. | ||||||||||||||||
2185 | */ | ||||||||||||||||
2186 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
2187 | sal_Int32 lastIndexOf(std::u16string_view sv) const { | ||||||||||||||||
2188 | return rtl_ustr_lastIndexOfStr_WithLength( | ||||||||||||||||
2189 | pData->buffer, pData->length, sv.data(), sv.size()); | ||||||||||||||||
2190 | } | ||||||||||||||||
2191 | #else | ||||||||||||||||
2192 | sal_Int32 lastIndexOf( const OUString & str ) const | ||||||||||||||||
2193 | { | ||||||||||||||||
2194 | return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, pData->length, | ||||||||||||||||
2195 | str.pData->buffer, str.pData->length ); | ||||||||||||||||
2196 | } | ||||||||||||||||
2197 | #endif | ||||||||||||||||
2198 | |||||||||||||||||
2199 | /** | ||||||||||||||||
2200 | Returns the index within this string of the last occurrence of | ||||||||||||||||
2201 | the specified substring, searching backward starting before the specified | ||||||||||||||||
2202 | index. | ||||||||||||||||
2203 | |||||||||||||||||
2204 | The returned index indicates the starting index of the substring | ||||||||||||||||
2205 | in this string. | ||||||||||||||||
2206 | If str doesn't include any character, always -1 is | ||||||||||||||||
2207 | returned. This is also the case, if both strings are empty. | ||||||||||||||||
2208 | |||||||||||||||||
2209 | @param str the substring to search for. | ||||||||||||||||
2210 | @param fromIndex the index before which to start the search. | ||||||||||||||||
2211 | @return If the string argument occurs one or more times as a substring | ||||||||||||||||
2212 | within this string before the starting index, then the index | ||||||||||||||||
2213 | of the first character of the last such substring is | ||||||||||||||||
2214 | returned. Otherwise, -1 is returned. | ||||||||||||||||
2215 | */ | ||||||||||||||||
2216 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
2217 | sal_Int32 lastIndexOf(std::u16string_view sv, sal_Int32 fromIndex) const { | ||||||||||||||||
2218 | return rtl_ustr_lastIndexOfStr_WithLength(pData->buffer, fromIndex, sv.data(), sv.size()); | ||||||||||||||||
2219 | } | ||||||||||||||||
2220 | #else | ||||||||||||||||
2221 | sal_Int32 lastIndexOf( const OUString & str, sal_Int32 fromIndex ) const | ||||||||||||||||
2222 | { | ||||||||||||||||
2223 | return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, fromIndex, | ||||||||||||||||
2224 | str.pData->buffer, str.pData->length ); | ||||||||||||||||
2225 | } | ||||||||||||||||
2226 | #endif | ||||||||||||||||
2227 | |||||||||||||||||
2228 | /** | ||||||||||||||||
2229 | @overload | ||||||||||||||||
2230 | This function accepts an ASCII string literal as its argument. | ||||||||||||||||
2231 | @since LibreOffice 3.6 | ||||||||||||||||
2232 | */ | ||||||||||||||||
2233 | template< typename T > | ||||||||||||||||
2234 | typename libreoffice_internal::ConstCharArrayDetector< T, sal_Int32 >::Type lastIndexOf( T& literal ) const | ||||||||||||||||
2235 | { | ||||||||||||||||
2236 | assert((static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2237, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||||||
2237 | libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(literal)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2237, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
2238 | return rtl_ustr_lastIndexOfAscii_WithLength( | ||||||||||||||||
2239 | pData->buffer, pData->length, | ||||||||||||||||
2240 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), | ||||||||||||||||
2241 | libreoffice_internal::ConstCharArrayDetector<T>::length); | ||||||||||||||||
2242 | } | ||||||||||||||||
2243 | |||||||||||||||||
2244 | /** | ||||||||||||||||
2245 | Returns the index within this string of the last occurrence of the | ||||||||||||||||
2246 | specified ASCII substring. | ||||||||||||||||
2247 | |||||||||||||||||
2248 | @param str | ||||||||||||||||
2249 | the substring to be searched for. Need not be null-terminated, but must | ||||||||||||||||
2250 | be at least as long as the specified len. Must only contain characters | ||||||||||||||||
2251 | in the ASCII range 0x00--7F. | ||||||||||||||||
2252 | |||||||||||||||||
2253 | @param len | ||||||||||||||||
2254 | the length of the substring; must be non-negative. | ||||||||||||||||
2255 | |||||||||||||||||
2256 | @return | ||||||||||||||||
2257 | the index (starting at 0) of the first character of the last occurrence | ||||||||||||||||
2258 | of the substring within this string, or -1 if the substring does not | ||||||||||||||||
2259 | occur. If len is zero, -1 is returned. | ||||||||||||||||
2260 | |||||||||||||||||
2261 | @since UDK 3.2.7 | ||||||||||||||||
2262 | */ | ||||||||||||||||
2263 | sal_Int32 lastIndexOfAsciiL(char const * str, sal_Int32 len) const | ||||||||||||||||
2264 | { | ||||||||||||||||
2265 | return rtl_ustr_lastIndexOfAscii_WithLength( | ||||||||||||||||
2266 | pData->buffer, pData->length, str, len); | ||||||||||||||||
2267 | } | ||||||||||||||||
2268 | |||||||||||||||||
2269 | /** | ||||||||||||||||
2270 | Returns a new string that is a substring of this string. | ||||||||||||||||
2271 | |||||||||||||||||
2272 | The substring begins at the specified beginIndex. If | ||||||||||||||||
2273 | beginIndex is negative or be greater than the length of | ||||||||||||||||
2274 | this string, behaviour is undefined. | ||||||||||||||||
2275 | |||||||||||||||||
2276 | @param beginIndex the beginning index, inclusive. | ||||||||||||||||
2277 | @return the specified substring. | ||||||||||||||||
2278 | */ | ||||||||||||||||
2279 | SAL_WARN_UNUSED_RESULT[[nodiscard]] OUString copy( sal_Int32 beginIndex ) const | ||||||||||||||||
2280 | { | ||||||||||||||||
2281 | return copy(beginIndex, getLength() - beginIndex); | ||||||||||||||||
2282 | } | ||||||||||||||||
2283 | |||||||||||||||||
2284 | /** | ||||||||||||||||
2285 | Returns a new string that is a substring of this string. | ||||||||||||||||
2286 | |||||||||||||||||
2287 | The substring begins at the specified beginIndex and contains count | ||||||||||||||||
2288 | characters. If either beginIndex or count are negative, | ||||||||||||||||
2289 | or beginIndex + count are greater than the length of this string | ||||||||||||||||
2290 | then behaviour is undefined. | ||||||||||||||||
2291 | |||||||||||||||||
2292 | @param beginIndex the beginning index, inclusive. | ||||||||||||||||
2293 | @param count the number of characters. | ||||||||||||||||
2294 | @return the specified substring. | ||||||||||||||||
2295 | */ | ||||||||||||||||
2296 | SAL_WARN_UNUSED_RESULT[[nodiscard]] OUString copy( sal_Int32 beginIndex, sal_Int32 count ) const | ||||||||||||||||
2297 | { | ||||||||||||||||
2298 | rtl_uString *pNew = NULL__null; | ||||||||||||||||
2299 | rtl_uString_newFromSubString( &pNew, pData, beginIndex, count ); | ||||||||||||||||
2300 | return OUString( pNew, SAL_NO_ACQUIRE ); | ||||||||||||||||
2301 | } | ||||||||||||||||
2302 | |||||||||||||||||
2303 | /** | ||||||||||||||||
2304 | Concatenates the specified string to the end of this string. | ||||||||||||||||
2305 | |||||||||||||||||
2306 | @param str the string that is concatenated to the end | ||||||||||||||||
2307 | of this string. | ||||||||||||||||
2308 | @return a string that represents the concatenation of this string | ||||||||||||||||
2309 | followed by the string argument. | ||||||||||||||||
2310 | */ | ||||||||||||||||
2311 | SAL_WARN_UNUSED_RESULT[[nodiscard]] OUString concat( const OUString & str ) const | ||||||||||||||||
2312 | { | ||||||||||||||||
2313 | rtl_uString* pNew = NULL__null; | ||||||||||||||||
2314 | rtl_uString_newConcat( &pNew, pData, str.pData ); | ||||||||||||||||
2315 | return OUString( pNew, SAL_NO_ACQUIRE ); | ||||||||||||||||
2316 | } | ||||||||||||||||
2317 | |||||||||||||||||
2318 | #ifndef LIBO_INTERNAL_ONLY1 // "RTL_FAST_STRING" | ||||||||||||||||
2319 | friend OUString operator+( const OUString& rStr1, const OUString& rStr2 ) | ||||||||||||||||
2320 | { | ||||||||||||||||
2321 | return rStr1.concat( rStr2 ); | ||||||||||||||||
2322 | } | ||||||||||||||||
2323 | #endif | ||||||||||||||||
2324 | |||||||||||||||||
2325 | /** | ||||||||||||||||
2326 | Returns a new string resulting from replacing n = count characters | ||||||||||||||||
2327 | from position index in this string with newStr. | ||||||||||||||||
2328 | |||||||||||||||||
2329 | @param index the replacing index in str. | ||||||||||||||||
2330 | The index must be greater than or equal to 0 and | ||||||||||||||||
2331 | less than or equal to the length of the string. | ||||||||||||||||
2332 | @param count the count of characters that will be replaced | ||||||||||||||||
2333 | The count must be greater than or equal to 0 and | ||||||||||||||||
2334 | less than or equal to the length of the string minus index. | ||||||||||||||||
2335 | @param newStr the new substring. | ||||||||||||||||
2336 | @return the new string. | ||||||||||||||||
2337 | */ | ||||||||||||||||
2338 | SAL_WARN_UNUSED_RESULT[[nodiscard]] OUString replaceAt( sal_Int32 index, sal_Int32 count, const OUString& newStr ) const | ||||||||||||||||
2339 | { | ||||||||||||||||
2340 | rtl_uString* pNew = NULL__null; | ||||||||||||||||
2341 | rtl_uString_newReplaceStrAt( &pNew, pData, index, count, newStr.pData ); | ||||||||||||||||
2342 | return OUString( pNew, SAL_NO_ACQUIRE ); | ||||||||||||||||
2343 | } | ||||||||||||||||
2344 | |||||||||||||||||
2345 | /** | ||||||||||||||||
2346 | Returns a new string resulting from replacing all occurrences of | ||||||||||||||||
2347 | oldChar in this string with newChar. | ||||||||||||||||
2348 | |||||||||||||||||
2349 | If the character oldChar does not occur in the character sequence | ||||||||||||||||
2350 | represented by this object, then the string is assigned with | ||||||||||||||||
2351 | str. | ||||||||||||||||
2352 | |||||||||||||||||
2353 | @param oldChar the old character. | ||||||||||||||||
2354 | @param newChar the new character. | ||||||||||||||||
2355 | @return a string derived from this string by replacing every | ||||||||||||||||
2356 | occurrence of oldChar with newChar. | ||||||||||||||||
2357 | */ | ||||||||||||||||
2358 | SAL_WARN_UNUSED_RESULT[[nodiscard]] OUString replace( sal_Unicode oldChar, sal_Unicode newChar ) const | ||||||||||||||||
2359 | { | ||||||||||||||||
2360 | rtl_uString* pNew = NULL__null; | ||||||||||||||||
2361 | rtl_uString_newReplace( &pNew, pData, oldChar, newChar ); | ||||||||||||||||
2362 | return OUString( pNew, SAL_NO_ACQUIRE ); | ||||||||||||||||
2363 | } | ||||||||||||||||
2364 | |||||||||||||||||
2365 | /** | ||||||||||||||||
2366 | Returns a new string resulting from replacing the first occurrence of a | ||||||||||||||||
2367 | given substring with another substring. | ||||||||||||||||
2368 | |||||||||||||||||
2369 | @param from the substring to be replaced | ||||||||||||||||
2370 | |||||||||||||||||
2371 | @param to the replacing substring | ||||||||||||||||
2372 | |||||||||||||||||
2373 | @param[in,out] index pointer to a start index; if the pointer is | ||||||||||||||||
2374 | non-null: upon entry to the function, its value is the index into this | ||||||||||||||||
2375 | string at which to start searching for the \p from substring, the value | ||||||||||||||||
2376 | must be non-negative and not greater than this string's length; upon exiting | ||||||||||||||||
2377 | the function its value is the index into this string at which the | ||||||||||||||||
2378 | replacement took place or -1 if no replacement took place; if the pointer | ||||||||||||||||
2379 | is null, searching always starts at index 0 | ||||||||||||||||
2380 | |||||||||||||||||
2381 | @since LibreOffice 3.6 | ||||||||||||||||
2382 | */ | ||||||||||||||||
2383 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
2384 | [[nodiscard]] OUString replaceFirst( | ||||||||||||||||
2385 | std::u16string_view from, std::u16string_view to, sal_Int32 * index = nullptr) const | ||||||||||||||||
2386 | { | ||||||||||||||||
2387 | rtl_uString * s = nullptr; | ||||||||||||||||
2388 | sal_Int32 i = 0; | ||||||||||||||||
2389 | rtl_uString_newReplaceFirstUtf16LUtf16L( | ||||||||||||||||
2390 | &s, pData, from.data(), from.size(), to.data(), to.size(), | ||||||||||||||||
2391 | index == nullptr ? &i : index); | ||||||||||||||||
2392 | return OUString(s, SAL_NO_ACQUIRE); | ||||||||||||||||
2393 | } | ||||||||||||||||
2394 | #else | ||||||||||||||||
2395 | SAL_WARN_UNUSED_RESULT[[nodiscard]] OUString replaceFirst( | ||||||||||||||||
2396 | OUString const & from, OUString const & to, sal_Int32 * index = NULL__null) const | ||||||||||||||||
2397 | { | ||||||||||||||||
2398 | rtl_uString * s = NULL__null; | ||||||||||||||||
2399 | sal_Int32 i = 0; | ||||||||||||||||
2400 | rtl_uString_newReplaceFirst( | ||||||||||||||||
2401 | &s, pData, from.pData, to.pData, index == NULL__null ? &i : index); | ||||||||||||||||
2402 | return OUString(s, SAL_NO_ACQUIRE); | ||||||||||||||||
2403 | } | ||||||||||||||||
2404 | #endif | ||||||||||||||||
2405 | |||||||||||||||||
2406 | /** | ||||||||||||||||
2407 | Returns a new string resulting from replacing the first occurrence of a | ||||||||||||||||
2408 | given substring with another substring. | ||||||||||||||||
2409 | |||||||||||||||||
2410 | @param from ASCII string literal, the substring to be replaced | ||||||||||||||||
2411 | |||||||||||||||||
2412 | @param to the replacing substring | ||||||||||||||||
2413 | |||||||||||||||||
2414 | @param[in,out] index pointer to a start index; if the pointer is | ||||||||||||||||
2415 | non-null: upon entry to the function, its value is the index into the this | ||||||||||||||||
2416 | string at which to start searching for the \p from substring, the value | ||||||||||||||||
2417 | must be non-negative and not greater than this string's length; upon exiting | ||||||||||||||||
2418 | the function its value is the index into this string at which the | ||||||||||||||||
2419 | replacement took place or -1 if no replacement took place; if the pointer | ||||||||||||||||
2420 | is null, searching always starts at index 0 | ||||||||||||||||
2421 | |||||||||||||||||
2422 | @since LibreOffice 3.6 | ||||||||||||||||
2423 | */ | ||||||||||||||||
2424 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
2425 | template<typename T> [[nodiscard]] | ||||||||||||||||
2426 | typename libreoffice_internal::ConstCharArrayDetector<T, OUString >::Type replaceFirst( | ||||||||||||||||
2427 | T & from, std::u16string_view to, sal_Int32 * index = nullptr) const | ||||||||||||||||
2428 | { | ||||||||||||||||
2429 | assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(from))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(from)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(from)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2429, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
2430 | rtl_uString * s = nullptr; | ||||||||||||||||
2431 | sal_Int32 i = 0; | ||||||||||||||||
2432 | rtl_uString_newReplaceFirstAsciiLUtf16L( | ||||||||||||||||
2433 | &s, pData, libreoffice_internal::ConstCharArrayDetector<T>::toPointer(from), | ||||||||||||||||
2434 | libreoffice_internal::ConstCharArrayDetector<T>::length, to.data(), to.size(), | ||||||||||||||||
2435 | index == nullptr ? &i : index); | ||||||||||||||||
2436 | return OUString(s, SAL_NO_ACQUIRE); | ||||||||||||||||
2437 | } | ||||||||||||||||
2438 | #else | ||||||||||||||||
2439 | template< typename T > | ||||||||||||||||
2440 | SAL_WARN_UNUSED_RESULT[[nodiscard]] typename libreoffice_internal::ConstCharArrayDetector< T, OUString >::Type replaceFirst( T& from, OUString const & to, | ||||||||||||||||
2441 | sal_Int32 * index = NULL__null) const | ||||||||||||||||
2442 | { | ||||||||||||||||
2443 | assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(from))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(from)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(from)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2443, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
2444 | rtl_uString * s = NULL__null; | ||||||||||||||||
2445 | sal_Int32 i = 0; | ||||||||||||||||
2446 | rtl_uString_newReplaceFirstAsciiL( | ||||||||||||||||
2447 | &s, pData, | ||||||||||||||||
2448 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(from), | ||||||||||||||||
2449 | libreoffice_internal::ConstCharArrayDetector<T>::length, to.pData, | ||||||||||||||||
2450 | index == NULL__null ? &i : index); | ||||||||||||||||
2451 | return OUString(s, SAL_NO_ACQUIRE); | ||||||||||||||||
2452 | } | ||||||||||||||||
2453 | #endif | ||||||||||||||||
2454 | |||||||||||||||||
2455 | /** | ||||||||||||||||
2456 | Returns a new string resulting from replacing the first occurrence of a | ||||||||||||||||
2457 | given substring with another substring. | ||||||||||||||||
2458 | |||||||||||||||||
2459 | @param from the substring to be replaced | ||||||||||||||||
2460 | |||||||||||||||||
2461 | @param to ASCII string literal, the replacing substring | ||||||||||||||||
2462 | |||||||||||||||||
2463 | @param[in,out] index pointer to a start index; if the pointer is | ||||||||||||||||
2464 | non-null: upon entry to the function, its value is the index into the this | ||||||||||||||||
2465 | string at which to start searching for the \p from substring, the value | ||||||||||||||||
2466 | must be non-negative and not greater than this string's length; upon exiting | ||||||||||||||||
2467 | the function its value is the index into this string at which the | ||||||||||||||||
2468 | replacement took place or -1 if no replacement took place; if the pointer | ||||||||||||||||
2469 | is null, searching always starts at index 0 | ||||||||||||||||
2470 | |||||||||||||||||
2471 | @since LibreOffice 5.1 | ||||||||||||||||
2472 | */ | ||||||||||||||||
2473 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
2474 | template<typename T> [[nodiscard]] | ||||||||||||||||
2475 | typename libreoffice_internal::ConstCharArrayDetector<T, OUString >::Type replaceFirst( | ||||||||||||||||
2476 | std::u16string_view from, T & to, sal_Int32 * index = nullptr) const | ||||||||||||||||
2477 | { | ||||||||||||||||
2478 | assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(to))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(to)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(to)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2478, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
2479 | rtl_uString * s = nullptr; | ||||||||||||||||
2480 | sal_Int32 i = 0; | ||||||||||||||||
2481 | rtl_uString_newReplaceFirstUtf16LAsciiL( | ||||||||||||||||
2482 | &s, pData, from.data(), from.size(), | ||||||||||||||||
2483 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(to), | ||||||||||||||||
2484 | libreoffice_internal::ConstCharArrayDetector<T>::length, index == nullptr ? &i : index); | ||||||||||||||||
2485 | return OUString(s, SAL_NO_ACQUIRE); | ||||||||||||||||
2486 | } | ||||||||||||||||
2487 | #else | ||||||||||||||||
2488 | template< typename T > | ||||||||||||||||
2489 | SAL_WARN_UNUSED_RESULT[[nodiscard]] typename libreoffice_internal::ConstCharArrayDetector< T, OUString >::Type replaceFirst( OUString const & from, T& to, | ||||||||||||||||
2490 | sal_Int32 * index = NULL__null) const | ||||||||||||||||
2491 | { | ||||||||||||||||
2492 | assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(to))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(to)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(to)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2492, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
2493 | rtl_uString * s = NULL__null; | ||||||||||||||||
2494 | sal_Int32 i = 0; | ||||||||||||||||
2495 | rtl_uString_newReplaceFirstToAsciiL( | ||||||||||||||||
2496 | &s, pData, from.pData, | ||||||||||||||||
2497 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(to), | ||||||||||||||||
2498 | libreoffice_internal::ConstCharArrayDetector<T>::length, | ||||||||||||||||
2499 | index == NULL__null ? &i : index); | ||||||||||||||||
2500 | return OUString(s, SAL_NO_ACQUIRE); | ||||||||||||||||
2501 | } | ||||||||||||||||
2502 | #endif | ||||||||||||||||
2503 | |||||||||||||||||
2504 | /** | ||||||||||||||||
2505 | Returns a new string resulting from replacing the first occurrence of a | ||||||||||||||||
2506 | given substring with another substring. | ||||||||||||||||
2507 | |||||||||||||||||
2508 | @param from ASCII string literal, the substring to be replaced | ||||||||||||||||
2509 | |||||||||||||||||
2510 | @param to ASCII string literal, the substring to be replaced | ||||||||||||||||
2511 | |||||||||||||||||
2512 | @param[in,out] index pointer to a start index; if the pointer is | ||||||||||||||||
2513 | non-null: upon entry to the function, its value is the index into the this | ||||||||||||||||
2514 | string at which to start searching for the \p from substring, the value | ||||||||||||||||
2515 | must be non-negative and not greater than this string's length; upon exiting | ||||||||||||||||
2516 | the function its value is the index into this string at which the | ||||||||||||||||
2517 | replacement took place or -1 if no replacement took place; if the pointer | ||||||||||||||||
2518 | is null, searching always starts at index 0 | ||||||||||||||||
2519 | |||||||||||||||||
2520 | @since LibreOffice 3.6 | ||||||||||||||||
2521 | */ | ||||||||||||||||
2522 | template< typename T1, typename T2 > | ||||||||||||||||
2523 | SAL_WARN_UNUSED_RESULT[[nodiscard]] typename libreoffice_internal::ConstCharArrayDetector< T1, typename libreoffice_internal::ConstCharArrayDetector< T2, OUString >::Type >::Type | ||||||||||||||||
2524 | replaceFirst( T1& from, T2& to, sal_Int32 * index = NULL__null) const | ||||||||||||||||
2525 | { | ||||||||||||||||
2526 | assert(libreoffice_internal::ConstCharArrayDetector<T1>::isValid(from))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T1>::isValid(from)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T1>::isValid(from)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2526, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
2527 | assert(libreoffice_internal::ConstCharArrayDetector<T2>::isValid(to))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T2>::isValid(to)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T2>::isValid(to)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2527, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
2528 | rtl_uString * s = NULL__null; | ||||||||||||||||
2529 | sal_Int32 i = 0; | ||||||||||||||||
2530 | rtl_uString_newReplaceFirstAsciiLAsciiL( | ||||||||||||||||
2531 | &s, pData, | ||||||||||||||||
2532 | libreoffice_internal::ConstCharArrayDetector<T1>::toPointer(from), | ||||||||||||||||
2533 | libreoffice_internal::ConstCharArrayDetector<T1>::length, | ||||||||||||||||
2534 | libreoffice_internal::ConstCharArrayDetector<T2>::toPointer(to), | ||||||||||||||||
2535 | libreoffice_internal::ConstCharArrayDetector<T2>::length, | ||||||||||||||||
2536 | index == NULL__null ? &i : index); | ||||||||||||||||
2537 | return OUString(s, SAL_NO_ACQUIRE); | ||||||||||||||||
2538 | } | ||||||||||||||||
2539 | |||||||||||||||||
2540 | /** | ||||||||||||||||
2541 | Returns a new string resulting from replacing all occurrences of a given | ||||||||||||||||
2542 | substring with another substring. | ||||||||||||||||
2543 | |||||||||||||||||
2544 | Replacing subsequent occurrences picks up only after a given replacement. | ||||||||||||||||
2545 | That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx". | ||||||||||||||||
2546 | |||||||||||||||||
2547 | @param from the substring to be replaced | ||||||||||||||||
2548 | |||||||||||||||||
2549 | @param to the replacing substring | ||||||||||||||||
2550 | |||||||||||||||||
2551 | @param fromIndex the position in the string where we will begin searching | ||||||||||||||||
2552 | |||||||||||||||||
2553 | @since LibreOffice 4.0 | ||||||||||||||||
2554 | */ | ||||||||||||||||
2555 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
2556 | [[nodiscard]] OUString replaceAll( | ||||||||||||||||
2557 | std::u16string_view from, std::u16string_view to, sal_Int32 fromIndex = 0) const | ||||||||||||||||
2558 | { | ||||||||||||||||
2559 | rtl_uString * s = nullptr; | ||||||||||||||||
2560 | rtl_uString_newReplaceAllFromIndexUtf16LUtf16L( | ||||||||||||||||
2561 | &s, pData, from.data(), from.size(), to.data(), to.size(), fromIndex); | ||||||||||||||||
2562 | return OUString(s, SAL_NO_ACQUIRE); | ||||||||||||||||
2563 | } | ||||||||||||||||
2564 | #else | ||||||||||||||||
2565 | SAL_WARN_UNUSED_RESULT[[nodiscard]] OUString replaceAll( | ||||||||||||||||
2566 | OUString const & from, OUString const & to, sal_Int32 fromIndex = 0) const | ||||||||||||||||
2567 | { | ||||||||||||||||
2568 | rtl_uString * s = NULL__null; | ||||||||||||||||
2569 | rtl_uString_newReplaceAllFromIndex(&s, pData, from.pData, to.pData, fromIndex); | ||||||||||||||||
2570 | return OUString(s, SAL_NO_ACQUIRE); | ||||||||||||||||
2571 | } | ||||||||||||||||
2572 | #endif | ||||||||||||||||
2573 | |||||||||||||||||
2574 | /** | ||||||||||||||||
2575 | Returns a new string resulting from replacing all occurrences of a given | ||||||||||||||||
2576 | substring with another substring. | ||||||||||||||||
2577 | |||||||||||||||||
2578 | Replacing subsequent occurrences picks up only after a given replacement. | ||||||||||||||||
2579 | That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx". | ||||||||||||||||
2580 | |||||||||||||||||
2581 | @param from ASCII string literal, the substring to be replaced | ||||||||||||||||
2582 | |||||||||||||||||
2583 | @param to the replacing substring | ||||||||||||||||
2584 | |||||||||||||||||
2585 | @since LibreOffice 3.6 | ||||||||||||||||
2586 | */ | ||||||||||||||||
2587 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
2588 | template<typename T> [[nodiscard]] | ||||||||||||||||
2589 | typename libreoffice_internal::ConstCharArrayDetector<T, OUString >::Type replaceAll( | ||||||||||||||||
2590 | T & from, std::u16string_view to) const | ||||||||||||||||
2591 | { | ||||||||||||||||
2592 | assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(from))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(from)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(from)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2592, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
2593 | rtl_uString * s = nullptr; | ||||||||||||||||
2594 | rtl_uString_newReplaceAllAsciiLUtf16L( | ||||||||||||||||
2595 | &s, pData, libreoffice_internal::ConstCharArrayDetector<T>::toPointer(from), | ||||||||||||||||
2596 | libreoffice_internal::ConstCharArrayDetector<T>::length, to.data(), to.size()); | ||||||||||||||||
2597 | return OUString(s, SAL_NO_ACQUIRE); | ||||||||||||||||
2598 | } | ||||||||||||||||
2599 | #else | ||||||||||||||||
2600 | template< typename T > | ||||||||||||||||
2601 | SAL_WARN_UNUSED_RESULT[[nodiscard]] typename libreoffice_internal::ConstCharArrayDetector< T, OUString >::Type replaceAll( T& from, OUString const & to) const | ||||||||||||||||
2602 | { | ||||||||||||||||
2603 | assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(from))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(from)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(from)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2603, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
2604 | rtl_uString * s = NULL__null; | ||||||||||||||||
2605 | rtl_uString_newReplaceAllAsciiL( | ||||||||||||||||
2606 | &s, pData, | ||||||||||||||||
2607 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(from), | ||||||||||||||||
2608 | libreoffice_internal::ConstCharArrayDetector<T>::length, to.pData); | ||||||||||||||||
2609 | return OUString(s, SAL_NO_ACQUIRE); | ||||||||||||||||
2610 | } | ||||||||||||||||
2611 | #endif | ||||||||||||||||
2612 | |||||||||||||||||
2613 | /** | ||||||||||||||||
2614 | Returns a new string resulting from replacing all occurrences of a given | ||||||||||||||||
2615 | substring with another substring. | ||||||||||||||||
2616 | |||||||||||||||||
2617 | Replacing subsequent occurrences picks up only after a given replacement. | ||||||||||||||||
2618 | That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx". | ||||||||||||||||
2619 | |||||||||||||||||
2620 | @param from the substring to be replaced | ||||||||||||||||
2621 | |||||||||||||||||
2622 | @param to ASCII string literal, the replacing substring | ||||||||||||||||
2623 | |||||||||||||||||
2624 | @since LibreOffice 5.1 | ||||||||||||||||
2625 | */ | ||||||||||||||||
2626 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
2627 | template<typename T> [[nodiscard]] | ||||||||||||||||
2628 | typename libreoffice_internal::ConstCharArrayDetector<T, OUString >::Type replaceAll( | ||||||||||||||||
2629 | std::u16string_view from, T & to) const | ||||||||||||||||
2630 | { | ||||||||||||||||
2631 | assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(to))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(to)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(to)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2631, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
2632 | rtl_uString * s = nullptr; | ||||||||||||||||
2633 | rtl_uString_newReplaceAllUtf16LAsciiL( | ||||||||||||||||
2634 | &s, pData, from.data(), from.size(), | ||||||||||||||||
2635 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(to), | ||||||||||||||||
2636 | libreoffice_internal::ConstCharArrayDetector<T>::length); | ||||||||||||||||
2637 | return OUString(s, SAL_NO_ACQUIRE); | ||||||||||||||||
2638 | } | ||||||||||||||||
2639 | #else | ||||||||||||||||
2640 | template< typename T > | ||||||||||||||||
2641 | SAL_WARN_UNUSED_RESULT[[nodiscard]] typename libreoffice_internal::ConstCharArrayDetector< T, OUString >::Type replaceAll( OUString const & from, T& to) const | ||||||||||||||||
2642 | { | ||||||||||||||||
2643 | assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(to))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T>::isValid(to)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T>::isValid(to)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2643, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
2644 | rtl_uString * s = NULL__null; | ||||||||||||||||
2645 | rtl_uString_newReplaceAllToAsciiL( | ||||||||||||||||
2646 | &s, pData, from.pData, | ||||||||||||||||
2647 | libreoffice_internal::ConstCharArrayDetector<T>::toPointer(to), | ||||||||||||||||
2648 | libreoffice_internal::ConstCharArrayDetector<T>::length); | ||||||||||||||||
2649 | return OUString(s, SAL_NO_ACQUIRE); | ||||||||||||||||
2650 | } | ||||||||||||||||
2651 | #endif | ||||||||||||||||
2652 | |||||||||||||||||
2653 | /** | ||||||||||||||||
2654 | Returns a new string resulting from replacing all occurrences of a given | ||||||||||||||||
2655 | substring with another substring. | ||||||||||||||||
2656 | |||||||||||||||||
2657 | Replacing subsequent occurrences picks up only after a given replacement. | ||||||||||||||||
2658 | That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx". | ||||||||||||||||
2659 | |||||||||||||||||
2660 | @param from ASCII string literal, the substring to be replaced | ||||||||||||||||
2661 | |||||||||||||||||
2662 | @param to ASCII string literal, the substring to be replaced | ||||||||||||||||
2663 | |||||||||||||||||
2664 | @since LibreOffice 3.6 | ||||||||||||||||
2665 | */ | ||||||||||||||||
2666 | template< typename T1, typename T2 > | ||||||||||||||||
2667 | SAL_WARN_UNUSED_RESULT[[nodiscard]] typename libreoffice_internal::ConstCharArrayDetector< T1, typename libreoffice_internal::ConstCharArrayDetector< T2, OUString >::Type >::Type | ||||||||||||||||
2668 | replaceAll( T1& from, T2& to ) const | ||||||||||||||||
2669 | { | ||||||||||||||||
2670 | assert(libreoffice_internal::ConstCharArrayDetector<T1>::isValid(from))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T1>::isValid(from)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T1>::isValid(from)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2670, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
2671 | assert(libreoffice_internal::ConstCharArrayDetector<T2>::isValid(to))(static_cast <bool> (libreoffice_internal::ConstCharArrayDetector <T2>::isValid(to)) ? void (0) : __assert_fail ("libreoffice_internal::ConstCharArrayDetector<T2>::isValid(to)" , "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 2671, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
2672 | rtl_uString * s = NULL__null; | ||||||||||||||||
2673 | rtl_uString_newReplaceAllAsciiLAsciiL( | ||||||||||||||||
2674 | &s, pData, | ||||||||||||||||
2675 | libreoffice_internal::ConstCharArrayDetector<T1>::toPointer(from), | ||||||||||||||||
2676 | libreoffice_internal::ConstCharArrayDetector<T1>::length, | ||||||||||||||||
2677 | libreoffice_internal::ConstCharArrayDetector<T2>::toPointer(to), | ||||||||||||||||
2678 | libreoffice_internal::ConstCharArrayDetector<T2>::length); | ||||||||||||||||
2679 | return OUString(s, SAL_NO_ACQUIRE); | ||||||||||||||||
2680 | } | ||||||||||||||||
2681 | |||||||||||||||||
2682 | /** | ||||||||||||||||
2683 | Converts from this string all ASCII uppercase characters (65-90) | ||||||||||||||||
2684 | to ASCII lowercase characters (97-122). | ||||||||||||||||
2685 | |||||||||||||||||
2686 | This function can't be used for language specific conversion. | ||||||||||||||||
2687 | If the string doesn't contain characters which must be converted, | ||||||||||||||||
2688 | then the new string is assigned with str. | ||||||||||||||||
2689 | |||||||||||||||||
2690 | @return the string, converted to ASCII lowercase. | ||||||||||||||||
2691 | */ | ||||||||||||||||
2692 | SAL_WARN_UNUSED_RESULT[[nodiscard]] OUString toAsciiLowerCase() const | ||||||||||||||||
2693 | { | ||||||||||||||||
2694 | rtl_uString* pNew = NULL__null; | ||||||||||||||||
2695 | rtl_uString_newToAsciiLowerCase( &pNew, pData ); | ||||||||||||||||
2696 | return OUString( pNew, SAL_NO_ACQUIRE ); | ||||||||||||||||
2697 | } | ||||||||||||||||
2698 | |||||||||||||||||
2699 | /** | ||||||||||||||||
2700 | Converts from this string all ASCII lowercase characters (97-122) | ||||||||||||||||
2701 | to ASCII uppercase characters (65-90). | ||||||||||||||||
2702 | |||||||||||||||||
2703 | This function can't be used for language specific conversion. | ||||||||||||||||
2704 | If the string doesn't contain characters which must be converted, | ||||||||||||||||
2705 | then the new string is assigned with str. | ||||||||||||||||
2706 | |||||||||||||||||
2707 | @return the string, converted to ASCII uppercase. | ||||||||||||||||
2708 | */ | ||||||||||||||||
2709 | SAL_WARN_UNUSED_RESULT[[nodiscard]] OUString toAsciiUpperCase() const | ||||||||||||||||
2710 | { | ||||||||||||||||
2711 | rtl_uString* pNew = NULL__null; | ||||||||||||||||
2712 | rtl_uString_newToAsciiUpperCase( &pNew, pData ); | ||||||||||||||||
2713 | return OUString( pNew, SAL_NO_ACQUIRE ); | ||||||||||||||||
2714 | } | ||||||||||||||||
2715 | |||||||||||||||||
2716 | /** | ||||||||||||||||
2717 | Returns a new string resulting from removing white space from both ends | ||||||||||||||||
2718 | of the string. | ||||||||||||||||
2719 | |||||||||||||||||
2720 | All characters that have codes less than or equal to | ||||||||||||||||
2721 | 32 (the space character), and Unicode General Punctuation area Space | ||||||||||||||||
2722 | and some Control characters are considered to be white space (see | ||||||||||||||||
2723 | rtl_ImplIsWhitespace). | ||||||||||||||||
2724 | If the string doesn't contain white spaces at both ends, | ||||||||||||||||
2725 | then the new string is assigned with str. | ||||||||||||||||
2726 | |||||||||||||||||
2727 | @return the string, with white space removed from the front and end. | ||||||||||||||||
2728 | */ | ||||||||||||||||
2729 | SAL_WARN_UNUSED_RESULT[[nodiscard]] OUString trim() const | ||||||||||||||||
2730 | { | ||||||||||||||||
2731 | rtl_uString* pNew = NULL__null; | ||||||||||||||||
2732 | rtl_uString_newTrim( &pNew, pData ); | ||||||||||||||||
2733 | return OUString( pNew, SAL_NO_ACQUIRE ); | ||||||||||||||||
2734 | } | ||||||||||||||||
2735 | |||||||||||||||||
2736 | /** | ||||||||||||||||
2737 | Returns a token in the string. | ||||||||||||||||
2738 | |||||||||||||||||
2739 | Example: | ||||||||||||||||
2740 | sal_Int32 nIndex = 0; | ||||||||||||||||
2741 | do | ||||||||||||||||
2742 | { | ||||||||||||||||
2743 | ... | ||||||||||||||||
2744 | OUString aToken = aStr.getToken( 0, ';', nIndex ); | ||||||||||||||||
2745 | ... | ||||||||||||||||
2746 | } | ||||||||||||||||
2747 | while ( nIndex >= 0 ); | ||||||||||||||||
2748 | |||||||||||||||||
2749 | @param token the number of the token to return | ||||||||||||||||
2750 | @param cTok the character which separate the tokens. | ||||||||||||||||
2751 | @param index the position at which the token is searched in the | ||||||||||||||||
2752 | string. | ||||||||||||||||
2753 | The index must not be greater than the length of the | ||||||||||||||||
2754 | string. | ||||||||||||||||
2755 | This param is set to the position of the | ||||||||||||||||
2756 | next token or to -1, if it is the last token. | ||||||||||||||||
2757 | @return the token; if either token or index is negative, an empty token | ||||||||||||||||
2758 | is returned (and index is set to -1) | ||||||||||||||||
2759 | */ | ||||||||||||||||
2760 | OUString getToken( sal_Int32 token, sal_Unicode cTok, sal_Int32& index ) const | ||||||||||||||||
2761 | { | ||||||||||||||||
2762 | rtl_uString * pNew = NULL__null; | ||||||||||||||||
2763 | index = rtl_uString_getToken( &pNew, pData, token, cTok, index ); | ||||||||||||||||
2764 | return OUString( pNew, SAL_NO_ACQUIRE ); | ||||||||||||||||
2765 | } | ||||||||||||||||
2766 | |||||||||||||||||
2767 | /** | ||||||||||||||||
2768 | Returns a token from the string. | ||||||||||||||||
2769 | |||||||||||||||||
2770 | The same as getToken(sal_Int32, sal_Unicode, sal_Int32 &), but always | ||||||||||||||||
2771 | passing in 0 as the start index in the third argument. | ||||||||||||||||
2772 | |||||||||||||||||
2773 | @param count the number of the token to return, starting with 0 | ||||||||||||||||
2774 | @param separator the character which separates the tokens | ||||||||||||||||
2775 | |||||||||||||||||
2776 | @return the given token, or an empty string | ||||||||||||||||
2777 | |||||||||||||||||
2778 | @since LibreOffice 3.6 | ||||||||||||||||
2779 | */ | ||||||||||||||||
2780 | OUString getToken(sal_Int32 count, sal_Unicode separator) const { | ||||||||||||||||
2781 | sal_Int32 n = 0; | ||||||||||||||||
2782 | return getToken(count, separator, n); | ||||||||||||||||
2783 | } | ||||||||||||||||
2784 | |||||||||||||||||
2785 | /** | ||||||||||||||||
2786 | Returns the Boolean value from this string. | ||||||||||||||||
2787 | |||||||||||||||||
2788 | This function can't be used for language specific conversion. | ||||||||||||||||
2789 | |||||||||||||||||
2790 | @return true, if the string is 1 or "True" in any ASCII case. | ||||||||||||||||
2791 | false in any other case. | ||||||||||||||||
2792 | */ | ||||||||||||||||
2793 | bool toBoolean() const | ||||||||||||||||
2794 | { | ||||||||||||||||
2795 | return rtl_ustr_toBoolean( pData->buffer ); | ||||||||||||||||
2796 | } | ||||||||||||||||
2797 | |||||||||||||||||
2798 | /** | ||||||||||||||||
2799 | Returns the first character from this string. | ||||||||||||||||
2800 | |||||||||||||||||
2801 | @return the first character from this string or 0, if this string | ||||||||||||||||
2802 | is empty. | ||||||||||||||||
2803 | */ | ||||||||||||||||
2804 | sal_Unicode toChar() const | ||||||||||||||||
2805 | { | ||||||||||||||||
2806 | return pData->buffer[0]; | ||||||||||||||||
2807 | } | ||||||||||||||||
2808 | |||||||||||||||||
2809 | /** | ||||||||||||||||
2810 | Returns the int32 value from this string. | ||||||||||||||||
2811 | |||||||||||||||||
2812 | This function can't be used for language specific conversion. | ||||||||||||||||
2813 | |||||||||||||||||
2814 | @param radix the radix (between 2 and 36) | ||||||||||||||||
2815 | @return the int32 represented from this string. | ||||||||||||||||
2816 | 0 if this string represents no number or one of too large | ||||||||||||||||
2817 | magnitude. | ||||||||||||||||
2818 | */ | ||||||||||||||||
2819 | sal_Int32 toInt32( sal_Int16 radix = 10 ) const | ||||||||||||||||
2820 | { | ||||||||||||||||
2821 | return rtl_ustr_toInt32( pData->buffer, radix ); | ||||||||||||||||
2822 | } | ||||||||||||||||
2823 | |||||||||||||||||
2824 | /** | ||||||||||||||||
2825 | Returns the uint32 value from this string. | ||||||||||||||||
2826 | |||||||||||||||||
2827 | This function can't be used for language specific conversion. | ||||||||||||||||
2828 | |||||||||||||||||
2829 | @param radix the radix (between 2 and 36) | ||||||||||||||||
2830 | @return the uint32 represented from this string. | ||||||||||||||||
2831 | 0 if this string represents no number or one of too large | ||||||||||||||||
2832 | magnitude. | ||||||||||||||||
2833 | |||||||||||||||||
2834 | @since LibreOffice 4.2 | ||||||||||||||||
2835 | */ | ||||||||||||||||
2836 | sal_uInt32 toUInt32( sal_Int16 radix = 10 ) const | ||||||||||||||||
2837 | { | ||||||||||||||||
2838 | return rtl_ustr_toUInt32( pData->buffer, radix ); | ||||||||||||||||
2839 | } | ||||||||||||||||
2840 | |||||||||||||||||
2841 | /** | ||||||||||||||||
2842 | Returns the int64 value from this string. | ||||||||||||||||
2843 | |||||||||||||||||
2844 | This function can't be used for language specific conversion. | ||||||||||||||||
2845 | |||||||||||||||||
2846 | @param radix the radix (between 2 and 36) | ||||||||||||||||
2847 | @return the int64 represented from this string. | ||||||||||||||||
2848 | 0 if this string represents no number or one of too large | ||||||||||||||||
2849 | magnitude. | ||||||||||||||||
2850 | */ | ||||||||||||||||
2851 | sal_Int64 toInt64( sal_Int16 radix = 10 ) const | ||||||||||||||||
2852 | { | ||||||||||||||||
2853 | return rtl_ustr_toInt64( pData->buffer, radix ); | ||||||||||||||||
2854 | } | ||||||||||||||||
2855 | |||||||||||||||||
2856 | /** | ||||||||||||||||
2857 | Returns the uint64 value from this string. | ||||||||||||||||
2858 | |||||||||||||||||
2859 | This function can't be used for language specific conversion. | ||||||||||||||||
2860 | |||||||||||||||||
2861 | @param radix the radix (between 2 and 36) | ||||||||||||||||
2862 | @return the uint64 represented from this string. | ||||||||||||||||
2863 | 0 if this string represents no number or one of too large | ||||||||||||||||
2864 | magnitude. | ||||||||||||||||
2865 | |||||||||||||||||
2866 | @since LibreOffice 4.1 | ||||||||||||||||
2867 | */ | ||||||||||||||||
2868 | sal_uInt64 toUInt64( sal_Int16 radix = 10 ) const | ||||||||||||||||
2869 | { | ||||||||||||||||
2870 | return rtl_ustr_toUInt64( pData->buffer, radix ); | ||||||||||||||||
2871 | } | ||||||||||||||||
2872 | |||||||||||||||||
2873 | /** | ||||||||||||||||
2874 | Returns the float value from this string. | ||||||||||||||||
2875 | |||||||||||||||||
2876 | This function can't be used for language specific conversion. | ||||||||||||||||
2877 | |||||||||||||||||
2878 | @return the float represented from this string. | ||||||||||||||||
2879 | 0.0 if this string represents no number. | ||||||||||||||||
2880 | */ | ||||||||||||||||
2881 | float toFloat() const | ||||||||||||||||
2882 | { | ||||||||||||||||
2883 | return rtl_ustr_toFloat( pData->buffer ); | ||||||||||||||||
2884 | } | ||||||||||||||||
2885 | |||||||||||||||||
2886 | /** | ||||||||||||||||
2887 | Returns the double value from this string. | ||||||||||||||||
2888 | |||||||||||||||||
2889 | This function can't be used for language specific conversion. | ||||||||||||||||
2890 | |||||||||||||||||
2891 | @return the double represented from this string. | ||||||||||||||||
2892 | 0.0 if this string represents no number. | ||||||||||||||||
2893 | */ | ||||||||||||||||
2894 | double toDouble() const | ||||||||||||||||
2895 | { | ||||||||||||||||
2896 | return rtl_ustr_toDouble( pData->buffer ); | ||||||||||||||||
2897 | } | ||||||||||||||||
2898 | |||||||||||||||||
2899 | |||||||||||||||||
2900 | /** | ||||||||||||||||
2901 | Return a canonical representation for a string. | ||||||||||||||||
2902 | |||||||||||||||||
2903 | A pool of strings, initially empty is maintained privately | ||||||||||||||||
2904 | by the string class. On invocation, if present in the pool | ||||||||||||||||
2905 | the original string will be returned. Otherwise this string, | ||||||||||||||||
2906 | or a copy thereof will be added to the pool and returned. | ||||||||||||||||
2907 | |||||||||||||||||
2908 | @return | ||||||||||||||||
2909 | a version of the string from the pool. | ||||||||||||||||
2910 | |||||||||||||||||
2911 | @exception std::bad_alloc is thrown if an out-of-memory condition occurs | ||||||||||||||||
2912 | |||||||||||||||||
2913 | @since UDK 3.2.7 | ||||||||||||||||
2914 | */ | ||||||||||||||||
2915 | OUString intern() const | ||||||||||||||||
2916 | { | ||||||||||||||||
2917 | rtl_uString * pNew = NULL__null; | ||||||||||||||||
2918 | rtl_uString_intern( &pNew, pData ); | ||||||||||||||||
2919 | if (pNew == NULL__null) { | ||||||||||||||||
2920 | throw std::bad_alloc(); | ||||||||||||||||
2921 | } | ||||||||||||||||
2922 | return OUString( pNew, SAL_NO_ACQUIRE ); | ||||||||||||||||
2923 | } | ||||||||||||||||
2924 | |||||||||||||||||
2925 | /** | ||||||||||||||||
2926 | Return a canonical representation for a converted string. | ||||||||||||||||
2927 | |||||||||||||||||
2928 | A pool of strings, initially empty is maintained privately | ||||||||||||||||
2929 | by the string class. On invocation, if present in the pool | ||||||||||||||||
2930 | the original string will be returned. Otherwise this string, | ||||||||||||||||
2931 | or a copy thereof will be added to the pool and returned. | ||||||||||||||||
2932 | |||||||||||||||||
2933 | @param value a 8-Bit character array. | ||||||||||||||||
2934 | @param length the number of character which should be converted. | ||||||||||||||||
2935 | The 8-Bit character array length must be | ||||||||||||||||
2936 | greater than or equal to this value. | ||||||||||||||||
2937 | @param encoding the text encoding from which the 8-Bit character | ||||||||||||||||
2938 | sequence should be converted. | ||||||||||||||||
2939 | @param convertFlags flags which controls the conversion. | ||||||||||||||||
2940 | see RTL_TEXTTOUNICODE_FLAGS_... | ||||||||||||||||
2941 | @param pInfo pointer to return conversion status or NULL. | ||||||||||||||||
2942 | |||||||||||||||||
2943 | @return | ||||||||||||||||
2944 | a version of the converted string from the pool. | ||||||||||||||||
2945 | |||||||||||||||||
2946 | @exception std::bad_alloc is thrown if an out-of-memory condition occurs | ||||||||||||||||
2947 | |||||||||||||||||
2948 | @since UDK 3.2.7 | ||||||||||||||||
2949 | */ | ||||||||||||||||
2950 | static OUString intern( const char * value, sal_Int32 length, | ||||||||||||||||
2951 | rtl_TextEncoding encoding, | ||||||||||||||||
2952 | sal_uInt32 convertFlags = OSTRING_TO_OUSTRING_CVTFLAGS(((sal_uInt32)0x0003) | ((sal_uInt32)0x0030) | ((sal_uInt32)0x0300 )), | ||||||||||||||||
2953 | sal_uInt32 *pInfo = NULL__null ) | ||||||||||||||||
2954 | { | ||||||||||||||||
2955 | rtl_uString * pNew = NULL__null; | ||||||||||||||||
2956 | rtl_uString_internConvert( &pNew, value, length, encoding, | ||||||||||||||||
2957 | convertFlags, pInfo ); | ||||||||||||||||
2958 | if (pNew == NULL__null) { | ||||||||||||||||
2959 | throw std::bad_alloc(); | ||||||||||||||||
2960 | } | ||||||||||||||||
2961 | return OUString( pNew, SAL_NO_ACQUIRE ); | ||||||||||||||||
2962 | } | ||||||||||||||||
2963 | |||||||||||||||||
2964 | /** | ||||||||||||||||
2965 | Converts to an OString, signalling failure. | ||||||||||||||||
2966 | |||||||||||||||||
2967 | @param pTarget | ||||||||||||||||
2968 | An out parameter receiving the converted OString. Must not be null; the | ||||||||||||||||
2969 | contents are not modified if conversion fails (convertToOString returns | ||||||||||||||||
2970 | false). | ||||||||||||||||
2971 | |||||||||||||||||
2972 | @param nEncoding | ||||||||||||||||
2973 | The text encoding to convert into. Must be an octet encoding (i.e., | ||||||||||||||||
2974 | rtl_isOctetTextEncoding(nEncoding) must return true). | ||||||||||||||||
2975 | |||||||||||||||||
2976 | @param nFlags | ||||||||||||||||
2977 | A combination of RTL_UNICODETOTEXT_FLAGS that detail how to do the | ||||||||||||||||
2978 | conversion (see rtl_convertUnicodeToText). RTL_UNICODETOTEXT_FLAGS_FLUSH | ||||||||||||||||
2979 | need not be included, it is implicitly assumed. Typical uses are either | ||||||||||||||||
2980 | RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR | | ||||||||||||||||
2981 | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR (fail if a Unicode character cannot | ||||||||||||||||
2982 | be converted to the target nEncoding) or OUSTRING_TO_OSTRING_CVTFLAGS | ||||||||||||||||
2983 | (make a best efforts conversion). | ||||||||||||||||
2984 | |||||||||||||||||
2985 | @return | ||||||||||||||||
2986 | True if the conversion succeeded, false otherwise. | ||||||||||||||||
2987 | */ | ||||||||||||||||
2988 | bool convertToString(OString * pTarget, rtl_TextEncoding nEncoding, | ||||||||||||||||
2989 | sal_uInt32 nFlags) const | ||||||||||||||||
2990 | { | ||||||||||||||||
2991 | return rtl_convertUStringToString(&pTarget->pData, pData->buffer, | ||||||||||||||||
2992 | pData->length, nEncoding, nFlags); | ||||||||||||||||
2993 | } | ||||||||||||||||
2994 | |||||||||||||||||
2995 | /** Iterate through this string based on code points instead of UTF-16 code | ||||||||||||||||
2996 | units. | ||||||||||||||||
2997 | |||||||||||||||||
2998 | See Chapter 3 of The Unicode Standard 5.0 (Addison--Wesley, 2006) for | ||||||||||||||||
2999 | definitions of the various terms used in this description. | ||||||||||||||||
3000 | |||||||||||||||||
3001 | This string is interpreted as a sequence of zero or more UTF-16 code | ||||||||||||||||
3002 | units. For each index into this sequence (from zero to one less than | ||||||||||||||||
3003 | the length of the sequence, inclusive), a code point represented | ||||||||||||||||
3004 | starting at the given index is computed as follows: | ||||||||||||||||
3005 | |||||||||||||||||
3006 | - If the UTF-16 code unit addressed by the index constitutes a | ||||||||||||||||
3007 | well-formed UTF-16 code unit sequence, the computed code point is the | ||||||||||||||||
3008 | scalar value encoded by that UTF-16 code unit sequence. | ||||||||||||||||
3009 | |||||||||||||||||
3010 | - Otherwise, if the index is at least two UTF-16 code units away from | ||||||||||||||||
3011 | the end of the sequence, and the sequence of two UTF-16 code units | ||||||||||||||||
3012 | addressed by the index constitutes a well-formed UTF-16 code unit | ||||||||||||||||
3013 | sequence, the computed code point is the scalar value encoded by that | ||||||||||||||||
3014 | UTF-16 code unit sequence. | ||||||||||||||||
3015 | |||||||||||||||||
3016 | - Otherwise, the computed code point is the UTF-16 code unit addressed | ||||||||||||||||
3017 | by the index. (This last case catches unmatched surrogates as well as | ||||||||||||||||
3018 | indices pointing into the middle of surrogate pairs.) | ||||||||||||||||
3019 | |||||||||||||||||
3020 | @param indexUtf16 | ||||||||||||||||
3021 | pointer to a UTF-16 based index into this string; must not be null. On | ||||||||||||||||
3022 | entry, the index must be in the range from zero to the length of this | ||||||||||||||||
3023 | string (in UTF-16 code units), inclusive. Upon successful return, the | ||||||||||||||||
3024 | index will be updated to address the UTF-16 code unit that is the given | ||||||||||||||||
3025 | incrementCodePoints away from the initial index. | ||||||||||||||||
3026 | |||||||||||||||||
3027 | @param incrementCodePoints | ||||||||||||||||
3028 | the number of code points to move the given *indexUtf16. If | ||||||||||||||||
3029 | non-negative, moving is done after determining the code point at the | ||||||||||||||||
3030 | index. If negative, moving is done before determining the code point | ||||||||||||||||
3031 | at the (then updated) index. The value must be such that the resulting | ||||||||||||||||
3032 | UTF-16 based index is in the range from zero to the length of this | ||||||||||||||||
3033 | string (in UTF-16 code units), inclusive. | ||||||||||||||||
3034 | |||||||||||||||||
3035 | @return | ||||||||||||||||
3036 | the code point (an integer in the range from 0 to 0x10FFFF, inclusive) | ||||||||||||||||
3037 | that is represented within this string starting at the index computed as | ||||||||||||||||
3038 | follows: If incrementCodePoints is non-negative, the index is the | ||||||||||||||||
3039 | initial value of *indexUtf16; if incrementCodePoints is negative, the | ||||||||||||||||
3040 | index is the updated value of *indexUtf16. In either case, the computed | ||||||||||||||||
3041 | index must be in the range from zero to one less than the length of this | ||||||||||||||||
3042 | string (in UTF-16 code units), inclusive. | ||||||||||||||||
3043 | |||||||||||||||||
3044 | @since UDK 3.2.7 | ||||||||||||||||
3045 | */ | ||||||||||||||||
3046 | sal_uInt32 iterateCodePoints( | ||||||||||||||||
3047 | sal_Int32 * indexUtf16, sal_Int32 incrementCodePoints = 1) const | ||||||||||||||||
3048 | { | ||||||||||||||||
3049 | return rtl_uString_iterateCodePoints( | ||||||||||||||||
3050 | pData, indexUtf16, incrementCodePoints); | ||||||||||||||||
3051 | } | ||||||||||||||||
3052 | |||||||||||||||||
3053 | /** | ||||||||||||||||
3054 | * Convert an OString to an OUString, assuming that the OString is | ||||||||||||||||
3055 | * UTF-8-encoded. | ||||||||||||||||
3056 | * | ||||||||||||||||
3057 | * @param rSource | ||||||||||||||||
3058 | * an OString to convert | ||||||||||||||||
3059 | * | ||||||||||||||||
3060 | * @since LibreOffice 4.4 | ||||||||||||||||
3061 | */ | ||||||||||||||||
3062 | static OUString fromUtf8(const OString& rSource) | ||||||||||||||||
3063 | { | ||||||||||||||||
3064 | OUString aTarget; | ||||||||||||||||
3065 | bool bSuccess = rtl_convertStringToUString(&aTarget.pData, | ||||||||||||||||
3066 | rSource.getStr(), | ||||||||||||||||
3067 | rSource.getLength(), | ||||||||||||||||
3068 | RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)), | ||||||||||||||||
3069 | RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR((sal_uInt32)0x0001)|RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR((sal_uInt32)0x0010)|RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR((sal_uInt32)0x0100)); | ||||||||||||||||
3070 | (void) bSuccess; | ||||||||||||||||
3071 | assert(bSuccess)(static_cast <bool> (bSuccess) ? void (0) : __assert_fail ("bSuccess", "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 3071, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
3072 | return aTarget; | ||||||||||||||||
3073 | } | ||||||||||||||||
3074 | |||||||||||||||||
3075 | /** | ||||||||||||||||
3076 | * Convert this string to an OString, assuming that the string can be | ||||||||||||||||
3077 | * UTF-8-encoded successfully. | ||||||||||||||||
3078 | * | ||||||||||||||||
3079 | * In other words, you must not use this method on a random sequence of | ||||||||||||||||
3080 | * UTF-16 code units, but only at places where it is assumed that the | ||||||||||||||||
3081 | * content is a proper string. | ||||||||||||||||
3082 | * | ||||||||||||||||
3083 | * @since LibreOffice 4.4 | ||||||||||||||||
3084 | */ | ||||||||||||||||
3085 | OString toUtf8() const | ||||||||||||||||
3086 | { | ||||||||||||||||
3087 | OString aTarget; | ||||||||||||||||
3088 | bool bSuccess = rtl_convertUStringToString(&aTarget.pData, | ||||||||||||||||
3089 | getStr(), | ||||||||||||||||
3090 | getLength(), | ||||||||||||||||
3091 | RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)), | ||||||||||||||||
3092 | RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR((sal_uInt32)0x0001)|RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR((sal_uInt32)0x0010)); | ||||||||||||||||
3093 | (void) bSuccess; | ||||||||||||||||
3094 | assert(bSuccess)(static_cast <bool> (bSuccess) ? void (0) : __assert_fail ("bSuccess", "/home/maarten/src/libreoffice/core/include/rtl/ustring.hxx" , 3094, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||||||
3095 | return aTarget; | ||||||||||||||||
3096 | } | ||||||||||||||||
3097 | |||||||||||||||||
3098 | #ifdef LIBO_INTERNAL_ONLY1 // "RTL_FAST_STRING" | ||||||||||||||||
3099 | |||||||||||||||||
3100 | static OUStringNumber< int > number( int i, sal_Int16 radix = 10 ) | ||||||||||||||||
3101 | { | ||||||||||||||||
3102 | return OUStringNumber< int >( i, radix ); | ||||||||||||||||
3103 | } | ||||||||||||||||
3104 | static OUStringNumber< long long > number( long long ll, sal_Int16 radix = 10 ) | ||||||||||||||||
3105 | { | ||||||||||||||||
3106 | return OUStringNumber< long long >( ll, radix ); | ||||||||||||||||
3107 | } | ||||||||||||||||
3108 | static OUStringNumber< unsigned long long > number( unsigned long long ll, sal_Int16 radix = 10 ) | ||||||||||||||||
3109 | { | ||||||||||||||||
3110 | return OUStringNumber< unsigned long long >( ll, radix ); | ||||||||||||||||
3111 | } | ||||||||||||||||
3112 | static OUStringNumber< unsigned long long > number( unsigned int i, sal_Int16 radix = 10 ) | ||||||||||||||||
3113 | { | ||||||||||||||||
3114 | return number( static_cast< unsigned long long >( i ), radix ); | ||||||||||||||||
3115 | } | ||||||||||||||||
3116 | static OUStringNumber< long long > number( long i, sal_Int16 radix = 10) | ||||||||||||||||
3117 | { | ||||||||||||||||
3118 | return number( static_cast< long long >( i ), radix ); | ||||||||||||||||
3119 | } | ||||||||||||||||
3120 | static OUStringNumber< unsigned long long > number( unsigned long i, sal_Int16 radix = 10 ) | ||||||||||||||||
3121 | { | ||||||||||||||||
3122 | return number( static_cast< unsigned long long >( i ), radix ); | ||||||||||||||||
3123 | } | ||||||||||||||||
3124 | static OUStringNumber< float > number( float f ) | ||||||||||||||||
3125 | { | ||||||||||||||||
3126 | return OUStringNumber< float >( f ); | ||||||||||||||||
3127 | } | ||||||||||||||||
3128 | static OUStringNumber< double > number( double d ) | ||||||||||||||||
3129 | { | ||||||||||||||||
3130 | return OUStringNumber< double >( d ); | ||||||||||||||||
3131 | } | ||||||||||||||||
3132 | #else | ||||||||||||||||
3133 | /** | ||||||||||||||||
3134 | Returns the string representation of the integer argument. | ||||||||||||||||
3135 | |||||||||||||||||
3136 | This function can't be used for language specific conversion. | ||||||||||||||||
3137 | |||||||||||||||||
3138 | @param i an integer value | ||||||||||||||||
3139 | @param radix the radix (between 2 and 36) | ||||||||||||||||
3140 | @return a string with the string representation of the argument. | ||||||||||||||||
3141 | @since LibreOffice 4.1 | ||||||||||||||||
3142 | */ | ||||||||||||||||
3143 | static OUString number( int i, sal_Int16 radix = 10 ) | ||||||||||||||||
3144 | { | ||||||||||||||||
3145 | sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFINT3233]; | ||||||||||||||||
3146 | return OUString(aBuf, rtl_ustr_valueOfInt32(aBuf, i, radix)); | ||||||||||||||||
3147 | } | ||||||||||||||||
3148 | /// @overload | ||||||||||||||||
3149 | /// @since LibreOffice 4.1 | ||||||||||||||||
3150 | static OUString number( unsigned int i, sal_Int16 radix = 10 ) | ||||||||||||||||
3151 | { | ||||||||||||||||
3152 | return number( static_cast< unsigned long long >( i ), radix ); | ||||||||||||||||
3153 | } | ||||||||||||||||
3154 | /// @overload | ||||||||||||||||
3155 | /// @since LibreOffice 4.1 | ||||||||||||||||
3156 | static OUString number( long i, sal_Int16 radix = 10) | ||||||||||||||||
3157 | { | ||||||||||||||||
3158 | return number( static_cast< long long >( i ), radix ); | ||||||||||||||||
3159 | } | ||||||||||||||||
3160 | /// @overload | ||||||||||||||||
3161 | /// @since LibreOffice 4.1 | ||||||||||||||||
3162 | static OUString number( unsigned long i, sal_Int16 radix = 10 ) | ||||||||||||||||
3163 | { | ||||||||||||||||
3164 | return number( static_cast< unsigned long long >( i ), radix ); | ||||||||||||||||
3165 | } | ||||||||||||||||
3166 | /// @overload | ||||||||||||||||
3167 | /// @since LibreOffice 4.1 | ||||||||||||||||
3168 | static OUString number( long long ll, sal_Int16 radix = 10 ) | ||||||||||||||||
3169 | { | ||||||||||||||||
3170 | sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFINT6465]; | ||||||||||||||||
3171 | return OUString(aBuf, rtl_ustr_valueOfInt64(aBuf, ll, radix)); | ||||||||||||||||
3172 | } | ||||||||||||||||
3173 | /// @overload | ||||||||||||||||
3174 | /// @since LibreOffice 4.1 | ||||||||||||||||
3175 | static OUString number( unsigned long long ll, sal_Int16 radix = 10 ) | ||||||||||||||||
3176 | { | ||||||||||||||||
3177 | sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFUINT6465]; | ||||||||||||||||
3178 | return OUString(aBuf, rtl_ustr_valueOfUInt64(aBuf, ll, radix)); | ||||||||||||||||
3179 | } | ||||||||||||||||
3180 | |||||||||||||||||
3181 | /** | ||||||||||||||||
3182 | Returns the string representation of the float argument. | ||||||||||||||||
3183 | |||||||||||||||||
3184 | This function can't be used for language specific conversion. | ||||||||||||||||
3185 | |||||||||||||||||
3186 | @param f a float. | ||||||||||||||||
3187 | @return a string with the decimal representation of the argument. | ||||||||||||||||
3188 | @since LibreOffice 4.1 | ||||||||||||||||
3189 | */ | ||||||||||||||||
3190 | static OUString number( float f ) | ||||||||||||||||
3191 | { | ||||||||||||||||
3192 | sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFFLOAT15]; | ||||||||||||||||
3193 | return OUString(aBuf, rtl_ustr_valueOfFloat(aBuf, f)); | ||||||||||||||||
3194 | } | ||||||||||||||||
3195 | |||||||||||||||||
3196 | /** | ||||||||||||||||
3197 | Returns the string representation of the double argument. | ||||||||||||||||
3198 | |||||||||||||||||
3199 | This function can't be used for language specific conversion. | ||||||||||||||||
3200 | |||||||||||||||||
3201 | @param d a double. | ||||||||||||||||
3202 | @return a string with the decimal representation of the argument. | ||||||||||||||||
3203 | @since LibreOffice 4.1 | ||||||||||||||||
3204 | */ | ||||||||||||||||
3205 | static OUString number( double d ) | ||||||||||||||||
3206 | { | ||||||||||||||||
3207 | sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFDOUBLE25]; | ||||||||||||||||
3208 | return OUString(aBuf, rtl_ustr_valueOfDouble(aBuf, d)); | ||||||||||||||||
3209 | } | ||||||||||||||||
3210 | #endif | ||||||||||||||||
3211 | |||||||||||||||||
3212 | /** | ||||||||||||||||
3213 | Returns the string representation of the sal_Bool argument. | ||||||||||||||||
3214 | |||||||||||||||||
3215 | If the sal_Bool is true, the string "true" is returned. | ||||||||||||||||
3216 | If the sal_Bool is false, the string "false" is returned. | ||||||||||||||||
3217 | This function can't be used for language specific conversion. | ||||||||||||||||
3218 | |||||||||||||||||
3219 | @param b a sal_Bool. | ||||||||||||||||
3220 | @return a string with the string representation of the argument. | ||||||||||||||||
3221 | @deprecated use boolean() | ||||||||||||||||
3222 | */ | ||||||||||||||||
3223 | SAL_DEPRECATED("use boolean()")__attribute__((deprecated("use boolean()"))) static OUString valueOf( sal_Bool b ) | ||||||||||||||||
3224 | { | ||||||||||||||||
3225 | return boolean(b); | ||||||||||||||||
3226 | } | ||||||||||||||||
3227 | |||||||||||||||||
3228 | /** | ||||||||||||||||
3229 | Returns the string representation of the boolean argument. | ||||||||||||||||
3230 | |||||||||||||||||
3231 | If the argument is true, the string "true" is returned. | ||||||||||||||||
3232 | If the argument is false, the string "false" is returned. | ||||||||||||||||
3233 | This function can't be used for language specific conversion. | ||||||||||||||||
3234 | |||||||||||||||||
3235 | @param b a bool. | ||||||||||||||||
3236 | @return a string with the string representation of the argument. | ||||||||||||||||
3237 | @since LibreOffice 4.1 | ||||||||||||||||
3238 | */ | ||||||||||||||||
3239 | static OUString boolean( bool b ) | ||||||||||||||||
3240 | { | ||||||||||||||||
3241 | sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFBOOLEAN6]; | ||||||||||||||||
3242 | return OUString(aBuf, rtl_ustr_valueOfBoolean(aBuf, b)); | ||||||||||||||||
3243 | } | ||||||||||||||||
3244 | |||||||||||||||||
3245 | /** | ||||||||||||||||
3246 | Returns the string representation of the char argument. | ||||||||||||||||
3247 | |||||||||||||||||
3248 | @param c a character. | ||||||||||||||||
3249 | @return a string with the string representation of the argument. | ||||||||||||||||
3250 | @deprecated use operator, function or constructor taking char or sal_Unicode argument | ||||||||||||||||
3251 | */ | ||||||||||||||||
3252 | SAL_DEPRECATED("convert to OUString or use directly")__attribute__((deprecated("convert to OUString or use directly" ))) static OUString valueOf( sal_Unicode c ) | ||||||||||||||||
3253 | { | ||||||||||||||||
3254 | return OUString( &c, 1 ); | ||||||||||||||||
3255 | } | ||||||||||||||||
3256 | |||||||||||||||||
3257 | /** | ||||||||||||||||
3258 | Returns the string representation of the int argument. | ||||||||||||||||
3259 | |||||||||||||||||
3260 | This function can't be used for language specific conversion. | ||||||||||||||||
3261 | |||||||||||||||||
3262 | @param i a int32. | ||||||||||||||||
3263 | @param radix the radix (between 2 and 36) | ||||||||||||||||
3264 | @return a string with the string representation of the argument. | ||||||||||||||||
3265 | @deprecated use number() | ||||||||||||||||
3266 | */ | ||||||||||||||||
3267 | SAL_DEPRECATED("use number()")__attribute__((deprecated("use number()"))) static OUString valueOf( sal_Int32 i, sal_Int16 radix = 10 ) | ||||||||||||||||
3268 | { | ||||||||||||||||
3269 | return number( i, radix ); | ||||||||||||||||
3270 | } | ||||||||||||||||
3271 | |||||||||||||||||
3272 | /** | ||||||||||||||||
3273 | Returns the string representation of the long argument. | ||||||||||||||||
3274 | |||||||||||||||||
3275 | This function can't be used for language specific conversion. | ||||||||||||||||
3276 | |||||||||||||||||
3277 | @param ll a int64. | ||||||||||||||||
3278 | @param radix the radix (between 2 and 36) | ||||||||||||||||
3279 | @return a string with the string representation of the argument. | ||||||||||||||||
3280 | @deprecated use number() | ||||||||||||||||
3281 | */ | ||||||||||||||||
3282 | SAL_DEPRECATED("use number()")__attribute__((deprecated("use number()"))) static OUString valueOf( sal_Int64 ll, sal_Int16 radix = 10 ) | ||||||||||||||||
3283 | { | ||||||||||||||||
3284 | return number( ll, radix ); | ||||||||||||||||
3285 | } | ||||||||||||||||
3286 | |||||||||||||||||
3287 | /** | ||||||||||||||||
3288 | Returns the string representation of the float argument. | ||||||||||||||||
3289 | |||||||||||||||||
3290 | This function can't be used for language specific conversion. | ||||||||||||||||
3291 | |||||||||||||||||
3292 | @param f a float. | ||||||||||||||||
3293 | @return a string with the string representation of the argument. | ||||||||||||||||
3294 | @deprecated use number() | ||||||||||||||||
3295 | */ | ||||||||||||||||
3296 | SAL_DEPRECATED("use number()")__attribute__((deprecated("use number()"))) static OUString valueOf( float f ) | ||||||||||||||||
3297 | { | ||||||||||||||||
3298 | return number(f); | ||||||||||||||||
3299 | } | ||||||||||||||||
3300 | |||||||||||||||||
3301 | /** | ||||||||||||||||
3302 | Returns the string representation of the double argument. | ||||||||||||||||
3303 | |||||||||||||||||
3304 | This function can't be used for language specific conversion. | ||||||||||||||||
3305 | |||||||||||||||||
3306 | @param d a double. | ||||||||||||||||
3307 | @return a string with the string representation of the argument. | ||||||||||||||||
3308 | @deprecated use number() | ||||||||||||||||
3309 | */ | ||||||||||||||||
3310 | SAL_DEPRECATED("use number()")__attribute__((deprecated("use number()"))) static OUString valueOf( double d ) | ||||||||||||||||
3311 | { | ||||||||||||||||
3312 | return number(d); | ||||||||||||||||
3313 | } | ||||||||||||||||
3314 | |||||||||||||||||
3315 | /** | ||||||||||||||||
3316 | Returns an OUString copied without conversion from an ASCII | ||||||||||||||||
3317 | character string. | ||||||||||||||||
3318 | |||||||||||||||||
3319 | Since this method is optimized for performance, the ASCII character | ||||||||||||||||
3320 | values are not converted in any way. The caller has to make sure that | ||||||||||||||||
3321 | all ASCII characters are in the allowed range between 0 and 127. | ||||||||||||||||
3322 | The ASCII string must be NULL-terminated. | ||||||||||||||||
3323 | |||||||||||||||||
3324 | Note that for string literals it is simpler and more efficient | ||||||||||||||||
3325 | to directly use the OUString constructor. | ||||||||||||||||
3326 | |||||||||||||||||
3327 | @param value the 8-Bit ASCII character string | ||||||||||||||||
3328 | @return a string with the string representation of the argument. | ||||||||||||||||
3329 | */ | ||||||||||||||||
3330 | static OUString createFromAscii( const char * value ) | ||||||||||||||||
3331 | { | ||||||||||||||||
3332 | rtl_uString* pNew = NULL__null; | ||||||||||||||||
3333 | rtl_uString_newFromAscii( &pNew, value ); | ||||||||||||||||
3334 | return OUString( pNew, SAL_NO_ACQUIRE ); | ||||||||||||||||
3335 | } | ||||||||||||||||
3336 | |||||||||||||||||
3337 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
3338 | static OUString createFromAscii(std::string_view value) { | ||||||||||||||||
3339 | rtl_uString * p = nullptr; | ||||||||||||||||
3340 | rtl_uString_newFromLiteral(&p, value.data(), value.size(), 0); //TODO: check for overflow | ||||||||||||||||
3341 | return OUString(p, SAL_NO_ACQUIRE); | ||||||||||||||||
3342 | } | ||||||||||||||||
3343 | #endif | ||||||||||||||||
3344 | |||||||||||||||||
3345 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
3346 | operator std::u16string_view() const { return {getStr(), sal_uInt32(getLength())}; } | ||||||||||||||||
3347 | #endif | ||||||||||||||||
3348 | |||||||||||||||||
3349 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
3350 | // A wrapper for the first expression in an | ||||||||||||||||
3351 | // | ||||||||||||||||
3352 | // OUString::Concat(e1) + e2 + ... | ||||||||||||||||
3353 | // | ||||||||||||||||
3354 | // concatenation chain, when neither of the first two e1, e2 is one of our rtl string-related | ||||||||||||||||
3355 | // classes (so something like | ||||||||||||||||
3356 | // | ||||||||||||||||
3357 | // OUString s = "a" + (b ? std::u16string_view(u"c") : std::u16string_view(u"dd")); | ||||||||||||||||
3358 | // | ||||||||||||||||
3359 | // would not compile): | ||||||||||||||||
3360 | template<typename T> [[nodiscard]] static | ||||||||||||||||
3361 | typename std::enable_if_t< | ||||||||||||||||
3362 | ToStringHelper<T>::allowOUStringConcat, OUStringConcat<OUStringConcatMarker, T>> | ||||||||||||||||
3363 | Concat(T const & value) { return OUStringConcat<OUStringConcatMarker, T>({}, value); } | ||||||||||||||||
3364 | |||||||||||||||||
3365 | // This overload is needed so that an argument of type 'char const[N]' ends up as | ||||||||||||||||
3366 | // 'OUStringConcat<rtl::OUStringConcatMarker, char const[N]>' rather than as | ||||||||||||||||
3367 | // 'OUStringConcat<rtl::OUStringConcatMarker, char[N]>': | ||||||||||||||||
3368 | template<typename T, std::size_t N> [[nodiscard]] static | ||||||||||||||||
3369 | typename std::enable_if_t< | ||||||||||||||||
3370 | ToStringHelper<T[N]>::allowOUStringConcat, OUStringConcat<OUStringConcatMarker, T[N]>> | ||||||||||||||||
3371 | Concat(T (& value)[N]) { return OUStringConcat<OUStringConcatMarker, T[N]>({}, value); } | ||||||||||||||||
3372 | #endif | ||||||||||||||||
3373 | |||||||||||||||||
3374 | private: | ||||||||||||||||
3375 | OUString & internalAppend( rtl_uString* pOtherData ) | ||||||||||||||||
3376 | { | ||||||||||||||||
3377 | rtl_uString* pNewData = NULL__null; | ||||||||||||||||
3378 | rtl_uString_newConcat( &pNewData, pData, pOtherData ); | ||||||||||||||||
3379 | if (pNewData == NULL__null) { | ||||||||||||||||
3380 | throw std::bad_alloc(); | ||||||||||||||||
3381 | } | ||||||||||||||||
3382 | rtl_uString_assign(&pData, pNewData); | ||||||||||||||||
3383 | rtl_uString_release(pNewData); | ||||||||||||||||
3384 | return *this; | ||||||||||||||||
3385 | } | ||||||||||||||||
3386 | |||||||||||||||||
3387 | }; | ||||||||||||||||
3388 | |||||||||||||||||
3389 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
3390 | // Prevent the operator ==/!= overloads with 'sal_Unicode const *' parameter from | ||||||||||||||||
3391 | // being selected for nonsensical code like | ||||||||||||||||
3392 | // | ||||||||||||||||
3393 | // if (ouIdAttr == nullptr) | ||||||||||||||||
3394 | // | ||||||||||||||||
3395 | void operator ==(OUString const &, std::nullptr_t) = delete; | ||||||||||||||||
3396 | void operator ==(std::nullptr_t, OUString const &) = delete; | ||||||||||||||||
3397 | void operator !=(OUString const &, std::nullptr_t) = delete; | ||||||||||||||||
3398 | void operator !=(std::nullptr_t, OUString const &) = delete; | ||||||||||||||||
3399 | #endif | ||||||||||||||||
3400 | |||||||||||||||||
3401 | #if defined LIBO_INTERNAL_ONLY1 // "RTL_FAST_STRING" | ||||||||||||||||
3402 | /// @cond INTERNAL | ||||||||||||||||
3403 | |||||||||||||||||
3404 | /** | ||||||||||||||||
3405 | @internal | ||||||||||||||||
3406 | */ | ||||||||||||||||
3407 | template<> | ||||||||||||||||
3408 | struct ToStringHelper< OUString > | ||||||||||||||||
3409 | { | ||||||||||||||||
3410 | static std::size_t length( const OUString& s ) { return s.getLength(); } | ||||||||||||||||
3411 | static sal_Unicode* addData( sal_Unicode* buffer, const OUString& s ) { return addDataHelper( buffer, s.getStr(), s.getLength()); } | ||||||||||||||||
3412 | static const bool allowOStringConcat = false; | ||||||||||||||||
3413 | static const bool allowOUStringConcat = true; | ||||||||||||||||
3414 | }; | ||||||||||||||||
3415 | |||||||||||||||||
3416 | /** | ||||||||||||||||
3417 | @internal | ||||||||||||||||
3418 | */ | ||||||||||||||||
3419 | template<std::size_t N> | ||||||||||||||||
3420 | struct ToStringHelper< OUStringLiteral<N> > | ||||||||||||||||
3421 | { | ||||||||||||||||
3422 | static std::size_t length( const OUStringLiteral<N>& str ) { return str.getLength(); } | ||||||||||||||||
3423 | static sal_Unicode* addData( sal_Unicode* buffer, const OUStringLiteral<N>& str ) { return addDataHelper( buffer, str.getStr(), str.getLength() ); } | ||||||||||||||||
3424 | static const bool allowOStringConcat = false; | ||||||||||||||||
3425 | static const bool allowOUStringConcat = true; | ||||||||||||||||
3426 | }; | ||||||||||||||||
3427 | |||||||||||||||||
3428 | /** | ||||||||||||||||
3429 | @internal | ||||||||||||||||
3430 | */ | ||||||||||||||||
3431 | template< typename charT, typename traits, typename T1, typename T2 > | ||||||||||||||||
3432 | inline std::basic_ostream<charT, traits> & operator <<( | ||||||||||||||||
3433 | std::basic_ostream<charT, traits> & stream, OUStringConcat< T1, T2 >&& concat) | ||||||||||||||||
3434 | { | ||||||||||||||||
3435 | return stream << OUString( std::move(concat) ); | ||||||||||||||||
3436 | } | ||||||||||||||||
3437 | |||||||||||||||||
3438 | /// @endcond | ||||||||||||||||
3439 | #endif | ||||||||||||||||
3440 | |||||||||||||||||
3441 | /** A helper to use OUStrings with hash maps. | ||||||||||||||||
3442 | |||||||||||||||||
3443 | Instances of this class are unary function objects that can be used as | ||||||||||||||||
3444 | hash function arguments to std::unordered_map and similar constructs. | ||||||||||||||||
3445 | */ | ||||||||||||||||
3446 | struct OUStringHash | ||||||||||||||||
3447 | { | ||||||||||||||||
3448 | /** Compute a hash code for a string. | ||||||||||||||||
3449 | |||||||||||||||||
3450 | @param rString | ||||||||||||||||
3451 | a string. | ||||||||||||||||
3452 | |||||||||||||||||
3453 | @return | ||||||||||||||||
3454 | a hash code for the string. This hash code should not be stored | ||||||||||||||||
3455 | persistently, as its computation may change in later revisions. | ||||||||||||||||
3456 | */ | ||||||||||||||||
3457 | size_t operator()(const OUString& rString) const | ||||||||||||||||
3458 | { return static_cast<size_t>(rString.hashCode()); } | ||||||||||||||||
3459 | }; | ||||||||||||||||
3460 | |||||||||||||||||
3461 | /* ======================================================================= */ | ||||||||||||||||
3462 | |||||||||||||||||
3463 | /** Convert an OString to an OUString, using a specific text encoding. | ||||||||||||||||
3464 | |||||||||||||||||
3465 | The lengths of the two strings may differ (e.g., for double-byte | ||||||||||||||||
3466 | encodings, UTF-7, UTF-8). | ||||||||||||||||
3467 | |||||||||||||||||
3468 | @param rStr | ||||||||||||||||
3469 | an OString to convert. | ||||||||||||||||
3470 | |||||||||||||||||
3471 | @param encoding | ||||||||||||||||
3472 | the text encoding to use for conversion. | ||||||||||||||||
3473 | |||||||||||||||||
3474 | @param convertFlags | ||||||||||||||||
3475 | flags which control the conversion. Either use | ||||||||||||||||
3476 | OSTRING_TO_OUSTRING_CVTFLAGS, or see | ||||||||||||||||
3477 | <http://udk.openoffice.org/cpp/man/spec/textconversion.html> for more | ||||||||||||||||
3478 | details. | ||||||||||||||||
3479 | */ | ||||||||||||||||
3480 | inline OUString OStringToOUString( const OString & rStr, | ||||||||||||||||
3481 | rtl_TextEncoding encoding, | ||||||||||||||||
3482 | sal_uInt32 convertFlags = OSTRING_TO_OUSTRING_CVTFLAGS(((sal_uInt32)0x0003) | ((sal_uInt32)0x0030) | ((sal_uInt32)0x0300 )) ) | ||||||||||||||||
3483 | { | ||||||||||||||||
3484 | return OUString( rStr.getStr(), rStr.getLength(), encoding, convertFlags ); | ||||||||||||||||
3485 | } | ||||||||||||||||
3486 | |||||||||||||||||
3487 | /** Convert an OUString to an OString, using a specific text encoding. | ||||||||||||||||
3488 | |||||||||||||||||
3489 | The lengths of the two strings may differ (e.g., for double-byte | ||||||||||||||||
3490 | encodings, UTF-7, UTF-8). | ||||||||||||||||
3491 | |||||||||||||||||
3492 | @param rUnicode | ||||||||||||||||
3493 | an OUString to convert. | ||||||||||||||||
3494 | |||||||||||||||||
3495 | @param encoding | ||||||||||||||||
3496 | the text encoding to use for conversion. | ||||||||||||||||
3497 | |||||||||||||||||
3498 | @param convertFlags | ||||||||||||||||
3499 | flags which control the conversion. Either use | ||||||||||||||||
3500 | OUSTRING_TO_OSTRING_CVTFLAGS, or see | ||||||||||||||||
3501 | <http://udk.openoffice.org/cpp/man/spec/textconversion.html> for more | ||||||||||||||||
3502 | details. | ||||||||||||||||
3503 | */ | ||||||||||||||||
3504 | inline OString OUStringToOString( const OUString & rUnicode, | ||||||||||||||||
3505 | rtl_TextEncoding encoding, | ||||||||||||||||
3506 | sal_uInt32 convertFlags = OUSTRING_TO_OSTRING_CVTFLAGS(((sal_uInt32)0x0006) | ((sal_uInt32)0x0060) | ((sal_uInt32)0x0100 ) | ((sal_uInt32)0x0400)) ) | ||||||||||||||||
3507 | { | ||||||||||||||||
3508 | return OString( rUnicode.getStr(), rUnicode.getLength(), encoding, convertFlags ); | ||||||||||||||||
3509 | } | ||||||||||||||||
3510 | |||||||||||||||||
3511 | /* ======================================================================= */ | ||||||||||||||||
3512 | |||||||||||||||||
3513 | /** | ||||||||||||||||
3514 | Support for rtl::OUString in std::ostream (and thus in | ||||||||||||||||
3515 | CPPUNIT_ASSERT or SAL_INFO macros, for example). | ||||||||||||||||
3516 | |||||||||||||||||
3517 | The rtl::OUString is converted to UTF-8. | ||||||||||||||||
3518 | |||||||||||||||||
3519 | @since LibreOffice 3.5. | ||||||||||||||||
3520 | */ | ||||||||||||||||
3521 | template< typename charT, typename traits > | ||||||||||||||||
3522 | inline std::basic_ostream<charT, traits> & operator <<( | ||||||||||||||||
3523 | std::basic_ostream<charT, traits> & stream, OUString const & rString) | ||||||||||||||||
3524 | { | ||||||||||||||||
3525 | return stream << | ||||||||||||||||
3526 | OUStringToOString(rString, RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76))); | ||||||||||||||||
3527 | // best effort; potentially loses data due to conversion failures | ||||||||||||||||
3528 | // (stray surrogate halves) and embedded null characters | ||||||||||||||||
3529 | } | ||||||||||||||||
3530 | |||||||||||||||||
3531 | } // namespace | ||||||||||||||||
3532 | |||||||||||||||||
3533 | #ifdef RTL_STRING_UNITTEST | ||||||||||||||||
3534 | namespace rtl | ||||||||||||||||
3535 | { | ||||||||||||||||
3536 | typedef rtlunittest::OUString OUString; | ||||||||||||||||
3537 | } | ||||||||||||||||
3538 | #endif | ||||||||||||||||
3539 | |||||||||||||||||
3540 | // In internal code, allow to use classes like OUString without having to | ||||||||||||||||
3541 | // explicitly refer to the rtl namespace, which is kind of superfluous given | ||||||||||||||||
3542 | // that OUString itself is namespaced by its OU prefix: | ||||||||||||||||
3543 | #if defined LIBO_INTERNAL_ONLY1 && !defined RTL_STRING_UNITTEST | ||||||||||||||||
3544 | using ::rtl::OUString; | ||||||||||||||||
3545 | using ::rtl::OUStringHash; | ||||||||||||||||
3546 | using ::rtl::OStringToOUString; | ||||||||||||||||
3547 | using ::rtl::OUStringToOString; | ||||||||||||||||
3548 | using ::rtl::OUStringLiteral; | ||||||||||||||||
3549 | using ::rtl::OUStringChar; | ||||||||||||||||
3550 | #endif | ||||||||||||||||
3551 | |||||||||||||||||
3552 | /// @cond INTERNAL | ||||||||||||||||
3553 | /** | ||||||||||||||||
3554 | Make OUString hashable by default for use in STL containers. | ||||||||||||||||
3555 | |||||||||||||||||
3556 | @since LibreOffice 6.0 | ||||||||||||||||
3557 | */ | ||||||||||||||||
3558 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||||||
3559 | namespace std { | ||||||||||||||||
3560 | |||||||||||||||||
3561 | template<> | ||||||||||||||||
3562 | struct hash<::rtl::OUString> | ||||||||||||||||
3563 | { | ||||||||||||||||
3564 | std::size_t operator()(::rtl::OUString const & s) const | ||||||||||||||||
3565 | { return std::size_t(s.hashCode()); } | ||||||||||||||||
3566 | }; | ||||||||||||||||
3567 | |||||||||||||||||
3568 | } | ||||||||||||||||
3569 | |||||||||||||||||
3570 | #endif | ||||||||||||||||
3571 | /// @endcond | ||||||||||||||||
3572 | |||||||||||||||||
3573 | #endif /* _RTL_USTRING_HXX */ | ||||||||||||||||
3574 | |||||||||||||||||
3575 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |