buffer.h
Go to the documentation of this file.
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_BUFFER_H
14#define LDNS_BUFFER_H
15
16#include <assert.h>
17#include <stdarg.h>
18#include <string.h>
19
20#include <ldns/error.h>
21#include <ldns/common.h>
22
23#include "ldns/util.h"
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
33#define LDNS_MIN_BUFLEN 512
34
51{
53 size_t _position;
54
56 size_t _limit;
57
59 size_t _capacity;
60
62 uint8_t *_data;
63
65 unsigned _fixed : 1;
66
71};
73
74
75#ifdef NDEBUG
76INLINE void
77ldns_buffer_invariant(const ldns_buffer *ATTR_UNUSED(buffer))
78{
79}
80#else
81INLINE void
82ldns_buffer_invariant(const ldns_buffer *buffer)
83{
84 assert(buffer != NULL);
85 assert(buffer->_position <= buffer->_limit);
86 assert(buffer->_limit <= buffer->_capacity);
87 assert(buffer->_data != NULL);
88}
89#endif
90
97ldns_buffer *ldns_buffer_new(size_t capacity);
98
108void ldns_buffer_new_frm_data(ldns_buffer *buffer, const void *data, size_t size);
109
115INLINE void ldns_buffer_clear(ldns_buffer *buffer)
116{
117 ldns_buffer_invariant(buffer);
118
119 /* reset status here? */
120
121 buffer->_position = 0;
122 buffer->_limit = buffer->_capacity;
123}
124
133INLINE void ldns_buffer_flip(ldns_buffer *buffer)
134{
135 ldns_buffer_invariant(buffer);
136
137 buffer->_limit = buffer->_position;
138 buffer->_position = 0;
139}
140
146INLINE void ldns_buffer_rewind(ldns_buffer *buffer)
147{
148 ldns_buffer_invariant(buffer);
149
150 buffer->_position = 0;
151}
152
158INLINE size_t
159ldns_buffer_position(const ldns_buffer *buffer)
160{
161 return buffer->_position;
162}
163
170INLINE void
171ldns_buffer_set_position(ldns_buffer *buffer, size_t mark)
172{
173 assert(mark <= buffer->_limit);
174 buffer->_position = mark;
175}
176
184INLINE void
185ldns_buffer_skip(ldns_buffer *buffer, ssize_t count)
186{
187 assert(buffer->_position + count <= buffer->_limit);
188 buffer->_position += count;
189}
190
196INLINE size_t
197ldns_buffer_limit(const ldns_buffer *buffer)
198{
199 return buffer->_limit;
200}
201
208INLINE void
209ldns_buffer_set_limit(ldns_buffer *buffer, size_t limit)
210{
211 assert(limit <= buffer->_capacity);
212 buffer->_limit = limit;
213 if (buffer->_position > buffer->_limit)
214 buffer->_position = buffer->_limit;
215}
216
222INLINE size_t
223ldns_buffer_capacity(const ldns_buffer *buffer)
224{
225 return buffer->_capacity;
226}
227
236bool ldns_buffer_set_capacity(ldns_buffer *buffer, size_t capacity);
237
248bool ldns_buffer_reserve(ldns_buffer *buffer, size_t amount);
249
256INLINE uint8_t *
257ldns_buffer_at(const ldns_buffer *buffer, size_t at)
258{
259 assert(at <= buffer->_limit);
260 return buffer->_data + at;
261}
262
269INLINE uint8_t *
270ldns_buffer_begin(const ldns_buffer *buffer)
271{
272 return ldns_buffer_at(buffer, 0);
273}
274
281INLINE uint8_t *
282ldns_buffer_end(const ldns_buffer *buffer)
283{
284 return ldns_buffer_at(buffer, buffer->_limit);
285}
286
292INLINE uint8_t *
293ldns_buffer_current(const ldns_buffer *buffer)
294{
295 return ldns_buffer_at(buffer, buffer->_position);
296}
297
305INLINE size_t
306ldns_buffer_remaining_at(const ldns_buffer *buffer, size_t at)
307{
308 ldns_buffer_invariant(buffer);
309 assert(at <= buffer->_limit);
310 return buffer->_limit - at;
311}
312
319INLINE size_t
320ldns_buffer_remaining(const ldns_buffer *buffer)
321{
322 return ldns_buffer_remaining_at(buffer, buffer->_position);
323}
324
334INLINE int
335ldns_buffer_available_at(const ldns_buffer *buffer, size_t at, size_t count)
336{
337 return count <= ldns_buffer_remaining_at(buffer, at);
338}
339
346INLINE int
347ldns_buffer_available(const ldns_buffer *buffer, size_t count)
348{
349 return ldns_buffer_available_at(buffer, buffer->_position, count);
350}
351
359INLINE void
360ldns_buffer_write_at(ldns_buffer *buffer, size_t at, const void *data, size_t count)
361{
362 assert(ldns_buffer_available_at(buffer, at, count));
363 memcpy(buffer->_data + at, data, count);
364}
365
372INLINE void
373ldns_buffer_write(ldns_buffer *buffer, const void *data, size_t count)
374{
375 ldns_buffer_write_at(buffer, buffer->_position, data, count);
376 buffer->_position += count;
377}
378
385INLINE void
386ldns_buffer_write_string_at(ldns_buffer *buffer, size_t at, const char *str)
387{
388 ldns_buffer_write_at(buffer, at, str, strlen(str));
389}
390
396INLINE void
397ldns_buffer_write_string(ldns_buffer *buffer, const char *str)
398{
399 ldns_buffer_write(buffer, str, strlen(str));
400}
401
408INLINE void
409ldns_buffer_write_chars(ldns_buffer *buffer, const char *str)
410{
411 if (!ldns_buffer_reserve(buffer, strlen(str)))
413 else
414 ldns_buffer_write_string(buffer, str);
415}
416
417
424INLINE void
425ldns_buffer_write_u8_at(ldns_buffer *buffer, size_t at, uint8_t data)
426{
427 assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
428 buffer->_data[at] = data;
429}
430
436INLINE void
437ldns_buffer_write_u8(ldns_buffer *buffer, uint8_t data)
438{
439 ldns_buffer_write_u8_at(buffer, buffer->_position, data);
440 buffer->_position += sizeof(data);
441}
442
449INLINE void
450ldns_buffer_write_char(ldns_buffer *buffer, uint8_t data)
451{
452 if (!ldns_buffer_reserve(buffer, sizeof(data)))
454 else
455 ldns_buffer_write_u8(buffer, data);
456}
457
464INLINE void
465ldns_buffer_write_u16_at(ldns_buffer *buffer, size_t at, uint16_t data)
466{
467 assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
468 ldns_write_uint16(buffer->_data + at, data);
469}
470
476INLINE void
477ldns_buffer_write_u16(ldns_buffer *buffer, uint16_t data)
478{
479 ldns_buffer_write_u16_at(buffer, buffer->_position, data);
480 buffer->_position += sizeof(data);
481}
482
489INLINE void
490ldns_buffer_write_u32_at(ldns_buffer *buffer, size_t at, uint32_t data)
491{
492 assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
493 ldns_write_uint32(buffer->_data + at, data);
494}
495
501INLINE void
502ldns_buffer_write_u32(ldns_buffer *buffer, uint32_t data)
503{
504 ldns_buffer_write_u32_at(buffer, buffer->_position, data);
505 buffer->_position += sizeof(data);
506}
507
515INLINE void
516ldns_buffer_read_at(const ldns_buffer *buffer, size_t at, void *data, size_t count)
517{
518 assert(ldns_buffer_available_at(buffer, at, count));
519 memcpy(data, buffer->_data + at, count);
520}
521
528INLINE void
529ldns_buffer_read(ldns_buffer *buffer, void *data, size_t count)
530{
531 ldns_buffer_read_at(buffer, buffer->_position, data, count);
532 buffer->_position += count;
533}
534
541INLINE uint8_t
542ldns_buffer_read_u8_at(const ldns_buffer *buffer, size_t at)
543{
544 assert(ldns_buffer_available_at(buffer, at, sizeof(uint8_t)));
545 return buffer->_data[at];
546}
547
553INLINE uint8_t
554ldns_buffer_read_u8(ldns_buffer *buffer)
555{
556 uint8_t result = ldns_buffer_read_u8_at(buffer, buffer->_position);
557 buffer->_position += sizeof(uint8_t);
558 return result;
559}
560
567INLINE uint16_t
568ldns_buffer_read_u16_at(ldns_buffer *buffer, size_t at)
569{
570 assert(ldns_buffer_available_at(buffer, at, sizeof(uint16_t)));
571 return ldns_read_uint16(buffer->_data + at);
572}
573
579INLINE uint16_t
580ldns_buffer_read_u16(ldns_buffer *buffer)
581{
582 uint16_t result = ldns_buffer_read_u16_at(buffer, buffer->_position);
583 buffer->_position += sizeof(uint16_t);
584 return result;
585}
586
593INLINE uint32_t
594ldns_buffer_read_u32_at(ldns_buffer *buffer, size_t at)
595{
596 assert(ldns_buffer_available_at(buffer, at, sizeof(uint32_t)));
597 return ldns_read_uint32(buffer->_data + at);
598}
599
605INLINE uint32_t
606ldns_buffer_read_u32(ldns_buffer *buffer)
607{
608 uint32_t result = ldns_buffer_read_u32_at(buffer, buffer->_position);
609 buffer->_position += sizeof(uint32_t);
610 return result;
611}
612
619ldns_buffer_status(const ldns_buffer *buffer)
620{
621 return buffer->_status;
622}
623
629INLINE bool
630ldns_buffer_status_ok(const ldns_buffer *buffer)
631{
632 if (buffer) {
633 return ldns_buffer_status(buffer) == LDNS_STATUS_OK;
634 } else {
635 return false;
636 }
637}
638
645int ldns_buffer_printf(ldns_buffer *buffer, const char *format, ...);
646/* ATTR_FORMAT(printf, 2, 3);*/
647
653void ldns_buffer_free(ldns_buffer *buffer);
654
661void *ldns_buffer_export(ldns_buffer *buffer);
662
670void ldns_buffer_copy(ldns_buffer* result, const ldns_buffer* from);
671
672#ifdef __cplusplus
673}
674#endif
675
676#endif /* LDNS_BUFFER_H */
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_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
Common definitions for LDNS.
#define ATTR_UNUSED(x)
Definition common.h:72
Defines error numbers and functions to translate those to a readable string.
@ LDNS_STATUS_MEM_ERR
Definition error.h:34
@ LDNS_STATUS_OK
Definition error.h:26
enum ldns_enum_status ldns_status
Definition error.h:148
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 INLINE
splint static inline workaround
Definition util.h:42