summaryrefslogtreecommitdiffstats
path: root/sal/rtl/strtmpl.cxx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--sal/rtl/strtmpl.cxx1911
1 files changed, 1911 insertions, 0 deletions
diff --git a/sal/rtl/strtmpl.cxx b/sal/rtl/strtmpl.cxx
new file mode 100644
index 000000000..8ff170767
--- /dev/null
+++ b/sal/rtl/strtmpl.cxx
@@ -0,0 +1,1911 @@
+/* -*- 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 .
+ */
+
+/* ======================================================================= */
+/* Internal C-String help functions which could be used without the */
+/* String-Class */
+/* ======================================================================= */
+
+#include <algorithm>
+#include <cassert>
+#include <limits>
+
+#include <cstring>
+#include <wchar.h>
+#include <sal/log.hxx>
+#include <rtl/character.hxx>
+
+/*
+inline void rtl_str_ImplCopy( IMPL_RTL_STRCODE* pDest,
+ const IMPL_RTL_STRCODE* pSrc,
+ sal_Int32 nCount )
+{
+ while ( nCount > 0 )
+ {
+ *pDest = *pSrc;
+ pDest++;
+ pSrc++;
+ nCount--;
+ }
+}
+*/
+
+static void rtl_str_ImplCopy( IMPL_RTL_STRCODE* _pDest,
+ const IMPL_RTL_STRCODE* _pSrc,
+ sal_Int32 _nCount )
+{
+ // take advantage of builtin optimisations
+ memcpy( _pDest, _pSrc, _nCount * sizeof(IMPL_RTL_STRCODE));
+}
+
+/* ======================================================================= */
+/* C-String functions which could be used without the String-Class */
+/* ======================================================================= */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( getLength )( const IMPL_RTL_STRCODE* pStr )
+ SAL_THROW_EXTERN_C()
+{
+ assert(pStr);
+#if !IMPL_RTL_IS_USTRING
+ // take advantage of builtin optimisations
+ return strlen( pStr);
+#else
+ if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
+ {
+ // take advantage of builtin optimisations
+ return wcslen(reinterpret_cast<wchar_t const *>(pStr));
+ }
+ else
+ {
+ const IMPL_RTL_STRCODE* pTempStr = pStr;
+ while( *pTempStr )
+ pTempStr++;
+ return pTempStr-pStr;
+ }
+#endif
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compare )( const IMPL_RTL_STRCODE* pStr1,
+ const IMPL_RTL_STRCODE* pStr2 )
+ SAL_THROW_EXTERN_C()
+{
+ assert(pStr1);
+ assert(pStr2);
+#if !IMPL_RTL_IS_USTRING
+ // take advantage of builtin optimisations
+ return strcmp( pStr1, pStr2);
+#else
+ if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
+ {
+ // take advantage of builtin optimisations
+ return wcscmp(reinterpret_cast<wchar_t const *>(pStr1), reinterpret_cast<wchar_t const *>(pStr2));
+ }
+ else
+ {
+ sal_Int32 nRet;
+ for (;;)
+ {
+ nRet = static_cast<sal_Int32>(IMPL_RTL_USTRCODE(*pStr1)) -
+ static_cast<sal_Int32>(IMPL_RTL_USTRCODE(*pStr2));
+ if (!(nRet == 0 && *pStr2 ))
+ break;
+ pStr1++;
+ pStr2++;
+ }
+
+ return nRet;
+ }
+#endif
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compare_WithLength )( const IMPL_RTL_STRCODE* pStr1,
+ sal_Int32 nStr1Len,
+ const IMPL_RTL_STRCODE* pStr2,
+ sal_Int32 nStr2Len )
+ SAL_THROW_EXTERN_C()
+{
+ assert(nStr1Len >= 0);
+ assert(nStr2Len >= 0);
+#if !IMPL_RTL_IS_USTRING
+ // take advantage of builtin optimisations
+ sal_Int32 nMin = std::min(nStr1Len, nStr2Len);
+ sal_Int32 nRet = memcmp(pStr1, pStr2, nMin);
+ return nRet == 0 ? nStr1Len - nStr2Len : nRet;
+#else
+ if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
+ {
+ // take advantage of builtin optimisations
+ sal_Int32 nMin = std::min(nStr1Len, nStr2Len);
+ sal_Int32 nRet = wmemcmp(reinterpret_cast<wchar_t const *>(pStr1),
+ reinterpret_cast<wchar_t const *>(pStr2), nMin);
+ return nRet == 0 ? nStr1Len - nStr2Len : nRet;
+ }
+ else
+ {
+ sal_Int32 nRet = nStr1Len - nStr2Len;
+ int nCount = (nRet <= 0) ? nStr1Len : nStr2Len;
+
+ --pStr1;
+ --pStr2;
+ while( (--nCount >= 0) && (*++pStr1 == *++pStr2) ) ;
+
+ if( nCount >= 0 )
+ nRet = static_cast<sal_Int32>(IMPL_RTL_USTRCODE( *pStr1 ))
+ - static_cast<sal_Int32>(IMPL_RTL_USTRCODE( *pStr2 ));
+
+ return nRet;
+ }
+#endif
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( shortenedCompare_WithLength )( const IMPL_RTL_STRCODE* pStr1,
+ sal_Int32 nStr1Len,
+ const IMPL_RTL_STRCODE* pStr2,
+ sal_Int32 nStr2Len,
+ sal_Int32 nShortenedLength )
+ SAL_THROW_EXTERN_C()
+{
+ assert(nStr1Len >= 0);
+ assert(nStr2Len >= 0);
+ assert(nShortenedLength >= 0);
+#if !IMPL_RTL_IS_USTRING
+ // take advantage of builtin optimisations
+ sal_Int32 nMin = std::min(std::min(nStr1Len, nStr2Len), nShortenedLength);
+ sal_Int32 nRet = memcmp(pStr1, pStr2, nMin);
+ if (nRet == 0 && nShortenedLength > std::min(nStr1Len, nStr2Len))
+ return nStr1Len - nStr2Len;
+ return nRet;
+#else
+ if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
+ {
+ // take advantage of builtin optimisations
+ sal_Int32 nMin = std::min(std::min(nStr1Len, nStr2Len), nShortenedLength);
+ sal_Int32 nRet = wmemcmp(reinterpret_cast<wchar_t const *>(pStr1), reinterpret_cast<wchar_t const *>(pStr2), nMin);
+ if (nRet == 0 && nShortenedLength > std::min(nStr1Len, nStr2Len))
+ return nStr1Len - nStr2Len;
+ return nRet;
+ }
+ else
+ {
+ const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len;
+ const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len;
+ sal_Int32 nRet;
+ while ( (nShortenedLength > 0) &&
+ (pStr1 < pStr1End) && (pStr2 < pStr2End) )
+ {
+ nRet = static_cast<sal_Int32>(IMPL_RTL_USTRCODE( *pStr1 ))-
+ static_cast<sal_Int32>(IMPL_RTL_USTRCODE( *pStr2 ));
+ if ( nRet )
+ return nRet;
+
+ nShortenedLength--;
+ pStr1++;
+ pStr2++;
+ }
+
+ if ( nShortenedLength <= 0 )
+ return 0;
+ return nStr1Len - nStr2Len;
+ }
+#endif
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( reverseCompare_WithLength )( const IMPL_RTL_STRCODE* pStr1,
+ sal_Int32 nStr1Len,
+ const IMPL_RTL_STRCODE* pStr2,
+ sal_Int32 nStr2Len )
+ SAL_THROW_EXTERN_C()
+{
+ assert(nStr1Len >= 0);
+ assert(nStr2Len >= 0);
+ const IMPL_RTL_STRCODE* pStr1Run = pStr1+nStr1Len;
+ const IMPL_RTL_STRCODE* pStr2Run = pStr2+nStr2Len;
+ sal_Int32 nRet;
+ while ( (pStr1 < pStr1Run) && (pStr2 < pStr2Run) )
+ {
+ pStr1Run--;
+ pStr2Run--;
+ nRet = static_cast<sal_Int32>(IMPL_RTL_USTRCODE( *pStr1Run ))-
+ static_cast<sal_Int32>(IMPL_RTL_USTRCODE( *pStr2Run ));
+ if ( nRet )
+ return nRet;
+ }
+
+ return nStr1Len - nStr2Len;
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compareIgnoreAsciiCase )( const IMPL_RTL_STRCODE* pStr1,
+ const IMPL_RTL_STRCODE* pStr2 )
+ SAL_THROW_EXTERN_C()
+{
+ assert(pStr1);
+ assert(pStr2);
+ sal_uInt32 c1;
+ do
+ {
+ c1 = IMPL_RTL_USTRCODE(*pStr1);
+ sal_Int32 nRet = rtl::compareIgnoreAsciiCase(
+ c1, IMPL_RTL_USTRCODE(*pStr2));
+ if ( nRet != 0 )
+ return nRet;
+
+ pStr1++;
+ pStr2++;
+ }
+ while (c1);
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compareIgnoreAsciiCase_WithLength )( const IMPL_RTL_STRCODE* pStr1,
+ sal_Int32 nStr1Len,
+ const IMPL_RTL_STRCODE* pStr2,
+ sal_Int32 nStr2Len )
+ SAL_THROW_EXTERN_C()
+{
+ assert(nStr1Len >= 0);
+ assert(nStr2Len >= 0);
+ const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len;
+ const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len;
+ while ( (pStr1 < pStr1End) && (pStr2 < pStr2End) )
+ {
+ sal_Int32 nRet = rtl::compareIgnoreAsciiCase(
+ IMPL_RTL_USTRCODE(*pStr1), IMPL_RTL_USTRCODE(*pStr2));
+ if ( nRet != 0 )
+ return nRet;
+
+ pStr1++;
+ pStr2++;
+ }
+
+ return nStr1Len - nStr2Len;
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( shortenedCompareIgnoreAsciiCase_WithLength )( const IMPL_RTL_STRCODE* pStr1,
+ sal_Int32 nStr1Len,
+ const IMPL_RTL_STRCODE* pStr2,
+ sal_Int32 nStr2Len,
+ sal_Int32 nShortenedLength )
+ SAL_THROW_EXTERN_C()
+{
+ assert(nStr1Len >= 0);
+ assert(nStr2Len >= 0);
+ assert(nShortenedLength >= 0);
+ const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len;
+ const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len;
+ while ( (nShortenedLength > 0) &&
+ (pStr1 < pStr1End) && (pStr2 < pStr2End) )
+ {
+ sal_Int32 nRet = rtl::compareIgnoreAsciiCase(
+ IMPL_RTL_USTRCODE(*pStr1), IMPL_RTL_USTRCODE(*pStr2));
+ if ( nRet != 0 )
+ return nRet;
+
+ nShortenedLength--;
+ pStr1++;
+ pStr2++;
+ }
+
+ if ( nShortenedLength <= 0 )
+ return 0;
+ return nStr1Len - nStr2Len;
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( hashCode )( const IMPL_RTL_STRCODE* pStr )
+ SAL_THROW_EXTERN_C()
+{
+ return IMPL_RTL_STRNAME( hashCode_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ) );
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( hashCode_WithLength )( const IMPL_RTL_STRCODE* pStr,
+ sal_Int32 nLen )
+ SAL_THROW_EXTERN_C()
+{
+ assert(nLen >= 0);
+ sal_uInt32 h = static_cast<sal_uInt32>(nLen);
+ while ( nLen > 0 )
+ {
+ h = (h*37U) + IMPL_RTL_USTRCODE( *pStr );
+ pStr++;
+ nLen--;
+ }
+ return static_cast<sal_Int32>(h);
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfChar )( const IMPL_RTL_STRCODE* pStr,
+ IMPL_RTL_STRCODE c )
+ SAL_THROW_EXTERN_C()
+{
+ assert(pStr);
+#if !IMPL_RTL_IS_USTRING
+ // take advantage of builtin optimisations
+ const IMPL_RTL_STRCODE* p = strchr(pStr, c);
+ return p ? p - pStr : -1;
+#else
+ if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
+ {
+ // take advantage of builtin optimisations
+ wchar_t const * p = wcschr(reinterpret_cast<wchar_t const *>(pStr), static_cast<wchar_t>(c));
+ return p ? p - reinterpret_cast<wchar_t const *>(pStr) : -1;
+ }
+ else
+ {
+ const IMPL_RTL_STRCODE* pTempStr = pStr;
+ while ( *pTempStr )
+ {
+ if ( *pTempStr == c )
+ return pTempStr-pStr;
+
+ pTempStr++;
+ }
+
+ return -1;
+ }
+#endif
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfChar_WithLength )( const IMPL_RTL_STRCODE* pStr,
+ sal_Int32 nLen,
+ IMPL_RTL_STRCODE c )
+ SAL_THROW_EXTERN_C()
+{
+// assert(nLen >= 0);
+#if !IMPL_RTL_IS_USTRING
+ // take advantage of builtin optimisations
+ IMPL_RTL_STRCODE* p = static_cast<IMPL_RTL_STRCODE*>(std::memchr(const_cast<IMPL_RTL_STRCODE *>(pStr), c, nLen));
+ return p ? p - pStr : -1;
+#else
+ const IMPL_RTL_STRCODE* pTempStr = pStr;
+ while ( nLen > 0 )
+ {
+ if ( *pTempStr == c )
+ return pTempStr-pStr;
+
+ pTempStr++;
+ nLen--;
+ }
+
+ return -1;
+#endif
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfChar )( const IMPL_RTL_STRCODE* pStr,
+ IMPL_RTL_STRCODE c )
+ SAL_THROW_EXTERN_C()
+{
+ assert(pStr);
+#if !IMPL_RTL_IS_USTRING
+ // take advantage of builtin optimisations
+ const IMPL_RTL_STRCODE* p = strrchr(pStr, c);
+ return p ? p - pStr : -1;
+#else
+ if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
+ {
+ // take advantage of builtin optimisations
+ wchar_t const * p = wcsrchr(reinterpret_cast<wchar_t const *>(pStr), static_cast<wchar_t>(c));
+ return p ? p - reinterpret_cast<wchar_t const *>(pStr) : -1;
+ }
+ else
+ {
+ return IMPL_RTL_STRNAME( lastIndexOfChar_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ), c );
+ }
+#endif
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfChar_WithLength )( const IMPL_RTL_STRCODE* pStr,
+ sal_Int32 nLen,
+ IMPL_RTL_STRCODE c )
+ SAL_THROW_EXTERN_C()
+{
+ assert(nLen >= 0);
+ pStr += nLen;
+ while ( nLen > 0 )
+ {
+ nLen--;
+ pStr--;
+
+ if ( *pStr == c )
+ return nLen;
+ }
+
+ return -1;
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfStr )( const IMPL_RTL_STRCODE* pStr,
+ const IMPL_RTL_STRCODE* pSubStr )
+ SAL_THROW_EXTERN_C()
+{
+ assert(pStr);
+ assert(pSubStr);
+#if !IMPL_RTL_IS_USTRING
+ // take advantage of builtin optimisations
+ const IMPL_RTL_STRCODE* p = strstr(pStr, pSubStr);
+ return p ? p - pStr : -1;
+#else
+ if (sizeof(IMPL_RTL_STRCODE) == sizeof(wchar_t))
+ {
+ // take advantage of builtin optimisations
+ wchar_t const * p = wcsstr(reinterpret_cast<wchar_t const *>(pStr), reinterpret_cast<wchar_t const *>(pSubStr));
+ return p ? p - reinterpret_cast<wchar_t const *>(pStr) : -1;
+ }
+ else
+ {
+ return IMPL_RTL_STRNAME( indexOfStr_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ),
+ pSubStr, IMPL_RTL_STRNAME( getLength )( pSubStr ) );
+ }
+#endif
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfStr_WithLength )( const IMPL_RTL_STRCODE* pStr,
+ sal_Int32 nStrLen,
+ const IMPL_RTL_STRCODE* pSubStr,
+ sal_Int32 nSubLen )
+ SAL_THROW_EXTERN_C()
+{
+ assert(nStrLen >= 0);
+ assert(nSubLen >= 0);
+ /* faster search for a single character */
+ if ( nSubLen < 2 )
+ {
+ /* an empty SubString is always not findable */
+ if ( nSubLen == 1 )
+ {
+ IMPL_RTL_STRCODE c = *pSubStr;
+ const IMPL_RTL_STRCODE* pTempStr = pStr;
+ while ( nStrLen > 0 )
+ {
+ if ( *pTempStr == c )
+ return pTempStr-pStr;
+
+ pTempStr++;
+ nStrLen--;
+ }
+ }
+ }
+ else
+ {
+ const IMPL_RTL_STRCODE* pTempStr = pStr;
+ while ( nStrLen > 0 )
+ {
+ if ( *pTempStr == *pSubStr )
+ {
+ /* Compare SubString */
+ if ( nSubLen <= nStrLen )
+ {
+ const IMPL_RTL_STRCODE* pTempStr1 = pTempStr;
+ const IMPL_RTL_STRCODE* pTempStr2 = pSubStr;
+ sal_Int32 nTempLen = nSubLen;
+ while ( nTempLen )
+ {
+ if ( *pTempStr1 != *pTempStr2 )
+ break;
+
+ pTempStr1++;
+ pTempStr2++;
+ nTempLen--;
+ }
+
+ if ( !nTempLen )
+ return pTempStr-pStr;
+ }
+ else
+ break;
+ }
+
+ nStrLen--;
+ pTempStr++;
+ }
+ }
+
+ return -1;
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfStr )( const IMPL_RTL_STRCODE* pStr,
+ const IMPL_RTL_STRCODE* pSubStr )
+ SAL_THROW_EXTERN_C()
+{
+ return IMPL_RTL_STRNAME( lastIndexOfStr_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ),
+ pSubStr, IMPL_RTL_STRNAME( getLength )( pSubStr ) );
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfStr_WithLength )( const IMPL_RTL_STRCODE* pStr,
+ sal_Int32 nStrLen,
+ const IMPL_RTL_STRCODE* pSubStr,
+ sal_Int32 nSubLen )
+ SAL_THROW_EXTERN_C()
+{
+ assert(nStrLen >= 0);
+ assert(nSubLen >= 0);
+ /* faster search for a single character */
+ if ( nSubLen < 2 )
+ {
+ /* an empty SubString is always not findable */
+ if ( nSubLen == 1 )
+ {
+ IMPL_RTL_STRCODE c = *pSubStr;
+ pStr += nStrLen;
+ while ( nStrLen > 0 )
+ {
+ nStrLen--;
+ pStr--;
+
+ if ( *pStr == c )
+ return nStrLen;
+ }
+ }
+ }
+ else
+ {
+ pStr += nStrLen;
+ nStrLen -= nSubLen;
+ pStr -= nSubLen;
+ while ( nStrLen >= 0 )
+ {
+ const IMPL_RTL_STRCODE* pTempStr1 = pStr;
+ const IMPL_RTL_STRCODE* pTempStr2 = pSubStr;
+ sal_Int32 nTempLen = nSubLen;
+ while ( nTempLen )
+ {
+ if ( *pTempStr1 != *pTempStr2 )
+ break;
+
+ pTempStr1++;
+ pTempStr2++;
+ nTempLen--;
+ }
+
+ if ( !nTempLen )
+ return nStrLen;
+
+ nStrLen--;
+ pStr--;
+ }
+ }
+
+ return -1;
+}
+
+/* ----------------------------------------------------------------------- */
+
+void SAL_CALL IMPL_RTL_STRNAME( replaceChar )( IMPL_RTL_STRCODE* pStr,
+ IMPL_RTL_STRCODE cOld,
+ IMPL_RTL_STRCODE cNew )
+ SAL_THROW_EXTERN_C()
+{
+ assert(pStr);
+ while ( *pStr )
+ {
+ if ( *pStr == cOld )
+ *pStr = cNew;
+
+ pStr++;
+ }
+}
+
+/* ----------------------------------------------------------------------- */
+
+void SAL_CALL IMPL_RTL_STRNAME( replaceChar_WithLength )( IMPL_RTL_STRCODE* pStr,
+ sal_Int32 nLen,
+ IMPL_RTL_STRCODE cOld,
+ IMPL_RTL_STRCODE cNew )
+ SAL_THROW_EXTERN_C()
+{
+ assert(nLen >= 0);
+ while ( nLen > 0 )
+ {
+ if ( *pStr == cOld )
+ *pStr = cNew;
+
+ pStr++;
+ nLen--;
+ }
+}
+
+/* ----------------------------------------------------------------------- */
+
+void SAL_CALL IMPL_RTL_STRNAME( toAsciiLowerCase )( IMPL_RTL_STRCODE* pStr )
+ SAL_THROW_EXTERN_C()
+{
+ assert(pStr);
+ while ( *pStr )
+ {
+ *pStr = rtl::toAsciiLowerCase(IMPL_RTL_USTRCODE(*pStr));
+
+ pStr++;
+ }
+}
+
+/* ----------------------------------------------------------------------- */
+
+void SAL_CALL IMPL_RTL_STRNAME( toAsciiLowerCase_WithLength )( IMPL_RTL_STRCODE* pStr,
+ sal_Int32 nLen )
+ SAL_THROW_EXTERN_C()
+{
+ assert(nLen >= 0);
+ while ( nLen > 0 )
+ {
+ *pStr = rtl::toAsciiLowerCase(IMPL_RTL_USTRCODE(*pStr));
+
+ pStr++;
+ nLen--;
+ }
+}
+
+/* ----------------------------------------------------------------------- */
+
+void SAL_CALL IMPL_RTL_STRNAME( toAsciiUpperCase )( IMPL_RTL_STRCODE* pStr )
+ SAL_THROW_EXTERN_C()
+{
+ assert(pStr);
+ while ( *pStr )
+ {
+ *pStr = rtl::toAsciiUpperCase(IMPL_RTL_USTRCODE(*pStr));
+
+ pStr++;
+ }
+}
+
+/* ----------------------------------------------------------------------- */
+
+void SAL_CALL IMPL_RTL_STRNAME( toAsciiUpperCase_WithLength )( IMPL_RTL_STRCODE* pStr,
+ sal_Int32 nLen )
+ SAL_THROW_EXTERN_C()
+{
+ assert(nLen >= 0);
+ while ( nLen > 0 )
+ {
+ *pStr = rtl::toAsciiUpperCase(IMPL_RTL_USTRCODE(*pStr));
+
+ pStr++;
+ nLen--;
+ }
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( trim )( IMPL_RTL_STRCODE* pStr )
+ SAL_THROW_EXTERN_C()
+{
+ return IMPL_RTL_STRNAME( trim_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ) );
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( trim_WithLength )( IMPL_RTL_STRCODE* pStr, sal_Int32 nLen )
+ SAL_THROW_EXTERN_C()
+{
+ assert(nLen >= 0);
+ sal_Int32 nPreSpaces = 0;
+ sal_Int32 nPostSpaces = 0;
+ sal_Int32 nIndex = nLen-1;
+
+ while ( (nPreSpaces < nLen) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pStr+nPreSpaces)) ) )
+ nPreSpaces++;
+
+ while ( (nIndex > nPreSpaces) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pStr+nIndex)) ) )
+ {
+ nPostSpaces++;
+ nIndex--;
+ }
+
+ if ( nPostSpaces )
+ {
+ nLen -= nPostSpaces;
+ *(pStr+nLen) = 0;
+ }
+
+ if ( nPreSpaces )
+ {
+ nLen -= nPreSpaces;
+ memmove(pStr, pStr + nPreSpaces, nLen * sizeof(IMPL_RTL_STRCODE));
+ pStr += nLen;
+ *pStr = 0;
+ }
+
+ return nLen;
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfBoolean )( IMPL_RTL_STRCODE* pStr, sal_Bool b )
+ SAL_THROW_EXTERN_C()
+{
+ assert(pStr);
+ if ( b )
+ {
+ *pStr = 't';
+ pStr++;
+ *pStr = 'r';
+ pStr++;
+ *pStr = 'u';
+ pStr++;
+ *pStr = 'e';
+ pStr++;
+ *pStr = 0;
+ return 4;
+ }
+ else
+ {
+ *pStr = 'f';
+ pStr++;
+ *pStr = 'a';
+ pStr++;
+ *pStr = 'l';
+ pStr++;
+ *pStr = 's';
+ pStr++;
+ *pStr = 'e';
+ pStr++;
+ *pStr = 0;
+ return 5;
+ }
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfChar )( IMPL_RTL_STRCODE* pStr,
+ IMPL_RTL_STRCODE c )
+ SAL_THROW_EXTERN_C()
+{
+ assert(pStr);
+ *pStr++ = c;
+ *pStr = 0;
+ return 1;
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfInt32 )( IMPL_RTL_STRCODE* pStr,
+ sal_Int32 n,
+ sal_Int16 nRadix )
+ SAL_THROW_EXTERN_C()
+{
+ assert(pStr);
+ assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX );
+ char aBuf[RTL_STR_MAX_VALUEOFINT32];
+ char* pBuf = aBuf;
+ sal_Int32 nLen = 0;
+ sal_uInt32 nValue;
+
+ /* Radix must be valid */
+ if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
+ nRadix = 10;
+
+ /* is value negative */
+ if ( n < 0 )
+ {
+ *pStr = '-';
+ pStr++;
+ nLen++;
+ nValue = n == SAL_MIN_INT32 ? static_cast<sal_uInt32>(n) : -n;
+ }
+ else
+ nValue = n;
+
+ /* create a recursive buffer with all values, except the last one */
+ do
+ {
+ char nDigit = static_cast<char>(nValue % nRadix);
+ nValue /= nRadix;
+ if ( nDigit > 9 )
+ *pBuf = (nDigit-10) + 'a';
+ else
+ *pBuf = (nDigit + '0' );
+ pBuf++;
+ }
+ while ( nValue > 0 );
+
+ /* copy the values in the right direction into the destination buffer */
+ do
+ {
+ pBuf--;
+ *pStr = *pBuf;
+ pStr++;
+ nLen++;
+ }
+ while ( pBuf != aBuf );
+ *pStr = 0;
+
+ return nLen;
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfInt64 )( IMPL_RTL_STRCODE* pStr,
+ sal_Int64 n,
+ sal_Int16 nRadix )
+ SAL_THROW_EXTERN_C()
+{
+ assert(pStr);
+ assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX );
+ char aBuf[RTL_STR_MAX_VALUEOFINT64];
+ char* pBuf = aBuf;
+ sal_Int32 nLen = 0;
+ sal_uInt64 nValue;
+
+ /* Radix must be valid */
+ if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
+ nRadix = 10;
+
+ /* is value negative */
+ if ( n < 0 )
+ {
+ *pStr = '-';
+ pStr++;
+ nLen++;
+ nValue = n == SAL_MIN_INT64 ? static_cast<sal_uInt64>(n) : -n;
+ }
+ else
+ nValue = n;
+
+ /* create a recursive buffer with all values, except the last one */
+ do
+ {
+ char nDigit = static_cast<char>(nValue % nRadix);
+ nValue /= nRadix;
+ if ( nDigit > 9 )
+ *pBuf = (nDigit-10) + 'a';
+ else
+ *pBuf = (nDigit + '0' );
+ pBuf++;
+ }
+ while ( nValue > 0 );
+
+ /* copy the values in the right direction into the destination buffer */
+ do
+ {
+ pBuf--;
+ *pStr = *pBuf;
+ pStr++;
+ nLen++;
+ }
+ while ( pBuf != aBuf );
+ *pStr = 0;
+
+ return nLen;
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfUInt64 )( IMPL_RTL_STRCODE* pStr,
+ sal_uInt64 n,
+ sal_Int16 nRadix )
+ SAL_THROW_EXTERN_C()
+{
+ assert(pStr);
+ assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX );
+ char aBuf[RTL_STR_MAX_VALUEOFUINT64];
+ char* pBuf = aBuf;
+ sal_Int32 nLen = 0;
+ sal_uInt64 nValue;
+
+ /* Radix must be valid */
+ if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
+ nRadix = 10;
+
+ nValue = n;
+
+ /* create a recursive buffer with all values, except the last one */
+ do
+ {
+ char nDigit = static_cast<char>(nValue % nRadix);
+ nValue /= nRadix;
+ if ( nDigit > 9 )
+ *pBuf = (nDigit-10) + 'a';
+ else
+ *pBuf = (nDigit + '0' );
+ pBuf++;
+ }
+ while ( nValue > 0 );
+
+ /* copy the values in the right direction into the destination buffer */
+ do
+ {
+ pBuf--;
+ *pStr = *pBuf;
+ pStr++;
+ nLen++;
+ }
+ while ( pBuf != aBuf );
+ *pStr = 0;
+
+ return nLen;
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Bool SAL_CALL IMPL_RTL_STRNAME( toBoolean )( const IMPL_RTL_STRCODE* pStr )
+ SAL_THROW_EXTERN_C()
+{
+ assert(pStr);
+ if ( *pStr == '1' )
+ return true;
+
+ if ( (*pStr == 'T') || (*pStr == 't') )
+ {
+ pStr++;
+ if ( (*pStr == 'R') || (*pStr == 'r') )
+ {
+ pStr++;
+ if ( (*pStr == 'U') || (*pStr == 'u') )
+ {
+ pStr++;
+ if ( (*pStr == 'E') || (*pStr == 'e') )
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+/* ----------------------------------------------------------------------- */
+namespace {
+ template<typename T, typename U> T IMPL_RTL_STRNAME( toInt_WithLength )( const IMPL_RTL_STRCODE* pStr,
+ sal_Int16 nRadix,
+ sal_Int32 nStrLength )
+ {
+ static_assert(std::numeric_limits<T>::is_signed, "is signed");
+ assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX );
+ assert( nStrLength >= 0 );
+ bool bNeg;
+ sal_Int16 nDigit;
+ U n = 0;
+ const IMPL_RTL_STRCODE* pEnd = pStr + nStrLength;
+
+ if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
+ nRadix = 10;
+
+ /* Skip whitespaces */
+ while ( pStr != pEnd && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) )
+ pStr++;
+
+ if ( *pStr == '-' )
+ {
+ bNeg = true;
+ pStr++;
+ }
+ else
+ {
+ if ( *pStr == '+' )
+ pStr++;
+ bNeg = false;
+ }
+
+ T nDiv;
+ sal_Int16 nMod;
+ if ( bNeg )
+ {
+ nDiv = std::numeric_limits<T>::min() / nRadix;
+ nMod = std::numeric_limits<T>::min() % nRadix;
+ // Cater for C++03 implementations that round the quotient down
+ // instead of truncating towards zero as mandated by C++11:
+ if ( nMod > 0 )
+ {
+ --nDiv;
+ nMod -= nRadix;
+ }
+ nDiv = -nDiv;
+ nMod = -nMod;
+ }
+ else
+ {
+ nDiv = std::numeric_limits<T>::max() / nRadix;
+ nMod = std::numeric_limits<T>::max() % nRadix;
+ }
+
+ while ( pStr != pEnd )
+ {
+ nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix );
+ if ( nDigit < 0 )
+ break;
+ assert(nDiv > 0);
+ if( static_cast<U>( nMod < nDigit ? nDiv-1 : nDiv ) < n )
+ return 0;
+
+ n *= nRadix;
+ n += nDigit;
+
+ pStr++;
+ }
+
+ if ( bNeg )
+ return n == static_cast<U>(std::numeric_limits<T>::min())
+ ? std::numeric_limits<T>::min() : -static_cast<T>(n);
+ else
+ return static_cast<T>(n);
+ }
+}
+
+sal_Int32 SAL_CALL IMPL_RTL_STRNAME( toInt32 )( const IMPL_RTL_STRCODE* pStr,
+ sal_Int16 nRadix )
+ SAL_THROW_EXTERN_C()
+{
+ assert(pStr);
+ return IMPL_RTL_STRNAME( toInt_WithLength )<sal_Int32, sal_uInt32>(pStr, nRadix, IMPL_RTL_STRNAME( getLength )(pStr));
+}
+
+sal_Int64 SAL_CALL IMPL_RTL_STRNAME( toInt64 )( const IMPL_RTL_STRCODE* pStr,
+ sal_Int16 nRadix )
+ SAL_THROW_EXTERN_C()
+{
+ assert(pStr);
+ return IMPL_RTL_STRNAME( toInt_WithLength )<sal_Int64, sal_uInt64>(pStr, nRadix, IMPL_RTL_STRNAME( getLength )(pStr));
+}
+
+sal_Int64 SAL_CALL IMPL_RTL_STRNAME( toInt64_WithLength )( const IMPL_RTL_STRCODE* pStr,
+ sal_Int16 nRadix,
+ sal_Int32 nStrLength)
+ SAL_THROW_EXTERN_C()
+{
+ assert(pStr);
+ return IMPL_RTL_STRNAME( toInt_WithLength )<sal_Int64, sal_uInt64>(pStr, nRadix, nStrLength);
+}
+
+/* ----------------------------------------------------------------------- */
+namespace {
+ template <typename T> T IMPL_RTL_STRNAME( toUInt )( const IMPL_RTL_STRCODE* pStr,
+ sal_Int16 nRadix )
+ {
+ static_assert(!std::numeric_limits<T>::is_signed, "is not signed");
+ assert( nRadix >= RTL_STR_MIN_RADIX && nRadix <= RTL_STR_MAX_RADIX );
+ sal_Int16 nDigit;
+ T n = 0;
+
+ if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) )
+ nRadix = 10;
+
+ /* Skip whitespaces */
+ while ( *pStr && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) )
+ ++pStr;
+
+ // skip optional explicit sign
+ if ( *pStr == '+' )
+ ++pStr;
+
+ T nDiv = std::numeric_limits<T>::max() / nRadix;
+ sal_Int16 nMod = std::numeric_limits<T>::max() % nRadix;
+ while ( *pStr )
+ {
+ nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix );
+ if ( nDigit < 0 )
+ break;
+ if( ( nMod < nDigit ? nDiv-1 : nDiv ) < n )
+ return 0;
+
+ n *= nRadix;
+ n += nDigit;
+
+ ++pStr;
+ }
+
+ return n;
+ }
+}
+
+sal_uInt32 SAL_CALL IMPL_RTL_STRNAME( toUInt32 )( const IMPL_RTL_STRCODE* pStr,
+ sal_Int16 nRadix )
+ SAL_THROW_EXTERN_C()
+{
+ assert(pStr);
+ return IMPL_RTL_STRNAME( toUInt )<sal_uInt32>(pStr, nRadix);
+}
+
+sal_uInt64 SAL_CALL IMPL_RTL_STRNAME( toUInt64 )( const IMPL_RTL_STRCODE* pStr,
+ sal_Int16 nRadix )
+ SAL_THROW_EXTERN_C()
+{
+ assert(pStr);
+ return IMPL_RTL_STRNAME( toUInt )<sal_uInt64>(pStr, nRadix);
+}
+
+/* ======================================================================= */
+/* Internal String-Class help functions */
+/* ======================================================================= */
+
+IMPL_RTL_STRINGDATA* IMPL_RTL_STRINGNAME( ImplAlloc )( sal_Int32 nLen )
+{
+ IMPL_RTL_STRINGDATA * pData
+ = (sal::static_int_cast< sal_uInt32 >(nLen)
+ <= ((SAL_MAX_UINT32 - sizeof (IMPL_RTL_STRINGDATA))
+ / sizeof (IMPL_RTL_STRCODE)))
+ ? static_cast<IMPL_RTL_STRINGDATA *>(rtl_allocateString(
+ sizeof (IMPL_RTL_STRINGDATA) + nLen * sizeof (IMPL_RTL_STRCODE)))
+ : nullptr;
+ if (pData != nullptr) {
+ pData->refCount = 1;
+ pData->length = nLen;
+ pData->buffer[nLen] = 0;
+ }
+ return pData;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static IMPL_RTL_STRCODE* IMPL_RTL_STRINGNAME( ImplNewCopy )( IMPL_RTL_STRINGDATA** ppThis,
+ IMPL_RTL_STRINGDATA* pStr,
+ sal_Int32 nCount )
+{
+ assert(nCount >= 0);
+ IMPL_RTL_STRCODE* pDest;
+ const IMPL_RTL_STRCODE* pSrc;
+ IMPL_RTL_STRINGDATA* pData = IMPL_RTL_STRINGNAME( ImplAlloc )( pStr->length );
+ OSL_ASSERT(pData != nullptr);
+
+ pDest = pData->buffer;
+ pSrc = pStr->buffer;
+
+ memcpy( pDest, pSrc, nCount * sizeof(IMPL_RTL_STRCODE));
+
+ *ppThis = pData;
+
+ RTL_LOG_STRING_NEW( pData );
+ return pDest + nCount;
+}
+
+/* ======================================================================= */
+/* String-Class functions */
+/* ======================================================================= */
+
+namespace {
+
+void IMPL_RTL_ACQUIRE(IMPL_RTL_STRINGDATA * pThis)
+{
+ if (!SAL_STRING_IS_STATIC (pThis))
+ osl_atomic_increment( &((pThis)->refCount) );
+}
+
+}
+
+/* ----------------------------------------------------------------------- */
+
+void SAL_CALL IMPL_RTL_STRINGNAME( acquire )( IMPL_RTL_STRINGDATA* pThis )
+ SAL_THROW_EXTERN_C()
+{
+ IMPL_RTL_ACQUIRE( pThis );
+}
+
+/* ----------------------------------------------------------------------- */
+
+void SAL_CALL IMPL_RTL_STRINGNAME( release )( IMPL_RTL_STRINGDATA* pThis )
+ SAL_THROW_EXTERN_C()
+{
+ if (SAL_UNLIKELY(SAL_STRING_IS_STATIC (pThis)))
+ return;
+
+/* OString doesn't have an 'intern' */
+#if IMPL_RTL_IS_USTRING
+ if (SAL_STRING_IS_INTERN (pThis))
+ {
+ internRelease (pThis);
+ return;
+ }
+#endif
+
+ if ( !osl_atomic_decrement( &(pThis->refCount) ) )
+ {
+ RTL_LOG_STRING_DELETE( pThis );
+ rtl_freeString( pThis );
+ }
+}
+
+/* ----------------------------------------------------------------------- */
+
+void SAL_CALL IMPL_RTL_STRINGNAME( new )( IMPL_RTL_STRINGDATA** ppThis )
+ SAL_THROW_EXTERN_C()
+{
+ assert(ppThis);
+ if ( *ppThis)
+ IMPL_RTL_STRINGNAME( release )( *ppThis );
+
+ *ppThis = const_cast<IMPL_RTL_STRINGDATA*>(&IMPL_RTL_EMPTYSTRING);
+}
+
+/* ----------------------------------------------------------------------- */
+
+IMPL_RTL_STRINGDATA* SAL_CALL IMPL_RTL_STRINGNAME( alloc )( sal_Int32 nLen )
+ SAL_THROW_EXTERN_C()
+{
+ assert(nLen >= 0);
+ return IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
+}
+
+/* ----------------------------------------------------------------------- */
+
+void SAL_CALL IMPL_RTL_STRINGNAME( new_WithLength )( IMPL_RTL_STRINGDATA** ppThis, sal_Int32 nLen )
+ SAL_THROW_EXTERN_C()
+{
+ assert(ppThis);
+ assert(nLen >= 0);
+ if ( nLen <= 0 )
+ IMPL_RTL_STRINGNAME( new )( ppThis );
+ else
+ {
+ if ( *ppThis)
+ IMPL_RTL_STRINGNAME( release )( *ppThis );
+
+ *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
+ OSL_ASSERT(*ppThis != nullptr);
+ (*ppThis)->length = 0;
+
+ IMPL_RTL_STRCODE* pTempStr = (*ppThis)->buffer;
+ memset(pTempStr, 0, nLen*sizeof(IMPL_RTL_STRCODE));
+ }
+}
+
+/* ----------------------------------------------------------------------- */
+
+void SAL_CALL IMPL_RTL_STRINGNAME( newFromString )( IMPL_RTL_STRINGDATA** ppThis,
+ const IMPL_RTL_STRINGDATA* pStr )
+ SAL_THROW_EXTERN_C()
+{
+ assert(ppThis);
+ assert(pStr);
+ IMPL_RTL_STRINGDATA* pOrg;
+
+ if ( !pStr->length )
+ {
+ IMPL_RTL_STRINGNAME( new )( ppThis );
+ return;
+ }
+
+ pOrg = *ppThis;
+ *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( pStr->length );
+ OSL_ASSERT(*ppThis != nullptr);
+ rtl_str_ImplCopy( (*ppThis)->buffer, pStr->buffer, pStr->length );
+ RTL_LOG_STRING_NEW( *ppThis );
+
+ /* must be done last, if pStr == *ppThis */
+ if ( pOrg )
+ IMPL_RTL_STRINGNAME( release )( pOrg );
+}
+
+/* ----------------------------------------------------------------------- */
+
+void SAL_CALL IMPL_RTL_STRINGNAME( newFromStr )( IMPL_RTL_STRINGDATA** ppThis,
+ const IMPL_RTL_STRCODE* pCharStr )
+ SAL_THROW_EXTERN_C()
+{
+ assert(ppThis);
+ IMPL_RTL_STRINGDATA* pOrg;
+ sal_Int32 nLen;
+
+ if ( pCharStr )
+ {
+ nLen = IMPL_RTL_STRNAME( getLength )( pCharStr );
+ }
+ else
+ nLen = 0;
+
+ if ( !nLen )
+ {
+ IMPL_RTL_STRINGNAME( new )( ppThis );
+ return;
+ }
+
+ pOrg = *ppThis;
+ *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
+ OSL_ASSERT(*ppThis != nullptr);
+ rtl_str_ImplCopy( (*ppThis)->buffer, pCharStr, nLen );
+ RTL_LOG_STRING_NEW( *ppThis );
+
+ /* must be done last, if pCharStr == *ppThis */
+ if ( pOrg )
+ IMPL_RTL_STRINGNAME( release )( pOrg );
+}
+
+/* ----------------------------------------------------------------------- */
+
+void SAL_CALL IMPL_RTL_STRINGNAME( newFromStr_WithLength )( IMPL_RTL_STRINGDATA** ppThis,
+ const IMPL_RTL_STRCODE* pCharStr,
+ sal_Int32 nLen )
+ SAL_THROW_EXTERN_C()
+{
+ assert(ppThis);
+ assert(nLen >= 0);
+ IMPL_RTL_STRINGDATA* pOrg;
+
+ if ( !pCharStr || (nLen <= 0) )
+ {
+ IMPL_RTL_STRINGNAME( new )( ppThis );
+ return;
+ }
+
+ pOrg = *ppThis;
+ *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
+ OSL_ASSERT(*ppThis != nullptr);
+ rtl_str_ImplCopy( (*ppThis)->buffer, pCharStr, nLen );
+
+ RTL_LOG_STRING_NEW( *ppThis );
+
+ /* must be done last, if pCharStr == *ppThis */
+ if ( pOrg )
+ IMPL_RTL_STRINGNAME( release )( pOrg );
+}
+
+/* ----------------------------------------------------------------------- */
+
+void SAL_CALL IMPL_RTL_STRINGNAME( newFromSubString )( IMPL_RTL_STRINGDATA** ppThis,
+ const IMPL_RTL_STRINGDATA* pFrom,
+ sal_Int32 beginIndex,
+ sal_Int32 count )
+ SAL_THROW_EXTERN_C()
+{
+ assert(ppThis);
+ if ( beginIndex == 0 && count == pFrom->length )
+ {
+ IMPL_RTL_STRINGNAME( assign )( ppThis, const_cast< IMPL_RTL_STRINGDATA * >( pFrom ) );
+ return;
+ }
+ if ( count < 0 || beginIndex < 0 || beginIndex + count > pFrom->length )
+ {
+ assert(false); // fail fast at least in debug builds
+ IMPL_RTL_STRINGNAME( newFromLiteral )( ppThis, "!!br0ken!!", 10, 0 );
+ return;
+ }
+
+ IMPL_RTL_STRINGNAME( newFromStr_WithLength )( ppThis, pFrom->buffer + beginIndex, count );
+}
+
+/* ----------------------------------------------------------------------- */
+
+// Used when creating from string literals.
+void SAL_CALL IMPL_RTL_STRINGNAME( newFromLiteral )( IMPL_RTL_STRINGDATA** ppThis,
+ const char* pCharStr,
+ sal_Int32 nLen,
+ sal_Int32 allocExtra )
+ SAL_THROW_EXTERN_C()
+{
+ assert(ppThis);
+ assert(nLen >= 0);
+ assert(allocExtra >= 0);
+ if ( nLen + allocExtra == 0 )
+ {
+ IMPL_RTL_STRINGNAME( new )( ppThis );
+ return;
+ }
+
+ if ( *ppThis )
+ IMPL_RTL_STRINGNAME( release )( *ppThis );
+
+ *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen + allocExtra );
+ assert( *ppThis != nullptr );
+
+ (*ppThis)->length = nLen; // fix after possible allocExtra != 0
+ (*ppThis)->buffer[nLen] = 0;
+ IMPL_RTL_STRCODE* pBuffer = (*ppThis)->buffer;
+ sal_Int32 nCount;
+ for( nCount = nLen; nCount > 0; --nCount )
+ {
+#if IMPL_RTL_IS_USTRING
+ assert(static_cast<unsigned char>(*pCharStr) < 0x80); // ASCII range
+#endif
+ SAL_WARN_IF( (static_cast<unsigned char>(*pCharStr)) == '\0', "rtl.string",
+ "rtl_uString_newFromLiteral - Found embedded \\0 character" );
+
+ *pBuffer = *pCharStr;
+ pBuffer++;
+ pCharStr++;
+ }
+
+ RTL_LOG_STRING_NEW( *ppThis );
+}
+
+/* ----------------------------------------------------------------------- */
+
+void SAL_CALL IMPL_RTL_STRINGNAME( assign )( IMPL_RTL_STRINGDATA** ppThis,
+ IMPL_RTL_STRINGDATA* pStr )
+ SAL_THROW_EXTERN_C()
+{
+ assert(ppThis);
+ /* must be done at first, if pStr == *ppThis */
+ IMPL_RTL_ACQUIRE( pStr );
+
+ if ( *ppThis )
+ IMPL_RTL_STRINGNAME( release )( *ppThis );
+
+ *ppThis = pStr;
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRINGNAME( getLength )( const IMPL_RTL_STRINGDATA* pThis )
+ SAL_THROW_EXTERN_C()
+{
+ assert(pThis);
+ return pThis->length;
+}
+
+/* ----------------------------------------------------------------------- */
+
+IMPL_RTL_STRCODE* SAL_CALL IMPL_RTL_STRINGNAME( getStr )( IMPL_RTL_STRINGDATA * pThis )
+ SAL_THROW_EXTERN_C()
+{
+ assert(pThis);
+ return pThis->buffer;
+}
+
+/* ----------------------------------------------------------------------- */
+
+void SAL_CALL IMPL_RTL_STRINGNAME( newConcat )( IMPL_RTL_STRINGDATA** ppThis,
+ IMPL_RTL_STRINGDATA* pLeft,
+ IMPL_RTL_STRINGDATA* pRight )
+ SAL_THROW_EXTERN_C()
+{
+ assert(ppThis);
+ IMPL_RTL_STRINGDATA* pOrg = *ppThis;
+
+ /* Test for 0-Pointer - if not, change newReplaceStrAt! */
+ if ( !pRight || !pRight->length )
+ {
+ *ppThis = pLeft;
+ IMPL_RTL_ACQUIRE( pLeft );
+ }
+ else if ( !pLeft || !pLeft->length )
+ {
+ *ppThis = pRight;
+ IMPL_RTL_ACQUIRE( pRight );
+ }
+ else if (pLeft->length
+ > std::numeric_limits<sal_Int32>::max() - pRight->length)
+ {
+ *ppThis = nullptr;
+ }
+ else
+ {
+ IMPL_RTL_STRINGDATA* pTempStr = IMPL_RTL_STRINGNAME( ImplAlloc )( pLeft->length + pRight->length );
+ OSL_ASSERT(pTempStr != nullptr);
+ *ppThis = pTempStr;
+ if (*ppThis != nullptr) {
+ rtl_str_ImplCopy( pTempStr->buffer, pLeft->buffer, pLeft->length );
+ rtl_str_ImplCopy( pTempStr->buffer+pLeft->length, pRight->buffer, pRight->length );
+
+ RTL_LOG_STRING_NEW( *ppThis );
+ }
+ }
+
+ /* must be done last, if left or right == *ppThis */
+ if ( pOrg )
+ IMPL_RTL_STRINGNAME( release )( pOrg );
+}
+
+/* ----------------------------------------------------------------------- */
+
+void SAL_CALL IMPL_RTL_STRINGNAME( ensureCapacity )( IMPL_RTL_STRINGDATA** ppThis,
+ sal_Int32 size )
+ SAL_THROW_EXTERN_C()
+{
+ assert(ppThis);
+ IMPL_RTL_STRINGDATA* const pOrg = *ppThis;
+ if ( pOrg->refCount == 1 && pOrg->length >= size )
+ return;
+ assert( pOrg->length <= size ); // do not truncate
+ IMPL_RTL_STRINGDATA* pTempStr = IMPL_RTL_STRINGNAME( ImplAlloc )( size );
+ rtl_str_ImplCopy( pTempStr->buffer, pOrg->buffer, pOrg->length );
+ // right now the length is still the same as of the original
+ pTempStr->length = pOrg->length;
+ pTempStr->buffer[ pOrg->length ] = '\0';
+ *ppThis = pTempStr;
+ RTL_LOG_STRING_NEW( *ppThis );
+
+ IMPL_RTL_STRINGNAME( release )( pOrg );
+}
+
+/* ----------------------------------------------------------------------- */
+
+void SAL_CALL IMPL_RTL_STRINGNAME( newReplaceStrAt )( IMPL_RTL_STRINGDATA** ppThis,
+ IMPL_RTL_STRINGDATA* pStr,
+ sal_Int32 nIndex,
+ sal_Int32 nCount,
+ IMPL_RTL_STRINGDATA* pNewSubStr )
+ SAL_THROW_EXTERN_C()
+{
+ assert(ppThis);
+ assert(nIndex >= 0 && nIndex <= pStr->length);
+ assert(nCount >= 0);
+ assert(nCount <= pStr->length - nIndex);
+ /* Append? */
+ if ( nIndex >= pStr->length )
+ {
+ /* newConcat test, if pNewSubStr is 0 */
+ IMPL_RTL_STRINGNAME( newConcat )( ppThis, pStr, pNewSubStr );
+ return;
+ }
+
+ /* negative index? */
+ if ( nIndex < 0 )
+ {
+ nCount -= nIndex;
+ nIndex = 0;
+ }
+
+ /* not more than the String length could be deleted */
+ if ( nCount >= pStr->length-nIndex )
+ {
+ nCount = pStr->length-nIndex;
+
+ /* Assign of NewSubStr? */
+ if ( !nIndex && (nCount >= pStr->length) )
+ {
+ if ( !pNewSubStr )
+ IMPL_RTL_STRINGNAME( new )( ppThis );
+ else
+ IMPL_RTL_STRINGNAME( assign )( ppThis, pNewSubStr );
+ return;
+ }
+ }
+
+ /* Assign of Str? */
+ if ( !nCount && (!pNewSubStr || !pNewSubStr->length) )
+ {
+ IMPL_RTL_STRINGNAME( assign )( ppThis, pStr );
+ return;
+ }
+
+ IMPL_RTL_STRINGDATA* pOrg = *ppThis;
+ IMPL_RTL_STRCODE* pBuffer;
+ sal_Int32 nNewLen;
+
+ /* Calculate length of the new string */
+ nNewLen = pStr->length-nCount;
+ if ( pNewSubStr )
+ nNewLen += pNewSubStr->length;
+
+ /* Alloc New Buffer */
+ *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nNewLen );
+ OSL_ASSERT(*ppThis != nullptr);
+ pBuffer = (*ppThis)->buffer;
+ if ( nIndex )
+ {
+ rtl_str_ImplCopy( pBuffer, pStr->buffer, nIndex );
+ pBuffer += nIndex;
+ }
+ if ( pNewSubStr && pNewSubStr->length )
+ {
+ rtl_str_ImplCopy( pBuffer, pNewSubStr->buffer, pNewSubStr->length );
+ pBuffer += pNewSubStr->length;
+ }
+ rtl_str_ImplCopy( pBuffer, pStr->buffer+nIndex+nCount, pStr->length-nIndex-nCount );
+
+ RTL_LOG_STRING_NEW( *ppThis );
+ /* must be done last, if pStr or pNewSubStr == *ppThis */
+ if ( pOrg )
+ IMPL_RTL_STRINGNAME( release )( pOrg );
+}
+
+/* ----------------------------------------------------------------------- */
+
+void SAL_CALL IMPL_RTL_STRINGNAME( newReplace )( IMPL_RTL_STRINGDATA** ppThis,
+ IMPL_RTL_STRINGDATA* pStr,
+ IMPL_RTL_STRCODE cOld,
+ IMPL_RTL_STRCODE cNew )
+ SAL_THROW_EXTERN_C()
+{
+ assert(ppThis);
+ assert(pStr);
+ IMPL_RTL_STRINGDATA* pOrg = *ppThis;
+ bool bChanged = false;
+ sal_Int32 nLen = pStr->length;
+ const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
+
+ while ( nLen > 0 )
+ {
+ if ( *pCharStr == cOld )
+ {
+ /* Copy String */
+ IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
+
+ /* replace/copy rest of the string */
+ if ( pNewCharStr )
+ {
+ *pNewCharStr = cNew;
+ pNewCharStr++;
+ pCharStr++;
+ nLen--;
+
+ while ( nLen > 0 )
+ {
+ if ( *pCharStr == cOld )
+ *pNewCharStr = cNew;
+ else
+ *pNewCharStr = *pCharStr;
+
+ pNewCharStr++;
+ pCharStr++;
+ nLen--;
+ }
+ }
+
+ bChanged = true;
+ break;
+ }
+
+ pCharStr++;
+ nLen--;
+ }
+
+ if ( !bChanged )
+ {
+ *ppThis = pStr;
+ IMPL_RTL_ACQUIRE( pStr );
+ }
+
+ RTL_LOG_STRING_NEW( *ppThis );
+ /* must be done last, if pStr == *ppThis */
+ if ( pOrg )
+ IMPL_RTL_STRINGNAME( release )( pOrg );
+}
+
+/* ----------------------------------------------------------------------- */
+
+void SAL_CALL IMPL_RTL_STRINGNAME( newToAsciiLowerCase )( IMPL_RTL_STRINGDATA** ppThis,
+ IMPL_RTL_STRINGDATA* pStr )
+ SAL_THROW_EXTERN_C()
+{
+ assert(ppThis);
+ assert(pStr);
+ IMPL_RTL_STRINGDATA* pOrg = *ppThis;
+ bool bChanged = false;
+ sal_Int32 nLen = pStr->length;
+ const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
+
+ while ( nLen > 0 )
+ {
+ if ( rtl::isAsciiUpperCase(IMPL_RTL_USTRCODE(*pCharStr)) )
+ {
+ /* Copy String */
+ IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
+
+ /* replace/copy rest of the string */
+ if ( pNewCharStr )
+ {
+ *pNewCharStr = rtl::toAsciiLowerCase(IMPL_RTL_USTRCODE(*pCharStr));
+ pNewCharStr++;
+ pCharStr++;
+ nLen--;
+
+ while ( nLen > 0 )
+ {
+ *pNewCharStr = rtl::toAsciiLowerCase(IMPL_RTL_USTRCODE(*pCharStr));
+
+ pNewCharStr++;
+ pCharStr++;
+ nLen--;
+ }
+ }
+
+ bChanged = true;
+ break;
+ }
+
+ pCharStr++;
+ nLen--;
+ }
+
+ if ( !bChanged )
+ {
+ *ppThis = pStr;
+ IMPL_RTL_ACQUIRE( pStr );
+ }
+
+ RTL_LOG_STRING_NEW( *ppThis );
+ /* must be done last, if pStr == *ppThis */
+ if ( pOrg )
+ IMPL_RTL_STRINGNAME( release )( pOrg );
+}
+
+/* ----------------------------------------------------------------------- */
+
+void SAL_CALL IMPL_RTL_STRINGNAME( newToAsciiUpperCase )( IMPL_RTL_STRINGDATA** ppThis,
+ IMPL_RTL_STRINGDATA* pStr )
+ SAL_THROW_EXTERN_C()
+{
+ assert(ppThis);
+ assert(pStr);
+ IMPL_RTL_STRINGDATA* pOrg = *ppThis;
+ bool bChanged = false;
+ sal_Int32 nLen = pStr->length;
+ const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
+
+ while ( nLen > 0 )
+ {
+ if ( rtl::isAsciiLowerCase(IMPL_RTL_USTRCODE(*pCharStr)) )
+ {
+ /* Copy String */
+ IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer );
+
+ /* replace/copy rest of the string */
+ if ( pNewCharStr )
+ {
+ *pNewCharStr = rtl::toAsciiUpperCase(IMPL_RTL_USTRCODE(*pCharStr));
+ pNewCharStr++;
+ pCharStr++;
+ nLen--;
+
+ while ( nLen > 0 )
+ {
+ *pNewCharStr = rtl::toAsciiUpperCase(IMPL_RTL_USTRCODE(*pCharStr));
+
+ pNewCharStr++;
+ pCharStr++;
+ nLen--;
+ }
+ }
+
+ bChanged = true;
+ break;
+ }
+
+ pCharStr++;
+ nLen--;
+ }
+
+ if ( !bChanged )
+ {
+ *ppThis = pStr;
+ IMPL_RTL_ACQUIRE( pStr );
+ }
+
+ RTL_LOG_STRING_NEW( *ppThis );
+ /* must be done last, if pStr == *ppThis */
+ if ( pOrg )
+ IMPL_RTL_STRINGNAME( release )( pOrg );
+}
+
+/* ----------------------------------------------------------------------- */
+
+void SAL_CALL IMPL_RTL_STRINGNAME( newTrim )( IMPL_RTL_STRINGDATA** ppThis,
+ IMPL_RTL_STRINGDATA* pStr )
+ SAL_THROW_EXTERN_C()
+{
+ assert(ppThis);
+ assert(pStr);
+ IMPL_RTL_STRINGDATA* pOrg = *ppThis;
+ const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
+ sal_Int32 nPreSpaces = 0;
+ sal_Int32 nPostSpaces = 0;
+ sal_Int32 nLen = pStr->length;
+ sal_Int32 nIndex = nLen-1;
+
+ while ( (nPreSpaces < nLen) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pCharStr+nPreSpaces)) ) )
+ nPreSpaces++;
+
+ while ( (nIndex > nPreSpaces) && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE(*(pCharStr+nIndex)) ) )
+ {
+ nPostSpaces++;
+ nIndex--;
+ }
+
+ if ( !nPreSpaces && !nPostSpaces )
+ {
+ *ppThis = pStr;
+ IMPL_RTL_ACQUIRE( pStr );
+ }
+ else
+ {
+ nLen -= nPostSpaces+nPreSpaces;
+ *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen );
+ assert(*ppThis);
+ rtl_str_ImplCopy( (*ppThis)->buffer, pStr->buffer+nPreSpaces, nLen );
+ }
+
+ RTL_LOG_STRING_NEW( *ppThis );
+ /* must be done last, if pStr == *ppThis */
+ if ( pOrg )
+ IMPL_RTL_STRINGNAME( release )( pOrg );
+}
+
+/* ----------------------------------------------------------------------- */
+
+sal_Int32 SAL_CALL IMPL_RTL_STRINGNAME( getToken )( IMPL_RTL_STRINGDATA** ppThis,
+ IMPL_RTL_STRINGDATA* pStr,
+ sal_Int32 nToken,
+ IMPL_RTL_STRCODE cTok,
+ sal_Int32 nIndex )
+ SAL_THROW_EXTERN_C()
+{
+ assert(ppThis);
+ assert(pStr);
+ const IMPL_RTL_STRCODE* pCharStr = pStr->buffer;
+ const IMPL_RTL_STRCODE* pCharStrStart;
+ const IMPL_RTL_STRCODE* pOrgCharStr;
+ sal_Int32 nLen = pStr->length-nIndex;
+ sal_Int32 nTokCount = 0;
+
+ // Set ppThis to an empty string and return -1 if either nToken or nIndex is
+ // negative:
+ if (nIndex < 0)
+ nToken = -1;
+
+ pCharStr += nIndex;
+ pOrgCharStr = pCharStr;
+ pCharStrStart = pCharStr;
+ while ( nLen > 0 )
+ {
+ if ( *pCharStr == cTok )
+ {
+ nTokCount++;
+
+ if ( nTokCount == nToken )
+ pCharStrStart = pCharStr+1;
+ else
+ {
+ if ( nTokCount > nToken )
+ break;
+ }
+ }
+
+ pCharStr++;
+ nLen--;
+ }
+
+ if ( (nToken < 0) || (nTokCount < nToken) || (pCharStr == pCharStrStart) )
+ {
+ IMPL_RTL_STRINGNAME( new )( ppThis );
+ if( (nToken < 0) || (nTokCount < nToken ) )
+ return -1;
+ else if( nLen > 0 )
+ return nIndex+(pCharStr-pOrgCharStr)+1;
+ else return -1;
+ }
+ else
+ {
+ IMPL_RTL_STRINGNAME( newFromStr_WithLength )( ppThis, pCharStrStart, pCharStr-pCharStrStart );
+ if ( nLen )
+ return nIndex+(pCharStr-pOrgCharStr)+1;
+ else
+ return -1;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */