00001
00002
00003
00004
00005 #include <sys/types.h>
00006 #include <sys/stat.h>
00007 #include <unistd.h>
00008 #include <stdio.h>
00009 #include <stdarg.h>
00010 #include <u/libu.h>
00011 #include <toolbox/buf.h>
00012
00013 struct u_buf_s
00014 {
00015 char *data;
00016 size_t size;
00017 size_t len;
00018 };
00019
00041 int u_buf_reserve (u_buf_t *ubuf, size_t size)
00042 {
00043 char *nbuf;
00044
00045 dbg_err_if (ubuf == NULL);
00046
00047 nop_return_if (size <= ubuf->size, 0);
00048
00049
00050 dbg_err_sif ((nbuf = u_realloc(ubuf->data, size + 1)) == NULL);
00051
00052
00053
00054 nbuf[size] = '\0';
00055
00056 ubuf->data = nbuf;
00057 ubuf->size = size;
00058
00059 return 0;
00060 err:
00061 return ~0;
00062 }
00063
00077 int u_buf_append (u_buf_t *ubuf, const void *data, size_t size)
00078 {
00079 dbg_return_if (ubuf == NULL, ~0);
00080 dbg_return_if (data == NULL, ~0);
00081 dbg_return_if (size == 0, ~0);
00082
00083 if (ubuf->size - ubuf->len < size)
00084 {
00085
00086 dbg_err_if (u_buf_reserve(ubuf, ubuf->size + ubuf->len + 2 * size));
00087 }
00088
00089 memcpy(ubuf->data + ubuf->len, data, size);
00090 ubuf->len += size;
00091
00092
00093 ubuf->data[ubuf->len] = '\0';
00094
00095 return 0;
00096 err:
00097 return ~0;
00098 }
00099
00111 int u_buf_load (u_buf_t *ubuf, const char *filename)
00112 {
00113 struct stat st;
00114 FILE *fp = NULL;
00115
00116 dbg_return_if (ubuf == NULL, ~0);
00117 dbg_return_if (filename == NULL, ~0);
00118
00119 dbg_err_sif (stat(filename, &st) == -1);
00120
00121
00122 dbg_err_if (u_buf_clear(ubuf));
00123
00124
00125 dbg_err_if (u_buf_reserve(ubuf, st.st_size));
00126
00127 dbg_err_sifm ((fp = fopen(filename, "r")) == NULL, "%s", filename);
00128
00129
00130 dbg_err_if (fread(ubuf->data, st.st_size, 1, fp) != 1);
00131 ubuf->len = st.st_size;
00132
00133 (void) fclose(fp);
00134
00135 return 0;
00136 err:
00137 U_FCLOSE(fp);
00138 return ~0;
00139 }
00140
00152 int u_buf_save (u_buf_t *ubuf, const char *filename)
00153 {
00154 dbg_return_if (ubuf == NULL, ~0);
00155 dbg_return_if (filename == NULL, ~0);
00156
00157 return u_data_dump(u_buf_ptr(ubuf), u_buf_len(ubuf), filename);
00158 }
00159
00174 int u_buf_detach (u_buf_t *ubuf)
00175 {
00176 dbg_return_if (ubuf == NULL, ~0);
00177
00178 ubuf->data = NULL;
00179 ubuf->size = 0;
00180 ubuf->len = 0;
00181
00182 return 0;
00183 }
00184
00197 ssize_t u_buf_size (u_buf_t *ubuf)
00198 {
00199 dbg_return_if (ubuf == NULL, -1);
00200
00201 return ubuf->size;
00202 }
00203
00215 ssize_t u_buf_len (u_buf_t *ubuf)
00216 {
00217 dbg_return_if (ubuf == NULL, -1);
00218
00219 return ubuf->len;
00220 }
00221
00233 int u_buf_clear (u_buf_t *ubuf)
00234 {
00235 dbg_return_if (ubuf == NULL, ~0);
00236
00237 ubuf->len = 0;
00238
00239 return 0;
00240 }
00241
00257 int u_buf_set (u_buf_t *ubuf, const void *data, size_t size)
00258 {
00259 dbg_return_if (ubuf == NULL, ~0);
00260 dbg_return_if (data == NULL, ~0);
00261 dbg_return_if (size == 0, ~0);
00262
00263 dbg_err_if (u_buf_clear(ubuf));
00264 dbg_err_if (u_buf_append(ubuf, data, size));
00265
00266 return 0;
00267 err:
00268 return ~0;
00269 }
00270
00282 void *u_buf_ptr (u_buf_t *ubuf)
00283 {
00284 dbg_return_if (ubuf == NULL, NULL);
00285
00286 return ubuf->data;
00287 }
00288
00302 int u_buf_shrink(u_buf_t *ubuf, size_t newlen)
00303 {
00304 dbg_err_if (ubuf == NULL);
00305 dbg_err_if (newlen > ubuf->len);
00306
00307 ubuf->len = newlen;
00308
00309 return 0;
00310 err:
00311 return ~0;
00312 }
00313
00324 int u_buf_free (u_buf_t *ubuf)
00325 {
00326 dbg_return_if (ubuf == NULL, ~0);
00327
00328 U_FREE(ubuf->data);
00329 u_free(ubuf);
00330
00331 return 0;
00332 }
00333
00349 int u_buf_printf (u_buf_t *ubuf, const char *fmt, ...)
00350 {
00351 va_list ap;
00352 size_t sz, avail;
00353
00354 dbg_return_if (ubuf == NULL, ~0);
00355 dbg_return_if (fmt == NULL, ~0);
00356
00357 again:
00358 va_start(ap, fmt);
00359
00360 avail = ubuf->size - ubuf->len;
00361
00362
00363 dbg_err_if ((sz = vsnprintf(ubuf->data + ubuf->len, avail, fmt, ap)) <= 0);
00364
00365 if (sz >= avail)
00366 {
00367
00368 dbg_err_if (u_buf_reserve(ubuf, ubuf->len + U_MIN(128, sz + 1)));
00369
00370
00371 ubuf->data[ubuf->len] = '\0';
00372
00373 va_end(ap);
00374
00375
00376 goto again;
00377 }
00378
00379
00380 ubuf->len += sz;
00381
00382 va_end(ap);
00383
00384 return 0;
00385 err:
00386 va_end(ap);
00387 return ~0;
00388 }
00389
00390
00402 int u_buf_create (u_buf_t **pubuf)
00403 {
00404 u_buf_t *ubuf = NULL;
00405
00406 dbg_return_if (pubuf == NULL, ~0);
00407
00408 dbg_err_sif ((ubuf = u_zalloc(sizeof(u_buf_t))) == NULL);
00409
00410 ubuf->len = 0;
00411 ubuf->size = 0;
00412 ubuf->data = NULL;
00413
00414 *pubuf = ubuf;
00415
00416 return 0;
00417 err:
00418 return ~0;
00419 }
00420