/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// no include "precompiled_tools.hxx" because this is included in other cxx files.

// =======================================================================

static sal_Int32 ImplStringCompare( const STRCODE* pStr1, const STRCODE* pStr2 )
{
	sal_Int32 nRet;
	while ( ((nRet = ((sal_Int32)((STRCODEU)*pStr1))-((sal_Int32)((STRCODEU)*pStr2))) == 0) &&
			*pStr2 )
	{
		++pStr1,
		++pStr2;
	}

	return nRet;
}

// -----------------------------------------------------------------------

static sal_Int32 ImplStringCompare( const STRCODE* pStr1, const STRCODE* pStr2,
									xub_StrLen nCount )
{
	sal_Int32 nRet = 0;
	while ( nCount &&
			((nRet = ((sal_Int32)((STRCODEU)*pStr1))-((sal_Int32)((STRCODEU)*pStr2))) == 0) &&
			*pStr2 )
	{
		++pStr1,
		++pStr2,
		--nCount;
	}

	return nRet;
}

// -----------------------------------------------------------------------

static sal_Int32 ImplStringCompareWithoutZero( const STRCODE* pStr1, const STRCODE* pStr2,
											   sal_Int32 nCount )
{
	sal_Int32 nRet = 0;
	while ( nCount &&
			((nRet = ((sal_Int32)((STRCODEU)*pStr1))-((sal_Int32)((STRCODEU)*pStr2))) == 0) )
	{
		++pStr1,
		++pStr2,
		--nCount;
	}

	return nRet;
}

// -----------------------------------------------------------------------

static sal_Int32 ImplStringICompare( const STRCODE* pStr1, const STRCODE* pStr2 )
{
	sal_Int32	nRet;
	STRCODE 	c1;
	STRCODE 	c2;
	do
	{
		// Ist das Zeichen zwischen 'A' und 'Z' dann umwandeln
		c1 = *pStr1;
		c2 = *pStr2;
		if ( (c1 >= 65) && (c1 <= 90) )
			c1 += 32;
		if ( (c2 >= 65) && (c2 <= 90) )
			c2 += 32;
		nRet = ((sal_Int32)((STRCODEU)c1))-((sal_Int32)((STRCODEU)c2));
		if ( nRet != 0 )
			break;

		++pStr1,
		++pStr2;
	}
	while ( c2 );

	return nRet;
}

// -----------------------------------------------------------------------

static sal_Int32 ImplStringICompare( const STRCODE* pStr1, const STRCODE* pStr2,
									 xub_StrLen nCount )
{
	sal_Int32	nRet = 0;
	STRCODE 	c1;
	STRCODE 	c2;
	do
	{
		if ( !nCount )
			break;

		// Ist das Zeichen zwischen 'A' und 'Z' dann umwandeln
		c1 = *pStr1;
		c2 = *pStr2;
		if ( (c1 >= 65) && (c1 <= 90) )
			c1 += 32;
		if ( (c2 >= 65) && (c2 <= 90) )
			c2 += 32;
		nRet = ((sal_Int32)((STRCODEU)c1))-((sal_Int32)((STRCODEU)c2));
		if ( nRet != 0 )
			break;

		++pStr1,
		++pStr2,
		--nCount;
	}
	while ( c2 );

	return nRet;
}

// -----------------------------------------------------------------------

static sal_Int32 ImplStringICompareWithoutZero( const STRCODE* pStr1, const STRCODE* pStr2,
												sal_Int32 nCount )
{
	sal_Int32	nRet = 0;
	STRCODE 	c1;
	STRCODE 	c2;
	do
	{
		if ( !nCount )
			break;

		// Ist das Zeichen zwischen 'A' und 'Z' dann umwandeln
		c1 = *pStr1;
		c2 = *pStr2;
		if ( (c1 >= 65) && (c1 <= 90) )
			c1 += 32;
		if ( (c2 >= 65) && (c2 <= 90) )
			c2 += 32;
		nRet = ((sal_Int32)((STRCODEU)c1))-((sal_Int32)((STRCODEU)c2));

		++pStr1,
		++pStr2,
		--nCount;
	}
	while ( nRet == 0 );

	return nRet;
}

// =======================================================================

#ifdef DBG_UTIL
const char* DBGCHECKSTRING( const void* pString )
{
	STRING* p = (STRING*)pString;

	if ( p->GetBuffer()[p->Len()] != 0 )
		return "String damaged: aStr[nLen] != 0";

	return NULL;
}
#endif

// =======================================================================

static STRINGDATA* ImplAllocData( sal_Int32 nLen )
{
	// Dann kopiere die Daten
	STRINGDATA* pData	= (STRINGDATA*)rtl_allocateMemory( sizeof(STRINGDATA)+(nLen*sizeof( STRCODE )) );
	pData->mnRefCount	= 1;
	pData->mnLen		= nLen;
	pData->maStr[nLen]	= 0;
	return pData;
}

// -----------------------------------------------------------------------

static STRINGDATA* _ImplCopyData( STRINGDATA* pData )
{
	unsigned int	nSize		= sizeof(STRINGDATA)+(pData->mnLen*sizeof( STRCODE ));
	STRINGDATA* 	pNewData	= (STRINGDATA*)rtl_allocateMemory( nSize );
	memcpy( pNewData, pData, nSize );
	pNewData->mnRefCount = 1;
	STRING_RELEASE((STRING_TYPE *)pData);
	return pNewData;
}

// -----------------------------------------------------------------------

inline void STRING::ImplCopyData()
{
	DBG_ASSERT( (mpData->mnRefCount != 0), "String::ImplCopyData() - RefCount == 0" );

	// ist es ein referenzierter String, dann die Daten abkoppeln
	if ( mpData->mnRefCount != 1 )
		mpData = _ImplCopyData( mpData );
}

// -----------------------------------------------------------------------

inline STRCODE* STRING::ImplCopyStringData( STRCODE* pStr )
{
	// Ist der Referenzzaehler groesser 0
	if ( mpData->mnRefCount != 1 ) {
        DBG_ASSERT( (pStr >= mpData->maStr) &&
                    ((pStr-mpData->maStr) < mpData->mnLen),
                    "ImplCopyStringData - pStr from other String-Instanz" );
        unsigned int nIndex = (unsigned int)(pStr-mpData->maStr);
        mpData = _ImplCopyData( mpData );
        pStr = mpData->maStr + nIndex;
    }
	return pStr;
}

// -----------------------------------------------------------------------

inline sal_Int32 ImplGetCopyLen( sal_Int32 nStrLen, sal_Int32 nCopyLen )
{
    OSL_ASSERT(nStrLen <= STRING_MAXLEN && nCopyLen <= STRING_MAXLEN);
	if ( nCopyLen > STRING_MAXLEN-nStrLen )
		nCopyLen = STRING_MAXLEN-nStrLen;
	return nCopyLen;
}

// =======================================================================

STRING::STRING() 
	: mpData(NULL)
{
	DBG_CTOR( STRING, DBGCHECKSTRING );

	STRING_NEW((STRING_TYPE **)&mpData);
}

// -----------------------------------------------------------------------

STRING::STRING( const STRING& rStr )
{
	DBG_CTOR( STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );

	// Pointer auf die Daten des uebergebenen Strings setzen und
	// Referenzzaehler erhoehen
	STRING_ACQUIRE((STRING_TYPE *)rStr.mpData);
	mpData = rStr.mpData;
}

// -----------------------------------------------------------------------

