User mmeeks doesn't have access to project sal ? sal/rtl/source/hash.cxx Index: sal/inc/rtl/string.h =================================================================== RCS file: /cvs/porting/sal/inc/rtl/string.h,v retrieving revision 1.14 retrieving revision 1.14.94.1 diff -u -p -u -r1.14 -r1.14.94.1 --- sal/inc/rtl/string.h 20 Jun 2006 04:14:27 -0000 1.14 +++ sal/inc/rtl/string.h 25 Jan 2007 17:56:36 -0000 1.14.94.1 @@ -4,9 +4,9 @@ * * $RCSfile: string.h,v $ * - * $Revision: 1.14 $ + * $Revision: 1.14.94.1 $ * - * last change: $Author: hr $ $Date: 2006/06/20 04:14:27 $ + * last change: $Author: mmeeks $ $Date: 2007/01/25 17:56:36 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -762,7 +762,7 @@ double SAL_CALL rtl_str_toDouble( const */ typedef struct _rtl_String { - sal_Int32 refCount; + sal_Int32 refCount; /* opaque */ sal_Int32 length; sal_Char buffer[1]; } rtl_String; Index: sal/inc/rtl/ustring.h =================================================================== RCS file: /cvs/porting/sal/inc/rtl/ustring.h,v retrieving revision 1.17 retrieving revision 1.17.94.2 diff -u -p -u -r1.17 -r1.17.94.2 --- sal/inc/rtl/ustring.h 20 Jun 2006 04:14:53 -0000 1.17 +++ sal/inc/rtl/ustring.h 26 Jan 2007 15:07:02 -0000 1.17.94.2 @@ -1030,7 +1030,7 @@ double SAL_CALL rtl_ustr_toDouble( const */ typedef struct _rtl_uString { - sal_Int32 refCount; + sal_Int32 refCount; /* opaque */ sal_Int32 length; sal_Unicode buffer[1]; } rtl_uString; @@ -1431,6 +1444,64 @@ sal_Int32 SAL_CALL rtl_uString_getToken( */ void SAL_CALL rtl_string2UString( rtl_uString ** newStr, const sal_Char * str, sal_Int32 len, rtl_TextEncoding encoding, sal_uInt32 convertFlags ) SAL_THROW_EXTERN_C(); +/* ======================================================================= */ +/* Interning methods */ + +/** Return a canonical representation for a string. + + A pool of strings, initially empty is maintained privately + by the string class. On invocation, if present in the pool + the original string will be returned. Otherwise this string, + or a copy thereof will be added to the pool and returned. + + @param newStr + pointer to the new string. The pointed-to data must be null or a valid + string. + + @param str + pointer to the string to be interned. + + @return + a version of the string from the pool. + */ + +/** Return a canonical representation for a string. + see rtl_ustring_intern. +*/ +void SAL_CALL rtl_uString_intern( rtl_uString ** newStr, + rtl_uString * str) SAL_THROW_EXTERN_C(); + +/** Return a canonical representation for a string. + + A pool of strings, initially empty is maintained privately + by the string class. On invocation, if present in the pool + the original string will be returned. Otherwise this string, + or a copy thereof will be added to the pool and returned. + + @param newStr + pointer to the new string. The pointed-to data must be null or a valid + string. + + @param str + a byte character array. Need not be null-terminated, but must be at + least as long as the specified len. + + @param len + the length of the byte character array. + + @param encoding + the text encoding to use for conversion. + + @return + a version of the string from the pool. + */ +void SAL_CALL rtl_uString_internConvert( rtl_uString ** newStr, + const sal_Char * str, + sal_Int32 len, + rtl_TextEncoding encoding, + sal_uInt32 convertFlags + ) SAL_THROW_EXTERN_C(); + #ifdef __cplusplus } #endif Index: sal/inc/rtl/ustring.hxx =================================================================== RCS file: /cvs/porting/sal/inc/rtl/ustring.hxx,v retrieving revision 1.27 retrieving revision 1.27.52.2 diff -u -p -u -r1.27 -r1.27.52.2 --- sal/inc/rtl/ustring.hxx 25 Sep 2006 13:13:38 -0000 1.27 +++ sal/inc/rtl/ustring.hxx 26 Jan 2007 15:07:03 -0000 1.27.52.2 @@ -4,9 +4,9 @@ * * $RCSfile: ustring.hxx,v $ * - * $Revision: 1.27 $ + * $Revision: 1.27.52.2 $ * - * last change: $Author: vg $ $Date: 2006/09/25 13:13:38 $ + * last change: $Author: mmeeks $ $Date: 2007/01/26 15:07:03 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -1082,6 +1082,59 @@ public: return rtl_ustr_toDouble( pData->buffer ); } + + /** + Return a canonical representation for a string. + + A pool of strings, initially empty is maintained privately + by the string class. On invocation, if present in the pool + the original string will be returned. Otherwise this string, + or a copy thereof will be added to the pool and returned. + + @return + a version of the string from the pool. + */ + OUString intern() SAL_THROW(()) + { + rtl_uString * pNew = 0; + rtl_uString_intern( &pNew, pData ); + return OUString( pNew, (DO_NOT_ACQUIRE *)0 ); + } + + /** + Return a canonical representation for a converted string. + + A pool of strings, initially empty is maintained privately + by the string class. On invocation, if present in the pool + the original string will be returned. Otherwise this string, + or a copy thereof will be added to the pool and returned. + + @param value a 8-Bit character array. + @param length the number of character which should be converted. + The 8-Bit character array length must be + greater or equal than this value. + @param encoding the text encoding from which the 8-Bit character + sequence should be converted. + @param convertFlags flags which controls the conversion. + see RTL_TEXTTOUNICODE_FLAGS_... + + @return + a version of the converted string from the pool. + */ + static OUString intern( const sal_Char * value, sal_Int32 length, + rtl_TextEncoding encoding, + sal_uInt32 convertFlags = OSTRING_TO_OUSTRING_CVTFLAGS ) SAL_THROW(()) + { + rtl_uString * pNew = 0; + rtl_uString_internConvert( &pNew, value, length, encoding, convertFlags ); + return OUString( pNew, (DO_NOT_ACQUIRE *)0 ); + } + + static OUString internAscii( const sal_Char * value ) SAL_THROW(()) + { + return intern( value, -1, RTL_TEXTENCODING_ASCII_US ); + } + /** Converts to an OString, signalling failure. Index: sal/qa/rtl/oustring/rtl_OUString2.cxx =================================================================== RCS file: /cvs/porting/sal/qa/rtl/oustring/rtl_OUString2.cxx,v retrieving revision 1.7 retrieving revision 1.7.58.1 diff -u -p -u -r1.7 -r1.7.58.1 --- sal/qa/rtl/oustring/rtl_OUString2.cxx 17 Sep 2006 08:58:11 -0000 1.7 +++ sal/qa/rtl/oustring/rtl_OUString2.cxx 26 Jan 2007 15:07:03 -0000 1.7.58.1 @@ -4,9 +4,9 @@ * * $RCSfile: rtl_OUString2.cxx,v $ * - * $Revision: 1.7 $ + * $Revision: 1.7.58.1 $ * - * last change: $Author: obo $ $Date: 2006/09/17 08:58:11 $ + * last change: $Author: mmeeks $ $Date: 2007/01/26 15:07:03 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -116,15 +116,6 @@ class valueOf : public CppUnit::TestFixt } public: - // initialise your test code values here. - void setUp() - { - } - - void tearDown() - { - } - // insert your test code here. void valueOf_float_test_001() { @@ -364,15 +355,6 @@ sal_Int16 SAL_CALL checkPrecisionSize() class toDouble : public CppUnit::TestFixture { public: - // initialise your test code values here. - void setUp() - { - } - - void tearDown() - { - } - void toDouble_test_impl(rtl::OString const& _sValue) { //t_print("the original str is %s\n", _sValue.getStr()); @@ -510,15 +492,6 @@ sal_Int16 SAL_CALL checkPrecisionSize() class toFloat : public CppUnit::TestFixture { public: - // initialise your test code values here. - void setUp() - { - } - - void tearDown() - { - } - void toFloat_test_impl(rtl::OString const& _sValue) { //t_print("the original str is %s\n", _sValue.getStr()); @@ -662,18 +635,6 @@ class lastIndexOf : public CppUnit::Test { public: - - // initialise your test code values here. - void setUp() - { - } - - void tearDown() - { - } - - // ----------------------------------------------------------------------------- - void lastIndexOf_oustring(rtl::OUString const& _suStr, rtl::OUString const& _suSearchStr, sal_Int32 _nExpectedResultPos) { // Algorithm @@ -889,18 +850,6 @@ class getToken : public CppUnit::TestFix { public: - - // initialise your test code values here. - void setUp() - { - } - - void tearDown() - { - } - - // ----------------------------------------------------------------------------- - void getToken_000() { rtl::OUString suTokenStr; @@ -1005,11 +954,51 @@ public: }; // class getToken // ----------------------------------------------------------------------------- +// - string construction & interning (tests) +// ----------------------------------------------------------------------------- +class construction : public CppUnit::TestFixture +{ +public: + void construct() + { + ::rtl::OUString aFoo( RTL_CONSTASCII_USTRINGPARAM("foo") ); + CPPUNIT_ASSERT_MESSAGE("string contents", aFoo[0] == 'f'); + CPPUNIT_ASSERT_MESSAGE("string contents", aFoo[1] == 'o'); + CPPUNIT_ASSERT_MESSAGE("string contents", aFoo[2] == 'o'); + CPPUNIT_ASSERT_MESSAGE("string length", aFoo.getLength() == 3); + + ::rtl::OUString aBaa( RTL_CONSTASCII_USTRINGPARAM("this is a very long string with a lot of long things inside it and it goes on and on and on forever etc.") ); + CPPUNIT_ASSERT_MESSAGE("string length", aBaa.getLength() == 104); + // Dig at the internals ... FIXME: should we have the bit-flag defines public ? + CPPUNIT_ASSERT_MESSAGE("string static flags", aBaa.pData->refCount & 1<<30); + } + + void intern() + { + ::rtl::OUString aFoo( RTL_CONSTASCII_USTRINGPARAM("foo") ); + ::rtl::OUString aFooIntern = aFoo.intern(); + CPPUNIT_ASSERT_MESSAGE("string contents", aFooIntern.equalsAscii("foo")); + CPPUNIT_ASSERT_MESSAGE("string length", aFooIntern.getLength() == 3); + // We have to dup due to no atomic 'intern' bit-set operation + CPPUNIT_ASSERT_MESSAGE("intern dups", aFoo.pData != aFooIntern.pData); + + ::rtl::OUString aFooIntern2 = rtl::OUString::internAscii("foo"); + CPPUNIT_ASSERT_MESSAGE("intern failed", aFooIntern.pData == aFooIntern2.pData); + } + + CPPUNIT_TEST_SUITE(construction); + CPPUNIT_TEST(construct); + CPPUNIT_TEST(intern); + CPPUNIT_TEST_SUITE_END(); +}; + +// ----------------------------------------------------------------------------- CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_OUString::valueOf, "rtl_OUString"); CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_OUString::toDouble, "rtl_OUString"); CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_OUString::toFloat, "rtl_OUString"); CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_OUString::lastIndexOf, "rtl_OUString"); CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_OUString::getToken, "rtl_OUString"); +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_OUString::construction, "rtl_OUString"); } // namespace rtl_OUString Index: sal/rtl/source/hash.c =================================================================== RCS file: sal/rtl/source/hash.c diff -N sal/rtl/source/hash.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sal/rtl/source/hash.c 26 Jan 2007 15:07:04 -0000 1.1.2.2 @@ -0,0 +1,155 @@ +#include + +#include "hash.h" +#include "strimp.h" + +// TODO: add bottom bit-set list terminator to string list + +static sal_uInt32 +getNextSize (sal_uInt32 nSize) +{ + return nSize * 2; +} + +static sal_uInt32 +hashString (rtl_uString *pString) +{ + return (sal_uInt32) rtl_ustr_hashCode_WithLength (pString->buffer, + pString->length); +} + +StringHashTable * +rtl_str_hash_new (sal_uInt32 nSize) +{ + StringHashTable *pHash = malloc (sizeof (StringHashTable)); + + pHash->nEntries = 0; + pHash->nSize = nSize; + pHash->pData = calloc (sizeof (rtl_uString *), nSize); + + return pHash; +} + +static void +rtl_str_hash_insert_nonequal (StringHashTable *pHash, + rtl_uString *pString) +{ + sal_uInt32 nHash = hashString (pString); + sal_uInt32 n; + rtl_uString *pHashStr; + + n = nHash % pHash->nSize; + while ((pHashStr = pHash->pData[n]) != NULL) { + n++; + if (n >= pHash->nSize) + n = 0; + } + pHash->pData[n] = pString; +} + +static void +rtl_str_hash_resize (StringHashTable *pHash, + sal_uInt32 nNewSize) +{ + sal_uInt32 i; + StringHashTable *pNewHash; + + OSL_ASSERT (nNewSize > pHash->nEntries); + + pNewHash = rtl_str_hash_new (nNewSize); + + for (i = 0; i < pHash->nSize; i++) + { + if (pHash->pData[i] != NULL) + rtl_str_hash_insert_nonequal (pNewHash, pHash->pData[i]); + } + free (pHash->pData); + *pHash = *pNewHash; + pNewHash->pData = NULL; + rtl_str_hash_free (pNewHash); +} + +void +rtl_str_hash_free (StringHashTable *pHash) +{ + if (!pHash) + return; + if (pHash->pData) + free (pHash->pData); + free (pHash); +} + +static int +compareEqual (rtl_uString *pStringA, rtl_uString *pStringB) +{ + if (pStringA == pStringB) + return 1; + if (pStringA->length != pStringB->length) + return 0; + return !rtl_ustr_compare_WithLength( pStringA->buffer, pStringA->length, + pStringB->buffer, pStringB->length); +} + +rtl_uString * +rtl_str_hash_intern (StringHashTable *pHash, + rtl_uString *pString, + int can_return) +{ + sal_uInt32 nHash = hashString (pString); + sal_uInt32 n; + rtl_uString *pHashStr; + + // Should we resize ? + if (pHash->nEntries >= pHash->nSize/2) + rtl_str_hash_resize (pHash, getNextSize(pHash->nSize)); + + n = nHash % pHash->nSize; + while ((pHashStr = pHash->pData[n]) != NULL) { + if (compareEqual (pHashStr, pString)) + { + rtl_uString_acquire (pHashStr); + return pHashStr; + } + n++; + if (n >= pHash->nSize) + n = 0; + } + if (!can_return) + rtl_uString_newFromString( &pString, pString ); + + pString->refCount |= SAL_STRING_INTERN_FLAG; + pHash->pData[n] = pString; + + return pString; +} + +void +rtl_str_hash_remove (StringHashTable *pHash, + rtl_uString *pString) +{ + sal_uInt32 n; + sal_uInt32 nHash = hashString (pString); + rtl_uString *pHashStr; + + n = nHash % pHash->nSize; + while ((pHashStr = pHash->pData[n]) != NULL) { + if (compareEqual (pHashStr, pString)) + break; + n++; + if (n >= pHash->nSize) + n = 0; + } + OSL_ASSERT (pHash->pData[n] != 0); + pHash->pData[n++] = NULL; + + while ((pHashStr = pHash->pData[n]) != NULL) { + pHash->pData[n] = NULL; + // FIXME: rather unsophisticated and N^2 in chain-length + rtl_str_hash_insert_nonequal (pHash, pHashStr); + n++; + if (n >= pHash->nSize) + n = 0; + } + + // FIXME: Should we down-size ? +} Index: sal/rtl/source/hash.h =================================================================== RCS file: sal/rtl/source/hash.h diff -N sal/rtl/source/hash.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sal/rtl/source/hash.h 25 Jan 2007 17:56:37 -0000 1.1.2.1 @@ -0,0 +1,33 @@ +#ifndef INCLUDED_RTL_SOURCE_HASH_H +#define INCLUDED_RTL_SOURCE_HASH_H + +#ifndef _SAL_TYPES_H_ +#include +#endif +#ifndef _RTL_USTRING_H_ +#include +#endif + +#if defined __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct { + sal_uInt32 nEntries; + sal_uInt32 nSize; + rtl_uString **pData; +} StringHashTable; + +StringHashTable *rtl_str_hash_new (sal_uInt32 nSize); +void rtl_str_hash_free (StringHashTable *pHash); +rtl_uString *rtl_str_hash_intern (StringHashTable *pHash, + rtl_uString *pString, + int can_return); +void rtl_str_hash_remove (StringHashTable *pHash, + rtl_uString *pString); + +#if defined __cplusplus +} +#endif /* __cplusplus */ + +#endif /* INCLUDED_RTL_SOURCE_HASH_H */ Index: sal/rtl/source/makefile.mk =================================================================== RCS file: /cvs/porting/sal/rtl/source/makefile.mk,v retrieving revision 1.26 retrieving revision 1.26.30.1 diff -u -p -u -r1.26 -r1.26.30.1 --- sal/rtl/source/makefile.mk 5 Oct 2006 10:45:36 -0000 1.26 +++ sal/rtl/source/makefile.mk 25 Jan 2007 17:56:37 -0000 1.26.30.1 @@ -4,9 +4,9 @@ # # $RCSfile: makefile.mk,v $ # -# $Revision: 1.26 $ +# $Revision: 1.26.30.1 $ # -# last change: $Author: kz $ $Date: 2006/10/05 10:45:36 $ +# last change: $Author: mmeeks $ $Date: 2007/01/25 17:56:37 $ # # The Contents of this file are made available subject to # the terms of GNU Lesser General Public License Version 2.1. @@ -73,6 +73,7 @@ SLOFILES= \ $(SLO)$/random.obj \ $(SLO)$/locale.obj \ $(SLO)$/strimp.obj \ + $(SLO)$/hash.obj \ $(SLO)$/string.obj \ $(SLO)$/ustring.obj \ $(SLO)$/strbuf.obj \ @@ -102,6 +103,7 @@ OBJFILES= \ $(OBJ)$/random.obj \ $(OBJ)$/locale.obj \ $(OBJ)$/strimp.obj \ + $(OBJ)$/hash.obj \ $(OBJ)$/string.obj \ $(OBJ)$/ustring.obj \ $(OBJ)$/strbuf.obj \ Index: sal/rtl/source/strimp.h =================================================================== RCS file: /cvs/porting/sal/rtl/source/strimp.h,v retrieving revision 1.3 retrieving revision 1.3.204.1 diff -u -p -u -r1.3 -r1.3.204.1 --- sal/rtl/source/strimp.h 8 Sep 2005 16:05:25 -0000 1.3 +++ sal/rtl/source/strimp.h 25 Jan 2007 17:56:37 -0000 1.3.204.1 @@ -4,9 +4,9 @@ * * $RCSfile: strimp.h,v $ * - * $Revision: 1.3 $ + * $Revision: 1.3.204.1 $ * - * last change: $Author: rt $ $Date: 2005/09/08 16:05:25 $ + * last change: $Author: mmeeks $ $Date: 2007/01/25 17:56:37 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -36,6 +36,10 @@ #ifndef INCLUDED_RTL_SOURCE_STRIMP_H #define INCLUDED_RTL_SOURCE_STRIMP_H +#ifndef _OSL_INTERLOCK_H_ +#include +#endif + #include "sal/types.h" /* ======================================================================= */ @@ -46,6 +50,21 @@ extern "C" { #endif /* __cplusplus */ +#define SAL_INTERLOCK_BITS (sizeof(oslInterlockedCount) * 8) + + +/* + * 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 (1<<(SAL_INTERLOCK_BITS-1)) +#define SAL_STRING_STATIC_FLAG (1<<(SAL_INTERLOCK_BITS-2)) + +#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 ); Index: sal/rtl/source/string.c =================================================================== RCS file: /cvs/porting/sal/rtl/source/string.c,v retrieving revision 1.15 retrieving revision 1.15.52.1 diff -u -p -u -r1.15 -r1.15.52.1 --- sal/rtl/source/string.c 25 Sep 2006 13:14:24 -0000 1.15 +++ sal/rtl/source/string.c 25 Jan 2007 17:56:37 -0000 1.15.52.1 @@ -4,9 +4,9 @@ * * $RCSfile: string.c,v $ * - * $Revision: 1.15 $ + * $Revision: 1.15.52.1 $ * - * last change: $Author: vg $ $Date: 2006/09/25 13:14:24 $ + * last change: $Author: mmeeks $ $Date: 2007/01/25 17:56:37 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -71,7 +71,8 @@ // MT: Should be const, but doesn't work because of #i64835# static rtl_String aImplEmpty_rtl_String = { - 1, /* sal_Int32 refCount; */ + SAL_STRING_STATIC_FLAG|1, + /* sal_Int32 refCount; */ 0, /* sal_Int32 length; */ { 0 } /* sal_Char buffer[1]; */ }; Index: sal/rtl/source/strtmpl.c =================================================================== RCS file: /cvs/porting/sal/rtl/source/strtmpl.c,v retrieving revision 1.22 retrieving revision 1.22.94.1 diff -u -p -u -r1.22 -r1.22.94.1 --- sal/rtl/source/strtmpl.c 20 Jun 2006 04:30:39 -0000 1.22 +++ sal/rtl/source/strtmpl.c 25 Jan 2007 17:56:37 -0000 1.22.94.1 @@ -4,9 +4,9 @@ * * $RCSfile: strtmpl.c,v $ * - * $Revision: 1.22 $ + * $Revision: 1.22.94.1 $ * - * last change: $Author: hr $ $Date: 2006/06/20 04:30:39 $ + * last change: $Author: mmeeks $ $Date: 2007/01/25 17:56:37 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -1025,7 +1025,7 @@ static IMPL_RTL_STRCODE* IMPL_RTL_STRING #define IMPL_RTL_AQUIRE( pThis ) \ { \ - if (pThis != &IMPL_RTL_EMPTYSTRING) \ + if (!SAL_STRING_IS_STATIC (pThis)) \ osl_incrementInterlockedCount( &((pThis)->refCount) ); \ } @@ -1040,17 +1040,15 @@ void SAL_CALL IMPL_RTL_STRINGNAME( acqui void SAL_CALL IMPL_RTL_STRINGNAME( release )( IMPL_RTL_STRINGDATA* pThis ) { - if (pThis == &IMPL_RTL_EMPTYSTRING) - return; + if (SAL_STRING_IS_STATIC (pThis)) + return; if ( pThis->refCount == 1 ) { - OSL_ENSURE( pThis != &IMPL_RTL_EMPTYSTRING, "static empty string: refCount < 1" ); rtl_freeMemory( pThis ); } else if ( !osl_decrementInterlockedCount( &(pThis->refCount) ) ) { - OSL_ENSURE( IMPL_RTL_EMPTYSTRING.refCount >= 1, "static empty string: refCount < 1" ); rtl_freeMemory( pThis ); } } Index: sal/rtl/source/ustring.c =================================================================== RCS file: /cvs/porting/sal/rtl/source/ustring.c,v retrieving revision 1.24 retrieving revision 1.24.38.3 diff -u -p -u -r1.24 -r1.24.38.3 --- sal/rtl/source/ustring.c 27 Oct 2006 12:14:32 -0000 1.24 +++ sal/rtl/source/ustring.c 26 Jan 2007 16:30:55 -0000 1.24.38.3 @@ -4,9 +4,9 @@ * * $RCSfile: ustring.c,v $ * - * $Revision: 1.24 $ + * $Revision: 1.24.38.3 $ * - * last change: $Author: rt $ $Date: 2006/10/27 12:14:32 $ + * last change: $Author: mmeeks $ $Date: 2007/01/26 16:30:55 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -49,11 +49,17 @@ #ifndef _RTL_ALLOC_H_ #include #endif +#include +#include #ifndef _RTL_TENCINFO_H #include #endif +#include +#include + +#include "hash.h" #include "strimp.h" #ifndef _RTL_USTRING_H_ @@ -71,9 +77,9 @@ // MT: Should be const, but doesn't work because of #i64835# static rtl_uString aImplEmpty_rtl_uString = { - 1, /* sal_Int32 refCount; */ - 0, /* sal_Int32 length; */ - { 0 } /* sal_Unicode buffer[1]; */ + SAL_STRING_STATIC_FLAG|1, /* sal_Int32 refCount; */ + 0, /* sal_Int32 length; */ + { 0 } /* sal_Unicode buffer[1]; */ }; /* ======================================================================= */ @@ -615,3 +621,104 @@ void SAL_CALL rtl_string2UString( rtl_uS } } } + +/* ----------------------------------------------------------------------- */ + +#define CAN_RETURN 1 +#define CANNOT_RETURN 0 + +static oslMutex +getInternMutex() +{ + static oslMutex pPoolGuard = NULL; + if( !pPoolGuard ) + { + oslMutex pGlobalGuard; + pGlobalGuard = *osl_getGlobalMutex(); + osl_acquireMutex( pGlobalGuard ); + if( !pPoolGuard ) + { + OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); + pPoolGuard = osl_createMutex(); + } + 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, + int can_return ) +{ + static StringHashTable *pPool = NULL; + + oslMutex pPoolMutex; + + pPoolMutex = getInternMutex(); + osl_acquireMutex( pPoolMutex ); + + if (!pPool) { + pPool = rtl_str_hash_new (1024); + } + + *newStr = rtl_str_hash_intern (pPool, str, can_return); + if( can_return && *newStr != str ) + { /* we dupped, then found a match */ + rtl_freeMemory( str ); + } + + osl_releaseMutex( pPoolMutex ); +} + +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_intern_internal( newStr, str, CANNOT_RETURN ); +} + +void SAL_CALL rtl_uString_internConvert( rtl_uString ** newStr, + const sal_Char * str, + sal_Int32 len, + rtl_TextEncoding eTextEncoding, + sal_uInt32 convertFlags ) +{ + rtl_uString *scratch; + + if ( len < 256 ) + { // try various optimisations + 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; + } + /* FIXME: we want a nice UTF-8 / alloca shortcut here */ + } + + scratch = NULL; + rtl_string2UString( &scratch, str, len, eTextEncoding, convertFlags ); + rtl_ustring_intern_internal( newStr, scratch, CAN_RETURN ); +} Index: sal/util/sal.map =================================================================== RCS file: /cvs/porting/sal/util/sal.map,v retrieving revision 1.57 retrieving revision 1.57.78.1 diff -u -p -u -r1.57 -r1.57.78.1 --- sal/util/sal.map 26 Jul 2006 07:46:09 -0000 1.57 +++ sal/util/sal.map 26 Jan 2007 15:07:05 -0000 1.57.78.1 @@ -312,6 +312,8 @@ UDK_3_0_0 { rtl_uString_newTrim; rtl_uString_new_WithLength; rtl_uString_release; + rtl_uString_intern; + rtl_uString_internConvert; rtl_uStringbuffer_ensureCapacity; rtl_uStringbuffer_insert; rtl_uStringbuffer_insert_ascii;