1 /*
2 * e-poolv.c
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18 #include "evolution-config.h"
19
20 #include "e-poolv.h"
21
22 #include <string.h>
23 #include <camel/camel.h>
24
25 struct _EPoolv {
26 guchar length;
27 const gchar *s[1];
28 };
29
30 /**
31 * e_poolv_new:
32 * @size: The number of elements in the poolv, maximum of 254 elements.
33 *
34 * Create a new #EPoolv: a string vector which shares a global string
35 * pool. An #EPoolv can be used to work with arrays of strings which
36 * save memory by eliminating duplicated allocations of the same string.
37 *
38 * This is useful when you have a log of read-only strings that do not
39 * go away and are duplicated a lot, such as email headers.
40 *
41 * Returns: a new #EPoolv
42 **/
43 EPoolv *
e_poolv_new(guint size)44 e_poolv_new (guint size)
45 {
46 EPoolv *poolv;
47
48 g_return_val_if_fail (size < 255, NULL);
49
50 poolv = g_malloc0 (sizeof (*poolv) + (size - 1) * sizeof (gchar *));
51 poolv->length = size;
52
53 return poolv;
54 }
55
56 /**
57 * e_poolv_set:
58 * @poolv: pooled string vector
59 * @index: index in vector of string
60 * @str: string to set
61 * @freeit: whether the caller is releasing its reference to the
62 * string
63 *
64 * Set a string vector reference. If the caller will no longer be
65 * referencing the string, freeit should be TRUE. Otherwise, this
66 * will duplicate the string if it is not found in the pool.
67 *
68 * Returns: @poolv
69 **/
70 EPoolv *
e_poolv_set(EPoolv * poolv,gint index,gchar * str,gint freeit)71 e_poolv_set (EPoolv *poolv,
72 gint index,
73 gchar *str,
74 gint freeit)
75 {
76 const gchar *old_str;
77
78 g_return_val_if_fail (poolv != NULL, NULL);
79 g_return_val_if_fail (index >= 0 && index < poolv->length, NULL);
80
81 if (!str) {
82 camel_pstring_free (poolv->s[index]);
83 poolv->s[index] = NULL;
84 return poolv;
85 }
86
87 old_str = poolv->s[index];
88 poolv->s[index] = (gchar *) camel_pstring_add (str, freeit);
89
90 camel_pstring_free (old_str);
91
92 return poolv;
93 }
94
95 /**
96 * e_poolv_get:
97 * @poolv: pooled string vector
98 * @index: index in vector of string
99 *
100 * Retrieve a string by index. This could possibly just be a macro.
101 *
102 * Since the pool is never freed, this string does not need to be
103 * duplicated, but should not be modified.
104 *
105 * Returns: string at that index.
106 **/
107 const gchar *
e_poolv_get(EPoolv * poolv,gint index)108 e_poolv_get (EPoolv *poolv,
109 gint index)
110 {
111 g_return_val_if_fail (poolv != NULL, NULL);
112 g_return_val_if_fail (index >= 0 && index < poolv->length, NULL);
113
114 return poolv->s[index] ? poolv->s[index] : "";
115 }
116
117 /**
118 * e_poolv_destroy:
119 * @poolv: pooled string vector to free
120 *
121 * Free a pooled string vector. This doesn't free the strings from
122 * the vector, however.
123 **/
124 void
e_poolv_destroy(EPoolv * poolv)125 e_poolv_destroy (EPoolv *poolv)
126 {
127 gint ii;
128
129 g_return_if_fail (poolv != NULL);
130
131 for (ii = 0; ii < poolv->length; ii++) {
132 camel_pstring_free (poolv->s[ii]);
133 }
134
135 g_free (poolv);
136 }
137