Commit e3204e7d authored by Lev Walkin's avatar Lev Walkin

abuf_vprintf

parent f75b8742
...@@ -53,32 +53,48 @@ abuf_clear(abuf *ab) { ...@@ -53,32 +53,48 @@ abuf_clear(abuf *ab) {
} }
static void static void
abuf_resize_by(abuf *ab, size_t add_bytes) { abuf_resize_by(abuf *ab, size_t size) {
union { union {
const char *c_buf; const char *c_buf;
char *nc_buf; char *nc_buf;
} const_cast; } const_cast;
const_cast.c_buf = ab->buffer; const_cast.c_buf = ab->buffer;
assert(ab->buffer[ab->length] == '\0'); assert(!ab->buffer || ab->buffer[ab->length] == '\0');
size_t new_size = ab->length + add_bytes; size_t new_size = ab->length + size;
char *p = realloc(const_cast.nc_buf, new_size); char *p = realloc(const_cast.nc_buf, new_size);
assert(p); assert(p);
if(!ab->buffer) {
assert(ab->length == 0);
*p = '\0';
}
ab->buffer = p; ab->buffer = p;
assert(ab->buffer[ab->length] == '\0'); assert(ab->buffer[ab->length] == '\0');
ab->size = new_size; ab->size = new_size;
} }
void abuf_add_bytes(abuf *ab, const char *str, size_t size) {
abuf_resize_by(ab, size + 1);
union {
const char *c_buf;
char *nc_buf;
} const_cast;
const_cast.c_buf = ab->buffer;
memcpy(&const_cast.nc_buf[ab->length], str, size);
ab->length += size;
const_cast.nc_buf[ab->length] = '\0';
}
void abuf_str(abuf *ab, const char *str) { void abuf_str(abuf *ab, const char *str) {
abuf_printf(ab, "%s", str); abuf_add_bytes(ab, str, strlen(str));
} }
void abuf_buf(abuf *ab, const abuf *buf) { void abuf_buf(abuf *ab, const abuf *buf) {
abuf_printf(ab, "%s", buf->buffer); abuf_add_bytes(ab, buf->buffer, buf->length);
} }
void abuf_printf(abuf *ab, const char *fmt, ...) { int abuf_printf(abuf *ab, const char *fmt, ...) {
va_list ap; va_list ap;
for(;;) { for(;;) {
...@@ -95,10 +111,25 @@ void abuf_printf(abuf *ab, const char *fmt, ...) { ...@@ -95,10 +111,25 @@ void abuf_printf(abuf *ab, const char *fmt, ...) {
if((size_t)ret < ab->size - ab->length) { if((size_t)ret < ab->size - ab->length) {
ab->length += ret; ab->length += ret;
assert(ab->buffer[ab->length] == '\0'); assert(ab->buffer[ab->length] == '\0');
break; return ret;
} }
const_cast.nc_buf[ab->length] = '\0'; /* Restore order */ const_cast.nc_buf[ab->length] = '\0'; /* Restore order */
abuf_resize_by(ab, ret + 1); abuf_resize_by(ab, ret + 1);
} }
} }
int abuf_vprintf(abuf *ab, const char *fmt, va_list ap) {
int ret;
char *str = 0;
ret = vasprintf(&str, fmt, ap);
assert(ret >= 0);
assert(str != NULL);
abuf_add_bytes(ab, str, ret);
free(str);
return ret;
}
#ifndef ASN1_BUFFER_H #ifndef ASN1_BUFFER_H
#define ASN1_BUFFER_H #define ASN1_BUFFER_H
#include <stdarg.h>
/* /*
* Your typical dynamic character string buffer. * Your typical dynamic character string buffer.
*/ */
...@@ -26,7 +28,9 @@ void abuf_clear(abuf *); ...@@ -26,7 +28,9 @@ void abuf_clear(abuf *);
*/ */
void abuf_str(abuf *, const char *str); void abuf_str(abuf *, const char *str);
void abuf_buf(abuf *, const abuf *); void abuf_buf(abuf *, const abuf *);
void abuf_printf(abuf *, const char *fmt, ...) void abuf_add_bytes(abuf *, const char *, size_t);
int abuf_printf(abuf *, const char *fmt, ...)
__attribute__((format(printf, 2, 3))); __attribute__((format(printf, 2, 3)));
int abuf_vprintf(abuf *, const char *fmt, va_list);
#endif /* ASN1_BUFFER_H */ #endif /* ASN1_BUFFER_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment