summaryrefslogtreecommitdiffstats
path: root/libnetdata/buffer
diff options
context:
space:
mode:
Diffstat (limited to 'libnetdata/buffer')
-rw-r--r--libnetdata/buffer/buffer.c47
-rw-r--r--libnetdata/buffer/buffer.h26
2 files changed, 43 insertions, 30 deletions
diff --git a/libnetdata/buffer/buffer.c b/libnetdata/buffer/buffer.c
index 488e7dd24f..64f9cce47c 100644
--- a/libnetdata/buffer/buffer.c
+++ b/libnetdata/buffer/buffer.c
@@ -81,6 +81,7 @@ void buffer_snprintf(BUFFER *wb, size_t len, const char *fmt, ...)
va_list args;
va_start(args, fmt);
+ // vsnprintfz() returns the number of bytes actually written - after possible truncation
wb->len += vsnprintfz(&wb->buffer[wb->len], len, fmt, args);
va_end(args);
@@ -89,53 +90,39 @@ void buffer_snprintf(BUFFER *wb, size_t len, const char *fmt, ...)
// the buffer is \0 terminated by vsnprintfz
}
-void buffer_vsprintf(BUFFER *wb, const char *fmt, va_list args)
-{
+inline void buffer_vsprintf(BUFFER *wb, const char *fmt, va_list args) {
if(unlikely(!fmt || !*fmt)) return;
- size_t wrote = 0, need = 2, space_remaining = 0;
+ size_t full_size_bytes = 0, need = 2, space_remaining = 0;
do {
- need += space_remaining * 2;
+ need += full_size_bytes + 2;
- netdata_log_debug(D_WEB_BUFFER, "web_buffer_sprintf(): increasing web_buffer at position %zu, size = %zu, by %zu bytes (wrote = %zu)\n", wb->len, wb->size, need, wrote);
buffer_need_bytes(wb, need);
space_remaining = wb->size - wb->len - 1;
- wrote = (size_t) vsnprintfz(&wb->buffer[wb->len], space_remaining, fmt, args);
+ // Use the copy of va_list for vsnprintf
+ va_list args_copy;
+ va_copy(args_copy, args);
+ // vsnprintf() returns the number of bytes required, even if bigger than the buffer provided
+ full_size_bytes = (size_t) vsnprintf(&wb->buffer[wb->len], space_remaining, fmt, args_copy);
+ va_end(args_copy);
- } while(wrote >= space_remaining);
+ } while(full_size_bytes >= space_remaining);
- wb->len += wrote;
+ wb->len += full_size_bytes;
- // the buffer is \0 terminated by vsnprintf
+ wb->buffer[wb->len] = '\0';
+ buffer_overflow_check(wb);
}
void buffer_sprintf(BUFFER *wb, const char *fmt, ...)
{
- if(unlikely(!fmt || !*fmt)) return;
-
va_list args;
- size_t wrote = 0, need = 2, space_remaining = 0;
-
- do {
- need += space_remaining * 2;
-
- netdata_log_debug(D_WEB_BUFFER, "web_buffer_sprintf(): increasing web_buffer at position %zu, size = %zu, by %zu bytes (wrote = %zu)\n", wb->len, wb->size, need, wrote);
- buffer_need_bytes(wb, need);
-
- space_remaining = wb->size - wb->len - 1;
-
- va_start(args, fmt);
- wrote = (size_t) vsnprintfz(&wb->buffer[wb->len], space_remaining, fmt, args);
- va_end(args);
-
- } while(wrote >= space_remaining);
-
- wb->len += wrote;
-
- // the buffer is \0 terminated by vsnprintf
+ va_start(args, fmt);
+ buffer_vsprintf(wb, fmt, args);
+ va_end(args);
}
// generate a javascript date, the fastest possible way...
diff --git a/libnetdata/buffer/buffer.h b/libnetdata/buffer/buffer.h
index e5dd9992d1..88d3f0282a 100644
--- a/libnetdata/buffer/buffer.h
+++ b/libnetdata/buffer/buffer.h
@@ -94,6 +94,8 @@ typedef struct web_buffer {
} json;
} BUFFER;
+#define CLEAN_BUFFER _cleanup_(buffer_freep) BUFFER
+
#define buffer_cacheable(wb) do { (wb)->options |= WB_CONTENT_CACHEABLE; if((wb)->options & WB_CONTENT_NO_CACHEABLE) (wb)->options &= ~WB_CONTENT_NO_CACHEABLE; } while(0)
#define buffer_no_cacheable(wb) do { (wb)->options |= WB_CONTENT_NO_CACHEABLE; if((wb)->options & WB_CONTENT_CACHEABLE) (wb)->options &= ~WB_CONTENT_CACHEABLE; (wb)->expires = 0; } while(0)
@@ -135,6 +137,10 @@ BUFFER *buffer_create(size_t size, size_t *statistics);
void buffer_free(BUFFER *b);
void buffer_increase(BUFFER *b, size_t free_size_required);
+static inline void buffer_freep(BUFFER **bp) {
+ if(bp) buffer_free(*bp);
+}
+
void buffer_snprintf(BUFFER *wb, size_t len, const char *fmt, ...) PRINTFLIKE(3, 4);
void buffer_vsprintf(BUFFER *wb, const char *fmt, va_list args);
void buffer_sprintf(BUFFER *wb, const char *fmt, ...) PRINTFLIKE(2,3);
@@ -210,6 +216,13 @@ static inline void buffer_fast_rawcat(BUFFER *wb, const char *txt, size_t len) {
buffer_overflow_check(wb);
}
+static inline void buffer_putc(BUFFER *wb, char c) {
+ buffer_need_bytes(wb, 2);
+ wb->buffer[wb->len++] = c;
+ wb->buffer[wb->len] = '\0';
+ buffer_overflow_check(wb);
+}
+
static inline void buffer_fast_strcat(BUFFER *wb, const char *txt, size_t len) {
if(unlikely(!txt || !*txt || !len)) return;
@@ -283,6 +296,19 @@ static inline void buffer_strncat(BUFFER *wb, const char *txt, size_t len) {
buffer_overflow_check(wb);
}
+static inline void buffer_memcat(BUFFER *wb, const void *mem, size_t bytes) {
+ if(unlikely(!mem)) return;
+
+ buffer_need_bytes(wb, bytes + 1);
+
+ memcpy(&wb->buffer[wb->len], mem, bytes);
+
+ wb->len += bytes;
+ wb->buffer[wb->len] = '\0';
+
+ buffer_overflow_check(wb);
+}
+
static inline void buffer_json_strcat(BUFFER *wb, const char *txt) {
if(unlikely(!txt || !*txt)) return;