/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * 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 . */ #include #include "boost/static_assert.hpp" #include #include #include #include #include #include #include DBG_NAME( UniString ) #define STRCODE sal_Unicode #define STRCODEU sal_Unicode #define STRING UniString #define STRINGDATA UniStringData #define STRING_TYPE rtl_uString #define STRING_ACQUIRE rtl_uString_acquire #define STRING_RELEASE rtl_uString_release #define STRING_NEW rtl_uString_new #if defined DBG_UTIL #define DBGCHECKSTRING DbgCheckUniString #endif #include #include UniString::UniString(char c): mpData(ImplAllocData(1)) { mpData->maStr[0] = c; } sal_Int32 UniString::ToInt32() const { DBG_CHKTHIS( UniString, DbgCheckUniString ); return rtl_ustr_toInt32( mpData->maStr, 10 ); } STRING& STRING::Insert( STRCODE c, xub_StrLen nIndex ) { DBG_CHKTHIS( STRING, DBGCHECKSTRING ); // Don't insert 0 char or string size is maximum if ( !c || (mpData->mnLen == STRING_MAXLEN) ) return *this; // Adjust string index if ( nIndex > mpData->mnLen ) nIndex = static_cast< xub_StrLen >(mpData->mnLen); // allocate string of new size STRINGDATA* pNewData = ImplAllocData( mpData->mnLen+1 ); // copy string 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 ) ); // free old data 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 ); if ( mpData == rStr.mpData ) return COMPARE_EQUAL; // determine maximal length 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); sal_Int32 nCompare = ImplStringCompareWithoutZero( mpData->maStr, rStr.mpData->maStr, nLen ); 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 ); if ( mpData == rStr.mpData ) return sal_True; if ( mpData->mnLen != rStr.mpData->mnLen ) return sal_False; return (ImplStringCompareWithoutZero( mpData->maStr, rStr.mpData->maStr, mpData->mnLen ) == 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); } return (ImplStringCompareWithoutZero( mpData->maStr+nIndex, rStr.mpData->maStr, nLen ) == 0); } STRING& STRING::Append( STRCODE c ) { DBG_CHKTHIS( STRING, DBGCHECKSTRING ); // don't append null characters and keep string length < maxlen sal_Int32 nLen = mpData->mnLen; if ( c && (nLen < STRING_MAXLEN) ) { // allocate string of new size STRINGDATA* pNewData = ImplAllocData( nLen+1 ); // copy string memcpy( pNewData->maStr, mpData->maStr, nLen*sizeof( STRCODE ) ); pNewData->maStr[nLen] = c; // free old string STRING_RELEASE((STRING_TYPE *)mpData); mpData = pNewData; } return *this; } STRING& STRING::Assign( STRCODE c ) { DBG_CHKTHIS( STRING, DBGCHECKSTRING ); DBG_ASSERT( c, "String::Assign() - c is 0" ); // initialize maintenance data STRING_RELEASE((STRING_TYPE *)mpData); mpData = ImplAllocData( 1 ); mpData->maStr[0] = c; return *this; } xub_StrLen ImplStringLen( const sal_Char* pStr ) { const sal_Char* pTempStr = pStr; while( *pTempStr ) ++pTempStr; return (xub_StrLen)(pTempStr-pStr); } xub_StrLen ImplStringLen( const sal_Unicode* pStr ) { const sal_Unicode* pTempStr = pStr; while( *pTempStr ) ++pTempStr; return (xub_StrLen)(pTempStr-pStr); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */