1 #/*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: strascii.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // no include "precompiled_tools.hxx" because this is included in other cxx files.
33 // =======================================================================
37 static BOOL
ImplDbgCheckAsciiStr( const sal_Char
* pAsciiStr
, sal_Int32 nLen
)
39 while ( nLen
&& *pAsciiStr
)
41 if ( ((unsigned char)*pAsciiStr
) > 127 )
52 // =======================================================================
54 static void ImplCopyAsciiStr( sal_Unicode
* pDest
, const sal_Char
* pSrc
,
57 DBG_ASSERT( ImplDbgCheckAsciiStr( pSrc
, nLen
),
58 "UniString::CopyAsciiStr() - pAsciiStr include characters > 127" );
62 *pDest
= (unsigned char)*pSrc
;
69 // =======================================================================
71 static sal_Int32
ImplStringCompareAscii( const sal_Unicode
* pStr1
, const sal_Char
* pStr2
)
74 while ( ((nRet
= ((sal_Int32
)*pStr1
)-((sal_Int32
)((unsigned char)*pStr2
))) == 0) &&
84 // -----------------------------------------------------------------------
86 static sal_Int32
ImplStringCompareAscii( const sal_Unicode
* pStr1
, const sal_Char
* pStr2
,
91 ((nRet
= ((sal_Int32
)*pStr1
)-((sal_Int32
)((unsigned char)*pStr2
))) == 0) &&
102 // -----------------------------------------------------------------------
104 static sal_Int32
ImplStringCompareWithoutZeroAscii( const sal_Unicode
* pStr1
, const sal_Char
* pStr2
,
109 ((nRet
= ((sal_Int32
)*pStr1
)-((sal_Int32
)((unsigned char)*pStr2
))) == 0) )
119 // -----------------------------------------------------------------------
121 static sal_Int32
ImplStringICompareAscii( const sal_Unicode
* pStr1
, const sal_Char
* pStr2
)
128 // Ist das Zeichen zwischen 'A' und 'Z' dann umwandeln
131 if ( (c1
>= 65) && (c1
<= 90) )
133 if ( (c2
>= 65) && (c2
<= 90) )
135 nRet
= ((sal_Int32
)c1
)-((sal_Int32
)((unsigned char)c2
));
147 // -----------------------------------------------------------------------
149 static sal_Int32
ImplStringICompareAscii( const sal_Unicode
* pStr1
, const sal_Char
* pStr2
,
160 // Ist das Zeichen zwischen 'A' und 'Z' dann umwandeln
163 if ( (c1
>= 65) && (c1
<= 90) )
165 if ( (c2
>= 65) && (c2
<= 90) )
167 nRet
= ((sal_Int32
)c1
)-((sal_Int32
)((unsigned char)c2
));
180 // =======================================================================
182 UniString
UniString::CreateFromAscii( const sal_Char
* pAsciiStr
)
184 DBG_ASSERT( pAsciiStr
, "UniString::CreateFromAscii() - pAsciiStr is NULL" );
186 // Stringlaenge ermitteln
187 xub_StrLen nLen
= ImplStringLen( pAsciiStr
);
192 ImplCopyAsciiStr( aTempStr
.AllocBuffer( nLen
), pAsciiStr
, nLen
);
197 // -----------------------------------------------------------------------
199 UniString
UniString::CreateFromAscii( const sal_Char
* pAsciiStr
, xub_StrLen nLen
)
201 DBG_ASSERT( pAsciiStr
, "UniString::CreateFromAscii() - pAsciiStr is NULL" );
203 // Stringlaenge ermitteln
204 if ( nLen
== STRING_LEN
)
205 nLen
= ImplStringLen( pAsciiStr
);
211 ImplCopyAsciiStr( aTempStr
.AllocBuffer( nLen
), pAsciiStr
, nLen
);
216 // -----------------------------------------------------------------------
218 UniString
& UniString::AssignAscii( const sal_Char
* pAsciiStr
)
220 DBG_CHKTHIS( UniString
, DbgCheckUniString
);
221 DBG_ASSERT( pAsciiStr
, "UniString::AssignAscii() - pAsciiStr is NULL" );
223 // Stringlaenge ermitteln
224 xub_StrLen nLen
= ImplStringLen( pAsciiStr
);
228 STRING_NEW((STRING_TYPE
**)&mpData
);
232 // Wenn String genauso lang ist, wie der String, dann direkt kopieren
233 if ( (nLen
== mpData
->mnLen
) && (mpData
->mnRefCount
== 1) )
234 ImplCopyAsciiStr( mpData
->maStr
, pAsciiStr
, nLen
);
237 // Alte Daten loeschen
238 STRING_RELEASE((STRING_TYPE
*)mpData
);
240 // Daten initialisieren und String kopieren
241 mpData
= ImplAllocData( nLen
);
242 ImplCopyAsciiStr( mpData
->maStr
, pAsciiStr
, nLen
);
249 // -----------------------------------------------------------------------
251 UniString
& UniString::AssignAscii( const sal_Char
* pAsciiStr
, xub_StrLen nLen
)
253 DBG_CHKTHIS( UniString
, DbgCheckUniString
);
254 DBG_ASSERT( pAsciiStr
, "UniString::AssignAscii() - pAsciiStr is NULL" );
256 if ( nLen
== STRING_LEN
)
257 nLen
= ImplStringLen( pAsciiStr
);
262 for ( xub_StrLen i
= 0; i
< nLen
; ++i
)
266 DBG_ERROR( "UniString::AssignAscii() : nLen is wrong" );
274 STRING_NEW((STRING_TYPE
**)&mpData
);
278 // Wenn String genauso lang ist, wie der String, dann direkt kopieren
279 if ( (nLen
== mpData
->mnLen
) && (mpData
->mnRefCount
== 1) )
280 ImplCopyAsciiStr( mpData
->maStr
, pAsciiStr
, nLen
);
283 // Alte Daten loeschen
284 STRING_RELEASE((STRING_TYPE
*)mpData
);
286 // Daten initialisieren und String kopieren
287 mpData
= ImplAllocData( nLen
);
288 ImplCopyAsciiStr( mpData
->maStr
, pAsciiStr
, nLen
);
295 // -----------------------------------------------------------------------
297 UniString
& UniString::AppendAscii( const sal_Char
* pAsciiStr
)
299 DBG_CHKTHIS( UniString
, DbgCheckUniString
);
300 DBG_ASSERT( pAsciiStr
, "UniString::AppendAscii() - pAsciiStr is NULL" );
302 // Stringlaenge ermitteln
303 sal_Int32 nCopyLen
= ImplStringLen( pAsciiStr
);
305 // Ueberlauf abfangen
306 nCopyLen
= ImplGetCopyLen( mpData
->mnLen
, nCopyLen
);
308 // Ist es kein leerer String
311 // Neue Datenstruktur und neuen String erzeugen
312 UniStringData
* pNewData
= ImplAllocData( mpData
->mnLen
+nCopyLen
);
315 memcpy( pNewData
->maStr
, mpData
->maStr
, mpData
->mnLen
*sizeof( sal_Unicode
) );
316 ImplCopyAsciiStr( pNewData
->maStr
+mpData
->mnLen
, pAsciiStr
, nCopyLen
);
318 // Alte Daten loeschen und Neue zuweisen
319 STRING_RELEASE((STRING_TYPE
*)mpData
);
326 // -----------------------------------------------------------------------
328 UniString
& UniString::AppendAscii( const sal_Char
* pAsciiStr
, xub_StrLen nLen
)
330 DBG_CHKTHIS( UniString
, DbgCheckUniString
);
331 DBG_ASSERT( pAsciiStr
, "UniString::AppendAscii() - pAsciiStr is NULL" );
333 if ( nLen
== STRING_LEN
)
334 nLen
= ImplStringLen( pAsciiStr
);
339 for ( xub_StrLen i
= 0; i
< nLen
; ++i
)
343 DBG_ERROR( "UniString::AppendAscii() : nLen is wrong" );
349 // Ueberlauf abfangen
350 sal_Int32 nCopyLen
= ImplGetCopyLen( mpData
->mnLen
, nLen
);
352 // Ist es kein leerer String
355 // Neue Datenstruktur und neuen String erzeugen
356 UniStringData
* pNewData
= ImplAllocData( mpData
->mnLen
+nCopyLen
);
359 memcpy( pNewData
->maStr
, mpData
->maStr
, mpData
->mnLen
*sizeof( sal_Unicode
) );
360 ImplCopyAsciiStr( pNewData
->maStr
+mpData
->mnLen
, pAsciiStr
, nCopyLen
);
362 // Alte Daten loeschen und Neue zuweisen
363 STRING_RELEASE((STRING_TYPE
*)mpData
);
370 // -----------------------------------------------------------------------
372 UniString
& UniString::InsertAscii( const char* pAsciiStr
, xub_StrLen nIndex
)
374 DBG_CHKTHIS( UniString
, DbgCheckUniString
);
375 DBG_ASSERT( pAsciiStr
, "UniString::InsertAscii() - pAsciiStr is NULL" );
377 // Stringlaenge ermitteln
378 sal_Int32 nCopyLen
= ImplStringLen( pAsciiStr
);
380 // Ueberlauf abfangen
381 nCopyLen
= ImplGetCopyLen( mpData
->mnLen
, nCopyLen
);
383 // Ist der einzufuegende String ein Leerstring
387 // Index groesser als Laenge
388 if ( nIndex
> mpData
->mnLen
)
389 nIndex
= static_cast< xub_StrLen
>(mpData
->mnLen
);
391 // Neue Laenge ermitteln und neuen String anlegen
392 UniStringData
* pNewData
= ImplAllocData( mpData
->mnLen
+nCopyLen
);
395 memcpy( pNewData
->maStr
, mpData
->maStr
, nIndex
*sizeof( sal_Unicode
) );
396 ImplCopyAsciiStr( pNewData
->maStr
+nIndex
, pAsciiStr
, nCopyLen
);
397 memcpy( pNewData
->maStr
+nIndex
+nCopyLen
, mpData
->maStr
+nIndex
,
398 (mpData
->mnLen
-nIndex
)*sizeof( sal_Unicode
) );
400 // Alte Daten loeschen und Neue zuweisen
401 STRING_RELEASE((STRING_TYPE
*)mpData
);
407 // -----------------------------------------------------------------------
409 UniString
& UniString::ReplaceAscii( xub_StrLen nIndex
, xub_StrLen nCount
,
410 const sal_Char
* pAsciiStr
, xub_StrLen nStrLen
)
412 DBG_CHKTHIS( UniString
, DbgCheckUniString
);
413 DBG_ASSERT( pAsciiStr
, "UniString::ReplaceAscii() - pAsciiStr is NULL" );
415 // Wenn Index groessergleich Laenge ist, dann ist es ein Append
416 if ( nIndex
>= mpData
->mnLen
)
418 AppendAscii( pAsciiStr
, nStrLen
);
422 // Ist es eine Zuweisung
423 if ( (nIndex
== 0) && (nCount
>= mpData
->mnLen
) )
425 AssignAscii( pAsciiStr
, nStrLen
);
430 if ( nStrLen
== STRING_LEN
)
431 nStrLen
= ImplStringLen( pAsciiStr
);
433 return Erase( nIndex
, nCount
);
435 // nCount darf nicht ueber das Stringende hinnausgehen
436 if ( nCount
> mpData
->mnLen
- nIndex
)
437 nCount
= static_cast< xub_StrLen
>(mpData
->mnLen
-nIndex
);
439 // Reicht eine zeichenweise Zuweisung
440 if ( nCount
== nStrLen
)
443 ImplCopyAsciiStr( mpData
->maStr
+nIndex
, pAsciiStr
, nStrLen
);
447 // Ueberlauf abfangen
448 sal_Int32 n
= ImplGetCopyLen( mpData
->mnLen
-nCount
, nStrLen
);
450 // Neue Daten anlegen
451 STRINGDATA
* pNewData
= ImplAllocData( mpData
->mnLen
-nCount
+n
);
454 memcpy( pNewData
->maStr
, mpData
->maStr
, nIndex
*sizeof( STRCODE
) );
455 ImplCopyAsciiStr( pNewData
->maStr
+nIndex
, pAsciiStr
, n
);
456 memcpy( pNewData
->maStr
+nIndex
+n
, mpData
->maStr
+nIndex
+nCount
,
457 (mpData
->mnLen
-nIndex
-nCount
+1)*sizeof( STRCODE
) );
459 // Alte Daten loeschen und Neue zuweisen
460 STRING_RELEASE((STRING_TYPE
*)mpData
);
466 // -----------------------------------------------------------------------
468 StringCompare
UniString::CompareToAscii( const sal_Char
* pAsciiStr
,
469 xub_StrLen nLen
) const
471 DBG_CHKTHIS( UniString
, DbgCheckUniString
);
472 DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr
, nLen
),
473 "UniString::CompareToAscii() - pAsciiStr include characters > 127" );
475 // String vergleichen
476 sal_Int32 nCompare
= ImplStringCompareAscii( mpData
->maStr
, pAsciiStr
, nLen
);
478 // Rueckgabewert anpassen
480 return COMPARE_EQUAL
;
481 else if ( nCompare
< 0 )
484 return COMPARE_GREATER
;
487 // -----------------------------------------------------------------------
489 StringCompare
UniString::CompareIgnoreCaseToAscii( const sal_Char
* pAsciiStr
,
490 xub_StrLen nLen
) const
492 DBG_CHKTHIS( UniString
, DbgCheckUniString
);
493 DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr
, nLen
),
494 "UniString::CompareIgnoreCaseToAscii() - pAsciiStr include characters > 127" );
496 // String vergleichen
497 sal_Int32 nCompare
= ImplStringICompareAscii( mpData
->maStr
, pAsciiStr
, nLen
);
499 // Rueckgabewert anpassen
501 return COMPARE_EQUAL
;
502 else if ( nCompare
< 0 )
505 return COMPARE_GREATER
;
508 // -----------------------------------------------------------------------
510 BOOL
UniString::EqualsAscii( const sal_Char
* pAsciiStr
) const
512 DBG_CHKTHIS( UniString
, DbgCheckUniString
);
513 DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr
, STRING_LEN
),
514 "UniString::EqualsAscii() - pAsciiStr include characters > 127" );
516 return (ImplStringCompareAscii( mpData
->maStr
, pAsciiStr
) == 0);
519 // -----------------------------------------------------------------------
521 BOOL
UniString::EqualsIgnoreCaseAscii( const sal_Char
* pAsciiStr
) const
523 DBG_CHKTHIS( UniString
, DbgCheckUniString
);
524 DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr
, STRING_LEN
),
525 "UniString::EqualsIgnoreCaseAscii() - pAsciiStr include characters > 127" );
527 return (ImplStringICompareAscii( mpData
->maStr
, pAsciiStr
) == 0);
530 // -----------------------------------------------------------------------
532 BOOL
UniString::EqualsAscii( const sal_Char
* pAsciiStr
,
533 xub_StrLen nIndex
, xub_StrLen nLen
) const
535 DBG_CHKTHIS( UniString
, DbgCheckUniString
);
536 DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr
, nLen
),
537 "UniString::EqualsAscii() - pAsciiStr include characters > 127" );
539 // Are there enough codes for comparing?
540 if ( nIndex
> mpData
->mnLen
)
541 return (*pAsciiStr
== 0);
543 return (ImplStringCompareAscii( mpData
->maStr
+nIndex
, pAsciiStr
, nLen
) == 0);
546 // -----------------------------------------------------------------------
548 BOOL
UniString::EqualsIgnoreCaseAscii( const sal_Char
* pAsciiStr
,
549 xub_StrLen nIndex
, xub_StrLen nLen
) const
551 DBG_CHKTHIS( UniString
, DbgCheckUniString
);
552 DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr
, nLen
),
553 "UniString::EqualsIgnoreCaseAscii() - pAsciiStr include characters > 127" );
555 // Are there enough codes for comparing?
556 if ( nIndex
> mpData
->mnLen
)
557 return (*pAsciiStr
== 0);
559 return (ImplStringICompareAscii( mpData
->maStr
+nIndex
, pAsciiStr
, nLen
) == 0);
562 // -----------------------------------------------------------------------
564 xub_StrLen
UniString::SearchAscii( const sal_Char
* pAsciiStr
, xub_StrLen nIndex
) const
566 DBG_CHKTHIS( UniString
, DbgCheckUniString
);
567 DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr
, STRING_LEN
),
568 "UniString::SearchAscii() - pAsciiStr include characters > 127" );
570 sal_Int32 nLen
= mpData
->mnLen
;
571 xub_StrLen nStrLen
= ImplStringLen( pAsciiStr
);
573 // Falls die Laenge des uebergebenen Strings 0 ist oder der Index
574 // hinter dem String liegt, dann wurde der String nicht gefunden
575 if ( !nStrLen
|| (nIndex
>= nLen
) )
576 return STRING_NOTFOUND
;
578 const sal_Unicode
* pStr
= mpData
->maStr
;
583 sal_Unicode cSearch
= (unsigned char)*pAsciiStr
;
584 while ( nIndex
< nLen
)
586 if ( *pStr
== cSearch
)
594 // Nur innerhalb des Strings suchen
595 while ( nLen
- nIndex
>= nStrLen
)
597 // Stimmt der String ueberein
598 if ( ImplStringCompareWithoutZeroAscii( pStr
, pAsciiStr
, nStrLen
) == 0 )
605 return STRING_NOTFOUND
;
608 // -----------------------------------------------------------------------
610 xub_StrLen
UniString::SearchAndReplaceAscii( const sal_Char
* pAsciiStr
, const UniString
& rRepStr
,
613 DBG_CHKTHIS( UniString
, DbgCheckUniString
);
614 DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr
, STRING_LEN
),
615 "UniString::SearchAndReplaceAscii() - pAsciiStr include characters > 127" );
617 xub_StrLen nSPos
= SearchAscii( pAsciiStr
, nIndex
);
618 if ( nSPos
!= STRING_NOTFOUND
)
619 Replace( nSPos
, ImplStringLen( pAsciiStr
), rRepStr
);
624 // -----------------------------------------------------------------------
626 void UniString::SearchAndReplaceAllAscii( const sal_Char
* pAsciiStr
, const UniString
& rRepStr
)
628 DBG_CHKTHIS( UniString
, DbgCheckUniString
);
629 DBG_ASSERT( ImplDbgCheckAsciiStr( pAsciiStr
, STRING_LEN
),
630 "UniString::SearchAndReplaceAllAscii() - pAsciiStr include characters > 127" );
632 xub_StrLen nCharLen
= ImplStringLen( pAsciiStr
);
633 xub_StrLen nSPos
= SearchAscii( pAsciiStr
, 0 );
634 while ( nSPos
!= STRING_NOTFOUND
)
636 Replace( nSPos
, nCharLen
, rRepStr
);
637 nSPos
= nSPos
+ rRepStr
.Len();
638 nSPos
= SearchAscii( pAsciiStr
, nSPos
);