Initial vendor import of ldns-1.6.4 into contrib.
[dragonfly.git] / contrib / ldns / ldns / buffer.h
1 /*
2  * buffer.h -- generic memory buffer.
3  *
4  * Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
5  *
6  * See LICENSE for the license.
7  *
8  *
9  * The buffer module implements a generic buffer.  The API is based on
10  * the java.nio.Buffer interface.
11  */
12
13 #ifndef LDNS_BUFFER_H
14 #define LDNS_BUFFER_H
15
16 #include <assert.h>
17 #include <stdarg.h>
18 #include <string.h>
19
20 #include <ldns/error.h>
21 #include <ldns/common.h>
22
23 #include "ldns/util.h"
24
25 /**
26  * number of initial bytes in buffer of
27  * which we cannot tell the size before hand
28  */
29 #define LDNS_MIN_BUFLEN 512
30
31 /**
32  * \file buffer.h
33  *
34  * This file contains the definition of ldns_buffer, and functions to manipulate those.
35  */
36
37 /** 
38  * implementation of buffers to ease operations
39  *
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.
43  *
44  * Example use of buffers is in the source code of \ref host2str.c
45  */
46 struct ldns_struct_buffer
47 {
48         /** The current position used for reading/writing */ 
49         size_t   _position;
50
51         /** The read/write limit */
52         size_t   _limit;
53
54         /** The amount of data the buffer can contain */
55         size_t   _capacity;
56
57         /** The data contained in the buffer */
58         uint8_t *_data;
59
60         /** If the buffer is fixed it cannot be resized */
61         unsigned _fixed : 1;
62
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. */
66         ldns_status _status;
67 };
68 typedef struct ldns_struct_buffer ldns_buffer;
69
70
71 #ifdef NDEBUG
72 INLINE void
73 ldns_buffer_invariant(ldns_buffer *ATTR_UNUSED(buffer))
74 {
75 }
76 #else
77 INLINE void
78 ldns_buffer_invariant(ldns_buffer *buffer)
79 {
80         assert(buffer != NULL);
81         assert(buffer->_position <= buffer->_limit);
82         assert(buffer->_limit <= buffer->_capacity);
83         assert(buffer->_data != NULL);
84 }
85 #endif
86
87 /**
88  * creates a new buffer with the specified capacity.
89  *
90  * \param[in] capacity the size (in bytes) to allocate for the buffer
91  * \return the created buffer
92  */
93 ldns_buffer *ldns_buffer_new(size_t capacity);
94
95 /**
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().
99  *
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
103  */
104 void ldns_buffer_new_frm_data(ldns_buffer *buffer, void *data, size_t size);
105
106 /**
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
110  */
111 INLINE void ldns_buffer_clear(ldns_buffer *buffer)
112 {
113         ldns_buffer_invariant(buffer);
114
115         /* reset status here? */
116
117         buffer->_position = 0;
118         buffer->_limit = buffer->_capacity;
119 }
120
121 /**
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.
125  *
126  * \param[in] buffer the buffer to flip
127  * \return void
128  */
129 INLINE void ldns_buffer_flip(ldns_buffer *buffer)
130 {
131         ldns_buffer_invariant(buffer);
132
133         buffer->_limit = buffer->_position;
134         buffer->_position = 0;
135 }
136
137 /**
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
141  */
142 INLINE void ldns_buffer_rewind(ldns_buffer *buffer)
143 {
144         ldns_buffer_invariant(buffer);
145
146         buffer->_position = 0;
147 }
148
149 /**
150  * returns the current position in the buffer (as a number of bytes)
151  * \param[in] buffer the buffer
152  * \return the current position
153  */
154 INLINE size_t
155 ldns_buffer_position(ldns_buffer *buffer)
156 {
157         return buffer->_position;
158 }
159
160 /**
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
165  */
166 INLINE void
167 ldns_buffer_set_position(ldns_buffer *buffer, size_t mark)
168 {
169         assert(mark <= buffer->_limit);
170         buffer->_position = mark;
171 }
172
173 /**
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
176  * buffer.
177  * \param[in] buffer the buffer
178  * \param[in] count the count to use
179  */
180 INLINE void
181 ldns_buffer_skip(ldns_buffer *buffer, ssize_t count)
182 {
183         assert(buffer->_position + count <= buffer->_limit);
184         buffer->_position += count;
185 }
186
187 /**
188  * returns the maximum size of the buffer
189  * \param[in] buffer
190  * \return the size
191  */
192 INLINE size_t
193 ldns_buffer_limit(ldns_buffer *buffer)
194 {
195         return buffer->_limit;
196 }
197
198 /**
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
203  */
204 INLINE void
205 ldns_buffer_set_limit(ldns_buffer *buffer, size_t limit)
206 {
207         assert(limit <= buffer->_capacity);
208         buffer->_limit = limit;
209         if (buffer->_position > buffer->_limit)
210                 buffer->_position = buffer->_limit;
211 }
212
213 /**
214  * returns the number of bytes the buffer can hold.
215  * \param[in] buffer the buffer
216  * \return the number of bytes
217  */
218 INLINE size_t
219 ldns_buffer_capacity(ldns_buffer *buffer)
220 {
221         return buffer->_capacity;
222 }
223
224 /**
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
231  */
232 bool ldns_buffer_set_capacity(ldns_buffer *buffer, size_t capacity);
233
234 /**
235  * ensures BUFFER can contain at least AMOUNT more bytes.  The buffer's
236  * capacity is increased if necessary using buffer_set_capacity().
237  *
238  * The buffer's limit is always set to the (possibly increased)
239  * capacity.
240  * \param[in] buffer the buffer
241  * \param[in] amount amount to use
242  * \return whether this failed or succeeded
243  */
244 bool ldns_buffer_reserve(ldns_buffer *buffer, size_t amount);
245
246 /**
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
251  */
252 INLINE uint8_t *
253 ldns_buffer_at(const ldns_buffer *buffer, size_t at)
254 {
255         assert(at <= buffer->_limit);
256         return buffer->_data + at;
257 }
258
259 /**
260  * returns a pointer to the beginning of the buffer (the data at
261  * position 0).
262  * \param[in] buffer the buffer
263  * \return the pointer
264  */
265 INLINE uint8_t *
266 ldns_buffer_begin(const ldns_buffer *buffer)
267 {
268         return ldns_buffer_at(buffer, 0);
269 }
270
271 /**
272  * returns a pointer to the end of the buffer (the data at the buffer's
273  * limit).
274  * \param[in] buffer the buffer
275  * \return the pointer
276  */
277 INLINE uint8_t *
278 ldns_buffer_end(ldns_buffer *buffer)
279 {
280         return ldns_buffer_at(buffer, buffer->_limit);
281 }
282
283 /**
284  * returns a pointer to the data at the buffer's current position.
285  * \param[in] buffer the buffer
286  * \return the pointer
287  */
288 INLINE uint8_t *
289 ldns_buffer_current(ldns_buffer *buffer)
290 {
291         return ldns_buffer_at(buffer, buffer->_position);
292 }
293
294 /**
295  * returns the number of bytes remaining between the indicated position and
296  * the limit.
297  * \param[in] buffer the buffer
298  * \param[in] at indicated position
299  * \return number of bytes
300  */
301 INLINE size_t
302 ldns_buffer_remaining_at(ldns_buffer *buffer, size_t at)
303 {
304         ldns_buffer_invariant(buffer);
305         assert(at <= buffer->_limit);
306         return buffer->_limit - at;
307 }
308
309 /**
310  * returns the number of bytes remaining between the buffer's position and
311  * limit.
312  * \param[in] buffer the buffer
313  * \return the number of bytes
314  */
315 INLINE size_t
316 ldns_buffer_remaining(ldns_buffer *buffer)
317 {
318         return ldns_buffer_remaining_at(buffer, buffer->_position);
319 }
320
321 /**
322  * checks if the buffer has at least COUNT more bytes available.
323  * Before reading or writing the caller needs to ensure enough space
324  * is available!
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?)
329  */
330 INLINE int
331 ldns_buffer_available_at(ldns_buffer *buffer, size_t at, size_t count)
332 {
333         return count <= ldns_buffer_remaining_at(buffer, at);
334 }
335
336 /**
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?)
341  */
342 INLINE int
343 ldns_buffer_available(ldns_buffer *buffer, size_t count)
344 {
345         return ldns_buffer_available_at(buffer, buffer->_position, count);
346 }
347
348 /**
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
354  */
355 INLINE void
356 ldns_buffer_write_at(ldns_buffer *buffer, size_t at, const void *data, size_t count)
357 {
358         assert(ldns_buffer_available_at(buffer, at, count));
359         memcpy(buffer->_data + at, data, count);
360 }
361
362 /**
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
367  */
368 INLINE void
369 ldns_buffer_write(ldns_buffer *buffer, const void *data, size_t count)
370 {
371         ldns_buffer_write_at(buffer, buffer->_position, data, count);
372         buffer->_position += count;
373 }
374
375 /**
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
380  */
381 INLINE void
382 ldns_buffer_write_string_at(ldns_buffer *buffer, size_t at, const char *str)
383 {
384         ldns_buffer_write_at(buffer, at, str, strlen(str));
385 }
386
387 /**
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
391  */
392 INLINE void
393 ldns_buffer_write_string(ldns_buffer *buffer, const char *str)
394 {
395         ldns_buffer_write(buffer, str, strlen(str));
396 }
397
398 /**
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
403  */
404 INLINE void
405 ldns_buffer_write_u8_at(ldns_buffer *buffer, size_t at, uint8_t data)
406 {
407         assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
408         buffer->_data[at] = data;
409 }
410
411 /**
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
415  */
416 INLINE void
417 ldns_buffer_write_u8(ldns_buffer *buffer, uint8_t data)
418 {
419         ldns_buffer_write_u8_at(buffer, buffer->_position, data);
420         buffer->_position += sizeof(data);
421 }
422
423 /**
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
428  */
429 INLINE void
430 ldns_buffer_write_u16_at(ldns_buffer *buffer, size_t at, uint16_t data)
431 {
432         assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
433         ldns_write_uint16(buffer->_data + at, data);
434 }
435
436 /**
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
440  */
441 INLINE void
442 ldns_buffer_write_u16(ldns_buffer *buffer, uint16_t data)
443 {
444         ldns_buffer_write_u16_at(buffer, buffer->_position, data);
445         buffer->_position += sizeof(data);
446 }
447
448 /**
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
453  */
454 INLINE void
455 ldns_buffer_write_u32_at(ldns_buffer *buffer, size_t at, uint32_t data)
456 {
457         assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
458         ldns_write_uint32(buffer->_data + at, data);
459 }
460
461 /**
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
465  */
466 INLINE void
467 ldns_buffer_write_u32(ldns_buffer *buffer, uint32_t data)
468 {
469         ldns_buffer_write_u32_at(buffer, buffer->_position, data);
470         buffer->_position += sizeof(data);
471 }
472
473 /**
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
479  */
480 INLINE void
481 ldns_buffer_read_at(ldns_buffer *buffer, size_t at, void *data, size_t count)
482 {
483         assert(ldns_buffer_available_at(buffer, at, count));
484         memcpy(data, buffer->_data + at, count);
485 }
486
487 /**
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
492  */
493 INLINE void
494 ldns_buffer_read(ldns_buffer *buffer, void *data, size_t count)
495 {
496         ldns_buffer_read_at(buffer, buffer->_position, data, count);
497         buffer->_position += count;
498 }
499
500 /**
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
505  */
506 INLINE uint8_t
507 ldns_buffer_read_u8_at(ldns_buffer *buffer, size_t at)
508 {
509         assert(ldns_buffer_available_at(buffer, at, sizeof(uint8_t)));
510         return buffer->_data[at];
511 }
512
513 /**
514  * returns the byte value at the current position in the buffer
515  * \param[in] buffer the buffer
516  * \return 1 byte integer
517  */
518 INLINE uint8_t
519 ldns_buffer_read_u8(ldns_buffer *buffer)
520 {
521         uint8_t result = ldns_buffer_read_u8_at(buffer, buffer->_position);
522         buffer->_position += sizeof(uint8_t);
523         return result;
524 }
525
526 /**
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
531  */
532 INLINE uint16_t
533 ldns_buffer_read_u16_at(ldns_buffer *buffer, size_t at)
534 {
535         assert(ldns_buffer_available_at(buffer, at, sizeof(uint16_t)));
536         return ldns_read_uint16(buffer->_data + at);
537 }
538
539 /**
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
543  */
544 INLINE uint16_t
545 ldns_buffer_read_u16(ldns_buffer *buffer)
546 {
547         uint16_t result = ldns_buffer_read_u16_at(buffer, buffer->_position);
548         buffer->_position += sizeof(uint16_t);
549         return result;
550 }
551
552 /**
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
557  */
558 INLINE uint32_t
559 ldns_buffer_read_u32_at(ldns_buffer *buffer, size_t at)
560 {
561         assert(ldns_buffer_available_at(buffer, at, sizeof(uint32_t)));
562         return ldns_read_uint32(buffer->_data + at);
563 }
564
565 /**
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
569  */
570 INLINE uint32_t
571 ldns_buffer_read_u32(ldns_buffer *buffer)
572 {
573         uint32_t result = ldns_buffer_read_u32_at(buffer, buffer->_position);
574         buffer->_position += sizeof(uint32_t);
575         return result;
576 }
577
578 /**
579  * returns the status of the buffer
580  * \param[in] buffer
581  * \return the status
582  */
583 INLINE ldns_status
584 ldns_buffer_status(ldns_buffer *buffer)
585 {
586         return buffer->_status;
587 }
588
589 /**
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
593  */
594 INLINE bool
595 ldns_buffer_status_ok(ldns_buffer *buffer)
596 {
597         if (buffer) {
598                 return ldns_buffer_status(buffer) == LDNS_STATUS_OK;
599         } else {
600                 return false;
601         }
602 }
603
604 /**
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.
609  */
610 int ldns_buffer_printf(ldns_buffer *buffer, const char *format, ...);
611 /*      ATTR_FORMAT(printf, 2, 3);*/
612
613 /**
614  * frees the buffer.
615  * \param[in] *buffer the buffer to be freed
616  * \return void
617  */
618 void ldns_buffer_free(ldns_buffer *buffer);
619
620 /**
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
624  * \return void
625  */
626 void *ldns_buffer_export(ldns_buffer *buffer);
627
628 /**
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.
633  */
634 void ldns_buffer_copy(ldns_buffer* result, ldns_buffer* from);
635
636 #endif /* LDNS_BUFFER_H */