2 * buffer.c -- generic memory buffer .
4 * Copyright (c) 2001-2008, NLnet Labs. All rights reserved.
6 * See LICENSE for the license.
10 #include <ldns/config.h>
12 #include <ldns/ldns.h>
13 #include <ldns/buffer.h>
16 ldns_buffer_new(size_t capacity)
18 ldns_buffer *buffer = LDNS_MALLOC(ldns_buffer);
24 buffer->_data = (uint8_t *) LDNS_XMALLOC(uint8_t, capacity);
30 buffer->_position = 0;
31 buffer->_limit = buffer->_capacity = capacity;
33 buffer->_status = LDNS_STATUS_OK;
35 ldns_buffer_invariant(buffer);
41 ldns_buffer_new_frm_data(ldns_buffer *buffer, void *data, size_t size)
45 buffer->_position = 0;
46 buffer->_limit = buffer->_capacity = size;
47 buffer->_data = LDNS_XMALLOC(uint8_t, size);
48 memcpy(buffer->_data, data, size);
50 buffer->_status = LDNS_STATUS_OK;
52 ldns_buffer_invariant(buffer);
56 ldns_buffer_set_capacity(ldns_buffer *buffer, size_t capacity)
60 ldns_buffer_invariant(buffer);
61 assert(buffer->_position <= capacity);
63 data = (uint8_t *) LDNS_XREALLOC(buffer->_data, uint8_t, capacity);
65 buffer->_status = LDNS_STATUS_MEM_ERR;
69 buffer->_limit = buffer->_capacity = capacity;
75 ldns_buffer_reserve(ldns_buffer *buffer, size_t amount)
77 ldns_buffer_invariant(buffer);
78 assert(!buffer->_fixed);
79 if (buffer->_capacity < buffer->_position + amount) {
80 size_t new_capacity = buffer->_capacity * 3 / 2;
82 if (new_capacity < buffer->_position + amount) {
83 new_capacity = buffer->_position + amount;
85 if (!ldns_buffer_set_capacity(buffer, new_capacity)) {
86 buffer->_status = LDNS_STATUS_MEM_ERR;
90 buffer->_limit = buffer->_capacity;
95 ldns_buffer_printf(ldns_buffer *buffer, const char *format, ...)
101 if (ldns_buffer_status_ok(buffer)) {
102 ldns_buffer_invariant(buffer);
103 assert(buffer->_limit == buffer->_capacity);
105 remaining = ldns_buffer_remaining(buffer);
106 va_start(args, format);
107 written = vsnprintf((char *) ldns_buffer_current(buffer), remaining,
111 buffer->_status = LDNS_STATUS_INTERNAL_ERR;
113 } else if ((size_t) written >= remaining) {
114 if (!ldns_buffer_reserve(buffer, (size_t) written + 1)) {
115 buffer->_status = LDNS_STATUS_MEM_ERR;
118 va_start(args, format);
119 written = vsnprintf((char *) ldns_buffer_current(buffer),
120 ldns_buffer_remaining(buffer), format, args);
123 buffer->_status = LDNS_STATUS_INTERNAL_ERR;
127 buffer->_position += written;
133 ldns_buffer_free(ldns_buffer *buffer)
139 LDNS_FREE(buffer->_data);
145 ldns_buffer_export(ldns_buffer *buffer)
148 return buffer->_data;
152 ldns_bgetc(ldns_buffer *buffer)
154 if (!ldns_buffer_available_at(buffer, buffer->_position, sizeof(uint8_t))) {
155 ldns_buffer_set_position(buffer, ldns_buffer_limit(buffer));
156 /* ldns_buffer_rewind(buffer);*/
159 return (int)ldns_buffer_read_u8(buffer);
163 ldns_buffer_copy(ldns_buffer* result, ldns_buffer* from)
165 size_t tocopy = ldns_buffer_limit(from);
167 if(tocopy > ldns_buffer_capacity(result))
168 tocopy = ldns_buffer_capacity(result);
169 ldns_buffer_clear(result);
170 ldns_buffer_write(result, ldns_buffer_begin(from), tocopy);
171 ldns_buffer_flip(result);