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
;
48 buffer
->_data
= LDNS_XMALLOC(uint8_t, size
);
50 buffer
->_status
= LDNS_STATUS_MEM_ERR
;
53 memcpy(buffer
->_data
, data
, size
);
54 buffer
->_status
= LDNS_STATUS_OK
;
56 ldns_buffer_invariant(buffer
);
60 ldns_buffer_set_capacity(ldns_buffer
*buffer
, size_t capacity
)
64 ldns_buffer_invariant(buffer
);
65 assert(buffer
->_position
<= capacity
);
67 data
= (uint8_t *) LDNS_XREALLOC(buffer
->_data
, uint8_t, capacity
);
69 buffer
->_status
= LDNS_STATUS_MEM_ERR
;
73 buffer
->_limit
= buffer
->_capacity
= capacity
;
79 ldns_buffer_reserve(ldns_buffer
*buffer
, size_t amount
)
81 ldns_buffer_invariant(buffer
);
82 assert(!buffer
->_fixed
);
83 if (buffer
->_capacity
< buffer
->_position
+ amount
) {
84 size_t new_capacity
= buffer
->_capacity
* 3 / 2;
86 if (new_capacity
< buffer
->_position
+ amount
) {
87 new_capacity
= buffer
->_position
+ amount
;
89 if (!ldns_buffer_set_capacity(buffer
, new_capacity
)) {
90 buffer
->_status
= LDNS_STATUS_MEM_ERR
;
94 buffer
->_limit
= buffer
->_capacity
;
99 ldns_buffer_printf(ldns_buffer
*buffer
, const char *format
, ...)
105 if (ldns_buffer_status_ok(buffer
)) {
106 ldns_buffer_invariant(buffer
);
107 assert(buffer
->_limit
== buffer
->_capacity
);
109 remaining
= ldns_buffer_remaining(buffer
);
110 va_start(args
, format
);
111 written
= vsnprintf((char *) ldns_buffer_current(buffer
), remaining
,
115 buffer
->_status
= LDNS_STATUS_INTERNAL_ERR
;
117 } else if ((size_t) written
>= remaining
) {
118 if (!ldns_buffer_reserve(buffer
, (size_t) written
+ 1)) {
119 buffer
->_status
= LDNS_STATUS_MEM_ERR
;
122 va_start(args
, format
);
123 written
= vsnprintf((char *) ldns_buffer_current(buffer
),
124 ldns_buffer_remaining(buffer
), format
, args
);
127 buffer
->_status
= LDNS_STATUS_INTERNAL_ERR
;
131 buffer
->_position
+= written
;
137 ldns_buffer_free(ldns_buffer
*buffer
)
144 LDNS_FREE(buffer
->_data
);
150 ldns_buffer_export(ldns_buffer
*buffer
)
153 return buffer
->_data
;
157 ldns_bgetc(ldns_buffer
*buffer
)
159 if (!ldns_buffer_available_at(buffer
, buffer
->_position
, sizeof(uint8_t))) {
160 ldns_buffer_set_position(buffer
, ldns_buffer_limit(buffer
));
161 /* ldns_buffer_rewind(buffer);*/
164 return (int)ldns_buffer_read_u8(buffer
);
168 ldns_buffer_copy(ldns_buffer
* result
, ldns_buffer
* from
)
170 size_t tocopy
= ldns_buffer_limit(from
);
172 if(tocopy
> ldns_buffer_capacity(result
))
173 tocopy
= ldns_buffer_capacity(result
);
174 ldns_buffer_clear(result
);
175 ldns_buffer_write(result
, ldns_buffer_begin(from
), tocopy
);
176 ldns_buffer_flip(result
);