buffer.c
Go to the documentation of this file.
1/*
2 * buffer.c -- generic memory buffer .
3 *
4 * Copyright (c) 2001-2008, NLnet Labs. All rights reserved.
5 *
6 * See LICENSE for the license.
7 *
8 */
9
10#include <ldns/config.h>
11
12#include <ldns/ldns.h>
13#include <ldns/buffer.h>
14
16ldns_buffer_new(size_t capacity)
17{
19
20 if (!buffer) {
21 return NULL;
22 }
23
24 buffer->_data = (uint8_t *) LDNS_XMALLOC(uint8_t, capacity);
25 if (!buffer->_data) {
26 LDNS_FREE(buffer);
27 return NULL;
28 }
29
30 buffer->_position = 0;
31 buffer->_limit = buffer->_capacity = capacity;
32 buffer->_fixed = 0;
33 buffer->_status = LDNS_STATUS_OK;
34
35 ldns_buffer_invariant(buffer);
36
37 return buffer;
38}
39
40void
41ldns_buffer_new_frm_data(ldns_buffer *buffer, const void *data, size_t size)
42{
43 assert(data != NULL);
44
45 buffer->_position = 0;
46 buffer->_limit = buffer->_capacity = size;
47 buffer->_fixed = 0;
48 buffer->_data = LDNS_XMALLOC(uint8_t, size);
49 if(!buffer->_data) {
51 return;
52 }
53 memcpy(buffer->_data, data, size);
54 buffer->_status = LDNS_STATUS_OK;
55
56 ldns_buffer_invariant(buffer);
57}
58
59bool
60ldns_buffer_set_capacity(ldns_buffer *buffer, size_t capacity)
61{
62 void *data;
63
64 ldns_buffer_invariant(buffer);
65 assert(buffer->_position <= capacity);
66 assert(!buffer->_fixed);
67
68 data = (uint8_t *) LDNS_XREALLOC(buffer->_data, uint8_t, capacity);
69 if (!data) {
71 return false;
72 } else {
73 buffer->_data = data;
74 buffer->_limit = buffer->_capacity = capacity;
75 return true;
76 }
77}
78
79bool
80ldns_buffer_reserve(ldns_buffer *buffer, size_t amount)
81{
82 ldns_buffer_invariant(buffer);
83 if (buffer->_capacity < buffer->_position + amount) {
84 size_t new_capacity = buffer->_capacity * 3 / 2;
85
86 if (new_capacity < buffer->_position + amount) {
87 new_capacity = buffer->_position + amount;
88 }
89 if (!ldns_buffer_set_capacity(buffer, new_capacity)) {
91 return false;
92 }
93 }
94 buffer->_limit = buffer->_capacity;
95 return true;
96}
97
98int
99ldns_buffer_printf(ldns_buffer *buffer, const char *format, ...)
100{
101 va_list args;
102 int written = 0;
103 size_t remaining;
104
105 if (ldns_buffer_status_ok(buffer)) {
106 ldns_buffer_invariant(buffer);
107 assert(buffer->_limit == buffer->_capacity);
108
109 remaining = ldns_buffer_remaining(buffer);
110 va_start(args, format);
111 written = vsnprintf((char *) ldns_buffer_current(buffer), remaining,
112 format, args);
113 va_end(args);
114 if (written == -1) {
116 return -1;
117 } else if ((size_t) written >= remaining) {
118 if (!ldns_buffer_reserve(buffer, (size_t) written + 1)) {
120 return -1;
121 }
122 va_start(args, format);
123 written = vsnprintf((char *) ldns_buffer_current(buffer),
124 ldns_buffer_remaining(buffer), format, args);
125 va_end(args);
126 if (written == -1) {
128 return -1;
129 }
130 }
131 buffer->_position += written;
132 }
133 return written;
134}
135
136void
138{
139 if (!buffer) {
140 return;
141 }
142
143 if (!buffer->_fixed)
144 LDNS_FREE(buffer->_data);
145
146 LDNS_FREE(buffer);
147}
148
149void *
151{
152 buffer->_fixed = 1;
153 return buffer->_data;
154}
155
156int
158{
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);*/
162 return EOF;
163 }
164 return (int)ldns_buffer_read_u8(buffer);
165}
166
167void
169{
170 size_t tocopy = ldns_buffer_limit(from);
171
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);
177}
void ldns_buffer_free(ldns_buffer *buffer)
frees the buffer.
Definition buffer.c:137
ldns_buffer * ldns_buffer_new(size_t capacity)
creates a new buffer with the specified capacity.
Definition buffer.c:16
void * ldns_buffer_export(ldns_buffer *buffer)
Makes the buffer fixed and returns a pointer to the data.
Definition buffer.c:150
void ldns_buffer_copy(ldns_buffer *result, const ldns_buffer *from)
Copy contents of the from buffer to the result buffer and then flips the result buffer.
Definition buffer.c:168
signed char ldns_buffer_set_capacity(ldns_buffer *buffer, size_t capacity)
changes the buffer's capacity.
Definition buffer.c:60
signed char ldns_buffer_reserve(ldns_buffer *buffer, size_t amount)
ensures BUFFER can contain at least AMOUNT more bytes.
Definition buffer.c:80
int ldns_bgetc(ldns_buffer *buffer)
returns the next character from a buffer.
Definition buffer.c:157
int ldns_buffer_printf(ldns_buffer *buffer, const char *format,...)
prints to the buffer, increasing the capacity if required using buffer_reserve().
Definition buffer.c:99
void ldns_buffer_new_frm_data(ldns_buffer *buffer, const void *data, size_t size)
creates a buffer with the specified data.
Definition buffer.c:41
This file contains the definition of ldns_buffer, and functions to manipulate those.
@ LDNS_STATUS_MEM_ERR
Definition error.h:34
@ LDNS_STATUS_INTERNAL_ERR
Definition error.h:35
@ LDNS_STATUS_OK
Definition error.h:26
Including this file will include all ldns files, and define some lookup tables.
implementation of buffers to ease operations
Definition buffer.h:51
size_t _capacity
The amount of data the buffer can contain.
Definition buffer.h:59
unsigned _fixed
If the buffer is fixed it cannot be resized.
Definition buffer.h:65
size_t _position
The current position used for reading/writing.
Definition buffer.h:53
ldns_status _status
The current state of the buffer.
Definition buffer.h:70
uint8_t * _data
The data contained in the buffer.
Definition buffer.h:62
size_t _limit
The read/write limit.
Definition buffer.h:56
#define LDNS_FREE(ptr)
Definition util.h:60
#define LDNS_MALLOC(type)
Memory management macros.
Definition util.h:49
#define LDNS_XMALLOC(type, count)
Definition util.h:51
#define LDNS_XREALLOC(ptr, type, count)
Definition util.h:57