STRING::STRING( const STRING& rStr, xub_StrLen nPos, xub_StrLen nLen )
: mpData( NULL )
{
	DBG_CTOR( STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );

	// Stringlaenge ermitteln
	if ( nPos > rStr.mpData->mnLen )
		nLen = 0;
	else
	{
		// Laenge korrigieren, wenn noetig
		sal_Int32 nMaxLen = rStr.mpData->mnLen-nPos;
		if ( nLen > nMaxLen )
			nLen = static_cast< xub_StrLen >(nMaxLen);
	}

	// Ist es kein leerer String
	if ( nLen )
	{
		// Reicht ein einfaches erhoehen des Referenzcounters
		if ( (nPos == 0) && (nLen == rStr.mpData->mnLen) )
		{
			STRING_ACQUIRE((STRING_TYPE *)rStr.mpData);
			mpData = rStr.mpData;
		}
		else
		{
			// Verwaltungsdaten anlegen und String kopieren
			mpData = ImplAllocData( nLen );
			memcpy( mpData->maStr, rStr.mpData->maStr+nPos, nLen*sizeof( STRCODE ) );
		}
	}
	else
	{
		STRING_NEW((STRING_TYPE **)&mpData);
	}
}

// -----------------------------------------------------------------------

STRING::STRING( const STRCODE* pCharStr )
	: mpData(NULL)
{
	DBG_CTOR( STRING, DBGCHECKSTRING );

	// Stringlaenge ermitteln
	// Bei diesem Ctor darf NULL uebergeben werden
	xub_StrLen nLen;
	if ( pCharStr )
		nLen = ImplStringLen( pCharStr );
	else
		nLen = 0;

	// Ist es kein leerer String
	if ( nLen )
	{
		// Verwaltungsdaten anlegen und String kopieren
		mpData = ImplAllocData( nLen );
		memcpy( mpData->maStr, pCharStr, nLen*sizeof( STRCODE ) );
	}
	else
	{
		STRING_NEW((STRING_TYPE **)&mpData);
	}
}

// -----------------------------------------------------------------------

STRING::STRING( const STRCODE* pCharStr, xub_StrLen nLen )
: mpData(NULL)
{
	DBG_CTOR( STRING, DBGCHECKSTRING );
	DBG_ASSERT( pCharStr, "String::String() - pCharStr is NULL" );

	if ( nLen == STRING_LEN )
		nLen = ImplStringLen( pCharStr );

#ifdef DBG_UTIL
	if ( DbgIsAssert() )
	{
		for ( xub_StrLen i = 0; i < nLen; i++ )
		{
			if ( !pCharStr[i] )
			{
				DBG_ERROR( "String::String() : nLen is wrong" );
			}
		}
	}
#endif

	// Ist es kein leerer String
	if ( nLen )
	{
		// Verwaltungsdaten anlegen und String kopieren
		mpData = ImplAllocData( nLen );
		memcpy( mpData->maStr, pCharStr, nLen*sizeof( STRCODE ) );
	}
	else
	{
		STRING_NEW((STRING_TYPE **)&mpData);
	}
}

// -----------------------------------------------------------------------

STRING::STRING( STRCODE c )
{
	DBG_CTOR( STRING, DBGCHECKSTRING );
	DBG_ASSERT( c, "String::String() - c is 0" );

	// Verwaltungsdaten anlegen und initialisieren
	mpData = ImplAllocData( 1 );
	mpData->maStr[0] = c;
}

// -----------------------------------------------------------------------

STRING::~STRING()
{
	DBG_DTOR( STRING, DBGCHECKSTRING );

	// Daten loeschen
	STRING_RELEASE((STRING_TYPE *)mpData);
}

// -----------------------------------------------------------------------

STRING& STRING::Assign( const STRING& rStr )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );

	STRING_ACQUIRE((STRING_TYPE *)rStr.mpData);
	STRING_RELEASE((STRING_TYPE *)mpData);
	mpData = rStr.mpData;
	return *this;
}

// -----------------------------------------------------------------------

STRING& STRING::Assign( const STRCODE* pCharStr )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_ASSERT( pCharStr, "String::Assign() - pCharStr is NULL" );

	// Stringlaenge ermitteln
	xub_StrLen nLen = ImplStringLen( pCharStr );

	if ( !nLen )
	{
		STRING_NEW((STRING_TYPE **)&mpData);
	}
	else
	{
		// Wenn String genauso lang ist, wie der String, dann direkt kopieren
		if ( (nLen == mpData->mnLen) && (mpData->mnRefCount == 1) )
			memcpy( mpData->maStr, pCharStr, nLen*sizeof( STRCODE ) );
		else
		{
			// Alte Daten loeschen
			STRING_RELEASE((STRING_TYPE *)mpData);

			// Daten initialisieren und String kopieren
			mpData = ImplAllocData( nLen );
			memcpy( mpData->maStr, pCharStr, nLen*sizeof( STRCODE ) );
		}
	}

	return *this;
}

// -----------------------------------------------------------------------

STRING& STRING::Assign( const STRCODE* pCharStr, xub_StrLen nLen )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_ASSERT( pCharStr, "String::Assign() - pCharStr is NULL" );

	if ( nLen == STRING_LEN )
		nLen = ImplStringLen( pCharStr );

#ifdef DBG_UTIL
	if ( DbgIsAssert() )
	{
		for ( xub_StrLen i = 0; i < nLen; i++ )
		{
			if ( !pCharStr[i] )
			{
				DBG_ERROR( "String::Assign() : nLen is wrong" );
			}
		}
	}
#endif

	if ( !nLen )
	{
		STRING_NEW((STRING_TYPE **)&mpData);
	}
	else
	{
		// Wenn String genauso lang ist, wie der String, dann direkt kopieren
		if ( (nLen == mpData->mnLen) && (mpData->mnRefCount == 1) )
			memcpy( mpData->maStr, pCharStr, nLen*sizeof( STRCODE ) );
		else
		{
			// Alte Daten loeschen
			STRING_RELEASE((STRING_TYPE *)mpData);

			// Daten initialisieren und String kopieren
			mpData = ImplAllocData( nLen );
			memcpy( mpData->maStr, pCharStr, nLen*sizeof( STRCODE ) );
		}
	}

	return *this;
}

// -----------------------------------------------------------------------

STRING& STRING::Assign( STRCODE c )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_ASSERT( c, "String::Assign() - c is 0" );

	// Verwaltungsdaten anlegen und initialisieren
	STRING_RELEASE((STRING_TYPE *)mpData);
	mpData = ImplAllocData( 1 );
	mpData->maStr[0] = c;
	return *this;
}

// -----------------------------------------------------------------------

STRING& STRING::Append( const STRING& rStr )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );

	// Wenn String leer, dann reicht eine Zuweisung
	sal_Int32 nLen = mpData->mnLen;
	if ( !nLen )
	{
		STRING_ACQUIRE((STRING_TYPE *)rStr.mpData);
		STRING_RELEASE((STRING_TYPE *)mpData);
		mpData = rStr.mpData;
	}
	else
	{
		// Ueberlauf abfangen
		sal_Int32 nCopyLen = ImplGetCopyLen( nLen, rStr.mpData->mnLen );

		// Ist der uebergebene String kein Leerstring
		if ( nCopyLen )
		{
			// Neue Datenstruktur und neuen String erzeugen
			STRINGDATA* pNewData = ImplAllocData( nLen+nCopyLen );

			// String kopieren
			memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) );
			memcpy( pNewData->maStr+nLen, rStr.mpData->maStr, nCopyLen*sizeof( STRCODE ) );

			// Alte Daten loeschen und Neue zuweisen
			STRING_RELEASE((STRING_TYPE *)mpData);
			mpData = pNewData;
		}
	}

	return *this;
}

