2 * buffer.h -- generic memory buffer.
4 * Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
6 * See LICENSE for the license.
9 * The buffer module implements a generic buffer. The API is based on
10 * the java.nio.Buffer interface.
20 #include <ldns/error.h>
21 #include <ldns/common.h>
23 #include "ldns/util.h"
26 * number of initial bytes in buffer of
27 * which we cannot tell the size before hand
29 #define LDNS_MIN_BUFLEN 512
34 * This file contains the definition of ldns_buffer, and functions to manipulate those.
38 * implementation of buffers to ease operations
40 * ldns_buffers can contain arbitrary information, per octet. You can write
41 * to the current end of a buffer, read from the current position, and
42 * access any data within it.
44 * Example use of buffers is in the source code of \ref host2str.c
46 struct ldns_struct_buffer
48 /** The current position used for reading/writing */
51 /** The read/write limit */
54 /** The amount of data the buffer can contain */
57 /** The data contained in the buffer */
60 /** If the buffer is fixed it cannot be resized */
63 /** The current state of the buffer. If writing to the buffer fails
64 * for any reason, this value is changed. This way, you can perform
65 * multiple writes in sequence and check for success afterwards. */
68 typedef struct ldns_struct_buffer ldns_buffer;
73 ldns_buffer_invariant(ldns_buffer *ATTR_UNUSED(buffer))
78 ldns_buffer_invariant(ldns_buffer *buffer)
80 assert(buffer != NULL);
81 assert(buffer->_position <= buffer->_limit);
82 assert(buffer->_limit <= buffer->_capacity);
83 assert(buffer->_data != NULL);
88 * creates a new buffer with the specified capacity.
90 * \param[in] capacity the size (in bytes) to allocate for the buffer
91 * \return the created buffer
93 ldns_buffer *ldns_buffer_new(size_t capacity);
96 * creates a buffer with the specified data. The data IS copied
97 * and MEMORY allocations are done. The buffer is not fixed and can
98 * be resized using buffer_reserve().
100 * \param[in] buffer pointer to the buffer to put the data in
101 * \param[in] data the data to encapsulate in the buffer
102 * \param[in] size the size of the data
104 void ldns_buffer_new_frm_data(ldns_buffer *buffer, void *data, size_t size);
107 * clears the buffer and make it ready for writing. The buffer's limit
108 * is set to the capacity and the position is set to 0.
109 * \param[in] buffer the buffer to clear
111 INLINE void ldns_buffer_clear(ldns_buffer *buffer)
113 ldns_buffer_invariant(buffer);
115 /* reset status here? */
117 buffer->_position = 0;
118 buffer->_limit = buffer->_capacity;
122 * makes the buffer ready for reading the data that has been written to
123 * the buffer. The buffer's limit is set to the current position and
124 * the position is set to 0.
126 * \param[in] buffer the buffer to flip
129 INLINE void ldns_buffer_flip(ldns_buffer *buffer)
131 ldns_buffer_invariant(buffer);
133 buffer->_limit = buffer->_position;
134 buffer->_position = 0;
138 * make the buffer ready for re-reading the data. The buffer's
139 * position is reset to 0.
140 * \param[in] buffer the buffer to rewind
142 INLINE void ldns_buffer_rewind(ldns_buffer *buffer)
144 ldns_buffer_invariant(buffer);
146 buffer->_position = 0;
150 * returns the current position in the buffer (as a number of bytes)
151 * \param[in] buffer the buffer
152 * \return the current position
155 ldns_buffer_position(ldns_buffer *buffer)
157 return buffer->_position;
161 * sets the buffer's position to MARK. The position must be less than
162 * or equal to the buffer's limit.
163 * \param[in] buffer the buffer
164 * \param[in] mark the mark to use
167 ldns_buffer_set_position(ldns_buffer *buffer, size_t mark)
169 assert(mark <= buffer->_limit);
170 buffer->_position = mark;
174 * changes the buffer's position by COUNT bytes. The position must not
175 * be moved behind the buffer's limit or before the beginning of the
177 * \param[in] buffer the buffer
178 * \param[in] count the count to use
181 ldns_buffer_skip(ldns_buffer *buffer, ssize_t count)
183 assert(buffer->_position + count <= buffer->_limit);
184 buffer->_position += count;
188 * returns the maximum size of the buffer
193 ldns_buffer_limit(ldns_buffer *buffer)
195 return buffer->_limit;
199 * changes the buffer's limit. If the buffer's position is greater
200 * than the new limit the position is set to the limit.
201 * \param[in] buffer the buffer
202 * \param[in] limit the new limit
205 ldns_buffer_set_limit(ldns_buffer *buffer, size_t limit)
207 assert(limit <= buffer->_capacity);
208 buffer->_limit = limit;
209 if (buffer->_position > buffer->_limit)
210 buffer->_position = buffer->_limit;
214 * returns the number of bytes the buffer can hold.
215 * \param[in] buffer the buffer
216 * \return the number of bytes
219 ldns_buffer_capacity(ldns_buffer *buffer)
221 return buffer->_capacity;
225 * changes the buffer's capacity. The data is reallocated so any
226 * pointers to the data may become invalid. The buffer's limit is set
227 * to the buffer's new capacity.
228 * \param[in] buffer the buffer
229 * \param[in] capacity the capacity to use
230 * \return whether this failed or succeeded
232 bool ldns_buffer_set_capacity(ldns_buffer *buffer, size_t capacity);
235 * ensures BUFFER can contain at least AMOUNT more bytes. The buffer's
236 * capacity is increased if necessary using buffer_set_capacity().
238 * The buffer's limit is always set to the (possibly increased)
240 * \param[in] buffer the buffer
241 * \param[in] amount amount to use
242 * \return whether this failed or succeeded
244 bool ldns_buffer_reserve(ldns_buffer *buffer, size_t amount);
247 * returns a pointer to the data at the indicated position.
248 * \param[in] buffer the buffer
249 * \param[in] at position
250 * \return the pointer to the data
253 ldns_buffer_at(const ldns_buffer *buffer, size_t at)
255 assert(at <= buffer->_limit);
256 return buffer->_data + at;
260 * returns a pointer to the beginning of the buffer (the data at
262 * \param[in] buffer the buffer
263 * \return the pointer
266 ldns_buffer_begin(const ldns_buffer *buffer)
268 return ldns_buffer_at(buffer, 0);
272 * returns a pointer to the end of the buffer (the data at the buffer's
274 * \param[in] buffer the buffer
275 * \return the pointer
278 ldns_buffer_end(ldns_buffer *buffer)
280 return ldns_buffer_at(buffer, buffer->_limit);
284 * returns a pointer to the data at the buffer's current position.
285 * \param[in] buffer the buffer
286 * \return the pointer
289 ldns_buffer_current(ldns_buffer *buffer)
291 return ldns_buffer_at(buffer, buffer->_position);
295 * returns the number of bytes remaining between the indicated position and
297 * \param[in] buffer the buffer
298 * \param[in] at indicated position
299 * \return number of bytes
302 ldns_buffer_remaining_at(ldns_buffer *buffer, size_t at)
304 ldns_buffer_invariant(buffer);
305 assert(at <= buffer->_limit);
306 return buffer->_limit - at;
310 * returns the number of bytes remaining between the buffer's position and
312 * \param[in] buffer the buffer
313 * \return the number of bytes
316 ldns_buffer_remaining(ldns_buffer *buffer)
318 return ldns_buffer_remaining_at(buffer, buffer->_position);
322 * checks if the buffer has at least COUNT more bytes available.
323 * Before reading or writing the caller needs to ensure enough space
325 * \param[in] buffer the buffer
326 * \param[in] at indicated position
327 * \param[in] count how much is available
328 * \return true or false (as int?)
331 ldns_buffer_available_at(ldns_buffer *buffer, size_t at, size_t count)
333 return count <= ldns_buffer_remaining_at(buffer, at);
337 * checks if the buffer has count bytes available at the current position
338 * \param[in] buffer the buffer
339 * \param[in] count how much is available
340 * \return true or false (as int?)
343 ldns_buffer_available(ldns_buffer *buffer, size_t count)
345 return ldns_buffer_available_at(buffer, buffer->_position, count);
349 * writes the given data to the buffer at the specified position
350 * \param[in] buffer the buffer
351 * \param[in] at the position (in number of bytes) to write the data at
352 * \param[in] data pointer to the data to write to the buffer
353 * \param[in] count the number of bytes of data to write
356 ldns_buffer_write_at(ldns_buffer *buffer, size_t at, const void *data, size_t count)
358 assert(ldns_buffer_available_at(buffer, at, count));
359 memcpy(buffer->_data + at, data, count);
363 * writes count bytes of data to the current position of the buffer
364 * \param[in] buffer the buffer
365 * \param[in] data the data to write
366 * \param[in] count the lenght of the data to write
369 ldns_buffer_write(ldns_buffer *buffer, const void *data, size_t count)
371 ldns_buffer_write_at(buffer, buffer->_position, data, count);
372 buffer->_position += count;
376 * copies the given (null-delimited) string to the specified position at the buffer
377 * \param[in] buffer the buffer
378 * \param[in] at the position in the buffer
379 * \param[in] str the string to write
382 ldns_buffer_write_string_at(ldns_buffer *buffer, size_t at, const char *str)
384 ldns_buffer_write_at(buffer, at, str, strlen(str));
388 * copies the given (null-delimited) string to the current position at the buffer
389 * \param[in] buffer the buffer
390 * \param[in] str the string to write
393 ldns_buffer_write_string(ldns_buffer *buffer, const char *str)
395 ldns_buffer_write(buffer, str, strlen(str));
399 * writes the given byte of data at the given position in the buffer
400 * \param[in] buffer the buffer
401 * \param[in] at the position in the buffer
402 * \param[in] data the 8 bits to write
405 ldns_buffer_write_u8_at(ldns_buffer *buffer, size_t at, uint8_t data)
407 assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
408 buffer->_data[at] = data;
412 * writes the given byte of data at the current position in the buffer
413 * \param[in] buffer the buffer
414 * \param[in] data the 8 bits to write
417 ldns_buffer_write_u8(ldns_buffer *buffer, uint8_t data)
419 ldns_buffer_write_u8_at(buffer, buffer->_position, data);
420 buffer->_position += sizeof(data);
424 * writes the given 2 byte integer at the given position in the buffer
425 * \param[in] buffer the buffer
426 * \param[in] at the position in the buffer
427 * \param[in] data the 16 bits to write
430 ldns_buffer_write_u16_at(ldns_buffer *buffer, size_t at, uint16_t data)
432 assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
433 ldns_write_uint16(buffer->_data + at, data);
437 * writes the given 2 byte integer at the current position in the buffer
438 * \param[in] buffer the buffer
439 * \param[in] data the 16 bits to write
442 ldns_buffer_write_u16(ldns_buffer *buffer, uint16_t data)
444 ldns_buffer_write_u16_at(buffer, buffer->_position, data);
445 buffer->_position += sizeof(data);
449 * writes the given 4 byte integer at the given position in the buffer
450 * \param[in] buffer the buffer
451 * \param[in] at the position in the buffer
452 * \param[in] data the 32 bits to write
455 ldns_buffer_write_u32_at(ldns_buffer *buffer, size_t at, uint32_t data)
457 assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
458 ldns_write_uint32(buffer->_data + at, data);
462 * writes the given 4 byte integer at the current position in the buffer
463 * \param[in] buffer the buffer
464 * \param[in] data the 32 bits to write
467 ldns_buffer_write_u32(ldns_buffer *buffer, uint32_t data)
469 ldns_buffer_write_u32_at(buffer, buffer->_position, data);
470 buffer->_position += sizeof(data);
474 * copies count bytes of data at the given position to the given data-array
475 * \param[in] buffer the buffer
476 * \param[in] at the position in the buffer to start
477 * \param[out] data buffer to copy to
478 * \param[in] count the length of the data to copy
481 ldns_buffer_read_at(ldns_buffer *buffer, size_t at, void *data, size_t count)
483 assert(ldns_buffer_available_at(buffer, at, count));
484 memcpy(data, buffer->_data + at, count);
488 * copies count bytes of data at the current position to the given data-array
489 * \param[in] buffer the buffer
490 * \param[out] data buffer to copy to
491 * \param[in] count the length of the data to copy
494 ldns_buffer_read(ldns_buffer *buffer, void *data, size_t count)
496 ldns_buffer_read_at(buffer, buffer->_position, data, count);
497 buffer->_position += count;
501 * returns the byte value at the given position in the buffer
502 * \param[in] buffer the buffer
503 * \param[in] at the position in the buffer
504 * \return 1 byte integer
507 ldns_buffer_read_u8_at(ldns_buffer *buffer, size_t at)
509 assert(ldns_buffer_available_at(buffer, at, sizeof(uint8_t)));
510 return buffer->_data[at];
514 * returns the byte value at the current position in the buffer
515 * \param[in] buffer the buffer
516 * \return 1 byte integer
519 ldns_buffer_read_u8(ldns_buffer *buffer)
521 uint8_t result = ldns_buffer_read_u8_at(buffer, buffer->_position);
522 buffer->_position += sizeof(uint8_t);
527 * returns the 2-byte integer value at the given position in the buffer
528 * \param[in] buffer the buffer
529 * \param[in] at position in the buffer
530 * \return 2 byte integer
533 ldns_buffer_read_u16_at(ldns_buffer *buffer, size_t at)
535 assert(ldns_buffer_available_at(buffer, at, sizeof(uint16_t)));
536 return ldns_read_uint16(buffer->_data + at);
540 * returns the 2-byte integer value at the current position in the buffer
541 * \param[in] buffer the buffer
542 * \return 2 byte integer
545 ldns_buffer_read_u16(ldns_buffer *buffer)
547 uint16_t result = ldns_buffer_read_u16_at(buffer, buffer->_position);
548 buffer->_position += sizeof(uint16_t);
553 * returns the 4-byte integer value at the given position in the buffer
554 * \param[in] buffer the buffer
555 * \param[in] at position in the buffer
556 * \return 4 byte integer
559 ldns_buffer_read_u32_at(ldns_buffer *buffer, size_t at)
561 assert(ldns_buffer_available_at(buffer, at, sizeof(uint32_t)));
562 return ldns_read_uint32(buffer->_data + at);
566 * returns the 4-byte integer value at the current position in the buffer
567 * \param[in] buffer the buffer
568 * \return 4 byte integer
571 ldns_buffer_read_u32(ldns_buffer *buffer)
573 uint32_t result = ldns_buffer_read_u32_at(buffer, buffer->_position);
574 buffer->_position += sizeof(uint32_t);
579 * returns the status of the buffer
584 ldns_buffer_status(ldns_buffer *buffer)
586 return buffer->_status;
590 * returns true if the status of the buffer is LDNS_STATUS_OK, false otherwise
591 * \param[in] buffer the buffer
592 * \return true or false
595 ldns_buffer_status_ok(ldns_buffer *buffer)
598 return ldns_buffer_status(buffer) == LDNS_STATUS_OK;
605 * prints to the buffer, increasing the capacity if required using
606 * buffer_reserve(). The buffer's position is set to the terminating
607 * '\\0'. Returns the number of characters written (not including the
608 * terminating '\\0') or -1 on failure.
610 int ldns_buffer_printf(ldns_buffer *buffer, const char *format, ...);
611 /* ATTR_FORMAT(printf, 2, 3);*/
615 * \param[in] *buffer the buffer to be freed
618 void ldns_buffer_free(ldns_buffer *buffer);
621 * Makes the buffer fixed and returns a pointer to the data. The
622 * caller is responsible for free'ing the result.
623 * \param[in] *buffer the buffer to be exported
626 void *ldns_buffer_export(ldns_buffer *buffer);
629 * Copy contents of the other buffer to this buffer. Silently truncated
630 * if this buffer is too small.
631 * \param[out] *result resulting buffer which is copied to.
632 * \param[in] *from what to copy to result.
634 void ldns_buffer_copy(ldns_buffer* result, ldns_buffer* from);
636 #endif /* LDNS_BUFFER_H */