Date: prev next · Thread: first prev next last
2011 Archives by date, by thread · List index


On Aug 31, 2011, at 12:04 PM, Caolán McNamara wrote:
rtl_string_new_WithLength/rtl_uString_new_WithLength create an
rtl/String/rtl_uString of the given length, but set the full buffer
contents to 0s[1]

No idea whether specifying that the "values of all characters are set to 0" was meant to be 
actually useful (and is exploited somewhere) or was misguided overeagerness.

meanwhile I see that we have x_rtl_uString_new_WithLength in
inc/i18nutil/x_rtl_ustring.h which is a non-zeroed out variant of
rtl_uString_new_WithLength so there's an uninitialized buffer available
to play with.

We can assign ownership of the rtl_uString to an OUString with
OUString( rtl_uString * str, __sal_NoAcquire ) and skip calling acquire,
i.e. OUString has *two* methods to take ownership of a rtl_uString
without calling acquire.
the public OUString( rtl_uString * str, __sal_NoAcquire )
the private OUString( rtl_uString * value, DO_NOT_ACQUIRE * )
as well as the usual add-add-refcount version of
OUString( rtl_uString * str ) 

While OString has only the private 
OString( rtl_String * value, DO_NOT_ACQUIRE * )
as well as the usual add-add-refcount version of
OString( rtl_String * str ), so the same hack isn't available.

No reason to not add a OString(…, __sal_NoAcquire) variant, too, I would say.

I'm vaguely thinking of moving that i18nutil x_rtl stuff into
comphelper/string or something, hard-coding its refcount argument to 0
or 1 and fixing up its uses to consistently use one or the other public
OUString acquire/noacquire ctors and add a OString variant so that
either of the belows is possible to skip copying buffers around the
place.

#if thinko-one
rtl_String *pStr = foo_rtl_string_new_WithLength(nLen/*, refCount=0*/);
//call acquire, refCount of 1, OString::dtor destroys buffer
rtl::OString aRet(pStr);
pStr->length = rStrm.Read(pStr->buffer, nLen);
#else
rtl_String *pStr = foo_rtl_string_new_WithLength(nLen/*, refCount=1*/);
//don't call acquire, refCount stays 1, OString::dtor destroys buffer
rtl::OString aRet(pStr, SAL_NO_ACQUIRE);
pStr->length = rStrm.Read(pStr->buffer, nLen);
#endif

I would go with the second choice.  foo_rtl_string_new_WithLength creates and returns a new 
resource that the caller is responsible of eventually releasing again, be it via an explicit 
rtl_string_release or via the SAL_NO_ACQUIRE trick.  Also, that way its behavior is similar to 
plain rtl_string_new_WithLength, and adding the corresponding optimization for nLen=0 in the future 
would be straightforward.

//if unlikely length != nLen make deep copy of string to release excess
//mem, nobody seems to worry about excess for rtl::O[U]String buffers,
//but much less opportunity to have a large chunk of unused
//buffer there.

C.

[1] with a loop, I suppose its no real optimization there to use memset
or rtl_allocateMemory for that case ?

Wouldn't hurt to use memset instead, I'd say.  Even if all compilers reduced the loop to something 
as efficient, using memset would still be shorter than that verbose loop.

-Stephan

Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.