Re: Lacking of a ref-counted string.



On 25/08/2008, "Paul LeoNerd Evans" wrote:

> On Sat, 23 Aug 2008 "Havoc Pennington" wrote:
>> If you're talking about converting existing APIs to refcounted
>> strings, that's a very different proposal from just adding some kind
>> of refcounted string feature. It would break thousands of apps, or
>> else duplicate hundreds of API entry points ...
> Personally, I didn't have in mind a change of existing API;
> simply an addition of something new:

While moderately handy, GString is nowhere near as useful as it could be, so I'd say if you're going to add ref-counted strings than it's safe to just add ref-count directly to GString.  I doubt it'll have a notable impact even in apps where it's not needed.  I can't think of any occasion when I've actually used a bare GString, it just doesn't do anything that can't be done better.


>     typedef struct {
>         gchar *str;
>         gsize len;
>         gint refcount;
>     } GCString;

Your GCString, like my ZString below, is somewhat more useful due to the ref-counting.  But until it's supported in a useful way by GLib and GTK natively, it may as well just be a chunk of text on a wiki page somewhere for people to copy and paste verbatim into their own projects.

What I generally do is use a very simple GString wrapper;
    typedef struct {
        GString str;
        gint refcount;
    } ZString;
and then a bunch of #defines to wrap most of the GString functions with appropriate type-casting back and forth.  The only functions that actually need re-implementing are the new/free ones.  It ain't pretty, but it works.


>     GCString *g_cstring_new_static(gchar *static_data);
>     GCString *g_cstring_new_from_gstring(GString *clone);
>     GCString *g_cstring_ref(GCString *str);
>     void g_cstring_unref(GCstring *str);

    GCString *g_cstring_new(gchar *dynamic_data);
which takes over ownership of an already-allocated string.  len and allocated_len are both set from strlen().

With an allocated_len field you can also indicate static string data by leaving it at zero.  (is_static = str && ! allocated_len)  That also makes this useful:

    GCString *g_cstring_new_full(gchar *dynamic_data, gint len, gint allocated_len);
which does everything that all three of them do.  If len is -ve, it's set from strlen(), likewise if allocated_len is -ve, it's set from len.  _new and _new_static could then simply be wrappers to _new_full(), although being as simple as they are it'd probably be better to keep them as discrete functions.


Fredderic


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]