1 /*!
2   \file db/dbmi_base/string.c
3 
4   \brief DBMI Library (base) - string management
5 
6   (C) 1999-2009 by the GRASS Development Team
7 
8   This program is free software under the GNU General Public License
9   (>=v2). Read the file COPYING that comes with GRASS for details.
10 
11   \author Joel Jones (CERL/UIUC)
12   \author Upgraded to GRASS 5.7 by Radim Blazek
13 */
14 
15 #include <string.h>
16 #include <stdlib.h>
17 #include <grass/gis.h>
18 #include <grass/dbmi.h>
19 
20 /*!
21   \brief Initialize dbString
22 
23   \param[out] x pointer to dbString
24  */
db_init_string(dbString * x)25 void db_init_string(dbString *x)
26 {
27     G_zero(x, sizeof(dbString));
28 }
29 
30 static int set_string(dbString * x, char *s, int copy);
31 
32 /*!
33   \brief Inserts string to dbString (enlarge string)
34 
35   \param[in,out] x pointer to dbString
36   \param s string to be inserted
37 
38   \return DB_OK on success
39   \return DB_MEMORY_ERR on error
40  */
db_set_string(dbString * x,const char * s)41 int db_set_string(dbString * x, const char *s)
42 {
43     return set_string(x, (char *)s, 1);
44 }
45 
46 /*!
47   \brief Inserts string to dbString (overwrite current value)
48 
49   \param[in,out] x pointer to dbString
50   \param s string to be inserted
51 
52   \return DB_OK on success
53   \return DB_MEMORY_ERR on error
54  */
db_set_string_no_copy(dbString * x,char * s)55 int db_set_string_no_copy(dbString * x, char *s)
56 {
57     return set_string(x, s, 0);
58 }
59 
60 /*!
61   \brief Get string size
62 
63   \param x pointer to dbString
64 
65   \return string size
66  */
db_sizeof_string(const dbString * x)67 unsigned int db_sizeof_string(const dbString * x)
68 {
69     if (x->nalloc < 0)
70 	return 0;
71     return (unsigned int)x->nalloc;
72 }
73 
74 /*!
75   \brief Zero string
76 
77   \param x pointer to dbString
78  */
db_zero_string(dbString * x)79 void db_zero_string(dbString * x)
80 {
81     if (db_get_string(x) && x->nalloc > 0)
82 	db_zero((void *)db_get_string(x), x->nalloc);
83 }
84 
set_string(dbString * x,char * s,int copy)85 static int set_string(dbString * x, char *s, int copy)
86 {
87     int len;
88     int stat;
89 
90     if (s == NULL) {
91 	s = "";
92 	copy = 1;
93     }
94 
95     len = strlen(s) + 1;
96 
97     if (copy) {
98 	stat = db_enlarge_string(x, len);
99 	if (stat != DB_OK)
100 	    return stat;
101 	strcpy(x->string, s);
102     }
103     else {
104 	db_free_string(x);
105 	x->string = s;
106 	x->nalloc = -1;
107     }
108     return DB_OK;
109 }
110 
111 /*!
112    \brief Enlarge dbString
113 
114    \param x pointer to dbString
115    \param len requested string size
116 
117    \return DB_OK on success
118    \return DB_MEMORY_ERR on error
119  */
db_enlarge_string(dbString * x,int len)120 int db_enlarge_string(dbString * x, int len)
121 {
122     if (x->nalloc < len) {
123 	if (x->nalloc < 0)
124 	    x->string = NULL;
125 	x->string = db_realloc((void *)x->string, len);
126 	if (x->string == NULL)
127 	    return DB_MEMORY_ERR;
128 	x->nalloc = len;
129     }
130     return DB_OK;
131 }
132 
133 /*!
134   \brief Get string
135 
136   \param x pointer to dbString
137 
138   \return pointer to buffer containing string
139 */
db_get_string(const dbString * x)140 char *db_get_string(const dbString * x)
141 {
142     return x->string;
143 }
144 
145 /*!
146   \brief Free allocated space for dbString
147 
148   \param x pointer to dbString
149 */
db_free_string(dbString * x)150 void db_free_string(dbString *x)
151 {
152     if (x->nalloc > 0)
153 	db_free(x->string);
154     db_init_string(x);
155 }
156 
157 /*!
158   \brief Free allocated dbString array
159 
160   \param a pointer to 1st dbString in the array
161   \param n number of items in array
162  */
db_free_string_array(dbString * a,int n)163 void db_free_string_array(dbString *a, int n)
164 {
165     int i;
166 
167     if (a) {
168 	for (i = 0; i < n; i++)
169 	    db_free_string(&a[i]);
170 	db_free(a);
171     }
172 }
173 
174 /*!
175   \brief Allocate dbString array
176 
177   \param count number of items to be allocated
178 
179   \return pointer to 1st dbString in the array
180 */
db_alloc_string_array(int count)181 dbString *db_alloc_string_array(int count)
182 {
183     int i;
184     dbString *a;
185 
186     if (count < 0)
187 	count = 0;
188     a = (dbString *) db_calloc(count, sizeof(dbString));
189     if (a) {
190 	for (i = 0; i < count; i++)
191 	    db_init_string(&a[i]);
192     }
193     return a;
194 }
195 
196 /*!
197   \brief Append string to dbString
198 
199   \param x pointer to dbString
200   \param s string to be appended
201 
202   \return DB_OK on success
203   \return otherwise error code is returned
204  */
db_append_string(dbString * x,const char * s)205 int db_append_string(dbString * x, const char *s)
206 {
207     int len;
208     int stat;
209 
210     if (!db_get_string(x))
211 	return db_set_string(x, s);
212 
213     len = strlen(db_get_string(x)) + strlen(s) + 1;
214     stat = db_enlarge_string(x, len);
215     if (stat != DB_OK)
216 	return stat;
217     strcat(db_get_string(x), s);
218     return DB_OK;
219 }
220 
221 /*!
222   \brief Copy dbString
223 
224   \param dst destination dbString
225   \param src source dbString
226 
227   \return DB_OK on success
228   \return DB_ERR code on error
229  */
db_copy_string(dbString * dst,const dbString * src)230 int db_copy_string(dbString * dst, const dbString * src)
231 {
232     return db_set_string(dst, db_get_string(src));
233 }
234 
235 /*!
236   \brief Replace each ' is replaced by ''
237 
238   \param src pointer to dbString
239 */
db_double_quote_string(dbString * src)240 void db_double_quote_string(dbString * src)
241 {
242     char *ptra, *ptrb, buf[2];
243     dbString tmp;
244 
245     db_init_string(&tmp);
246     buf[1] = 0;
247 
248     ptrb = db_get_string(src);
249     while ((ptra = strchr(ptrb, '\'')) != NULL) {
250 	for (; ptrb <= ptra; ptrb++) {
251 	    buf[0] = ptrb[0];
252 	    db_append_string(&tmp, buf);
253 	}
254 	db_append_string(&tmp, "'");
255     }
256     db_append_string(&tmp, ptrb);
257     db_set_string(src, db_get_string(&tmp));
258     db_free_string(&tmp);
259 }
260