]>
Commit | Line | Data |
---|---|---|
89c4ed63 A |
1 | /* |
2 | * buffer.h -- generic memory buffer. | |
3 | * | |
4 | * Copyright (c) 2005-2008, NLnet Labs. All rights reserved. | |
5 | * | |
6 | * See LICENSE for the license. | |
7 | * | |
8 | * | |
9 | * The buffer module implements a generic buffer. The API is based on | |
10 | * the java.nio.Buffer interface. | |
11 | */ | |
12 | ||
13 | #ifndef LDNS_SBUFFER_H | |
14 | #define LDNS_SBUFFER_H | |
15 | ||
16 | #ifdef __cplusplus | |
17 | extern "C" { | |
18 | #endif | |
19 | ||
20 | #ifdef S_SPLINT_S | |
21 | # define INLINE | |
22 | #else | |
23 | # ifdef SWIG | |
24 | # define INLINE static | |
25 | # else | |
26 | # define INLINE static inline | |
27 | # endif | |
28 | #endif | |
29 | ||
30 | /* | |
31 | * Copy data allowing for unaligned accesses in network byte order | |
32 | * (big endian). | |
33 | */ | |
34 | INLINE uint16_t | |
35 | sldns_read_uint16(const void *src) | |
36 | { | |
37 | #ifdef ALLOW_UNALIGNED_ACCESSES | |
38 | return ntohs(*(const uint16_t *) src); | |
39 | #else | |
40 | const uint8_t *p = (const uint8_t *) src; | |
41 | return ((uint16_t) p[0] << 8) | (uint16_t) p[1]; | |
42 | #endif | |
43 | } | |
44 | ||
45 | INLINE uint32_t | |
46 | sldns_read_uint32(const void *src) | |
47 | { | |
48 | #ifdef ALLOW_UNALIGNED_ACCESSES | |
49 | return ntohl(*(const uint32_t *) src); | |
50 | #else | |
51 | const uint8_t *p = (const uint8_t *) src; | |
52 | return ( ((uint32_t) p[0] << 24) | |
53 | | ((uint32_t) p[1] << 16) | |
54 | | ((uint32_t) p[2] << 8) | |
55 | | (uint32_t) p[3]); | |
56 | #endif | |
57 | } | |
58 | ||
59 | /* | |
60 | * Copy data allowing for unaligned accesses in network byte order | |
61 | * (big endian). | |
62 | */ | |
63 | INLINE void | |
64 | sldns_write_uint16(void *dst, uint16_t data) | |
65 | { | |
66 | #ifdef ALLOW_UNALIGNED_ACCESSES | |
67 | * (uint16_t *) dst = htons(data); | |
68 | #else | |
69 | uint8_t *p = (uint8_t *) dst; | |
70 | p[0] = (uint8_t) ((data >> 8) & 0xff); | |
71 | p[1] = (uint8_t) (data & 0xff); | |
72 | #endif | |
73 | } | |
74 | ||
75 | INLINE void | |
76 | sldns_write_uint32(void *dst, uint32_t data) | |
77 | { | |
78 | #ifdef ALLOW_UNALIGNED_ACCESSES | |
79 | * (uint32_t *) dst = htonl(data); | |
80 | #else | |
81 | uint8_t *p = (uint8_t *) dst; | |
82 | p[0] = (uint8_t) ((data >> 24) & 0xff); | |
83 | p[1] = (uint8_t) ((data >> 16) & 0xff); | |
84 | p[2] = (uint8_t) ((data >> 8) & 0xff); | |
85 | p[3] = (uint8_t) (data & 0xff); | |
86 | #endif | |
87 | } | |
88 | ||
89 | ||
90 | /** | |
91 | * \file sbuffer.h | |
92 | * | |
93 | * This file contains the definition of sldns_buffer, and functions to manipulate those. | |
94 | */ | |
95 | ||
96 | /** | |
97 | * implementation of buffers to ease operations | |
98 | * | |
99 | * sldns_buffers can contain arbitrary information, per octet. You can write | |
100 | * to the current end of a buffer, read from the current position, and | |
101 | * access any data within it. | |
102 | */ | |
103 | struct sldns_buffer | |
104 | { | |
105 | /** The current position used for reading/writing */ | |
106 | size_t _position; | |
107 | ||
108 | /** The read/write limit */ | |
109 | size_t _limit; | |
110 | ||
111 | /** The amount of data the buffer can contain */ | |
112 | size_t _capacity; | |
113 | ||
114 | /** The data contained in the buffer */ | |
115 | uint8_t *_data; | |
116 | ||
117 | /** If the buffer is fixed it cannot be resized */ | |
118 | unsigned _fixed : 1; | |
119 | ||
120 | /** The current state of the buffer. If writing to the buffer fails | |
121 | * for any reason, this value is changed. This way, you can perform | |
122 | * multiple writes in sequence and check for success afterwards. */ | |
123 | unsigned _status_err : 1; | |
124 | }; | |
125 | typedef struct sldns_buffer sldns_buffer; | |
126 | ||
127 | #ifdef NDEBUG | |
128 | INLINE void | |
129 | sldns_buffer_invariant(sldns_buffer *ATTR_UNUSED(buffer)) | |
130 | { | |
131 | } | |
132 | #else | |
133 | INLINE void | |
134 | sldns_buffer_invariant(sldns_buffer *buffer) | |
135 | { | |
136 | assert(buffer != NULL); | |
137 | assert(buffer->_position <= buffer->_limit); | |
138 | assert(buffer->_limit <= buffer->_capacity); | |
139 | assert(buffer->_data != NULL); | |
140 | } | |
141 | #endif | |
142 | ||
143 | /** | |
144 | * creates a new buffer with the specified capacity. | |
145 | * | |
146 | * \param[in] capacity the size (in bytes) to allocate for the buffer | |
147 | * \return the created buffer | |
148 | */ | |
149 | sldns_buffer *sldns_buffer_new(size_t capacity); | |
150 | ||
151 | /** | |
152 | * creates a buffer with the specified data. The data IS copied | |
153 | * and MEMORY allocations are done. The buffer is not fixed and can | |
154 | * be resized using buffer_reserve(). | |
155 | * | |
156 | * \param[in] buffer pointer to the buffer to put the data in | |
157 | * \param[in] data the data to encapsulate in the buffer | |
158 | * \param[in] size the size of the data | |
159 | */ | |
160 | void sldns_buffer_new_frm_data(sldns_buffer *buffer, void *data, size_t size); | |
161 | ||
162 | /** | |
163 | * Setup a buffer with the data pointed to. No data copied, no memory allocs. | |
164 | * The buffer is fixed. | |
165 | * \param[in] buffer pointer to the buffer to put the data in | |
166 | * \param[in] data the data to encapsulate in the buffer | |
167 | * \param[in] size the size of the data | |
168 | */ | |
169 | void sldns_buffer_init_frm_data(sldns_buffer *buffer, void *data, size_t size); | |
170 | ||
171 | /** | |
172 | * clears the buffer and make it ready for writing. The buffer's limit | |
173 | * is set to the capacity and the position is set to 0. | |
174 | * \param[in] buffer the buffer to clear | |
175 | */ | |
176 | INLINE void sldns_buffer_clear(sldns_buffer *buffer) | |
177 | { | |
178 | sldns_buffer_invariant(buffer); | |
179 | ||
180 | /* reset status here? */ | |
181 | ||
182 | buffer->_position = 0; | |
183 | buffer->_limit = buffer->_capacity; | |
184 | } | |
185 | ||
186 | /** | |
187 | * makes the buffer ready for reading the data that has been written to | |
188 | * the buffer. The buffer's limit is set to the current position and | |
189 | * the position is set to 0. | |
190 | * | |
191 | * \param[in] buffer the buffer to flip | |
192 | * \return void | |
193 | */ | |
194 | INLINE void sldns_buffer_flip(sldns_buffer *buffer) | |
195 | { | |
196 | sldns_buffer_invariant(buffer); | |
197 | ||
198 | buffer->_limit = buffer->_position; | |
199 | buffer->_position = 0; | |
200 | } | |
201 | ||
202 | /** | |
203 | * make the buffer ready for re-reading the data. The buffer's | |
204 | * position is reset to 0. | |
205 | * \param[in] buffer the buffer to rewind | |
206 | */ | |
207 | INLINE void sldns_buffer_rewind(sldns_buffer *buffer) | |
208 | { | |
209 | sldns_buffer_invariant(buffer); | |
210 | ||
211 | buffer->_position = 0; | |
212 | } | |
213 | ||
214 | /** | |
215 | * returns the current position in the buffer (as a number of bytes) | |
216 | * \param[in] buffer the buffer | |
217 | * \return the current position | |
218 | */ | |
219 | INLINE size_t | |
220 | sldns_buffer_position(sldns_buffer *buffer) | |
221 | { | |
222 | return buffer->_position; | |
223 | } | |
224 | ||
225 | /** | |
226 | * sets the buffer's position to MARK. The position must be less than | |
227 | * or equal to the buffer's limit. | |
228 | * \param[in] buffer the buffer | |
229 | * \param[in] mark the mark to use | |
230 | */ | |
231 | INLINE void | |
232 | sldns_buffer_set_position(sldns_buffer *buffer, size_t mark) | |
233 | { | |
234 | assert(mark <= buffer->_limit); | |
235 | buffer->_position = mark; | |
236 | } | |
237 | ||
238 | /** | |
239 | * changes the buffer's position by COUNT bytes. The position must not | |
240 | * be moved behind the buffer's limit or before the beginning of the | |
241 | * buffer. | |
242 | * \param[in] buffer the buffer | |
243 | * \param[in] count the count to use | |
244 | */ | |
245 | INLINE void | |
246 | sldns_buffer_skip(sldns_buffer *buffer, ssize_t count) | |
247 | { | |
248 | assert(buffer->_position + count <= buffer->_limit); | |
249 | buffer->_position += count; | |
250 | } | |
251 | ||
252 | /** | |
253 | * returns the maximum size of the buffer | |
254 | * \param[in] buffer | |
255 | * \return the size | |
256 | */ | |
257 | INLINE size_t | |
258 | sldns_buffer_limit(sldns_buffer *buffer) | |
259 | { | |
260 | return buffer->_limit; | |
261 | } | |
262 | ||
263 | /** | |
264 | * changes the buffer's limit. If the buffer's position is greater | |
265 | * than the new limit the position is set to the limit. | |
266 | * \param[in] buffer the buffer | |
267 | * \param[in] limit the new limit | |
268 | */ | |
269 | INLINE void | |
270 | sldns_buffer_set_limit(sldns_buffer *buffer, size_t limit) | |
271 | { | |
272 | assert(limit <= buffer->_capacity); | |
273 | buffer->_limit = limit; | |
274 | if (buffer->_position > buffer->_limit) | |
275 | buffer->_position = buffer->_limit; | |
276 | } | |
277 | ||
278 | /** | |
279 | * returns the number of bytes the buffer can hold. | |
280 | * \param[in] buffer the buffer | |
281 | * \return the number of bytes | |
282 | */ | |
283 | INLINE size_t | |
284 | sldns_buffer_capacity(sldns_buffer *buffer) | |
285 | { | |
286 | return buffer->_capacity; | |
287 | } | |
288 | ||
289 | /** | |
290 | * changes the buffer's capacity. The data is reallocated so any | |
291 | * pointers to the data may become invalid. The buffer's limit is set | |
292 | * to the buffer's new capacity. | |
293 | * \param[in] buffer the buffer | |
294 | * \param[in] capacity the capacity to use | |
295 | * \return whether this failed or succeeded | |
296 | */ | |
297 | int sldns_buffer_set_capacity(sldns_buffer *buffer, size_t capacity); | |
298 | ||
299 | /** | |
300 | * ensures BUFFER can contain at least AMOUNT more bytes. The buffer's | |
301 | * capacity is increased if necessary using buffer_set_capacity(). | |
302 | * | |
303 | * The buffer's limit is always set to the (possibly increased) | |
304 | * capacity. | |
305 | * \param[in] buffer the buffer | |
306 | * \param[in] amount amount to use | |
307 | * \return whether this failed or succeeded | |
308 | */ | |
309 | int sldns_buffer_reserve(sldns_buffer *buffer, size_t amount); | |
310 | ||
311 | /** | |
312 | * returns a pointer to the data at the indicated position. | |
313 | * \param[in] buffer the buffer | |
314 | * \param[in] at position | |
315 | * \return the pointer to the data | |
316 | */ | |
317 | INLINE uint8_t * | |
318 | sldns_buffer_at(const sldns_buffer *buffer, size_t at) | |
319 | { | |
320 | assert(at <= buffer->_limit); | |
321 | return buffer->_data + at; | |
322 | } | |
323 | ||
324 | /** | |
325 | * returns a pointer to the beginning of the buffer (the data at | |
326 | * position 0). | |
327 | * \param[in] buffer the buffer | |
328 | * \return the pointer | |
329 | */ | |
330 | INLINE uint8_t * | |
331 | sldns_buffer_begin(const sldns_buffer *buffer) | |
332 | { | |
333 | return sldns_buffer_at(buffer, 0); | |
334 | } | |
335 | ||
336 | /** | |
337 | * returns a pointer to the end of the buffer (the data at the buffer's | |
338 | * limit). | |
339 | * \param[in] buffer the buffer | |
340 | * \return the pointer | |
341 | */ | |
342 | INLINE uint8_t * | |
343 | sldns_buffer_end(sldns_buffer *buffer) | |
344 | { | |
345 | return sldns_buffer_at(buffer, buffer->_limit); | |
346 | } | |
347 | ||
348 | /** | |
349 | * returns a pointer to the data at the buffer's current position. | |
350 | * \param[in] buffer the buffer | |
351 | * \return the pointer | |
352 | */ | |
353 | INLINE uint8_t * | |
354 | sldns_buffer_current(sldns_buffer *buffer) | |
355 | { | |
356 | return sldns_buffer_at(buffer, buffer->_position); | |
357 | } | |
358 | ||
359 | /** | |
360 | * returns the number of bytes remaining between the indicated position and | |
361 | * the limit. | |
362 | * \param[in] buffer the buffer | |
363 | * \param[in] at indicated position | |
364 | * \return number of bytes | |
365 | */ | |
366 | INLINE size_t | |
367 | sldns_buffer_remaining_at(sldns_buffer *buffer, size_t at) | |
368 | { | |
369 | sldns_buffer_invariant(buffer); | |
370 | assert(at <= buffer->_limit); | |
371 | return buffer->_limit - at; | |
372 | } | |
373 | ||
374 | /** | |
375 | * returns the number of bytes remaining between the buffer's position and | |
376 | * limit. | |
377 | * \param[in] buffer the buffer | |
378 | * \return the number of bytes | |
379 | */ | |
380 | INLINE size_t | |
381 | sldns_buffer_remaining(sldns_buffer *buffer) | |
382 | { | |
383 | return sldns_buffer_remaining_at(buffer, buffer->_position); | |
384 | } | |
385 | ||
386 | /** | |
387 | * checks if the buffer has at least COUNT more bytes available. | |
388 | * Before reading or writing the caller needs to ensure enough space | |
389 | * is available! | |
390 | * \param[in] buffer the buffer | |
391 | * \param[in] at indicated position | |
392 | * \param[in] count how much is available | |
393 | * \return true or false (as int?) | |
394 | */ | |
395 | INLINE int | |
396 | sldns_buffer_available_at(sldns_buffer *buffer, size_t at, size_t count) | |
397 | { | |
398 | return count <= sldns_buffer_remaining_at(buffer, at); | |
399 | } | |
400 | ||
401 | /** | |
402 | * checks if the buffer has count bytes available at the current position | |
403 | * \param[in] buffer the buffer | |
404 | * \param[in] count how much is available | |
405 | * \return true or false (as int?) | |
406 | */ | |
407 | INLINE int | |
408 | sldns_buffer_available(sldns_buffer *buffer, size_t count) | |
409 | { | |
410 | return sldns_buffer_available_at(buffer, buffer->_position, count); | |
411 | } | |
412 | ||
413 | /** | |
414 | * writes the given data to the buffer at the specified position | |
415 | * \param[in] buffer the buffer | |
416 | * \param[in] at the position (in number of bytes) to write the data at | |
417 | * \param[in] data pointer to the data to write to the buffer | |
418 | * \param[in] count the number of bytes of data to write | |
419 | */ | |
420 | INLINE void | |
421 | sldns_buffer_write_at(sldns_buffer *buffer, size_t at, const void *data, size_t count) | |
422 | { | |
423 | assert(sldns_buffer_available_at(buffer, at, count)); | |
424 | memcpy(buffer->_data + at, data, count); | |
425 | } | |
426 | ||
427 | /** | |
428 | * writes count bytes of data to the current position of the buffer | |
429 | * \param[in] buffer the buffer | |
430 | * \param[in] data the data to write | |
431 | * \param[in] count the lenght of the data to write | |
432 | */ | |
433 | INLINE void | |
434 | sldns_buffer_write(sldns_buffer *buffer, const void *data, size_t count) | |
435 | { | |
436 | sldns_buffer_write_at(buffer, buffer->_position, data, count); | |
437 | buffer->_position += count; | |
438 | } | |
439 | ||
440 | /** | |
441 | * copies the given (null-delimited) string to the specified position at the buffer | |
442 | * \param[in] buffer the buffer | |
443 | * \param[in] at the position in the buffer | |
444 | * \param[in] str the string to write | |
445 | */ | |
446 | INLINE void | |
447 | sldns_buffer_write_string_at(sldns_buffer *buffer, size_t at, const char *str) | |
448 | { | |
449 | sldns_buffer_write_at(buffer, at, str, strlen(str)); | |
450 | } | |
451 | ||
452 | /** | |
453 | * copies the given (null-delimited) string to the current position at the buffer | |
454 | * \param[in] buffer the buffer | |
455 | * \param[in] str the string to write | |
456 | */ | |
457 | INLINE void | |
458 | sldns_buffer_write_string(sldns_buffer *buffer, const char *str) | |
459 | { | |
460 | sldns_buffer_write(buffer, str, strlen(str)); | |
461 | } | |
462 | ||
463 | /** | |
464 | * writes the given byte of data at the given position in the buffer | |
465 | * \param[in] buffer the buffer | |
466 | * \param[in] at the position in the buffer | |
467 | * \param[in] data the 8 bits to write | |
468 | */ | |
469 | INLINE void | |
470 | sldns_buffer_write_u8_at(sldns_buffer *buffer, size_t at, uint8_t data) | |
471 | { | |
472 | assert(sldns_buffer_available_at(buffer, at, sizeof(data))); | |
473 | buffer->_data[at] = data; | |
474 | } | |
475 | ||
476 | /** | |
477 | * writes the given byte of data at the current position in the buffer | |
478 | * \param[in] buffer the buffer | |
479 | * \param[in] data the 8 bits to write | |
480 | */ | |
481 | INLINE void | |
482 | sldns_buffer_write_u8(sldns_buffer *buffer, uint8_t data) | |
483 | { | |
484 | sldns_buffer_write_u8_at(buffer, buffer->_position, data); | |
485 | buffer->_position += sizeof(data); | |
486 | } | |
487 | ||
488 | /** | |
489 | * writes the given 2 byte integer at the given position in the buffer | |
490 | * \param[in] buffer the buffer | |
491 | * \param[in] at the position in the buffer | |
492 | * \param[in] data the 16 bits to write | |
493 | */ | |
494 | INLINE void | |
495 | sldns_buffer_write_u16_at(sldns_buffer *buffer, size_t at, uint16_t data) | |
496 | { | |
497 | assert(sldns_buffer_available_at(buffer, at, sizeof(data))); | |
498 | sldns_write_uint16(buffer->_data + at, data); | |
499 | } | |
500 | ||
501 | /** | |
502 | * writes the given 2 byte integer at the current position in the buffer | |
503 | * \param[in] buffer the buffer | |
504 | * \param[in] data the 16 bits to write | |
505 | */ | |
506 | INLINE void | |
507 | sldns_buffer_write_u16(sldns_buffer *buffer, uint16_t data) | |
508 | { | |
509 | sldns_buffer_write_u16_at(buffer, buffer->_position, data); | |
510 | buffer->_position += sizeof(data); | |
511 | } | |
512 | ||
513 | /** | |
514 | * writes the given 4 byte integer at the given position in the buffer | |
515 | * \param[in] buffer the buffer | |
516 | * \param[in] at the position in the buffer | |
517 | * \param[in] data the 32 bits to write | |
518 | */ | |
519 | INLINE void | |
520 | sldns_buffer_write_u32_at(sldns_buffer *buffer, size_t at, uint32_t data) | |
521 | { | |
522 | assert(sldns_buffer_available_at(buffer, at, sizeof(data))); | |
523 | sldns_write_uint32(buffer->_data + at, data); | |
524 | } | |
525 | ||
526 | /** | |
527 | * writes the given 4 byte integer at the current position in the buffer | |
528 | * \param[in] buffer the buffer | |
529 | * \param[in] data the 32 bits to write | |
530 | */ | |
531 | INLINE void | |
532 | sldns_buffer_write_u32(sldns_buffer *buffer, uint32_t data) | |
533 | { | |
534 | sldns_buffer_write_u32_at(buffer, buffer->_position, data); | |
535 | buffer->_position += sizeof(data); | |
536 | } | |
537 | ||
538 | /** | |
539 | * copies count bytes of data at the given position to the given data-array | |
540 | * \param[in] buffer the buffer | |
541 | * \param[in] at the position in the buffer to start | |
542 | * \param[out] data buffer to copy to | |
543 | * \param[in] count the length of the data to copy | |
544 | */ | |
545 | INLINE void | |
546 | sldns_buffer_read_at(sldns_buffer *buffer, size_t at, void *data, size_t count) | |
547 | { | |
548 | assert(sldns_buffer_available_at(buffer, at, count)); | |
549 | memcpy(data, buffer->_data + at, count); | |
550 | } | |
551 | ||
552 | /** | |
553 | * copies count bytes of data at the current position to the given data-array | |
554 | * \param[in] buffer the buffer | |
555 | * \param[out] data buffer to copy to | |
556 | * \param[in] count the length of the data to copy | |
557 | */ | |
558 | INLINE void | |
559 | sldns_buffer_read(sldns_buffer *buffer, void *data, size_t count) | |
560 | { | |
561 | sldns_buffer_read_at(buffer, buffer->_position, data, count); | |
562 | buffer->_position += count; | |
563 | } | |
564 | ||
565 | /** | |
566 | * returns the byte value at the given position in the buffer | |
567 | * \param[in] buffer the buffer | |
568 | * \param[in] at the position in the buffer | |
569 | * \return 1 byte integer | |
570 | */ | |
571 | INLINE uint8_t | |
572 | sldns_buffer_read_u8_at(sldns_buffer *buffer, size_t at) | |
573 | { | |
574 | assert(sldns_buffer_available_at(buffer, at, sizeof(uint8_t))); | |
575 | return buffer->_data[at]; | |
576 | } | |
577 | ||
578 | /** | |
579 | * returns the byte value at the current position in the buffer | |
580 | * \param[in] buffer the buffer | |
581 | * \return 1 byte integer | |
582 | */ | |
583 | INLINE uint8_t | |
584 | sldns_buffer_read_u8(sldns_buffer *buffer) | |
585 | { | |
586 | uint8_t result = sldns_buffer_read_u8_at(buffer, buffer->_position); | |
587 | buffer->_position += sizeof(uint8_t); | |
588 | return result; | |
589 | } | |
590 | ||
591 | /** | |
592 | * returns the 2-byte integer value at the given position in the buffer | |
593 | * \param[in] buffer the buffer | |
594 | * \param[in] at position in the buffer | |
595 | * \return 2 byte integer | |
596 | */ | |
597 | INLINE uint16_t | |
598 | sldns_buffer_read_u16_at(sldns_buffer *buffer, size_t at) | |
599 | { | |
600 | assert(sldns_buffer_available_at(buffer, at, sizeof(uint16_t))); | |
601 | return sldns_read_uint16(buffer->_data + at); | |
602 | } | |
603 | ||
604 | /** | |
605 | * returns the 2-byte integer value at the current position in the buffer | |
606 | * \param[in] buffer the buffer | |
607 | * \return 2 byte integer | |
608 | */ | |
609 | INLINE uint16_t | |
610 | sldns_buffer_read_u16(sldns_buffer *buffer) | |
611 | { | |
612 | uint16_t result = sldns_buffer_read_u16_at(buffer, buffer->_position); | |
613 | buffer->_position += sizeof(uint16_t); | |
614 | return result; | |
615 | } | |
616 | ||
617 | /** | |
618 | * returns the 4-byte integer value at the given position in the buffer | |
619 | * \param[in] buffer the buffer | |
620 | * \param[in] at position in the buffer | |
621 | * \return 4 byte integer | |
622 | */ | |
623 | INLINE uint32_t | |
624 | sldns_buffer_read_u32_at(sldns_buffer *buffer, size_t at) | |
625 | { | |
626 | assert(sldns_buffer_available_at(buffer, at, sizeof(uint32_t))); | |
627 | return sldns_read_uint32(buffer->_data + at); | |
628 | } | |
629 | ||
630 | /** | |
631 | * returns the 4-byte integer value at the current position in the buffer | |
632 | * \param[in] buffer the buffer | |
633 | * \return 4 byte integer | |
634 | */ | |
635 | INLINE uint32_t | |
636 | sldns_buffer_read_u32(sldns_buffer *buffer) | |
637 | { | |
638 | uint32_t result = sldns_buffer_read_u32_at(buffer, buffer->_position); | |
639 | buffer->_position += sizeof(uint32_t); | |
640 | return result; | |
641 | } | |
642 | ||
643 | /** | |
644 | * returns the status of the buffer | |
645 | * \param[in] buffer | |
646 | * \return the status | |
647 | */ | |
648 | INLINE int | |
649 | sldns_buffer_status(sldns_buffer *buffer) | |
650 | { | |
651 | return (int)buffer->_status_err; | |
652 | } | |
653 | ||
654 | /** | |
655 | * returns true if the status of the buffer is LDNS_STATUS_OK, false otherwise | |
656 | * \param[in] buffer the buffer | |
657 | * \return true or false | |
658 | */ | |
659 | INLINE int | |
660 | sldns_buffer_status_ok(sldns_buffer *buffer) | |
661 | { | |
662 | if (buffer) { | |
663 | return sldns_buffer_status(buffer) == 0; | |
664 | } else { | |
665 | return 0; | |
666 | } | |
667 | } | |
668 | ||
669 | /** | |
670 | * prints to the buffer, increasing the capacity if required using | |
671 | * buffer_reserve(). The buffer's position is set to the terminating '\\0' | |
672 | * Returns the number of characters written (not including the | |
673 | * terminating '\\0') or -1 on failure. | |
674 | */ | |
675 | int sldns_buffer_printf(sldns_buffer *buffer, const char *format, ...) | |
676 | ATTR_FORMAT(printf, 2, 3); | |
677 | ||
678 | /** | |
679 | * frees the buffer. | |
680 | * \param[in] *buffer the buffer to be freed | |
681 | * \return void | |
682 | */ | |
683 | void sldns_buffer_free(sldns_buffer *buffer); | |
684 | ||
685 | /** | |
686 | * Makes the buffer fixed and returns a pointer to the data. The | |
687 | * caller is responsible for free'ing the result. | |
688 | * \param[in] *buffer the buffer to be exported | |
689 | * \return void | |
690 | */ | |
691 | void *sldns_buffer_export(sldns_buffer *buffer); | |
692 | ||
693 | /** | |
694 | * Copy contents of the from buffer to the result buffer and then flips | |
695 | * the result buffer. Data will be silently truncated if the result buffer is | |
696 | * too small. | |
697 | * \param[out] *result resulting buffer which is copied to. | |
698 | * \param[in] *from what to copy to result. | |
699 | */ | |
700 | void sldns_buffer_copy(sldns_buffer* result, sldns_buffer* from); | |
701 | ||
702 | #ifdef __cplusplus | |
703 | } | |
704 | #endif | |
705 | ||
706 | #endif /* LDNS_SBUFFER_H */ |