/**************************************************************
 *
 * 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) )
		{
			if( nLen <= STRING_MAXLEN - nLineEndLen )
				nLen = nLen + nLineEndLen;
			else
				nLen = STRING_MAXLEN;

			// 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
		{
			if( nLen < STRING_MAXLEN )
			    ++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;
}
