[Mono-devel-list] StringBuilder patch
Paolo Molaro
lupus at ximian.com
Mon Jan 12 11:28:30 EST 2004
On 12/12/03 Torstensson, Patrik wrote:
> diff -u -r1.108 object.h
> --- object.h 7 Dec 2003 13:12:09 -0000 1.108
> +++ object.h 12 Dec 2003 21:21:01 -0000
> @@ -112,9 +112,8 @@
>
> typedef struct {
> MonoObject object;
> - gint32 capacity;
> gint32 length;
> - MonoArray *chars;
> + MonoString *str;
> } MonoStringBuilder;
>
> typedef struct {
> Index: marshal.c
> ===================================================================
> RCS file: /cvs/public/mono/mono/metadata/marshal.c,v
> retrieving revision 1.130
> diff -u -r1.130 marshal.c
> --- marshal.c 9 Dec 2003 14:30:48 -0000 1.130
> +++ marshal.c 12 Dec 2003 21:21:05 -0000
> @@ -167,12 +167,12 @@
> l = strlen (text);
>
> ut = g_utf8_to_utf16 (text, l, NULL, &items_written, &error);
> -
> - if (items_written > sb->capacity)
> - items_written = sb->capacity;
> +
> + if (items_written > sb->str->length)
> + items_written = sb->str->length;
Add a comment there, something like:
/* sb->str->length is the StringBuilder capacity */
or, maybe better, add a macro to the header file and use that:
#define mono_stringbuilder_capacity(sb) ((sb)->str->length)
> Index: System/String.cs
> ===================================================================
> RCS file: /cvs/public/mcs/class/corlib/System/String.cs,v
> retrieving revision 1.98
> diff -u -r1.98 String.cs
> --- System/String.cs 6 Dec 2003 16:54:59 -0000 1.98
> +++ System/String.cs 12 Dec 2003 23:43:26 -0000
[...]
> @@ -1197,7 +1197,26 @@
> ptr = p;
> return n;
> }
> -
> +
> + internal unsafe void InternalSetChar(int idx, char val)
> + {
> + if ((UInt32) idx >= (UInt32) Length)
Use:
if ((uint) idx >= (uint) length)
> diff -u -r1.26 StringBuilder.cs
> --- System.Text/StringBuilder.cs 17 Nov 2003 22:42:53 -0000 1.26
> +++ System.Text/StringBuilder.cs 12 Dec 2003 23:43:26 -0000
[...]
> - public override string ToString() {
> - if (thestring != null)
> - return thestring;
> - return (thestring = ToString(0, sLength));
> + public override string ToString ()
> + {
> + if (_length == 0)
> + return String.Empty;
> +
> + if (null != _cached_str)
> + return _cached_str;
> +
> + // If we only have a half-full buffer we return a new string.
> + if (_length < (_str.Length / 2))
Use a shift directly here, instead of the division, so we don't have to
bother optimizing it.
> + {
> + _cached_str = _str.Substring(0, _length);
> + return _cached_str;
> + }
> +
> + _cached_str = _str;
> + _str.InternalSetLength(_length);
> +
> + return _str;
> }
Strings have the property that they are 0-terminated (so they can be
passed to P/Invoked methods without a copy). Maybe the best place to
ensure that is String.InternalSetLength(). The old impl got this for
free, since we always alloc strings with one char more than their
length, but in the stringbuilder there could be a non-zero char
left there from previous operations.
Thanks. The patch can be committed (sorry it took a long time to review it).
lupus
--
-----------------------------------------------------------------
lupus at debian.org debian/rules
lupus at ximian.com Monkeys do it better
More information about the Mono-devel-list
mailing list