File Coverage

src/ldns/buffer.c
Criterion Covered Total %
statement 65 90 72.2
branch 19 32 59.3
condition n/a
subroutine n/a
pod n/a
total 84 122 68.8


line stmt bran cond sub pod time code
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
11              
12             #include
13             #include
14              
15             ldns_buffer *
16 322           ldns_buffer_new(size_t capacity)
17             {
18 322           ldns_buffer *buffer = LDNS_MALLOC(ldns_buffer);
19              
20 322 50         if (!buffer) {
21 0           return NULL;
22             }
23            
24 322           buffer->_data = (uint8_t *) LDNS_XMALLOC(uint8_t, capacity);
25 322 50         if (!buffer->_data) {
26 0           LDNS_FREE(buffer);
27 0           return NULL;
28             }
29            
30 322           buffer->_position = 0;
31 322           buffer->_limit = buffer->_capacity = capacity;
32 322           buffer->_fixed = 0;
33 322           buffer->_status = LDNS_STATUS_OK;
34            
35 322           ldns_buffer_invariant(buffer);
36            
37 322           return buffer;
38             }
39              
40             void
41 127           ldns_buffer_new_frm_data(ldns_buffer *buffer, void *data, size_t size)
42             {
43             assert(data != NULL);
44              
45 127           buffer->_position = 0;
46 127           buffer->_limit = buffer->_capacity = size;
47 127           buffer->_fixed = 0;
48 127           buffer->_data = LDNS_XMALLOC(uint8_t, size);
49 127 50         if(!buffer->_data) {
50 0           buffer->_status = LDNS_STATUS_MEM_ERR;
51 0           return;
52             }
53 127           memcpy(buffer->_data, data, size);
54 127           buffer->_status = LDNS_STATUS_OK;
55            
56 127           ldns_buffer_invariant(buffer);
57             }
58              
59             bool
60 231           ldns_buffer_set_capacity(ldns_buffer *buffer, size_t capacity)
61             {
62             void *data;
63            
64 231           ldns_buffer_invariant(buffer);
65             assert(buffer->_position <= capacity);
66              
67 231           data = (uint8_t *) LDNS_XREALLOC(buffer->_data, uint8_t, capacity);
68 231 50         if (!data) {
69 0           buffer->_status = LDNS_STATUS_MEM_ERR;
70 0           return false;
71             } else {
72 231           buffer->_data = data;
73 231           buffer->_limit = buffer->_capacity = capacity;
74 231           return true;
75             }
76             }
77              
78             bool
79 769           ldns_buffer_reserve(ldns_buffer *buffer, size_t amount)
80             {
81 769           ldns_buffer_invariant(buffer);
82             assert(!buffer->_fixed);
83 769 100         if (buffer->_capacity < buffer->_position + amount) {
84 1           size_t new_capacity = buffer->_capacity * 3 / 2;
85              
86 1 50         if (new_capacity < buffer->_position + amount) {
87 0           new_capacity = buffer->_position + amount;
88             }
89 1 50         if (!ldns_buffer_set_capacity(buffer, new_capacity)) {
90 0           buffer->_status = LDNS_STATUS_MEM_ERR;
91 0           return false;
92             }
93             }
94 769           buffer->_limit = buffer->_capacity;
95 769           return true;
96             }
97              
98             int
99 1227           ldns_buffer_printf(ldns_buffer *buffer, const char *format, ...)
100             {
101             va_list args;
102 1227           int written = 0;
103             size_t remaining;
104            
105 1227 50         if (ldns_buffer_status_ok(buffer)) {
106 1227           ldns_buffer_invariant(buffer);
107             assert(buffer->_limit == buffer->_capacity);
108              
109 1227           remaining = ldns_buffer_remaining(buffer);
110 1227           va_start(args, format);
111 1227           written = vsnprintf((char *) ldns_buffer_current(buffer), remaining,
112             format, args);
113 1227           va_end(args);
114 1227 50         if (written == -1) {
115 0           buffer->_status = LDNS_STATUS_INTERNAL_ERR;
116 0           return -1;
117 1227 100         } else if ((size_t) written >= remaining) {
118 1 50         if (!ldns_buffer_reserve(buffer, (size_t) written + 1)) {
119 0           buffer->_status = LDNS_STATUS_MEM_ERR;
120 0           return -1;
121             }
122 1           va_start(args, format);
123 1           written = vsnprintf((char *) ldns_buffer_current(buffer),
124             ldns_buffer_remaining(buffer), format, args);
125 1           va_end(args);
126 1 50         if (written == -1) {
127 0           buffer->_status = LDNS_STATUS_INTERNAL_ERR;
128 0           return -1;
129             }
130             }
131 1227           buffer->_position += written;
132             }
133 1227           return written;
134             }
135              
136             void
137 449           ldns_buffer_free(ldns_buffer *buffer)
138             {
139 449 50         if (!buffer) {
140 0           return;
141             }
142              
143 449 100         if (!buffer->_fixed)
144 216           LDNS_FREE(buffer->_data);
145              
146 449           LDNS_FREE(buffer);
147             }
148              
149             void *
150 233           ldns_buffer_export(ldns_buffer *buffer)
151             {
152 233           buffer->_fixed = 1;
153 233           return buffer->_data;
154             }
155              
156             int
157 5671           ldns_bgetc(ldns_buffer *buffer)
158             {
159 5671 100         if (!ldns_buffer_available_at(buffer, buffer->_position, sizeof(uint8_t))) {
160 146           ldns_buffer_set_position(buffer, ldns_buffer_limit(buffer));
161             /* ldns_buffer_rewind(buffer);*/
162 146           return EOF;
163             }
164 5525           return (int)ldns_buffer_read_u8(buffer);
165             }
166              
167             void
168 0           ldns_buffer_copy(ldns_buffer* result, ldns_buffer* from)
169             {
170 0           size_t tocopy = ldns_buffer_limit(from);
171              
172 0 0         if(tocopy > ldns_buffer_capacity(result))
173 0           tocopy = ldns_buffer_capacity(result);
174 0           ldns_buffer_clear(result);
175 0           ldns_buffer_write(result, ldns_buffer_begin(from), tocopy);
176 0           ldns_buffer_flip(result);
177 0           }