1 /*	$NetBSD: buffer.h,v 1.8 2023/01/25 21:43:31 christos Exp $	*/
2 
3 /*
4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5  *
6  * SPDX-License-Identifier: MPL-2.0
7  *
8  * This Source Code Form is subject to the terms of the Mozilla Public
9  * License, v. 2.0. If a copy of the MPL was not distributed with this
10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11  *
12  * See the COPYRIGHT file distributed with this work for additional
13  * information regarding copyright ownership.
14  */
15 
16 #ifndef ISC_BUFFER_H
17 #define ISC_BUFFER_H 1
18 
19 /*****
20 ***** Module Info
21 *****/
22 
23 /*! \file isc/buffer.h
24  *
25  * \brief A buffer is a region of memory, together with a set of related
26  * subregions. Buffers are used for parsing and I/O operations.
27  *
28  * The 'used region' and the 'available region' are disjoint, and their
29  * union is the buffer's region.  The used region extends from the beginning
30  * of the buffer region to the last used byte.  The available region
31  * extends from one byte greater than the last used byte to the end of the
32  * buffer's region.  The size of the used region can be changed using various
33  * buffer commands.  Initially, the used region is empty.
34  *
35  * The used region is further subdivided into two disjoint regions: the
36  * 'consumed region' and the 'remaining region'.  The union of these two
37  * regions is the used region.  The consumed region extends from the beginning
38  * of the used region to the byte before the 'current' offset (if any).  The
39  * 'remaining' region extends from the current offset to the end of the used
40  * region.  The size of the consumed region can be changed using various
41  * buffer commands.  Initially, the consumed region is empty.
42  *
43  * The 'active region' is an (optional) subregion of the remaining region.
44  * It extends from the current offset to an offset in the remaining region
45  * that is selected with isc_buffer_setactive().  Initially, the active region
46  * is empty.  If the current offset advances beyond the chosen offset, the
47  * active region will also be empty.
48  *
49  * \verbatim
50  *  /------------entire length---------------\
51  *  /----- used region -----\/-- available --\
52  *  +----------------------------------------+
53  *  | consumed  | remaining |                |
54  *  +----------------------------------------+
55  *  a           b     c     d                e
56  *
57  * a == base of buffer.
58  * b == current pointer.  Can be anywhere between a and d.
59  * c == active pointer.  Meaningful between b and d.
60  * d == used pointer.
61  * e == length of buffer.
62  *
63  * a-e == entire length of buffer.
64  * a-d == used region.
65  * a-b == consumed region.
66  * b-d == remaining region.
67  * b-c == optional active region.
68  *\endverbatim
69  *
70  * The following invariants are maintained by all routines:
71  *
72  *\code
73  *	length > 0
74  *
75  *	base is a valid pointer to length bytes of memory
76  *
77  *	0 <= used <= length
78  *
79  *	0 <= current <= used
80  *
81  *	0 <= active <= used
82  *	(although active < current implies empty active region)
83  *\endcode
84  *
85  * \li MP:
86  *	Buffers have no synchronization.  Clients must ensure exclusive
87  *	access.
88  *
89  * \li Reliability:
90  *	No anticipated impact.
91  *
92  * \li Resources:
93  *	Memory: 1 pointer + 6 unsigned integers per buffer.
94  *
95  * \li Security:
96  *	No anticipated impact.
97  *
98  * \li Standards:
99  *	None.
100  */
101 
102 /***
103  *** Imports
104  ***/
105 
106 #include <inttypes.h>
107 #include <stdbool.h>
108 
109 #include <isc/assertions.h>
110 #include <isc/formatcheck.h>
111 #include <isc/lang.h>
112 #include <isc/likely.h>
113 #include <isc/list.h>
114 #include <isc/magic.h>
115 #include <isc/types.h>
116 
117 /*!
118  * To make many functions be inline macros (via \#define) define this.
119  * If it is undefined, a function will be used.
120  */
121 /* #define ISC_BUFFER_USEINLINE */
122 
123 ISC_LANG_BEGINDECLS
124 
125 /*@{*/
126 /*!
127  *** Magic numbers
128  ***/
129 #define ISC_BUFFER_MAGIC    0x42756621U /* Buf!. */
130 #define ISC_BUFFER_VALID(b) ISC_MAGIC_VALID(b, ISC_BUFFER_MAGIC)
131 /*@}*/
132 
133 /*!
134  * Size granularity for dynamically resizable buffers; when reserving
135  * space in a buffer, we round the allocated buffer length up to the
136  * nearest * multiple of this value.
137  */
138 #define ISC_BUFFER_INCR 2048
139 
140 /*
141  * The following macros MUST be used only on valid buffers.  It is the
142  * caller's responsibility to ensure this by using the ISC_BUFFER_VALID
143  * check above, or by calling another isc_buffer_*() function (rather than
144  * another macro.)
145  */
146 
147 /*@{*/
148 /*!
149  * Fundamental buffer elements.  (A through E in the introductory comment.)
150  */
151 #define isc_buffer_base(b) ((void *)(b)->base) /*a*/
152 #define isc_buffer_current(b) \
153 	((void *)((unsigned char *)(b)->base + (b)->current)) /*b*/
154 #define isc_buffer_active(b) \
155 	((void *)((unsigned char *)(b)->base + (b)->active)) /*c*/
156 #define isc_buffer_used(b) \
157 	((void *)((unsigned char *)(b)->base + (b)->used)) /*d*/
158 #define isc_buffer_length(b) ((b)->length)		   /*e*/
159 /*@}*/
160 
161 /*@{*/
162 /*!
163  * Derived lengths.  (Described in the introductory comment.)
164  */
165 #define isc_buffer_usedlength(b)      ((b)->used)		   /* d-a */
166 #define isc_buffer_consumedlength(b)  ((b)->current)		   /* b-a */
167 #define isc_buffer_remaininglength(b) ((b)->used - (b)->current)   /* d-b */
168 #define isc_buffer_activelength(b)    ((b)->active - (b)->current) /* c-b */
169 #define isc_buffer_availablelength(b) ((b)->length - (b)->used)	   /* e-d */
170 /*@}*/
171 
172 /*!
173  * Note that the buffer structure is public.  This is principally so buffer
174  * operations can be implemented using macros.  Applications are strongly
175  * discouraged from directly manipulating the structure.
176  */
177 
178 struct isc_buffer {
179 	unsigned int magic;
180 	void	    *base;
181 	/*@{*/
182 	/*! The following integers are byte offsets from 'base'. */
183 	unsigned int length;
184 	unsigned int used;
185 	unsigned int current;
186 	unsigned int active;
187 	/*@}*/
188 	/*! linkable */
189 	ISC_LINK(isc_buffer_t) link;
190 	/*! private internal elements */
191 	isc_mem_t *mctx;
192 	/* automatically realloc buffer at put* */
193 	bool autore;
194 };
195 
196 /***
197  *** Functions
198  ***/
199 
200 void
201 isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer,
202 		    unsigned int length);
203 /*!<
204  * \brief Allocate a dynamic linkable buffer which has "length" bytes in the
205  * data region.
206  *
207  * Requires:
208  *\li	"mctx" is valid.
209  *
210  *\li	"dynbuffer" is non-NULL, and "*dynbuffer" is NULL.
211  *
212  * Note:
213  *\li	Changing the buffer's length field is not permitted.
214  */
215 
216 isc_result_t
217 isc_buffer_reserve(isc_buffer_t **dynbuffer, unsigned int size);
218 /*!<
219  * \brief Make "size" bytes of space available in the buffer. The buffer
220  * pointer may move when you call this function.
221  *
222  * Requires:
223  *\li	"dynbuffer" is not NULL.
224  *
225  *\li	"*dynbuffer" is a valid dynamic buffer.
226  *
227  * Returns:
228  *\li	ISC_R_SUCCESS		- success
229  *\li	ISC_R_NOMEMORY		- no memory available
230  *
231  * Ensures:
232  *\li	"*dynbuffer" will be valid on return and will contain all the
233  *	original data. However, the buffer pointer may be moved during
234  *	reallocation.
235  */
236 
237 void
238 isc_buffer_free(isc_buffer_t **dynbuffer);
239 /*!<
240  * \brief Release resources allocated for a dynamic buffer.
241  *
242  * Requires:
243  *\li	"dynbuffer" is not NULL.
244  *
245  *\li	"*dynbuffer" is a valid dynamic buffer.
246  *
247  * Ensures:
248  *\li	"*dynbuffer" will be NULL on return, and all memory associated with
249  *	the dynamic buffer is returned to the memory context used in
250  *	isc_buffer_allocate().
251  */
252 
253 void
254 isc__buffer_init(isc_buffer_t *b, void *base, unsigned int length);
255 /*!<
256  * \brief Make 'b' refer to the 'length'-byte region starting at base.
257  *
258  * Requires:
259  *
260  *\li	'length' > 0
261  *
262  *\li	'base' is a pointer to a sequence of 'length' bytes.
263  *
264  */
265 
266 void
267 isc__buffer_initnull(isc_buffer_t *b);
268 /*!<
269  *\brief Initialize a buffer 'b' with a null data and zero length/
270  */
271 
272 void
273 isc_buffer_reinit(isc_buffer_t *b, void *base, unsigned int length);
274 /*!<
275  * \brief Make 'b' refer to the 'length'-byte region starting at base.
276  * Any existing data will be copied.
277  *
278  * Requires:
279  *
280  *\li	'length' > 0 AND length >= previous length
281  *
282  *\li	'base' is a pointer to a sequence of 'length' bytes.
283  *
284  */
285 
286 void
287 isc__buffer_invalidate(isc_buffer_t *b);
288 /*!<
289  * \brief Make 'b' an invalid buffer.
290  *
291  * Requires:
292  *\li	'b' is a valid buffer.
293  *
294  * Ensures:
295  *\li	If assertion checking is enabled, future attempts to use 'b' without
296  *	calling isc_buffer_init() on it will cause an assertion failure.
297  */
298 
299 void
300 isc_buffer_setautorealloc(isc_buffer_t *b, bool enable);
301 /*!<
302  * \brief Enable or disable autoreallocation on 'b'.
303  *
304  * Requires:
305  *\li	'b' is a valid dynamic buffer (b->mctx != NULL).
306  *
307  */
308 
309 void
310 isc__buffer_region(isc_buffer_t *b, isc_region_t *r);
311 /*!<
312  * \brief Make 'r' refer to the region of 'b'.
313  *
314  * Requires:
315  *
316  *\li	'b' is a valid buffer.
317  *
318  *\li	'r' points to a region structure.
319  */
320 
321 void
322 isc__buffer_usedregion(const isc_buffer_t *b, isc_region_t *r);
323 /*!<
324  * \brief Make 'r' refer to the used region of 'b'.
325  *
326  * Requires:
327  *
328  *\li	'b' is a valid buffer.
329  *
330  *\li	'r' points to a region structure.
331  */
332 
333 void
334 isc__buffer_availableregion(isc_buffer_t *b, isc_region_t *r);
335 /*!<
336  * \brief Make 'r' refer to the available region of 'b'.
337  *
338  * Requires:
339  *
340  *\li	'b' is a valid buffer.
341  *
342  *\li	'r' points to a region structure.
343  */
344 
345 void
346 isc__buffer_add(isc_buffer_t *b, unsigned int n);
347 /*!<
348  * \brief Increase the 'used' region of 'b' by 'n' bytes.
349  *
350  * Requires:
351  *
352  *\li	'b' is a valid buffer
353  *
354  *\li	used + n <= length
355  *
356  */
357 
358 void
359 isc__buffer_subtract(isc_buffer_t *b, unsigned int n);
360 /*!<
361  * \brief Decrease the 'used' region of 'b' by 'n' bytes.
362  *
363  * Requires:
364  *
365  *\li	'b' is a valid buffer
366  *
367  *\li	used >= n
368  *
369  */
370 
371 void
372 isc__buffer_clear(isc_buffer_t *b);
373 /*!<
374  * \brief Make the used region empty.
375  *
376  * Requires:
377  *
378  *\li	'b' is a valid buffer
379  *
380  * Ensures:
381  *
382  *\li	used = 0
383  *
384  */
385 
386 void
387 isc__buffer_consumedregion(isc_buffer_t *b, isc_region_t *r);
388 /*!<
389  * \brief Make 'r' refer to the consumed region of 'b'.
390  *
391  * Requires:
392  *
393  *\li	'b' is a valid buffer.
394  *
395  *\li	'r' points to a region structure.
396  */
397 
398 void
399 isc__buffer_remainingregion(isc_buffer_t *b, isc_region_t *r);
400 /*!<
401  * \brief Make 'r' refer to the remaining region of 'b'.
402  *
403  * Requires:
404  *
405  *\li	'b' is a valid buffer.
406  *
407  *\li	'r' points to a region structure.
408  */
409 
410 void
411 isc__buffer_activeregion(isc_buffer_t *b, isc_region_t *r);
412 /*!<
413  * \brief Make 'r' refer to the active region of 'b'.
414  *
415  * Requires:
416  *
417  *\li	'b' is a valid buffer.
418  *
419  *\li	'r' points to a region structure.
420  */
421 
422 void
423 isc__buffer_setactive(isc_buffer_t *b, unsigned int n);
424 /*!<
425  * \brief Sets the end of the active region 'n' bytes after current.
426  *
427  * Requires:
428  *
429  *\li	'b' is a valid buffer.
430  *
431  *\li	current + n <= used
432  */
433 
434 void
435 isc__buffer_first(isc_buffer_t *b);
436 /*!<
437  * \brief Make the consumed region empty.
438  *
439  * Requires:
440  *
441  *\li	'b' is a valid buffer
442  *
443  * Ensures:
444  *
445  *\li	current == 0
446  *
447  */
448 
449 void
450 isc__buffer_forward(isc_buffer_t *b, unsigned int n);
451 /*!<
452  * \brief Increase the 'consumed' region of 'b' by 'n' bytes.
453  *
454  * Requires:
455  *
456  *\li	'b' is a valid buffer
457  *
458  *\li	current + n <= used
459  *
460  */
461 
462 void
463 isc__buffer_back(isc_buffer_t *b, unsigned int n);
464 /*!<
465  * \brief Decrease the 'consumed' region of 'b' by 'n' bytes.
466  *
467  * Requires:
468  *
469  *\li	'b' is a valid buffer
470  *
471  *\li	n <= current
472  *
473  */
474 
475 void
476 isc_buffer_compact(isc_buffer_t *b);
477 /*!<
478  * \brief Compact the used region by moving the remaining region so it occurs
479  * at the start of the buffer.  The used region is shrunk by the size of
480  * the consumed region, and the consumed region is then made empty.
481  *
482  * Requires:
483  *
484  *\li	'b' is a valid buffer
485  *
486  * Ensures:
487  *
488  *\li	current == 0
489  *
490  *\li	The size of the used region is now equal to the size of the remaining
491  *	region (as it was before the call).  The contents of the used region
492  *	are those of the remaining region (as it was before the call).
493  */
494 
495 uint8_t
496 isc_buffer_getuint8(isc_buffer_t *b);
497 /*!<
498  * \brief Read an unsigned 8-bit integer from 'b' and return it.
499  *
500  * Requires:
501  *
502  *\li	'b' is a valid buffer.
503  *
504  *\li	The length of the remaining region of 'b' is at least 1.
505  *
506  * Ensures:
507  *
508  *\li	The current pointer in 'b' is advanced by 1.
509  *
510  * Returns:
511  *
512  *\li	A 8-bit unsigned integer.
513  */
514 
515 void
516 isc__buffer_putuint8(isc_buffer_t *b, uint8_t val);
517 /*!<
518  * \brief Store an unsigned 8-bit integer from 'val' into 'b'.
519  *
520  * Requires:
521  *\li	'b' is a valid buffer.
522  *
523  *\li	The length of the available region of 'b' is at least 1
524  *	or the buffer has autoreallocation enabled.
525  *
526  * Ensures:
527  *\li	The used pointer in 'b' is advanced by 1.
528  */
529 
530 uint16_t
531 isc_buffer_getuint16(isc_buffer_t *b);
532 /*!<
533  * \brief Read an unsigned 16-bit integer in network byte order from 'b',
534  * convert it to host byte order, and return it.
535  *
536  * Requires:
537  *
538  *\li	'b' is a valid buffer.
539  *
540  *\li	The length of the remaining region of 'b' is at least 2.
541  *
542  * Ensures:
543  *
544  *\li	The current pointer in 'b' is advanced by 2.
545  *
546  * Returns:
547  *
548  *\li	A 16-bit unsigned integer.
549  */
550 
551 void
552 isc__buffer_putuint16(isc_buffer_t *b, uint16_t val);
553 /*!<
554  * \brief Store an unsigned 16-bit integer in host byte order from 'val'
555  * into 'b' in network byte order.
556  *
557  * Requires:
558  *\li	'b' is a valid buffer.
559  *
560  *\li	The length of the available region of 'b' is at least 2
561  *	or the buffer has autoreallocation enabled.
562  *
563  * Ensures:
564  *\li	The used pointer in 'b' is advanced by 2.
565  */
566 
567 uint32_t
568 isc_buffer_getuint32(isc_buffer_t *b);
569 /*!<
570  * \brief Read an unsigned 32-bit integer in network byte order from 'b',
571  * convert it to host byte order, and return it.
572  *
573  * Requires:
574  *
575  *\li	'b' is a valid buffer.
576  *
577  *\li	The length of the remaining region of 'b' is at least 4.
578  *
579  * Ensures:
580  *
581  *\li	The current pointer in 'b' is advanced by 4.
582  *
583  * Returns:
584  *
585  *\li	A 32-bit unsigned integer.
586  */
587 
588 void
589 isc__buffer_putuint32(isc_buffer_t *b, uint32_t val);
590 /*!<
591  * \brief Store an unsigned 32-bit integer in host byte order from 'val'
592  * into 'b' in network byte order.
593  *
594  * Requires:
595  *\li	'b' is a valid buffer.
596  *
597  *\li	The length of the available region of 'b' is at least 4
598  *	or the buffer has autoreallocation enabled.
599  *
600  * Ensures:
601  *\li	The used pointer in 'b' is advanced by 4.
602  */
603 
604 uint64_t
605 isc_buffer_getuint48(isc_buffer_t *b);
606 /*!<
607  * \brief Read an unsigned 48-bit integer in network byte order from 'b',
608  * convert it to host byte order, and return it.
609  *
610  * Requires:
611  *
612  *\li	'b' is a valid buffer.
613  *
614  *\li	The length of the remaining region of 'b' is at least 6.
615  *
616  * Ensures:
617  *
618  *\li	The current pointer in 'b' is advanced by 6.
619  *
620  * Returns:
621  *
622  *\li	A 48-bit unsigned integer (stored in a 64-bit integer).
623  */
624 
625 void
626 isc__buffer_putuint48(isc_buffer_t *b, uint64_t val);
627 /*!<
628  * \brief Store an unsigned 48-bit integer in host byte order from 'val'
629  * into 'b' in network byte order.
630  *
631  * Requires:
632  *\li	'b' is a valid buffer.
633  *
634  *\li	The length of the available region of 'b' is at least 6
635  *	or the buffer has autoreallocation enabled.
636  *
637  * Ensures:
638  *\li	The used pointer in 'b' is advanced by 6.
639  */
640 
641 void
642 isc__buffer_putuint24(isc_buffer_t *b, uint32_t val);
643 /*!<
644  * Store an unsigned 24-bit integer in host byte order from 'val'
645  * into 'b' in network byte order.
646  *
647  * Requires:
648  *\li	'b' is a valid buffer.
649  *
650  *\li	The length of the available region of 'b' is at least 3
651  *	or the buffer has autoreallocation enabled.
652  *
653  * Ensures:
654  *\li	The used pointer in 'b' is advanced by 3.
655  */
656 
657 void
658 isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base,
659 		   unsigned int length);
660 /*!<
661  * \brief Copy 'length' bytes of memory at 'base' into 'b'.
662  *
663  * Requires:
664  *\li	'b' is a valid buffer.
665  *
666  *\li	'base' points to 'length' bytes of valid memory.
667  *
668  *\li	The length of the available region of 'b' is at least 'length'
669  *	or the buffer has autoreallocation enabled.
670  *
671  * Ensures:
672  *\li	The used pointer in 'b' is advanced by 'length'.
673  */
674 
675 void
676 isc__buffer_putstr(isc_buffer_t *b, const char *source);
677 /*!<
678  * \brief Copy 'source' into 'b', not including terminating NUL.
679  *
680  * Requires:
681  *\li	'b' is a valid buffer.
682  *
683  *\li	'source' is a valid NULL terminated string.
684  *
685  *\li	The length of the available region of 'b' is at least strlen('source')
686  *	or the buffer has autoreallocation enabled.
687  *
688  * Ensures:
689  *\li	The used pointer in 'b' is advanced by strlen('source').
690  */
691 
692 void
693 isc_buffer_putdecint(isc_buffer_t *b, int64_t v);
694 /*!<
695  * \brief Put decimal representation of 'v' in b
696  *
697  * Requires:
698  *\li	'b' is a valid buffer.
699  *
700  *\li	The length of the available region of 'b' is at least strlen(dec('v'))
701  *	or the buffer has autoreallocation enabled.
702  *
703  * Ensures:
704  *\li	The used pointer in 'b' is advanced by strlen(dec('v')).
705  */
706 
707 isc_result_t
708 isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r);
709 /*!<
710  * \brief Copy the contents of 'r' into 'b'.
711  *
712  * Notes:
713  *\li	If 'b' has autoreallocation enabled, and the length of 'r' is greater
714  *	than the length of the available region of 'b', 'b' is reallocated.
715  *
716  * Requires:
717  *\li	'b' is a valid buffer.
718  *
719  *\li	'r' is a valid region.
720  *
721  * Returns:
722  *\li	ISC_R_SUCCESS
723  *\li	ISC_R_NOSPACE			The available region of 'b' is not
724  *					big enough.
725  */
726 
727 isc_result_t
728 isc_buffer_dup(isc_mem_t *mctx, isc_buffer_t **dstp, const isc_buffer_t *src);
729 /*!<
730  * \brief Allocate 'dst' and copy used contents of 'src' into it.
731  *
732  * Requires:
733  *\li	'dstp' is not NULL and *dst is NULL.
734  *\li	'src' is a valid buffer.
735  *
736  * Returns:
737  *\li	ISC_R_SUCCESS
738  */
739 
740 isc_result_t
741 isc_buffer_printf(isc_buffer_t *b, const char *format, ...)
742 	ISC_FORMAT_PRINTF(2, 3);
743 /*!<
744  * \brief Append a formatted string to the used region of 'b'.
745  *
746  * Notes:
747  *
748  *\li	The 'format' argument is a printf(3) string, with additional arguments
749  *	as necessary.
750  *
751  *\li	If 'b' has autoreallocation enabled, and the length of the formatted
752  *	string is greater than the length of the available region of 'b', 'b'
753  *	is reallocated.
754  *
755  * Requires:
756  *
757  *\li	'b' is a valid buffer.
758  *
759  * Ensures:
760  *
761  *\li	The used pointer in 'b' is advanced by the number of bytes appended
762  *	(excluding the terminating NULL byte).
763  *
764  * Returns:
765  *
766  *\li	#ISC_R_SUCCESS	Operation succeeded.
767  *\li	#ISC_R_NOSPACE	'b' does not allow reallocation and appending the
768  *			formatted string to it would cause it to overflow.
769  *\li	#ISC_R_NOMEMORY	Reallocation failed.
770  *\li	#ISC_R_FAILURE	Other error occurred.
771  */
772 
773 ISC_LANG_ENDDECLS
774 
775 /*
776  * Inline macro versions of the functions.  These should never be called
777  * directly by an application, but will be used by the functions within
778  * buffer.c.  The callers should always use "isc_buffer_*()" names, never
779  * ones beginning with "isc__"
780  */
781 
782 /*! \note
783  * XXXDCL Something more could be done with initializing buffers that
784  * point to const data.  For example, isc_buffer_constinit() could
785  * set a new boolean flag in the buffer structure indicating whether
786  * the buffer was initialized with that function.  * Then if the
787  * boolean were true, the isc_buffer_put* functions could assert a
788  * contractual requirement for a non-const buffer.
789  *
790  * One drawback is that the isc_buffer_* functions (macros) that return
791  * pointers would still need to return non-const pointers to avoid compiler
792  * warnings, so it would be up to code that uses them to have to deal
793  * with the possibility that the buffer was initialized as const --
794  * a problem that they *already* have to deal with but have absolutely
795  * no ability to.  With a new isc_buffer_isconst() function returning
796  * true/false, they could at least assert a contractual requirement for
797  * non-const buffers when needed.
798  */
799 #define ISC__BUFFER_INIT(_b, _base, _length)    \
800 	do {                                    \
801 		ISC_REQUIRE((_b) != NULL);      \
802 		(_b)->base = _base;             \
803 		(_b)->length = (_length);       \
804 		(_b)->used = 0;                 \
805 		(_b)->current = 0;              \
806 		(_b)->active = 0;               \
807 		(_b)->mctx = NULL;              \
808 		ISC_LINK_INIT(_b, link);        \
809 		(_b)->magic = ISC_BUFFER_MAGIC; \
810 		(_b)->autore = false;           \
811 	} while (0)
812 
813 #define ISC__BUFFER_INITNULL(_b) ISC__BUFFER_INIT(_b, NULL, 0)
814 
815 #define ISC__BUFFER_INVALIDATE(_b)                         \
816 	do {                                               \
817 		ISC_REQUIRE(ISC_BUFFER_VALID(_b));         \
818 		ISC_REQUIRE(!ISC_LINK_LINKED((_b), link)); \
819 		ISC_REQUIRE((_b)->mctx == NULL);           \
820 		(_b)->magic = 0;                           \
821 		(_b)->base = NULL;                         \
822 		(_b)->length = 0;                          \
823 		(_b)->used = 0;                            \
824 		(_b)->current = 0;                         \
825 		(_b)->active = 0;                          \
826 	} while (0)
827 
828 #define ISC__BUFFER_REGION(_b, _r)                 \
829 	do {                                       \
830 		ISC_REQUIRE(ISC_BUFFER_VALID(_b)); \
831 		ISC_REQUIRE((_r) != NULL);         \
832 		(_r)->base = (_b)->base;           \
833 		(_r)->length = (_b)->length;       \
834 	} while (0)
835 
836 #define ISC__BUFFER_USEDREGION(_b, _r)             \
837 	do {                                       \
838 		ISC_REQUIRE(ISC_BUFFER_VALID(_b)); \
839 		ISC_REQUIRE((_r) != NULL);         \
840 		(_r)->base = (_b)->base;           \
841 		(_r)->length = (_b)->used;         \
842 	} while (0)
843 
844 #define ISC__BUFFER_AVAILABLEREGION(_b, _r)                    \
845 	do {                                                   \
846 		ISC_REQUIRE(ISC_BUFFER_VALID(_b));             \
847 		ISC_REQUIRE((_r) != NULL);                     \
848 		(_r)->base = isc_buffer_used(_b);              \
849 		(_r)->length = isc_buffer_availablelength(_b); \
850 	} while (0)
851 
852 #define ISC__BUFFER_ADD(_b, _n)                                 \
853 	do {                                                    \
854 		ISC_REQUIRE(ISC_BUFFER_VALID(_b));              \
855 		ISC_REQUIRE((_b)->used + (_n) <= (_b)->length); \
856 		(_b)->used += (_n);                             \
857 	} while (0)
858 
859 #define ISC__BUFFER_SUBTRACT(_b, _n)                \
860 	do {                                        \
861 		ISC_REQUIRE(ISC_BUFFER_VALID(_b));  \
862 		ISC_REQUIRE((_b)->used >= (_n));    \
863 		(_b)->used -= (_n);                 \
864 		if ((_b)->current > (_b)->used)     \
865 			(_b)->current = (_b)->used; \
866 		if ((_b)->active > (_b)->used)      \
867 			(_b)->active = (_b)->used;  \
868 	} while (0)
869 
870 #define ISC__BUFFER_CLEAR(_b)                      \
871 	do {                                       \
872 		ISC_REQUIRE(ISC_BUFFER_VALID(_b)); \
873 		(_b)->used = 0;                    \
874 		(_b)->current = 0;                 \
875 		(_b)->active = 0;                  \
876 	} while (0)
877 
878 #define ISC__BUFFER_CONSUMEDREGION(_b, _r)         \
879 	do {                                       \
880 		ISC_REQUIRE(ISC_BUFFER_VALID(_b)); \
881 		ISC_REQUIRE((_r) != NULL);         \
882 		(_r)->base = (_b)->base;           \
883 		(_r)->length = (_b)->current;      \
884 	} while (0)
885 
886 #define ISC__BUFFER_REMAININGREGION(_b, _r)                    \
887 	do {                                                   \
888 		ISC_REQUIRE(ISC_BUFFER_VALID(_b));             \
889 		ISC_REQUIRE((_r) != NULL);                     \
890 		(_r)->base = isc_buffer_current(_b);           \
891 		(_r)->length = isc_buffer_remaininglength(_b); \
892 	} while (0)
893 
894 #define ISC__BUFFER_ACTIVEREGION(_b, _r)                            \
895 	do {                                                        \
896 		ISC_REQUIRE(ISC_BUFFER_VALID(_b));                  \
897 		ISC_REQUIRE((_r) != NULL);                          \
898 		if ((_b)->current < (_b)->active) {                 \
899 			(_r)->base = isc_buffer_current(_b);        \
900 			(_r)->length = isc_buffer_activelength(_b); \
901 		} else {                                            \
902 			(_r)->base = NULL;                          \
903 			(_r)->length = 0;                           \
904 		}                                                   \
905 	} while (0)
906 
907 #define ISC__BUFFER_SETACTIVE(_b, _n)                            \
908 	do {                                                     \
909 		ISC_REQUIRE(ISC_BUFFER_VALID(_b));               \
910 		ISC_REQUIRE((_b)->current + (_n) <= (_b)->used); \
911 		(_b)->active = (_b)->current + (_n);             \
912 	} while (0)
913 
914 #define ISC__BUFFER_FIRST(_b)                      \
915 	do {                                       \
916 		ISC_REQUIRE(ISC_BUFFER_VALID(_b)); \
917 		(_b)->current = 0;                 \
918 	} while (0)
919 
920 #define ISC__BUFFER_FORWARD(_b, _n)                              \
921 	do {                                                     \
922 		ISC_REQUIRE(ISC_BUFFER_VALID(_b));               \
923 		ISC_REQUIRE((_b)->current + (_n) <= (_b)->used); \
924 		(_b)->current += (_n);                           \
925 	} while (0)
926 
927 #define ISC__BUFFER_BACK(_b, _n)                    \
928 	do {                                        \
929 		ISC_REQUIRE(ISC_BUFFER_VALID(_b));  \
930 		ISC_REQUIRE((_n) <= (_b)->current); \
931 		(_b)->current -= (_n);              \
932 	} while (0)
933 
934 #define ISC__BUFFER_PUTMEM(_b, _base, _length)                            \
935 	do {                                                              \
936 		ISC_REQUIRE(ISC_BUFFER_VALID(_b));                        \
937 		if (ISC_UNLIKELY((_b)->autore)) {                         \
938 			isc_buffer_t *_tmp = _b;                          \
939 			ISC_REQUIRE(isc_buffer_reserve(&_tmp, _length) == \
940 				    ISC_R_SUCCESS);                       \
941 		}                                                         \
942 		ISC_REQUIRE(isc_buffer_availablelength(_b) >=             \
943 			    (unsigned int)_length);                       \
944 		if (_length > 0U) {                                       \
945 			memmove(isc_buffer_used(_b), (_base), (_length)); \
946 			(_b)->used += (_length);                          \
947 		}                                                         \
948 	} while (0)
949 
950 #define ISC__BUFFER_PUTSTR(_b, _source)                                   \
951 	do {                                                              \
952 		unsigned int   _length;                                   \
953 		unsigned char *_cp;                                       \
954 		ISC_REQUIRE(ISC_BUFFER_VALID(_b));                        \
955 		ISC_REQUIRE((_source) != NULL);                           \
956 		_length = (unsigned int)strlen(_source);                  \
957 		if (ISC_UNLIKELY((_b)->autore)) {                         \
958 			isc_buffer_t *_tmp = _b;                          \
959 			ISC_REQUIRE(isc_buffer_reserve(&_tmp, _length) == \
960 				    ISC_R_SUCCESS);                       \
961 		}                                                         \
962 		ISC_REQUIRE(isc_buffer_availablelength(_b) >= _length);   \
963 		_cp = isc_buffer_used(_b);                                \
964 		memmove(_cp, (_source), _length);                         \
965 		(_b)->used += (_length);                                  \
966 	} while (0)
967 
968 #define ISC__BUFFER_PUTUINT8(_b, _val)                              \
969 	do {                                                        \
970 		unsigned char *_cp;                                 \
971 		/* evaluate (_val) only once */                     \
972 		uint8_t _val2 = (_val);                             \
973 		ISC_REQUIRE(ISC_BUFFER_VALID(_b));                  \
974 		if (ISC_UNLIKELY((_b)->autore)) {                   \
975 			isc_buffer_t *_tmp = _b;                    \
976 			ISC_REQUIRE(isc_buffer_reserve(&_tmp, 1) == \
977 				    ISC_R_SUCCESS);                 \
978 		}                                                   \
979 		ISC_REQUIRE(isc_buffer_availablelength(_b) >= 1U);  \
980 		_cp = isc_buffer_used(_b);                          \
981 		(_b)->used++;                                       \
982 		_cp[0] = _val2;                                     \
983 	} while (0)
984 
985 #define ISC__BUFFER_PUTUINT16(_b, _val)                             \
986 	do {                                                        \
987 		unsigned char *_cp;                                 \
988 		/* evaluate (_val) only once */                     \
989 		uint16_t _val2 = (_val);                            \
990 		ISC_REQUIRE(ISC_BUFFER_VALID(_b));                  \
991 		if (ISC_UNLIKELY((_b)->autore)) {                   \
992 			isc_buffer_t *_tmp = _b;                    \
993 			ISC_REQUIRE(isc_buffer_reserve(&_tmp, 2) == \
994 				    ISC_R_SUCCESS);                 \
995 		}                                                   \
996 		ISC_REQUIRE(isc_buffer_availablelength(_b) >= 2U);  \
997 		_cp = isc_buffer_used(_b);                          \
998 		(_b)->used += 2;                                    \
999 		_cp[0] = (unsigned char)(_val2 >> 8);               \
1000 		_cp[1] = (unsigned char)_val2;                      \
1001 	} while (0)
1002 
1003 #define ISC__BUFFER_PUTUINT24(_b, _val)                             \
1004 	do {                                                        \
1005 		unsigned char *_cp;                                 \
1006 		/* evaluate (_val) only once */                     \
1007 		uint32_t _val2 = (_val);                            \
1008 		ISC_REQUIRE(ISC_BUFFER_VALID(_b));                  \
1009 		if (ISC_UNLIKELY((_b)->autore)) {                   \
1010 			isc_buffer_t *_tmp = _b;                    \
1011 			ISC_REQUIRE(isc_buffer_reserve(&_tmp, 3) == \
1012 				    ISC_R_SUCCESS);                 \
1013 		}                                                   \
1014 		ISC_REQUIRE(isc_buffer_availablelength(_b) >= 3U);  \
1015 		_cp = isc_buffer_used(_b);                          \
1016 		(_b)->used += 3;                                    \
1017 		_cp[0] = (unsigned char)(_val2 >> 16);              \
1018 		_cp[1] = (unsigned char)(_val2 >> 8);               \
1019 		_cp[2] = (unsigned char)_val2;                      \
1020 	} while (0)
1021 
1022 #define ISC__BUFFER_PUTUINT32(_b, _val)                             \
1023 	do {                                                        \
1024 		unsigned char *_cp;                                 \
1025 		/* evaluate (_val) only once */                     \
1026 		uint32_t _val2 = (_val);                            \
1027 		ISC_REQUIRE(ISC_BUFFER_VALID(_b));                  \
1028 		if (ISC_UNLIKELY((_b)->autore)) {                   \
1029 			isc_buffer_t *_tmp = _b;                    \
1030 			ISC_REQUIRE(isc_buffer_reserve(&_tmp, 4) == \
1031 				    ISC_R_SUCCESS);                 \
1032 		}                                                   \
1033 		ISC_REQUIRE(isc_buffer_availablelength(_b) >= 4U);  \
1034 		_cp = isc_buffer_used(_b);                          \
1035 		(_b)->used += 4;                                    \
1036 		_cp[0] = (unsigned char)(_val2 >> 24);              \
1037 		_cp[1] = (unsigned char)(_val2 >> 16);              \
1038 		_cp[2] = (unsigned char)(_val2 >> 8);               \
1039 		_cp[3] = (unsigned char)_val2;                      \
1040 	} while (0)
1041 
1042 #if defined(ISC_BUFFER_USEINLINE)
1043 #define isc_buffer_init		   ISC__BUFFER_INIT
1044 #define isc_buffer_initnull	   ISC__BUFFER_INITNULL
1045 #define isc_buffer_invalidate	   ISC__BUFFER_INVALIDATE
1046 #define isc_buffer_region	   ISC__BUFFER_REGION
1047 #define isc_buffer_usedregion	   ISC__BUFFER_USEDREGION
1048 #define isc_buffer_availableregion ISC__BUFFER_AVAILABLEREGION
1049 #define isc_buffer_add		   ISC__BUFFER_ADD
1050 #define isc_buffer_subtract	   ISC__BUFFER_SUBTRACT
1051 #define isc_buffer_clear	   ISC__BUFFER_CLEAR
1052 #define isc_buffer_consumedregion  ISC__BUFFER_CONSUMEDREGION
1053 #define isc_buffer_remainingregion ISC__BUFFER_REMAININGREGION
1054 #define isc_buffer_activeregion	   ISC__BUFFER_ACTIVEREGION
1055 #define isc_buffer_setactive	   ISC__BUFFER_SETACTIVE
1056 #define isc_buffer_first	   ISC__BUFFER_FIRST
1057 #define isc_buffer_forward	   ISC__BUFFER_FORWARD
1058 #define isc_buffer_back		   ISC__BUFFER_BACK
1059 #define isc_buffer_putmem	   ISC__BUFFER_PUTMEM
1060 #define isc_buffer_putstr	   ISC__BUFFER_PUTSTR
1061 #define isc_buffer_putuint8	   ISC__BUFFER_PUTUINT8
1062 #define isc_buffer_putuint16	   ISC__BUFFER_PUTUINT16
1063 #define isc_buffer_putuint24	   ISC__BUFFER_PUTUINT24
1064 #define isc_buffer_putuint32	   ISC__BUFFER_PUTUINT32
1065 #else /* if defined(ISC_BUFFER_USEINLINE) */
1066 #define isc_buffer_init		   isc__buffer_init
1067 #define isc_buffer_initnull	   isc__buffer_initnull
1068 #define isc_buffer_invalidate	   isc__buffer_invalidate
1069 #define isc_buffer_region	   isc__buffer_region
1070 #define isc_buffer_usedregion	   isc__buffer_usedregion
1071 #define isc_buffer_availableregion isc__buffer_availableregion
1072 #define isc_buffer_add		   isc__buffer_add
1073 #define isc_buffer_subtract	   isc__buffer_subtract
1074 #define isc_buffer_clear	   isc__buffer_clear
1075 #define isc_buffer_consumedregion  isc__buffer_consumedregion
1076 #define isc_buffer_remainingregion isc__buffer_remainingregion
1077 #define isc_buffer_activeregion	   isc__buffer_activeregion
1078 #define isc_buffer_setactive	   isc__buffer_setactive
1079 #define isc_buffer_first	   isc__buffer_first
1080 #define isc_buffer_forward	   isc__buffer_forward
1081 #define isc_buffer_back		   isc__buffer_back
1082 #define isc_buffer_putmem	   isc__buffer_putmem
1083 #define isc_buffer_putstr	   isc__buffer_putstr
1084 #define isc_buffer_putuint8	   isc__buffer_putuint8
1085 #define isc_buffer_putuint16	   isc__buffer_putuint16
1086 #define isc_buffer_putuint24	   isc__buffer_putuint24
1087 #define isc_buffer_putuint32	   isc__buffer_putuint32
1088 #endif /* if defined(ISC_BUFFER_USEINLINE) */
1089 
1090 #define isc_buffer_constinit(_b, _d, _l)                    \
1091 	do {                                                \
1092 		union {                                     \
1093 			void	   *_var;                   \
1094 			const void *_const;                 \
1095 		} _deconst;                                 \
1096 		_deconst._const = (_d);                     \
1097 		isc_buffer_init((_b), _deconst._var, (_l)); \
1098 	} while (0)
1099 
1100 /*
1101  * No inline method for this one (yet).
1102  */
1103 #define isc_buffer_putuint48 isc__buffer_putuint48
1104 
1105 #endif /* ISC_BUFFER_H */
1106