fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / tools / source / string / strascii.cxx
blobe057c03fc655ff1826b511f6e46d6de662c04d7b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifdef DBG_UTIL
21 static sal_Bool ImplDbgCheckAsciiStr( const sal_Char* pAsciiStr, sal_Int32 nLen )
23 while ( nLen && *pAsciiStr )
25 if ( ((unsigned char)*pAsciiStr) > 127 )
26 return sal_False;
27 ++pAsciiStr,
28 --nLen;
31 return sal_True;
33 #endif
35 static void ImplCopyAsciiStr( sal_Unicode* pDest, const sal_Char* pSrc,
36 sal_Int32 nLen )
38 DBG_ASSERT( ImplDbgCheckAsciiStr( pSrc, nLen ),
39 "UniString::CopyAsciiStr() - pAsciiStr include characters > 127" );
41 while ( nLen )
43 *pDest = (unsigned char)*pSrc;
44 ++pDest,
45 ++pSrc,
46 --nLen;
50 static sal_Int32 ImplStringCompareAscii( const sal_Unicode* pStr1, const sal_Char* pStr2 )
52 sal_Int32 nRet;
53 while ( ((nRet = ((sal_Int32)*pStr1)-((sal_Int32)((unsigned char)*pStr2))) == 0) &&
54 *pStr2 )
56 ++pStr1,
57 ++pStr2;
60 return nRet;
63 static sal_Int32 ImplStringCompareAscii( const sal_Unicode* pStr1, const sal_Char* pStr2,
64 xub_StrLen nCount )
66 sal_Int32 nRet = 0;
67 while ( nCount &&
68 ((nRet = ((sal_Int32)*pStr1)-((sal_Int32)((unsigned char)*pStr2))) == 0) &&
69 *pStr2 )
71 ++pStr1,
72 ++pStr2,
73 --nCount;
76 return nRet;
79 static sal_Int32 ImplStringCompareWithoutZeroAscii( const sal_Unicode* pStr1, const sal_Char* pStr2,
80 xub_StrLen nCount )
82 sal_Int32 nRet = 0;
83 while ( nCount &&
84 ((nRet = ((sal_Int32)*pStr1)-((sal_Int32)((unsigned char)*pStr2))) == 0) )
86 ++pStr1,
87 ++pStr2,
88 --nCount;
91 return nRet;
94 static sal_Int32 ImplStringICompareAscii( const sal_Unicode* pStr1, const sal_Char* pStr2 )
96 sal_Int32 nRet;
97 sal_Unicode c1;
98 sal_Char c2;
101 // Convert if char is between 'A' and 'Z'
102 c1 = *pStr1;
103 c2 = *pStr2;
104 if ( (c1 >= 65) && (c1 <= 90) )
105 c1 += 32;
106 if ( (c2 >= 65) && (c2 <= 90) )
107 c2 += 32;
108 nRet = ((sal_Int32)c1)-((sal_Int32)((unsigned char)c2));
109 if ( nRet != 0 )
110 break;
112 ++pStr1,
113 ++pStr2;
115 while ( c2 );
117 return nRet;
120 static sal_Int32 ImplStringICompareAscii( const sal_Unicode* pStr1, const sal_Char* pStr2,
121 xub_StrLen nCount )
123 sal_Int32 nRet = 0;
124 sal_Unicode c1;
125 sal_Char c2;
128 if ( !nCount )
129 break;
131 // Convert if char is between 'A' and 'Z'
132 c1 = *pStr1;
133 c2 = *pStr2;
134 if ( (c1 >= 65) && (c1 <= 90) )
135 c1 += 32;
136 if ( (c2 >= 65) && (c2 <= 90) )
137 c2 += 32;
138 nRet = ((sal_Int32)c1)-((sal_Int32)((unsigned char)c2));
139 if ( nRet != 0 )
140 break;
142 ++pStr1,
143 ++pStr2,
144 --nCount;
146 while ( c2 );
148 return nRet;
151 UniString& UniString::AssignAscii( const sal_Char* pAsciiStr )
153 DBG_CHKTHIS( UniString, DbgCheckUniString );
154 DBG_ASSERT( pAsciiStr, "UniString::AssignAscii() - pAsciiStr is NULL" );
156 // Determine string length
157 xub_StrLen nLen = ImplStringLen( pAsciiStr );
159 if ( !nLen )
161 STRING_NEW((STRING_TYPE **)&mpData);
163 else
165 // Replace string in-place if new size is equal
166 if ( (nLen == mpData->mnLen) && (mpData->mnRefCount == 1) )
167 ImplCopyAsciiStr( mpData->maStr, pAsciiStr, nLen );
168 else
170 // release old string
171 STRING_RELEASE((STRING_TYPE *)mpData);
173 // copy new string
174 mpData = ImplAllocData( nLen );
175 ImplCopyAsciiStr( mpData->maStr, pAsciiStr, nLen );
179 return *this;
182 UniString& UniString::AssignAscii( const sal_Char* pAsciiStr, xub_StrLen nLen )
184 DBG_CHKTHIS( UniString, DbgCheckUniString );
185 DBG_ASSERT( pAsciiStr, "UniString::AssignAscii() - pAsciiStr is NULL" );
187 if ( nLen == STRING_LEN )
188 nLen = ImplStringLen( pAsciiStr );
190 #ifdef DBG_UTIL
191 if ( DbgIsAssert() )
193 for ( xub_StrLen i = 0; i < nLen; ++i )
195 if ( !pAsciiStr[i] )
197 OSL_FAIL( "UniString::AssignAscii() : nLen is wrong" );
201 #endif
203 if ( !nLen )
205 STRING_NEW((STRING_TYPE **)&mpData);
207 else
209 // Replace string in-place if new size is equal
210 if ( (nLen == mpData->mnLen) && (mpData->mnRefCount == 1) )
211 ImplCopyAsciiStr( mpData->maStr, pAsciiStr, nLen );
212 else
214 // release old string
215 STRING_RELEASE((STRING_TYPE *)mpData);
217 // copy new string
218 mpData = ImplAllocData( nLen );
219 ImplCopyAsciiStr( mpData->maStr, pAsciiStr, nLen );
223 return *this;
226 UniString& UniString::AppendAscii( const sal_Char* pAsciiStr )
228 DBG_CHKTHIS( UniString, DbgCheckUniString );
229 DBG_ASSERT( pAsciiStr, "UniString::AppendAscii() - pAsciiStr is NULL" );
231 // determine string length
232 sal_Int32 nCopyLen = ImplStringLen( pAsciiStr );
234 // detect overflow
235 nCopyLen = ImplGetCopyLen( mpData->mnLen, nCopyLen );
237 // If appended string is not empty
238 if ( nCopyLen )
240 // Allocate new string
241 UniStringData* pNewData = ImplAllocData( mpData->mnLen+nCopyLen );
243 // copy string data
244 memcpy( pNewData->maStr, mpData->maStr, mpData->mnLen*sizeof( sal_Unicode ) );
245 ImplCopyAsciiStr( pNewData->maStr+mpData->mnLen, pAsciiStr, nCopyLen );
247 // release old string
248 STRING_RELEASE((STRING_TYPE *)mpData);
249 mpData = pNewData;
252 return *this;
255 UniString& UniString::AppendAscii( const sal_Char* pAsciiStr, xub_StrLen nLen )
257 DBG_CHKTHIS( UniString, DbgCheckUniString );
258 DBG_ASSERT( pAsciiStr, "UniString::AppendAscii() - pAsciiStr is NULL" );
260 if ( nLen == STRING_LEN )
261 nLen = ImplStringLen( pAsciiStr );
263 #ifdef DBG_UTIL
264 if ( DbgIsAssert() )
266 for ( xub_StrLen i = 0; i < nLen; ++i )
268 if ( !pAsciiStr[i] )
270 OSL_FAIL( "UniString::AppendAscii() : nLen is wrong" );
274 #endif
276 // detect overflow
277 sal_Int32 nCopyLen = ImplGetCopyLen( mpData->mnLen, nLen );
279 // If appended string is not empty
280 if ( nCopyLen )
282 // Allocate new string
283 UniStringData* pNewData = ImplAllocData( mpData->mnLen+nCopyLen );
285 // copy string data
286 memcpy( pNewData->maStr, mpData->maStr, mpData->mnLen*sizeof( sal_Unicode ) );
287 ImplCopyAsciiStr( pNewData->maStr+mpData->mnLen, pAsciiStr, nCopyLen );
289 // release old string
290 STRING_RELEASE((STRING_TYPE *)mpData);
291 mpData = pNewData;
294 return *this;
297 UniString& UniString::InsertAscii( const char* pAsciiStr, xub_StrLen nIndex )
299 DBG_CHKTHIS( UniString, DbgCheckUniString );
300 DBG_ASSERT( pAsciiStr, "UniString::InsertAscii() - pAsciiStr is NULL" );
302 // Determine string length
303 sal_Int32 nCopyLen = ImplStringLen( pAsciiStr );
305 // detect overflow
306 nCopyLen = ImplGetCopyLen( mpData->mnLen, nCopyLen );
308 // If appended string is not empty
309 if ( !nCopyLen )
310 return *this;
312 // Adjust index if exceeds length
313 if ( nIndex > mpData->mnLen )
314 nIndex = static_cast< xub_StrLen >(mpData->mnLen);
316 // Allocate new string
317 UniStringData* pNewData = ImplAllocData( mpData->mnLen+nCopyLen );
319 // copy string data
320 memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( sal_Unicode ) );
321 ImplCopyAsciiStr( pNewData->maStr+nIndex, pAsciiStr, nCopyLen );
322 memcpy( pNewData->maStr+nIndex+nCopyLen, mpData->maStr+nIndex,
323 (mpData->mnLen-nIndex)*sizeof( sal_Unicode ) );
325 // release old string
326 STRING_RELEASE((STRING_TYPE *)mpData);
327 mpData = pNewData;
329 return *this;
332 UniString& UniString::ReplaceAscii( xub_StrLen nIndex, xub_StrLen nCount,
333 const sal_Char* pAsciiStr, xub_StrLen nStrLen )
335 DBG_CHKTHIS( UniString, DbgCheckUniString );
336 DBG_ASSERT( pAsciiStr, "UniString::ReplaceAscii() - pAsciiStr is NULL" );
338 // Use append if index >= length
339 if ( nIndex >= mpData->mnLen )
341 AppendAscii( pAsciiStr, nStrLen );
342 return *this;
345 // Use assign if index = 0 and count >= length
346 if ( (nIndex == 0) && (nCount >= mpData->mnLen) )
348 AssignAscii( pAsciiStr, nStrLen );
349 return *this;
352 // Use erase if length is equal
353 if ( nStrLen == STRING_LEN )
354 nStrLen = ImplStringLen( pAsciiStr );
355 if ( !nStrLen )
356 return Erase( nIndex, nCount );
358 // nCount must not exceed string length
359 if ( nCount > mpData->mnLen - nIndex )
360 nCount = static_cast< xub_StrLen >(mpData->mnLen-nIndex);
362 // Use assign if length matches
363 if ( nCount == nStrLen )
365 ImplCopyData();
366 ImplCopyAsciiStr( mpData->maStr+nIndex, pAsciiStr, nStrLen );
367 return *this;
370 // detect overflow
371 sal_Int32 n = ImplGetCopyLen( mpData->mnLen-nCount, nStrLen );
373 // allocate new string
374 STRINGDATA* pNewData = ImplAllocData( mpData->mnLen-nCount+n );
376 // copy string data
377 memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( STRCODE ) );
378 ImplCopyAsciiStr( pNewData->maStr+nIndex, pAsciiStr, n );
379 memcpy( pNewData->maStr+nIndex+n, mpData->maStr+nIndex+nCount,
380 (mpData->mnLen-nIndex-nCount+1)*sizeof( STRCODE ) );
382 // release old string
383 STRING_RELEASE((STRING_TYPE *)mpData);
384 mpData = pNewData;
386 return *this;
389 StringCompare UniString::CompareToAscii( const sal_Char* pAsciiStr,
390 xub_StrLen nLen ) const
392 DBG_CHKTHIS( UniString, DbgCheckUniString );
393 DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr, nLen ),
394 "UniString::CompareToAscii() - pAsciiStr include characters > 127" );
396 // String vergleichen
397 sal_Int32 nCompare = ImplStringCompareAscii( mpData->maStr, pAsciiStr, nLen );
399 // Rueckgabewert anpassen
400 if ( nCompare == 0 )
401 return COMPARE_EQUAL;
402 else if ( nCompare < 0 )
403 return COMPARE_LESS;
404 else
405 return COMPARE_GREATER;
408 StringCompare UniString::CompareIgnoreCaseToAscii( const sal_Char* pAsciiStr,
409 xub_StrLen nLen ) const
411 DBG_CHKTHIS( UniString, DbgCheckUniString );
412 DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr, nLen ),
413 "UniString::CompareIgnoreCaseToAscii() - pAsciiStr include characters > 127" );
415 // compare strings
416 sal_Int32 nCompare = ImplStringICompareAscii( mpData->maStr, pAsciiStr, nLen );
418 if ( nCompare == 0 )
419 return COMPARE_EQUAL;
420 else if ( nCompare < 0 )
421 return COMPARE_LESS;
422 else
423 return COMPARE_GREATER;
426 sal_Bool UniString::EqualsAscii( const sal_Char* pAsciiStr ) const
428 DBG_CHKTHIS( UniString, DbgCheckUniString );
429 DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr, STRING_LEN ),
430 "UniString::EqualsAscii() - pAsciiStr include characters > 127" );
432 return (ImplStringCompareAscii( mpData->maStr, pAsciiStr ) == 0);
435 sal_Bool UniString::EqualsIgnoreCaseAscii( const sal_Char* pAsciiStr ) const
437 DBG_CHKTHIS( UniString, DbgCheckUniString );
438 DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr, STRING_LEN ),
439 "UniString::EqualsIgnoreCaseAscii() - pAsciiStr include characters > 127" );
441 return (ImplStringICompareAscii( mpData->maStr, pAsciiStr ) == 0);
444 sal_Bool UniString::EqualsAscii( const sal_Char* pAsciiStr,
445 xub_StrLen nIndex, xub_StrLen nLen ) const
447 DBG_CHKTHIS( UniString, DbgCheckUniString );
448 DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr, nLen ),
449 "UniString::EqualsAscii() - pAsciiStr include characters > 127" );
451 // Are there enough codes for comparing?
452 if ( nIndex > mpData->mnLen )
453 return (*pAsciiStr == 0);
455 return (ImplStringCompareAscii( mpData->maStr+nIndex, pAsciiStr, nLen ) == 0);
458 sal_Bool UniString::EqualsIgnoreCaseAscii( const sal_Char* pAsciiStr,
459 xub_StrLen nIndex, xub_StrLen nLen ) const
461 DBG_CHKTHIS( UniString, DbgCheckUniString );
462 DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr, nLen ),
463 "UniString::EqualsIgnoreCaseAscii() - pAsciiStr include characters > 127" );
465 // Are there enough codes for comparing?
466 if ( nIndex > mpData->mnLen )
467 return (*pAsciiStr == 0);
469 return (ImplStringICompareAscii( mpData->maStr+nIndex, pAsciiStr, nLen ) == 0);
472 xub_StrLen UniString::SearchAscii( const sal_Char* pAsciiStr, xub_StrLen nIndex ) const
474 DBG_CHKTHIS( UniString, DbgCheckUniString );
475 DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr, STRING_LEN ),
476 "UniString::SearchAscii() - pAsciiStr include characters > 127" );
478 sal_Int32 nLen = mpData->mnLen;
479 xub_StrLen nStrLen = ImplStringLen( pAsciiStr );
481 // If length of pAsciiStr is 0 or index exceeds length, it was not found
482 if ( !nStrLen || (nIndex >= nLen) )
483 return STRING_NOTFOUND;
485 const sal_Unicode* pStr = mpData->maStr;
486 pStr += nIndex;
488 if ( nStrLen == 1 )
490 sal_Unicode cSearch = (unsigned char)*pAsciiStr;
491 while ( nIndex < nLen )
493 if ( *pStr == cSearch )
494 return nIndex;
495 ++pStr,
496 ++nIndex;
499 else
501 // Only search within string
502 while ( nLen - nIndex >= nStrLen )
504 // Check if string matches
505 if ( ImplStringCompareWithoutZeroAscii( pStr, pAsciiStr, nStrLen ) == 0 )
506 return nIndex;
507 ++pStr,
508 ++nIndex;
512 return STRING_NOTFOUND;
515 xub_StrLen UniString::SearchAndReplaceAscii( const sal_Char* pAsciiStr, const UniString& rRepStr,
516 xub_StrLen nIndex )
518 DBG_CHKTHIS( UniString, DbgCheckUniString );
519 DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr, STRING_LEN ),
520 "UniString::SearchAndReplaceAscii() - pAsciiStr include characters > 127" );
522 xub_StrLen nSPos = SearchAscii( pAsciiStr, nIndex );
523 if ( nSPos != STRING_NOTFOUND )
524 Replace( nSPos, ImplStringLen( pAsciiStr ), rRepStr );
526 return nSPos;
529 void UniString::SearchAndReplaceAllAscii( const sal_Char* pAsciiStr, const UniString& rRepStr )
531 DBG_CHKTHIS( UniString, DbgCheckUniString );
532 DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr, STRING_LEN ),
533 "UniString::SearchAndReplaceAllAscii() - pAsciiStr include characters > 127" );
535 xub_StrLen nCharLen = ImplStringLen( pAsciiStr );
536 xub_StrLen nSPos = SearchAscii( pAsciiStr, 0 );
537 while ( nSPos != STRING_NOTFOUND )
539 Replace( nSPos, nCharLen, rRepStr );
540 nSPos = nSPos + rRepStr.Len();
541 nSPos = SearchAscii( pAsciiStr, nSPos );
545 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */