1238104Sdes/*
2238104Sdes * buffer.h -- generic memory buffer.
3238104Sdes *
4238104Sdes * Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
5238104Sdes *
6238104Sdes * See LICENSE for the license.
7238104Sdes *
8238104Sdes *
9238104Sdes * The buffer module implements a generic buffer.  The API is based on
10238104Sdes * the java.nio.Buffer interface.
11238104Sdes */
12238104Sdes
13238104Sdes#ifndef LDNS_BUFFER_H
14238104Sdes#define LDNS_BUFFER_H
15238104Sdes
16238104Sdes#include <assert.h>
17238104Sdes#include <stdarg.h>
18238104Sdes#include <string.h>
19238104Sdes
20238104Sdes#include <ldns/error.h>
21238104Sdes#include <ldns/common.h>
22238104Sdes
23238104Sdes#include "ldns/util.h"
24238104Sdes
25238104Sdes#ifdef __cplusplus
26238104Sdesextern "C" {
27238104Sdes#endif
28238104Sdes
29238104Sdes/**
30238104Sdes * number of initial bytes in buffer of
31238104Sdes * which we cannot tell the size before hand
32238104Sdes */
33238104Sdes#define LDNS_MIN_BUFLEN	512
34238104Sdes
35238104Sdes/**
36238104Sdes * \file buffer.h
37238104Sdes *
38238104Sdes * This file contains the definition of ldns_buffer, and functions to manipulate those.
39238104Sdes */
40238104Sdes
41238104Sdes/**
42238104Sdes * implementation of buffers to ease operations
43238104Sdes *
44238104Sdes * ldns_buffers can contain arbitrary information, per octet. You can write
45238104Sdes * to the current end of a buffer, read from the current position, and
46238104Sdes * access any data within it.
47238104Sdes *
48238104Sdes * Example use of buffers is in the source code of \ref host2str.c
49238104Sdes */
50238104Sdesstruct ldns_struct_buffer
51238104Sdes{
52238104Sdes	/** The current position used for reading/writing */
53238104Sdes	size_t   _position;
54238104Sdes
55238104Sdes	/** The read/write limit */
56238104Sdes	size_t   _limit;
57238104Sdes
58238104Sdes	/** The amount of data the buffer can contain */
59238104Sdes	size_t   _capacity;
60238104Sdes
61238104Sdes	/** The data contained in the buffer */
62238104Sdes	uint8_t *_data;
63238104Sdes
64238104Sdes	/** If the buffer is fixed it cannot be resized */
65238104Sdes	unsigned _fixed : 1;
66238104Sdes
67238104Sdes	/** The current state of the buffer. If writing to the buffer fails
68238104Sdes	 * for any reason, this value is changed. This way, you can perform
69238104Sdes	 * multiple writes in sequence and check for success afterwards. */
70238104Sdes	ldns_status _status;
71238104Sdes};
72238104Sdestypedef struct ldns_struct_buffer ldns_buffer;
73238104Sdes
74238104Sdes
75238104Sdes#ifdef NDEBUG
76238104SdesINLINE void
77238104Sdesldns_buffer_invariant(ldns_buffer *ATTR_UNUSED(buffer))
78238104Sdes{
79238104Sdes}
80238104Sdes#else
81238104SdesINLINE void
82238104Sdesldns_buffer_invariant(ldns_buffer *buffer)
83238104Sdes{
84238104Sdes	assert(buffer != NULL);
85238104Sdes	assert(buffer->_position <= buffer->_limit);
86238104Sdes	assert(buffer->_limit <= buffer->_capacity);
87238104Sdes	assert(buffer->_data != NULL);
88238104Sdes}
89238104Sdes#endif
90238104Sdes
91238104Sdes/**
92238104Sdes * creates a new buffer with the specified capacity.
93238104Sdes *
94238104Sdes * \param[in] capacity the size (in bytes) to allocate for the buffer
95238104Sdes * \return the created buffer
96238104Sdes */
97238104Sdesldns_buffer *ldns_buffer_new(size_t capacity);
98238104Sdes
99238104Sdes/**
100238104Sdes * creates a buffer with the specified data.  The data IS copied
101238104Sdes * and MEMORY allocations are done.  The buffer is not fixed and can
102238104Sdes * be resized using buffer_reserve().
103238104Sdes *
104238104Sdes * \param[in] buffer pointer to the buffer to put the data in
105238104Sdes * \param[in] data the data to encapsulate in the buffer
106238104Sdes * \param[in] size the size of the data
107238104Sdes */
108238104Sdesvoid ldns_buffer_new_frm_data(ldns_buffer *buffer, void *data, size_t size);
109238104Sdes
110238104Sdes/**
111238104Sdes * clears the buffer and make it ready for writing.  The buffer's limit
112238104Sdes * is set to the capacity and the position is set to 0.
113238104Sdes * \param[in] buffer the buffer to clear
114238104Sdes */
115238104SdesINLINE void ldns_buffer_clear(ldns_buffer *buffer)
116238104Sdes{
117238104Sdes	ldns_buffer_invariant(buffer);
118238104Sdes
119238104Sdes	/* reset status here? */
120238104Sdes
121238104Sdes	buffer->_position = 0;
122238104Sdes	buffer->_limit = buffer->_capacity;
123238104Sdes}
124238104Sdes
125238104Sdes/**
126238104Sdes * makes the buffer ready for reading the data that has been written to
127238104Sdes * the buffer.  The buffer's limit is set to the current position and
128238104Sdes * the position is set to 0.
129238104Sdes *
130238104Sdes * \param[in] buffer the buffer to flip
131238104Sdes * \return void
132238104Sdes */
133238104SdesINLINE void ldns_buffer_flip(ldns_buffer *buffer)
134238104Sdes{
135238104Sdes	ldns_buffer_invariant(buffer);
136238104Sdes
137238104Sdes	buffer->_limit = buffer->_position;
138238104Sdes	buffer->_position = 0;
139238104Sdes}
140238104Sdes
141238104Sdes/**
142238104Sdes * make the buffer ready for re-reading the data.  The buffer's
143238104Sdes * position is reset to 0.
144238104Sdes * \param[in] buffer the buffer to rewind
145238104Sdes */
146238104SdesINLINE void ldns_buffer_rewind(ldns_buffer *buffer)
147238104Sdes{
148238104Sdes	ldns_buffer_invariant(buffer);
149238104Sdes
150238104Sdes	buffer->_position = 0;
151238104Sdes}
152238104Sdes
153238104Sdes/**
154238104Sdes * returns the current position in the buffer (as a number of bytes)
155238104Sdes * \param[in] buffer the buffer
156238104Sdes * \return the current position
157238104Sdes */
158238104SdesINLINE size_t
159238104Sdesldns_buffer_position(ldns_buffer *buffer)
160238104Sdes{
161238104Sdes	return buffer->_position;
162238104Sdes}
163238104Sdes
164238104Sdes/**
165238104Sdes * sets the buffer's position to MARK.  The position must be less than
166238104Sdes * or equal to the buffer's limit.
167238104Sdes * \param[in] buffer the buffer
168238104Sdes * \param[in] mark the mark to use
169238104Sdes */
170238104SdesINLINE void
171238104Sdesldns_buffer_set_position(ldns_buffer *buffer, size_t mark)
172238104Sdes{
173238104Sdes	assert(mark <= buffer->_limit);
174238104Sdes	buffer->_position = mark;
175238104Sdes}
176238104Sdes
177238104Sdes/**
178238104Sdes * changes the buffer's position by COUNT bytes.  The position must not
179238104Sdes * be moved behind the buffer's limit or before the beginning of the
180238104Sdes * buffer.
181238104Sdes * \param[in] buffer the buffer
182238104Sdes * \param[in] count the count to use
183238104Sdes */
184238104SdesINLINE void
185238104Sdesldns_buffer_skip(ldns_buffer *buffer, ssize_t count)
186238104Sdes{
187238104Sdes	assert(buffer->_position + count <= buffer->_limit);
188238104Sdes	buffer->_position += count;
189238104Sdes}
190238104Sdes
191238104Sdes/**
192238104Sdes * returns the maximum size of the buffer
193238104Sdes * \param[in] buffer
194238104Sdes * \return the size
195238104Sdes */
196238104SdesINLINE size_t
197238104Sdesldns_buffer_limit(ldns_buffer *buffer)
198238104Sdes{
199238104Sdes	return buffer->_limit;
200238104Sdes}
201238104Sdes
202238104Sdes/**
203238104Sdes * changes the buffer's limit.  If the buffer's position is greater
204238104Sdes * than the new limit the position is set to the limit.
205238104Sdes * \param[in] buffer the buffer
206238104Sdes * \param[in] limit the new limit
207238104Sdes */
208238104SdesINLINE void
209238104Sdesldns_buffer_set_limit(ldns_buffer *buffer, size_t limit)
210238104Sdes{
211238104Sdes	assert(limit <= buffer->_capacity);
212238104Sdes	buffer->_limit = limit;
213238104Sdes	if (buffer->_position > buffer->_limit)
214238104Sdes		buffer->_position = buffer->_limit;
215238104Sdes}
216238104Sdes
217238104Sdes/**
218238104Sdes * returns the number of bytes the buffer can hold.
219238104Sdes * \param[in] buffer the buffer
220238104Sdes * \return the number of bytes
221238104Sdes */
222238104SdesINLINE size_t
223238104Sdesldns_buffer_capacity(ldns_buffer *buffer)
224238104Sdes{
225238104Sdes	return buffer->_capacity;
226238104Sdes}
227238104Sdes
228238104Sdes/**
229238104Sdes * changes the buffer's capacity.  The data is reallocated so any
230238104Sdes * pointers to the data may become invalid.  The buffer's limit is set
231238104Sdes * to the buffer's new capacity.
232238104Sdes * \param[in] buffer the buffer
233238104Sdes * \param[in] capacity the capacity to use
234238104Sdes * \return whether this failed or succeeded
235238104Sdes */
236238104Sdesbool ldns_buffer_set_capacity(ldns_buffer *buffer, size_t capacity);
237238104Sdes
238238104Sdes/**
239238104Sdes * ensures BUFFER can contain at least AMOUNT more bytes.  The buffer's
240238104Sdes * capacity is increased if necessary using buffer_set_capacity().
241238104Sdes *
242238104Sdes * The buffer's limit is always set to the (possibly increased)
243238104Sdes * capacity.
244238104Sdes * \param[in] buffer the buffer
245238104Sdes * \param[in] amount amount to use
246238104Sdes * \return whether this failed or succeeded
247238104Sdes */
248238104Sdesbool ldns_buffer_reserve(ldns_buffer *buffer, size_t amount);
249238104Sdes
250238104Sdes/**
251238104Sdes * returns a pointer to the data at the indicated position.
252238104Sdes * \param[in] buffer the buffer
253238104Sdes * \param[in] at position
254238104Sdes * \return the pointer to the data
255238104Sdes */
256238104SdesINLINE uint8_t *
257238104Sdesldns_buffer_at(const ldns_buffer *buffer, size_t at)
258238104Sdes{
259238104Sdes	assert(at <= buffer->_limit);
260238104Sdes	return buffer->_data + at;
261238104Sdes}
262238104Sdes
263238104Sdes/**
264238104Sdes * returns a pointer to the beginning of the buffer (the data at
265238104Sdes * position 0).
266238104Sdes * \param[in] buffer the buffer
267238104Sdes * \return the pointer
268238104Sdes */
269238104SdesINLINE uint8_t *
270238104Sdesldns_buffer_begin(const ldns_buffer *buffer)
271238104Sdes{
272238104Sdes	return ldns_buffer_at(buffer, 0);
273238104Sdes}
274238104Sdes
275238104Sdes/**
276238104Sdes * returns a pointer to the end of the buffer (the data at the buffer's
277238104Sdes * limit).
278238104Sdes * \param[in] buffer the buffer
279238104Sdes * \return the pointer
280238104Sdes */
281238104SdesINLINE uint8_t *
282238104Sdesldns_buffer_end(ldns_buffer *buffer)
283238104Sdes{
284238104Sdes	return ldns_buffer_at(buffer, buffer->_limit);
285238104Sdes}
286238104Sdes
287238104Sdes/**
288238104Sdes * returns a pointer to the data at the buffer's current position.
289238104Sdes * \param[in] buffer the buffer
290238104Sdes * \return the pointer
291238104Sdes */
292238104SdesINLINE uint8_t *
293238104Sdesldns_buffer_current(ldns_buffer *buffer)
294238104Sdes{
295238104Sdes	return ldns_buffer_at(buffer, buffer->_position);
296238104Sdes}
297238104Sdes
298238104Sdes/**
299238104Sdes * returns the number of bytes remaining between the indicated position and
300238104Sdes * the limit.
301238104Sdes * \param[in] buffer the buffer
302238104Sdes * \param[in] at indicated position
303238104Sdes * \return number of bytes
304238104Sdes */
305238104SdesINLINE size_t
306238104Sdesldns_buffer_remaining_at(ldns_buffer *buffer, size_t at)
307238104Sdes{
308238104Sdes	ldns_buffer_invariant(buffer);
309238104Sdes	assert(at <= buffer->_limit);
310238104Sdes	return buffer->_limit - at;
311238104Sdes}
312238104Sdes
313238104Sdes/**
314238104Sdes * returns the number of bytes remaining between the buffer's position and
315238104Sdes * limit.
316238104Sdes * \param[in] buffer the buffer
317238104Sdes * \return the number of bytes
318238104Sdes */
319238104SdesINLINE size_t
320238104Sdesldns_buffer_remaining(ldns_buffer *buffer)
321238104Sdes{
322238104Sdes	return ldns_buffer_remaining_at(buffer, buffer->_position);
323238104Sdes}
324238104Sdes
325238104Sdes/**
326238104Sdes * checks if the buffer has at least COUNT more bytes available.
327238104Sdes * Before reading or writing the caller needs to ensure enough space
328238104Sdes * is available!
329238104Sdes * \param[in] buffer the buffer
330238104Sdes * \param[in] at indicated position
331238104Sdes * \param[in] count how much is available
332238104Sdes * \return true or false (as int?)
333238104Sdes */
334238104SdesINLINE int
335238104Sdesldns_buffer_available_at(ldns_buffer *buffer, size_t at, size_t count)
336238104Sdes{
337238104Sdes	return count <= ldns_buffer_remaining_at(buffer, at);
338238104Sdes}
339238104Sdes
340238104Sdes/**
341238104Sdes * checks if the buffer has count bytes available at the current position
342238104Sdes * \param[in] buffer the buffer
343238104Sdes * \param[in] count how much is available
344238104Sdes * \return true or false (as int?)
345238104Sdes */
346238104SdesINLINE int
347238104Sdesldns_buffer_available(ldns_buffer *buffer, size_t count)
348238104Sdes{
349238104Sdes	return ldns_buffer_available_at(buffer, buffer->_position, count);
350238104Sdes}
351238104Sdes
352238104Sdes/**
353238104Sdes * writes the given data to the buffer at the specified position
354238104Sdes * \param[in] buffer the buffer
355238104Sdes * \param[in] at the position (in number of bytes) to write the data at
356238104Sdes * \param[in] data pointer to the data to write to the buffer
357238104Sdes * \param[in] count the number of bytes of data to write
358238104Sdes */
359238104SdesINLINE void
360238104Sdesldns_buffer_write_at(ldns_buffer *buffer, size_t at, const void *data, size_t count)
361238104Sdes{
362238104Sdes	assert(ldns_buffer_available_at(buffer, at, count));
363238104Sdes	memcpy(buffer->_data + at, data, count);
364238104Sdes}
365238104Sdes
366238104Sdes/**
367238104Sdes * writes count bytes of data to the current position of the buffer
368238104Sdes * \param[in] buffer the buffer
369238104Sdes * \param[in] data the data to write
370238104Sdes * \param[in] count the lenght of the data to write
371238104Sdes */
372238104SdesINLINE void
373238104Sdesldns_buffer_write(ldns_buffer *buffer, const void *data, size_t count)
374238104Sdes{
375238104Sdes	ldns_buffer_write_at(buffer, buffer->_position, data, count);
376238104Sdes	buffer->_position += count;
377238104Sdes}
378238104Sdes
379238104Sdes/**
380238104Sdes * copies the given (null-delimited) string to the specified position at the buffer
381238104Sdes * \param[in] buffer the buffer
382238104Sdes * \param[in] at the position in the buffer
383238104Sdes * \param[in] str the string to write
384238104Sdes */
385238104SdesINLINE void
386238104Sdesldns_buffer_write_string_at(ldns_buffer *buffer, size_t at, const char *str)
387238104Sdes{
388238104Sdes	ldns_buffer_write_at(buffer, at, str, strlen(str));
389238104Sdes}
390238104Sdes
391238104Sdes/**
392238104Sdes * copies the given (null-delimited) string to the current position at the buffer
393238104Sdes * \param[in] buffer the buffer
394238104Sdes * \param[in] str the string to write
395238104Sdes */
396238104SdesINLINE void
397238104Sdesldns_buffer_write_string(ldns_buffer *buffer, const char *str)
398238104Sdes{
399238104Sdes	ldns_buffer_write(buffer, str, strlen(str));
400238104Sdes}
401238104Sdes
402238104Sdes/**
403238104Sdes * writes the given byte of data at the given position in the buffer
404238104Sdes * \param[in] buffer the buffer
405238104Sdes * \param[in] at the position in the buffer
406238104Sdes * \param[in] data the 8 bits to write
407238104Sdes */
408238104SdesINLINE void
409238104Sdesldns_buffer_write_u8_at(ldns_buffer *buffer, size_t at, uint8_t data)
410238104Sdes{
411238104Sdes	assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
412238104Sdes	buffer->_data[at] = data;
413238104Sdes}
414238104Sdes
415238104Sdes/**
416238104Sdes * writes the given byte of data at the current position in the buffer
417238104Sdes * \param[in] buffer the buffer
418238104Sdes * \param[in] data the 8 bits to write
419238104Sdes */
420238104SdesINLINE void
421238104Sdesldns_buffer_write_u8(ldns_buffer *buffer, uint8_t data)
422238104Sdes{
423238104Sdes	ldns_buffer_write_u8_at(buffer, buffer->_position, data);
424238104Sdes	buffer->_position += sizeof(data);
425238104Sdes}
426238104Sdes
427238104Sdes/**
428238104Sdes * writes the given 2 byte integer at the given position in the buffer
429238104Sdes * \param[in] buffer the buffer
430238104Sdes * \param[in] at the position in the buffer
431238104Sdes * \param[in] data the 16 bits to write
432238104Sdes */
433238104SdesINLINE void
434238104Sdesldns_buffer_write_u16_at(ldns_buffer *buffer, size_t at, uint16_t data)
435238104Sdes{
436238104Sdes	assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
437238104Sdes	ldns_write_uint16(buffer->_data + at, data);
438238104Sdes}
439238104Sdes
440238104Sdes/**
441238104Sdes * writes the given 2 byte integer at the current position in the buffer
442238104Sdes * \param[in] buffer the buffer
443238104Sdes * \param[in] data the 16 bits to write
444238104Sdes */
445238104SdesINLINE void
446238104Sdesldns_buffer_write_u16(ldns_buffer *buffer, uint16_t data)
447238104Sdes{
448238104Sdes	ldns_buffer_write_u16_at(buffer, buffer->_position, data);
449238104Sdes	buffer->_position += sizeof(data);
450238104Sdes}
451238104Sdes
452238104Sdes/**
453238104Sdes * writes the given 4 byte integer at the given position in the buffer
454238104Sdes * \param[in] buffer the buffer
455238104Sdes * \param[in] at the position in the buffer
456238104Sdes * \param[in] data the 32 bits to write
457238104Sdes */
458238104SdesINLINE void
459238104Sdesldns_buffer_write_u32_at(ldns_buffer *buffer, size_t at, uint32_t data)
460238104Sdes{
461238104Sdes	assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
462238104Sdes	ldns_write_uint32(buffer->_data + at, data);
463238104Sdes}
464238104Sdes
465238104Sdes/**
466238104Sdes * writes the given 4 byte integer at the current position in the buffer
467238104Sdes * \param[in] buffer the buffer
468238104Sdes * \param[in] data the 32 bits to write
469238104Sdes */
470238104SdesINLINE void
471238104Sdesldns_buffer_write_u32(ldns_buffer *buffer, uint32_t data)
472238104Sdes{
473238104Sdes	ldns_buffer_write_u32_at(buffer, buffer->_position, data);
474238104Sdes	buffer->_position += sizeof(data);
475238104Sdes}
476238104Sdes
477238104Sdes/**
478238104Sdes * copies count bytes of data at the given position to the given data-array
479238104Sdes * \param[in] buffer the buffer
480238104Sdes * \param[in] at the position in the buffer to start
481238104Sdes * \param[out] data buffer to copy to
482238104Sdes * \param[in] count the length of the data to copy
483238104Sdes */
484238104SdesINLINE void
485238104Sdesldns_buffer_read_at(ldns_buffer *buffer, size_t at, void *data, size_t count)
486238104Sdes{
487238104Sdes	assert(ldns_buffer_available_at(buffer, at, count));
488238104Sdes	memcpy(data, buffer->_data + at, count);
489238104Sdes}
490238104Sdes
491238104Sdes/**
492238104Sdes * copies count bytes of data at the current position to the given data-array
493238104Sdes * \param[in] buffer the buffer
494238104Sdes * \param[out] data buffer to copy to
495238104Sdes * \param[in] count the length of the data to copy
496238104Sdes */
497238104SdesINLINE void
498238104Sdesldns_buffer_read(ldns_buffer *buffer, void *data, size_t count)
499238104Sdes{
500238104Sdes	ldns_buffer_read_at(buffer, buffer->_position, data, count);
501238104Sdes	buffer->_position += count;
502238104Sdes}
503238104Sdes
504238104Sdes/**
505238104Sdes * returns the byte value at the given position in the buffer
506238104Sdes * \param[in] buffer the buffer
507238104Sdes * \param[in] at the position in the buffer
508238104Sdes * \return 1 byte integer
509238104Sdes */
510238104SdesINLINE uint8_t
511238104Sdesldns_buffer_read_u8_at(ldns_buffer *buffer, size_t at)
512238104Sdes{
513238104Sdes	assert(ldns_buffer_available_at(buffer, at, sizeof(uint8_t)));
514238104Sdes	return buffer->_data[at];
515238104Sdes}
516238104Sdes
517238104Sdes/**
518238104Sdes * returns the byte value at the current position in the buffer
519238104Sdes * \param[in] buffer the buffer
520238104Sdes * \return 1 byte integer
521238104Sdes */
522238104SdesINLINE uint8_t
523238104Sdesldns_buffer_read_u8(ldns_buffer *buffer)
524238104Sdes{
525238104Sdes	uint8_t result = ldns_buffer_read_u8_at(buffer, buffer->_position);
526238104Sdes	buffer->_position += sizeof(uint8_t);
527238104Sdes	return result;
528238104Sdes}
529238104Sdes
530238104Sdes/**
531238104Sdes * returns the 2-byte integer value at the given position in the buffer
532238104Sdes * \param[in] buffer the buffer
533238104Sdes * \param[in] at position in the buffer
534238104Sdes * \return 2 byte integer
535238104Sdes */
536238104SdesINLINE uint16_t
537238104Sdesldns_buffer_read_u16_at(ldns_buffer *buffer, size_t at)
538238104Sdes{
539238104Sdes	assert(ldns_buffer_available_at(buffer, at, sizeof(uint16_t)));
540238104Sdes	return ldns_read_uint16(buffer->_data + at);
541238104Sdes}
542238104Sdes
543238104Sdes/**
544238104Sdes * returns the 2-byte integer value at the current position in the buffer
545238104Sdes * \param[in] buffer the buffer
546238104Sdes * \return 2 byte integer
547238104Sdes */
548238104SdesINLINE uint16_t
549238104Sdesldns_buffer_read_u16(ldns_buffer *buffer)
550238104Sdes{
551238104Sdes	uint16_t result = ldns_buffer_read_u16_at(buffer, buffer->_position);
552238104Sdes	buffer->_position += sizeof(uint16_t);
553238104Sdes	return result;
554238104Sdes}
555238104Sdes
556238104Sdes/**
557238104Sdes * returns the 4-byte integer value at the given position in the buffer
558238104Sdes * \param[in] buffer the buffer
559238104Sdes * \param[in] at position in the buffer
560238104Sdes * \return 4 byte integer
561238104Sdes */
562238104SdesINLINE uint32_t
563238104Sdesldns_buffer_read_u32_at(ldns_buffer *buffer, size_t at)
564238104Sdes{
565238104Sdes	assert(ldns_buffer_available_at(buffer, at, sizeof(uint32_t)));
566238104Sdes	return ldns_read_uint32(buffer->_data + at);
567238104Sdes}
568238104Sdes
569238104Sdes/**
570238104Sdes * returns the 4-byte integer value at the current position in the buffer
571238104Sdes * \param[in] buffer the buffer
572238104Sdes * \return 4 byte integer
573238104Sdes */
574238104SdesINLINE uint32_t
575238104Sdesldns_buffer_read_u32(ldns_buffer *buffer)
576238104Sdes{
577238104Sdes	uint32_t result = ldns_buffer_read_u32_at(buffer, buffer->_position);
578238104Sdes	buffer->_position += sizeof(uint32_t);
579238104Sdes	return result;
580238104Sdes}
581238104Sdes
582238104Sdes/**
583238104Sdes * returns the status of the buffer
584238104Sdes * \param[in] buffer
585238104Sdes * \return the status
586238104Sdes */
587238104SdesINLINE ldns_status
588238104Sdesldns_buffer_status(ldns_buffer *buffer)
589238104Sdes{
590238104Sdes	return buffer->_status;
591238104Sdes}
592238104Sdes
593238104Sdes/**
594238104Sdes * returns true if the status of the buffer is LDNS_STATUS_OK, false otherwise
595238104Sdes * \param[in] buffer the buffer
596238104Sdes * \return true or false
597238104Sdes */
598238104SdesINLINE bool
599238104Sdesldns_buffer_status_ok(ldns_buffer *buffer)
600238104Sdes{
601238104Sdes	if (buffer) {
602238104Sdes		return ldns_buffer_status(buffer) == LDNS_STATUS_OK;
603238104Sdes	} else {
604238104Sdes		return false;
605238104Sdes	}
606238104Sdes}
607238104Sdes
608238104Sdes/**
609238104Sdes * prints to the buffer, increasing the capacity if required using
610238104Sdes * buffer_reserve(). The buffer's position is set to the terminating '\\0'
611238104Sdes * Returns the number of characters written (not including the
612238104Sdes * terminating '\\0') or -1 on failure.
613238104Sdes */
614238104Sdesint ldns_buffer_printf(ldns_buffer *buffer, const char *format, ...);
615238104Sdes/*	ATTR_FORMAT(printf, 2, 3);*/
616238104Sdes
617238104Sdes/**
618238104Sdes * frees the buffer.
619238104Sdes * \param[in] *buffer the buffer to be freed
620238104Sdes * \return void
621238104Sdes */
622238104Sdesvoid ldns_buffer_free(ldns_buffer *buffer);
623238104Sdes
624238104Sdes/**
625238104Sdes * Makes the buffer fixed and returns a pointer to the data.  The
626238104Sdes * caller is responsible for free'ing the result.
627238104Sdes * \param[in] *buffer the buffer to be exported
628238104Sdes * \return void
629238104Sdes */
630238104Sdesvoid *ldns_buffer_export(ldns_buffer *buffer);
631238104Sdes
632238104Sdes/**
633246854Sdes * Copy contents of the from buffer to the result buffer and then flips
634246854Sdes * the result buffer. Data will be silently truncated if the result buffer is
635246854Sdes * too small.
636238104Sdes * \param[out] *result resulting buffer which is copied to.
637238104Sdes * \param[in] *from what to copy to result.
638238104Sdes */
639238104Sdesvoid ldns_buffer_copy(ldns_buffer* result, ldns_buffer* from);
640238104Sdes
641238104Sdes#ifdef __cplusplus
642238104Sdes}
643238104Sdes#endif
644238104Sdes
645238104Sdes#endif /* LDNS_BUFFER_H */
646