// -----------------------------------------------------------------------

STRING& STRING::Append( const STRCODE* pCharStr )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_ASSERT( pCharStr, "String::Append() - pCharStr is NULL" );

	// Stringlaenge ermitteln
	sal_Int32 nLen = mpData->mnLen;
	sal_Int32 nCopyLen = ImplStringLen( pCharStr );

	// Ueberlauf abfangen
	nCopyLen = ImplGetCopyLen( nLen, nCopyLen );

	// Ist es kein leerer String
	if ( nCopyLen )
	{
		// Neue Datenstruktur und neuen String erzeugen
		STRINGDATA* pNewData = ImplAllocData( nLen+nCopyLen );

		// String kopieren
		memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) );
		memcpy( pNewData->maStr+nLen, pCharStr, nCopyLen*sizeof( STRCODE ) );

		// Alte Daten loeschen und Neue zuweisen
		STRING_RELEASE((STRING_TYPE *)mpData);
		mpData = pNewData;
	}

	return *this;
}

// -----------------------------------------------------------------------

STRING& STRING::Append( const STRCODE* pCharStr, xub_StrLen nCharLen )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_ASSERT( pCharStr, "String::Append() - pCharStr is NULL" );

	if ( nCharLen == STRING_LEN )
		nCharLen = ImplStringLen( pCharStr );

#ifdef DBG_UTIL
	if ( DbgIsAssert() )
	{
		for ( xub_StrLen i = 0; i < nCharLen; i++ )
		{
			if ( !pCharStr[i] )
			{
				DBG_ERROR( "String::Append() : nLen is wrong" );
			}
		}
	}
#endif

	// Ueberlauf abfangen
	sal_Int32 nLen = mpData->mnLen;
	sal_Int32 nCopyLen = ImplGetCopyLen( nLen, nCharLen );

	// Ist es kein leerer String
	if ( nCopyLen )
	{
		// Neue Datenstruktur und neuen String erzeugen
		STRINGDATA* pNewData = ImplAllocData( nLen+nCopyLen );

		// String kopieren
		memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) );
		memcpy( pNewData->maStr+nLen, pCharStr, nCopyLen*sizeof( STRCODE ) );

		// Alte Daten loeschen und Neue zuweisen
		STRING_RELEASE((STRING_TYPE *)mpData);
		mpData = pNewData;
	}

	return *this;
}

// -----------------------------------------------------------------------

STRING& STRING::Append( STRCODE c )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	// kein 0-Character und maximale Stringlaenge nicht ueberschreiten
	sal_Int32 nLen = mpData->mnLen;
	if ( c && (nLen < STRING_MAXLEN) )
	{
		// Neue Datenstruktur und neuen String erzeugen
		STRINGDATA* pNewData = ImplAllocData( nLen+1 );

		// String kopieren
		memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) );
		pNewData->maStr[nLen] = c;

		// Alte Daten loeschen und Neue zuweisen
		STRING_RELEASE((STRING_TYPE *)mpData);
		mpData = pNewData;
	}

	return *this;
}

// -----------------------------------------------------------------------

void STRING::SetChar( xub_StrLen nIndex, STRCODE c )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_ASSERT( nIndex < mpData->mnLen, "String::SetChar() - nIndex > String.Len()" );

	// Daten kopieren, wenn noetig und Character zuweisen
	ImplCopyData();
	mpData->maStr[nIndex] = c;
}

// -----------------------------------------------------------------------

STRING& STRING::Insert( const STRING& rStr, xub_StrLen nIndex )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );

	// Ueberlauf abfangen
	sal_Int32 nCopyLen = ImplGetCopyLen( mpData->mnLen, rStr.mpData->mnLen );

	// Ist der einzufuegende String ein Leerstring
	if ( !nCopyLen )
		return *this;

	// Index groesser als Laenge
	if ( nIndex > mpData->mnLen )
		nIndex = static_cast< xub_StrLen >(mpData->mnLen);

	// Neue Laenge ermitteln und neuen String anlegen
	STRINGDATA* pNewData = ImplAllocData( mpData->mnLen+nCopyLen );

	// String kopieren
	memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( STRCODE ) );
	memcpy( pNewData->maStr+nIndex, rStr.mpData->maStr, nCopyLen*sizeof( STRCODE ) );
	memcpy( pNewData->maStr+nIndex+nCopyLen, mpData->maStr+nIndex,
			(mpData->mnLen-nIndex)*sizeof( STRCODE ) );

	// Alte Daten loeschen und Neue zuweisen
	STRING_RELEASE((STRING_TYPE *)mpData);
	mpData = pNewData;

	return *this;
}

// -----------------------------------------------------------------------

STRING& STRING::Insert( const STRING& rStr, xub_StrLen nPos, xub_StrLen nLen,
						xub_StrLen nIndex )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );

	// Stringlaenge ermitteln
	if ( nPos > rStr.mpData->mnLen )
		nLen = 0;
	else
	{
		// Laenge korrigieren, wenn noetig
		sal_Int32 nMaxLen = rStr.mpData->mnLen-nPos;
		if ( nLen > nMaxLen )
			nLen = static_cast< xub_StrLen >(nMaxLen);
	}

	// Ueberlauf abfangen
	sal_Int32 nCopyLen = ImplGetCopyLen( mpData->mnLen, nLen );

	// Ist der einzufuegende String ein Leerstring
	if ( !nCopyLen )
		return *this;

	// Index groesser als Laenge
	if ( nIndex > mpData->mnLen )
		nIndex = static_cast< xub_StrLen >(mpData->mnLen);

	// Neue Laenge ermitteln und neuen String anlegen
	STRINGDATA* pNewData = ImplAllocData( mpData->mnLen+nCopyLen );

	// String kopieren
	memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( STRCODE ) );
	memcpy( pNewData->maStr+nIndex, rStr.mpData->maStr+nPos, nCopyLen*sizeof( STRCODE ) );
	memcpy( pNewData->maStr+nIndex+nCopyLen, mpData->maStr+nIndex,
			(mpData->mnLen-nIndex)*sizeof( STRCODE ) );

	// Alte Daten loeschen und Neue zuweisen
	STRING_RELEASE((STRING_TYPE *)mpData);
	mpData = pNewData;

	return *this;
}

// -----------------------------------------------------------------------

STRING& STRING::Insert( const STRCODE* pCharStr, xub_StrLen nIndex )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_ASSERT( pCharStr, "String::Insert() - pCharStr is NULL" );

	// Stringlaenge ermitteln
	sal_Int32 nCopyLen = ImplStringLen( pCharStr );

	// Ueberlauf abfangen
	nCopyLen = ImplGetCopyLen( mpData->mnLen, nCopyLen );

	// Ist der einzufuegende String ein Leerstring
	if ( !nCopyLen )
		return *this;

	// Index groesser als Laenge
	if ( nIndex > mpData->mnLen )
		nIndex = static_cast< xub_StrLen >(mpData->mnLen);

	// Neue Laenge ermitteln und neuen String anlegen
	STRINGDATA* pNewData = ImplAllocData( mpData->mnLen+nCopyLen );

	// String kopieren
	memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( STRCODE ) );
	memcpy( pNewData->maStr+nIndex, pCharStr, nCopyLen*sizeof( STRCODE ) );
	memcpy( pNewData->maStr+nIndex+nCopyLen, mpData->maStr+nIndex,
			(mpData->mnLen-nIndex)*sizeof( STRCODE ) );

	// Alte Daten loeschen und Neue zuweisen
	STRING_RELEASE((STRING_TYPE *)mpData);
	mpData = pNewData;

	return *this;
}

