109a3aaf3SDag-Erling Smørgrav /*
209a3aaf3SDag-Erling Smørgrav * buffer.h -- generic memory buffer.
309a3aaf3SDag-Erling Smørgrav *
409a3aaf3SDag-Erling Smørgrav * Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
509a3aaf3SDag-Erling Smørgrav *
609a3aaf3SDag-Erling Smørgrav * See LICENSE for the license.
709a3aaf3SDag-Erling Smørgrav *
809a3aaf3SDag-Erling Smørgrav *
909a3aaf3SDag-Erling Smørgrav * The buffer module implements a generic buffer. The API is based on
1009a3aaf3SDag-Erling Smørgrav * the java.nio.Buffer interface.
1109a3aaf3SDag-Erling Smørgrav */
1209a3aaf3SDag-Erling Smørgrav
1309a3aaf3SDag-Erling Smørgrav #ifndef LDNS_SBUFFER_H
1409a3aaf3SDag-Erling Smørgrav #define LDNS_SBUFFER_H
1509a3aaf3SDag-Erling Smørgrav
1609a3aaf3SDag-Erling Smørgrav #ifdef __cplusplus
1709a3aaf3SDag-Erling Smørgrav extern "C" {
1809a3aaf3SDag-Erling Smørgrav #endif
1909a3aaf3SDag-Erling Smørgrav
2009a3aaf3SDag-Erling Smørgrav #ifdef S_SPLINT_S
2109a3aaf3SDag-Erling Smørgrav # define INLINE
2209a3aaf3SDag-Erling Smørgrav #else
2309a3aaf3SDag-Erling Smørgrav # ifdef SWIG
2409a3aaf3SDag-Erling Smørgrav # define INLINE static
2509a3aaf3SDag-Erling Smørgrav # else
2609a3aaf3SDag-Erling Smørgrav # define INLINE static inline
2709a3aaf3SDag-Erling Smørgrav # endif
2809a3aaf3SDag-Erling Smørgrav #endif
2909a3aaf3SDag-Erling Smørgrav
3009a3aaf3SDag-Erling Smørgrav /*
3109a3aaf3SDag-Erling Smørgrav * Copy data allowing for unaligned accesses in network byte order
3209a3aaf3SDag-Erling Smørgrav * (big endian).
3309a3aaf3SDag-Erling Smørgrav */
3409a3aaf3SDag-Erling Smørgrav INLINE uint16_t
sldns_read_uint16(const void * src)3509a3aaf3SDag-Erling Smørgrav sldns_read_uint16(const void *src)
3609a3aaf3SDag-Erling Smørgrav {
3709a3aaf3SDag-Erling Smørgrav #ifdef ALLOW_UNALIGNED_ACCESSES
3809a3aaf3SDag-Erling Smørgrav return ntohs(*(const uint16_t *) src);
3909a3aaf3SDag-Erling Smørgrav #else
4009a3aaf3SDag-Erling Smørgrav const uint8_t *p = (const uint8_t *) src;
4109a3aaf3SDag-Erling Smørgrav return ((uint16_t) p[0] << 8) | (uint16_t) p[1];
4209a3aaf3SDag-Erling Smørgrav #endif
4309a3aaf3SDag-Erling Smørgrav }
4409a3aaf3SDag-Erling Smørgrav
4509a3aaf3SDag-Erling Smørgrav INLINE uint32_t
sldns_read_uint32(const void * src)4609a3aaf3SDag-Erling Smørgrav sldns_read_uint32(const void *src)
4709a3aaf3SDag-Erling Smørgrav {
4809a3aaf3SDag-Erling Smørgrav #ifdef ALLOW_UNALIGNED_ACCESSES
4909a3aaf3SDag-Erling Smørgrav return ntohl(*(const uint32_t *) src);
5009a3aaf3SDag-Erling Smørgrav #else
5109a3aaf3SDag-Erling Smørgrav const uint8_t *p = (const uint8_t *) src;
5209a3aaf3SDag-Erling Smørgrav return ( ((uint32_t) p[0] << 24)
5309a3aaf3SDag-Erling Smørgrav | ((uint32_t) p[1] << 16)
5409a3aaf3SDag-Erling Smørgrav | ((uint32_t) p[2] << 8)
5509a3aaf3SDag-Erling Smørgrav | (uint32_t) p[3]);
5609a3aaf3SDag-Erling Smørgrav #endif
5709a3aaf3SDag-Erling Smørgrav }
5809a3aaf3SDag-Erling Smørgrav
5909a3aaf3SDag-Erling Smørgrav /*
6009a3aaf3SDag-Erling Smørgrav * Copy data allowing for unaligned accesses in network byte order
6109a3aaf3SDag-Erling Smørgrav * (big endian).
6209a3aaf3SDag-Erling Smørgrav */
6309a3aaf3SDag-Erling Smørgrav INLINE void
sldns_write_uint16(void * dst,uint16_t data)6409a3aaf3SDag-Erling Smørgrav sldns_write_uint16(void *dst, uint16_t data)
6509a3aaf3SDag-Erling Smørgrav {
6609a3aaf3SDag-Erling Smørgrav #ifdef ALLOW_UNALIGNED_ACCESSES
6709a3aaf3SDag-Erling Smørgrav * (uint16_t *) dst = htons(data);
6809a3aaf3SDag-Erling Smørgrav #else
6909a3aaf3SDag-Erling Smørgrav uint8_t *p = (uint8_t *) dst;
7009a3aaf3SDag-Erling Smørgrav p[0] = (uint8_t) ((data >> 8) & 0xff);
7109a3aaf3SDag-Erling Smørgrav p[1] = (uint8_t) (data & 0xff);
7209a3aaf3SDag-Erling Smørgrav #endif
7309a3aaf3SDag-Erling Smørgrav }
7409a3aaf3SDag-Erling Smørgrav
7509a3aaf3SDag-Erling Smørgrav INLINE void
sldns_write_uint32(void * dst,uint32_t data)7609a3aaf3SDag-Erling Smørgrav sldns_write_uint32(void *dst, uint32_t data)
7709a3aaf3SDag-Erling Smørgrav {
7809a3aaf3SDag-Erling Smørgrav #ifdef ALLOW_UNALIGNED_ACCESSES
7909a3aaf3SDag-Erling Smørgrav * (uint32_t *) dst = htonl(data);
8009a3aaf3SDag-Erling Smørgrav #else
8109a3aaf3SDag-Erling Smørgrav uint8_t *p = (uint8_t *) dst;
8209a3aaf3SDag-Erling Smørgrav p[0] = (uint8_t) ((data >> 24) & 0xff);
8309a3aaf3SDag-Erling Smørgrav p[1] = (uint8_t) ((data >> 16) & 0xff);
8409a3aaf3SDag-Erling Smørgrav p[2] = (uint8_t) ((data >> 8) & 0xff);
8509a3aaf3SDag-Erling Smørgrav p[3] = (uint8_t) (data & 0xff);
8609a3aaf3SDag-Erling Smørgrav #endif
8709a3aaf3SDag-Erling Smørgrav }
8809a3aaf3SDag-Erling Smørgrav
8909a3aaf3SDag-Erling Smørgrav
9065b390aaSDag-Erling Smørgrav INLINE void
sldns_write_uint48(void * dst,uint64_t data)9165b390aaSDag-Erling Smørgrav sldns_write_uint48(void *dst, uint64_t data)
9265b390aaSDag-Erling Smørgrav {
9365b390aaSDag-Erling Smørgrav uint8_t *p = (uint8_t *) dst;
9465b390aaSDag-Erling Smørgrav p[0] = (uint8_t) ((data >> 40) & 0xff);
9565b390aaSDag-Erling Smørgrav p[1] = (uint8_t) ((data >> 32) & 0xff);
9665b390aaSDag-Erling Smørgrav p[2] = (uint8_t) ((data >> 24) & 0xff);
9765b390aaSDag-Erling Smørgrav p[3] = (uint8_t) ((data >> 16) & 0xff);
9865b390aaSDag-Erling Smørgrav p[4] = (uint8_t) ((data >> 8) & 0xff);
9965b390aaSDag-Erling Smørgrav p[5] = (uint8_t) (data & 0xff);
10065b390aaSDag-Erling Smørgrav }
10165b390aaSDag-Erling Smørgrav
10265b390aaSDag-Erling Smørgrav
10309a3aaf3SDag-Erling Smørgrav /**
10409a3aaf3SDag-Erling Smørgrav * \file sbuffer.h
10509a3aaf3SDag-Erling Smørgrav *
10609a3aaf3SDag-Erling Smørgrav * This file contains the definition of sldns_buffer, and functions to manipulate those.
10709a3aaf3SDag-Erling Smørgrav */
10809a3aaf3SDag-Erling Smørgrav
10909a3aaf3SDag-Erling Smørgrav /**
11009a3aaf3SDag-Erling Smørgrav * implementation of buffers to ease operations
11109a3aaf3SDag-Erling Smørgrav *
11209a3aaf3SDag-Erling Smørgrav * sldns_buffers can contain arbitrary information, per octet. You can write
11309a3aaf3SDag-Erling Smørgrav * to the current end of a buffer, read from the current position, and
11409a3aaf3SDag-Erling Smørgrav * access any data within it.
11509a3aaf3SDag-Erling Smørgrav */
11609a3aaf3SDag-Erling Smørgrav struct sldns_buffer
11709a3aaf3SDag-Erling Smørgrav {
11809a3aaf3SDag-Erling Smørgrav /** The current position used for reading/writing */
11909a3aaf3SDag-Erling Smørgrav size_t _position;
12009a3aaf3SDag-Erling Smørgrav
12109a3aaf3SDag-Erling Smørgrav /** The read/write limit */
12209a3aaf3SDag-Erling Smørgrav size_t _limit;
12309a3aaf3SDag-Erling Smørgrav
12409a3aaf3SDag-Erling Smørgrav /** The amount of data the buffer can contain */
12509a3aaf3SDag-Erling Smørgrav size_t _capacity;
12609a3aaf3SDag-Erling Smørgrav
12709a3aaf3SDag-Erling Smørgrav /** The data contained in the buffer */
12809a3aaf3SDag-Erling Smørgrav uint8_t *_data;
12909a3aaf3SDag-Erling Smørgrav
13009a3aaf3SDag-Erling Smørgrav /** If the buffer is fixed it cannot be resized */
13109a3aaf3SDag-Erling Smørgrav unsigned _fixed : 1;
13209a3aaf3SDag-Erling Smørgrav
13309a3aaf3SDag-Erling Smørgrav /** The current state of the buffer. If writing to the buffer fails
13409a3aaf3SDag-Erling Smørgrav * for any reason, this value is changed. This way, you can perform
13509a3aaf3SDag-Erling Smørgrav * multiple writes in sequence and check for success afterwards. */
13609a3aaf3SDag-Erling Smørgrav unsigned _status_err : 1;
13709a3aaf3SDag-Erling Smørgrav };
13809a3aaf3SDag-Erling Smørgrav typedef struct sldns_buffer sldns_buffer;
13909a3aaf3SDag-Erling Smørgrav
14009a3aaf3SDag-Erling Smørgrav #ifdef NDEBUG
14109a3aaf3SDag-Erling Smørgrav INLINE void
sldns_buffer_invariant(sldns_buffer * ATTR_UNUSED (buffer))14209a3aaf3SDag-Erling Smørgrav sldns_buffer_invariant(sldns_buffer *ATTR_UNUSED(buffer))
14309a3aaf3SDag-Erling Smørgrav {
14409a3aaf3SDag-Erling Smørgrav }
14509a3aaf3SDag-Erling Smørgrav #else
14609a3aaf3SDag-Erling Smørgrav INLINE void
sldns_buffer_invariant(sldns_buffer * buffer)14709a3aaf3SDag-Erling Smørgrav sldns_buffer_invariant(sldns_buffer *buffer)
14809a3aaf3SDag-Erling Smørgrav {
14909a3aaf3SDag-Erling Smørgrav assert(buffer != NULL);
150*0eefd307SCy Schubert assert(buffer->_position <= buffer->_limit);
15109a3aaf3SDag-Erling Smørgrav assert(buffer->_limit <= buffer->_capacity);
152*0eefd307SCy Schubert assert(buffer->_data != NULL);
15309a3aaf3SDag-Erling Smørgrav }
15409a3aaf3SDag-Erling Smørgrav #endif
15509a3aaf3SDag-Erling Smørgrav
15609a3aaf3SDag-Erling Smørgrav /**
15709a3aaf3SDag-Erling Smørgrav * creates a new buffer with the specified capacity.
15809a3aaf3SDag-Erling Smørgrav *
15909a3aaf3SDag-Erling Smørgrav * \param[in] capacity the size (in bytes) to allocate for the buffer
16009a3aaf3SDag-Erling Smørgrav * \return the created buffer
16109a3aaf3SDag-Erling Smørgrav */
16209a3aaf3SDag-Erling Smørgrav sldns_buffer *sldns_buffer_new(size_t capacity);
16309a3aaf3SDag-Erling Smørgrav
16409a3aaf3SDag-Erling Smørgrav /**
16509a3aaf3SDag-Erling Smørgrav * creates a buffer with the specified data. The data IS copied
16609a3aaf3SDag-Erling Smørgrav * and MEMORY allocations are done. The buffer is not fixed and can
16709a3aaf3SDag-Erling Smørgrav * be resized using buffer_reserve().
16809a3aaf3SDag-Erling Smørgrav *
16909a3aaf3SDag-Erling Smørgrav * \param[in] buffer pointer to the buffer to put the data in
17009a3aaf3SDag-Erling Smørgrav * \param[in] data the data to encapsulate in the buffer
17109a3aaf3SDag-Erling Smørgrav * \param[in] size the size of the data
17209a3aaf3SDag-Erling Smørgrav */
17309a3aaf3SDag-Erling Smørgrav void sldns_buffer_new_frm_data(sldns_buffer *buffer, void *data, size_t size);
17409a3aaf3SDag-Erling Smørgrav
17509a3aaf3SDag-Erling Smørgrav /**
17609a3aaf3SDag-Erling Smørgrav * Setup a buffer with the data pointed to. No data copied, no memory allocs.
17709a3aaf3SDag-Erling Smørgrav * The buffer is fixed.
17809a3aaf3SDag-Erling Smørgrav * \param[in] buffer pointer to the buffer to put the data in
17909a3aaf3SDag-Erling Smørgrav * \param[in] data the data to encapsulate in the buffer
18009a3aaf3SDag-Erling Smørgrav * \param[in] size the size of the data
18109a3aaf3SDag-Erling Smørgrav */
18209a3aaf3SDag-Erling Smørgrav void sldns_buffer_init_frm_data(sldns_buffer *buffer, void *data, size_t size);
18309a3aaf3SDag-Erling Smørgrav
18409a3aaf3SDag-Erling Smørgrav /**
18509a3aaf3SDag-Erling Smørgrav * clears the buffer and make it ready for writing. The buffer's limit
18609a3aaf3SDag-Erling Smørgrav * is set to the capacity and the position is set to 0.
18709a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer to clear
18809a3aaf3SDag-Erling Smørgrav */
sldns_buffer_clear(sldns_buffer * buffer)18909a3aaf3SDag-Erling Smørgrav INLINE void sldns_buffer_clear(sldns_buffer *buffer)
19009a3aaf3SDag-Erling Smørgrav {
19109a3aaf3SDag-Erling Smørgrav sldns_buffer_invariant(buffer);
19209a3aaf3SDag-Erling Smørgrav
19309a3aaf3SDag-Erling Smørgrav /* reset status here? */
19409a3aaf3SDag-Erling Smørgrav
19509a3aaf3SDag-Erling Smørgrav buffer->_position = 0;
19609a3aaf3SDag-Erling Smørgrav buffer->_limit = buffer->_capacity;
19709a3aaf3SDag-Erling Smørgrav }
19809a3aaf3SDag-Erling Smørgrav
19909a3aaf3SDag-Erling Smørgrav /**
20009a3aaf3SDag-Erling Smørgrav * makes the buffer ready for reading the data that has been written to
20109a3aaf3SDag-Erling Smørgrav * the buffer. The buffer's limit is set to the current position and
20209a3aaf3SDag-Erling Smørgrav * the position is set to 0.
20309a3aaf3SDag-Erling Smørgrav *
20409a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer to flip
20509a3aaf3SDag-Erling Smørgrav */
sldns_buffer_flip(sldns_buffer * buffer)20609a3aaf3SDag-Erling Smørgrav INLINE void sldns_buffer_flip(sldns_buffer *buffer)
20709a3aaf3SDag-Erling Smørgrav {
20809a3aaf3SDag-Erling Smørgrav sldns_buffer_invariant(buffer);
20909a3aaf3SDag-Erling Smørgrav
21009a3aaf3SDag-Erling Smørgrav buffer->_limit = buffer->_position;
21109a3aaf3SDag-Erling Smørgrav buffer->_position = 0;
21209a3aaf3SDag-Erling Smørgrav }
21309a3aaf3SDag-Erling Smørgrav
21409a3aaf3SDag-Erling Smørgrav /**
21509a3aaf3SDag-Erling Smørgrav * make the buffer ready for re-reading the data. The buffer's
21609a3aaf3SDag-Erling Smørgrav * position is reset to 0.
21709a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer to rewind
21809a3aaf3SDag-Erling Smørgrav */
sldns_buffer_rewind(sldns_buffer * buffer)21909a3aaf3SDag-Erling Smørgrav INLINE void sldns_buffer_rewind(sldns_buffer *buffer)
22009a3aaf3SDag-Erling Smørgrav {
22109a3aaf3SDag-Erling Smørgrav sldns_buffer_invariant(buffer);
22209a3aaf3SDag-Erling Smørgrav
22309a3aaf3SDag-Erling Smørgrav buffer->_position = 0;
22409a3aaf3SDag-Erling Smørgrav }
22509a3aaf3SDag-Erling Smørgrav
22609a3aaf3SDag-Erling Smørgrav /**
22709a3aaf3SDag-Erling Smørgrav * returns the current position in the buffer (as a number of bytes)
22809a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
22909a3aaf3SDag-Erling Smørgrav * \return the current position
23009a3aaf3SDag-Erling Smørgrav */
23109a3aaf3SDag-Erling Smørgrav INLINE size_t
sldns_buffer_position(sldns_buffer * buffer)23209a3aaf3SDag-Erling Smørgrav sldns_buffer_position(sldns_buffer *buffer)
23309a3aaf3SDag-Erling Smørgrav {
23409a3aaf3SDag-Erling Smørgrav return buffer->_position;
23509a3aaf3SDag-Erling Smørgrav }
23609a3aaf3SDag-Erling Smørgrav
23709a3aaf3SDag-Erling Smørgrav /**
23809a3aaf3SDag-Erling Smørgrav * sets the buffer's position to MARK. The position must be less than
23909a3aaf3SDag-Erling Smørgrav * or equal to the buffer's limit.
24009a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
24109a3aaf3SDag-Erling Smørgrav * \param[in] mark the mark to use
24209a3aaf3SDag-Erling Smørgrav */
24309a3aaf3SDag-Erling Smørgrav INLINE void
sldns_buffer_set_position(sldns_buffer * buffer,size_t mark)24409a3aaf3SDag-Erling Smørgrav sldns_buffer_set_position(sldns_buffer *buffer, size_t mark)
24509a3aaf3SDag-Erling Smørgrav {
246*0eefd307SCy Schubert assert(mark <= buffer->_limit);
24709a3aaf3SDag-Erling Smørgrav buffer->_position = mark;
24809a3aaf3SDag-Erling Smørgrav }
24909a3aaf3SDag-Erling Smørgrav
25009a3aaf3SDag-Erling Smørgrav /**
25109a3aaf3SDag-Erling Smørgrav * changes the buffer's position by COUNT bytes. The position must not
25209a3aaf3SDag-Erling Smørgrav * be moved behind the buffer's limit or before the beginning of the
25309a3aaf3SDag-Erling Smørgrav * buffer.
25409a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
25509a3aaf3SDag-Erling Smørgrav * \param[in] count the count to use
25609a3aaf3SDag-Erling Smørgrav */
25709a3aaf3SDag-Erling Smørgrav INLINE void
sldns_buffer_skip(sldns_buffer * buffer,ssize_t count)25809a3aaf3SDag-Erling Smørgrav sldns_buffer_skip(sldns_buffer *buffer, ssize_t count)
25909a3aaf3SDag-Erling Smørgrav {
260*0eefd307SCy Schubert assert(buffer->_position + count <= buffer->_limit);
26109a3aaf3SDag-Erling Smørgrav buffer->_position += count;
26209a3aaf3SDag-Erling Smørgrav }
26309a3aaf3SDag-Erling Smørgrav
26409a3aaf3SDag-Erling Smørgrav /**
26509a3aaf3SDag-Erling Smørgrav * returns the maximum size of the buffer
26609a3aaf3SDag-Erling Smørgrav * \param[in] buffer
26709a3aaf3SDag-Erling Smørgrav * \return the size
26809a3aaf3SDag-Erling Smørgrav */
26909a3aaf3SDag-Erling Smørgrav INLINE size_t
sldns_buffer_limit(sldns_buffer * buffer)27009a3aaf3SDag-Erling Smørgrav sldns_buffer_limit(sldns_buffer *buffer)
27109a3aaf3SDag-Erling Smørgrav {
27209a3aaf3SDag-Erling Smørgrav return buffer->_limit;
27309a3aaf3SDag-Erling Smørgrav }
27409a3aaf3SDag-Erling Smørgrav
27509a3aaf3SDag-Erling Smørgrav /**
27609a3aaf3SDag-Erling Smørgrav * changes the buffer's limit. If the buffer's position is greater
27709a3aaf3SDag-Erling Smørgrav * than the new limit the position is set to the limit.
27809a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
27909a3aaf3SDag-Erling Smørgrav * \param[in] limit the new limit
28009a3aaf3SDag-Erling Smørgrav */
28109a3aaf3SDag-Erling Smørgrav INLINE void
sldns_buffer_set_limit(sldns_buffer * buffer,size_t limit)28209a3aaf3SDag-Erling Smørgrav sldns_buffer_set_limit(sldns_buffer *buffer, size_t limit)
28309a3aaf3SDag-Erling Smørgrav {
28409a3aaf3SDag-Erling Smørgrav assert(limit <= buffer->_capacity);
28509a3aaf3SDag-Erling Smørgrav buffer->_limit = limit;
28609a3aaf3SDag-Erling Smørgrav if (buffer->_position > buffer->_limit)
28709a3aaf3SDag-Erling Smørgrav buffer->_position = buffer->_limit;
28809a3aaf3SDag-Erling Smørgrav }
28909a3aaf3SDag-Erling Smørgrav
29009a3aaf3SDag-Erling Smørgrav /**
29109a3aaf3SDag-Erling Smørgrav * returns the number of bytes the buffer can hold.
29209a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
29309a3aaf3SDag-Erling Smørgrav * \return the number of bytes
29409a3aaf3SDag-Erling Smørgrav */
29509a3aaf3SDag-Erling Smørgrav INLINE size_t
sldns_buffer_capacity(sldns_buffer * buffer)29609a3aaf3SDag-Erling Smørgrav sldns_buffer_capacity(sldns_buffer *buffer)
29709a3aaf3SDag-Erling Smørgrav {
29809a3aaf3SDag-Erling Smørgrav return buffer->_capacity;
29909a3aaf3SDag-Erling Smørgrav }
30009a3aaf3SDag-Erling Smørgrav
30109a3aaf3SDag-Erling Smørgrav /**
30209a3aaf3SDag-Erling Smørgrav * changes the buffer's capacity. The data is reallocated so any
30309a3aaf3SDag-Erling Smørgrav * pointers to the data may become invalid. The buffer's limit is set
30409a3aaf3SDag-Erling Smørgrav * to the buffer's new capacity.
30509a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
30609a3aaf3SDag-Erling Smørgrav * \param[in] capacity the capacity to use
30709a3aaf3SDag-Erling Smørgrav * \return whether this failed or succeeded
30809a3aaf3SDag-Erling Smørgrav */
30909a3aaf3SDag-Erling Smørgrav int sldns_buffer_set_capacity(sldns_buffer *buffer, size_t capacity);
31009a3aaf3SDag-Erling Smørgrav
31109a3aaf3SDag-Erling Smørgrav /**
31209a3aaf3SDag-Erling Smørgrav * ensures BUFFER can contain at least AMOUNT more bytes. The buffer's
31309a3aaf3SDag-Erling Smørgrav * capacity is increased if necessary using buffer_set_capacity().
31409a3aaf3SDag-Erling Smørgrav *
31509a3aaf3SDag-Erling Smørgrav * The buffer's limit is always set to the (possibly increased)
31609a3aaf3SDag-Erling Smørgrav * capacity.
31709a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
31809a3aaf3SDag-Erling Smørgrav * \param[in] amount amount to use
31909a3aaf3SDag-Erling Smørgrav * \return whether this failed or succeeded
32009a3aaf3SDag-Erling Smørgrav */
32109a3aaf3SDag-Erling Smørgrav int sldns_buffer_reserve(sldns_buffer *buffer, size_t amount);
32209a3aaf3SDag-Erling Smørgrav
32309a3aaf3SDag-Erling Smørgrav /**
32409a3aaf3SDag-Erling Smørgrav * returns a pointer to the data at the indicated position.
32509a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
32609a3aaf3SDag-Erling Smørgrav * \param[in] at position
32709a3aaf3SDag-Erling Smørgrav * \return the pointer to the data
32809a3aaf3SDag-Erling Smørgrav */
32909a3aaf3SDag-Erling Smørgrav INLINE uint8_t *
sldns_buffer_at(const sldns_buffer * buffer,size_t at)33009a3aaf3SDag-Erling Smørgrav sldns_buffer_at(const sldns_buffer *buffer, size_t at)
33109a3aaf3SDag-Erling Smørgrav {
332*0eefd307SCy Schubert assert(at <= buffer->_limit);
33309a3aaf3SDag-Erling Smørgrav return buffer->_data + at;
33409a3aaf3SDag-Erling Smørgrav }
33509a3aaf3SDag-Erling Smørgrav
33609a3aaf3SDag-Erling Smørgrav /**
33709a3aaf3SDag-Erling Smørgrav * returns a pointer to the beginning of the buffer (the data at
33809a3aaf3SDag-Erling Smørgrav * position 0).
33909a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
34009a3aaf3SDag-Erling Smørgrav * \return the pointer
34109a3aaf3SDag-Erling Smørgrav */
34209a3aaf3SDag-Erling Smørgrav INLINE uint8_t *
sldns_buffer_begin(const sldns_buffer * buffer)34309a3aaf3SDag-Erling Smørgrav sldns_buffer_begin(const sldns_buffer *buffer)
34409a3aaf3SDag-Erling Smørgrav {
34509a3aaf3SDag-Erling Smørgrav return sldns_buffer_at(buffer, 0);
34609a3aaf3SDag-Erling Smørgrav }
34709a3aaf3SDag-Erling Smørgrav
34809a3aaf3SDag-Erling Smørgrav /**
34909a3aaf3SDag-Erling Smørgrav * returns a pointer to the end of the buffer (the data at the buffer's
35009a3aaf3SDag-Erling Smørgrav * limit).
35109a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
35209a3aaf3SDag-Erling Smørgrav * \return the pointer
35309a3aaf3SDag-Erling Smørgrav */
35409a3aaf3SDag-Erling Smørgrav INLINE uint8_t *
sldns_buffer_end(sldns_buffer * buffer)35509a3aaf3SDag-Erling Smørgrav sldns_buffer_end(sldns_buffer *buffer)
35609a3aaf3SDag-Erling Smørgrav {
35709a3aaf3SDag-Erling Smørgrav return sldns_buffer_at(buffer, buffer->_limit);
35809a3aaf3SDag-Erling Smørgrav }
35909a3aaf3SDag-Erling Smørgrav
36009a3aaf3SDag-Erling Smørgrav /**
36109a3aaf3SDag-Erling Smørgrav * returns a pointer to the data at the buffer's current position.
36209a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
36309a3aaf3SDag-Erling Smørgrav * \return the pointer
36409a3aaf3SDag-Erling Smørgrav */
36509a3aaf3SDag-Erling Smørgrav INLINE uint8_t *
sldns_buffer_current(sldns_buffer * buffer)36609a3aaf3SDag-Erling Smørgrav sldns_buffer_current(sldns_buffer *buffer)
36709a3aaf3SDag-Erling Smørgrav {
36809a3aaf3SDag-Erling Smørgrav return sldns_buffer_at(buffer, buffer->_position);
36909a3aaf3SDag-Erling Smørgrav }
37009a3aaf3SDag-Erling Smørgrav
37109a3aaf3SDag-Erling Smørgrav /**
37209a3aaf3SDag-Erling Smørgrav * returns the number of bytes remaining between the indicated position and
37309a3aaf3SDag-Erling Smørgrav * the limit.
37409a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
37509a3aaf3SDag-Erling Smørgrav * \param[in] at indicated position
37609a3aaf3SDag-Erling Smørgrav * \return number of bytes
37709a3aaf3SDag-Erling Smørgrav */
37809a3aaf3SDag-Erling Smørgrav INLINE size_t
sldns_buffer_remaining_at(sldns_buffer * buffer,size_t at)37909a3aaf3SDag-Erling Smørgrav sldns_buffer_remaining_at(sldns_buffer *buffer, size_t at)
38009a3aaf3SDag-Erling Smørgrav {
38109a3aaf3SDag-Erling Smørgrav sldns_buffer_invariant(buffer);
382*0eefd307SCy Schubert assert(at <= buffer->_limit);
38365b390aaSDag-Erling Smørgrav return at < buffer->_limit ? buffer->_limit - at : 0;
38409a3aaf3SDag-Erling Smørgrav }
38509a3aaf3SDag-Erling Smørgrav
38609a3aaf3SDag-Erling Smørgrav /**
38709a3aaf3SDag-Erling Smørgrav * returns the number of bytes remaining between the buffer's position and
38809a3aaf3SDag-Erling Smørgrav * limit.
38909a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
39009a3aaf3SDag-Erling Smørgrav * \return the number of bytes
39109a3aaf3SDag-Erling Smørgrav */
39209a3aaf3SDag-Erling Smørgrav INLINE size_t
sldns_buffer_remaining(sldns_buffer * buffer)39309a3aaf3SDag-Erling Smørgrav sldns_buffer_remaining(sldns_buffer *buffer)
39409a3aaf3SDag-Erling Smørgrav {
39509a3aaf3SDag-Erling Smørgrav return sldns_buffer_remaining_at(buffer, buffer->_position);
39609a3aaf3SDag-Erling Smørgrav }
39709a3aaf3SDag-Erling Smørgrav
39809a3aaf3SDag-Erling Smørgrav /**
39909a3aaf3SDag-Erling Smørgrav * checks if the buffer has at least COUNT more bytes available.
40009a3aaf3SDag-Erling Smørgrav * Before reading or writing the caller needs to ensure enough space
40109a3aaf3SDag-Erling Smørgrav * is available!
40209a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
40309a3aaf3SDag-Erling Smørgrav * \param[in] at indicated position
40409a3aaf3SDag-Erling Smørgrav * \param[in] count how much is available
40509a3aaf3SDag-Erling Smørgrav * \return true or false (as int?)
40609a3aaf3SDag-Erling Smørgrav */
40709a3aaf3SDag-Erling Smørgrav INLINE int
sldns_buffer_available_at(sldns_buffer * buffer,size_t at,size_t count)40809a3aaf3SDag-Erling Smørgrav sldns_buffer_available_at(sldns_buffer *buffer, size_t at, size_t count)
40909a3aaf3SDag-Erling Smørgrav {
41009a3aaf3SDag-Erling Smørgrav return count <= sldns_buffer_remaining_at(buffer, at);
41109a3aaf3SDag-Erling Smørgrav }
41209a3aaf3SDag-Erling Smørgrav
41309a3aaf3SDag-Erling Smørgrav /**
41409a3aaf3SDag-Erling Smørgrav * checks if the buffer has count bytes available at the current position
41509a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
41609a3aaf3SDag-Erling Smørgrav * \param[in] count how much is available
41709a3aaf3SDag-Erling Smørgrav * \return true or false (as int?)
41809a3aaf3SDag-Erling Smørgrav */
41909a3aaf3SDag-Erling Smørgrav INLINE int
sldns_buffer_available(sldns_buffer * buffer,size_t count)42009a3aaf3SDag-Erling Smørgrav sldns_buffer_available(sldns_buffer *buffer, size_t count)
42109a3aaf3SDag-Erling Smørgrav {
42209a3aaf3SDag-Erling Smørgrav return sldns_buffer_available_at(buffer, buffer->_position, count);
42309a3aaf3SDag-Erling Smørgrav }
42409a3aaf3SDag-Erling Smørgrav
42509a3aaf3SDag-Erling Smørgrav /**
42609a3aaf3SDag-Erling Smørgrav * writes the given data to the buffer at the specified position
42709a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
42809a3aaf3SDag-Erling Smørgrav * \param[in] at the position (in number of bytes) to write the data at
42909a3aaf3SDag-Erling Smørgrav * \param[in] data pointer to the data to write to the buffer
43009a3aaf3SDag-Erling Smørgrav * \param[in] count the number of bytes of data to write
43109a3aaf3SDag-Erling Smørgrav */
43209a3aaf3SDag-Erling Smørgrav INLINE void
sldns_buffer_write_at(sldns_buffer * buffer,size_t at,const void * data,size_t count)43309a3aaf3SDag-Erling Smørgrav sldns_buffer_write_at(sldns_buffer *buffer, size_t at, const void *data, size_t count)
43409a3aaf3SDag-Erling Smørgrav {
43509a3aaf3SDag-Erling Smørgrav assert(sldns_buffer_available_at(buffer, at, count));
43609a3aaf3SDag-Erling Smørgrav memcpy(buffer->_data + at, data, count);
43709a3aaf3SDag-Erling Smørgrav }
43809a3aaf3SDag-Erling Smørgrav
43909a3aaf3SDag-Erling Smørgrav /**
44065b390aaSDag-Erling Smørgrav * set the given byte to the buffer at the specified position
44165b390aaSDag-Erling Smørgrav * \param[in] buffer the buffer
44265b390aaSDag-Erling Smørgrav * \param[in] at the position (in number of bytes) to write the data at
44365b390aaSDag-Erling Smørgrav * \param[in] c the byte to set to the buffer
44465b390aaSDag-Erling Smørgrav * \param[in] count the number of bytes of bytes to write
44565b390aaSDag-Erling Smørgrav */
44665b390aaSDag-Erling Smørgrav
44765b390aaSDag-Erling Smørgrav INLINE void
sldns_buffer_set_at(sldns_buffer * buffer,size_t at,int c,size_t count)44865b390aaSDag-Erling Smørgrav sldns_buffer_set_at(sldns_buffer *buffer, size_t at, int c, size_t count)
44965b390aaSDag-Erling Smørgrav {
45065b390aaSDag-Erling Smørgrav assert(sldns_buffer_available_at(buffer, at, count));
45165b390aaSDag-Erling Smørgrav memset(buffer->_data + at, c, count);
45265b390aaSDag-Erling Smørgrav }
45365b390aaSDag-Erling Smørgrav
45465b390aaSDag-Erling Smørgrav
45565b390aaSDag-Erling Smørgrav /**
45609a3aaf3SDag-Erling Smørgrav * writes count bytes of data to the current position of the buffer
45709a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
45809a3aaf3SDag-Erling Smørgrav * \param[in] data the data to write
4598a384985SDag-Erling Smørgrav * \param[in] count the length of the data to write
46009a3aaf3SDag-Erling Smørgrav */
46109a3aaf3SDag-Erling Smørgrav INLINE void
sldns_buffer_write(sldns_buffer * buffer,const void * data,size_t count)46209a3aaf3SDag-Erling Smørgrav sldns_buffer_write(sldns_buffer *buffer, const void *data, size_t count)
46309a3aaf3SDag-Erling Smørgrav {
46409a3aaf3SDag-Erling Smørgrav sldns_buffer_write_at(buffer, buffer->_position, data, count);
46509a3aaf3SDag-Erling Smørgrav buffer->_position += count;
46609a3aaf3SDag-Erling Smørgrav }
46709a3aaf3SDag-Erling Smørgrav
46809a3aaf3SDag-Erling Smørgrav /**
46909a3aaf3SDag-Erling Smørgrav * copies the given (null-delimited) string to the specified position at the buffer
47009a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
47109a3aaf3SDag-Erling Smørgrav * \param[in] at the position in the buffer
47209a3aaf3SDag-Erling Smørgrav * \param[in] str the string to write
47309a3aaf3SDag-Erling Smørgrav */
47409a3aaf3SDag-Erling Smørgrav INLINE void
sldns_buffer_write_string_at(sldns_buffer * buffer,size_t at,const char * str)47509a3aaf3SDag-Erling Smørgrav sldns_buffer_write_string_at(sldns_buffer *buffer, size_t at, const char *str)
47609a3aaf3SDag-Erling Smørgrav {
47709a3aaf3SDag-Erling Smørgrav sldns_buffer_write_at(buffer, at, str, strlen(str));
47809a3aaf3SDag-Erling Smørgrav }
47909a3aaf3SDag-Erling Smørgrav
48009a3aaf3SDag-Erling Smørgrav /**
48109a3aaf3SDag-Erling Smørgrav * copies the given (null-delimited) string to the current position at the buffer
48209a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
48309a3aaf3SDag-Erling Smørgrav * \param[in] str the string to write
48409a3aaf3SDag-Erling Smørgrav */
48509a3aaf3SDag-Erling Smørgrav INLINE void
sldns_buffer_write_string(sldns_buffer * buffer,const char * str)48609a3aaf3SDag-Erling Smørgrav sldns_buffer_write_string(sldns_buffer *buffer, const char *str)
48709a3aaf3SDag-Erling Smørgrav {
48809a3aaf3SDag-Erling Smørgrav sldns_buffer_write(buffer, str, strlen(str));
48909a3aaf3SDag-Erling Smørgrav }
49009a3aaf3SDag-Erling Smørgrav
49109a3aaf3SDag-Erling Smørgrav /**
49209a3aaf3SDag-Erling Smørgrav * writes the given byte of data at the given position in the buffer
49309a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
49409a3aaf3SDag-Erling Smørgrav * \param[in] at the position in the buffer
49509a3aaf3SDag-Erling Smørgrav * \param[in] data the 8 bits to write
49609a3aaf3SDag-Erling Smørgrav */
49709a3aaf3SDag-Erling Smørgrav INLINE void
sldns_buffer_write_u8_at(sldns_buffer * buffer,size_t at,uint8_t data)49809a3aaf3SDag-Erling Smørgrav sldns_buffer_write_u8_at(sldns_buffer *buffer, size_t at, uint8_t data)
49909a3aaf3SDag-Erling Smørgrav {
50009a3aaf3SDag-Erling Smørgrav assert(sldns_buffer_available_at(buffer, at, sizeof(data)));
50109a3aaf3SDag-Erling Smørgrav buffer->_data[at] = data;
50209a3aaf3SDag-Erling Smørgrav }
50309a3aaf3SDag-Erling Smørgrav
50409a3aaf3SDag-Erling Smørgrav /**
50509a3aaf3SDag-Erling Smørgrav * writes the given byte of data at the current position in the buffer
50609a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
50709a3aaf3SDag-Erling Smørgrav * \param[in] data the 8 bits to write
50809a3aaf3SDag-Erling Smørgrav */
50909a3aaf3SDag-Erling Smørgrav INLINE void
sldns_buffer_write_u8(sldns_buffer * buffer,uint8_t data)51009a3aaf3SDag-Erling Smørgrav sldns_buffer_write_u8(sldns_buffer *buffer, uint8_t data)
51109a3aaf3SDag-Erling Smørgrav {
51209a3aaf3SDag-Erling Smørgrav sldns_buffer_write_u8_at(buffer, buffer->_position, data);
51309a3aaf3SDag-Erling Smørgrav buffer->_position += sizeof(data);
51409a3aaf3SDag-Erling Smørgrav }
51509a3aaf3SDag-Erling Smørgrav
51609a3aaf3SDag-Erling Smørgrav /**
51709a3aaf3SDag-Erling Smørgrav * writes the given 2 byte integer at the given position in the buffer
51809a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
51909a3aaf3SDag-Erling Smørgrav * \param[in] at the position in the buffer
52009a3aaf3SDag-Erling Smørgrav * \param[in] data the 16 bits to write
52109a3aaf3SDag-Erling Smørgrav */
52209a3aaf3SDag-Erling Smørgrav INLINE void
sldns_buffer_write_u16_at(sldns_buffer * buffer,size_t at,uint16_t data)52309a3aaf3SDag-Erling Smørgrav sldns_buffer_write_u16_at(sldns_buffer *buffer, size_t at, uint16_t data)
52409a3aaf3SDag-Erling Smørgrav {
52509a3aaf3SDag-Erling Smørgrav assert(sldns_buffer_available_at(buffer, at, sizeof(data)));
52609a3aaf3SDag-Erling Smørgrav sldns_write_uint16(buffer->_data + at, data);
52709a3aaf3SDag-Erling Smørgrav }
52809a3aaf3SDag-Erling Smørgrav
52909a3aaf3SDag-Erling Smørgrav /**
53009a3aaf3SDag-Erling Smørgrav * writes the given 2 byte integer at the current position in the buffer
53109a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
53209a3aaf3SDag-Erling Smørgrav * \param[in] data the 16 bits to write
53309a3aaf3SDag-Erling Smørgrav */
53409a3aaf3SDag-Erling Smørgrav INLINE void
sldns_buffer_write_u16(sldns_buffer * buffer,uint16_t data)53509a3aaf3SDag-Erling Smørgrav sldns_buffer_write_u16(sldns_buffer *buffer, uint16_t data)
53609a3aaf3SDag-Erling Smørgrav {
53709a3aaf3SDag-Erling Smørgrav sldns_buffer_write_u16_at(buffer, buffer->_position, data);
53809a3aaf3SDag-Erling Smørgrav buffer->_position += sizeof(data);
53909a3aaf3SDag-Erling Smørgrav }
54009a3aaf3SDag-Erling Smørgrav
54109a3aaf3SDag-Erling Smørgrav /**
54209a3aaf3SDag-Erling Smørgrav * writes the given 4 byte integer at the given position in the buffer
54309a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
54409a3aaf3SDag-Erling Smørgrav * \param[in] at the position in the buffer
54509a3aaf3SDag-Erling Smørgrav * \param[in] data the 32 bits to write
54609a3aaf3SDag-Erling Smørgrav */
54709a3aaf3SDag-Erling Smørgrav INLINE void
sldns_buffer_write_u32_at(sldns_buffer * buffer,size_t at,uint32_t data)54809a3aaf3SDag-Erling Smørgrav sldns_buffer_write_u32_at(sldns_buffer *buffer, size_t at, uint32_t data)
54909a3aaf3SDag-Erling Smørgrav {
55009a3aaf3SDag-Erling Smørgrav assert(sldns_buffer_available_at(buffer, at, sizeof(data)));
55109a3aaf3SDag-Erling Smørgrav sldns_write_uint32(buffer->_data + at, data);
55209a3aaf3SDag-Erling Smørgrav }
55309a3aaf3SDag-Erling Smørgrav
55409a3aaf3SDag-Erling Smørgrav /**
55565b390aaSDag-Erling Smørgrav * writes the given 6 byte integer at the given position in the buffer
55665b390aaSDag-Erling Smørgrav * \param[in] buffer the buffer
55765b390aaSDag-Erling Smørgrav * \param[in] at the position in the buffer
55865b390aaSDag-Erling Smørgrav * \param[in] data the (lower) 48 bits to write
55965b390aaSDag-Erling Smørgrav */
56065b390aaSDag-Erling Smørgrav INLINE void
sldns_buffer_write_u48_at(sldns_buffer * buffer,size_t at,uint64_t data)56165b390aaSDag-Erling Smørgrav sldns_buffer_write_u48_at(sldns_buffer *buffer, size_t at, uint64_t data)
56265b390aaSDag-Erling Smørgrav {
56365b390aaSDag-Erling Smørgrav assert(sldns_buffer_available_at(buffer, at, 6));
56465b390aaSDag-Erling Smørgrav sldns_write_uint48(buffer->_data + at, data);
56565b390aaSDag-Erling Smørgrav }
56665b390aaSDag-Erling Smørgrav
56765b390aaSDag-Erling Smørgrav /**
56809a3aaf3SDag-Erling Smørgrav * writes the given 4 byte integer at the current position in the buffer
56909a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
57009a3aaf3SDag-Erling Smørgrav * \param[in] data the 32 bits to write
57109a3aaf3SDag-Erling Smørgrav */
57209a3aaf3SDag-Erling Smørgrav INLINE void
sldns_buffer_write_u32(sldns_buffer * buffer,uint32_t data)57309a3aaf3SDag-Erling Smørgrav sldns_buffer_write_u32(sldns_buffer *buffer, uint32_t data)
57409a3aaf3SDag-Erling Smørgrav {
57509a3aaf3SDag-Erling Smørgrav sldns_buffer_write_u32_at(buffer, buffer->_position, data);
57609a3aaf3SDag-Erling Smørgrav buffer->_position += sizeof(data);
57709a3aaf3SDag-Erling Smørgrav }
57809a3aaf3SDag-Erling Smørgrav
57909a3aaf3SDag-Erling Smørgrav /**
58065b390aaSDag-Erling Smørgrav * writes the given 6 byte integer at the current position in the buffer
58165b390aaSDag-Erling Smørgrav * \param[in] buffer the buffer
58265b390aaSDag-Erling Smørgrav * \param[in] data the 48 bits to write
58365b390aaSDag-Erling Smørgrav */
58465b390aaSDag-Erling Smørgrav INLINE void
sldns_buffer_write_u48(sldns_buffer * buffer,uint64_t data)58565b390aaSDag-Erling Smørgrav sldns_buffer_write_u48(sldns_buffer *buffer, uint64_t data)
58665b390aaSDag-Erling Smørgrav {
58765b390aaSDag-Erling Smørgrav sldns_buffer_write_u48_at(buffer, buffer->_position, data);
58865b390aaSDag-Erling Smørgrav buffer->_position += 6;
58965b390aaSDag-Erling Smørgrav }
59065b390aaSDag-Erling Smørgrav
59165b390aaSDag-Erling Smørgrav /**
59209a3aaf3SDag-Erling Smørgrav * copies count bytes of data at the given position to the given data-array
59309a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
59409a3aaf3SDag-Erling Smørgrav * \param[in] at the position in the buffer to start
59509a3aaf3SDag-Erling Smørgrav * \param[out] data buffer to copy to
59609a3aaf3SDag-Erling Smørgrav * \param[in] count the length of the data to copy
59709a3aaf3SDag-Erling Smørgrav */
59809a3aaf3SDag-Erling Smørgrav INLINE void
sldns_buffer_read_at(sldns_buffer * buffer,size_t at,void * data,size_t count)59909a3aaf3SDag-Erling Smørgrav sldns_buffer_read_at(sldns_buffer *buffer, size_t at, void *data, size_t count)
60009a3aaf3SDag-Erling Smørgrav {
60109a3aaf3SDag-Erling Smørgrav assert(sldns_buffer_available_at(buffer, at, count));
60209a3aaf3SDag-Erling Smørgrav memcpy(data, buffer->_data + at, count);
60309a3aaf3SDag-Erling Smørgrav }
60409a3aaf3SDag-Erling Smørgrav
60509a3aaf3SDag-Erling Smørgrav /**
60609a3aaf3SDag-Erling Smørgrav * copies count bytes of data at the current position to the given data-array
60709a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
60809a3aaf3SDag-Erling Smørgrav * \param[out] data buffer to copy to
60909a3aaf3SDag-Erling Smørgrav * \param[in] count the length of the data to copy
61009a3aaf3SDag-Erling Smørgrav */
61109a3aaf3SDag-Erling Smørgrav INLINE void
sldns_buffer_read(sldns_buffer * buffer,void * data,size_t count)61209a3aaf3SDag-Erling Smørgrav sldns_buffer_read(sldns_buffer *buffer, void *data, size_t count)
61309a3aaf3SDag-Erling Smørgrav {
61409a3aaf3SDag-Erling Smørgrav sldns_buffer_read_at(buffer, buffer->_position, data, count);
61509a3aaf3SDag-Erling Smørgrav buffer->_position += count;
61609a3aaf3SDag-Erling Smørgrav }
61709a3aaf3SDag-Erling Smørgrav
61809a3aaf3SDag-Erling Smørgrav /**
61909a3aaf3SDag-Erling Smørgrav * returns the byte value at the given position in the buffer
62009a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
62109a3aaf3SDag-Erling Smørgrav * \param[in] at the position in the buffer
62209a3aaf3SDag-Erling Smørgrav * \return 1 byte integer
62309a3aaf3SDag-Erling Smørgrav */
62409a3aaf3SDag-Erling Smørgrav INLINE uint8_t
sldns_buffer_read_u8_at(sldns_buffer * buffer,size_t at)62509a3aaf3SDag-Erling Smørgrav sldns_buffer_read_u8_at(sldns_buffer *buffer, size_t at)
62609a3aaf3SDag-Erling Smørgrav {
62709a3aaf3SDag-Erling Smørgrav assert(sldns_buffer_available_at(buffer, at, sizeof(uint8_t)));
62809a3aaf3SDag-Erling Smørgrav return buffer->_data[at];
62909a3aaf3SDag-Erling Smørgrav }
63009a3aaf3SDag-Erling Smørgrav
63109a3aaf3SDag-Erling Smørgrav /**
63209a3aaf3SDag-Erling Smørgrav * returns the byte value at the current position in the buffer
63309a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
63409a3aaf3SDag-Erling Smørgrav * \return 1 byte integer
63509a3aaf3SDag-Erling Smørgrav */
63609a3aaf3SDag-Erling Smørgrav INLINE uint8_t
sldns_buffer_read_u8(sldns_buffer * buffer)63709a3aaf3SDag-Erling Smørgrav sldns_buffer_read_u8(sldns_buffer *buffer)
63809a3aaf3SDag-Erling Smørgrav {
63909a3aaf3SDag-Erling Smørgrav uint8_t result = sldns_buffer_read_u8_at(buffer, buffer->_position);
64009a3aaf3SDag-Erling Smørgrav buffer->_position += sizeof(uint8_t);
64109a3aaf3SDag-Erling Smørgrav return result;
64209a3aaf3SDag-Erling Smørgrav }
64309a3aaf3SDag-Erling Smørgrav
64409a3aaf3SDag-Erling Smørgrav /**
64509a3aaf3SDag-Erling Smørgrav * returns the 2-byte integer value at the given position in the buffer
64609a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
64709a3aaf3SDag-Erling Smørgrav * \param[in] at position in the buffer
64809a3aaf3SDag-Erling Smørgrav * \return 2 byte integer
64909a3aaf3SDag-Erling Smørgrav */
65009a3aaf3SDag-Erling Smørgrav INLINE uint16_t
sldns_buffer_read_u16_at(sldns_buffer * buffer,size_t at)65109a3aaf3SDag-Erling Smørgrav sldns_buffer_read_u16_at(sldns_buffer *buffer, size_t at)
65209a3aaf3SDag-Erling Smørgrav {
65309a3aaf3SDag-Erling Smørgrav assert(sldns_buffer_available_at(buffer, at, sizeof(uint16_t)));
65409a3aaf3SDag-Erling Smørgrav return sldns_read_uint16(buffer->_data + at);
65509a3aaf3SDag-Erling Smørgrav }
65609a3aaf3SDag-Erling Smørgrav
65709a3aaf3SDag-Erling Smørgrav /**
65809a3aaf3SDag-Erling Smørgrav * returns the 2-byte integer value at the current position in the buffer
65909a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
66009a3aaf3SDag-Erling Smørgrav * \return 2 byte integer
66109a3aaf3SDag-Erling Smørgrav */
66209a3aaf3SDag-Erling Smørgrav INLINE uint16_t
sldns_buffer_read_u16(sldns_buffer * buffer)66309a3aaf3SDag-Erling Smørgrav sldns_buffer_read_u16(sldns_buffer *buffer)
66409a3aaf3SDag-Erling Smørgrav {
66509a3aaf3SDag-Erling Smørgrav uint16_t result = sldns_buffer_read_u16_at(buffer, buffer->_position);
66609a3aaf3SDag-Erling Smørgrav buffer->_position += sizeof(uint16_t);
66709a3aaf3SDag-Erling Smørgrav return result;
66809a3aaf3SDag-Erling Smørgrav }
66909a3aaf3SDag-Erling Smørgrav
67009a3aaf3SDag-Erling Smørgrav /**
67109a3aaf3SDag-Erling Smørgrav * returns the 4-byte integer value at the given position in the buffer
67209a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
67309a3aaf3SDag-Erling Smørgrav * \param[in] at position in the buffer
67409a3aaf3SDag-Erling Smørgrav * \return 4 byte integer
67509a3aaf3SDag-Erling Smørgrav */
67609a3aaf3SDag-Erling Smørgrav INLINE uint32_t
sldns_buffer_read_u32_at(sldns_buffer * buffer,size_t at)67709a3aaf3SDag-Erling Smørgrav sldns_buffer_read_u32_at(sldns_buffer *buffer, size_t at)
67809a3aaf3SDag-Erling Smørgrav {
67909a3aaf3SDag-Erling Smørgrav assert(sldns_buffer_available_at(buffer, at, sizeof(uint32_t)));
68009a3aaf3SDag-Erling Smørgrav return sldns_read_uint32(buffer->_data + at);
68109a3aaf3SDag-Erling Smørgrav }
68209a3aaf3SDag-Erling Smørgrav
68309a3aaf3SDag-Erling Smørgrav /**
68409a3aaf3SDag-Erling Smørgrav * returns the 4-byte integer value at the current position in the buffer
68509a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
68609a3aaf3SDag-Erling Smørgrav * \return 4 byte integer
68709a3aaf3SDag-Erling Smørgrav */
68809a3aaf3SDag-Erling Smørgrav INLINE uint32_t
sldns_buffer_read_u32(sldns_buffer * buffer)68909a3aaf3SDag-Erling Smørgrav sldns_buffer_read_u32(sldns_buffer *buffer)
69009a3aaf3SDag-Erling Smørgrav {
69109a3aaf3SDag-Erling Smørgrav uint32_t result = sldns_buffer_read_u32_at(buffer, buffer->_position);
69209a3aaf3SDag-Erling Smørgrav buffer->_position += sizeof(uint32_t);
69309a3aaf3SDag-Erling Smørgrav return result;
69409a3aaf3SDag-Erling Smørgrav }
69509a3aaf3SDag-Erling Smørgrav
69609a3aaf3SDag-Erling Smørgrav /**
69709a3aaf3SDag-Erling Smørgrav * returns the status of the buffer
69809a3aaf3SDag-Erling Smørgrav * \param[in] buffer
69909a3aaf3SDag-Erling Smørgrav * \return the status
70009a3aaf3SDag-Erling Smørgrav */
70109a3aaf3SDag-Erling Smørgrav INLINE int
sldns_buffer_status(sldns_buffer * buffer)70209a3aaf3SDag-Erling Smørgrav sldns_buffer_status(sldns_buffer *buffer)
70309a3aaf3SDag-Erling Smørgrav {
70409a3aaf3SDag-Erling Smørgrav return (int)buffer->_status_err;
70509a3aaf3SDag-Erling Smørgrav }
70609a3aaf3SDag-Erling Smørgrav
70709a3aaf3SDag-Erling Smørgrav /**
70809a3aaf3SDag-Erling Smørgrav * returns true if the status of the buffer is LDNS_STATUS_OK, false otherwise
70909a3aaf3SDag-Erling Smørgrav * \param[in] buffer the buffer
71009a3aaf3SDag-Erling Smørgrav * \return true or false
71109a3aaf3SDag-Erling Smørgrav */
71209a3aaf3SDag-Erling Smørgrav INLINE int
sldns_buffer_status_ok(sldns_buffer * buffer)71309a3aaf3SDag-Erling Smørgrav sldns_buffer_status_ok(sldns_buffer *buffer)
71409a3aaf3SDag-Erling Smørgrav {
71509a3aaf3SDag-Erling Smørgrav if (buffer) {
71609a3aaf3SDag-Erling Smørgrav return sldns_buffer_status(buffer) == 0;
71709a3aaf3SDag-Erling Smørgrav } else {
71809a3aaf3SDag-Erling Smørgrav return 0;
71909a3aaf3SDag-Erling Smørgrav }
72009a3aaf3SDag-Erling Smørgrav }
72109a3aaf3SDag-Erling Smørgrav
72209a3aaf3SDag-Erling Smørgrav /**
72309a3aaf3SDag-Erling Smørgrav * prints to the buffer, increasing the capacity if required using
72409a3aaf3SDag-Erling Smørgrav * buffer_reserve(). The buffer's position is set to the terminating '\\0'
72509a3aaf3SDag-Erling Smørgrav * Returns the number of characters written (not including the
72609a3aaf3SDag-Erling Smørgrav * terminating '\\0') or -1 on failure.
72709a3aaf3SDag-Erling Smørgrav */
72809a3aaf3SDag-Erling Smørgrav int sldns_buffer_printf(sldns_buffer *buffer, const char *format, ...)
72909a3aaf3SDag-Erling Smørgrav ATTR_FORMAT(printf, 2, 3);
73009a3aaf3SDag-Erling Smørgrav
73109a3aaf3SDag-Erling Smørgrav /**
73209a3aaf3SDag-Erling Smørgrav * frees the buffer.
73309a3aaf3SDag-Erling Smørgrav * \param[in] *buffer the buffer to be freed
73409a3aaf3SDag-Erling Smørgrav */
73509a3aaf3SDag-Erling Smørgrav void sldns_buffer_free(sldns_buffer *buffer);
73609a3aaf3SDag-Erling Smørgrav
73709a3aaf3SDag-Erling Smørgrav /**
73809a3aaf3SDag-Erling Smørgrav * Copy contents of the from buffer to the result buffer and then flips
73909a3aaf3SDag-Erling Smørgrav * the result buffer. Data will be silently truncated if the result buffer is
74009a3aaf3SDag-Erling Smørgrav * too small.
74109a3aaf3SDag-Erling Smørgrav * \param[out] *result resulting buffer which is copied to.
74209a3aaf3SDag-Erling Smørgrav * \param[in] *from what to copy to result.
74309a3aaf3SDag-Erling Smørgrav */
74409a3aaf3SDag-Erling Smørgrav void sldns_buffer_copy(sldns_buffer* result, sldns_buffer* from);
74509a3aaf3SDag-Erling Smørgrav
74609a3aaf3SDag-Erling Smørgrav #ifdef __cplusplus
74709a3aaf3SDag-Erling Smørgrav }
74809a3aaf3SDag-Erling Smørgrav #endif
74909a3aaf3SDag-Erling Smørgrav
75009a3aaf3SDag-Erling Smørgrav #endif /* LDNS_SBUFFER_H */
751