diff options
Diffstat (limited to 'external/unbound/sldns/sbuffer.c')
-rw-r--r-- | external/unbound/sldns/sbuffer.c | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/external/unbound/sldns/sbuffer.c b/external/unbound/sldns/sbuffer.c new file mode 100644 index 000000000..a7fe53aa0 --- /dev/null +++ b/external/unbound/sldns/sbuffer.c @@ -0,0 +1,178 @@ +/* + * buffer.c -- generic memory buffer . + * + * Copyright (c) 2001-2008, NLnet Labs. All rights reserved. + * + * See LICENSE for the license. + * + */ +/** + * \file + * + * This file contains the definition of sldns_buffer, and functions to manipulate those. + */ +#include "config.h" +#include "sldns/sbuffer.h" +#include <stdarg.h> + +sldns_buffer * +sldns_buffer_new(size_t capacity) +{ + sldns_buffer *buffer = (sldns_buffer*)malloc(sizeof(sldns_buffer)); + + if (!buffer) { + return NULL; + } + + buffer->_data = (uint8_t *) malloc(capacity); + if (!buffer->_data) { + free(buffer); + return NULL; + } + + buffer->_position = 0; + buffer->_limit = buffer->_capacity = capacity; + buffer->_fixed = 0; + buffer->_status_err = 0; + + sldns_buffer_invariant(buffer); + + return buffer; +} + +void +sldns_buffer_new_frm_data(sldns_buffer *buffer, void *data, size_t size) +{ + assert(data != NULL); + + buffer->_position = 0; + buffer->_limit = buffer->_capacity = size; + buffer->_fixed = 0; + buffer->_data = malloc(size); + if(!buffer->_data) { + buffer->_status_err = 1; + return; + } + memcpy(buffer->_data, data, size); + buffer->_status_err = 0; + + sldns_buffer_invariant(buffer); +} + +void +sldns_buffer_init_frm_data(sldns_buffer *buffer, void *data, size_t size) +{ + memset(buffer, 0, sizeof(*buffer)); + buffer->_data = data; + buffer->_capacity = buffer->_limit = size; + buffer->_fixed = 1; +} + +int +sldns_buffer_set_capacity(sldns_buffer *buffer, size_t capacity) +{ + void *data; + + sldns_buffer_invariant(buffer); + assert(buffer->_position <= capacity); + + data = (uint8_t *) realloc(buffer->_data, capacity); + if (!data) { + buffer->_status_err = 1; + return 0; + } else { + buffer->_data = data; + buffer->_limit = buffer->_capacity = capacity; + return 1; + } +} + +int +sldns_buffer_reserve(sldns_buffer *buffer, size_t amount) +{ + sldns_buffer_invariant(buffer); + assert(!buffer->_fixed); + if (buffer->_capacity < buffer->_position + amount) { + size_t new_capacity = buffer->_capacity * 3 / 2; + + if (new_capacity < buffer->_position + amount) { + new_capacity = buffer->_position + amount; + } + if (!sldns_buffer_set_capacity(buffer, new_capacity)) { + buffer->_status_err = 1; + return 0; + } + } + buffer->_limit = buffer->_capacity; + return 1; +} + +int +sldns_buffer_printf(sldns_buffer *buffer, const char *format, ...) +{ + va_list args; + int written = 0; + size_t remaining; + + if (sldns_buffer_status_ok(buffer)) { + sldns_buffer_invariant(buffer); + assert(buffer->_limit == buffer->_capacity); + + remaining = sldns_buffer_remaining(buffer); + va_start(args, format); + written = vsnprintf((char *) sldns_buffer_current(buffer), remaining, + format, args); + va_end(args); + if (written == -1) { + buffer->_status_err = 1; + return -1; + } else if ((size_t) written >= remaining) { + if (!sldns_buffer_reserve(buffer, (size_t) written + 1)) { + buffer->_status_err = 1; + return -1; + } + va_start(args, format); + written = vsnprintf((char *) sldns_buffer_current(buffer), + sldns_buffer_remaining(buffer), format, args); + va_end(args); + if (written == -1) { + buffer->_status_err = 1; + return -1; + } + } + buffer->_position += written; + } + return written; +} + +void +sldns_buffer_free(sldns_buffer *buffer) +{ + if (!buffer) { + return; + } + + if (!buffer->_fixed) + free(buffer->_data); + + free(buffer); +} + +void * +sldns_buffer_export(sldns_buffer *buffer) +{ + buffer->_fixed = 1; + return buffer->_data; +} + +void +sldns_buffer_copy(sldns_buffer* result, sldns_buffer* from) +{ + size_t tocopy = sldns_buffer_limit(from); + + if(tocopy > sldns_buffer_capacity(result)) + tocopy = sldns_buffer_capacity(result); + sldns_buffer_clear(result); + sldns_buffer_write(result, sldns_buffer_begin(from), tocopy); + sldns_buffer_flip(result); +} |