diff options
author | Not Zed <NotZed@Ximian.com> | 2004-11-12 13:53:12 +0800 |
---|---|---|
committer | Michael Zucci <zucchi@src.gnome.org> | 2004-11-12 13:53:12 +0800 |
commit | 8e212824134c1740d05fb36799f78716c5059801 (patch) | |
tree | 47fc692dba176af4fa0ccfa45d31739886162c12 /camel/camel-string-utils.c | |
parent | 55bead18b69fd4e7ad2b09700867add2ca7e9838 (diff) | |
download | gsoc2013-evolution-8e212824134c1740d05fb36799f78716c5059801.tar.gz gsoc2013-evolution-8e212824134c1740d05fb36799f78716c5059801.tar.zst gsoc2013-evolution-8e212824134c1740d05fb36799f78716c5059801.zip |
** Merge in notzed-messageinfo-branch, fix some minor conflicts.
2004-11-12 Not Zed <NotZed@Ximian.com>
** Merge in notzed-messageinfo-branch, fix some minor conflicts.
svn path=/trunk/; revision=27898
Diffstat (limited to 'camel/camel-string-utils.c')
-rw-r--r-- | camel/camel-string-utils.c | 80 |
1 files changed, 79 insertions, 1 deletions
diff --git a/camel/camel-string-utils.c b/camel/camel-string-utils.c index 6949a9aa53..c169c8a65a 100644 --- a/camel/camel-string-utils.c +++ b/camel/camel-string-utils.c @@ -26,10 +26,10 @@ #endif #include <string.h> +#include <pthread.h> #include "camel-string-utils.h" - int camel_strcase_equal (gconstpointer a, gconstpointer b) { @@ -141,3 +141,81 @@ char camel_toupper(char c) return c; } +/* working stuff for pstrings */ +static pthread_mutex_t pstring_lock = PTHREAD_MUTEX_INITIALIZER; +static GHashTable *pstring_table = NULL; + +/** + * camel_pstring_strdup: + * @s: String to copy. + * + * Create a new pooled string entry for the string @s. A pooled + * string is a table where common strings are uniquified to the same + * pointer value. They are also refcounted, so freed when no longer + * in use. In a thread-safe manner. + * + * The NULL and empty strings are special cased to constant values. + * + * Return value: A pointer to an equivalent string of @s. Use + * camel_pstring_free() when it is no longer needed. + **/ +const char *camel_pstring_strdup(const char *s) +{ + char *p; + void *pcount; + int count; + + if (s == NULL) + return NULL; + if (s[0] == 0) + return ""; + + pthread_mutex_lock(&pstring_lock); + if (pstring_table == NULL) + pstring_table = g_hash_table_new(g_str_hash, g_str_equal); + + if (g_hash_table_lookup_extended(pstring_table, s, (void **)&p, &pcount)) { + count = GPOINTER_TO_INT(pcount)+1; + g_hash_table_insert(pstring_table, p, GINT_TO_POINTER(count)); + } else { + p = g_strdup(s); + g_hash_table_insert(pstring_table, p, GINT_TO_POINTER(1)); + } + pthread_mutex_unlock(&pstring_lock); + + return p; +} + +/** + * camel_pstring_free: + * @s: String to free. + * + * De-ref a pooled string. If no more refs exist to this string, it will be deallocated. + * + * NULL and the empty string are special cased. + **/ +void camel_pstring_free(const char *s) +{ + char *p; + void *pcount; + int count; + + if (pstring_table == NULL) + return; + if (s == NULL || s[0] == 0) + return; + + pthread_mutex_lock(&pstring_lock); + if (g_hash_table_lookup_extended(pstring_table, s, (void **)&p, &pcount)) { + count = GPOINTER_TO_INT(pcount)-1; + if (count == 0) { + g_hash_table_remove(pstring_table, p); + g_free(p); + } else { + g_hash_table_insert(pstring_table, p, GINT_TO_POINTER(count)); + } + } else { + g_warning("Trying to free string not allocated from the pool '%s'", s); + } + pthread_mutex_unlock(&pstring_lock); +} |