1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Authors: Jeffrey Stedfast <fejj@ximian.com>
5 * Copyright 2002 Ximian, Inc. (www.ximian.com)
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31 #include "camel-string-utils.h"
34 camel_strcase_equal (gconstpointer a, gconstpointer b)
36 return (g_ascii_strcasecmp ((const char *) a, (const char *) b) == 0);
40 camel_strcase_hash (gconstpointer v)
42 const char *p = (char *) v;
45 for ( ; *p != '\0'; p++) {
46 h = (h << 4) + g_ascii_toupper (*p);
47 if ((g = h & 0xf0000000)) {
58 free_string (gpointer string, gpointer user_data)
64 camel_string_list_free (GList *string_list)
66 if (string_list == NULL)
69 g_list_foreach (string_list, free_string, NULL);
70 g_list_free (string_list);
74 camel_strstrcase (const char *haystack, const char *needle)
76 /* find the needle in the haystack neglecting case */
80 g_return_val_if_fail (haystack != NULL, NULL);
81 g_return_val_if_fail (needle != NULL, NULL);
83 len = strlen (needle);
84 if (len > strlen (haystack))
88 return (char *) haystack;
90 for (ptr = haystack; *(ptr + len - 1) != '\0'; ptr++)
91 if (!g_ascii_strncasecmp (ptr, needle, len))
99 camel_strdown (char *str)
101 register char *s = str;
104 if (*s >= 'A' && *s <= 'Z')
116 * ASCII to-lower function.
120 char camel_tolower(char c)
122 if (c >= 'A' && c <= 'Z')
132 * ASCII to-upper function.
136 char camel_toupper(char c)
138 if (c >= 'a' && c <= 'z')
144 /* working stuff for pstrings */
145 static pthread_mutex_t pstring_lock = PTHREAD_MUTEX_INITIALIZER;
146 static GHashTable *pstring_table = NULL;
150 * @str: string to add to the string pool
151 * @own: whether the string pool will own the memory pointed to by @str, if @str is not yet in the pool
153 * Add the string to the pool.
155 * The NULL and empty strings are special cased to constant values.
157 * Return value: A pointer to an equivalent string of @s. Use
158 * camel_pstring_free() when it is no longer needed.
161 camel_pstring_add (char *str, gboolean own)
170 if (str[0] == '\0') {
176 pthread_mutex_lock (&pstring_lock);
177 if (pstring_table == NULL)
178 pstring_table = g_hash_table_new (g_str_hash, g_str_equal);
180 if (g_hash_table_lookup_extended (pstring_table, str, (void **) &pstr, &pcount)) {
181 count = GPOINTER_TO_INT (pcount) + 1;
182 g_hash_table_insert (pstring_table, pstr, GINT_TO_POINTER (count));
186 pstr = own ? str : g_strdup (str);
187 g_hash_table_insert (pstring_table, pstr, GINT_TO_POINTER (1));
190 pthread_mutex_unlock (&pstring_lock);
197 * camel_pstring_strdup:
198 * @s: String to copy.
200 * Create a new pooled string entry for the string @s. A pooled
201 * string is a table where common strings are uniquified to the same
202 * pointer value. They are also refcounted, so freed when no longer
203 * in use. In a thread-safe manner.
205 * The NULL and empty strings are special cased to constant values.
207 * Return value: A pointer to an equivalent string of @s. Use
208 * camel_pstring_free() when it is no longer needed.
211 camel_pstring_strdup (const char *s)
213 return camel_pstring_add ((char *) s, FALSE);
218 * camel_pstring_free:
219 * @s: String to free.
221 * De-ref a pooled string. If no more refs exist to this string, it will be deallocated.
223 * NULL and the empty string are special cased.
226 camel_pstring_free(const char *s)
232 if (pstring_table == NULL)
234 if (s == NULL || s[0] == 0)
237 pthread_mutex_lock(&pstring_lock);
238 if (g_hash_table_lookup_extended(pstring_table, s, (void **)&p, &pcount)) {
239 count = GPOINTER_TO_INT(pcount)-1;
241 g_hash_table_remove(pstring_table, p);
244 g_hash_table_insert(pstring_table, p, GINT_TO_POINTER(count));
247 g_warning("Trying to free string not allocated from the pool '%s'", s);
249 pthread_mutex_unlock(&pstring_lock);