1 /* EINA - EFL data type library
2 * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2010
3 * Carsten Haitzler,
4 * Jorge Luis Zapata Muga,
5 * Cedric Bail,
6 * Gustavo Sverzut Barbieri
7 * Tom Hacohen
8 * Brett Nash
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library;
22 * if not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28
29 #include "eina_config.h"
30 #include "eina_private.h"
31 #include "eina_log.h"
32 #include "eina_lock.h"
33 #include "eina_share_common.h"
34
35 /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
36 #include "eina_safety_checks.h"
37 #include "eina_tmpstr.h"
38
39 typedef struct _Str Str;
40
41 struct _Str
42 {
43 size_t length;
44 Str *next;
45 char *str;
46 Eina_Bool ma : 1;
47 };
48
49 static Eina_Lock _mutex;
50 static Str *strs = NULL;
51
52 Eina_Bool
eina_tmpstr_init(void)53 eina_tmpstr_init(void)
54 {
55 if (!eina_lock_new(&_mutex)) return EINA_FALSE;
56 return EINA_TRUE;
57 }
58
59 Eina_Bool
eina_tmpstr_shutdown(void)60 eina_tmpstr_shutdown(void)
61 {
62 eina_lock_free(&_mutex);
63 return EINA_TRUE;
64 }
65
66 EAPI Eina_Tmpstr *
eina_tmpstr_add_length(const char * str,size_t length)67 eina_tmpstr_add_length(const char *str, size_t length)
68 {
69 Str *s;
70
71 if (!str || !length) return NULL;
72 s = malloc(sizeof(Str) + length + 1);
73 if (!s) return NULL;
74 s->length = length;
75 s->str = ((char *)s) + sizeof(Str);
76 strncpy(s->str, str, length);
77 s->str[length] = '\0';
78 s->ma = EINA_FALSE;
79 eina_lock_take(&_mutex);
80 s->next = strs;
81 strs = s;
82 eina_lock_release(&_mutex);
83 return s->str;
84 }
85
86 EAPI Eina_Tmpstr *
eina_tmpstr_manage_new_length(char * str,size_t length)87 eina_tmpstr_manage_new_length(char *str, size_t length)
88 {
89 Str *s;
90
91 if (!str || !length) return NULL;
92 s = calloc(1, sizeof(Str));
93 if (!s) return NULL;
94 s->length = length;
95 s->str = str;
96 s->ma = EINA_TRUE;
97 eina_lock_take(&_mutex);
98 s->next = strs;
99 strs = s;
100 eina_lock_release(&_mutex);
101 return s->str;
102 }
103
104 EAPI Eina_Tmpstr *
eina_tmpstr_manage_new(char * str)105 eina_tmpstr_manage_new(char *str)
106 {
107 size_t len;
108
109 if (!str) return NULL;
110 len = strlen(str);
111 return eina_tmpstr_manage_new_length(str, len);
112 }
113
114 EAPI Eina_Tmpstr *
eina_tmpstr_add(const char * str)115 eina_tmpstr_add(const char *str)
116 {
117 size_t len;
118
119 if (!str) return NULL;
120 len = strlen(str);
121 return eina_tmpstr_add_length(str, len);
122 }
123
124 EAPI void
eina_tmpstr_del(Eina_Tmpstr * tmpstr)125 eina_tmpstr_del(Eina_Tmpstr *tmpstr)
126 {
127 Str *s, *sp;
128
129 if ((!strs) || (!tmpstr)) return;
130 eina_lock_take(&_mutex);
131 for (sp = NULL, s = strs; s; sp = s, s = s->next)
132 {
133 if (s->str == tmpstr)
134 {
135 if (sp) sp->next = s->next;
136 else strs = s->next;
137 if (s->ma) free(s->str);
138 free(s);
139 break;
140 }
141 }
142 eina_lock_release(&_mutex);
143 }
144
145 EAPI size_t
eina_tmpstr_strlen(Eina_Tmpstr * tmpstr)146 eina_tmpstr_strlen(Eina_Tmpstr *tmpstr)
147 {
148 if (!tmpstr) return 0;
149 return eina_tmpstr_len(tmpstr) + 1;
150 }
151
152 EAPI size_t
eina_tmpstr_len(Eina_Tmpstr * tmpstr)153 eina_tmpstr_len(Eina_Tmpstr *tmpstr)
154 {
155 Str *s;
156
157 if (!tmpstr) return 0;
158 if (!strs) return strlen(tmpstr);
159 eina_lock_take(&_mutex);
160 for (s = strs; s; s = s->next)
161 {
162 if (s->str == tmpstr)
163 {
164 size_t ret = s->length;
165 eina_lock_release(&_mutex);
166 return ret;
167 }
168 }
169 eina_lock_release(&_mutex);
170
171 return strlen(tmpstr);
172 }
173