xref: /freebsd/contrib/ldns/ldns/buffer.h (revision 5afab0e5)
17b5038d7SDag-Erling Smørgrav /*
27b5038d7SDag-Erling Smørgrav  * buffer.h -- generic memory buffer.
37b5038d7SDag-Erling Smørgrav  *
47b5038d7SDag-Erling Smørgrav  * Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
57b5038d7SDag-Erling Smørgrav  *
67b5038d7SDag-Erling Smørgrav  * See LICENSE for the license.
77b5038d7SDag-Erling Smørgrav  *
87b5038d7SDag-Erling Smørgrav  *
97b5038d7SDag-Erling Smørgrav  * The buffer module implements a generic buffer.  The API is based on
107b5038d7SDag-Erling Smørgrav  * the java.nio.Buffer interface.
117b5038d7SDag-Erling Smørgrav  */
127b5038d7SDag-Erling Smørgrav 
137b5038d7SDag-Erling Smørgrav #ifndef LDNS_BUFFER_H
147b5038d7SDag-Erling Smørgrav #define LDNS_BUFFER_H
157b5038d7SDag-Erling Smørgrav 
167b5038d7SDag-Erling Smørgrav #include <assert.h>
177b5038d7SDag-Erling Smørgrav #include <stdarg.h>
187b5038d7SDag-Erling Smørgrav #include <string.h>
197b5038d7SDag-Erling Smørgrav 
207b5038d7SDag-Erling Smørgrav #include <ldns/error.h>
217b5038d7SDag-Erling Smørgrav #include <ldns/common.h>
227b5038d7SDag-Erling Smørgrav 
237b5038d7SDag-Erling Smørgrav #include "ldns/util.h"
247b5038d7SDag-Erling Smørgrav 
257b5038d7SDag-Erling Smørgrav #ifdef __cplusplus
267b5038d7SDag-Erling Smørgrav extern "C" {
277b5038d7SDag-Erling Smørgrav #endif
287b5038d7SDag-Erling Smørgrav 
297b5038d7SDag-Erling Smørgrav /**
307b5038d7SDag-Erling Smørgrav  * number of initial bytes in buffer of
317b5038d7SDag-Erling Smørgrav  * which we cannot tell the size before hand
327b5038d7SDag-Erling Smørgrav  */
337b5038d7SDag-Erling Smørgrav #define LDNS_MIN_BUFLEN	512
347b5038d7SDag-Erling Smørgrav 
357b5038d7SDag-Erling Smørgrav /**
367b5038d7SDag-Erling Smørgrav  * \file buffer.h
377b5038d7SDag-Erling Smørgrav  *
387b5038d7SDag-Erling Smørgrav  * This file contains the definition of ldns_buffer, and functions to manipulate those.
397b5038d7SDag-Erling Smørgrav  */
407b5038d7SDag-Erling Smørgrav 
417b5038d7SDag-Erling Smørgrav /**
427b5038d7SDag-Erling Smørgrav  * implementation of buffers to ease operations
437b5038d7SDag-Erling Smørgrav  *
447b5038d7SDag-Erling Smørgrav  * ldns_buffers can contain arbitrary information, per octet. You can write
457b5038d7SDag-Erling Smørgrav  * to the current end of a buffer, read from the current position, and
467b5038d7SDag-Erling Smørgrav  * access any data within it.
477b5038d7SDag-Erling Smørgrav  *
487b5038d7SDag-Erling Smørgrav  * Example use of buffers is in the source code of \ref host2str.c
497b5038d7SDag-Erling Smørgrav  */
507b5038d7SDag-Erling Smørgrav struct ldns_struct_buffer
517b5038d7SDag-Erling Smørgrav {
527b5038d7SDag-Erling Smørgrav 	/** The current position used for reading/writing */
537b5038d7SDag-Erling Smørgrav 	size_t   _position;
547b5038d7SDag-Erling Smørgrav 
557b5038d7SDag-Erling Smørgrav 	/** The read/write limit */
567b5038d7SDag-Erling Smørgrav 	size_t   _limit;
577b5038d7SDag-Erling Smørgrav 
587b5038d7SDag-Erling Smørgrav 	/** The amount of data the buffer can contain */
597b5038d7SDag-Erling Smørgrav 	size_t   _capacity;
607b5038d7SDag-Erling Smørgrav 
617b5038d7SDag-Erling Smørgrav 	/** The data contained in the buffer */
627b5038d7SDag-Erling Smørgrav 	uint8_t *_data;
637b5038d7SDag-Erling Smørgrav 
647b5038d7SDag-Erling Smørgrav 	/** If the buffer is fixed it cannot be resized */
657b5038d7SDag-Erling Smørgrav 	unsigned _fixed : 1;
667b5038d7SDag-Erling Smørgrav 
677b5038d7SDag-Erling Smørgrav 	/** The current state of the buffer. If writing to the buffer fails
687b5038d7SDag-Erling Smørgrav 	 * for any reason, this value is changed. This way, you can perform
697b5038d7SDag-Erling Smørgrav 	 * multiple writes in sequence and check for success afterwards. */
707b5038d7SDag-Erling Smørgrav 	ldns_status _status;
717b5038d7SDag-Erling Smørgrav };
727b5038d7SDag-Erling Smørgrav typedef struct ldns_struct_buffer ldns_buffer;
737b5038d7SDag-Erling Smørgrav 
747b5038d7SDag-Erling Smørgrav 
757b5038d7SDag-Erling Smørgrav #ifdef NDEBUG
767b5038d7SDag-Erling Smørgrav INLINE void
ldns_buffer_invariant(const ldns_buffer * ATTR_UNUSED (buffer))77986ba33cSDag-Erling Smørgrav ldns_buffer_invariant(const ldns_buffer *ATTR_UNUSED(buffer))
787b5038d7SDag-Erling Smørgrav {
797b5038d7SDag-Erling Smørgrav }
807b5038d7SDag-Erling Smørgrav #else
817b5038d7SDag-Erling Smørgrav INLINE void
ldns_buffer_invariant(const ldns_buffer * buffer)82986ba33cSDag-Erling Smørgrav ldns_buffer_invariant(const ldns_buffer *buffer)
837b5038d7SDag-Erling Smørgrav {
847b5038d7SDag-Erling Smørgrav 	assert(buffer != NULL);
857b5038d7SDag-Erling Smørgrav 	assert(buffer->_position <= buffer->_limit);
867b5038d7SDag-Erling Smørgrav 	assert(buffer->_limit <= buffer->_capacity);
877b5038d7SDag-Erling Smørgrav 	assert(buffer->_data != NULL);
887b5038d7SDag-Erling Smørgrav }
897b5038d7SDag-Erling Smørgrav #endif
907b5038d7SDag-Erling Smørgrav 
917b5038d7SDag-Erling Smørgrav /**
927b5038d7SDag-Erling Smørgrav  * creates a new buffer with the specified capacity.
937b5038d7SDag-Erling Smørgrav  *
947b5038d7SDag-Erling Smørgrav  * \param[in] capacity the size (in bytes) to allocate for the buffer
957b5038d7SDag-Erling Smørgrav  * \return the created buffer
967b5038d7SDag-Erling Smørgrav  */
977b5038d7SDag-Erling Smørgrav ldns_buffer *ldns_buffer_new(size_t capacity);
987b5038d7SDag-Erling Smørgrav 
997b5038d7SDag-Erling Smørgrav /**
1007b5038d7SDag-Erling Smørgrav  * creates a buffer with the specified data.  The data IS copied
1017b5038d7SDag-Erling Smørgrav  * and MEMORY allocations are done.  The buffer is not fixed and can
1027b5038d7SDag-Erling Smørgrav  * be resized using buffer_reserve().
1037b5038d7SDag-Erling Smørgrav  *
1047b5038d7SDag-Erling Smørgrav  * \param[in] buffer pointer to the buffer to put the data in
1057b5038d7SDag-Erling Smørgrav  * \param[in] data the data to encapsulate in the buffer
1067b5038d7SDag-Erling Smørgrav  * \param[in] size the size of the data
1077b5038d7SDag-Erling Smørgrav  */
108986ba33cSDag-Erling Smørgrav void ldns_buffer_new_frm_data(ldns_buffer *buffer, const void *data, size_t size);
1097b5038d7SDag-Erling Smørgrav 
1107b5038d7SDag-Erling Smørgrav /**
1117b5038d7SDag-Erling Smørgrav  * clears the buffer and make it ready for writing.  The buffer's limit
1127b5038d7SDag-Erling Smørgrav  * is set to the capacity and the position is set to 0.
1137b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer to clear
1147b5038d7SDag-Erling Smørgrav  */
ldns_buffer_clear(ldns_buffer * buffer)1157b5038d7SDag-Erling Smørgrav INLINE void ldns_buffer_clear(ldns_buffer *buffer)
1167b5038d7SDag-Erling Smørgrav {
1177b5038d7SDag-Erling Smørgrav 	ldns_buffer_invariant(buffer);
1187b5038d7SDag-Erling Smørgrav 
1197b5038d7SDag-Erling Smørgrav 	/* reset status here? */
1207b5038d7SDag-Erling Smørgrav 
1217b5038d7SDag-Erling Smørgrav 	buffer->_position = 0;
1227b5038d7SDag-Erling Smørgrav 	buffer->_limit = buffer->_capacity;
1237b5038d7SDag-Erling Smørgrav }
1247b5038d7SDag-Erling Smørgrav 
1257b5038d7SDag-Erling Smørgrav /**
1267b5038d7SDag-Erling Smørgrav  * makes the buffer ready for reading the data that has been written to
1277b5038d7SDag-Erling Smørgrav  * the buffer.  The buffer's limit is set to the current position and
1287b5038d7SDag-Erling Smørgrav  * the position is set to 0.
1297b5038d7SDag-Erling Smørgrav  *
1307b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer to flip
1317b5038d7SDag-Erling Smørgrav  * \return void
1327b5038d7SDag-Erling Smørgrav  */
ldns_buffer_flip(ldns_buffer * buffer)1337b5038d7SDag-Erling Smørgrav INLINE void ldns_buffer_flip(ldns_buffer *buffer)
1347b5038d7SDag-Erling Smørgrav {
1357b5038d7SDag-Erling Smørgrav 	ldns_buffer_invariant(buffer);
1367b5038d7SDag-Erling Smørgrav 
1377b5038d7SDag-Erling Smørgrav 	buffer->_limit = buffer->_position;
1387b5038d7SDag-Erling Smørgrav 	buffer->_position = 0;
1397b5038d7SDag-Erling Smørgrav }
1407b5038d7SDag-Erling Smørgrav 
1417b5038d7SDag-Erling Smørgrav /**
1427b5038d7SDag-Erling Smørgrav  * make the buffer ready for re-reading the data.  The buffer's
1437b5038d7SDag-Erling Smørgrav  * position is reset to 0.
1447b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer to rewind
1457b5038d7SDag-Erling Smørgrav  */
ldns_buffer_rewind(ldns_buffer * buffer)1467b5038d7SDag-Erling Smørgrav INLINE void ldns_buffer_rewind(ldns_buffer *buffer)
1477b5038d7SDag-Erling Smørgrav {
1487b5038d7SDag-Erling Smørgrav 	ldns_buffer_invariant(buffer);
1497b5038d7SDag-Erling Smørgrav 
1507b5038d7SDag-Erling Smørgrav 	buffer->_position = 0;
1517b5038d7SDag-Erling Smørgrav }
1527b5038d7SDag-Erling Smørgrav 
1537b5038d7SDag-Erling Smørgrav /**
1547b5038d7SDag-Erling Smørgrav  * returns the current position in the buffer (as a number of bytes)
1557b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
1567b5038d7SDag-Erling Smørgrav  * \return the current position
1577b5038d7SDag-Erling Smørgrav  */
1587b5038d7SDag-Erling Smørgrav INLINE size_t
ldns_buffer_position(const ldns_buffer * buffer)159986ba33cSDag-Erling Smørgrav ldns_buffer_position(const ldns_buffer *buffer)
1607b5038d7SDag-Erling Smørgrav {
1617b5038d7SDag-Erling Smørgrav 	return buffer->_position;
1627b5038d7SDag-Erling Smørgrav }
1637b5038d7SDag-Erling Smørgrav 
1647b5038d7SDag-Erling Smørgrav /**
1657b5038d7SDag-Erling Smørgrav  * sets the buffer's position to MARK.  The position must be less than
1667b5038d7SDag-Erling Smørgrav  * or equal to the buffer's limit.
1677b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
1687b5038d7SDag-Erling Smørgrav  * \param[in] mark the mark to use
1697b5038d7SDag-Erling Smørgrav  */
1707b5038d7SDag-Erling Smørgrav INLINE void
ldns_buffer_set_position(ldns_buffer * buffer,size_t mark)1717b5038d7SDag-Erling Smørgrav ldns_buffer_set_position(ldns_buffer *buffer, size_t mark)
1727b5038d7SDag-Erling Smørgrav {
1737b5038d7SDag-Erling Smørgrav 	assert(mark <= buffer->_limit);
1747b5038d7SDag-Erling Smørgrav 	buffer->_position = mark;
1757b5038d7SDag-Erling Smørgrav }
1767b5038d7SDag-Erling Smørgrav 
1777b5038d7SDag-Erling Smørgrav /**
1787b5038d7SDag-Erling Smørgrav  * changes the buffer's position by COUNT bytes.  The position must not
1797b5038d7SDag-Erling Smørgrav  * be moved behind the buffer's limit or before the beginning of the
1807b5038d7SDag-Erling Smørgrav  * buffer.
1817b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
1827b5038d7SDag-Erling Smørgrav  * \param[in] count the count to use
1837b5038d7SDag-Erling Smørgrav  */
1847b5038d7SDag-Erling Smørgrav INLINE void
ldns_buffer_skip(ldns_buffer * buffer,ssize_t count)1857b5038d7SDag-Erling Smørgrav ldns_buffer_skip(ldns_buffer *buffer, ssize_t count)
1867b5038d7SDag-Erling Smørgrav {
1877b5038d7SDag-Erling Smørgrav 	assert(buffer->_position + count <= buffer->_limit);
1887b5038d7SDag-Erling Smørgrav 	buffer->_position += count;
1897b5038d7SDag-Erling Smørgrav }
1907b5038d7SDag-Erling Smørgrav 
1917b5038d7SDag-Erling Smørgrav /**
1927b5038d7SDag-Erling Smørgrav  * returns the maximum size of the buffer
1937b5038d7SDag-Erling Smørgrav  * \param[in] buffer
1947b5038d7SDag-Erling Smørgrav  * \return the size
1957b5038d7SDag-Erling Smørgrav  */
1967b5038d7SDag-Erling Smørgrav INLINE size_t
ldns_buffer_limit(const ldns_buffer * buffer)197986ba33cSDag-Erling Smørgrav ldns_buffer_limit(const ldns_buffer *buffer)
1987b5038d7SDag-Erling Smørgrav {
1997b5038d7SDag-Erling Smørgrav 	return buffer->_limit;
2007b5038d7SDag-Erling Smørgrav }
2017b5038d7SDag-Erling Smørgrav 
2027b5038d7SDag-Erling Smørgrav /**
2037b5038d7SDag-Erling Smørgrav  * changes the buffer's limit.  If the buffer's position is greater
2047b5038d7SDag-Erling Smørgrav  * than the new limit the position is set to the limit.
2057b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
2067b5038d7SDag-Erling Smørgrav  * \param[in] limit the new limit
2077b5038d7SDag-Erling Smørgrav  */
2087b5038d7SDag-Erling Smørgrav INLINE void
ldns_buffer_set_limit(ldns_buffer * buffer,size_t limit)2097b5038d7SDag-Erling Smørgrav ldns_buffer_set_limit(ldns_buffer *buffer, size_t limit)
2107b5038d7SDag-Erling Smørgrav {
2117b5038d7SDag-Erling Smørgrav 	assert(limit <= buffer->_capacity);
2127b5038d7SDag-Erling Smørgrav 	buffer->_limit = limit;
2137b5038d7SDag-Erling Smørgrav 	if (buffer->_position > buffer->_limit)
2147b5038d7SDag-Erling Smørgrav 		buffer->_position = buffer->_limit;
2157b5038d7SDag-Erling Smørgrav }
2167b5038d7SDag-Erling Smørgrav 
2177b5038d7SDag-Erling Smørgrav /**
2187b5038d7SDag-Erling Smørgrav  * returns the number of bytes the buffer can hold.
2197b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
2207b5038d7SDag-Erling Smørgrav  * \return the number of bytes
2217b5038d7SDag-Erling Smørgrav  */
2227b5038d7SDag-Erling Smørgrav INLINE size_t
ldns_buffer_capacity(const ldns_buffer * buffer)223986ba33cSDag-Erling Smørgrav ldns_buffer_capacity(const ldns_buffer *buffer)
2247b5038d7SDag-Erling Smørgrav {
2257b5038d7SDag-Erling Smørgrav 	return buffer->_capacity;
2267b5038d7SDag-Erling Smørgrav }
2277b5038d7SDag-Erling Smørgrav 
2287b5038d7SDag-Erling Smørgrav /**
2297b5038d7SDag-Erling Smørgrav  * changes the buffer's capacity.  The data is reallocated so any
2307b5038d7SDag-Erling Smørgrav  * pointers to the data may become invalid.  The buffer's limit is set
2317b5038d7SDag-Erling Smørgrav  * to the buffer's new capacity.
2327b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
2337b5038d7SDag-Erling Smørgrav  * \param[in] capacity the capacity to use
2347b5038d7SDag-Erling Smørgrav  * \return whether this failed or succeeded
2357b5038d7SDag-Erling Smørgrav  */
2367b5038d7SDag-Erling Smørgrav bool ldns_buffer_set_capacity(ldns_buffer *buffer, size_t capacity);
2377b5038d7SDag-Erling Smørgrav 
2387b5038d7SDag-Erling Smørgrav /**
2397b5038d7SDag-Erling Smørgrav  * ensures BUFFER can contain at least AMOUNT more bytes.  The buffer's
2407b5038d7SDag-Erling Smørgrav  * capacity is increased if necessary using buffer_set_capacity().
2417b5038d7SDag-Erling Smørgrav  *
2427b5038d7SDag-Erling Smørgrav  * The buffer's limit is always set to the (possibly increased)
2437b5038d7SDag-Erling Smørgrav  * capacity.
2447b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
2457b5038d7SDag-Erling Smørgrav  * \param[in] amount amount to use
2467b5038d7SDag-Erling Smørgrav  * \return whether this failed or succeeded
2477b5038d7SDag-Erling Smørgrav  */
2487b5038d7SDag-Erling Smørgrav bool ldns_buffer_reserve(ldns_buffer *buffer, size_t amount);
2497b5038d7SDag-Erling Smørgrav 
2507b5038d7SDag-Erling Smørgrav /**
2517b5038d7SDag-Erling Smørgrav  * returns a pointer to the data at the indicated position.
2527b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
2537b5038d7SDag-Erling Smørgrav  * \param[in] at position
2547b5038d7SDag-Erling Smørgrav  * \return the pointer to the data
2557b5038d7SDag-Erling Smørgrav  */
2567b5038d7SDag-Erling Smørgrav INLINE uint8_t *
ldns_buffer_at(const ldns_buffer * buffer,size_t at)2577b5038d7SDag-Erling Smørgrav ldns_buffer_at(const ldns_buffer *buffer, size_t at)
2587b5038d7SDag-Erling Smørgrav {
2597b5038d7SDag-Erling Smørgrav 	assert(at <= buffer->_limit);
2607b5038d7SDag-Erling Smørgrav 	return buffer->_data + at;
2617b5038d7SDag-Erling Smørgrav }
2627b5038d7SDag-Erling Smørgrav 
2637b5038d7SDag-Erling Smørgrav /**
2647b5038d7SDag-Erling Smørgrav  * returns a pointer to the beginning of the buffer (the data at
2657b5038d7SDag-Erling Smørgrav  * position 0).
2667b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
2677b5038d7SDag-Erling Smørgrav  * \return the pointer
2687b5038d7SDag-Erling Smørgrav  */
2697b5038d7SDag-Erling Smørgrav INLINE uint8_t *
ldns_buffer_begin(const ldns_buffer * buffer)2707b5038d7SDag-Erling Smørgrav ldns_buffer_begin(const ldns_buffer *buffer)
2717b5038d7SDag-Erling Smørgrav {
2727b5038d7SDag-Erling Smørgrav 	return ldns_buffer_at(buffer, 0);
2737b5038d7SDag-Erling Smørgrav }
2747b5038d7SDag-Erling Smørgrav 
2757b5038d7SDag-Erling Smørgrav /**
2767b5038d7SDag-Erling Smørgrav  * returns a pointer to the end of the buffer (the data at the buffer's
2777b5038d7SDag-Erling Smørgrav  * limit).
2787b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
2797b5038d7SDag-Erling Smørgrav  * \return the pointer
2807b5038d7SDag-Erling Smørgrav  */
2817b5038d7SDag-Erling Smørgrav INLINE uint8_t *
ldns_buffer_end(const ldns_buffer * buffer)282986ba33cSDag-Erling Smørgrav ldns_buffer_end(const ldns_buffer *buffer)
2837b5038d7SDag-Erling Smørgrav {
2847b5038d7SDag-Erling Smørgrav 	return ldns_buffer_at(buffer, buffer->_limit);
2857b5038d7SDag-Erling Smørgrav }
2867b5038d7SDag-Erling Smørgrav 
2877b5038d7SDag-Erling Smørgrav /**
2887b5038d7SDag-Erling Smørgrav  * returns a pointer to the data at the buffer's current position.
2897b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
2907b5038d7SDag-Erling Smørgrav  * \return the pointer
2917b5038d7SDag-Erling Smørgrav  */
2927b5038d7SDag-Erling Smørgrav INLINE uint8_t *
ldns_buffer_current(const ldns_buffer * buffer)293986ba33cSDag-Erling Smørgrav ldns_buffer_current(const ldns_buffer *buffer)
2947b5038d7SDag-Erling Smørgrav {
2957b5038d7SDag-Erling Smørgrav 	return ldns_buffer_at(buffer, buffer->_position);
2967b5038d7SDag-Erling Smørgrav }
2977b5038d7SDag-Erling Smørgrav 
2987b5038d7SDag-Erling Smørgrav /**
2997b5038d7SDag-Erling Smørgrav  * returns the number of bytes remaining between the indicated position and
3007b5038d7SDag-Erling Smørgrav  * the limit.
3017b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
3027b5038d7SDag-Erling Smørgrav  * \param[in] at indicated position
3037b5038d7SDag-Erling Smørgrav  * \return number of bytes
3047b5038d7SDag-Erling Smørgrav  */
3057b5038d7SDag-Erling Smørgrav INLINE size_t
ldns_buffer_remaining_at(const ldns_buffer * buffer,size_t at)306986ba33cSDag-Erling Smørgrav ldns_buffer_remaining_at(const ldns_buffer *buffer, size_t at)
3077b5038d7SDag-Erling Smørgrav {
3087b5038d7SDag-Erling Smørgrav 	ldns_buffer_invariant(buffer);
3097b5038d7SDag-Erling Smørgrav 	assert(at <= buffer->_limit);
3107b5038d7SDag-Erling Smørgrav 	return buffer->_limit - at;
3117b5038d7SDag-Erling Smørgrav }
3127b5038d7SDag-Erling Smørgrav 
3137b5038d7SDag-Erling Smørgrav /**
3147b5038d7SDag-Erling Smørgrav  * returns the number of bytes remaining between the buffer's position and
3157b5038d7SDag-Erling Smørgrav  * limit.
3167b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
3177b5038d7SDag-Erling Smørgrav  * \return the number of bytes
3187b5038d7SDag-Erling Smørgrav  */
3197b5038d7SDag-Erling Smørgrav INLINE size_t
ldns_buffer_remaining(const ldns_buffer * buffer)320986ba33cSDag-Erling Smørgrav ldns_buffer_remaining(const ldns_buffer *buffer)
3217b5038d7SDag-Erling Smørgrav {
3227b5038d7SDag-Erling Smørgrav 	return ldns_buffer_remaining_at(buffer, buffer->_position);
3237b5038d7SDag-Erling Smørgrav }
3247b5038d7SDag-Erling Smørgrav 
3257b5038d7SDag-Erling Smørgrav /**
3267b5038d7SDag-Erling Smørgrav  * checks if the buffer has at least COUNT more bytes available.
3277b5038d7SDag-Erling Smørgrav  * Before reading or writing the caller needs to ensure enough space
3287b5038d7SDag-Erling Smørgrav  * is available!
3297b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
3307b5038d7SDag-Erling Smørgrav  * \param[in] at indicated position
3317b5038d7SDag-Erling Smørgrav  * \param[in] count how much is available
3327b5038d7SDag-Erling Smørgrav  * \return true or false (as int?)
3337b5038d7SDag-Erling Smørgrav  */
3347b5038d7SDag-Erling Smørgrav INLINE int
ldns_buffer_available_at(const ldns_buffer * buffer,size_t at,size_t count)335986ba33cSDag-Erling Smørgrav ldns_buffer_available_at(const ldns_buffer *buffer, size_t at, size_t count)
3367b5038d7SDag-Erling Smørgrav {
3377b5038d7SDag-Erling Smørgrav 	return count <= ldns_buffer_remaining_at(buffer, at);
3387b5038d7SDag-Erling Smørgrav }
3397b5038d7SDag-Erling Smørgrav 
3407b5038d7SDag-Erling Smørgrav /**
3417b5038d7SDag-Erling Smørgrav  * checks if the buffer has count bytes available at the current position
3427b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
3437b5038d7SDag-Erling Smørgrav  * \param[in] count how much is available
3447b5038d7SDag-Erling Smørgrav  * \return true or false (as int?)
3457b5038d7SDag-Erling Smørgrav  */
3467b5038d7SDag-Erling Smørgrav INLINE int
ldns_buffer_available(const ldns_buffer * buffer,size_t count)347986ba33cSDag-Erling Smørgrav ldns_buffer_available(const ldns_buffer *buffer, size_t count)
3487b5038d7SDag-Erling Smørgrav {
3497b5038d7SDag-Erling Smørgrav 	return ldns_buffer_available_at(buffer, buffer->_position, count);
3507b5038d7SDag-Erling Smørgrav }
3517b5038d7SDag-Erling Smørgrav 
3527b5038d7SDag-Erling Smørgrav /**
3537b5038d7SDag-Erling Smørgrav  * writes the given data to the buffer at the specified position
3547b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
3557b5038d7SDag-Erling Smørgrav  * \param[in] at the position (in number of bytes) to write the data at
3567b5038d7SDag-Erling Smørgrav  * \param[in] data pointer to the data to write to the buffer
3577b5038d7SDag-Erling Smørgrav  * \param[in] count the number of bytes of data to write
3587b5038d7SDag-Erling Smørgrav  */
3597b5038d7SDag-Erling Smørgrav INLINE void
ldns_buffer_write_at(ldns_buffer * buffer,size_t at,const void * data,size_t count)3607b5038d7SDag-Erling Smørgrav ldns_buffer_write_at(ldns_buffer *buffer, size_t at, const void *data, size_t count)
3617b5038d7SDag-Erling Smørgrav {
3627b5038d7SDag-Erling Smørgrav 	assert(ldns_buffer_available_at(buffer, at, count));
3637b5038d7SDag-Erling Smørgrav 	memcpy(buffer->_data + at, data, count);
3647b5038d7SDag-Erling Smørgrav }
3657b5038d7SDag-Erling Smørgrav 
3667b5038d7SDag-Erling Smørgrav /**
3677b5038d7SDag-Erling Smørgrav  * writes count bytes of data to the current position of the buffer
3687b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
3697b5038d7SDag-Erling Smørgrav  * \param[in] data the data to write
370986ba33cSDag-Erling Smørgrav  * \param[in] count the length of the data to write
3717b5038d7SDag-Erling Smørgrav  */
3727b5038d7SDag-Erling Smørgrav INLINE void
ldns_buffer_write(ldns_buffer * buffer,const void * data,size_t count)3737b5038d7SDag-Erling Smørgrav ldns_buffer_write(ldns_buffer *buffer, const void *data, size_t count)
3747b5038d7SDag-Erling Smørgrav {
3757b5038d7SDag-Erling Smørgrav 	ldns_buffer_write_at(buffer, buffer->_position, data, count);
3767b5038d7SDag-Erling Smørgrav 	buffer->_position += count;
3777b5038d7SDag-Erling Smørgrav }
3787b5038d7SDag-Erling Smørgrav 
3797b5038d7SDag-Erling Smørgrav /**
3807b5038d7SDag-Erling Smørgrav  * copies the given (null-delimited) string to the specified position at the buffer
3817b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
3827b5038d7SDag-Erling Smørgrav  * \param[in] at the position in the buffer
3837b5038d7SDag-Erling Smørgrav  * \param[in] str the string to write
3847b5038d7SDag-Erling Smørgrav  */
3857b5038d7SDag-Erling Smørgrav INLINE void
ldns_buffer_write_string_at(ldns_buffer * buffer,size_t at,const char * str)3867b5038d7SDag-Erling Smørgrav ldns_buffer_write_string_at(ldns_buffer *buffer, size_t at, const char *str)
3877b5038d7SDag-Erling Smørgrav {
3887b5038d7SDag-Erling Smørgrav 	ldns_buffer_write_at(buffer, at, str, strlen(str));
3897b5038d7SDag-Erling Smørgrav }
3907b5038d7SDag-Erling Smørgrav 
3917b5038d7SDag-Erling Smørgrav /**
3927b5038d7SDag-Erling Smørgrav  * copies the given (null-delimited) string to the current position at the buffer
3937b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
3947b5038d7SDag-Erling Smørgrav  * \param[in] str the string to write
3957b5038d7SDag-Erling Smørgrav  */
3967b5038d7SDag-Erling Smørgrav INLINE void
ldns_buffer_write_string(ldns_buffer * buffer,const char * str)3977b5038d7SDag-Erling Smørgrav ldns_buffer_write_string(ldns_buffer *buffer, const char *str)
3987b5038d7SDag-Erling Smørgrav {
3997b5038d7SDag-Erling Smørgrav 	ldns_buffer_write(buffer, str, strlen(str));
4007b5038d7SDag-Erling Smørgrav }
4017b5038d7SDag-Erling Smørgrav 
4027b5038d7SDag-Erling Smørgrav /**
403*5afab0e5SDag-Erling Smørgrav  * copies the given (null-delimited) string to the current position at the buffer
404*5afab0e5SDag-Erling Smørgrav  * increasing the capacity if necessary
405*5afab0e5SDag-Erling Smørgrav  * \param[in] buffer the buffer
406*5afab0e5SDag-Erling Smørgrav  * \param[in] str the string to write
407*5afab0e5SDag-Erling Smørgrav  */
408*5afab0e5SDag-Erling Smørgrav INLINE void
ldns_buffer_write_chars(ldns_buffer * buffer,const char * str)409*5afab0e5SDag-Erling Smørgrav ldns_buffer_write_chars(ldns_buffer *buffer, const char *str)
410*5afab0e5SDag-Erling Smørgrav {
411*5afab0e5SDag-Erling Smørgrav 	if (!ldns_buffer_reserve(buffer, strlen(str)))
412*5afab0e5SDag-Erling Smørgrav 		buffer->_status = LDNS_STATUS_MEM_ERR;
413*5afab0e5SDag-Erling Smørgrav 	else
414*5afab0e5SDag-Erling Smørgrav 		ldns_buffer_write_string(buffer, str);
415*5afab0e5SDag-Erling Smørgrav }
416*5afab0e5SDag-Erling Smørgrav 
417*5afab0e5SDag-Erling Smørgrav 
418*5afab0e5SDag-Erling Smørgrav /**
4197b5038d7SDag-Erling Smørgrav  * writes the given byte of data at the given position in the buffer
4207b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
4217b5038d7SDag-Erling Smørgrav  * \param[in] at the position in the buffer
4227b5038d7SDag-Erling Smørgrav  * \param[in] data the 8 bits to write
4237b5038d7SDag-Erling Smørgrav  */
4247b5038d7SDag-Erling Smørgrav INLINE void
ldns_buffer_write_u8_at(ldns_buffer * buffer,size_t at,uint8_t data)4257b5038d7SDag-Erling Smørgrav ldns_buffer_write_u8_at(ldns_buffer *buffer, size_t at, uint8_t data)
4267b5038d7SDag-Erling Smørgrav {
4277b5038d7SDag-Erling Smørgrav 	assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
4287b5038d7SDag-Erling Smørgrav 	buffer->_data[at] = data;
4297b5038d7SDag-Erling Smørgrav }
4307b5038d7SDag-Erling Smørgrav 
4317b5038d7SDag-Erling Smørgrav /**
4327b5038d7SDag-Erling Smørgrav  * writes the given byte of data at the current position in the buffer
4337b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
4347b5038d7SDag-Erling Smørgrav  * \param[in] data the 8 bits to write
4357b5038d7SDag-Erling Smørgrav  */
4367b5038d7SDag-Erling Smørgrav INLINE void
ldns_buffer_write_u8(ldns_buffer * buffer,uint8_t data)4377b5038d7SDag-Erling Smørgrav ldns_buffer_write_u8(ldns_buffer *buffer, uint8_t data)
4387b5038d7SDag-Erling Smørgrav {
4397b5038d7SDag-Erling Smørgrav 	ldns_buffer_write_u8_at(buffer, buffer->_position, data);
4407b5038d7SDag-Erling Smørgrav 	buffer->_position += sizeof(data);
4417b5038d7SDag-Erling Smørgrav }
4427b5038d7SDag-Erling Smørgrav 
4437b5038d7SDag-Erling Smørgrav /**
444*5afab0e5SDag-Erling Smørgrav  * writes the given byte of data at the current position in the buffer
445*5afab0e5SDag-Erling Smørgrav  * increasing the capacity if necessary
446*5afab0e5SDag-Erling Smørgrav  * \param[in] buffer the buffer
447*5afab0e5SDag-Erling Smørgrav  * \param[in] data the 8 bits to write
448*5afab0e5SDag-Erling Smørgrav  */
449*5afab0e5SDag-Erling Smørgrav INLINE void
ldns_buffer_write_char(ldns_buffer * buffer,uint8_t data)450*5afab0e5SDag-Erling Smørgrav ldns_buffer_write_char(ldns_buffer *buffer, uint8_t data)
451*5afab0e5SDag-Erling Smørgrav {
452*5afab0e5SDag-Erling Smørgrav 	if (!ldns_buffer_reserve(buffer, sizeof(data)))
453*5afab0e5SDag-Erling Smørgrav 		buffer->_status = LDNS_STATUS_MEM_ERR;
454*5afab0e5SDag-Erling Smørgrav 	else
455*5afab0e5SDag-Erling Smørgrav 		ldns_buffer_write_u8(buffer, data);
456*5afab0e5SDag-Erling Smørgrav }
457*5afab0e5SDag-Erling Smørgrav 
458*5afab0e5SDag-Erling Smørgrav /**
4597b5038d7SDag-Erling Smørgrav  * writes the given 2 byte integer at the given position in the buffer
4607b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
4617b5038d7SDag-Erling Smørgrav  * \param[in] at the position in the buffer
4627b5038d7SDag-Erling Smørgrav  * \param[in] data the 16 bits to write
4637b5038d7SDag-Erling Smørgrav  */
4647b5038d7SDag-Erling Smørgrav INLINE void
ldns_buffer_write_u16_at(ldns_buffer * buffer,size_t at,uint16_t data)4657b5038d7SDag-Erling Smørgrav ldns_buffer_write_u16_at(ldns_buffer *buffer, size_t at, uint16_t data)
4667b5038d7SDag-Erling Smørgrav {
4677b5038d7SDag-Erling Smørgrav 	assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
4687b5038d7SDag-Erling Smørgrav 	ldns_write_uint16(buffer->_data + at, data);
4697b5038d7SDag-Erling Smørgrav }
4707b5038d7SDag-Erling Smørgrav 
4717b5038d7SDag-Erling Smørgrav /**
4727b5038d7SDag-Erling Smørgrav  * writes the given 2 byte integer at the current position in the buffer
4737b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
4747b5038d7SDag-Erling Smørgrav  * \param[in] data the 16 bits to write
4757b5038d7SDag-Erling Smørgrav  */
4767b5038d7SDag-Erling Smørgrav INLINE void
ldns_buffer_write_u16(ldns_buffer * buffer,uint16_t data)4777b5038d7SDag-Erling Smørgrav ldns_buffer_write_u16(ldns_buffer *buffer, uint16_t data)
4787b5038d7SDag-Erling Smørgrav {
4797b5038d7SDag-Erling Smørgrav 	ldns_buffer_write_u16_at(buffer, buffer->_position, data);
4807b5038d7SDag-Erling Smørgrav 	buffer->_position += sizeof(data);
4817b5038d7SDag-Erling Smørgrav }
4827b5038d7SDag-Erling Smørgrav 
4837b5038d7SDag-Erling Smørgrav /**
4847b5038d7SDag-Erling Smørgrav  * writes the given 4 byte integer at the given position in the buffer
4857b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
4867b5038d7SDag-Erling Smørgrav  * \param[in] at the position in the buffer
4877b5038d7SDag-Erling Smørgrav  * \param[in] data the 32 bits to write
4887b5038d7SDag-Erling Smørgrav  */
4897b5038d7SDag-Erling Smørgrav INLINE void
ldns_buffer_write_u32_at(ldns_buffer * buffer,size_t at,uint32_t data)4907b5038d7SDag-Erling Smørgrav ldns_buffer_write_u32_at(ldns_buffer *buffer, size_t at, uint32_t data)
4917b5038d7SDag-Erling Smørgrav {
4927b5038d7SDag-Erling Smørgrav 	assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
4937b5038d7SDag-Erling Smørgrav 	ldns_write_uint32(buffer->_data + at, data);
4947b5038d7SDag-Erling Smørgrav }
4957b5038d7SDag-Erling Smørgrav 
4967b5038d7SDag-Erling Smørgrav /**
4977b5038d7SDag-Erling Smørgrav  * writes the given 4 byte integer at the current position in the buffer
4987b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
4997b5038d7SDag-Erling Smørgrav  * \param[in] data the 32 bits to write
5007b5038d7SDag-Erling Smørgrav  */
5017b5038d7SDag-Erling Smørgrav INLINE void
ldns_buffer_write_u32(ldns_buffer * buffer,uint32_t data)5027b5038d7SDag-Erling Smørgrav ldns_buffer_write_u32(ldns_buffer *buffer, uint32_t data)
5037b5038d7SDag-Erling Smørgrav {
5047b5038d7SDag-Erling Smørgrav 	ldns_buffer_write_u32_at(buffer, buffer->_position, data);
5057b5038d7SDag-Erling Smørgrav 	buffer->_position += sizeof(data);
5067b5038d7SDag-Erling Smørgrav }
5077b5038d7SDag-Erling Smørgrav 
5087b5038d7SDag-Erling Smørgrav /**
5097b5038d7SDag-Erling Smørgrav  * copies count bytes of data at the given position to the given data-array
5107b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
5117b5038d7SDag-Erling Smørgrav  * \param[in] at the position in the buffer to start
5127b5038d7SDag-Erling Smørgrav  * \param[out] data buffer to copy to
5137b5038d7SDag-Erling Smørgrav  * \param[in] count the length of the data to copy
5147b5038d7SDag-Erling Smørgrav  */
5157b5038d7SDag-Erling Smørgrav INLINE void
ldns_buffer_read_at(const ldns_buffer * buffer,size_t at,void * data,size_t count)516986ba33cSDag-Erling Smørgrav ldns_buffer_read_at(const ldns_buffer *buffer, size_t at, void *data, size_t count)
5177b5038d7SDag-Erling Smørgrav {
5187b5038d7SDag-Erling Smørgrav 	assert(ldns_buffer_available_at(buffer, at, count));
5197b5038d7SDag-Erling Smørgrav 	memcpy(data, buffer->_data + at, count);
5207b5038d7SDag-Erling Smørgrav }
5217b5038d7SDag-Erling Smørgrav 
5227b5038d7SDag-Erling Smørgrav /**
5237b5038d7SDag-Erling Smørgrav  * copies count bytes of data at the current position to the given data-array
5247b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
5257b5038d7SDag-Erling Smørgrav  * \param[out] data buffer to copy to
5267b5038d7SDag-Erling Smørgrav  * \param[in] count the length of the data to copy
5277b5038d7SDag-Erling Smørgrav  */
5287b5038d7SDag-Erling Smørgrav INLINE void
ldns_buffer_read(ldns_buffer * buffer,void * data,size_t count)5297b5038d7SDag-Erling Smørgrav ldns_buffer_read(ldns_buffer *buffer, void *data, size_t count)
5307b5038d7SDag-Erling Smørgrav {
5317b5038d7SDag-Erling Smørgrav 	ldns_buffer_read_at(buffer, buffer->_position, data, count);
5327b5038d7SDag-Erling Smørgrav 	buffer->_position += count;
5337b5038d7SDag-Erling Smørgrav }
5347b5038d7SDag-Erling Smørgrav 
5357b5038d7SDag-Erling Smørgrav /**
5367b5038d7SDag-Erling Smørgrav  * returns the byte value at the given position in the buffer
5377b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
5387b5038d7SDag-Erling Smørgrav  * \param[in] at the position in the buffer
5397b5038d7SDag-Erling Smørgrav  * \return 1 byte integer
5407b5038d7SDag-Erling Smørgrav  */
5417b5038d7SDag-Erling Smørgrav INLINE uint8_t
ldns_buffer_read_u8_at(const ldns_buffer * buffer,size_t at)542986ba33cSDag-Erling Smørgrav ldns_buffer_read_u8_at(const ldns_buffer *buffer, size_t at)
5437b5038d7SDag-Erling Smørgrav {
5447b5038d7SDag-Erling Smørgrav 	assert(ldns_buffer_available_at(buffer, at, sizeof(uint8_t)));
5457b5038d7SDag-Erling Smørgrav 	return buffer->_data[at];
5467b5038d7SDag-Erling Smørgrav }
5477b5038d7SDag-Erling Smørgrav 
5487b5038d7SDag-Erling Smørgrav /**
5497b5038d7SDag-Erling Smørgrav  * returns the byte value at the current position in the buffer
5507b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
5517b5038d7SDag-Erling Smørgrav  * \return 1 byte integer
5527b5038d7SDag-Erling Smørgrav  */
5537b5038d7SDag-Erling Smørgrav INLINE uint8_t
ldns_buffer_read_u8(ldns_buffer * buffer)5547b5038d7SDag-Erling Smørgrav ldns_buffer_read_u8(ldns_buffer *buffer)
5557b5038d7SDag-Erling Smørgrav {
5567b5038d7SDag-Erling Smørgrav 	uint8_t result = ldns_buffer_read_u8_at(buffer, buffer->_position);
5577b5038d7SDag-Erling Smørgrav 	buffer->_position += sizeof(uint8_t);
5587b5038d7SDag-Erling Smørgrav 	return result;
5597b5038d7SDag-Erling Smørgrav }
5607b5038d7SDag-Erling Smørgrav 
5617b5038d7SDag-Erling Smørgrav /**
5627b5038d7SDag-Erling Smørgrav  * returns the 2-byte integer value at the given position in the buffer
5637b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
5647b5038d7SDag-Erling Smørgrav  * \param[in] at position in the buffer
5657b5038d7SDag-Erling Smørgrav  * \return 2 byte integer
5667b5038d7SDag-Erling Smørgrav  */
5677b5038d7SDag-Erling Smørgrav INLINE uint16_t
ldns_buffer_read_u16_at(ldns_buffer * buffer,size_t at)5687b5038d7SDag-Erling Smørgrav ldns_buffer_read_u16_at(ldns_buffer *buffer, size_t at)
5697b5038d7SDag-Erling Smørgrav {
5707b5038d7SDag-Erling Smørgrav 	assert(ldns_buffer_available_at(buffer, at, sizeof(uint16_t)));
5717b5038d7SDag-Erling Smørgrav 	return ldns_read_uint16(buffer->_data + at);
5727b5038d7SDag-Erling Smørgrav }
5737b5038d7SDag-Erling Smørgrav 
5747b5038d7SDag-Erling Smørgrav /**
5757b5038d7SDag-Erling Smørgrav  * returns the 2-byte integer value at the current position in the buffer
5767b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
5777b5038d7SDag-Erling Smørgrav  * \return 2 byte integer
5787b5038d7SDag-Erling Smørgrav  */
5797b5038d7SDag-Erling Smørgrav INLINE uint16_t
ldns_buffer_read_u16(ldns_buffer * buffer)5807b5038d7SDag-Erling Smørgrav ldns_buffer_read_u16(ldns_buffer *buffer)
5817b5038d7SDag-Erling Smørgrav {
5827b5038d7SDag-Erling Smørgrav 	uint16_t result = ldns_buffer_read_u16_at(buffer, buffer->_position);
5837b5038d7SDag-Erling Smørgrav 	buffer->_position += sizeof(uint16_t);
5847b5038d7SDag-Erling Smørgrav 	return result;
5857b5038d7SDag-Erling Smørgrav }
5867b5038d7SDag-Erling Smørgrav 
5877b5038d7SDag-Erling Smørgrav /**
5887b5038d7SDag-Erling Smørgrav  * returns the 4-byte integer value at the given position in the buffer
5897b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
5907b5038d7SDag-Erling Smørgrav  * \param[in] at position in the buffer
5917b5038d7SDag-Erling Smørgrav  * \return 4 byte integer
5927b5038d7SDag-Erling Smørgrav  */
5937b5038d7SDag-Erling Smørgrav INLINE uint32_t
ldns_buffer_read_u32_at(ldns_buffer * buffer,size_t at)5947b5038d7SDag-Erling Smørgrav ldns_buffer_read_u32_at(ldns_buffer *buffer, size_t at)
5957b5038d7SDag-Erling Smørgrav {
5967b5038d7SDag-Erling Smørgrav 	assert(ldns_buffer_available_at(buffer, at, sizeof(uint32_t)));
5977b5038d7SDag-Erling Smørgrav 	return ldns_read_uint32(buffer->_data + at);
5987b5038d7SDag-Erling Smørgrav }
5997b5038d7SDag-Erling Smørgrav 
6007b5038d7SDag-Erling Smørgrav /**
6017b5038d7SDag-Erling Smørgrav  * returns the 4-byte integer value at the current position in the buffer
6027b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
6037b5038d7SDag-Erling Smørgrav  * \return 4 byte integer
6047b5038d7SDag-Erling Smørgrav  */
6057b5038d7SDag-Erling Smørgrav INLINE uint32_t
ldns_buffer_read_u32(ldns_buffer * buffer)6067b5038d7SDag-Erling Smørgrav ldns_buffer_read_u32(ldns_buffer *buffer)
6077b5038d7SDag-Erling Smørgrav {
6087b5038d7SDag-Erling Smørgrav 	uint32_t result = ldns_buffer_read_u32_at(buffer, buffer->_position);
6097b5038d7SDag-Erling Smørgrav 	buffer->_position += sizeof(uint32_t);
6107b5038d7SDag-Erling Smørgrav 	return result;
6117b5038d7SDag-Erling Smørgrav }
6127b5038d7SDag-Erling Smørgrav 
6137b5038d7SDag-Erling Smørgrav /**
6147b5038d7SDag-Erling Smørgrav  * returns the status of the buffer
6157b5038d7SDag-Erling Smørgrav  * \param[in] buffer
6167b5038d7SDag-Erling Smørgrav  * \return the status
6177b5038d7SDag-Erling Smørgrav  */
6187b5038d7SDag-Erling Smørgrav INLINE ldns_status
ldns_buffer_status(const ldns_buffer * buffer)619986ba33cSDag-Erling Smørgrav ldns_buffer_status(const ldns_buffer *buffer)
6207b5038d7SDag-Erling Smørgrav {
6217b5038d7SDag-Erling Smørgrav 	return buffer->_status;
6227b5038d7SDag-Erling Smørgrav }
6237b5038d7SDag-Erling Smørgrav 
6247b5038d7SDag-Erling Smørgrav /**
6257b5038d7SDag-Erling Smørgrav  * returns true if the status of the buffer is LDNS_STATUS_OK, false otherwise
6267b5038d7SDag-Erling Smørgrav  * \param[in] buffer the buffer
6277b5038d7SDag-Erling Smørgrav  * \return true or false
6287b5038d7SDag-Erling Smørgrav  */
6297b5038d7SDag-Erling Smørgrav INLINE bool
ldns_buffer_status_ok(const ldns_buffer * buffer)630986ba33cSDag-Erling Smørgrav ldns_buffer_status_ok(const ldns_buffer *buffer)
6317b5038d7SDag-Erling Smørgrav {
6327b5038d7SDag-Erling Smørgrav 	if (buffer) {
6337b5038d7SDag-Erling Smørgrav 		return ldns_buffer_status(buffer) == LDNS_STATUS_OK;
6347b5038d7SDag-Erling Smørgrav 	} else {
6357b5038d7SDag-Erling Smørgrav 		return false;
6367b5038d7SDag-Erling Smørgrav 	}
6377b5038d7SDag-Erling Smørgrav }
6387b5038d7SDag-Erling Smørgrav 
6397b5038d7SDag-Erling Smørgrav /**
6407b5038d7SDag-Erling Smørgrav  * prints to the buffer, increasing the capacity if required using
6417b5038d7SDag-Erling Smørgrav  * buffer_reserve(). The buffer's position is set to the terminating '\\0'
6427b5038d7SDag-Erling Smørgrav  * Returns the number of characters written (not including the
6437b5038d7SDag-Erling Smørgrav  * terminating '\\0') or -1 on failure.
6447b5038d7SDag-Erling Smørgrav  */
6457b5038d7SDag-Erling Smørgrav int ldns_buffer_printf(ldns_buffer *buffer, const char *format, ...);
6467b5038d7SDag-Erling Smørgrav /*	ATTR_FORMAT(printf, 2, 3);*/
6477b5038d7SDag-Erling Smørgrav 
6487b5038d7SDag-Erling Smørgrav /**
6497b5038d7SDag-Erling Smørgrav  * frees the buffer.
6507b5038d7SDag-Erling Smørgrav  * \param[in] *buffer the buffer to be freed
6517b5038d7SDag-Erling Smørgrav  * \return void
6527b5038d7SDag-Erling Smørgrav  */
6537b5038d7SDag-Erling Smørgrav void ldns_buffer_free(ldns_buffer *buffer);
6547b5038d7SDag-Erling Smørgrav 
6557b5038d7SDag-Erling Smørgrav /**
6567b5038d7SDag-Erling Smørgrav  * Makes the buffer fixed and returns a pointer to the data.  The
6577b5038d7SDag-Erling Smørgrav  * caller is responsible for free'ing the result.
6587b5038d7SDag-Erling Smørgrav  * \param[in] *buffer the buffer to be exported
6597b5038d7SDag-Erling Smørgrav  * \return void
6607b5038d7SDag-Erling Smørgrav  */
6617b5038d7SDag-Erling Smørgrav void *ldns_buffer_export(ldns_buffer *buffer);
6627b5038d7SDag-Erling Smørgrav 
6637b5038d7SDag-Erling Smørgrav /**
6642787e39aSDag-Erling Smørgrav  * Copy contents of the from buffer to the result buffer and then flips
6652787e39aSDag-Erling Smørgrav  * the result buffer. Data will be silently truncated if the result buffer is
6662787e39aSDag-Erling Smørgrav  * too small.
6677b5038d7SDag-Erling Smørgrav  * \param[out] *result resulting buffer which is copied to.
6687b5038d7SDag-Erling Smørgrav  * \param[in] *from what to copy to result.
6697b5038d7SDag-Erling Smørgrav  */
670986ba33cSDag-Erling Smørgrav void ldns_buffer_copy(ldns_buffer* result, const ldns_buffer* from);
6717b5038d7SDag-Erling Smørgrav 
6727b5038d7SDag-Erling Smørgrav #ifdef __cplusplus
6737b5038d7SDag-Erling Smørgrav }
6747b5038d7SDag-Erling Smørgrav #endif
6757b5038d7SDag-Erling Smørgrav 
6767b5038d7SDag-Erling Smørgrav #endif /* LDNS_BUFFER_H */
677