/** * \brief Fill a buffer object with the content of a file * * Open \a filename and copy its whole content into the given buffer. * * \param ubuf buffer object * \param filename the source filename * * \return \c 0 on success, not zero on failure */ int u_buf_load(u_buf_t *ubuf, char *filename) { enum { BUFSZ = 4096 }; struct stat st; FILE *fp = NULL; dbg_err_if(ubuf == NULL); dbg_err_if(filename == NULL); dbg_err_if(stat(filename, &st)); /* clear the current data */ dbg_err_if(u_buf_clear(ubuf)); /* be sure to have a big enough buffer */ dbg_err_if(u_buf_reserve(ubuf, st.st_size)); warn_err_sif((fp = fopen(filename, "r")) == NULL); /* fill the buffer with the whole file content */ dbg_err_if(fread(ubuf->data, st.st_size, 1, fp) == 0); ubuf->len = st.st_size; fclose(fp); return 0; err: if(fp) fclose(fp); return ~0; }
/** * \brief Fill a buffer object with the content of a file * * Open \p filename and copy its whole content into the given buffer \p ubuf * * \param ubuf an already allocated ::u_buf_t object * \param filename path of the source file * * \retval 0 on success * \retval ~0 on failure */ int u_buf_load (u_buf_t *ubuf, const char *filename) { struct stat st; FILE *fp = NULL; dbg_return_if (ubuf == NULL, ~0); dbg_return_if (filename == NULL, ~0); dbg_err_sif (stat(filename, &st) == -1); /* clear the current data */ dbg_err_if (u_buf_clear(ubuf)); /* be sure to have a big enough buffer */ dbg_err_if (u_buf_reserve(ubuf, st.st_size)); dbg_err_sifm ((fp = fopen(filename, "r")) == NULL, "%s", filename); /* fill the buffer with the whole file content */ dbg_err_if (fread(ubuf->data, st.st_size, 1, fp) != 1); ubuf->len = st.st_size; (void) fclose(fp); return 0; err: U_FCLOSE(fp); return ~0; }
/** * \brief Append a string to the given buffer * * Create a NUL-terminated string from the \c printf(3) like arguments and * append it to the given ::u_buf_t object. The length of the appended string * (NOT including the ending \c \\0) will be added to the current length of * the buffer (::u_buf_len). * * \param ubuf a previously allocated ::u_buf_t object * \param fmt printf(3) format string * \param ... variable list of arguments used by the \p fmt * * \retval 0 on success * \retval ~0 on error */ int u_buf_printf (u_buf_t *ubuf, const char *fmt, ...) { va_list ap; size_t sz, avail; dbg_return_if (ubuf == NULL, ~0); dbg_return_if (fmt == NULL, ~0); again: va_start(ap, fmt); avail = ubuf->size - ubuf->len; /* avail may be zero */ /* write to the internal buffer of ubuf */ dbg_err_if ((sz = vsnprintf(ubuf->data + ubuf->len, avail, fmt, ap)) <= 0); if (sz >= avail) { /* enlarge the buffer (make it at least 128 bytes bigger) */ dbg_err_if (u_buf_reserve(ubuf, ubuf->len + U_MIN(128, sz + 1))); /* zero-term the buffer (vsnprintf has removed the last \0!) */ ubuf->data[ubuf->len] = '\0'; va_end(ap); /* try again with a bigger buffer */ goto again; } /* update data length (don't include the '\0' in the size count) */ ubuf->len += sz; va_end(ap); return 0; err: va_end(ap); return ~0; }
/** * \brief Append data to the buffer * * Append \p size bytes of \p data to the given buffer. If needed the buffer * will be transparently enlarged. * * \param ubuf an already allocated ::u_buf_t object * \param data a reference to the data block that will be appended * \param size the number of bytes to append * * \retval 0 on success * \retval ~0 on failure */ int u_buf_append (u_buf_t *ubuf, const void *data, size_t size) { dbg_return_if (ubuf == NULL, ~0); dbg_return_if (data == NULL, ~0); dbg_return_if (size == 0, ~0); if (ubuf->size - ubuf->len < size) { /* buffer too small, resize generously */ dbg_err_if (u_buf_reserve(ubuf, ubuf->size + ubuf->len + 2 * size)); } memcpy(ubuf->data + ubuf->len, data, size); ubuf->len += size; /* zero term the buffer so it can be used (when applicable) as a string */ ubuf->data[ubuf->len] = '\0'; return 0; err: return ~0; }
/** * \brief Append some data to the buffer * * Append \a data of size \a size to the given buffer. If needed the buffer * will be enlarged. * * \param ubuf buffer object * \param data the data block to append * \param size size of \a data * * \return \c 0 on success, not zero on failure */ int u_buf_append(u_buf_t *ubuf, void *data, size_t size) { dbg_err_if(ubuf == NULL); // dbg_err_if(data == NULL); dbg_err_if(size == 0); if(ubuf->size - ubuf->len < size) { /* buffer too small, need to resize */ dbg_err_if(u_buf_reserve(ubuf, ubuf->size + ubuf->len + 2*size)); } if (data) { memcpy(ubuf->data + ubuf->len, data, size); ubuf->len += size; /* zero term the buffer so it can be used (when applicable) as a string */ ubuf->data[ubuf->len] = 0; } return 0; err: return ~0; }