// -----------------------------------------------------------------------

STRING& STRING::Insert( STRCODE c, xub_StrLen nIndex )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	// Ist es kein 0-Character
	if ( !c || (mpData->mnLen == STRING_MAXLEN) )
		return *this;

	// Index groesser als Laenge
	if ( nIndex > mpData->mnLen )
		nIndex = static_cast< xub_StrLen >(mpData->mnLen);

	// Neue Laenge ermitteln und neuen String anlegen
	STRINGDATA* pNewData = ImplAllocData( mpData->mnLen+1 );

	// String kopieren
	memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( STRCODE ) );
	pNewData->maStr[nIndex] = c;
	memcpy( pNewData->maStr+nIndex+1, mpData->maStr+nIndex,
			(mpData->mnLen-nIndex)*sizeof( STRCODE ) );

	// Alte Daten loeschen und Neue zuweisen
	STRING_RELEASE((STRING_TYPE *)mpData);
	mpData = pNewData;

	return *this;
}

// -----------------------------------------------------------------------

STRING& STRING::Replace( xub_StrLen nIndex, xub_StrLen nCount, const STRING& rStr )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );

	// Wenn Index groessergleich Laenge ist, dann ist es ein Append
	if ( nIndex >= mpData->mnLen )
	{
		Append( rStr );
		return *this;
	}

	// Ist es eine Zuweisung
	if ( (nIndex == 0) && (nCount >= mpData->mnLen) )
	{
		Assign( rStr );
		return *this;
	}

	// Reicht ein Erase
	sal_Int32 nStrLen = rStr.mpData->mnLen;
	if ( !nStrLen )
		return Erase( nIndex, nCount );

	// nCount darf nicht ueber das Stringende hinnausgehen
	if ( nCount > mpData->mnLen - nIndex )
		nCount = static_cast< xub_StrLen >(mpData->mnLen-nIndex);

	// Reicht ein Insert
	if ( !nCount )
		return Insert( rStr, nIndex );

	// Reicht eine zeichenweise Zuweisung
	if ( nCount == nStrLen )
	{
		ImplCopyData();
		memcpy( mpData->maStr+nIndex, rStr.mpData->maStr, nCount*sizeof( STRCODE ) );
		return *this;
	}

	// Ueberlauf abfangen
	nStrLen = ImplGetCopyLen( mpData->mnLen-nCount, nStrLen );

	// Neue Daten anlegen
	STRINGDATA* pNewData = ImplAllocData( mpData->mnLen-nCount+nStrLen );

	// String kopieren
	memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( STRCODE ) );
	memcpy( pNewData->maStr+nIndex, rStr.mpData->maStr, nStrLen*sizeof( STRCODE ) );
	memcpy( pNewData->maStr+nIndex+nStrLen, mpData->maStr+nIndex+nCount,
			(mpData->mnLen-nIndex-nCount+1)*sizeof( STRCODE ) );

	// Alte Daten loeschen und Neue zuweisen
	STRING_RELEASE((STRING_TYPE *)mpData);
	mpData = pNewData;

	return *this;
}

// -----------------------------------------------------------------------

STRING& STRING::Erase( xub_StrLen nIndex, xub_StrLen nCount )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	// Ist der Index ausserhalb des Strings oder ist nCount == 0
	if ( (nIndex >= mpData->mnLen) || !nCount )
		return *this;

	// nCount darf nicht ueber das Stringende hinnausgehen
	if ( nCount > mpData->mnLen - nIndex )
		nCount = static_cast< xub_StrLen >(mpData->mnLen-nIndex);

	// Ist das Ergebnis kein Leerstring
	if ( mpData->mnLen - nCount )
	{
		// Neue Daten anlegen
		STRINGDATA* pNewData = ImplAllocData( mpData->mnLen-nCount );

		// String kopieren
		memcpy( pNewData->maStr, mpData->maStr, nIndex*sizeof( STRCODE ) );
		memcpy( pNewData->maStr+nIndex, mpData->maStr+nIndex+nCount,
				(mpData->mnLen-nIndex-nCount+1)*sizeof( STRCODE ) );

		// Alte Daten loeschen und Neue zuweisen
		STRING_RELEASE((STRING_TYPE *)mpData);
		mpData = pNewData;
	}
	else
	{
		STRING_NEW((STRING_TYPE **)&mpData);
	}

	return *this;
}

// -----------------------------------------------------------------------

STRING& STRING::Fill( xub_StrLen nCount, STRCODE cFillChar )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	if ( !nCount )
		return *this;

	// Ist nCount groesser wie der jetzige String, dann verlaengern
	if ( nCount > mpData->mnLen )
	{
		// dann neuen String mit der neuen Laenge anlegen
		STRINGDATA* pNewData = ImplAllocData( nCount );
		STRING_RELEASE((STRING_TYPE *)mpData);
		mpData = pNewData;
	}
	else
		ImplCopyData();

	STRCODE* pStr = mpData->maStr;
	do
	{
		*pStr = cFillChar;
		++pStr,
		--nCount;
	}
	while ( nCount );

	return *this;
}

// -----------------------------------------------------------------------

STRING& STRING::Expand( xub_StrLen nCount, STRCODE cExpandChar )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	// Muss der String erweitert werden
	sal_Int32 nLen = mpData->mnLen;
	if ( nCount <= nLen )
		return *this;

	// Neuen String anlegen
	STRINGDATA* pNewData = ImplAllocData( nCount );

	// Alten String kopieren
	memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) );

	// und initialisieren
	STRCODE* pStr = pNewData->maStr;
	pStr += nLen;
	for (sal_Int32 i = nCount - nLen; i > 0; --i) {
		*pStr++ = cExpandChar;
	}

	// Alte Daten loeschen und Neue zuweisen
	STRING_RELEASE((STRING_TYPE *)mpData);
	mpData = pNewData;

	return *this;
}

// -----------------------------------------------------------------------

STRING& STRING::EraseLeadingChars( STRCODE c )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	if ( mpData->maStr[0] != c )
		return *this;

	xub_StrLen nStart = 0;
	while ( mpData->maStr[nStart] == c )
		++nStart;

	return Erase( 0, nStart );
}

// -----------------------------------------------------------------------

STRING& STRING::EraseTrailingChars( STRCODE c )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	sal_Int32 nEnd = mpData->mnLen;
	while ( nEnd && (mpData->maStr[nEnd-1] == c) )
		nEnd--;

	if ( nEnd != mpData->mnLen )
		Erase( static_cast< xub_StrLen >(nEnd) );

	return *this;
}

// -----------------------------------------------------------------------

STRING& STRING::EraseLeadingAndTrailingChars( STRCODE c )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	xub_StrLen nStart = 0;
	while ( mpData->maStr[nStart] == c )
		++nStart;
	if ( nStart )
		Erase( 0, nStart );

	sal_Int32 nEnd = mpData->mnLen;
	while ( nEnd && (mpData->maStr[nEnd-1] == c) )
		nEnd--;
	if ( nEnd != mpData->mnLen )
		Erase( static_cast< xub_StrLen >(nEnd) );

	return *this;
}

// -----------------------------------------------------------------------

