# HG changeset patch # User Ethan Blanton # Date 1070643363 0 # Node ID dc79649b829d63d6ef3a7841d0ff31d9a11f8603 # Parent 5f1908a49c788a93231c1073c0696f6a53824eec [gaim-migrate @ 8408] This is an implementation of immutable, reference-counted strings. It is exceedingly trivial, I have no idea why I didn't do this long ago... PLEASE use these anywhere you pass around strings that may be stuck in multiple places; I'm not sure that it will save us too much heap holistically, but it should prevent having to make a hojillion twenty-byte allocations and free them immediately. committer: Tailor Script diff -r 5f1908a49c78 -r dc79649b829d src/Makefile.am --- a/src/Makefile.am Fri Dec 05 16:22:49 2003 +0000 +++ b/src/Makefile.am Fri Dec 05 16:56:03 2003 +0000 @@ -97,6 +97,8 @@ signals.h \ status.c \ status.h \ + stringref.c \ + stringref.h \ sound.c \ sound.h \ sslconn.c \ diff -r 5f1908a49c78 -r dc79649b829d src/stringref.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/stringref.c Fri Dec 05 16:56:03 2003 +0000 @@ -0,0 +1,60 @@ +/** + * @file stringref.c Reference-counted strings + * @ingroup core + * + * gaim + * + * Copyright (C) 2003 Ethan Blanton + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "internal.h" + +#include + +#include "stringref.h" + +GaimStringref *gaim_stringref_new(const char *value) +{ + GaimStringref *newref; + + newref = g_malloc(sizeof(GaimStringref) + strlen(value) + 1); + strcpy(newref->value, value); + newref->ref = 1; + + return newref; +} + +GaimStringref *gaim_stringref_ref(GaimStringref *stringref) +{ + if (stringref == NULL) + return NULL; + stringref->ref++; + return stringref; +} + +void gaim_stringref_unref(GaimStringref *stringref) +{ + g_return_if_fail(stringref != NULL); + if (--stringref->ref == 0) + g_free(stringref); +} + +const char *gaim_stringref_value(GaimStringref *stringref) +{ + return (stringref == NULL ? NULL : stringref->value); +} diff -r 5f1908a49c78 -r dc79649b829d src/stringref.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/stringref.h Fri Dec 05 16:56:03 2003 +0000 @@ -0,0 +1,85 @@ +/** + * @file stringref.h Reference-counted immutable strings + * @ingroup core + * + * gaim + * + * Copyright (C) 2003 Ethan Blanton + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _GAIM_STRINGREF_H_ +#define _GAIM_STRINGREF_H_ + +/** + * @note For this structure to be useful, the string contained within + * it must be immutable -- for this reason, do _not_ access it + * directly! + */ +typedef struct _GaimStringref { + int ref; + char value[0]; +} GaimStringref; + +/** + * Creates an immutable reference-counted string object. The newly + * created object will have a reference count of 1. + * + * @param value This will be the value of the string; it will be + * duplicated. + * + * @return A newly allocated string reference object. + */ +GaimStringref *gaim_stringref_new(const char *value); + +/** + * Increase the reference count of the given stringref. + * + * @param stringref String to be referenced. + * + * @return A pointer to the referenced string. + */ +GaimStringref *gaim_stringref_ref(GaimStringref *stringref); + +/** + * Decrease the reference count of the given stringref. If this + * reference count reaches zero, the stringref will be freed; thus + * you MUST NOT use this string after dereferencing it. + * + * @param stringref String to be dereferenced. + */ +void gaim_stringref_unref(GaimStringref *stringref); + +/** + * Retrieve the value of a stringref. + * + * @note This value should not be cached or stored in a local variable. + * While there is nothing inherently incorrect about doing so, it + * is easy to forget that the cached value is in fact a + * reference-counted object and accidentally use it after + * dereferencing. This is more problematic for a reference- + * counted object than a heap-allocated object, as it may seem to + * be valid or invalid nondeterministically based on how many + * other references to it exist. + * + * @param stringref String reference from which to retrieve the value. + * + * @return The contents of the string reference. + */ +const char *gaim_stringref_value(GaimStringref *stringref); + +#endif /* _GAIM_STRINGREF_H_ */