Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/ldns/buffer.c
39476 views
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
15
ldns_buffer *
16
ldns_buffer_new(size_t capacity)
17
{
18
ldns_buffer *buffer = LDNS_MALLOC(ldns_buffer);
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
40
void
41
ldns_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) {
50
buffer->_status = LDNS_STATUS_MEM_ERR;
51
return;
52
}
53
memcpy(buffer->_data, data, size);
54
buffer->_status = LDNS_STATUS_OK;
55
56
ldns_buffer_invariant(buffer);
57
}
58
59
bool
60
ldns_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) {
70
buffer->_status = LDNS_STATUS_MEM_ERR;
71
return false;
72
} else {
73
buffer->_data = data;
74
buffer->_limit = buffer->_capacity = capacity;
75
return true;
76
}
77
}
78
79
bool
80
ldns_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)) {
90
buffer->_status = LDNS_STATUS_MEM_ERR;
91
return false;
92
}
93
}
94
buffer->_limit = buffer->_capacity;
95
return true;
96
}
97
98
int
99
ldns_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) {
115
buffer->_status = LDNS_STATUS_INTERNAL_ERR;
116
return -1;
117
} else if ((size_t) written >= remaining) {
118
if (!ldns_buffer_reserve(buffer, (size_t) written + 1)) {
119
buffer->_status = LDNS_STATUS_MEM_ERR;
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) {
127
buffer->_status = LDNS_STATUS_INTERNAL_ERR;
128
return -1;
129
}
130
}
131
buffer->_position += written;
132
}
133
return written;
134
}
135
136
void
137
ldns_buffer_free(ldns_buffer *buffer)
138
{
139
if (!buffer) {
140
return;
141
}
142
143
if (!buffer->_fixed)
144
LDNS_FREE(buffer->_data);
145
146
LDNS_FREE(buffer);
147
}
148
149
void *
150
ldns_buffer_export(ldns_buffer *buffer)
151
{
152
buffer->_fixed = 1;
153
return buffer->_data;
154
}
155
156
int
157
ldns_bgetc(ldns_buffer *buffer)
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
167
void
168
ldns_buffer_copy(ldns_buffer* result, const ldns_buffer* from)
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
}
178
179