00001
00002
00003
00004
00005 static const char rcsid[] =
00006 "$Id: str.c,v 1.3 2007/02/14 20:38:53 tat Exp $";
00007
00008 #include <stdlib.h>
00009 #include <errno.h>
00010
00011 #include <toolbox/str.h>
00012 #include <toolbox/misc.h>
00013 #include <toolbox/carpal.h>
00014 #include <toolbox/memory.h>
00015
00021
00022 static char null_cstr[1] = { 0 };
00023 static char* null = null_cstr;
00024
00025
00026 struct u_string_s
00027 {
00028 char *data;
00029 size_t data_sz, data_len, shift_cnt;
00030 };
00031
00041 int u_string_trim(u_string_t *s)
00042 {
00043 if(s->data_len)
00044 {
00045 u_trim(s->data);
00046
00047 s->data_len = strlen(s->data);
00048 }
00049
00050 return 0;
00051 }
00052
00062 int u_string_set_length(u_string_t *s, size_t len)
00063 {
00064 dbg_err_if(len > s->data_len);
00065
00066 if(len < s->data_len)
00067 {
00068 s->data_len = len;
00069 s->data[len] = 0;
00070 }
00071
00072 return 0;
00073 err:
00074 return ~0;
00075 }
00076
00086 inline size_t u_string_len(u_string_t *s)
00087 {
00088 return s->data_len;
00089 }
00090
00101 inline const char *u_string_c(u_string_t *s)
00102 {
00103 return s->data;
00104 }
00105
00116 inline int u_string_copy(u_string_t *dst, u_string_t *src)
00117 {
00118 u_string_clear(dst);
00119 return u_string_append(dst, src->data, src->data_len);
00120 }
00121
00131 int u_string_clear(u_string_t *s)
00132 {
00133
00134 if(s->data_sz)
00135 {
00136 s->data[0] = 0;
00137 s->data_len = 0;
00138 }
00139
00140 return 0;
00141 }
00142
00157 int u_string_create(const char *buf, size_t len, u_string_t **ps)
00158 {
00159 u_string_t *s = NULL;
00160
00161 s = u_zalloc(sizeof(u_string_t));
00162 dbg_err_sif(s == NULL);
00163
00164 s->data = null;
00165
00166 if(buf)
00167 dbg_err_if(u_string_append(s, buf, len));
00168
00169 *ps = s;
00170
00171 return 0;
00172 err:
00173 return ~0;
00174 }
00175
00176
00186 int u_string_free(u_string_t *s)
00187 {
00188 if(s)
00189 {
00190 if(s->data_sz)
00191 U_FREE(s->data);
00192 U_FREE(s);
00193 }
00194 return 0;
00195 }
00196
00197
00209 int u_string_set(u_string_t *s, const char *buf, size_t len)
00210 {
00211 u_string_clear(s);
00212 return u_string_append(s, buf, len);
00213 }
00214
00225 int u_string_reserve(u_string_t *s, size_t size)
00226 {
00227 char *nbuf;
00228
00229 dbg_err_if(s == NULL);
00230
00231 if(size <= s->data_sz)
00232 return 0;
00233
00234
00235 nbuf = u_realloc( ((s->data == null) ? NULL : s->data), size+1);
00236 dbg_err_if(nbuf == NULL);
00237
00238
00239 nbuf[size] = 0;
00240
00241 s->data = (void*)nbuf;
00242 s->data_sz = size;
00243
00244 return 0;
00245 err:
00246 return ~0;
00247 }
00248
00249
00250
00251 int u_string_do_printf(u_string_t *s, int clear, const char *fmt, ...)
00252 {
00253 va_list ap;
00254 size_t sz, avail;
00255
00256 dbg_return_if(s == NULL, ~0);
00257 dbg_return_if(fmt == NULL, ~0);
00258
00259 if(clear)
00260 u_string_clear(s);
00261
00262 again:
00263 va_start(ap, fmt);
00264
00265 avail = s->data_sz - s->data_len;
00266
00267
00268 dbg_err_if(( sz = vsnprintf(s->data + s->data_len, avail, fmt, ap)) <= 0);
00269
00270 if(sz >= avail)
00271 {
00272
00273 dbg_err_if(u_string_reserve(s, s->data_sz + s->data_len + 2*sz + 1));
00274
00275
00276 s->data[s->data_len] = 0;
00277
00278 va_end(ap);
00279
00280
00281 goto again;
00282 }
00283
00284
00285 s->data_len += sz;
00286 s->data[s->data_len] = 0;
00287
00288 va_end(ap);
00289
00290 return 0;
00291 err:
00292 va_end(ap);
00293 return ~0;
00294 }
00295
00307 int u_string_append(u_string_t *s, const char *buf, size_t len)
00308 {
00309 size_t nsz, min;
00310
00311 if(!len)
00312 return 0;
00313
00314
00315 if(s->data_len + len + 1 > s->data_sz)
00316 {
00317 min = s->data_len + len + 1;
00318 nsz = s->data_sz;
00319 while(nsz <= min)
00320 nsz += (BLOCK_SIZE << s->shift_cnt++);
00321
00322 dbg_err_if(u_string_reserve(s, nsz));
00323 }
00324
00325
00326 strncpy(s->data + s->data_len, buf, len);
00327 s->data_len += len;
00328 s->data[s->data_len] = 0;
00329
00330 return 0;
00331 err:
00332 return ~0;
00333 }
00334
00335
00336