STRING& STRING::EraseAllChars( STRCODE c )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	sal_Int32 nCount = 0;
	for (sal_Int32 i = 0; i < mpData->mnLen; ++i) {
		if ( mpData->maStr[i] == c )
			++nCount;
	}

	if ( nCount )
	{
		if ( nCount == mpData->mnLen )
		{
			STRING_NEW((STRING_TYPE **)&mpData);
		}
		else
		{
			// Neuen String anlegen
			STRINGDATA* pNewData = ImplAllocData( mpData->mnLen-nCount );

			// Alten String kopieren und initialisieren
			nCount = 0;
			for( xub_StrLen j = 0; j < mpData->mnLen; ++j )
			{
				if ( mpData->maStr[j] != c )
				{
					pNewData->maStr[nCount] = mpData->maStr[j];
					++nCount;
				}
			}

			// Alte Daten loeschen und Neue zuweisen
			STRING_RELEASE((STRING_TYPE *)mpData);
			mpData = pNewData;
		}
	}

	return *this;
}

// -----------------------------------------------------------------------

STRING& STRING::Reverse()
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	if ( !mpData->mnLen )
		return *this;

	// Daten kopieren, wenn noetig
	ImplCopyData();

	// Reverse
	sal_Int32 nCount = mpData->mnLen / 2;
	for ( sal_Int32 i = 0; i < nCount; ++i )
	{
		STRCODE cTemp = mpData->maStr[i];
		mpData->maStr[i] = mpData->maStr[mpData->mnLen-i-1];
		mpData->maStr[mpData->mnLen-i-1] = cTemp;
	}

	return *this;
}

// -----------------------------------------------------------------------

STRING& STRING::ToLowerAscii()
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	sal_Int32 nIndex = 0;
	sal_Int32 nLen = mpData->mnLen;
	STRCODE*	pStr = mpData->maStr;
	while ( nIndex < nLen )
	{
		// Ist das Zeichen zwischen 'A' und 'Z' dann umwandeln
		if ( (*pStr >= 65) && (*pStr <= 90) )
		{
			// Daten kopieren, wenn noetig
			pStr = ImplCopyStringData( pStr );
			*pStr += 32;
		}

		++pStr,
		++nIndex;
	}

	return *this;
}

// -----------------------------------------------------------------------

STRING& STRING::ToUpperAscii()
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	sal_Int32 nIndex = 0;
	sal_Int32 nLen = mpData->mnLen;
	STRCODE*	pStr = mpData->maStr;
	while ( nIndex < nLen )
	{
		// Ist das Zeichen zwischen 'a' und 'z' dann umwandeln
		if ( (*pStr >= 97) && (*pStr <= 122) )
		{
			// Daten kopieren, wenn noetig
			pStr = ImplCopyStringData( pStr );
			*pStr -= 32;
		}

		++pStr,
		++nIndex;
	}

	return *this;
}

// -----------------------------------------------------------------------

STRING& STRING::ConvertLineEnd( LineEnd eLineEnd )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	// Zeilenumbrueche ermitteln und neue Laenge berechnen
	sal_Bool			bConvert	= sal_False;			// Muss konvertiert werden
	const STRCODE*	pStr		= mpData->maStr;	// damit es schneller geht
	xub_StrLen		nLineEndLen = (eLineEnd == LINEEND_CRLF) ? 2 : 1;
	xub_StrLen		nLen		= 0;				// Ziel-Laenge
	xub_StrLen		i			= 0;				// Source-Zaehler

	while ( i < mpData->mnLen )
	{
		// Bei \r oder \n gibt es neuen Zeilenumbruch
		if ( (pStr[i] == _CR) || (pStr[i] == _LF) )
		{
			nLen = nLen + nLineEndLen;

			// Wenn schon gesetzt, dann brauchen wir keine aufwendige Abfrage
			if ( !bConvert )
			{
				// Muessen wir Konvertieren
				if ( ((eLineEnd != LINEEND_LF) && (pStr[i] == _LF)) ||
					 ((eLineEnd == LINEEND_CRLF) && (pStr[i+1] != _LF)) ||
					 ((eLineEnd == LINEEND_LF) &&
					  ((pStr[i] == _CR) || (pStr[i+1] == _CR))) ||
					 ((eLineEnd == LINEEND_CR) &&
					  ((pStr[i] == _LF) || (pStr[i+1] == _LF))) )
					bConvert = sal_True;
			}

			// \r\n oder \n\r, dann Zeichen ueberspringen
			if ( ((pStr[i+1] == _CR) || (pStr[i+1] == _LF)) &&
				 (pStr[i] != pStr[i+1]) )
				++i;
		}
		else
			++nLen;
		++i;

		// Wenn String zu lang, dann konvertieren wir nicht
		if ( nLen >= STRING_MAXLEN )
			return *this;
	}

	// Zeilenumbrueche konvertieren
	if ( bConvert )
	{
		// Neuen String anlegen
		STRINGDATA* pNewData = ImplAllocData( nLen );
		xub_StrLen	j = 0;
		i = 0;
		while ( i < mpData->mnLen )
		{
			// Bei \r oder \n gibt es neuen Zeilenumbruch
			if ( (pStr[i] == _CR) || (pStr[i] == _LF) )
			{
				if ( eLineEnd == LINEEND_CRLF )
				{
					pNewData->maStr[j]	 = _CR;
					pNewData->maStr[j+1] = _LF;
					j += 2;
				}
				else
				{
					if ( eLineEnd == LINEEND_CR )
						pNewData->maStr[j] = _CR;
					else
						pNewData->maStr[j] = _LF;
					++j;
				}

				if ( ((pStr[i+1] == _CR) || (pStr[i+1] == _LF)) &&
					 (pStr[i] != pStr[i+1]) )
					++i;
			}
			else
			{
				pNewData->maStr[j] = mpData->maStr[i];
				++j;
			}

			++i;
		}

		// Alte Daten loeschen und Neue zuweisen
		STRING_RELEASE((STRING_TYPE *)mpData);
		mpData = pNewData;
	}

	return *this;
}

// -----------------------------------------------------------------------

StringCompare STRING::CompareTo( const STRING& rStr, xub_StrLen nLen ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );

	// Auf Gleichheit der Pointer testen
	if ( mpData == rStr.mpData )
		return COMPARE_EQUAL;

	// Maximale Laenge ermitteln
	if ( mpData->mnLen < nLen )
		nLen = static_cast< xub_StrLen >(mpData->mnLen+1);
	if ( rStr.mpData->mnLen < nLen )
		nLen = static_cast< xub_StrLen >(rStr.mpData->mnLen+1);

	// String vergleichen
	sal_Int32 nCompare = ImplStringCompareWithoutZero( mpData->maStr, rStr.mpData->maStr, nLen );

	// Rueckgabewert anpassen
	if ( nCompare == 0 )
		return COMPARE_EQUAL;
	else if ( nCompare < 0 )
		return COMPARE_LESS;
	else
		return COMPARE_GREATER;
}

// -----------------------------------------------------------------------

StringCompare STRING::CompareTo( const STRCODE* pCharStr, xub_StrLen nLen ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	// String vergleichen
	sal_Int32 nCompare = ImplStringCompare( mpData->maStr, pCharStr, nLen );

	// Rueckgabewert anpassen
	if ( nCompare == 0 )
		return COMPARE_EQUAL;
	else if ( nCompare < 0 )
		return COMPARE_LESS;
	else
		return COMPARE_GREATER;
}

// -----------------------------------------------------------------------

StringCompare STRING::CompareIgnoreCaseToAscii( const STRING& rStr,
												xub_StrLen nLen ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );

	// Auf Gleichheit der Pointer testen
	if ( mpData == rStr.mpData )
		return COMPARE_EQUAL;

	// Maximale Laenge ermitteln
	if ( mpData->mnLen < nLen )
		nLen = static_cast< xub_StrLen >(mpData->mnLen+1);
	if ( rStr.mpData->mnLen < nLen )
		nLen = static_cast< xub_StrLen >(rStr.mpData->mnLen+1);

	// String vergleichen
	sal_Int32 nCompare = ImplStringICompareWithoutZero( mpData->maStr, rStr.mpData->maStr, nLen );

	// Rueckgabewert anpassen
	if ( nCompare == 0 )
		return COMPARE_EQUAL;
	else if ( nCompare < 0 )
		return COMPARE_LESS;
	else
		return COMPARE_GREATER;
}

