From 54760dfdc26fcded5c62bbad05429db5c9cee935 Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Mon, 31 Oct 2011 22:32:07 +0100 Subject: Moved sal/rtl/source string files from C to C++, for easier maintenance. --- sal/rtl/source/hash.cxx | 4 +- sal/rtl/source/hash.h | 24 - sal/rtl/source/hash.hxx | 16 + sal/rtl/source/strbuf.c | 179 ----- sal/rtl/source/strbuf.cxx | 179 +++++ sal/rtl/source/strimp.c | 61 -- sal/rtl/source/strimp.cxx | 61 ++ sal/rtl/source/strimp.h | 67 -- sal/rtl/source/strimp.hxx | 59 ++ sal/rtl/source/string.c | 323 -------- sal/rtl/source/string.cxx | 327 +++++++++ sal/rtl/source/strtmpl.c | 1567 --------------------------------------- sal/rtl/source/strtmpl.cxx | 1617 +++++++++++++++++++++++++++++++++++++++++ sal/rtl/source/surrogates.h | 53 -- sal/rtl/source/surrogates.hxx | 53 ++ sal/rtl/source/uri.cxx | 2 +- sal/rtl/source/ustrbuf.c | 239 ------ sal/rtl/source/ustrbuf.cxx | 240 ++++++ sal/rtl/source/ustring.c | 983 ------------------------- sal/rtl/source/ustring.cxx | 997 +++++++++++++++++++++++++ 20 files changed, 3552 insertions(+), 3499 deletions(-) delete mode 100644 sal/rtl/source/hash.h create mode 100644 sal/rtl/source/hash.hxx delete mode 100644 sal/rtl/source/strbuf.c create mode 100644 sal/rtl/source/strbuf.cxx delete mode 100644 sal/rtl/source/strimp.c create mode 100644 sal/rtl/source/strimp.cxx delete mode 100644 sal/rtl/source/strimp.h create mode 100644 sal/rtl/source/strimp.hxx delete mode 100644 sal/rtl/source/string.c create mode 100644 sal/rtl/source/string.cxx delete mode 100644 sal/rtl/source/strtmpl.c create mode 100644 sal/rtl/source/strtmpl.cxx delete mode 100644 sal/rtl/source/surrogates.h create mode 100644 sal/rtl/source/surrogates.hxx delete mode 100644 sal/rtl/source/ustrbuf.c create mode 100644 sal/rtl/source/ustrbuf.cxx delete mode 100644 sal/rtl/source/ustring.c create mode 100644 sal/rtl/source/ustring.cxx (limited to 'sal') diff --git a/sal/rtl/source/hash.cxx b/sal/rtl/source/hash.cxx index 4e03dfc2a6d7..8ddf2683ad53 100644 --- a/sal/rtl/source/hash.cxx +++ b/sal/rtl/source/hash.cxx @@ -29,8 +29,8 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sal.hxx" -#include "hash.h" -#include "strimp.h" +#include "hash.hxx" +#include "strimp.hxx" #include #include diff --git a/sal/rtl/source/hash.h b/sal/rtl/source/hash.h deleted file mode 100644 index 6a6518833dfd..000000000000 --- a/sal/rtl/source/hash.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -#ifndef INCLUDED_RTL_SOURCE_HASH_H -#define INCLUDED_RTL_SOURCE_HASH_H - -#include -#include - -#if defined __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* These functions are not multi-thread safe: */ - -rtl_uString *rtl_str_hash_intern (rtl_uString *pString, - int can_return); -void rtl_str_hash_remove (rtl_uString *pString); - -#if defined __cplusplus -} -#endif /* __cplusplus */ - -#endif /* INCLUDED_RTL_SOURCE_HASH_H */ - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/rtl/source/hash.hxx b/sal/rtl/source/hash.hxx new file mode 100644 index 000000000000..d103efcd64e7 --- /dev/null +++ b/sal/rtl/source/hash.hxx @@ -0,0 +1,16 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +#ifndef INCLUDED_RTL_SOURCE_HASH_HXX +#define INCLUDED_RTL_SOURCE_HASH_HXX + +#include +#include + +/* These functions are not multi-thread safe: */ + +rtl_uString *rtl_str_hash_intern (rtl_uString *pString, + int can_return); +void rtl_str_hash_remove (rtl_uString *pString); + +#endif /* INCLUDED_RTL_SOURCE_HASH_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/rtl/source/strbuf.c b/sal/rtl/source/strbuf.c deleted file mode 100644 index c9a4f3140643..000000000000 --- a/sal/rtl/source/strbuf.c +++ /dev/null @@ -1,179 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#include - -#ifndef _RTL_STRING_HXX_ -#include -#endif -#include - -/* -#include -*/ - - - -/************************************************************************* - * rtl_stringbuffer_newFromStr_WithLength - */ -void SAL_CALL rtl_stringbuffer_newFromStr_WithLength( rtl_String ** newStr, - const sal_Char * value, - sal_Int32 count ) -{ - if (!value) - { - rtl_string_new_WithLength( newStr, 16 ); - return; - } - - rtl_string_new_WithLength( newStr, count + 16 ); - (*newStr)->length = count; - rtl_copyMemory( (*newStr)->buffer, value, count ); - return; -} - -/************************************************************************* - * rtl_stringbuffer_newFromStringBuffer - */ -sal_Int32 SAL_CALL rtl_stringbuffer_newFromStringBuffer( rtl_String ** newStr, - sal_Int32 capacity, - rtl_String * oldStr ) -{ - sal_Int32 newCapacity = capacity; - - if (newCapacity < oldStr->length) - newCapacity = oldStr->length; - - rtl_string_new_WithLength( newStr, newCapacity ); - if (oldStr->length > 0) { - (*newStr)->length = oldStr->length; - rtl_copyMemory( (*newStr)->buffer, oldStr->buffer, oldStr->length ); - } - return newCapacity; -} - -/************************************************************************* - * rtl_stringbuffer_ensureCapacity - */ -void SAL_CALL rtl_stringbuffer_ensureCapacity - (rtl_String ** This, sal_Int32* capacity, sal_Int32 minimumCapacity) -{ - if (minimumCapacity > *capacity) - { - rtl_String * pTmp = *This; - rtl_String * pNew = NULL; - *capacity = ((*This)->length + 1) * 2; - if (minimumCapacity > *capacity) - /* still lower, set to the minimum capacity */ - *capacity = minimumCapacity; - - rtl_string_new_WithLength(&pNew, *capacity); - pNew->length = (*This)->length; - *This = pNew; - - rtl_copyMemory( (*This)->buffer, pTmp->buffer, pTmp->length ); - rtl_string_release( pTmp ); - } -} - -/************************************************************************* - * rtl_stringbuffer_insert - */ -void SAL_CALL rtl_stringbuffer_insert( rtl_String ** This, - sal_Int32 * capacity, - sal_Int32 offset, - const sal_Char * str, - sal_Int32 len ) -{ - sal_Int32 nOldLen; - sal_Char * pBuf; - sal_Int32 n; - if( len != 0 ) - { - if (*capacity < (*This)->length + len) - rtl_stringbuffer_ensureCapacity( This, capacity, (*This)->length + len ); - - /* - if( len == 1 ) - This->buffer - */ - nOldLen = (*This)->length; - pBuf = (*This)->buffer; - - /* copy the tail */ - n = (nOldLen - offset); - if( n == 1 ) - /* optimized for 1 character */ - pBuf[offset + len] = pBuf[offset]; - else if( n > 1 ) - rtl_moveMemory( pBuf + offset + len, pBuf + offset, n * sizeof(sal_Char) ); - - /* insert the new characters */ - n = len; - if( len == 1 ) - /* optimized for 1 character */ - pBuf[offset] = *str; - else if( n > 1 ) - rtl_copyMemory( pBuf + offset, str, len * sizeof(sal_Char) ); - (*This)->length = nOldLen + len; - pBuf[ nOldLen + len ] = 0; - } -} - -/************************************************************************* - * rtl_stringbuffer_remove - */ -void SAL_CALL rtl_stringbuffer_remove( rtl_String ** This, - sal_Int32 start, - sal_Int32 len ) -{ - sal_Int32 nTailLen; - sal_Char * pBuf; - - if (len > (*This)->length - start) - len = (*This)->length - start; - - //remove nothing - if (!len) - return; - - pBuf = (*This)->buffer; - nTailLen = (*This)->length - ( start + len ); - - if (nTailLen) - { - /* move the tail */ - rtl_moveMemory(pBuf + start, pBuf + start + len, nTailLen * sizeof(sal_Char)); - } - - (*This)->length-=len; - pBuf[ (*This)->length ] = 0; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/rtl/source/strbuf.cxx b/sal/rtl/source/strbuf.cxx new file mode 100644 index 000000000000..c9a4f3140643 --- /dev/null +++ b/sal/rtl/source/strbuf.cxx @@ -0,0 +1,179 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include + +#ifndef _RTL_STRING_HXX_ +#include +#endif +#include + +/* +#include +*/ + + + +/************************************************************************* + * rtl_stringbuffer_newFromStr_WithLength + */ +void SAL_CALL rtl_stringbuffer_newFromStr_WithLength( rtl_String ** newStr, + const sal_Char * value, + sal_Int32 count ) +{ + if (!value) + { + rtl_string_new_WithLength( newStr, 16 ); + return; + } + + rtl_string_new_WithLength( newStr, count + 16 ); + (*newStr)->length = count; + rtl_copyMemory( (*newStr)->buffer, value, count ); + return; +} + +/************************************************************************* + * rtl_stringbuffer_newFromStringBuffer + */ +sal_Int32 SAL_CALL rtl_stringbuffer_newFromStringBuffer( rtl_String ** newStr, + sal_Int32 capacity, + rtl_String * oldStr ) +{ + sal_Int32 newCapacity = capacity; + + if (newCapacity < oldStr->length) + newCapacity = oldStr->length; + + rtl_string_new_WithLength( newStr, newCapacity ); + if (oldStr->length > 0) { + (*newStr)->length = oldStr->length; + rtl_copyMemory( (*newStr)->buffer, oldStr->buffer, oldStr->length ); + } + return newCapacity; +} + +/************************************************************************* + * rtl_stringbuffer_ensureCapacity + */ +void SAL_CALL rtl_stringbuffer_ensureCapacity + (rtl_String ** This, sal_Int32* capacity, sal_Int32 minimumCapacity) +{ + if (minimumCapacity > *capacity) + { + rtl_String * pTmp = *This; + rtl_String * pNew = NULL; + *capacity = ((*This)->length + 1) * 2; + if (minimumCapacity > *capacity) + /* still lower, set to the minimum capacity */ + *capacity = minimumCapacity; + + rtl_string_new_WithLength(&pNew, *capacity); + pNew->length = (*This)->length; + *This = pNew; + + rtl_copyMemory( (*This)->buffer, pTmp->buffer, pTmp->length ); + rtl_string_release( pTmp ); + } +} + +/************************************************************************* + * rtl_stringbuffer_insert + */ +void SAL_CALL rtl_stringbuffer_insert( rtl_String ** This, + sal_Int32 * capacity, + sal_Int32 offset, + const sal_Char * str, + sal_Int32 len ) +{ + sal_Int32 nOldLen; + sal_Char * pBuf; + sal_Int32 n; + if( len != 0 ) + { + if (*capacity < (*This)->length + len) + rtl_stringbuffer_ensureCapacity( This, capacity, (*This)->length + len ); + + /* + if( len == 1 ) + This->buffer + */ + nOldLen = (*This)->length; + pBuf = (*This)->buffer; + + /* copy the tail */ + n = (nOldLen - offset); + if( n == 1 ) + /* optimized for 1 character */ + pBuf[offset + len] = pBuf[offset]; + else if( n > 1 ) + rtl_moveMemory( pBuf + offset + len, pBuf + offset, n * sizeof(sal_Char) ); + + /* insert the new characters */ + n = len; + if( len == 1 ) + /* optimized for 1 character */ + pBuf[offset] = *str; + else if( n > 1 ) + rtl_copyMemory( pBuf + offset, str, len * sizeof(sal_Char) ); + (*This)->length = nOldLen + len; + pBuf[ nOldLen + len ] = 0; + } +} + +/************************************************************************* + * rtl_stringbuffer_remove + */ +void SAL_CALL rtl_stringbuffer_remove( rtl_String ** This, + sal_Int32 start, + sal_Int32 len ) +{ + sal_Int32 nTailLen; + sal_Char * pBuf; + + if (len > (*This)->length - start) + len = (*This)->length - start; + + //remove nothing + if (!len) + return; + + pBuf = (*This)->buffer; + nTailLen = (*This)->length - ( start + len ); + + if (nTailLen) + { + /* move the tail */ + rtl_moveMemory(pBuf + start, pBuf + start + len, nTailLen * sizeof(sal_Char)); + } + + (*This)->length-=len; + pBuf[ (*This)->length ] = 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/rtl/source/strimp.c b/sal/rtl/source/strimp.c deleted file mode 100644 index ae75249fb4aa..000000000000 --- a/sal/rtl/source/strimp.c +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#include "strimp.h" - -sal_Int16 rtl_ImplGetDigit( sal_Unicode ch, sal_Int16 nRadix ) -{ - sal_Int16 n = -1; - if ( (ch >= '0') && (ch <= '9') ) - n = ch-'0'; - else if ( (ch >= 'a') && (ch <= 'z') ) - n = ch-'a'+10; - else if ( (ch >= 'A') && (ch <= 'Z') ) - n = ch-'A'+10; - return (n < nRadix) ? n : -1; -} - -sal_Bool rtl_ImplIsWhitespace( sal_Unicode c ) -{ - /* Space or Control character? */ - if ( (c <= 32) && c ) - return sal_True; - - /* Only in the General Punctuation area Space or Control characters are included? */ - if ( (c < 0x2000) || (c > 0x206F) ) - return sal_False; - - if ( ((c >= 0x2000) && (c <= 0x200B)) || /* All Spaces */ - (c == 0x2028) || /* LINE SEPARATOR */ - (c == 0x2029) ) /* PARAGRAPH SEPARATOR */ - return sal_True; - - return sal_False; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/rtl/source/strimp.cxx b/sal/rtl/source/strimp.cxx new file mode 100644 index 000000000000..a5b8f827a1b8 --- /dev/null +++ b/sal/rtl/source/strimp.cxx @@ -0,0 +1,61 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "strimp.hxx" + +sal_Int16 rtl_ImplGetDigit( sal_Unicode ch, sal_Int16 nRadix ) +{ + sal_Int16 n = -1; + if ( (ch >= '0') && (ch <= '9') ) + n = ch-'0'; + else if ( (ch >= 'a') && (ch <= 'z') ) + n = ch-'a'+10; + else if ( (ch >= 'A') && (ch <= 'Z') ) + n = ch-'A'+10; + return (n < nRadix) ? n : -1; +} + +sal_Bool rtl_ImplIsWhitespace( sal_Unicode c ) +{ + /* Space or Control character? */ + if ( (c <= 32) && c ) + return sal_True; + + /* Only in the General Punctuation area Space or Control characters are included? */ + if ( (c < 0x2000) || (c > 0x206F) ) + return sal_False; + + if ( ((c >= 0x2000) && (c <= 0x200B)) || /* All Spaces */ + (c == 0x2028) || /* LINE SEPARATOR */ + (c == 0x2029) ) /* PARAGRAPH SEPARATOR */ + return sal_True; + + return sal_False; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/rtl/source/strimp.h b/sal/rtl/source/strimp.h deleted file mode 100644 index 3db89cec8145..000000000000 --- a/sal/rtl/source/strimp.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#ifndef INCLUDED_RTL_SOURCE_STRIMP_H -#define INCLUDED_RTL_SOURCE_STRIMP_H - -#include - -#include "sal/types.h" - -/* ======================================================================= */ -/* Help functions for String and UString */ -/* ======================================================================= */ - -#if defined __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * refCount is opaqueincludes 2 bit-fields; - * MSB: 'interned' - is stored in the intern hash - * MSB-1: 'static' - is a const / static string, - * do no ref counting - */ -#define SAL_STRING_INTERN_FLAG 0x80000000 -#define SAL_STRING_STATIC_FLAG 0x40000000 -#define SAL_STRING_REFCOUNT(a) ((a) & 0x3fffffff) - -#define SAL_STRING_IS_INTERN(a) ((a)->refCount & SAL_STRING_INTERN_FLAG) -#define SAL_STRING_IS_STATIC(a) ((a)->refCount & SAL_STRING_STATIC_FLAG) - -sal_Int16 rtl_ImplGetDigit( sal_Unicode ch, sal_Int16 nRadix ); - -sal_Bool rtl_ImplIsWhitespace( sal_Unicode c ); - -#if defined __cplusplus -} -#endif /* __cplusplus */ - -#endif /* INCLUDED_RTL_SOURCE_STRIMP_H */ - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/rtl/source/strimp.hxx b/sal/rtl/source/strimp.hxx new file mode 100644 index 000000000000..a9e5a38f6da7 --- /dev/null +++ b/sal/rtl/source/strimp.hxx @@ -0,0 +1,59 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_RTL_SOURCE_STRIMP_HXX +#define INCLUDED_RTL_SOURCE_STRIMP_HXX + +#include + +#include "sal/types.h" + +/* ======================================================================= */ +/* Help functions for String and UString */ +/* ======================================================================= */ + +/* + * refCount is opaqueincludes 2 bit-fields; + * MSB: 'interned' - is stored in the intern hash + * MSB-1: 'static' - is a const / static string, + * do no ref counting + */ +#define SAL_STRING_INTERN_FLAG 0x80000000 +#define SAL_STRING_STATIC_FLAG 0x40000000 +#define SAL_STRING_REFCOUNT(a) ((a) & 0x3fffffff) + +#define SAL_STRING_IS_INTERN(a) ((a)->refCount & SAL_STRING_INTERN_FLAG) +#define SAL_STRING_IS_STATIC(a) ((a)->refCount & SAL_STRING_STATIC_FLAG) + +sal_Int16 rtl_ImplGetDigit( sal_Unicode ch, sal_Int16 nRadix ); + +sal_Bool rtl_ImplIsWhitespace( sal_Unicode c ); + +#endif /* INCLUDED_RTL_SOURCE_STRIMP_HXX */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/rtl/source/string.c b/sal/rtl/source/string.c deleted file mode 100644 index 2ee79611218a..000000000000 --- a/sal/rtl/source/string.c +++ /dev/null @@ -1,323 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ -#if defined(_MSC_VER) && (_MSC_VER >= 1400) -#pragma warning(disable:4738) // storing 32-bit float result in memory, possible loss of performance -#endif - -#include -#include -#include -#include -#include - -#include "strimp.h" -#include "surrogates.h" -#include - -#include "rtl/math.h" -#include "rtl/tencinfo.h" - -/* ======================================================================= */ - -/* static data to be referenced by all empty strings - * the refCount is predefined to 1 and must never become 0 ! - */ -static rtl_String const aImplEmpty_rtl_String = -{ - SAL_STRING_STATIC_FLAG|1, - /* sal_Int32 refCount; */ - 0, /* sal_Int32 length; */ - { 0 } /* sal_Char buffer[1]; */ -}; - -/* ======================================================================= */ - -#define IMPL_RTL_STRCODE sal_Char -#define IMPL_RTL_USTRCODE( c ) ((unsigned char)c) -#define IMPL_RTL_STRNAME( n ) rtl_str_ ## n - -#define IMPL_RTL_STRINGNAME( n ) rtl_string_ ## n -#define IMPL_RTL_STRINGDATA rtl_String -#define IMPL_RTL_EMPTYSTRING aImplEmpty_rtl_String - -/* ======================================================================= */ - -/* Include String/UString template code */ - -#include "strtmpl.c" - -sal_Int32 SAL_CALL rtl_str_valueOfFloat(sal_Char * pStr, float f) -{ - rtl_String * pResult = NULL; - sal_Int32 nLen; - rtl_math_doubleToString( - &pResult, 0, 0, f, rtl_math_StringFormat_G, - RTL_STR_MAX_VALUEOFFLOAT - RTL_CONSTASCII_LENGTH("-x.E-xxx"), '.', 0, 0, - sal_True); - nLen = pResult->length; - OSL_ASSERT(nLen < RTL_STR_MAX_VALUEOFFLOAT); - rtl_copyMemory(pStr, pResult->buffer, (nLen + 1) * sizeof(sal_Char)); - rtl_string_release(pResult); - return nLen; -} - -sal_Int32 SAL_CALL rtl_str_valueOfDouble(sal_Char * pStr, double d) -{ - rtl_String * pResult = NULL; - sal_Int32 nLen; - rtl_math_doubleToString( - &pResult, 0, 0, d, rtl_math_StringFormat_G, - RTL_STR_MAX_VALUEOFDOUBLE - RTL_CONSTASCII_LENGTH("-x.E-xxx"), '.', 0, - 0, sal_True); - nLen = pResult->length; - OSL_ASSERT(nLen < RTL_STR_MAX_VALUEOFDOUBLE); - rtl_copyMemory(pStr, pResult->buffer, (nLen + 1) * sizeof(sal_Char)); - rtl_string_release(pResult); - return nLen; -} - -float SAL_CALL rtl_str_toFloat(sal_Char const * pStr) -{ - return (float) rtl_math_stringToDouble(pStr, pStr + rtl_str_getLength(pStr), - '.', 0, 0, 0); -} - -double SAL_CALL rtl_str_toDouble(sal_Char const * pStr) -{ - return rtl_math_stringToDouble(pStr, pStr + rtl_str_getLength(pStr), '.', 0, - 0, 0); -} - -/* ======================================================================= */ - -static int rtl_ImplGetFastUTF8ByteLen( const sal_Unicode* pStr, sal_Int32 nLen ) -{ - int n; - sal_Unicode c; - sal_uInt32 nUCS4Char; - const sal_Unicode* pEndStr; - - n = 0; - pEndStr = pStr+nLen; - while ( pStr < pEndStr ) - { - c = *pStr; - - if ( c < 0x80 ) - n++; - else if ( c < 0x800 ) - n += 2; - else - { - if ( !SAL_RTL_IS_HIGH_SURROGATE(c) ) - n += 3; - else - { - nUCS4Char = c; - - if ( pStr+1 < pEndStr ) - { - c = *(pStr+1); - if ( SAL_RTL_IS_LOW_SURROGATE(c) ) - { - nUCS4Char = SAL_RTL_COMBINE_SURROGATES(nUCS4Char, c); - pStr++; - } - } - - if ( nUCS4Char < 0x10000 ) - n += 3; - else if ( nUCS4Char < 0x200000 ) - n += 4; - else if ( nUCS4Char < 0x4000000 ) - n += 5; - else - n += 6; - } - } - - pStr++; - } - - return n; -} - -/* ----------------------------------------------------------------------- */ - -sal_Bool SAL_CALL rtl_impl_convertUStringToString(rtl_String ** pTarget, - sal_Unicode const * pSource, - sal_Int32 nLength, - rtl_TextEncoding nEncoding, - sal_uInt32 nFlags, - sal_Bool bCheckErrors) -{ - OSL_ASSERT(pTarget != NULL - && (pSource != NULL || nLength == 0) - && nLength >= 0 - && (nLength == 0 || rtl_isOctetTextEncoding(nEncoding))); - - if ( !nLength ) - rtl_string_new( pTarget ); - else - { - rtl_String* pTemp; - rtl_UnicodeToTextConverter hConverter; - sal_uInt32 nInfo; - sal_Size nSrcChars; - sal_Size nDestBytes; - sal_Size nNewLen; - sal_Size nNotConvertedChars; - sal_Size nMaxCharLen; - - /* Optimization for UTF-8 - we try to calculate the exact length */ - /* For all other encoding we try an good estimation */ - if ( nEncoding == RTL_TEXTENCODING_UTF8 ) - { - nNewLen = rtl_ImplGetFastUTF8ByteLen( pSource, nLength ); - /* Includes the string only ASCII, then we could copy - the buffer faster */ - if ( nNewLen == (sal_Size)nLength ) - { - IMPL_RTL_STRCODE* pBuffer; - if ( *pTarget ) - IMPL_RTL_STRINGNAME( release )( *pTarget ); - *pTarget = IMPL_RTL_STRINGNAME( ImplAlloc )( nLength ); - OSL_ASSERT(*pTarget != NULL); - pBuffer = (*pTarget)->buffer; - do - { - /* Check ASCII range */ - OSL_ENSURE( *pSource <= 127, - "rtl_uString2String() - UTF8 test is encoding is wrong" ); - - *pBuffer = (IMPL_RTL_STRCODE)(unsigned char)*pSource; - pBuffer++; - pSource++; - nLength--; - } - while ( nLength ); - return sal_True; - } - - nMaxCharLen = 4; - } - else - { - rtl_TextEncodingInfo aTextEncInfo; - aTextEncInfo.StructSize = sizeof( aTextEncInfo ); - if ( !rtl_getTextEncodingInfo( nEncoding, &aTextEncInfo ) ) - { - aTextEncInfo.AverageCharSize = 1; - aTextEncInfo.MaximumCharSize = 8; - } - - nNewLen = nLength*aTextEncInfo.AverageCharSize; - nMaxCharLen = aTextEncInfo.MaximumCharSize; - } - - nFlags |= RTL_UNICODETOTEXT_FLAGS_FLUSH; - hConverter = rtl_createUnicodeToTextConverter( nEncoding ); - - for (;;) - { - pTemp = IMPL_RTL_STRINGNAME( ImplAlloc )( nNewLen ); - OSL_ASSERT(pTemp != NULL); - nDestBytes = rtl_convertUnicodeToText( hConverter, 0, - pSource, nLength, - pTemp->buffer, nNewLen, - nFlags, - &nInfo, &nSrcChars ); - if (bCheckErrors && (nInfo & RTL_UNICODETOTEXT_INFO_ERROR) != 0) - { - rtl_freeMemory(pTemp); - rtl_destroyUnicodeToTextConverter(hConverter); - return sal_False; - } - - if ((nInfo & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL) == 0) - break; - - /* Buffer not big enough, try again with enough space */ - rtl_freeMemory( pTemp ); - - /* Try with the max. count of characters with - additional overhead for replacing functionality */ - nNotConvertedChars = nLength-nSrcChars; - nNewLen = nDestBytes+(nNotConvertedChars*nMaxCharLen)+nNotConvertedChars+4; - } - - /* Set the buffer to the correct size or is there to - much overhead, reallocate to the correct size */ - if ( nNewLen > nDestBytes+8 ) - { - rtl_String* pTemp2 = IMPL_RTL_STRINGNAME( ImplAlloc )( nDestBytes ); - OSL_ASSERT(pTemp2 != NULL); - rtl_str_ImplCopy( pTemp2->buffer, pTemp->buffer, nDestBytes ); - rtl_freeMemory( pTemp ); - pTemp = pTemp2; - } - else - { - pTemp->length = nDestBytes; - pTemp->buffer[nDestBytes] = 0; - } - - rtl_destroyUnicodeToTextConverter( hConverter ); - if ( *pTarget ) - IMPL_RTL_STRINGNAME( release )( *pTarget ); - *pTarget = pTemp; - - /* Results the conversion in an empty buffer - - create an empty string */ - if ( pTemp && !nDestBytes ) - rtl_string_new( pTarget ); - } - return sal_True; -} - -void SAL_CALL rtl_uString2String( rtl_String** ppThis, - const sal_Unicode* pUStr, - sal_Int32 nULen, - rtl_TextEncoding eTextEncoding, - sal_uInt32 nCvtFlags ) -{ - rtl_impl_convertUStringToString(ppThis, pUStr, nULen, eTextEncoding, - nCvtFlags, sal_False); -} - -sal_Bool SAL_CALL rtl_convertUStringToString(rtl_String ** pTarget, - sal_Unicode const * pSource, - sal_Int32 nLength, - rtl_TextEncoding nEncoding, - sal_uInt32 nFlags) -{ - return rtl_impl_convertUStringToString(pTarget, pSource, nLength, nEncoding, - nFlags, sal_True); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/rtl/source/string.cxx b/sal/rtl/source/string.cxx new file mode 100644 index 000000000000..c43b564a2099 --- /dev/null +++ b/sal/rtl/source/string.cxx @@ -0,0 +1,327 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#pragma warning(disable:4738) // storing 32-bit float result in memory, possible loss of performance +#endif + +#include +#include +#include +#include +#include + +#include "strimp.hxx" +#include "surrogates.hxx" +#include + +#include "rtl/math.h" +#include "rtl/tencinfo.h" + +/* ======================================================================= */ + +/* static data to be referenced by all empty strings + * the refCount is predefined to 1 and must never become 0 ! + */ +static rtl_String const aImplEmpty_rtl_String = +{ + SAL_STRING_STATIC_FLAG|1, + /* sal_Int32 refCount; */ + 0, /* sal_Int32 length; */ + { 0 } /* sal_Char buffer[1]; */ +}; + +/* ======================================================================= */ + +#define IMPL_RTL_STRCODE sal_Char +#define IMPL_RTL_USTRCODE( c ) ((unsigned char)c) +#define IMPL_RTL_STRNAME( n ) rtl_str_ ## n + +#define IMPL_RTL_STRINGNAME( n ) rtl_string_ ## n +#define IMPL_RTL_STRINGDATA rtl_String +#define IMPL_RTL_EMPTYSTRING aImplEmpty_rtl_String + +/* ======================================================================= */ + +/* Include String/UString template code */ + +#include "strtmpl.cxx" + +sal_Int32 SAL_CALL rtl_str_valueOfFloat(sal_Char * pStr, float f) + SAL_THROW_EXTERN_C() +{ + rtl_String * pResult = NULL; + sal_Int32 nLen; + rtl_math_doubleToString( + &pResult, 0, 0, f, rtl_math_StringFormat_G, + RTL_STR_MAX_VALUEOFFLOAT - RTL_CONSTASCII_LENGTH("-x.E-xxx"), '.', 0, 0, + sal_True); + nLen = pResult->length; + OSL_ASSERT(nLen < RTL_STR_MAX_VALUEOFFLOAT); + rtl_copyMemory(pStr, pResult->buffer, (nLen + 1) * sizeof(sal_Char)); + rtl_string_release(pResult); + return nLen; +} + +sal_Int32 SAL_CALL rtl_str_valueOfDouble(sal_Char * pStr, double d) + SAL_THROW_EXTERN_C() +{ + rtl_String * pResult = NULL; + sal_Int32 nLen; + rtl_math_doubleToString( + &pResult, 0, 0, d, rtl_math_StringFormat_G, + RTL_STR_MAX_VALUEOFDOUBLE - RTL_CONSTASCII_LENGTH("-x.E-xxx"), '.', 0, + 0, sal_True); + nLen = pResult->length; + OSL_ASSERT(nLen < RTL_STR_MAX_VALUEOFDOUBLE); + rtl_copyMemory(pStr, pResult->buffer, (nLen + 1) * sizeof(sal_Char)); + rtl_string_release(pResult); + return nLen; +} + +float SAL_CALL rtl_str_toFloat(sal_Char const * pStr) SAL_THROW_EXTERN_C() +{ + return (float) rtl_math_stringToDouble(pStr, pStr + rtl_str_getLength(pStr), + '.', 0, 0, 0); +} + +double SAL_CALL rtl_str_toDouble(sal_Char const * pStr) SAL_THROW_EXTERN_C() +{ + return rtl_math_stringToDouble(pStr, pStr + rtl_str_getLength(pStr), '.', 0, + 0, 0); +} + +/* ======================================================================= */ + +static int rtl_ImplGetFastUTF8ByteLen( const sal_Unicode* pStr, sal_Int32 nLen ) +{ + int n; + sal_Unicode c; + sal_uInt32 nUCS4Char; + const sal_Unicode* pEndStr; + + n = 0; + pEndStr = pStr+nLen; + while ( pStr < pEndStr ) + { + c = *pStr; + + if ( c < 0x80 ) + n++; + else if ( c < 0x800 ) + n += 2; + else + { + if ( !SAL_RTL_IS_HIGH_SURROGATE(c) ) + n += 3; + else + { + nUCS4Char = c; + + if ( pStr+1 < pEndStr ) + { + c = *(pStr+1); + if ( SAL_RTL_IS_LOW_SURROGATE(c) ) + { + nUCS4Char = SAL_RTL_COMBINE_SURROGATES(nUCS4Char, c); + pStr++; + } + } + + if ( nUCS4Char < 0x10000 ) + n += 3; + else if ( nUCS4Char < 0x200000 ) + n += 4; + else if ( nUCS4Char < 0x4000000 ) + n += 5; + else + n += 6; + } + } + + pStr++; + } + + return n; +} + +/* ----------------------------------------------------------------------- */ + +sal_Bool SAL_CALL rtl_impl_convertUStringToString(rtl_String ** pTarget, + sal_Unicode const * pSource, + sal_Int32 nLength, + rtl_TextEncoding nEncoding, + sal_uInt32 nFlags, + sal_Bool bCheckErrors) +{ + OSL_ASSERT(pTarget != NULL + && (pSource != NULL || nLength == 0) + && nLength >= 0 + && (nLength == 0 || rtl_isOctetTextEncoding(nEncoding))); + + if ( !nLength ) + rtl_string_new( pTarget ); + else + { + rtl_String* pTemp; + rtl_UnicodeToTextConverter hConverter; + sal_uInt32 nInfo; + sal_Size nSrcChars; + sal_Size nDestBytes; + sal_Size nNewLen; + sal_Size nNotConvertedChars; + sal_Size nMaxCharLen; + + /* Optimization for UTF-8 - we try to calculate the exact length */ + /* For all other encoding we try an good estimation */ + if ( nEncoding == RTL_TEXTENCODING_UTF8 ) + { + nNewLen = rtl_ImplGetFastUTF8ByteLen( pSource, nLength ); + /* Includes the string only ASCII, then we could copy + the buffer faster */ + if ( nNewLen == (sal_Size)nLength ) + { + IMPL_RTL_STRCODE* pBuffer; + if ( *pTarget ) + IMPL_RTL_STRINGNAME( release )( *pTarget ); + *pTarget = IMPL_RTL_STRINGNAME( ImplAlloc )( nLength ); + OSL_ASSERT(*pTarget != NULL); + pBuffer = (*pTarget)->buffer; + do + { + /* Check ASCII range */ + OSL_ENSURE( *pSource <= 127, + "rtl_uString2String() - UTF8 test is encoding is wrong" ); + + *pBuffer = (IMPL_RTL_STRCODE)(unsigned char)*pSource; + pBuffer++; + pSource++; + nLength--; + } + while ( nLength ); + return sal_True; + } + + nMaxCharLen = 4; + } + else + { + rtl_TextEncodingInfo aTextEncInfo; + aTextEncInfo.StructSize = sizeof( aTextEncInfo ); + if ( !rtl_getTextEncodingInfo( nEncoding, &aTextEncInfo ) ) + { + aTextEncInfo.AverageCharSize = 1; + aTextEncInfo.MaximumCharSize = 8; + } + + nNewLen = nLength*aTextEncInfo.AverageCharSize; + nMaxCharLen = aTextEncInfo.MaximumCharSize; + } + + nFlags |= RTL_UNICODETOTEXT_FLAGS_FLUSH; + hConverter = rtl_createUnicodeToTextConverter( nEncoding ); + + for (;;) + { + pTemp = IMPL_RTL_STRINGNAME( ImplAlloc )( nNewLen ); + OSL_ASSERT(pTemp != NULL); + nDestBytes = rtl_convertUnicodeToText( hConverter, 0, + pSource, nLength, + pTemp->buffer, nNewLen, + nFlags, + &nInfo, &nSrcChars ); + if (bCheckErrors && (nInfo & RTL_UNICODETOTEXT_INFO_ERROR) != 0) + { + rtl_freeMemory(pTemp); + rtl_destroyUnicodeToTextConverter(hConverter); + return sal_False; + } + + if ((nInfo & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL) == 0) + break; + + /* Buffer not big enough, try again with enough space */ + rtl_freeMemory( pTemp ); + + /* Try with the max. count of characters with + additional overhead for replacing functionality */ + nNotConvertedChars = nLength-nSrcChars; + nNewLen = nDestBytes+(nNotConvertedChars*nMaxCharLen)+nNotConvertedChars+4; + } + + /* Set the buffer to the correct size or is there to + much overhead, reallocate to the correct size */ + if ( nNewLen > nDestBytes+8 ) + { + rtl_String* pTemp2 = IMPL_RTL_STRINGNAME( ImplAlloc )( nDestBytes ); + OSL_ASSERT(pTemp2 != NULL); + rtl_str_ImplCopy( pTemp2->buffer, pTemp->buffer, nDestBytes ); + rtl_freeMemory( pTemp ); + pTemp = pTemp2; + } + else + { + pTemp->length = nDestBytes; + pTemp->buffer[nDestBytes] = 0; + } + + rtl_destroyUnicodeToTextConverter( hConverter ); + if ( *pTarget ) + IMPL_RTL_STRINGNAME( release )( *pTarget ); + *pTarget = pTemp; + + /* Results the conversion in an empty buffer - + create an empty string */ + if ( pTemp && !nDestBytes ) + rtl_string_new( pTarget ); + } + return sal_True; +} + +void SAL_CALL rtl_uString2String( rtl_String** ppThis, + const sal_Unicode* pUStr, + sal_Int32 nULen, + rtl_TextEncoding eTextEncoding, + sal_uInt32 nCvtFlags ) + SAL_THROW_EXTERN_C() +{ + rtl_impl_convertUStringToString(ppThis, pUStr, nULen, eTextEncoding, + nCvtFlags, sal_False); +} + +sal_Bool SAL_CALL rtl_convertUStringToString(rtl_String ** pTarget, + sal_Unicode const * pSource, + sal_Int32 nLength, + rtl_TextEncoding nEncoding, + sal_uInt32 nFlags) + SAL_THROW_EXTERN_C() +{ + return rtl_impl_convertUStringToString(pTarget, pSource, nLength, nEncoding, + nFlags, sal_True); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/rtl/source/strtmpl.c b/sal/rtl/source/strtmpl.c deleted file mode 100644 index 830521d7b94f..000000000000 --- a/sal/rtl/source/strtmpl.c +++ /dev/null @@ -1,1567 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -/* ======================================================================= */ -/* Internal C-String help functions which could be used without the */ -/* String-Class */ -/* ======================================================================= */ - -#include - -/* -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--; - } -} -*/ - -#define rtl_str_ImplCopy( _pDest, _pSrc, _nCount ) \ -{ \ - IMPL_RTL_STRCODE* __mm_pDest = _pDest; \ - const IMPL_RTL_STRCODE* __mm_pSrc = _pSrc; \ - sal_Int32 __mm_nCount = _nCount; \ - while ( __mm_nCount > 0 ) \ - { \ - *__mm_pDest = *__mm_pSrc; \ - __mm_pDest++; \ - __mm_pSrc++; \ - __mm_nCount--; \ - } \ -} - -/* ======================================================================= */ -/* C-String functions which could be used without the String-Class */ -/* ======================================================================= */ - -sal_Int32 SAL_CALL IMPL_RTL_STRNAME( getLength )( const IMPL_RTL_STRCODE* pStr ) -{ - const IMPL_RTL_STRCODE* pTempStr = pStr; - while( *pTempStr ) - pTempStr++; - return pTempStr-pStr; -} - -/* ----------------------------------------------------------------------- */ - -sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compare )( const IMPL_RTL_STRCODE* pStr1, - const IMPL_RTL_STRCODE* pStr2 ) -{ - sal_Int32 nRet; - while ( ((nRet = ((sal_Int32)(IMPL_RTL_USTRCODE(*pStr1)))- - ((sal_Int32)(IMPL_RTL_USTRCODE(*pStr2)))) == 0) && - *pStr2 ) - { - pStr1++; - pStr2++; - } - - return nRet; -} - -/* ----------------------------------------------------------------------- */ - -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_Int32 nRet = nStr1Len - nStr2Len; - int nCount = (nRet <= 0) ? nStr1Len : nStr2Len; - - --pStr1; - --pStr2; - while( (--nCount >= 0) && (*++pStr1 == *++pStr2) ); - - if( nCount >= 0 ) - nRet = ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr1 ))) - - ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr2 ))); - - return nRet; -} - -/* ----------------------------------------------------------------------- */ - -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 ) -{ - 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 = ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr1 )))- - ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr2 ))); - if ( nRet ) - return nRet; - - nShortenedLength--; - pStr1++; - pStr2++; - } - - if ( nShortenedLength <= 0 ) - return 0; - return nStr1Len - nStr2Len; -} - -/* ----------------------------------------------------------------------- */ - -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 ) -{ - 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 = ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr1Run )))- - ((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_Int32 nRet; - sal_Int32 c1; - sal_Int32 c2; - do - { - /* If character between 'A' and 'Z', than convert it to lowercase */ - c1 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr1 ); - c2 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr2 ); - if ( (c1 >= 65) && (c1 <= 90) ) - c1 += 32; - if ( (c2 >= 65) && (c2 <= 90) ) - c2 += 32; - nRet = c1-c2; - if ( nRet != 0 ) - return nRet; - - pStr1++; - pStr2++; - } - while ( c2 ); - - 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 ) -{ - const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len; - const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len; - sal_Int32 nRet; - sal_Int32 c1; - sal_Int32 c2; - while ( (pStr1 < pStr1End) && (pStr2 < pStr2End) ) - { - /* If character between 'A' and 'Z', than convert it to lowercase */ - c1 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr1 ); - c2 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr2 ); - if ( (c1 >= 65) && (c1 <= 90) ) - c1 += 32; - if ( (c2 >= 65) && (c2 <= 90) ) - c2 += 32; - nRet = c1-c2; - 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 ) -{ - const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len; - const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len; - sal_Int32 nRet; - sal_Int32 c1; - sal_Int32 c2; - while ( (nShortenedLength > 0) && - (pStr1 < pStr1End) && (pStr2 < pStr2End) ) - { - /* If character between 'A' and 'Z', than convert it to lowercase */ - c1 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr1 ); - c2 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr2 ); - if ( (c1 >= 65) && (c1 <= 90) ) - c1 += 32; - if ( (c2 >= 65) && (c2 <= 90) ) - c2 += 32; - nRet = c1-c2; - 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 ) -{ - 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_Int32 h = nLen; - - if ( nLen < 256 ) - { - while ( nLen > 0 ) - { - h = (h*37) + IMPL_RTL_USTRCODE( *pStr ); - pStr++; - nLen--; - } - } - else - { - sal_Int32 nSkip; - const IMPL_RTL_STRCODE* pEndStr = pStr+nLen-5; - - /* only sample some characters */ - /* the first 3, some characters between, and the last 5 */ - h = (h*39) + IMPL_RTL_USTRCODE( *pStr ); - pStr++; - h = (h*39) + IMPL_RTL_USTRCODE( *pStr ); - pStr++; - h = (h*39) + IMPL_RTL_USTRCODE( *pStr ); - pStr++; - - if ( nLen < 32 ) - nSkip = nLen / 4; - else - nSkip = nLen / 8; - nLen -= 8; - while ( nLen > 0 ) - { - h = (h*39) + IMPL_RTL_USTRCODE( *pStr ); - pStr += nSkip; - nLen -= nSkip; - } - - h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr ); - pEndStr++; - h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr ); - pEndStr++; - h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr ); - pEndStr++; - h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr ); - pEndStr++; - h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr ); - } - - return h; -} - -/* ----------------------------------------------------------------------- */ - -sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfChar )( const IMPL_RTL_STRCODE* pStr, - IMPL_RTL_STRCODE c ) -{ - const IMPL_RTL_STRCODE* pTempStr = pStr; - while ( *pTempStr ) - { - if ( *pTempStr == c ) - return pTempStr-pStr; - - pTempStr++; - } - - return -1; -} - -/* ----------------------------------------------------------------------- */ - -sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfChar_WithLength )( const IMPL_RTL_STRCODE* pStr, - sal_Int32 nLen, - IMPL_RTL_STRCODE c ) -{ - const IMPL_RTL_STRCODE* pTempStr = pStr; - while ( nLen > 0 ) - { - if ( *pTempStr == c ) - return pTempStr-pStr; - - pTempStr++; - nLen--; - } - - return -1; -} - -/* ----------------------------------------------------------------------- */ - -sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfChar )( const IMPL_RTL_STRCODE* pStr, - IMPL_RTL_STRCODE c ) -{ - return IMPL_RTL_STRNAME( lastIndexOfChar_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ), c ); -} - -/* ----------------------------------------------------------------------- */ - -sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfChar_WithLength )( const IMPL_RTL_STRCODE* pStr, - sal_Int32 nLen, - IMPL_RTL_STRCODE c ) -{ - 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 ) -{ - return IMPL_RTL_STRNAME( indexOfStr_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ), - pSubStr, IMPL_RTL_STRNAME( getLength )( pSubStr ) ); -} - -/* ----------------------------------------------------------------------- */ - -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 ) -{ - /* faster search for a single character */ - if ( nSubLen < 2 ) - { - /* an empty SubString is always not foundable */ - 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 ) -{ - 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 ) -{ - /* faster search for a single character */ - if ( nSubLen < 2 ) - { - /* an empty SubString is always not foundable */ - 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 ) -{ - 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 ) -{ - while ( nLen > 0 ) - { - if ( *pStr == cOld ) - *pStr = cNew; - - pStr++; - nLen--; - } -} - -/* ----------------------------------------------------------------------- */ - -void SAL_CALL IMPL_RTL_STRNAME( toAsciiLowerCase )( IMPL_RTL_STRCODE* pStr ) -{ - while ( *pStr ) - { - /* Between A-Z (65-90), than to lowercase (+32) */ - if ( (*pStr >= 65) && (*pStr <= 90) ) - *pStr += 32; - - pStr++; - } -} - -/* ----------------------------------------------------------------------- */ - -void SAL_CALL IMPL_RTL_STRNAME( toAsciiLowerCase_WithLength )( IMPL_RTL_STRCODE* pStr, - sal_Int32 nLen ) -{ - while ( nLen > 0 ) - { - /* Between A-Z (65-90), than to lowercase (+32) */ - if ( (*pStr >= 65) && (*pStr <= 90) ) - *pStr += 32; - - pStr++; - nLen--; - } -} - -/* ----------------------------------------------------------------------- */ - -void SAL_CALL IMPL_RTL_STRNAME( toAsciiUpperCase )( IMPL_RTL_STRCODE* pStr ) -{ - while ( *pStr ) - { - /* Between a-z (97-122), than to uppercase (-32) */ - if ( (*pStr >= 97) && (*pStr <= 122) ) - *pStr -= 32; - - pStr++; - } -} - -/* ----------------------------------------------------------------------- */ - -void SAL_CALL IMPL_RTL_STRNAME( toAsciiUpperCase_WithLength )( IMPL_RTL_STRCODE* pStr, - sal_Int32 nLen ) -{ - while ( nLen > 0 ) - { - /* Between a-z (97-122), than to uppercase (-32) */ - if ( (*pStr >= 97) && (*pStr <= 122) ) - *pStr -= 32; - - pStr++; - nLen--; - } -} - -/* ----------------------------------------------------------------------- */ - -sal_Int32 SAL_CALL IMPL_RTL_STRNAME( trim )( IMPL_RTL_STRCODE* pStr ) -{ - 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_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 ) - { - IMPL_RTL_STRCODE* pNewStr = pStr+nPreSpaces; - - nLen -= nPreSpaces; - nIndex = nLen; - - while ( nIndex ) - { - *pStr = *pNewStr; - pStr++; - pNewStr++; - nIndex--; - } - *pStr = 0; - } - - return nLen; -} - -/* ----------------------------------------------------------------------- */ - -sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfBoolean )( IMPL_RTL_STRCODE* pStr, sal_Bool b ) -{ - 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 ) -{ - *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_Char aBuf[RTL_STR_MAX_VALUEOFINT32]; - sal_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 negativ */ - if ( n < 0 ) - { - *pStr = '-'; - pStr++; - nLen++; - nValue = -n; /* FIXME this code is not portable for n == -2147483648 - (smallest negative value for sal_Int32) */ - } - else - nValue = n; - - /* create a recursive buffer with all values, except the last one */ - do - { - sal_Char nDigit = (sal_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_Char aBuf[RTL_STR_MAX_VALUEOFINT64]; - sal_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 negativ */ - if ( n < 0 ) - { - *pStr = '-'; - pStr++; - nLen++; - nValue = -n; /* FIXME this code is not portable for - n == -9223372036854775808 (smallest negative value for - sal_Int64) */ - } - else - nValue = n; - - /* create a recursive buffer with all values, except the last one */ - do - { - sal_Char nDigit = (sal_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 ) -{ - if ( *pStr == '1' ) - return sal_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 sal_True; - } - } - } - - return sal_False; -} - -/* ----------------------------------------------------------------------- */ - -sal_Int32 SAL_CALL IMPL_RTL_STRNAME( toInt32 )( const IMPL_RTL_STRCODE* pStr, - sal_Int16 nRadix ) -{ - sal_Bool bNeg; - sal_Int16 nDigit; - sal_Int32 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++; - - if ( *pStr == '-' ) - { - bNeg = sal_True; - pStr++; - } - else - { - if ( *pStr == '+' ) - pStr++; - bNeg = sal_False; - } - - while ( *pStr ) - { - nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix ); - if ( nDigit < 0 ) - break; - - n *= nRadix; - n += nDigit; - - pStr++; - } - - if ( bNeg ) - return -n; - else - return n; -} - -/* ----------------------------------------------------------------------- */ - -sal_Int64 SAL_CALL IMPL_RTL_STRNAME( toInt64 )( const IMPL_RTL_STRCODE* pStr, - sal_Int16 nRadix ) -{ - sal_Bool bNeg; - sal_Int16 nDigit; - sal_Int64 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++; - - if ( *pStr == '-' ) - { - bNeg = sal_True; - pStr++; - } - else - { - if ( *pStr == '+' ) - pStr++; - bNeg = sal_False; - } - - while ( *pStr ) - { - nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix ); - if ( nDigit < 0 ) - break; - - n *= nRadix; - n += nDigit; - - pStr++; - } - - if ( bNeg ) - return -n; - else - return n; -} - -/* ======================================================================= */ -/* Internal String-Class help functions */ -/* ======================================================================= */ - -static IMPL_RTL_STRINGDATA* IMPL_RTL_STRINGNAME( ImplAlloc )( sal_Int32 nLen ) -{ - IMPL_RTL_STRINGDATA * pData - = (SAL_INT_CAST(sal_uInt32, nLen) - <= ((SAL_MAX_UINT32 - sizeof (IMPL_RTL_STRINGDATA)) - / sizeof (IMPL_RTL_STRCODE))) - ? (IMPL_RTL_STRINGDATA *) rtl_allocateMemory( - sizeof (IMPL_RTL_STRINGDATA) + nLen * sizeof (IMPL_RTL_STRCODE)) - : NULL; - if (pData != NULL) { - 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 ) -{ - IMPL_RTL_STRCODE* pDest; - const IMPL_RTL_STRCODE* pSrc; - IMPL_RTL_STRINGDATA* pData = IMPL_RTL_STRINGNAME( ImplAlloc )( pStr->length ); - OSL_ASSERT(pData != NULL); - - pDest = pData->buffer; - pSrc = pStr->buffer; - while ( nCount > 0 ) - { - *pDest = *pSrc; - pDest++; - pSrc++; - nCount--; - } - - *ppThis = pData; - return pDest; -} - -/* ======================================================================= */ -/* String-Class functions */ -/* ======================================================================= */ - -#define IMPL_RTL_AQUIRE( pThis ) \ -{ \ - if (!SAL_STRING_IS_STATIC (pThis)) \ - osl_incrementInterlockedCount( &((pThis)->refCount) ); \ -} - -/* ----------------------------------------------------------------------- */ - -void SAL_CALL IMPL_RTL_STRINGNAME( acquire )( IMPL_RTL_STRINGDATA* pThis ) -{ - IMPL_RTL_AQUIRE( pThis ); -} - -/* ----------------------------------------------------------------------- */ - -void SAL_CALL IMPL_RTL_STRINGNAME( release )( IMPL_RTL_STRINGDATA* pThis ) -{ - if (SAL_STRING_IS_STATIC (pThis)) - return; - -/* OString doesn't have an 'intern' */ -#ifdef IMPL_RTL_INTERN - if (SAL_STRING_IS_INTERN (pThis)) - { - internRelease (pThis); - return; - } -#endif - - if ( pThis->refCount == 1 || - !osl_decrementInterlockedCount( &(pThis->refCount) ) ) - { - rtl_freeMemory( pThis ); - } -} - -/* ----------------------------------------------------------------------- */ - -void SAL_CALL IMPL_RTL_STRINGNAME( new )( IMPL_RTL_STRINGDATA** ppThis ) -{ - if ( *ppThis) - IMPL_RTL_STRINGNAME( release )( *ppThis ); - - *ppThis = (IMPL_RTL_STRINGDATA*) (&IMPL_RTL_EMPTYSTRING); - IMPL_RTL_AQUIRE( *ppThis ); -} - -/* ----------------------------------------------------------------------- */ - -void SAL_CALL IMPL_RTL_STRINGNAME( new_WithLength )( IMPL_RTL_STRINGDATA** ppThis, sal_Int32 nLen ) -{ - 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 != NULL); - (*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 ) -{ - 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 != NULL); - rtl_str_ImplCopy( (*ppThis)->buffer, pStr->buffer, pStr->length ); - - /* must be done at least, 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 ) -{ - IMPL_RTL_STRCODE* pBuffer; - IMPL_RTL_STRINGDATA* pOrg; - sal_Int32 nLen; - - if ( pCharStr ) - { - const IMPL_RTL_STRCODE* pTempStr = pCharStr; - while( *pTempStr ) - pTempStr++; - nLen = pTempStr-pCharStr; - } - else - nLen = 0; - - if ( !nLen ) - { - IMPL_RTL_STRINGNAME( new )( ppThis ); - return; - } - - pOrg = *ppThis; - *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen ); - OSL_ASSERT(*ppThis != NULL); - pBuffer = (*ppThis)->buffer; - do - { - *pBuffer = *pCharStr; - pBuffer++; - pCharStr++; - } - while ( *pCharStr ); - - /* must be done at least, 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 ) -{ - 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 != NULL); - rtl_str_ImplCopy( (*ppThis)->buffer, pCharStr, nLen ); - - /* must be done at least, if pCharStr == *ppThis */ - if ( pOrg ) - IMPL_RTL_STRINGNAME( release )( pOrg ); -} - -/* ----------------------------------------------------------------------- */ - -void SAL_CALL IMPL_RTL_STRINGNAME( assign )( IMPL_RTL_STRINGDATA** ppThis, - IMPL_RTL_STRINGDATA* pStr ) -{ - /* must be done at first, if pStr == *ppThis */ - IMPL_RTL_AQUIRE( pStr ); - - if ( *ppThis ) - IMPL_RTL_STRINGNAME( release )( *ppThis ); - - *ppThis = pStr; -} - -/* ----------------------------------------------------------------------- */ - -sal_Int32 SAL_CALL IMPL_RTL_STRINGNAME( getLength )( const IMPL_RTL_STRINGDATA* pThis ) -{ - return pThis->length; -} - -/* ----------------------------------------------------------------------- */ - -IMPL_RTL_STRCODE* SAL_CALL IMPL_RTL_STRINGNAME( getStr )( IMPL_RTL_STRINGDATA * pThis ) -{ - return pThis->buffer; -} - -/* ----------------------------------------------------------------------- */ - -void SAL_CALL IMPL_RTL_STRINGNAME( newConcat )( IMPL_RTL_STRINGDATA** ppThis, - IMPL_RTL_STRINGDATA* pLeft, - IMPL_RTL_STRINGDATA* pRight ) -{ - IMPL_RTL_STRINGDATA* pOrg = *ppThis; - - /* Test for 0-Pointer - if not, change newReplaceStrAt! */ - if ( !pRight || !pRight->length ) - { - *ppThis = pLeft; - IMPL_RTL_AQUIRE( pLeft ); - } - else if ( !pLeft || !pLeft->length ) - { - *ppThis = pRight; - IMPL_RTL_AQUIRE( pRight ); - } - else - { - IMPL_RTL_STRINGDATA* pTempStr = IMPL_RTL_STRINGNAME( ImplAlloc )( pLeft->length + pRight->length ); - OSL_ASSERT(pTempStr != NULL); - rtl_str_ImplCopy( pTempStr->buffer, pLeft->buffer, pLeft->length ); - rtl_str_ImplCopy( pTempStr->buffer+pLeft->length, pRight->buffer, pRight->length ); - *ppThis = pTempStr; - } - - /* must be done at least, if left or right == *ppThis */ - if ( pOrg ) - 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 ) -{ - /* Append? */ - if ( nIndex >= pStr->length ) - { - /* newConcat test, if pNewSubStr is 0 */ - IMPL_RTL_STRINGNAME( newConcat )( ppThis, pStr, pNewSubStr ); - return; - } - - /* negativ 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 != NULL); - 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 ); - - /* must be done at least, 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 ) -{ - IMPL_RTL_STRINGDATA* pOrg = *ppThis; - int bChanged = 0; - 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 = 1; - break; - } - - pCharStr++; - nLen--; - } - - if ( !bChanged ) - { - *ppThis = pStr; - IMPL_RTL_AQUIRE( pStr ); - } - - /* must be done at least, 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 ) -{ - IMPL_RTL_STRINGDATA* pOrg = *ppThis; - int bChanged = 0; - sal_Int32 nLen = pStr->length; - const IMPL_RTL_STRCODE* pCharStr = pStr->buffer; - - while ( nLen > 0 ) - { - /* Between A-Z (65-90), than to lowercase (+32) */ - if ( (*pCharStr >= 65) && (*pCharStr <= 90) ) - { - /* Copy String */ - IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer ); - - /* replace/copy rest of the string */ - if ( pNewCharStr ) - { - /* to lowercase (+32) */ - *pNewCharStr = *pCharStr+32; - pNewCharStr++; - pCharStr++; - nLen--; - - while ( nLen > 0 ) - { - /* Between A-Z (65-90), than to lowercase (+32) */ - if ( (*pCharStr >= 65) && (*pCharStr <= 90) ) - *pNewCharStr = *pCharStr+32; - else - *pNewCharStr = *pCharStr; - - pNewCharStr++; - pCharStr++; - nLen--; - } - } - - bChanged = 1; - break; - } - - pCharStr++; - nLen--; - } - - if ( !bChanged ) - { - *ppThis = pStr; - IMPL_RTL_AQUIRE( pStr ); - } - - /* must be done at least, 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 ) -{ - IMPL_RTL_STRINGDATA* pOrg = *ppThis; - int bChanged = 0; - sal_Int32 nLen = pStr->length; - const IMPL_RTL_STRCODE* pCharStr = pStr->buffer; - - while ( nLen > 0 ) - { - /* Between a-z (97-122), than to uppercase (-32) */ - if ( (*pCharStr >= 97) && (*pCharStr <= 122) ) - { - /* Copy String */ - IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer ); - - /* replace/copy rest of the string */ - if ( pNewCharStr ) - { - /* to uppercase (-32) */ - *pNewCharStr = *pCharStr-32; - pNewCharStr++; - pCharStr++; - nLen--; - - while ( nLen > 0 ) - { - /* Between a-z (97-122), than to uppercase (-32) */ - if ( (*pCharStr >= 97) && (*pCharStr <= 122) ) - *pNewCharStr = *pCharStr-32; - else - *pNewCharStr = *pCharStr; - - pNewCharStr++; - pCharStr++; - nLen--; - } - } - - bChanged = 1; - break; - } - - pCharStr++; - nLen--; - } - - if ( !bChanged ) - { - *ppThis = pStr; - IMPL_RTL_AQUIRE( pStr ); - } - - /* must be done at least, 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 ) -{ - 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_AQUIRE( pStr ); - } - else - { - nLen -= nPostSpaces+nPreSpaces; - *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen ); - OSL_ASSERT(*ppThis != NULL); - if ( *ppThis ) - rtl_str_ImplCopy( (*ppThis)->buffer, pStr->buffer+nPreSpaces, nLen ); - } - - /* must be done at least, 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 ) -{ - 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: */ diff --git a/sal/rtl/source/strtmpl.cxx b/sal/rtl/source/strtmpl.cxx new file mode 100644 index 000000000000..93f91331d376 --- /dev/null +++ b/sal/rtl/source/strtmpl.cxx @@ -0,0 +1,1617 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +/* ======================================================================= */ +/* Internal C-String help functions which could be used without the */ +/* String-Class */ +/* ======================================================================= */ + +#include + +/* +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--; + } +} +*/ + +#define rtl_str_ImplCopy( _pDest, _pSrc, _nCount ) \ +{ \ + IMPL_RTL_STRCODE* __mm_pDest = _pDest; \ + const IMPL_RTL_STRCODE* __mm_pSrc = _pSrc; \ + sal_Int32 __mm_nCount = _nCount; \ + while ( __mm_nCount > 0 ) \ + { \ + *__mm_pDest = *__mm_pSrc; \ + __mm_pDest++; \ + __mm_pSrc++; \ + __mm_nCount--; \ + } \ +} + +/* ======================================================================= */ +/* 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() +{ + const IMPL_RTL_STRCODE* pTempStr = pStr; + while( *pTempStr ) + pTempStr++; + return pTempStr-pStr; +} + +/* ----------------------------------------------------------------------- */ + +sal_Int32 SAL_CALL IMPL_RTL_STRNAME( compare )( const IMPL_RTL_STRCODE* pStr1, + const IMPL_RTL_STRCODE* pStr2 ) + SAL_THROW_EXTERN_C() +{ + sal_Int32 nRet; + while ( ((nRet = ((sal_Int32)(IMPL_RTL_USTRCODE(*pStr1)))- + ((sal_Int32)(IMPL_RTL_USTRCODE(*pStr2)))) == 0) && + *pStr2 ) + { + pStr1++; + pStr2++; + } + + return nRet; +} + +/* ----------------------------------------------------------------------- */ + +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() +{ + sal_Int32 nRet = nStr1Len - nStr2Len; + int nCount = (nRet <= 0) ? nStr1Len : nStr2Len; + + --pStr1; + --pStr2; + while( (--nCount >= 0) && (*++pStr1 == *++pStr2) ); + + if( nCount >= 0 ) + nRet = ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr1 ))) + - ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr2 ))); + + return nRet; +} + +/* ----------------------------------------------------------------------- */ + +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() +{ + 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 = ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr1 )))- + ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr2 ))); + if ( nRet ) + return nRet; + + nShortenedLength--; + pStr1++; + pStr2++; + } + + if ( nShortenedLength <= 0 ) + return 0; + return nStr1Len - nStr2Len; +} + +/* ----------------------------------------------------------------------- */ + +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() +{ + 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 = ((sal_Int32)(IMPL_RTL_USTRCODE( *pStr1Run )))- + ((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() +{ + sal_Int32 nRet; + sal_Int32 c1; + sal_Int32 c2; + do + { + /* If character between 'A' and 'Z', than convert it to lowercase */ + c1 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr1 ); + c2 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr2 ); + if ( (c1 >= 65) && (c1 <= 90) ) + c1 += 32; + if ( (c2 >= 65) && (c2 <= 90) ) + c2 += 32; + nRet = c1-c2; + if ( nRet != 0 ) + return nRet; + + pStr1++; + pStr2++; + } + while ( c2 ); + + 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() +{ + const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len; + const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len; + sal_Int32 nRet; + sal_Int32 c1; + sal_Int32 c2; + while ( (pStr1 < pStr1End) && (pStr2 < pStr2End) ) + { + /* If character between 'A' and 'Z', than convert it to lowercase */ + c1 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr1 ); + c2 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr2 ); + if ( (c1 >= 65) && (c1 <= 90) ) + c1 += 32; + if ( (c2 >= 65) && (c2 <= 90) ) + c2 += 32; + nRet = c1-c2; + 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() +{ + const IMPL_RTL_STRCODE* pStr1End = pStr1 + nStr1Len; + const IMPL_RTL_STRCODE* pStr2End = pStr2 + nStr2Len; + sal_Int32 nRet; + sal_Int32 c1; + sal_Int32 c2; + while ( (nShortenedLength > 0) && + (pStr1 < pStr1End) && (pStr2 < pStr2End) ) + { + /* If character between 'A' and 'Z', than convert it to lowercase */ + c1 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr1 ); + c2 = (sal_Int32)IMPL_RTL_USTRCODE( *pStr2 ); + if ( (c1 >= 65) && (c1 <= 90) ) + c1 += 32; + if ( (c2 >= 65) && (c2 <= 90) ) + c2 += 32; + nRet = c1-c2; + 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() +{ + sal_Int32 h = nLen; + + if ( nLen < 256 ) + { + while ( nLen > 0 ) + { + h = (h*37) + IMPL_RTL_USTRCODE( *pStr ); + pStr++; + nLen--; + } + } + else + { + sal_Int32 nSkip; + const IMPL_RTL_STRCODE* pEndStr = pStr+nLen-5; + + /* only sample some characters */ + /* the first 3, some characters between, and the last 5 */ + h = (h*39) + IMPL_RTL_USTRCODE( *pStr ); + pStr++; + h = (h*39) + IMPL_RTL_USTRCODE( *pStr ); + pStr++; + h = (h*39) + IMPL_RTL_USTRCODE( *pStr ); + pStr++; + + if ( nLen < 32 ) + nSkip = nLen / 4; + else + nSkip = nLen / 8; + nLen -= 8; + while ( nLen > 0 ) + { + h = (h*39) + IMPL_RTL_USTRCODE( *pStr ); + pStr += nSkip; + nLen -= nSkip; + } + + h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr ); + pEndStr++; + h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr ); + pEndStr++; + h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr ); + pEndStr++; + h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr ); + pEndStr++; + h = (h*39) + IMPL_RTL_USTRCODE( *pEndStr ); + } + + return h; +} + +/* ----------------------------------------------------------------------- */ + +sal_Int32 SAL_CALL IMPL_RTL_STRNAME( indexOfChar )( const IMPL_RTL_STRCODE* pStr, + IMPL_RTL_STRCODE c ) + SAL_THROW_EXTERN_C() +{ + const IMPL_RTL_STRCODE* pTempStr = pStr; + while ( *pTempStr ) + { + if ( *pTempStr == c ) + return pTempStr-pStr; + + pTempStr++; + } + + return -1; +} + +/* ----------------------------------------------------------------------- */ + +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() +{ + const IMPL_RTL_STRCODE* pTempStr = pStr; + while ( nLen > 0 ) + { + if ( *pTempStr == c ) + return pTempStr-pStr; + + pTempStr++; + nLen--; + } + + return -1; +} + +/* ----------------------------------------------------------------------- */ + +sal_Int32 SAL_CALL IMPL_RTL_STRNAME( lastIndexOfChar )( const IMPL_RTL_STRCODE* pStr, + IMPL_RTL_STRCODE c ) + SAL_THROW_EXTERN_C() +{ + return IMPL_RTL_STRNAME( lastIndexOfChar_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ), c ); +} + +/* ----------------------------------------------------------------------- */ + +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() +{ + 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() +{ + return IMPL_RTL_STRNAME( indexOfStr_WithLength )( pStr, IMPL_RTL_STRNAME( getLength )( pStr ), + pSubStr, IMPL_RTL_STRNAME( getLength )( pSubStr ) ); +} + +/* ----------------------------------------------------------------------- */ + +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() +{ + /* faster search for a single character */ + if ( nSubLen < 2 ) + { + /* an empty SubString is always not foundable */ + 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() +{ + /* faster search for a single character */ + if ( nSubLen < 2 ) + { + /* an empty SubString is always not foundable */ + 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() +{ + 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() +{ + 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() +{ + while ( *pStr ) + { + /* Between A-Z (65-90), than to lowercase (+32) */ + if ( (*pStr >= 65) && (*pStr <= 90) ) + *pStr += 32; + + pStr++; + } +} + +/* ----------------------------------------------------------------------- */ + +void SAL_CALL IMPL_RTL_STRNAME( toAsciiLowerCase_WithLength )( IMPL_RTL_STRCODE* pStr, + sal_Int32 nLen ) + SAL_THROW_EXTERN_C() +{ + while ( nLen > 0 ) + { + /* Between A-Z (65-90), than to lowercase (+32) */ + if ( (*pStr >= 65) && (*pStr <= 90) ) + *pStr += 32; + + pStr++; + nLen--; + } +} + +/* ----------------------------------------------------------------------- */ + +void SAL_CALL IMPL_RTL_STRNAME( toAsciiUpperCase )( IMPL_RTL_STRCODE* pStr ) + SAL_THROW_EXTERN_C() +{ + while ( *pStr ) + { + /* Between a-z (97-122), than to uppercase (-32) */ + if ( (*pStr >= 97) && (*pStr <= 122) ) + *pStr -= 32; + + pStr++; + } +} + +/* ----------------------------------------------------------------------- */ + +void SAL_CALL IMPL_RTL_STRNAME( toAsciiUpperCase_WithLength )( IMPL_RTL_STRCODE* pStr, + sal_Int32 nLen ) + SAL_THROW_EXTERN_C() +{ + while ( nLen > 0 ) + { + /* Between a-z (97-122), than to uppercase (-32) */ + if ( (*pStr >= 97) && (*pStr <= 122) ) + *pStr -= 32; + + 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() +{ + 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 ) + { + IMPL_RTL_STRCODE* pNewStr = pStr+nPreSpaces; + + nLen -= nPreSpaces; + nIndex = nLen; + + while ( nIndex ) + { + *pStr = *pNewStr; + pStr++; + pNewStr++; + nIndex--; + } + *pStr = 0; + } + + return nLen; +} + +/* ----------------------------------------------------------------------- */ + +sal_Int32 SAL_CALL IMPL_RTL_STRNAME( valueOfBoolean )( IMPL_RTL_STRCODE* pStr, sal_Bool b ) + SAL_THROW_EXTERN_C() +{ + 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() +{ + *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() +{ + sal_Char aBuf[RTL_STR_MAX_VALUEOFINT32]; + sal_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 negativ */ + if ( n < 0 ) + { + *pStr = '-'; + pStr++; + nLen++; + nValue = -n; /* FIXME this code is not portable for n == -2147483648 + (smallest negative value for sal_Int32) */ + } + else + nValue = n; + + /* create a recursive buffer with all values, except the last one */ + do + { + sal_Char nDigit = (sal_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() +{ + sal_Char aBuf[RTL_STR_MAX_VALUEOFINT64]; + sal_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 negativ */ + if ( n < 0 ) + { + *pStr = '-'; + pStr++; + nLen++; + nValue = -n; /* FIXME this code is not portable for + n == -9223372036854775808 (smallest negative value for + sal_Int64) */ + } + else + nValue = n; + + /* create a recursive buffer with all values, except the last one */ + do + { + sal_Char nDigit = (sal_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() +{ + if ( *pStr == '1' ) + return sal_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 sal_True; + } + } + } + + return sal_False; +} + +/* ----------------------------------------------------------------------- */ + +sal_Int32 SAL_CALL IMPL_RTL_STRNAME( toInt32 )( const IMPL_RTL_STRCODE* pStr, + sal_Int16 nRadix ) + SAL_THROW_EXTERN_C() +{ + sal_Bool bNeg; + sal_Int16 nDigit; + sal_Int32 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++; + + if ( *pStr == '-' ) + { + bNeg = sal_True; + pStr++; + } + else + { + if ( *pStr == '+' ) + pStr++; + bNeg = sal_False; + } + + while ( *pStr ) + { + nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix ); + if ( nDigit < 0 ) + break; + + n *= nRadix; + n += nDigit; + + pStr++; + } + + if ( bNeg ) + return -n; + else + return n; +} + +/* ----------------------------------------------------------------------- */ + +sal_Int64 SAL_CALL IMPL_RTL_STRNAME( toInt64 )( const IMPL_RTL_STRCODE* pStr, + sal_Int16 nRadix ) + SAL_THROW_EXTERN_C() +{ + sal_Bool bNeg; + sal_Int16 nDigit; + sal_Int64 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++; + + if ( *pStr == '-' ) + { + bNeg = sal_True; + pStr++; + } + else + { + if ( *pStr == '+' ) + pStr++; + bNeg = sal_False; + } + + while ( *pStr ) + { + nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix ); + if ( nDigit < 0 ) + break; + + n *= nRadix; + n += nDigit; + + pStr++; + } + + if ( bNeg ) + return -n; + else + return n; +} + +/* ======================================================================= */ +/* Internal String-Class help functions */ +/* ======================================================================= */ + +static 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))) + ? (IMPL_RTL_STRINGDATA *) rtl_allocateMemory( + sizeof (IMPL_RTL_STRINGDATA) + nLen * sizeof (IMPL_RTL_STRCODE)) + : NULL; + if (pData != NULL) { + 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 ) +{ + IMPL_RTL_STRCODE* pDest; + const IMPL_RTL_STRCODE* pSrc; + IMPL_RTL_STRINGDATA* pData = IMPL_RTL_STRINGNAME( ImplAlloc )( pStr->length ); + OSL_ASSERT(pData != NULL); + + pDest = pData->buffer; + pSrc = pStr->buffer; + while ( nCount > 0 ) + { + *pDest = *pSrc; + pDest++; + pSrc++; + nCount--; + } + + *ppThis = pData; + return pDest; +} + +/* ======================================================================= */ +/* String-Class functions */ +/* ======================================================================= */ + +#define IMPL_RTL_AQUIRE( pThis ) \ +{ \ + if (!SAL_STRING_IS_STATIC (pThis)) \ + osl_incrementInterlockedCount( &((pThis)->refCount) ); \ +} + +/* ----------------------------------------------------------------------- */ + +void SAL_CALL IMPL_RTL_STRINGNAME( acquire )( IMPL_RTL_STRINGDATA* pThis ) + SAL_THROW_EXTERN_C() +{ + IMPL_RTL_AQUIRE( pThis ); +} + +/* ----------------------------------------------------------------------- */ + +void SAL_CALL IMPL_RTL_STRINGNAME( release )( IMPL_RTL_STRINGDATA* pThis ) + SAL_THROW_EXTERN_C() +{ + if (SAL_STRING_IS_STATIC (pThis)) + return; + +/* OString doesn't have an 'intern' */ +#ifdef IMPL_RTL_INTERN + if (SAL_STRING_IS_INTERN (pThis)) + { + internRelease (pThis); + return; + } +#endif + + if ( pThis->refCount == 1 || + !osl_decrementInterlockedCount( &(pThis->refCount) ) ) + { + rtl_freeMemory( pThis ); + } +} + +/* ----------------------------------------------------------------------- */ + +void SAL_CALL IMPL_RTL_STRINGNAME( new )( IMPL_RTL_STRINGDATA** ppThis ) + SAL_THROW_EXTERN_C() +{ + if ( *ppThis) + IMPL_RTL_STRINGNAME( release )( *ppThis ); + + *ppThis = (IMPL_RTL_STRINGDATA*) (&IMPL_RTL_EMPTYSTRING); + IMPL_RTL_AQUIRE( *ppThis ); +} + +/* ----------------------------------------------------------------------- */ + +void SAL_CALL IMPL_RTL_STRINGNAME( new_WithLength )( IMPL_RTL_STRINGDATA** ppThis, sal_Int32 nLen ) + SAL_THROW_EXTERN_C() +{ + 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 != NULL); + (*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() +{ + 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 != NULL); + rtl_str_ImplCopy( (*ppThis)->buffer, pStr->buffer, pStr->length ); + + /* must be done at least, 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() +{ + IMPL_RTL_STRCODE* pBuffer; + IMPL_RTL_STRINGDATA* pOrg; + sal_Int32 nLen; + + if ( pCharStr ) + { + const IMPL_RTL_STRCODE* pTempStr = pCharStr; + while( *pTempStr ) + pTempStr++; + nLen = pTempStr-pCharStr; + } + else + nLen = 0; + + if ( !nLen ) + { + IMPL_RTL_STRINGNAME( new )( ppThis ); + return; + } + + pOrg = *ppThis; + *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen ); + OSL_ASSERT(*ppThis != NULL); + pBuffer = (*ppThis)->buffer; + do + { + *pBuffer = *pCharStr; + pBuffer++; + pCharStr++; + } + while ( *pCharStr ); + + /* must be done at least, 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() +{ + 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 != NULL); + rtl_str_ImplCopy( (*ppThis)->buffer, pCharStr, nLen ); + + /* must be done at least, if pCharStr == *ppThis */ + if ( pOrg ) + IMPL_RTL_STRINGNAME( release )( pOrg ); +} + +/* ----------------------------------------------------------------------- */ + +void SAL_CALL IMPL_RTL_STRINGNAME( assign )( IMPL_RTL_STRINGDATA** ppThis, + IMPL_RTL_STRINGDATA* pStr ) + SAL_THROW_EXTERN_C() +{ + /* must be done at first, if pStr == *ppThis */ + IMPL_RTL_AQUIRE( 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() +{ + return pThis->length; +} + +/* ----------------------------------------------------------------------- */ + +IMPL_RTL_STRCODE* SAL_CALL IMPL_RTL_STRINGNAME( getStr )( IMPL_RTL_STRINGDATA * pThis ) + SAL_THROW_EXTERN_C() +{ + 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() +{ + IMPL_RTL_STRINGDATA* pOrg = *ppThis; + + /* Test for 0-Pointer - if not, change newReplaceStrAt! */ + if ( !pRight || !pRight->length ) + { + *ppThis = pLeft; + IMPL_RTL_AQUIRE( pLeft ); + } + else if ( !pLeft || !pLeft->length ) + { + *ppThis = pRight; + IMPL_RTL_AQUIRE( pRight ); + } + else + { + IMPL_RTL_STRINGDATA* pTempStr = IMPL_RTL_STRINGNAME( ImplAlloc )( pLeft->length + pRight->length ); + OSL_ASSERT(pTempStr != NULL); + rtl_str_ImplCopy( pTempStr->buffer, pLeft->buffer, pLeft->length ); + rtl_str_ImplCopy( pTempStr->buffer+pLeft->length, pRight->buffer, pRight->length ); + *ppThis = pTempStr; + } + + /* must be done at least, if left or right == *ppThis */ + if ( pOrg ) + 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() +{ + /* Append? */ + if ( nIndex >= pStr->length ) + { + /* newConcat test, if pNewSubStr is 0 */ + IMPL_RTL_STRINGNAME( newConcat )( ppThis, pStr, pNewSubStr ); + return; + } + + /* negativ 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 != NULL); + 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 ); + + /* must be done at least, 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() +{ + IMPL_RTL_STRINGDATA* pOrg = *ppThis; + int bChanged = 0; + 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 = 1; + break; + } + + pCharStr++; + nLen--; + } + + if ( !bChanged ) + { + *ppThis = pStr; + IMPL_RTL_AQUIRE( pStr ); + } + + /* must be done at least, 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() +{ + IMPL_RTL_STRINGDATA* pOrg = *ppThis; + int bChanged = 0; + sal_Int32 nLen = pStr->length; + const IMPL_RTL_STRCODE* pCharStr = pStr->buffer; + + while ( nLen > 0 ) + { + /* Between A-Z (65-90), than to lowercase (+32) */ + if ( (*pCharStr >= 65) && (*pCharStr <= 90) ) + { + /* Copy String */ + IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer ); + + /* replace/copy rest of the string */ + if ( pNewCharStr ) + { + /* to lowercase (+32) */ + *pNewCharStr = *pCharStr+32; + pNewCharStr++; + pCharStr++; + nLen--; + + while ( nLen > 0 ) + { + /* Between A-Z (65-90), than to lowercase (+32) */ + if ( (*pCharStr >= 65) && (*pCharStr <= 90) ) + *pNewCharStr = *pCharStr+32; + else + *pNewCharStr = *pCharStr; + + pNewCharStr++; + pCharStr++; + nLen--; + } + } + + bChanged = 1; + break; + } + + pCharStr++; + nLen--; + } + + if ( !bChanged ) + { + *ppThis = pStr; + IMPL_RTL_AQUIRE( pStr ); + } + + /* must be done at least, 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() +{ + IMPL_RTL_STRINGDATA* pOrg = *ppThis; + int bChanged = 0; + sal_Int32 nLen = pStr->length; + const IMPL_RTL_STRCODE* pCharStr = pStr->buffer; + + while ( nLen > 0 ) + { + /* Between a-z (97-122), than to uppercase (-32) */ + if ( (*pCharStr >= 97) && (*pCharStr <= 122) ) + { + /* Copy String */ + IMPL_RTL_STRCODE* pNewCharStr = IMPL_RTL_STRINGNAME( ImplNewCopy )( ppThis, pStr, pCharStr-pStr->buffer ); + + /* replace/copy rest of the string */ + if ( pNewCharStr ) + { + /* to uppercase (-32) */ + *pNewCharStr = *pCharStr-32; + pNewCharStr++; + pCharStr++; + nLen--; + + while ( nLen > 0 ) + { + /* Between a-z (97-122), than to uppercase (-32) */ + if ( (*pCharStr >= 97) && (*pCharStr <= 122) ) + *pNewCharStr = *pCharStr-32; + else + *pNewCharStr = *pCharStr; + + pNewCharStr++; + pCharStr++; + nLen--; + } + } + + bChanged = 1; + break; + } + + pCharStr++; + nLen--; + } + + if ( !bChanged ) + { + *ppThis = pStr; + IMPL_RTL_AQUIRE( pStr ); + } + + /* must be done at least, 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() +{ + 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_AQUIRE( pStr ); + } + else + { + nLen -= nPostSpaces+nPreSpaces; + *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen ); + OSL_ASSERT(*ppThis != NULL); + if ( *ppThis ) + rtl_str_ImplCopy( (*ppThis)->buffer, pStr->buffer+nPreSpaces, nLen ); + } + + /* must be done at least, 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() +{ + 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: */ diff --git a/sal/rtl/source/surrogates.h b/sal/rtl/source/surrogates.h deleted file mode 100644 index c686e181047a..000000000000 --- a/sal/rtl/source/surrogates.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#ifndef INCLUDED_SAL_RTL_SOURCE_SURROGATES_H -#define INCLUDED_SAL_RTL_SOURCE_SURROGATES_H - -#include "sal/config.h" - -#define SAL_RTL_FIRST_HIGH_SURROGATE 0xD800 -#define SAL_RTL_LAST_HIGH_SURROGATE 0xDBFF -#define SAL_RTL_FIRST_LOW_SURROGATE 0xDC00 -#define SAL_RTL_LAST_LOW_SURROGATE 0xDFFF - -#define SAL_RTL_IS_HIGH_SURROGATE(utf16) \ - ((utf16) >= SAL_RTL_FIRST_HIGH_SURROGATE && \ - (utf16) <= SAL_RTL_LAST_HIGH_SURROGATE) - -#define SAL_RTL_IS_LOW_SURROGATE(utf16) \ - ((utf16) >= SAL_RTL_FIRST_LOW_SURROGATE && \ - (utf16) <= SAL_RTL_LAST_LOW_SURROGATE) - -#define SAL_RTL_COMBINE_SURROGATES(high, low) \ - ((((high) - SAL_RTL_FIRST_HIGH_SURROGATE) << 10) + \ - ((low) - SAL_RTL_FIRST_LOW_SURROGATE) + 0x10000) - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/rtl/source/surrogates.hxx b/sal/rtl/source/surrogates.hxx new file mode 100644 index 000000000000..42d4355ade00 --- /dev/null +++ b/sal/rtl/source/surrogates.hxx @@ -0,0 +1,53 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_SAL_RTL_SOURCE_SURROGATES_HXX +#define INCLUDED_SAL_RTL_SOURCE_SURROGATES_HXX + +#include "sal/config.h" + +#define SAL_RTL_FIRST_HIGH_SURROGATE 0xD800 +#define SAL_RTL_LAST_HIGH_SURROGATE 0xDBFF +#define SAL_RTL_FIRST_LOW_SURROGATE 0xDC00 +#define SAL_RTL_LAST_LOW_SURROGATE 0xDFFF + +#define SAL_RTL_IS_HIGH_SURROGATE(utf16) \ + ((utf16) >= SAL_RTL_FIRST_HIGH_SURROGATE && \ + (utf16) <= SAL_RTL_LAST_HIGH_SURROGATE) + +#define SAL_RTL_IS_LOW_SURROGATE(utf16) \ + ((utf16) >= SAL_RTL_FIRST_LOW_SURROGATE && \ + (utf16) <= SAL_RTL_LAST_LOW_SURROGATE) + +#define SAL_RTL_COMBINE_SURROGATES(high, low) \ + ((((high) - SAL_RTL_FIRST_HIGH_SURROGATE) << 10) + \ + ((low) - SAL_RTL_FIRST_LOW_SURROGATE) + 0x10000) + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/rtl/source/uri.cxx b/sal/rtl/source/uri.cxx index 928614eb32ce..191d319c6474 100644 --- a/sal/rtl/source/uri.cxx +++ b/sal/rtl/source/uri.cxx @@ -31,7 +31,7 @@ #include "rtl/uri.h" -#include "surrogates.h" +#include "surrogates.hxx" #include "osl/diagnose.h" #include "rtl/strbuf.hxx" diff --git a/sal/rtl/source/ustrbuf.c b/sal/rtl/source/ustrbuf.c deleted file mode 100644 index 374913ae78b8..000000000000 --- a/sal/rtl/source/ustrbuf.c +++ /dev/null @@ -1,239 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#include - -#ifndef _RTL_STRING_HXX_ -#include -#endif -#include - -/* -#include -*/ - - - -/************************************************************************* - * rtl_uStringbuffer_newFromStr_WithLength - */ -void SAL_CALL rtl_uStringbuffer_newFromStr_WithLength( rtl_uString ** newStr, - const sal_Unicode * value, - sal_Int32 count) -{ - if (!value) - { - rtl_uString_new_WithLength( newStr, 16 ); - return; - } - - rtl_uString_new_WithLength( newStr, count + 16 ); - (*newStr)->length = count; - rtl_copyMemory( (*newStr)->buffer, value, count * sizeof(sal_Unicode)); - return; -} - -/************************************************************************* - * rtl_uStringbuffer_newFromStringBuffer - */ -sal_Int32 SAL_CALL rtl_uStringbuffer_newFromStringBuffer( rtl_uString ** newStr, - sal_Int32 capacity, - rtl_uString * oldStr ) -{ - sal_Int32 newCapacity = capacity; - - if (newCapacity < oldStr->length) - newCapacity = oldStr->length; - - rtl_uString_new_WithLength( newStr, newCapacity ); - - if (oldStr->length > 0) { - (*newStr)->length = oldStr->length; - rtl_copyMemory( (*newStr)->buffer, oldStr->buffer, oldStr->length * sizeof(sal_Unicode)); - } - return newCapacity; -} - -/************************************************************************* - * rtl_uStringbuffer_ensureCapacity - */ -void SAL_CALL rtl_uStringbuffer_ensureCapacity - (rtl_uString ** This, sal_Int32* capacity, sal_Int32 minimumCapacity) -{ - if (minimumCapacity > *capacity) - { - rtl_uString * pTmp = *This; - rtl_uString * pNew = NULL; - *capacity = ((*This)->length + 1) * 2; - if (minimumCapacity > *capacity) - /* still lower, set to the minimum capacity */ - *capacity = minimumCapacity; - - rtl_uString_new_WithLength(&pNew, *capacity); - pNew->length = (*This)->length; - *This = pNew; - - rtl_copyMemory( (*This)->buffer, pTmp->buffer, pTmp->length * sizeof(sal_Unicode) ); - rtl_uString_release( pTmp ); - } -} - -/************************************************************************* - * rtl_uStringbuffer_insert - */ -void SAL_CALL rtl_uStringbuffer_insert( rtl_uString ** This, - sal_Int32 * capacity, - sal_Int32 offset, - const sal_Unicode * str, - sal_Int32 len) -{ - sal_Int32 nOldLen; - sal_Unicode * pBuf; - sal_Int32 n; - if( len != 0 ) - { - if (*capacity < (*This)->length + len) - rtl_uStringbuffer_ensureCapacity( This, capacity, (*This)->length + len ); - - /* - if( len == 1 ) - This->buffer - */ - nOldLen = (*This)->length; - pBuf = (*This)->buffer; - - /* copy the tail */ - n = (nOldLen - offset); - if( n == 1 ) - /* optimized for 1 character */ - pBuf[offset + len] = pBuf[offset]; - else if( n > 1 ) - rtl_moveMemory( pBuf + offset + len, pBuf + offset, n * sizeof(sal_Unicode) ); - - /* insert the new characters */ - if( len == 1 ) - /* optimized for 1 character */ - pBuf[offset] = *str; - else if( len > 1 ) - rtl_copyMemory( pBuf + offset, str, len * sizeof(sal_Unicode) ); - (*This)->length = nOldLen + len; - pBuf[ nOldLen + len ] = 0; - } -} - -void rtl_uStringbuffer_insertUtf32( - rtl_uString ** pThis, sal_Int32 * capacity, sal_Int32 offset, sal_uInt32 c) -{ - sal_Unicode buf[2]; - sal_Int32 len; - OSL_ASSERT(c <= 0x10FFFF && !(c >= 0xD800 && c <= 0xDFFF)); - if (c <= 0xFFFF) { - buf[0] = (sal_Unicode) c; - len = 1; - } else { - c -= 0x10000; - buf[0] = (sal_Unicode) ((c >> 10) | 0xD800); - buf[1] = (sal_Unicode) ((c & 0x3FF) | 0xDC00); - len = 2; - } - rtl_uStringbuffer_insert(pThis, capacity, offset, buf, len); -} - -/************************************************************************* - * rtl_uStringbuffer_insert_ascii - */ -void SAL_CALL rtl_uStringbuffer_insert_ascii( /*inout*/rtl_uString ** This, - /*inout*/sal_Int32 * capacity, - sal_Int32 offset, - const sal_Char * str, - sal_Int32 len) -{ - sal_Int32 nOldLen; - sal_Unicode * pBuf; - sal_Int32 n; - if( len != 0 ) - { - if (*capacity < (*This)->length + len) - rtl_uStringbuffer_ensureCapacity( This, capacity, (*This)->length + len ); - - nOldLen = (*This)->length; - pBuf = (*This)->buffer; - - /* copy the tail */ - n = (nOldLen - offset); - if( n == 1 ) - /* optimized for 1 character */ - pBuf[offset + len] = pBuf[offset]; - else if( n > 1 ) - rtl_moveMemory( pBuf + offset + len, pBuf + offset, n * sizeof(sal_Unicode) ); - - /* insert the new characters */ - for( n = 0; n < len; n++ ) - { - /* Check ASCII range */ - OSL_ENSURE( (*str & 0x80) == 0, "Found ASCII char > 127"); - - pBuf[offset + n] = (sal_Unicode)*(str++); - } - - (*This)->length = nOldLen + len; - pBuf[ nOldLen + len ] = 0; - } -} - -/************************************************************************* - * rtl_uStringbuffer_remove - */ -void SAL_CALL rtl_uStringbuffer_remove( rtl_uString ** This, - sal_Int32 start, - sal_Int32 len ) -{ - sal_Int32 nTailLen; - sal_Unicode * pBuf; - - if (len > (*This)->length - start) - len = (*This)->length - start; - - //remove nothing - if (!len) - return; - - pBuf = (*This)->buffer; - nTailLen = (*This)->length - ( start + len ); - - if (nTailLen) - { - /* move the tail */ - rtl_moveMemory(pBuf + start, pBuf + start + len, nTailLen * sizeof(sal_Unicode)); - } - - (*This)->length-=len; - pBuf[ (*This)->length ] = 0; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/rtl/source/ustrbuf.cxx b/sal/rtl/source/ustrbuf.cxx new file mode 100644 index 000000000000..82b2fcb43d1b --- /dev/null +++ b/sal/rtl/source/ustrbuf.cxx @@ -0,0 +1,240 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include + +#ifndef _RTL_STRING_HXX_ +#include +#endif +#include + +/* +#include +*/ + + + +/************************************************************************* + * rtl_uStringbuffer_newFromStr_WithLength + */ +void SAL_CALL rtl_uStringbuffer_newFromStr_WithLength( rtl_uString ** newStr, + const sal_Unicode * value, + sal_Int32 count) +{ + if (!value) + { + rtl_uString_new_WithLength( newStr, 16 ); + return; + } + + rtl_uString_new_WithLength( newStr, count + 16 ); + (*newStr)->length = count; + rtl_copyMemory( (*newStr)->buffer, value, count * sizeof(sal_Unicode)); + return; +} + +/************************************************************************* + * rtl_uStringbuffer_newFromStringBuffer + */ +sal_Int32 SAL_CALL rtl_uStringbuffer_newFromStringBuffer( rtl_uString ** newStr, + sal_Int32 capacity, + rtl_uString * oldStr ) +{ + sal_Int32 newCapacity = capacity; + + if (newCapacity < oldStr->length) + newCapacity = oldStr->length; + + rtl_uString_new_WithLength( newStr, newCapacity ); + + if (oldStr->length > 0) { + (*newStr)->length = oldStr->length; + rtl_copyMemory( (*newStr)->buffer, oldStr->buffer, oldStr->length * sizeof(sal_Unicode)); + } + return newCapacity; +} + +/************************************************************************* + * rtl_uStringbuffer_ensureCapacity + */ +void SAL_CALL rtl_uStringbuffer_ensureCapacity + (rtl_uString ** This, sal_Int32* capacity, sal_Int32 minimumCapacity) +{ + if (minimumCapacity > *capacity) + { + rtl_uString * pTmp = *This; + rtl_uString * pNew = NULL; + *capacity = ((*This)->length + 1) * 2; + if (minimumCapacity > *capacity) + /* still lower, set to the minimum capacity */ + *capacity = minimumCapacity; + + rtl_uString_new_WithLength(&pNew, *capacity); + pNew->length = (*This)->length; + *This = pNew; + + rtl_copyMemory( (*This)->buffer, pTmp->buffer, pTmp->length * sizeof(sal_Unicode) ); + rtl_uString_release( pTmp ); + } +} + +/************************************************************************* + * rtl_uStringbuffer_insert + */ +void SAL_CALL rtl_uStringbuffer_insert( rtl_uString ** This, + sal_Int32 * capacity, + sal_Int32 offset, + const sal_Unicode * str, + sal_Int32 len) +{ + sal_Int32 nOldLen; + sal_Unicode * pBuf; + sal_Int32 n; + if( len != 0 ) + { + if (*capacity < (*This)->length + len) + rtl_uStringbuffer_ensureCapacity( This, capacity, (*This)->length + len ); + + /* + if( len == 1 ) + This->buffer + */ + nOldLen = (*This)->length; + pBuf = (*This)->buffer; + + /* copy the tail */ + n = (nOldLen - offset); + if( n == 1 ) + /* optimized for 1 character */ + pBuf[offset + len] = pBuf[offset]; + else if( n > 1 ) + rtl_moveMemory( pBuf + offset + len, pBuf + offset, n * sizeof(sal_Unicode) ); + + /* insert the new characters */ + if( len == 1 ) + /* optimized for 1 character */ + pBuf[offset] = *str; + else if( len > 1 ) + rtl_copyMemory( pBuf + offset, str, len * sizeof(sal_Unicode) ); + (*This)->length = nOldLen + len; + pBuf[ nOldLen + len ] = 0; + } +} + +void rtl_uStringbuffer_insertUtf32( + rtl_uString ** pThis, sal_Int32 * capacity, sal_Int32 offset, sal_uInt32 c) + SAL_THROW_EXTERN_C() +{ + sal_Unicode buf[2]; + sal_Int32 len; + OSL_ASSERT(c <= 0x10FFFF && !(c >= 0xD800 && c <= 0xDFFF)); + if (c <= 0xFFFF) { + buf[0] = (sal_Unicode) c; + len = 1; + } else { + c -= 0x10000; + buf[0] = (sal_Unicode) ((c >> 10) | 0xD800); + buf[1] = (sal_Unicode) ((c & 0x3FF) | 0xDC00); + len = 2; + } + rtl_uStringbuffer_insert(pThis, capacity, offset, buf, len); +} + +/************************************************************************* + * rtl_uStringbuffer_insert_ascii + */ +void SAL_CALL rtl_uStringbuffer_insert_ascii( /*inout*/rtl_uString ** This, + /*inout*/sal_Int32 * capacity, + sal_Int32 offset, + const sal_Char * str, + sal_Int32 len) +{ + sal_Int32 nOldLen; + sal_Unicode * pBuf; + sal_Int32 n; + if( len != 0 ) + { + if (*capacity < (*This)->length + len) + rtl_uStringbuffer_ensureCapacity( This, capacity, (*This)->length + len ); + + nOldLen = (*This)->length; + pBuf = (*This)->buffer; + + /* copy the tail */ + n = (nOldLen - offset); + if( n == 1 ) + /* optimized for 1 character */ + pBuf[offset + len] = pBuf[offset]; + else if( n > 1 ) + rtl_moveMemory( pBuf + offset + len, pBuf + offset, n * sizeof(sal_Unicode) ); + + /* insert the new characters */ + for( n = 0; n < len; n++ ) + { + /* Check ASCII range */ + OSL_ENSURE( (*str & 0x80) == 0, "Found ASCII char > 127"); + + pBuf[offset + n] = (sal_Unicode)*(str++); + } + + (*This)->length = nOldLen + len; + pBuf[ nOldLen + len ] = 0; + } +} + +/************************************************************************* + * rtl_uStringbuffer_remove + */ +void SAL_CALL rtl_uStringbuffer_remove( rtl_uString ** This, + sal_Int32 start, + sal_Int32 len ) +{ + sal_Int32 nTailLen; + sal_Unicode * pBuf; + + if (len > (*This)->length - start) + len = (*This)->length - start; + + //remove nothing + if (!len) + return; + + pBuf = (*This)->buffer; + nTailLen = (*This)->length - ( start + len ); + + if (nTailLen) + { + /* move the tail */ + rtl_moveMemory(pBuf + start, pBuf + start + len, nTailLen * sizeof(sal_Unicode)); + } + + (*This)->length-=len; + pBuf[ (*This)->length ] = 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/rtl/source/ustring.c b/sal/rtl/source/ustring.c deleted file mode 100644 index feb597547ae1..000000000000 --- a/sal/rtl/source/ustring.c +++ /dev/null @@ -1,983 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ -#if defined(_MSC_VER) && (_MSC_VER >= 1400) -#pragma warning(disable:4738) // storing 32-bit float result in memory, possible loss of performance -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "hash.h" -#include "strimp.h" -#include "surrogates.h" -#include - -#include "rtl/math.h" -#include "rtl/tencinfo.h" - -/* ======================================================================= */ - -/* static data to be referenced by all empty strings - * the refCount is predefined to 1 and must never become 0 ! - */ -static rtl_uString const aImplEmpty_rtl_uString = -{ - (sal_Int32) (SAL_STRING_INTERN_FLAG|SAL_STRING_STATIC_FLAG|1), /*sal_Int32 refCount; */ - 0, /*sal_Int32 length; */ - { 0 } /*sal_Unicode buffer[1];*/ -}; - -/* ======================================================================= */ - -#define IMPL_RTL_STRCODE sal_Unicode -#define IMPL_RTL_USTRCODE( c ) (c) -#define IMPL_RTL_STRNAME( n ) rtl_ustr_ ## n - -#define IMPL_RTL_STRINGNAME( n ) rtl_uString_ ## n -#define IMPL_RTL_STRINGDATA rtl_uString -#define IMPL_RTL_EMPTYSTRING aImplEmpty_rtl_uString -#define IMPL_RTL_INTERN -static void internRelease (rtl_uString *pThis); - -/* ======================================================================= */ - -/* Include String/UString template code */ - -#include "strtmpl.c" - -sal_Int32 rtl_ustr_indexOfAscii_WithLength( - sal_Unicode const * str, sal_Int32 len, - char const * subStr, sal_Int32 subLen) -{ - if (subLen > 0 && subLen <= len) { - sal_Int32 i; - for (i = 0; i <= len - subLen; ++i) { - if (rtl_ustr_asciil_reverseEquals_WithLength( - str + i, subStr, subLen)) - { - return i; - } - } - } - return -1; -} - -sal_Int32 rtl_ustr_lastIndexOfAscii_WithLength( - sal_Unicode const * str, sal_Int32 len, - char const * subStr, sal_Int32 subLen) -{ - if (subLen > 0 && subLen <= len) { - sal_Int32 i; - for (i = len - subLen; i >= 0; --i) { - if (rtl_ustr_asciil_reverseEquals_WithLength( - str + i, subStr, subLen)) - { - return i; - } - } - } - return -1; -} - -sal_Int32 SAL_CALL rtl_ustr_valueOfFloat(sal_Unicode * pStr, float f) -{ - rtl_uString * pResult = NULL; - sal_Int32 nLen; - rtl_math_doubleToUString( - &pResult, 0, 0, f, rtl_math_StringFormat_G, - RTL_USTR_MAX_VALUEOFFLOAT - RTL_CONSTASCII_LENGTH("-x.E-xxx"), '.', 0, - 0, sal_True); - nLen = pResult->length; - OSL_ASSERT(nLen < RTL_USTR_MAX_VALUEOFFLOAT); - rtl_copyMemory(pStr, pResult->buffer, (nLen + 1) * sizeof(sal_Unicode)); - rtl_uString_release(pResult); - return nLen; -} - -sal_Int32 SAL_CALL rtl_ustr_valueOfDouble(sal_Unicode * pStr, double d) -{ - rtl_uString * pResult = NULL; - sal_Int32 nLen; - rtl_math_doubleToUString( - &pResult, 0, 0, d, rtl_math_StringFormat_G, - RTL_USTR_MAX_VALUEOFDOUBLE - RTL_CONSTASCII_LENGTH("-x.E-xxx"), '.', 0, - 0, sal_True); - nLen = pResult->length; - OSL_ASSERT(nLen < RTL_USTR_MAX_VALUEOFDOUBLE); - rtl_copyMemory(pStr, pResult->buffer, (nLen + 1) * sizeof(sal_Unicode)); - rtl_uString_release(pResult); - return nLen; -} - -float SAL_CALL rtl_ustr_toFloat(sal_Unicode const * pStr) -{ - return (float) rtl_math_uStringToDouble(pStr, - pStr + rtl_ustr_getLength(pStr), - '.', 0, 0, 0); -} - -double SAL_CALL rtl_ustr_toDouble(sal_Unicode const * pStr) -{ - return rtl_math_uStringToDouble(pStr, pStr + rtl_ustr_getLength(pStr), '.', - 0, 0, 0); -} - -/* ======================================================================= */ - -sal_Int32 SAL_CALL rtl_ustr_ascii_compare( const sal_Unicode* pStr1, - const sal_Char* pStr2 ) -{ - sal_Int32 nRet; - while ( ((nRet = ((sal_Int32)(*pStr1))- - ((sal_Int32)((unsigned char)(*pStr2)))) == 0) && - *pStr2 ) - { - pStr1++; - pStr2++; - } - - return nRet; -} - -/* ----------------------------------------------------------------------- */ - -sal_Int32 SAL_CALL rtl_ustr_ascii_compare_WithLength( const sal_Unicode* pStr1, - sal_Int32 nStr1Len, - const sal_Char* pStr2 ) -{ - sal_Int32 nRet = 0; - while( ((nRet = (nStr1Len ? (sal_Int32)(*pStr1) : 0)- - ((sal_Int32)((unsigned char)(*pStr2)))) == 0) && - nStr1Len && *pStr2 ) - { - pStr1++; - pStr2++; - nStr1Len--; - } - - return nRet; -} - -/* ----------------------------------------------------------------------- */ - -sal_Int32 SAL_CALL rtl_ustr_ascii_shortenedCompare_WithLength( const sal_Unicode* pStr1, - sal_Int32 nStr1Len, - const sal_Char* pStr2, - sal_Int32 nShortenedLength ) -{ - const sal_Unicode* pStr1End = pStr1 + nStr1Len; - sal_Int32 nRet; - while ( (nShortenedLength > 0) && - (pStr1 < pStr1End) && *pStr2 ) - { - /* Check ASCII range */ - OSL_ENSURE( (*pStr2 & 0x80) == 0, "Found ASCII char > 127"); - - nRet = ((sal_Int32)*pStr1)- - ((sal_Int32)(unsigned char)*pStr2); - if ( nRet != 0 ) - return nRet; - - nShortenedLength--; - pStr1++; - pStr2++; - } - - if ( nShortenedLength <= 0 ) - return 0; - - if ( *pStr2 ) - { - OSL_ENSURE( pStr1 == pStr1End, "pStr1 == pStr1End failed" ); - // first is a substring of the second string => less (negative value) - nRet = -1; - } - else - { - // greater or equal - nRet = pStr1End - pStr1; - } - - return nRet; -} - -/* ----------------------------------------------------------------------- */ - -sal_Int32 SAL_CALL rtl_ustr_asciil_reverseCompare_WithLength( const sal_Unicode* pStr1, - sal_Int32 nStr1Len, - const sal_Char* pStr2, - sal_Int32 nStr2Len ) -{ - const sal_Unicode* pStr1Run = pStr1+nStr1Len; - const sal_Char* pStr2Run = pStr2+nStr2Len; - sal_Int32 nRet; - while ( (pStr1 < pStr1Run) && (pStr2 < pStr2Run) ) - { - pStr1Run--; - pStr2Run--; - nRet = ((sal_Int32)*pStr1Run)-((sal_Int32)*pStr2Run); - if ( nRet ) - return nRet; - } - - return nStr1Len - nStr2Len; -} - -/* ----------------------------------------------------------------------- */ - -sal_Bool SAL_CALL rtl_ustr_asciil_reverseEquals_WithLength( const sal_Unicode* pStr1, - const sal_Char* pStr2, - sal_Int32 nStrLen ) -{ - const sal_Unicode* pStr1Run = pStr1+nStrLen; - const sal_Char* pStr2Run = pStr2+nStrLen; - while ( pStr1 < pStr1Run ) - { - pStr1Run--; - pStr2Run--; - if( *pStr1Run != (sal_Unicode)*pStr2Run ) - return sal_False; - } - - return sal_True; -} - -/* ----------------------------------------------------------------------- */ - -sal_Int32 SAL_CALL rtl_ustr_ascii_compareIgnoreAsciiCase( const sal_Unicode* pStr1, - const sal_Char* pStr2 ) -{ - sal_Int32 nRet; - sal_Int32 c1; - sal_Int32 c2; - do - { - /* If character between 'A' and 'Z', than convert it to lowercase */ - c1 = (sal_Int32)*pStr1; - c2 = (sal_Int32)((unsigned char)*pStr2); - if ( (c1 >= 65) && (c1 <= 90) ) - c1 += 32; - if ( (c2 >= 65) && (c2 <= 90) ) - c2 += 32; - nRet = c1-c2; - if ( nRet != 0 ) - return nRet; - - pStr1++; - pStr2++; - } - while ( c2 ); - - return 0; -} - -/* ----------------------------------------------------------------------- */ - -sal_Int32 SAL_CALL rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( const sal_Unicode* pStr1, - sal_Int32 nStr1Len, - const sal_Char* pStr2 ) -{ - sal_Int32 nRet; - sal_Int32 c1; - sal_Int32 c2; - do - { - if ( !nStr1Len ) - return *pStr2 == '\0' ? 0 : -1; - - /* If character between 'A' and 'Z', than convert it to lowercase */ - c1 = (sal_Int32)*pStr1; - c2 = (sal_Int32)((unsigned char)*pStr2); - if ( (c1 >= 65) && (c1 <= 90) ) - c1 += 32; - if ( (c2 >= 65) && (c2 <= 90) ) - c2 += 32; - nRet = c1-c2; - if ( nRet != 0 ) - return nRet; - - pStr1++; - pStr2++; - nStr1Len--; - } - while( c2 ); - - return 0; -} - -sal_Int32 rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths( - sal_Unicode const * first, sal_Int32 firstLen, - char const * second, sal_Int32 secondLen) -{ - sal_Int32 i; - sal_Int32 len = firstLen < secondLen ? firstLen : secondLen; - for (i = 0; i < len; ++i) { - sal_Int32 c1 = *first++; - sal_Int32 c2 = (unsigned char) *second++; - sal_Int32 d; - if (c1 >= 65 && c1 <= 90) { - c1 += 32; - } - if (c2 >= 65 && c2 <= 90) { - c2 += 32; - } - d = c1 - c2; - if (d != 0) { - return d; - } - } - return firstLen - secondLen; -} - -/* ----------------------------------------------------------------------- */ - -sal_Int32 SAL_CALL rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( const sal_Unicode* pStr1, - sal_Int32 nStr1Len, - const sal_Char* pStr2, - sal_Int32 nShortenedLength ) -{ - const sal_Unicode* pStr1End = pStr1 + nStr1Len; - sal_Int32 nRet; - sal_Int32 c1; - sal_Int32 c2; - while ( (nShortenedLength > 0) && - (pStr1 < pStr1End) && *pStr2 ) - { - /* Check ASCII range */ - OSL_ENSURE( (*pStr2 & 0x80) == 0, "Found ASCII char > 127"); - - /* If character between 'A' and 'Z', than convert it to lowercase */ - c1 = (sal_Int32)*pStr1; - c2 = (sal_Int32)((unsigned char)*pStr2); - if ( (c1 >= 65) && (c1 <= 90) ) - c1 += 32; - if ( (c2 >= 65) && (c2 <= 90) ) - c2 += 32; - nRet = c1-c2; - if ( nRet != 0 ) - return nRet; - - nShortenedLength--; - pStr1++; - pStr2++; - } - - if ( nShortenedLength <= 0 ) - return 0; - - if ( *pStr2 ) - { - OSL_ENSURE( pStr1 == pStr1End, "pStr1 == pStr1End failed" ); - // first is a substring of the second string => less (negative value) - nRet = -1; - } - else - { - // greater or equal - nRet = pStr1End - pStr1; - } - - return nRet; -} - -/* ----------------------------------------------------------------------- */ - -void SAL_CALL rtl_uString_newFromAscii( rtl_uString** ppThis, - const sal_Char* pCharStr ) -{ - sal_Int32 nLen; - - if ( pCharStr ) - { - const sal_Char* pTempStr = pCharStr; - while( *pTempStr ) - pTempStr++; - nLen = pTempStr-pCharStr; - } - else - nLen = 0; - - if ( !nLen ) - { - IMPL_RTL_STRINGNAME( new )( ppThis ); - return; - } - - if ( *ppThis ) - IMPL_RTL_STRINGNAME( release )( *ppThis ); - - *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen ); - OSL_ASSERT(*ppThis != NULL); - if ( (*ppThis) ) - { - IMPL_RTL_STRCODE* pBuffer = (*ppThis)->buffer; - do - { - /* Check ASCII range */ - OSL_ENSURE( ((unsigned char)*pCharStr) <= 127, - "rtl_uString_newFromAscii() - Found ASCII char > 127" ); - - *pBuffer = *pCharStr; - pBuffer++; - pCharStr++; - } - while ( *pCharStr ); - } -} - -void SAL_CALL rtl_uString_newFromCodePoints( - rtl_uString ** newString, sal_uInt32 const * codePoints, - sal_Int32 codePointCount) -{ - sal_Int32 n; - sal_Int32 i; - sal_Unicode * p; - OSL_ASSERT( - newString != NULL && - (codePoints != NULL || codePointCount == 0) && - codePointCount >= 0); - if (codePointCount == 0) { - rtl_uString_new(newString); - return; - } - if (*newString != NULL) { - rtl_uString_release(*newString); - } - n = codePointCount; - for (i = 0; i < codePointCount; ++i) { - OSL_ASSERT(codePoints[i] <= 0x10FFFF); - if (codePoints[i] >= 0x10000) { - ++n; - } - } - /* Builds on the assumption that sal_Int32 uses 32 bit two's complement - representation with wrap around (the necessary number of UTF-16 code - units will be no larger than 2 * SAL_MAX_INT32, represented as - sal_Int32 -2): */ - if (n < 0) { - *newString = NULL; - return; - } - *newString = rtl_uString_ImplAlloc(n); - if (*newString == NULL) { - return; - } - p = (*newString)->buffer; - for (i = 0; i < codePointCount; ++i) { - sal_uInt32 c = codePoints[i]; - if (c < 0x10000) { - *p++ = (sal_Unicode) c; - } else { - c -= 0x10000; - *p++ = (sal_Unicode) ((c >> 10) | SAL_RTL_FIRST_HIGH_SURROGATE); - *p++ = (sal_Unicode) ((c & 0x3FF) | SAL_RTL_FIRST_LOW_SURROGATE); - } - } -} - -/* ======================================================================= */ - -static int rtl_ImplGetFastUTF8UnicodeLen( const sal_Char* pStr, sal_Int32 nLen ) -{ - int n; - sal_uChar c; - const sal_Char* pEndStr; - - n = 0; - pEndStr = pStr+nLen; - while ( pStr < pEndStr ) - { - c = (sal_uChar)*pStr; - - if ( !(c & 0x80) ) - pStr++; - else if ( (c & 0xE0) == 0xC0 ) - pStr += 2; - else if ( (c & 0xF0) == 0xE0 ) - pStr += 3; - else if ( (c & 0xF8) == 0xF0 ) - pStr += 4; - else if ( (c & 0xFC) == 0xF8 ) - pStr += 5; - else if ( (c & 0xFE) == 0xFC ) - pStr += 6; - else - pStr++; - - n++; - } - - return n; -} - -/* ----------------------------------------------------------------------- */ - -static void rtl_string2UString_status( rtl_uString** ppThis, - const sal_Char* pStr, - sal_Int32 nLen, - rtl_TextEncoding eTextEncoding, - sal_uInt32 nCvtFlags, - sal_uInt32 *pInfo ) -{ - OSL_ENSURE(nLen == 0 || rtl_isOctetTextEncoding(eTextEncoding), - "rtl_string2UString_status() - Wrong TextEncoding" ); - - if ( !nLen ) - { - rtl_uString_new( ppThis ); - if (pInfo != NULL) { - *pInfo = 0; - } - } - else - { - if ( *ppThis ) - IMPL_RTL_STRINGNAME( release )( *ppThis ); - - /* Optimization for US-ASCII */ - if ( eTextEncoding == RTL_TEXTENCODING_ASCII_US ) - { - IMPL_RTL_STRCODE* pBuffer; - *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen ); - if (*ppThis == NULL) { - if (pInfo != NULL) { - *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR | - RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL; - } - return; - } - pBuffer = (*ppThis)->buffer; - do - { - /* Check ASCII range */ - OSL_ENSURE( ((unsigned char)*pStr) <= 127, - "rtl_string2UString_status() - Found char > 127 and RTL_TEXTENCODING_ASCII_US is specified" ); - - *pBuffer = *pStr; - pBuffer++; - pStr++; - nLen--; - } - while ( nLen ); - if (pInfo != NULL) { - *pInfo = 0; - } - } - else - { - rtl_uString* pTemp; - rtl_uString* pTemp2 = NULL; - rtl_TextToUnicodeConverter hConverter; - sal_uInt32 nInfo; - sal_Size nSrcBytes; - sal_Size nDestChars; - sal_Size nNewLen; - - /* Optimization for UTF-8 - we try to calculate the exact length */ - /* For all other encoding we try the maximum - and reallocate - the buffer if needed */ - if ( eTextEncoding == RTL_TEXTENCODING_UTF8 ) - { - nNewLen = rtl_ImplGetFastUTF8UnicodeLen( pStr, nLen ); - /* Includes the string only ASCII, then we could copy - the buffer faster */ - if ( nNewLen == (sal_Size)nLen ) - { - IMPL_RTL_STRCODE* pBuffer; - *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen ); - if (*ppThis == NULL) - { - if (pInfo != NULL) { - *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR | - RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL; - } - return; - } - pBuffer = (*ppThis)->buffer; - do - { - /* Check ASCII range */ - OSL_ENSURE( ((unsigned char)*pStr) <= 127, - "rtl_string2UString_status() - UTF8 test encoding is wrong" ); - - *pBuffer = *pStr; - pBuffer++; - pStr++; - nLen--; - } - while ( nLen ); - if (pInfo != NULL) { - *pInfo = 0; - } - return; - } - } - else - nNewLen = nLen; - - nCvtFlags |= RTL_TEXTTOUNICODE_FLAGS_FLUSH; - hConverter = rtl_createTextToUnicodeConverter( eTextEncoding ); - - pTemp = IMPL_RTL_STRINGNAME( ImplAlloc )( nNewLen ); - if (pTemp == NULL) { - if (pInfo != NULL) { - *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR | - RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL; - } - return; - } - nDestChars = rtl_convertTextToUnicode( hConverter, 0, - pStr, nLen, - pTemp->buffer, nNewLen, - nCvtFlags, - &nInfo, &nSrcBytes ); - - /* Buffer not big enough, try again with enough space */ - /* Shouldn't be the case, but if we get textencoding which - could results in more unicode characters we have this - code here. Could be the case for apple encodings */ - while ( nInfo & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL ) - { - rtl_freeMemory( pTemp ); - nNewLen += 8; - pTemp = IMPL_RTL_STRINGNAME( ImplAlloc )( nNewLen ); - if (pTemp == NULL) { - if (pInfo != NULL) { - *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR | - RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL; - } - return; - } - nDestChars = rtl_convertTextToUnicode( hConverter, 0, - pStr, nLen, - pTemp->buffer, nNewLen, - nCvtFlags, - &nInfo, &nSrcBytes ); - } - - if (pInfo) - *pInfo = nInfo; - - /* Set the buffer to the correct size or if there is too - much overhead, reallocate to the correct size */ - if ( nNewLen > nDestChars+8 ) - { - pTemp2 = IMPL_RTL_STRINGNAME( ImplAlloc )( nDestChars ); - } - if (pTemp2 != NULL) - { - rtl_str_ImplCopy(pTemp2->buffer, pTemp->buffer, nDestChars); - rtl_freeMemory(pTemp); - pTemp = pTemp2; - } - else - { - pTemp->length = nDestChars; - pTemp->buffer[nDestChars] = 0; - } - - rtl_destroyTextToUnicodeConverter( hConverter ); - *ppThis = pTemp; - - /* Results the conversion in an empty buffer - - create an empty string */ - if ( pTemp && !nDestChars ) - rtl_uString_new( ppThis ); - } - } -} - -void SAL_CALL rtl_string2UString( rtl_uString** ppThis, - const sal_Char* pStr, - sal_Int32 nLen, - rtl_TextEncoding eTextEncoding, - sal_uInt32 nCvtFlags ) -{ - rtl_string2UString_status( ppThis, pStr, nLen, eTextEncoding, - nCvtFlags, NULL ); -} - -/* ----------------------------------------------------------------------- */ - -typedef enum { - CANNOT_RETURN, - CAN_RETURN = 1 -} StrLifecycle; - -static oslMutex -getInternMutex() -{ - static oslMutex pPoolGuard = NULL; - if( !pPoolGuard ) - { - oslMutex pGlobalGuard; - pGlobalGuard = *osl_getGlobalMutex(); - osl_acquireMutex( pGlobalGuard ); - if( !pPoolGuard ) - { - oslMutex p = osl_createMutex(); - OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); - pPoolGuard = p; - } - osl_releaseMutex( pGlobalGuard ); - } - else - { - OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); - } - - return pPoolGuard; -} - -/* returns true if we found a dup in the pool */ -static void rtl_ustring_intern_internal( rtl_uString ** newStr, - rtl_uString * str, - StrLifecycle can_return ) -{ - oslMutex pPoolMutex; - - pPoolMutex = getInternMutex(); - - osl_acquireMutex( pPoolMutex ); - - *newStr = rtl_str_hash_intern (str, can_return); - - osl_releaseMutex( pPoolMutex ); - - if( can_return && *newStr != str ) - { /* we dupped, then found a match */ - rtl_freeMemory( str ); - } -} - -void SAL_CALL rtl_uString_intern( rtl_uString ** newStr, - rtl_uString * str) -{ - if (SAL_STRING_IS_INTERN(str)) - { - IMPL_RTL_AQUIRE( str ); - *newStr = str; - } - else - { - rtl_uString *pOrg = *newStr; - *newStr = NULL; - rtl_ustring_intern_internal( newStr, str, CANNOT_RETURN ); - if (pOrg) - rtl_uString_release (pOrg); - } -} - -static int rtl_canGuessUOutputLength( int len, rtl_TextEncoding eTextEncoding ) -{ - // FIXME: Maybe we should use a bit flag in the higher bits of the - // eTextEncoding value itself to determine the encoding type. But if we - // do, be sure to mask the value in certain places that expect the values - // to be numbered serially from 0 and up. One such place is - // Impl_getTextEncodingData(). - - switch ( eTextEncoding ) - { - // 1 to 1 (with no zero elements) - case RTL_TEXTENCODING_IBM_437: - case RTL_TEXTENCODING_IBM_850: - case RTL_TEXTENCODING_IBM_860: - case RTL_TEXTENCODING_IBM_861: - case RTL_TEXTENCODING_IBM_863: - case RTL_TEXTENCODING_IBM_865: - return len; - break; - } - return 0; -} - -void SAL_CALL rtl_uString_internConvert( rtl_uString ** newStr, - const sal_Char * str, - sal_Int32 len, - rtl_TextEncoding eTextEncoding, - sal_uInt32 convertFlags, - sal_uInt32 * pInfo ) -{ - rtl_uString *scratch; - - if (*newStr) - { - rtl_uString_release (*newStr); - *newStr = NULL; - } - - if ( len < 256 ) - { // try various optimisations - sal_Int32 ulen; - if ( len < 0 ) - len = strlen( str ); - if ( eTextEncoding == RTL_TEXTENCODING_ASCII_US ) - { - int i; - rtl_uString *pScratch; - pScratch = alloca( sizeof( rtl_uString ) - + len * sizeof (IMPL_RTL_STRCODE ) ); - for (i = 0; i < len; i++) - { - /* Check ASCII range */ - OSL_ENSURE( ((unsigned char)str[i]) <= 127, - "rtl_ustring_internConvert() - Found char > 127 and RTL_TEXTENCODING_ASCII_US is specified" ); - pScratch->buffer[i] = str[i]; - } - pScratch->length = len; - rtl_ustring_intern_internal( newStr, pScratch, CANNOT_RETURN ); - return; - } - else if ( (ulen = rtl_canGuessUOutputLength(len, eTextEncoding)) != 0 ) - { - rtl_uString *pScratch; - rtl_TextToUnicodeConverter hConverter; - sal_Size nSrcBytes; - sal_uInt32 nInfo; - - pScratch = alloca( sizeof(rtl_uString) + ulen * sizeof (IMPL_RTL_STRCODE) ); - - hConverter = rtl_createTextToUnicodeConverter( eTextEncoding ); - rtl_convertTextToUnicode( - hConverter, 0, str, len, pScratch->buffer, ulen, convertFlags, &nInfo, &nSrcBytes ); - rtl_destroyTextToUnicodeConverter( hConverter ); - - if (pInfo) - *pInfo = nInfo; - - pScratch->length = ulen; - rtl_ustring_intern_internal( newStr, pScratch, CANNOT_RETURN ); - return; - } - - /* FIXME: we want a nice UTF-8 / alloca shortcut here */ - } - - scratch = NULL; - rtl_string2UString_status( &scratch, str, len, eTextEncoding, convertFlags, - pInfo ); - if (!scratch) { - return; - } - rtl_ustring_intern_internal( newStr, scratch, CAN_RETURN ); -} - -static void -internRelease (rtl_uString *pThis) -{ - oslMutex pPoolMutex; - - rtl_uString *pFree = NULL; - if ( SAL_STRING_REFCOUNT( - osl_decrementInterlockedCount( &(pThis->refCount) ) ) == 0) - { - pPoolMutex = getInternMutex(); - osl_acquireMutex( pPoolMutex ); - - rtl_str_hash_remove (pThis); - - /* May have been separately acquired */ - if ( SAL_STRING_REFCOUNT( - osl_incrementInterlockedCount( &(pThis->refCount) ) ) == 1 ) - { - /* we got the last ref */ - pFree = pThis; - } - else /* very unusual */ - { - internRelease (pThis); - } - - osl_releaseMutex( pPoolMutex ); - } - if (pFree) - rtl_freeMemory (pFree); -} - -sal_uInt32 SAL_CALL rtl_uString_iterateCodePoints( - rtl_uString const * string, sal_Int32 * indexUtf16, - sal_Int32 incrementCodePoints) -{ - sal_Int32 n; - sal_Unicode cu; - sal_uInt32 cp; - OSL_ASSERT(string != NULL && indexUtf16 != NULL); - n = *indexUtf16; - OSL_ASSERT(n >= 0 && n <= string->length); - while (incrementCodePoints < 0) { - OSL_ASSERT(n > 0); - cu = string->buffer[--n]; - if (SAL_RTL_IS_LOW_SURROGATE(cu) && n != 0 && - SAL_RTL_IS_HIGH_SURROGATE(string->buffer[n - 1])) - { - --n; - } - ++incrementCodePoints; - } - OSL_ASSERT(n >= 0 && n < string->length); - cu = string->buffer[n]; - if (SAL_RTL_IS_HIGH_SURROGATE(cu) && string->length - n >= 2 && - SAL_RTL_IS_LOW_SURROGATE(string->buffer[n + 1])) - { - cp = SAL_RTL_COMBINE_SURROGATES(cu, string->buffer[n + 1]); - } else { - cp = cu; - } - while (incrementCodePoints > 0) { - OSL_ASSERT(n < string->length); - cu = string->buffer[n++]; - if (SAL_RTL_IS_HIGH_SURROGATE(cu) && n != string->length && - SAL_RTL_IS_LOW_SURROGATE(string->buffer[n])) - { - ++n; - } - --incrementCodePoints; - } - OSL_ASSERT(n >= 0 && n <= string->length); - *indexUtf16 = n; - return cp; -} - -sal_Bool rtl_convertStringToUString( - rtl_uString ** target, char const * source, sal_Int32 length, - rtl_TextEncoding encoding, sal_uInt32 flags) SAL_THROW_EXTERN_C() -{ - sal_uInt32 info; - rtl_string2UString_status(target, source, length, encoding, flags, &info); - return (sal_Bool) ((info & RTL_TEXTTOUNICODE_INFO_ERROR) == 0); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/rtl/source/ustring.cxx b/sal/rtl/source/ustring.cxx new file mode 100644 index 000000000000..a37353c99161 --- /dev/null +++ b/sal/rtl/source/ustring.cxx @@ -0,0 +1,997 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#pragma warning(disable:4738) // storing 32-bit float result in memory, possible loss of performance +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "hash.hxx" +#include "strimp.hxx" +#include "surrogates.hxx" +#include + +#include "rtl/math.h" +#include "rtl/tencinfo.h" + +/* ======================================================================= */ + +/* static data to be referenced by all empty strings + * the refCount is predefined to 1 and must never become 0 ! + */ +static rtl_uString const aImplEmpty_rtl_uString = +{ + (sal_Int32) (SAL_STRING_INTERN_FLAG|SAL_STRING_STATIC_FLAG|1), /*sal_Int32 refCount; */ + 0, /*sal_Int32 length; */ + { 0 } /*sal_Unicode buffer[1];*/ +}; + +/* ======================================================================= */ + +#define IMPL_RTL_STRCODE sal_Unicode +#define IMPL_RTL_USTRCODE( c ) (c) +#define IMPL_RTL_STRNAME( n ) rtl_ustr_ ## n + +#define IMPL_RTL_STRINGNAME( n ) rtl_uString_ ## n +#define IMPL_RTL_STRINGDATA rtl_uString +#define IMPL_RTL_EMPTYSTRING aImplEmpty_rtl_uString +#define IMPL_RTL_INTERN +static void internRelease (rtl_uString *pThis); + +/* ======================================================================= */ + +/* Include String/UString template code */ + +#include "strtmpl.cxx" + +sal_Int32 rtl_ustr_indexOfAscii_WithLength( + sal_Unicode const * str, sal_Int32 len, + char const * subStr, sal_Int32 subLen) SAL_THROW_EXTERN_C() +{ + if (subLen > 0 && subLen <= len) { + sal_Int32 i; + for (i = 0; i <= len - subLen; ++i) { + if (rtl_ustr_asciil_reverseEquals_WithLength( + str + i, subStr, subLen)) + { + return i; + } + } + } + return -1; +} + +sal_Int32 rtl_ustr_lastIndexOfAscii_WithLength( + sal_Unicode const * str, sal_Int32 len, + char const * subStr, sal_Int32 subLen) SAL_THROW_EXTERN_C() +{ + if (subLen > 0 && subLen <= len) { + sal_Int32 i; + for (i = len - subLen; i >= 0; --i) { + if (rtl_ustr_asciil_reverseEquals_WithLength( + str + i, subStr, subLen)) + { + return i; + } + } + } + return -1; +} + +sal_Int32 SAL_CALL rtl_ustr_valueOfFloat(sal_Unicode * pStr, float f) + SAL_THROW_EXTERN_C() +{ + rtl_uString * pResult = NULL; + sal_Int32 nLen; + rtl_math_doubleToUString( + &pResult, 0, 0, f, rtl_math_StringFormat_G, + RTL_USTR_MAX_VALUEOFFLOAT - RTL_CONSTASCII_LENGTH("-x.E-xxx"), '.', 0, + 0, sal_True); + nLen = pResult->length; + OSL_ASSERT(nLen < RTL_USTR_MAX_VALUEOFFLOAT); + rtl_copyMemory(pStr, pResult->buffer, (nLen + 1) * sizeof(sal_Unicode)); + rtl_uString_release(pResult); + return nLen; +} + +sal_Int32 SAL_CALL rtl_ustr_valueOfDouble(sal_Unicode * pStr, double d) + SAL_THROW_EXTERN_C() +{ + rtl_uString * pResult = NULL; + sal_Int32 nLen; + rtl_math_doubleToUString( + &pResult, 0, 0, d, rtl_math_StringFormat_G, + RTL_USTR_MAX_VALUEOFDOUBLE - RTL_CONSTASCII_LENGTH("-x.E-xxx"), '.', 0, + 0, sal_True); + nLen = pResult->length; + OSL_ASSERT(nLen < RTL_USTR_MAX_VALUEOFDOUBLE); + rtl_copyMemory(pStr, pResult->buffer, (nLen + 1) * sizeof(sal_Unicode)); + rtl_uString_release(pResult); + return nLen; +} + +float SAL_CALL rtl_ustr_toFloat(sal_Unicode const * pStr) SAL_THROW_EXTERN_C() +{ + return (float) rtl_math_uStringToDouble(pStr, + pStr + rtl_ustr_getLength(pStr), + '.', 0, 0, 0); +} + +double SAL_CALL rtl_ustr_toDouble(sal_Unicode const * pStr) SAL_THROW_EXTERN_C() +{ + return rtl_math_uStringToDouble(pStr, pStr + rtl_ustr_getLength(pStr), '.', + 0, 0, 0); +} + +/* ======================================================================= */ + +sal_Int32 SAL_CALL rtl_ustr_ascii_compare( const sal_Unicode* pStr1, + const sal_Char* pStr2 ) + SAL_THROW_EXTERN_C() +{ + sal_Int32 nRet; + while ( ((nRet = ((sal_Int32)(*pStr1))- + ((sal_Int32)((unsigned char)(*pStr2)))) == 0) && + *pStr2 ) + { + pStr1++; + pStr2++; + } + + return nRet; +} + +/* ----------------------------------------------------------------------- */ + +sal_Int32 SAL_CALL rtl_ustr_ascii_compare_WithLength( const sal_Unicode* pStr1, + sal_Int32 nStr1Len, + const sal_Char* pStr2 ) + SAL_THROW_EXTERN_C() +{ + sal_Int32 nRet = 0; + while( ((nRet = (nStr1Len ? (sal_Int32)(*pStr1) : 0)- + ((sal_Int32)((unsigned char)(*pStr2)))) == 0) && + nStr1Len && *pStr2 ) + { + pStr1++; + pStr2++; + nStr1Len--; + } + + return nRet; +} + +/* ----------------------------------------------------------------------- */ + +sal_Int32 SAL_CALL rtl_ustr_ascii_shortenedCompare_WithLength( const sal_Unicode* pStr1, + sal_Int32 nStr1Len, + const sal_Char* pStr2, + sal_Int32 nShortenedLength ) + SAL_THROW_EXTERN_C() +{ + const sal_Unicode* pStr1End = pStr1 + nStr1Len; + sal_Int32 nRet; + while ( (nShortenedLength > 0) && + (pStr1 < pStr1End) && *pStr2 ) + { + /* Check ASCII range */ + OSL_ENSURE( (*pStr2 & 0x80) == 0, "Found ASCII char > 127"); + + nRet = ((sal_Int32)*pStr1)- + ((sal_Int32)(unsigned char)*pStr2); + if ( nRet != 0 ) + return nRet; + + nShortenedLength--; + pStr1++; + pStr2++; + } + + if ( nShortenedLength <= 0 ) + return 0; + + if ( *pStr2 ) + { + OSL_ENSURE( pStr1 == pStr1End, "pStr1 == pStr1End failed" ); + // first is a substring of the second string => less (negative value) + nRet = -1; + } + else + { + // greater or equal + nRet = pStr1End - pStr1; + } + + return nRet; +} + +/* ----------------------------------------------------------------------- */ + +sal_Int32 SAL_CALL rtl_ustr_asciil_reverseCompare_WithLength( const sal_Unicode* pStr1, + sal_Int32 nStr1Len, + const sal_Char* pStr2, + sal_Int32 nStr2Len ) + SAL_THROW_EXTERN_C() +{ + const sal_Unicode* pStr1Run = pStr1+nStr1Len; + const sal_Char* pStr2Run = pStr2+nStr2Len; + sal_Int32 nRet; + while ( (pStr1 < pStr1Run) && (pStr2 < pStr2Run) ) + { + pStr1Run--; + pStr2Run--; + nRet = ((sal_Int32)*pStr1Run)-((sal_Int32)*pStr2Run); + if ( nRet ) + return nRet; + } + + return nStr1Len - nStr2Len; +} + +/* ----------------------------------------------------------------------- */ + +sal_Bool SAL_CALL rtl_ustr_asciil_reverseEquals_WithLength( const sal_Unicode* pStr1, + const sal_Char* pStr2, + sal_Int32 nStrLen ) + SAL_THROW_EXTERN_C() +{ + const sal_Unicode* pStr1Run = pStr1+nStrLen; + const sal_Char* pStr2Run = pStr2+nStrLen; + while ( pStr1 < pStr1Run ) + { + pStr1Run--; + pStr2Run--; + if( *pStr1Run != (sal_Unicode)*pStr2Run ) + return sal_False; + } + + return sal_True; +} + +/* ----------------------------------------------------------------------- */ + +sal_Int32 SAL_CALL rtl_ustr_ascii_compareIgnoreAsciiCase( const sal_Unicode* pStr1, + const sal_Char* pStr2 ) + SAL_THROW_EXTERN_C() +{ + sal_Int32 nRet; + sal_Int32 c1; + sal_Int32 c2; + do + { + /* If character between 'A' and 'Z', than convert it to lowercase */ + c1 = (sal_Int32)*pStr1; + c2 = (sal_Int32)((unsigned char)*pStr2); + if ( (c1 >= 65) && (c1 <= 90) ) + c1 += 32; + if ( (c2 >= 65) && (c2 <= 90) ) + c2 += 32; + nRet = c1-c2; + if ( nRet != 0 ) + return nRet; + + pStr1++; + pStr2++; + } + while ( c2 ); + + return 0; +} + +/* ----------------------------------------------------------------------- */ + +sal_Int32 SAL_CALL rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( const sal_Unicode* pStr1, + sal_Int32 nStr1Len, + const sal_Char* pStr2 ) + SAL_THROW_EXTERN_C() +{ + sal_Int32 nRet; + sal_Int32 c1; + sal_Int32 c2; + do + { + if ( !nStr1Len ) + return *pStr2 == '\0' ? 0 : -1; + + /* If character between 'A' and 'Z', than convert it to lowercase */ + c1 = (sal_Int32)*pStr1; + c2 = (sal_Int32)((unsigned char)*pStr2); + if ( (c1 >= 65) && (c1 <= 90) ) + c1 += 32; + if ( (c2 >= 65) && (c2 <= 90) ) + c2 += 32; + nRet = c1-c2; + if ( nRet != 0 ) + return nRet; + + pStr1++; + pStr2++; + nStr1Len--; + } + while( c2 ); + + return 0; +} + +sal_Int32 rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths( + sal_Unicode const * first, sal_Int32 firstLen, + char const * second, sal_Int32 secondLen) SAL_THROW_EXTERN_C() +{ + sal_Int32 i; + sal_Int32 len = firstLen < secondLen ? firstLen : secondLen; + for (i = 0; i < len; ++i) { + sal_Int32 c1 = *first++; + sal_Int32 c2 = (unsigned char) *second++; + sal_Int32 d; + if (c1 >= 65 && c1 <= 90) { + c1 += 32; + } + if (c2 >= 65 && c2 <= 90) { + c2 += 32; + } + d = c1 - c2; + if (d != 0) { + return d; + } + } + return firstLen - secondLen; +} + +/* ----------------------------------------------------------------------- */ + +sal_Int32 SAL_CALL rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( const sal_Unicode* pStr1, + sal_Int32 nStr1Len, + const sal_Char* pStr2, + sal_Int32 nShortenedLength ) + SAL_THROW_EXTERN_C() +{ + const sal_Unicode* pStr1End = pStr1 + nStr1Len; + sal_Int32 nRet; + sal_Int32 c1; + sal_Int32 c2; + while ( (nShortenedLength > 0) && + (pStr1 < pStr1End) && *pStr2 ) + { + /* Check ASCII range */ + OSL_ENSURE( (*pStr2 & 0x80) == 0, "Found ASCII char > 127"); + + /* If character between 'A' and 'Z', than convert it to lowercase */ + c1 = (sal_Int32)*pStr1; + c2 = (sal_Int32)((unsigned char)*pStr2); + if ( (c1 >= 65) && (c1 <= 90) ) + c1 += 32; + if ( (c2 >= 65) && (c2 <= 90) ) + c2 += 32; + nRet = c1-c2; + if ( nRet != 0 ) + return nRet; + + nShortenedLength--; + pStr1++; + pStr2++; + } + + if ( nShortenedLength <= 0 ) + return 0; + + if ( *pStr2 ) + { + OSL_ENSURE( pStr1 == pStr1End, "pStr1 == pStr1End failed" ); + // first is a substring of the second string => less (negative value) + nRet = -1; + } + else + { + // greater or equal + nRet = pStr1End - pStr1; + } + + return nRet; +} + +/* ----------------------------------------------------------------------- */ + +void SAL_CALL rtl_uString_newFromAscii( rtl_uString** ppThis, + const sal_Char* pCharStr ) + SAL_THROW_EXTERN_C() +{ + sal_Int32 nLen; + + if ( pCharStr ) + { + const sal_Char* pTempStr = pCharStr; + while( *pTempStr ) + pTempStr++; + nLen = pTempStr-pCharStr; + } + else + nLen = 0; + + if ( !nLen ) + { + IMPL_RTL_STRINGNAME( new )( ppThis ); + return; + } + + if ( *ppThis ) + IMPL_RTL_STRINGNAME( release )( *ppThis ); + + *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen ); + OSL_ASSERT(*ppThis != NULL); + if ( (*ppThis) ) + { + IMPL_RTL_STRCODE* pBuffer = (*ppThis)->buffer; + do + { + /* Check ASCII range */ + OSL_ENSURE( ((unsigned char)*pCharStr) <= 127, + "rtl_uString_newFromAscii() - Found ASCII char > 127" ); + + *pBuffer = *pCharStr; + pBuffer++; + pCharStr++; + } + while ( *pCharStr ); + } +} + +void SAL_CALL rtl_uString_newFromCodePoints( + rtl_uString ** newString, sal_uInt32 const * codePoints, + sal_Int32 codePointCount) SAL_THROW_EXTERN_C() +{ + sal_Int32 n; + sal_Int32 i; + sal_Unicode * p; + OSL_ASSERT( + newString != NULL && + (codePoints != NULL || codePointCount == 0) && + codePointCount >= 0); + if (codePointCount == 0) { + rtl_uString_new(newString); + return; + } + if (*newString != NULL) { + rtl_uString_release(*newString); + } + n = codePointCount; + for (i = 0; i < codePointCount; ++i) { + OSL_ASSERT(codePoints[i] <= 0x10FFFF); + if (codePoints[i] >= 0x10000) { + ++n; + } + } + /* Builds on the assumption that sal_Int32 uses 32 bit two's complement + representation with wrap around (the necessary number of UTF-16 code + units will be no larger than 2 * SAL_MAX_INT32, represented as + sal_Int32 -2): */ + if (n < 0) { + *newString = NULL; + return; + } + *newString = rtl_uString_ImplAlloc(n); + if (*newString == NULL) { + return; + } + p = (*newString)->buffer; + for (i = 0; i < codePointCount; ++i) { + sal_uInt32 c = codePoints[i]; + if (c < 0x10000) { + *p++ = (sal_Unicode) c; + } else { + c -= 0x10000; + *p++ = (sal_Unicode) ((c >> 10) | SAL_RTL_FIRST_HIGH_SURROGATE); + *p++ = (sal_Unicode) ((c & 0x3FF) | SAL_RTL_FIRST_LOW_SURROGATE); + } + } +} + +/* ======================================================================= */ + +static int rtl_ImplGetFastUTF8UnicodeLen( const sal_Char* pStr, sal_Int32 nLen ) +{ + int n; + sal_uChar c; + const sal_Char* pEndStr; + + n = 0; + pEndStr = pStr+nLen; + while ( pStr < pEndStr ) + { + c = (sal_uChar)*pStr; + + if ( !(c & 0x80) ) + pStr++; + else if ( (c & 0xE0) == 0xC0 ) + pStr += 2; + else if ( (c & 0xF0) == 0xE0 ) + pStr += 3; + else if ( (c & 0xF8) == 0xF0 ) + pStr += 4; + else if ( (c & 0xFC) == 0xF8 ) + pStr += 5; + else if ( (c & 0xFE) == 0xFC ) + pStr += 6; + else + pStr++; + + n++; + } + + return n; +} + +/* ----------------------------------------------------------------------- */ + +static void rtl_string2UString_status( rtl_uString** ppThis, + const sal_Char* pStr, + sal_Int32 nLen, + rtl_TextEncoding eTextEncoding, + sal_uInt32 nCvtFlags, + sal_uInt32 *pInfo ) +{ + OSL_ENSURE(nLen == 0 || rtl_isOctetTextEncoding(eTextEncoding), + "rtl_string2UString_status() - Wrong TextEncoding" ); + + if ( !nLen ) + { + rtl_uString_new( ppThis ); + if (pInfo != NULL) { + *pInfo = 0; + } + } + else + { + if ( *ppThis ) + IMPL_RTL_STRINGNAME( release )( *ppThis ); + + /* Optimization for US-ASCII */ + if ( eTextEncoding == RTL_TEXTENCODING_ASCII_US ) + { + IMPL_RTL_STRCODE* pBuffer; + *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen ); + if (*ppThis == NULL) { + if (pInfo != NULL) { + *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR | + RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL; + } + return; + } + pBuffer = (*ppThis)->buffer; + do + { + /* Check ASCII range */ + OSL_ENSURE( ((unsigned char)*pStr) <= 127, + "rtl_string2UString_status() - Found char > 127 and RTL_TEXTENCODING_ASCII_US is specified" ); + + *pBuffer = *pStr; + pBuffer++; + pStr++; + nLen--; + } + while ( nLen ); + if (pInfo != NULL) { + *pInfo = 0; + } + } + else + { + rtl_uString* pTemp; + rtl_uString* pTemp2 = NULL; + rtl_TextToUnicodeConverter hConverter; + sal_uInt32 nInfo; + sal_Size nSrcBytes; + sal_Size nDestChars; + sal_Size nNewLen; + + /* Optimization for UTF-8 - we try to calculate the exact length */ + /* For all other encoding we try the maximum - and reallocate + the buffer if needed */ + if ( eTextEncoding == RTL_TEXTENCODING_UTF8 ) + { + nNewLen = rtl_ImplGetFastUTF8UnicodeLen( pStr, nLen ); + /* Includes the string only ASCII, then we could copy + the buffer faster */ + if ( nNewLen == (sal_Size)nLen ) + { + IMPL_RTL_STRCODE* pBuffer; + *ppThis = IMPL_RTL_STRINGNAME( ImplAlloc )( nLen ); + if (*ppThis == NULL) + { + if (pInfo != NULL) { + *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR | + RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL; + } + return; + } + pBuffer = (*ppThis)->buffer; + do + { + /* Check ASCII range */ + OSL_ENSURE( ((unsigned char)*pStr) <= 127, + "rtl_string2UString_status() - UTF8 test encoding is wrong" ); + + *pBuffer = *pStr; + pBuffer++; + pStr++; + nLen--; + } + while ( nLen ); + if (pInfo != NULL) { + *pInfo = 0; + } + return; + } + } + else + nNewLen = nLen; + + nCvtFlags |= RTL_TEXTTOUNICODE_FLAGS_FLUSH; + hConverter = rtl_createTextToUnicodeConverter( eTextEncoding ); + + pTemp = IMPL_RTL_STRINGNAME( ImplAlloc )( nNewLen ); + if (pTemp == NULL) { + if (pInfo != NULL) { + *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR | + RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL; + } + return; + } + nDestChars = rtl_convertTextToUnicode( hConverter, 0, + pStr, nLen, + pTemp->buffer, nNewLen, + nCvtFlags, + &nInfo, &nSrcBytes ); + + /* Buffer not big enough, try again with enough space */ + /* Shouldn't be the case, but if we get textencoding which + could results in more unicode characters we have this + code here. Could be the case for apple encodings */ + while ( nInfo & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL ) + { + rtl_freeMemory( pTemp ); + nNewLen += 8; + pTemp = IMPL_RTL_STRINGNAME( ImplAlloc )( nNewLen ); + if (pTemp == NULL) { + if (pInfo != NULL) { + *pInfo = RTL_TEXTTOUNICODE_INFO_ERROR | + RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL; + } + return; + } + nDestChars = rtl_convertTextToUnicode( hConverter, 0, + pStr, nLen, + pTemp->buffer, nNewLen, + nCvtFlags, + &nInfo, &nSrcBytes ); + } + + if (pInfo) + *pInfo = nInfo; + + /* Set the buffer to the correct size or if there is too + much overhead, reallocate to the correct size */ + if ( nNewLen > nDestChars+8 ) + { + pTemp2 = IMPL_RTL_STRINGNAME( ImplAlloc )( nDestChars ); + } + if (pTemp2 != NULL) + { + rtl_str_ImplCopy(pTemp2->buffer, pTemp->buffer, nDestChars); + rtl_freeMemory(pTemp); + pTemp = pTemp2; + } + else + { + pTemp->length = nDestChars; + pTemp->buffer[nDestChars] = 0; + } + + rtl_destroyTextToUnicodeConverter( hConverter ); + *ppThis = pTemp; + + /* Results the conversion in an empty buffer - + create an empty string */ + if ( pTemp && !nDestChars ) + rtl_uString_new( ppThis ); + } + } +} + +void SAL_CALL rtl_string2UString( rtl_uString** ppThis, + const sal_Char* pStr, + sal_Int32 nLen, + rtl_TextEncoding eTextEncoding, + sal_uInt32 nCvtFlags ) SAL_THROW_EXTERN_C() +{ + rtl_string2UString_status( ppThis, pStr, nLen, eTextEncoding, + nCvtFlags, NULL ); +} + +/* ----------------------------------------------------------------------- */ + +enum StrLifecycle { + CANNOT_RETURN, + CAN_RETURN = 1 +}; + +static oslMutex +getInternMutex() +{ + static oslMutex pPoolGuard = NULL; + if( !pPoolGuard ) + { + oslMutex pGlobalGuard; + pGlobalGuard = *osl_getGlobalMutex(); + osl_acquireMutex( pGlobalGuard ); + if( !pPoolGuard ) + { + oslMutex p = osl_createMutex(); + OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); + pPoolGuard = p; + } + osl_releaseMutex( pGlobalGuard ); + } + else + { + OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); + } + + return pPoolGuard; +} + +/* returns true if we found a dup in the pool */ +static void rtl_ustring_intern_internal( rtl_uString ** newStr, + rtl_uString * str, + StrLifecycle can_return ) +{ + oslMutex pPoolMutex; + + pPoolMutex = getInternMutex(); + + osl_acquireMutex( pPoolMutex ); + + *newStr = rtl_str_hash_intern (str, can_return); + + osl_releaseMutex( pPoolMutex ); + + if( can_return && *newStr != str ) + { /* we dupped, then found a match */ + rtl_freeMemory( str ); + } +} + +void SAL_CALL rtl_uString_intern( rtl_uString ** newStr, + rtl_uString * str) SAL_THROW_EXTERN_C() +{ + if (SAL_STRING_IS_INTERN(str)) + { + IMPL_RTL_AQUIRE( str ); + *newStr = str; + } + else + { + rtl_uString *pOrg = *newStr; + *newStr = NULL; + rtl_ustring_intern_internal( newStr, str, CANNOT_RETURN ); + if (pOrg) + rtl_uString_release (pOrg); + } +} + +static int rtl_canGuessUOutputLength( int len, rtl_TextEncoding eTextEncoding ) +{ + // FIXME: Maybe we should use a bit flag in the higher bits of the + // eTextEncoding value itself to determine the encoding type. But if we + // do, be sure to mask the value in certain places that expect the values + // to be numbered serially from 0 and up. One such place is + // Impl_getTextEncodingData(). + + switch ( eTextEncoding ) + { + // 1 to 1 (with no zero elements) + case RTL_TEXTENCODING_IBM_437: + case RTL_TEXTENCODING_IBM_850: + case RTL_TEXTENCODING_IBM_860: + case RTL_TEXTENCODING_IBM_861: + case RTL_TEXTENCODING_IBM_863: + case RTL_TEXTENCODING_IBM_865: + return len; + break; + } + return 0; +} + +void SAL_CALL rtl_uString_internConvert( rtl_uString ** newStr, + const sal_Char * str, + sal_Int32 len, + rtl_TextEncoding eTextEncoding, + sal_uInt32 convertFlags, + sal_uInt32 * pInfo ) + SAL_THROW_EXTERN_C() +{ + rtl_uString *scratch; + + if (*newStr) + { + rtl_uString_release (*newStr); + *newStr = NULL; + } + + if ( len < 256 ) + { // try various optimisations + sal_Int32 ulen; + if ( len < 0 ) + len = strlen( str ); + if ( eTextEncoding == RTL_TEXTENCODING_ASCII_US ) + { + int i; + rtl_uString *pScratch; + pScratch = static_cast< rtl_uString * >( + alloca(sizeof (rtl_uString) + len * sizeof (IMPL_RTL_STRCODE))); + for (i = 0; i < len; i++) + { + /* Check ASCII range */ + OSL_ENSURE( ((unsigned char)str[i]) <= 127, + "rtl_ustring_internConvert() - Found char > 127 and RTL_TEXTENCODING_ASCII_US is specified" ); + pScratch->buffer[i] = str[i]; + } + pScratch->length = len; + rtl_ustring_intern_internal( newStr, pScratch, CANNOT_RETURN ); + return; + } + else if ( (ulen = rtl_canGuessUOutputLength(len, eTextEncoding)) != 0 ) + { + rtl_uString *pScratch; + rtl_TextToUnicodeConverter hConverter; + sal_Size nSrcBytes; + sal_uInt32 nInfo; + + pScratch = static_cast< rtl_uString * >( + alloca( + sizeof (rtl_uString) + ulen * sizeof (IMPL_RTL_STRCODE))); + + hConverter = rtl_createTextToUnicodeConverter( eTextEncoding ); + rtl_convertTextToUnicode( + hConverter, 0, str, len, pScratch->buffer, ulen, convertFlags, &nInfo, &nSrcBytes ); + rtl_destroyTextToUnicodeConverter( hConverter ); + + if (pInfo) + *pInfo = nInfo; + + pScratch->length = ulen; + rtl_ustring_intern_internal( newStr, pScratch, CANNOT_RETURN ); + return; + } + + /* FIXME: we want a nice UTF-8 / alloca shortcut here */ + } + + scratch = NULL; + rtl_string2UString_status( &scratch, str, len, eTextEncoding, convertFlags, + pInfo ); + if (!scratch) { + return; + } + rtl_ustring_intern_internal( newStr, scratch, CAN_RETURN ); +} + +static void +internRelease (rtl_uString *pThis) +{ + oslMutex pPoolMutex; + + rtl_uString *pFree = NULL; + if ( SAL_STRING_REFCOUNT( + osl_decrementInterlockedCount( &(pThis->refCount) ) ) == 0) + { + pPoolMutex = getInternMutex(); + osl_acquireMutex( pPoolMutex ); + + rtl_str_hash_remove (pThis); + + /* May have been separately acquired */ + if ( SAL_STRING_REFCOUNT( + osl_incrementInterlockedCount( &(pThis->refCount) ) ) == 1 ) + { + /* we got the last ref */ + pFree = pThis; + } + else /* very unusual */ + { + internRelease (pThis); + } + + osl_releaseMutex( pPoolMutex ); + } + if (pFree) + rtl_freeMemory (pFree); +} + +sal_uInt32 SAL_CALL rtl_uString_iterateCodePoints( + rtl_uString const * string, sal_Int32 * indexUtf16, + sal_Int32 incrementCodePoints) +{ + sal_Int32 n; + sal_Unicode cu; + sal_uInt32 cp; + OSL_ASSERT(string != NULL && indexUtf16 != NULL); + n = *indexUtf16; + OSL_ASSERT(n >= 0 && n <= string->length); + while (incrementCodePoints < 0) { + OSL_ASSERT(n > 0); + cu = string->buffer[--n]; + if (SAL_RTL_IS_LOW_SURROGATE(cu) && n != 0 && + SAL_RTL_IS_HIGH_SURROGATE(string->buffer[n - 1])) + { + --n; + } + ++incrementCodePoints; + } + OSL_ASSERT(n >= 0 && n < string->length); + cu = string->buffer[n]; + if (SAL_RTL_IS_HIGH_SURROGATE(cu) && string->length - n >= 2 && + SAL_RTL_IS_LOW_SURROGATE(string->buffer[n + 1])) + { + cp = SAL_RTL_COMBINE_SURROGATES(cu, string->buffer[n + 1]); + } else { + cp = cu; + } + while (incrementCodePoints > 0) { + OSL_ASSERT(n < string->length); + cu = string->buffer[n++]; + if (SAL_RTL_IS_HIGH_SURROGATE(cu) && n != string->length && + SAL_RTL_IS_LOW_SURROGATE(string->buffer[n])) + { + ++n; + } + --incrementCodePoints; + } + OSL_ASSERT(n >= 0 && n <= string->length); + *indexUtf16 = n; + return cp; +} + +sal_Bool rtl_convertStringToUString( + rtl_uString ** target, char const * source, sal_Int32 length, + rtl_TextEncoding encoding, sal_uInt32 flags) SAL_THROW_EXTERN_C() +{ + sal_uInt32 info; + rtl_string2UString_status(target, source, length, encoding, flags, &info); + return (sal_Bool) ((info & RTL_TEXTTOUNICODE_INFO_ERROR) == 0); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit