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