// -----------------------------------------------------------------------

StringCompare STRING::CompareIgnoreCaseToAscii( const STRCODE* pCharStr,
												xub_StrLen nLen ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	// String vergleichen
	sal_Int32 nCompare = ImplStringICompare( mpData->maStr, pCharStr, nLen );

	// Rueckgabewert anpassen
	if ( nCompare == 0 )
		return COMPARE_EQUAL;
	else if ( nCompare < 0 )
		return COMPARE_LESS;
	else
		return COMPARE_GREATER;
}

// -----------------------------------------------------------------------

sal_Bool STRING::Equals( const STRING& rStr ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );

	// Sind die Daten gleich
	if ( mpData == rStr.mpData )
		return sal_True;

	// Gleiche Laenge
	if ( mpData->mnLen != rStr.mpData->mnLen )
		return sal_False;

	// String vergleichen
	return (ImplStringCompareWithoutZero( mpData->maStr, rStr.mpData->maStr, mpData->mnLen ) == 0);
}

// -----------------------------------------------------------------------

sal_Bool STRING::Equals( const STRCODE* pCharStr ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	return (ImplStringCompare( mpData->maStr, pCharStr ) == 0);
}

// -----------------------------------------------------------------------

sal_Bool STRING::EqualsIgnoreCaseAscii( const STRING& rStr ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );

	// Sind die Daten gleich
	if ( mpData == rStr.mpData )
		return sal_True;

	// Gleiche Laenge
	if ( mpData->mnLen != rStr.mpData->mnLen )
		return sal_False;

	// String vergleichen
	return (ImplStringICompareWithoutZero( mpData->maStr, rStr.mpData->maStr, mpData->mnLen ) == 0);
}

// -----------------------------------------------------------------------

sal_Bool STRING::EqualsIgnoreCaseAscii( const STRCODE* pCharStr ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	return (ImplStringICompare( mpData->maStr, pCharStr ) == 0);
}

// -----------------------------------------------------------------------

sal_Bool STRING::Equals( const STRING& rStr, xub_StrLen nIndex, xub_StrLen nLen ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );

	// Are there enough codes for comparing?
	if ( nIndex > mpData->mnLen )
		return (rStr.mpData->mnLen == 0);
	sal_Int32 nMaxLen = mpData->mnLen-nIndex;
	if ( nMaxLen < nLen )
	{
		if ( rStr.mpData->mnLen != nMaxLen )
			return sal_False;
		nLen = static_cast< xub_StrLen >(nMaxLen);
	}

	// String vergleichen
	return (ImplStringCompareWithoutZero( mpData->maStr+nIndex, rStr.mpData->maStr, nLen ) == 0);
}

// -----------------------------------------------------------------------

sal_Bool STRING::Equals( const STRCODE* pCharStr, xub_StrLen nIndex, xub_StrLen nLen ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	// Are there enough codes for comparing?
	if ( nIndex > mpData->mnLen )
		return (*pCharStr == 0);

	return (ImplStringCompare( mpData->maStr+nIndex, pCharStr, nLen ) == 0);
}

// -----------------------------------------------------------------------

sal_Bool STRING::EqualsIgnoreCaseAscii( const STRING& rStr, xub_StrLen nIndex, xub_StrLen nLen ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );

	// Are there enough codes for comparing?
	if ( nIndex > mpData->mnLen )
		return (rStr.mpData->mnLen == 0);
	sal_Int32 nMaxLen = mpData->mnLen-nIndex;
	if ( nMaxLen < nLen )
	{
		if ( rStr.mpData->mnLen != nMaxLen )
			return sal_False;
		nLen = static_cast< xub_StrLen >(nMaxLen);
	}

	// String vergleichen
	return (ImplStringICompareWithoutZero( mpData->maStr+nIndex, rStr.mpData->maStr, nLen ) == 0);
}

// -----------------------------------------------------------------------

sal_Bool STRING::EqualsIgnoreCaseAscii( const STRCODE* pCharStr, xub_StrLen nIndex, xub_StrLen nLen ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	// Are there enough codes for comparing?
	if ( nIndex > mpData->mnLen )
		return (*pCharStr == 0);

	return (ImplStringICompare( mpData->maStr+nIndex, pCharStr, nLen ) == 0);
}

// -----------------------------------------------------------------------

xub_StrLen STRING::Match( const STRING& rStr ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );

	// Ist dieser String leer
	if ( !mpData->mnLen )
		return STRING_MATCH;

	// Suche bis Stringende nach dem ersten nicht uebereinstimmenden Zeichen
	const STRCODE*	pStr1 = mpData->maStr;
	const STRCODE*	pStr2 = rStr.mpData->maStr;
	xub_StrLen		i = 0;
	while ( i < mpData->mnLen )
	{
		// Stimmt das Zeichen nicht ueberein, dann abbrechen
		if ( *pStr1 != *pStr2 )
			return i;
		++pStr1,
		++pStr2,
		++i;
	}

	return STRING_MATCH;
}

// -----------------------------------------------------------------------

xub_StrLen STRING::Match( const STRCODE* pCharStr ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	// Ist dieser String leer
	if ( !mpData->mnLen )
		return STRING_MATCH;

	// Suche bis Stringende nach dem ersten nicht uebereinstimmenden Zeichen
	const STRCODE*	pStr = mpData->maStr;
	xub_StrLen		i = 0;
	while ( i < mpData->mnLen )
	{
		// Stimmt das Zeichen nicht ueberein, dann abbrechen
		if ( *pStr != *pCharStr )
			return i;
		++pStr,
		++pCharStr,
		++i;
	}

	return STRING_MATCH;
}

// -----------------------------------------------------------------------

xub_StrLen STRING::Search( STRCODE c, xub_StrLen nIndex ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	sal_Int32		nLen = mpData->mnLen;
	const STRCODE*	pStr = mpData->maStr;
	pStr += nIndex;
	while ( nIndex < nLen )
	{
		if ( *pStr == c )
			return nIndex;
		++pStr,
		++nIndex;
	}

	return STRING_NOTFOUND;
}

// -----------------------------------------------------------------------

xub_StrLen STRING::Search( const STRING& rStr, xub_StrLen nIndex ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );

	sal_Int32 nLen = mpData->mnLen;
	sal_Int32 nStrLen = rStr.mpData->mnLen;

	// Falls die Laenge des uebergebenen Strings 0 ist oder der Index
	// hinter dem String liegt, dann wurde der String nicht gefunden
	if ( !nStrLen || (nIndex >= nLen) )
		return STRING_NOTFOUND;

	const STRCODE* pStr1 = mpData->maStr;
	pStr1 += nIndex;

	if ( nStrLen == 1 )
	{
		STRCODE cSearch = rStr.mpData->maStr[0];
		while ( nIndex < nLen )
		{
			if ( *pStr1 == cSearch )
				return nIndex;
			++pStr1,
			++nIndex;
		}
	}
	else
	{
		const STRCODE* pStr2 = rStr.mpData->maStr;

		// Nur innerhalb des Strings suchen
		while ( nLen - nIndex >= nStrLen )
		{
			// Stimmt der String ueberein
			if ( ImplStringCompareWithoutZero( pStr1, pStr2, nStrLen ) == 0 )
				return nIndex;
			++pStr1,
			++nIndex;
		}
	}

	return STRING_NOTFOUND;
}

