Main Page | Modules | Data Structures | Directories | File List | Data Fields

buf.c

00001 /* 
00002  * Copyright (c) 2005-2007 by KoanLogic s.r.l. - All rights reserved.  
00003  */
00004 
00005 static const char rcsid[] =
00006     "$Id: buf.c,v 1.2 2007/02/12 08:32:27 tho Exp $";
00007 
00008 #include <sys/types.h>
00009 #include <sys/stat.h>
00010 #include <unistd.h>
00011 #include <stdio.h>
00012 #include <stdarg.h>
00013 #include <u/libu.h>
00014 #include <toolbox/buf.h>
00015 
00031 int u_buf_reserve(u_buf_t *ubuf, size_t size)
00032 {
00033     char *nbuf;
00034 
00035     dbg_err_if(ubuf == NULL);
00036 
00037     if(size <= ubuf->size)
00038         return 0; /* nothing to do */
00039    
00040     /* size plus 1 char to store a '\0' */
00041     nbuf = u_realloc(ubuf->data, size+1);
00042     dbg_err_if(nbuf == NULL);
00043 
00044     /* buffer data will always be zero-terminated (but the len field will not
00045      * count the last '\0') */
00046     nbuf[size] = 0;
00047 
00048     ubuf->data = (void*)nbuf;
00049     ubuf->size = size;
00050 
00051     return 0;
00052 err:
00053     return ~0;
00054 }
00055 
00068 int u_buf_append(u_buf_t *ubuf, const void *data, size_t size)
00069 {
00070     dbg_err_if(ubuf == NULL);
00071     dbg_err_if(data == NULL);
00072     dbg_err_if(size == 0);
00073 
00074     if(ubuf->size - ubuf->len < size)
00075     {   /* buffer too small, need to resize */
00076         dbg_err_if(u_buf_reserve(ubuf, ubuf->size + ubuf->len + 2*size));
00077     }
00078    
00079     memcpy(ubuf->data + ubuf->len, data, size);
00080     ubuf->len += size;
00081 
00082     /* zero term the buffer so it can be used (when applicable) as a string */
00083     ubuf->data[ubuf->len] = 0;
00084 
00085     return 0;
00086 err:
00087     return ~0;
00088 }
00089 
00100 int u_buf_load(u_buf_t *ubuf, const char *filename)
00101 {
00102     struct stat st;
00103     FILE *fp = NULL;
00104 
00105     dbg_err_if(ubuf == NULL);
00106     dbg_err_if(filename == NULL);
00107 
00108     dbg_err_if(stat(filename, &st));
00109 
00110     /* clear the current data */
00111     dbg_err_if(u_buf_clear(ubuf));
00112 
00113     /* be sure to have a big enough buffer */
00114     dbg_err_if(u_buf_reserve(ubuf, st.st_size));
00115 
00116     warn_err_sif((fp = fopen(filename, "r")) == NULL);
00117 
00118     /* fill the buffer with the whole file content */
00119     dbg_err_if(fread(ubuf->data, st.st_size, 1, fp) == 0);
00120     ubuf->len = st.st_size;
00121 
00122     fclose(fp);
00123 
00124     return 0;
00125 err:
00126     if(fp)
00127         fclose(fp);
00128     return ~0;
00129 }
00130 
00145 int u_buf_detach(u_buf_t *ubuf)
00146 {
00147     dbg_err_if(ubuf == NULL);
00148 
00149     ubuf->data = NULL;
00150     ubuf->size = 0;
00151     ubuf->len = 0;
00152 
00153     return 0;
00154 err:
00155     return ~0;
00156 }
00157 
00167 size_t u_buf_size(u_buf_t *ubuf)
00168 {
00169     dbg_err_if(ubuf == NULL);
00170 
00171     return ubuf->size;
00172 err:
00173     return 0;
00174 }
00175 
00185 size_t u_buf_len(u_buf_t *ubuf)
00186 {
00187     dbg_err_if(ubuf == NULL);
00188 
00189     return ubuf->len;
00190 err:
00191     return 0;
00192 }
00193 
00204 int u_buf_clear(u_buf_t *ubuf)
00205 {
00206     dbg_err_if(ubuf == NULL);
00207     
00208     ubuf->len = 0;
00209 
00210     return 0;
00211 err:
00212     return ~0;
00213 }
00214 
00227 int u_buf_set(u_buf_t *ubuf, const void *data, size_t size)
00228 {
00229     dbg_err_if(ubuf == NULL);
00230     dbg_err_if(data == NULL);
00231     dbg_err_if(size == 0);
00232 
00233     dbg_err_if(u_buf_clear(ubuf));
00234 
00235     dbg_err_if(u_buf_append(ubuf, data, size));
00236 
00237     return 0;
00238 err:
00239     return ~0;
00240 }
00241 
00251 void* u_buf_ptr(u_buf_t *ubuf)
00252 {
00253     dbg_err_if(ubuf == NULL);
00254     
00255     return ubuf->data;
00256 err:
00257     return NULL;
00258 }
00259 
00269 int u_buf_free(u_buf_t *ubuf)
00270 {
00271     dbg_err_if(ubuf == NULL);
00272 
00273     if(ubuf->data)
00274         u_free(ubuf->data);
00275 
00276     u_free(ubuf);
00277 
00278     return 0;
00279 err:
00280     return ~0;
00281 }
00282 
00298 int u_buf_printf(u_buf_t *ubuf, const char *fmt, ...)
00299 {
00300     va_list ap;
00301     size_t sz, avail;
00302 
00303     dbg_return_if(ubuf == NULL, ~0);
00304     dbg_return_if(fmt == NULL, ~0);
00305 
00306 again:
00307     va_start(ap, fmt); 
00308 
00309     avail = ubuf->size - ubuf->len; /* avail may be zero */
00310 
00311     /* write to the internal buffer of ubuf */
00312     dbg_err_if(( sz = vsnprintf(ubuf->data + ubuf->len, avail, fmt, ap)) <= 0);
00313 
00314     if(sz >= avail)
00315     {
00316         /* enlarge the buffer (make it at least 128 bytes bigger) */
00317         dbg_err_if(u_buf_reserve(ubuf, ubuf->len + U_MAX(128, sz + 1)));
00318 
00319         /* zero-term the buffer (vsnprintf has removed the last \0!) */
00320         ubuf->data[ubuf->len] = 0;
00321 
00322         va_end(ap);
00323 
00324         /* try again with a bigger buffer */
00325         goto again;
00326     }
00327 
00328     /* update data length (don't include the '\0' in the size count) */
00329     ubuf->len += sz; 
00330 
00331     va_end(ap);
00332 
00333     return 0;
00334 err:
00335     va_end(ap);
00336     return ~0; /* error */
00337 }
00338 
00348 int u_buf_create(u_buf_t **pubuf)
00349 {
00350     u_buf_t *ubuf = NULL;
00351 
00352     dbg_err_if(pubuf == NULL);
00353 
00354     ubuf = (u_buf_t*)u_zalloc(sizeof(u_buf_t));
00355     dbg_err_if(ubuf == NULL);
00356 
00357     *pubuf = ubuf;
00358 
00359     return 0;
00360 err:
00361     return ~0;
00362 }
00363 

←Products
© 2005-2007 - KoanLogic S.r.l. - All rights reserved