// -----------------------------------------------------------------------

xub_StrLen STRING::Search( const STRCODE* pCharStr, xub_StrLen nIndex ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	sal_Int32 nLen = mpData->mnLen;
	xub_StrLen nStrLen	= ImplStringLen( pCharStr );

	// Falls die Laenge des uebergebenen Strings 0 ist oder der Index
	// hinter dem String liegt, dann wurde der String nicht gefunden
	if ( !nStrLen || (nIndex >= nLen) )
		return STRING_NOTFOUND;

	const STRCODE* pStr = mpData->maStr;
	pStr += nIndex;

	if ( nStrLen == 1 )
	{
		STRCODE cSearch = *pCharStr;
		while ( nIndex < nLen )
		{
			if ( *pStr == cSearch )
				return nIndex;
			++pStr,
			++nIndex;
		}
	}
	else
	{
		// Nur innerhalb des Strings suchen
		while ( nLen - nIndex >= nStrLen )
		{
			// Stimmt der String ueberein
			if ( ImplStringCompareWithoutZero( pStr, pCharStr, nStrLen ) == 0 )
				return nIndex;
			++pStr,
			++nIndex;
		}
	}

	return STRING_NOTFOUND;
}

// -----------------------------------------------------------------------

xub_StrLen STRING::SearchBackward( STRCODE c, xub_StrLen nIndex ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	if ( nIndex > mpData->mnLen )
		nIndex = (xub_StrLen)mpData->mnLen;

	const STRCODE* pStr = mpData->maStr;
	pStr += nIndex;

	while ( nIndex )
	{
		nIndex--;
		pStr--;
		if ( *pStr == c )
			return nIndex;
	}

	return STRING_NOTFOUND;
}

// -----------------------------------------------------------------------

xub_StrLen STRING::SearchChar( const STRCODE* pChars, xub_StrLen nIndex ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	sal_Int32		nLen = mpData->mnLen;
	const STRCODE*	pStr = mpData->maStr;
	pStr += nIndex;
	while ( nIndex < nLen )
	{
		STRCODE 		c = *pStr;
		const STRCODE*	pCompStr = pChars;
		while ( *pCompStr )
		{
			if ( *pCompStr == c )
				return nIndex;
			++pCompStr;
		}
		++pStr,
		++nIndex;
	}

	return STRING_NOTFOUND;
}

// -----------------------------------------------------------------------

xub_StrLen STRING::SearchCharBackward( const STRCODE* pChars, xub_StrLen nIndex ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	if ( nIndex > mpData->mnLen )
		nIndex = (xub_StrLen)mpData->mnLen;

	const STRCODE* pStr = mpData->maStr;
	pStr += nIndex;

	while ( nIndex )
	{
		nIndex--;
		pStr--;

		STRCODE 		c =*pStr;
		const STRCODE*	pCompStr = pChars;
		while ( *pCompStr )
		{
			if ( *pCompStr == c )
				return nIndex;
			++pCompStr;
		}
	}

	return STRING_NOTFOUND;
}

// -----------------------------------------------------------------------

xub_StrLen STRING::SearchAndReplace( STRCODE c, STRCODE cRep, xub_StrLen nIndex )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	sal_Int32		nLen = mpData->mnLen;
	const STRCODE*	pStr = mpData->maStr;
	pStr += nIndex;
	while ( nIndex < nLen )
	{
		if ( *pStr == c )
		{
			ImplCopyData();
			mpData->maStr[nIndex] = cRep;
			return nIndex;
		}
		++pStr,
		++nIndex;
	}

	return STRING_NOTFOUND;
}

// -----------------------------------------------------------------------

xub_StrLen STRING::SearchAndReplace( const STRING& rStr, const STRING& rRepStr,
									 xub_StrLen nIndex )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rRepStr, STRING, DBGCHECKSTRING );

	xub_StrLen nSPos = Search( rStr, nIndex );
	if ( nSPos != STRING_NOTFOUND )
		Replace( nSPos, rStr.Len(), rRepStr );

	return nSPos;
}

// -----------------------------------------------------------------------

xub_StrLen STRING::SearchAndReplace( const STRCODE* pCharStr, const STRING& rRepStr,
									 xub_StrLen nIndex )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rRepStr, STRING, DBGCHECKSTRING );

	xub_StrLen nSPos = Search( pCharStr, nIndex );
	if ( nSPos != STRING_NOTFOUND )
		Replace( nSPos, ImplStringLen( pCharStr ), rRepStr );

	return nSPos;
}

// -----------------------------------------------------------------------

void STRING::SearchAndReplaceAll( STRCODE c, STRCODE cRep )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	sal_Int32		nLen	= mpData->mnLen;
	const STRCODE*	pStr	= mpData->maStr;
	sal_Int32		nIndex	= 0;
	while ( nIndex < nLen )
	{
		if ( *pStr == c )
		{
			ImplCopyData();
			mpData->maStr[nIndex] = cRep;
		}
		++pStr,
		++nIndex;
	}
}

// -----------------------------------------------------------------------

void STRING::SearchAndReplaceAll( const STRCODE* pCharStr, const STRING& rRepStr )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rRepStr, STRING, DBGCHECKSTRING );

	xub_StrLen nCharLen = ImplStringLen( pCharStr );
	xub_StrLen nSPos = Search( pCharStr, 0 );
	while ( nSPos != STRING_NOTFOUND )
	{
		Replace( nSPos, nCharLen, rRepStr );
		nSPos = nSPos + rRepStr.Len();
		nSPos = Search( pCharStr, nSPos );
	}
}

// -----------------------------------------------------------------------

void STRING::SearchAndReplaceAll( const STRING& rStr, const STRING& rRepStr )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rRepStr, STRING, DBGCHECKSTRING );

	xub_StrLen nSPos = Search( rStr, 0 );
	while ( nSPos != STRING_NOTFOUND )
	{
		Replace( nSPos, rStr.Len(), rRepStr );
		nSPos = nSPos + rRepStr.Len();
		nSPos = Search( rStr, nSPos );
	}
}

// -----------------------------------------------------------------------

xub_StrLen STRING::GetTokenCount( STRCODE cTok ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	// Leerer String: TokenCount per Definition 0
	if ( !mpData->mnLen )
		return 0;

	xub_StrLen		nTokCount		= 1;
	sal_Int32		nLen			= mpData->mnLen;
	const STRCODE*	pStr			= mpData->maStr;
	sal_Int32		nIndex			= 0;
	while ( nIndex < nLen )
	{
		// Stimmt das Tokenzeichen ueberein, dann erhoehe TokCount
		if ( *pStr == cTok )
			++nTokCount;
		++pStr,
		++nIndex;
	}

	return nTokCount;
}

// -----------------------------------------------------------------------

void STRING::SetToken( xub_StrLen nToken, STRCODE cTok, const STRING& rStr,
					   xub_StrLen nIndex )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rStr, STRING, DBGCHECKSTRING );

	const STRCODE*	pStr			= mpData->maStr;
	xub_StrLen		nLen			= (xub_StrLen)mpData->mnLen;
	xub_StrLen		nTok			= 0;
	xub_StrLen		nFirstChar		= nIndex;
	xub_StrLen		i				= nFirstChar;

	// Bestimme die Token-Position und Laenge
	pStr += i;
	while ( i < nLen )
	{
		// Stimmt das Tokenzeichen ueberein, dann erhoehe TokCount
		if ( *pStr == cTok )
		{
			++nTok;

			if ( nTok == nToken )
				nFirstChar = i+1;
			else
			{
				if ( nTok > nToken )
					break;
			}
		}

		++pStr,
		++i;
	}

	if ( nTok >= nToken )
		Replace( nFirstChar, i-nFirstChar, rStr );
}

// -----------------------------------------------------------------------

STRING STRING::GetToken( xub_StrLen nToken, STRCODE cTok, xub_StrLen& rIndex ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	const STRCODE*	pStr			= mpData->maStr;
	xub_StrLen		nLen			= (xub_StrLen)mpData->mnLen;
	xub_StrLen		nTok			= 0;
	xub_StrLen		nFirstChar		= rIndex;
	xub_StrLen		i				= nFirstChar;

	// Bestimme die Token-Position und Laenge
	pStr += i;
	while ( i < nLen )
	{
		// Stimmt das Tokenzeichen ueberein, dann erhoehe TokCount
		if ( *pStr == cTok )
		{
			++nTok;

			if ( nTok == nToken )
				nFirstChar = i+1;
			else
			{
				if ( nTok > nToken )
					break;
			}
		}

		++pStr,
		++i;
	}

	if ( nTok >= nToken )
	{
		if ( i < nLen )
			rIndex = i+1;
		else
			rIndex = STRING_NOTFOUND;
		return Copy( nFirstChar, i-nFirstChar );
	}
	else
	{
		rIndex = STRING_NOTFOUND;
		return STRING();
	}
}

// -----------------------------------------------------------------------

xub_StrLen STRING::GetQuotedTokenCount( const STRING& rQuotedPairs, STRCODE cTok ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rQuotedPairs, STRING, DBGCHECKSTRING );
	DBG_ASSERT( !(rQuotedPairs.Len()%2), "String::GetQuotedTokenCount() - QuotedString%2 != 0" );
	DBG_ASSERT( rQuotedPairs.Search(cTok) == STRING_NOTFOUND, "String::GetQuotedTokenCount() - cTok in QuotedString" );

	// Leerer String: TokenCount per Definition 0
	if ( !mpData->mnLen )
		return 0;

	xub_StrLen		nTokCount		= 1;
	sal_Int32		nLen			= mpData->mnLen;
	xub_StrLen		nQuotedLen		= rQuotedPairs.Len();
	STRCODE 		cQuotedEndChar	= 0;
	const STRCODE*	pQuotedStr		= rQuotedPairs.mpData->maStr;
	const STRCODE*	pStr			= mpData->maStr;
	sal_Int32		nIndex			= 0;
	while ( nIndex < nLen )
	{
		STRCODE c = *pStr;
		if ( cQuotedEndChar )
		{
			// Ende des Quotes erreicht ?
			if ( c == cQuotedEndChar )
				cQuotedEndChar = 0;
		}
		else
		{
			// Ist das Zeichen ein Quote-Anfang-Zeichen ?
			xub_StrLen nQuoteIndex = 0;
			while ( nQuoteIndex < nQuotedLen )
			{
				if ( pQuotedStr[nQuoteIndex] == c )
				{
					cQuotedEndChar = pQuotedStr[nQuoteIndex+1];
					break;
				}
				else
					nQuoteIndex += 2;
			}

			// Stimmt das Tokenzeichen ueberein, dann erhoehe TokCount
			if ( c == cTok )
				++nTokCount;
		}

		++pStr,
		++nIndex;
	}

	return nTokCount;
}

// -----------------------------------------------------------------------

STRING STRING::GetQuotedToken( xub_StrLen nToken, const STRING& rQuotedPairs,
							   STRCODE cTok, xub_StrLen& rIndex ) const
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );
	DBG_CHKOBJ( &rQuotedPairs, STRING, DBGCHECKSTRING );
	DBG_ASSERT( !(rQuotedPairs.Len()%2), "String::GetQuotedToken() - QuotedString%2 != 0" );
	DBG_ASSERT( rQuotedPairs.Search(cTok) == STRING_NOTFOUND, "String::GetQuotedToken() - cTok in QuotedString" );

	const STRCODE*	pStr			= mpData->maStr;
	const STRCODE*	pQuotedStr		= rQuotedPairs.mpData->maStr;
	STRCODE 		cQuotedEndChar	= 0;
	xub_StrLen		nQuotedLen		= rQuotedPairs.Len();
	xub_StrLen		nLen			= (xub_StrLen)mpData->mnLen;
	xub_StrLen		nTok			= 0;
	xub_StrLen		nFirstChar		= rIndex;
	xub_StrLen		i				= nFirstChar;

	// Bestimme die Token-Position und Laenge
	pStr += i;
	while ( i < nLen )
	{
		STRCODE c = *pStr;
		if ( cQuotedEndChar )
		{
			// Ende des Quotes erreicht ?
			if ( c == cQuotedEndChar )
				cQuotedEndChar = 0;
		}
		else
		{
			// Ist das Zeichen ein Quote-Anfang-Zeichen ?
			xub_StrLen nQuoteIndex = 0;
			while ( nQuoteIndex < nQuotedLen )
			{
				if ( pQuotedStr[nQuoteIndex] == c )
				{
					cQuotedEndChar = pQuotedStr[nQuoteIndex+1];
					break;
				}
				else
					nQuoteIndex += 2;
			}

			// Stimmt das Tokenzeichen ueberein, dann erhoehe TokCount
			if ( c == cTok )
			{
				++nTok;

				if ( nTok == nToken )
					nFirstChar = i+1;
				else
				{
					if ( nTok > nToken )
						break;
				}
			}
		}

		++pStr,
		++i;
	}

	if ( nTok >= nToken )
	{
		if ( i < nLen )
			rIndex = i+1;
		else
			rIndex = STRING_NOTFOUND;
		return Copy( nFirstChar, i-nFirstChar );
	}
	else
	{
		rIndex = STRING_NOTFOUND;
		return STRING();
	}
}

// -----------------------------------------------------------------------

STRCODE* STRING::GetBufferAccess()
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	// Daten kopieren, wenn noetig
	if ( mpData->mnLen )
		ImplCopyData();

	// Pointer auf den String zurueckgeben
	return mpData->maStr;
}

// -----------------------------------------------------------------------

void STRING::ReleaseBufferAccess( xub_StrLen nLen )
{
	// Hier ohne Funktionstest, da String nicht konsistent
	DBG_CHKTHIS( STRING, NULL );
	DBG_ASSERT( mpData->mnRefCount == 1, "String::ReleaseCharStr() called for String with RefCount" );

	if ( nLen > mpData->mnLen )
		nLen = ImplStringLen( mpData->maStr );
    OSL_ASSERT(nLen <= mpData->mnLen);
	if ( !nLen )
	{
		STRING_NEW((STRING_TYPE **)&mpData);
	}
	// Bei mehr als 8 Zeichen unterschied, kuerzen wir den Buffer
	else if ( mpData->mnLen - nLen > 8 )
	{
		STRINGDATA* pNewData = ImplAllocData( nLen );
		memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) );
		STRING_RELEASE((STRING_TYPE *)mpData);
		mpData = pNewData;
	}
	else
		mpData->mnLen = nLen;
}

// -----------------------------------------------------------------------

STRCODE* STRING::AllocBuffer( xub_StrLen nLen )
{
	DBG_CHKTHIS( STRING, DBGCHECKSTRING );

	STRING_RELEASE((STRING_TYPE *)mpData);
	if ( nLen )
		mpData = ImplAllocData( nLen );
	else
	{
		mpData = NULL;
		STRING_NEW((STRING_TYPE **)&mpData);
	}

	return mpData->maStr;
}
