buffer.h 24.4 KB
Newer Older
Bob Halley's avatar
Bob Halley committed
1
/*
2
 * Copyright (C) 2004-2008, 2010, 2012, 2014, 2016  Internet Systems Consortium, Inc. ("ISC")
Mark Andrews's avatar
Mark Andrews committed
3
 * Copyright (C) 1998-2002  Internet Software Consortium.
4
 *
Automatic Updater's avatar
Automatic Updater committed
5
 * Permission to use, copy, modify, and/or distribute this software for any
Bob Halley's avatar
Bob Halley committed
6 7
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
8
 *
Mark Andrews's avatar
Mark Andrews committed
9 10 11 12 13 14 15
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
Bob Halley's avatar
Bob Halley committed
16
 */
Bob Halley's avatar
add  
Bob Halley committed
17 18 19 20 21 22 23 24

#ifndef ISC_BUFFER_H
#define ISC_BUFFER_H 1

/*****
 ***** Module Info
 *****/

25
/*! \file isc/buffer.h
Bob Halley's avatar
add  
Bob Halley committed
26
 *
27
 * \brief A buffer is a region of memory, together with a set of related subregions.
Bob Halley's avatar
add  
Bob Halley committed
28 29 30 31 32 33 34 35 36 37 38 39
 * Buffers are used for parsing and I/O operations.
 *
 * The 'used region' and the 'available' region are disjoint, and their
 * union is the buffer's region.  The used region extends from the beginning
 * of the buffer region to the last used byte.  The available region
 * extends from one byte greater than the last used byte to the end of the
 * buffer's region.  The size of the used region can be changed using various
 * buffer commands.  Initially, the used region is empty.
 *
 * The used region is further subdivided into two disjoint regions: the
 * 'consumed region' and the 'remaining region'.  The union of these two
 * regions is the used region.  The consumed region extends from the beginning
40 41
 * of the used region to the byte before the 'current' offset (if any).  The
 * 'remaining' region the current pointer to the end of the used
Bob Halley's avatar
add  
Bob Halley committed
42 43 44
 * region.  The size of the consumed region can be changed using various
 * buffer commands.  Initially, the consumed region is empty.
 *
Bob Halley's avatar
Bob Halley committed
45 46 47 48 49 50
 * The 'active region' is an (optional) subregion of the remaining region.
 * It extends from the current offset to an offset in the remaining region
 * that is selected with isc_buffer_setactive().  Initially, the active region
 * is empty.  If the current offset advances beyond the chosen offset, the
 * active region will also be empty.
 *
51
 * \verbatim
52
 *  /------------entire length---------------\
53 54 55 56 57 58 59 60 61 62 63 64
 *  /----- used region -----\/-- available --\
 *  +----------------------------------------+
 *  | consumed  | remaining |                |
 *  +----------------------------------------+
 *  a           b     c     d                e
 *
 * a == base of buffer.
 * b == current pointer.  Can be anywhere between a and d.
 * c == active pointer.  Meaningful between b and d.
 * d == used pointer.
 * e == length of buffer.
 *
David Lawrence's avatar
David Lawrence committed
65
 * a-e == entire length of buffer.
66 67 68 69
 * a-d == used region.
 * a-b == consumed region.
 * b-d == remaining region.
 * b-c == optional active region.
70
 *\endverbatim
71
 *
Bob Halley's avatar
add  
Bob Halley committed
72 73
 * The following invariants are maintained by all routines:
 *
74
 *\code
Bob Halley's avatar
add  
Bob Halley committed
75 76 77 78 79 80
 *	length > 0
 *
 *	base is a valid pointer to length bytes of memory
 *
 *	0 <= used <= length
 *
81
 *	0 <= current <= used
Bob Halley's avatar
add  
Bob Halley committed
82
 *
Bob Halley's avatar
Bob Halley committed
83
 *	0 <= active <= used
84
 *	(although active < current implies empty active region)
85
 *\endcode
Bob Halley's avatar
Bob Halley committed
86
 *
87
 * \li MP:
Bob Halley's avatar
add  
Bob Halley committed
88 89 90
 *	Buffers have no synchronization.  Clients must ensure exclusive
 *	access.
 *
91
 * \li Reliability:
Bob Halley's avatar
add  
Bob Halley committed
92 93
 *	No anticipated impact.
 *
94
 * \li Resources:
95
 *	Memory: 1 pointer + 6 unsigned integers per buffer.
Bob Halley's avatar
add  
Bob Halley committed
96
 *
97
 * \li Security:
Bob Halley's avatar
add  
Bob Halley committed
98 99
 *	No anticipated impact.
 *
100
 * \li Standards:
Bob Halley's avatar
add  
Bob Halley committed
101 102 103 104 105 106 107
 *	None.
 */

/***
 *** Imports
 ***/

Bob Halley's avatar
Bob Halley committed
108
#include <isc/lang.h>
109
#include <isc/magic.h>
110
#include <isc/types.h>
Bob Halley's avatar
add  
Bob Halley committed
111

112
/*!
113
 * To make many functions be inline macros (via \#define) define this.
114 115
 * If it is undefined, a function will be used.
 */
116
/* #define ISC_BUFFER_USEINLINE */
117

Bob Halley's avatar
Bob Halley committed
118 119
ISC_LANG_BEGINDECLS

120 121
/*@{*/
/*!
122 123 124
 *** Magic numbers
 ***/
#define ISC_BUFFER_MAGIC		0x42756621U	/* Buf!. */
125
#define ISC_BUFFER_VALID(b)		ISC_MAGIC_VALID(b, ISC_BUFFER_MAGIC)
126
/*@}*/
127

128 129 130 131 132 133 134
/*!
 * Size granularity for dynamically resizeable buffers; when reserving
 * space in a buffer, we round the allocated buffer length up to the
 * nearest * multiple of this value.
 */
#define ISC_BUFFER_INCR 2048

135 136 137 138 139 140 141
/*
 * The following macros MUST be used only on valid buffers.  It is the
 * caller's responsibility to ensure this by using the ISC_BUFFER_VALID
 * check above, or by calling another isc_buffer_*() function (rather than
 * another macro.)
 */

142 143
/*@{*/
/*!
144
 * Fundamental buffer elements.  (A through E in the introductory comment.)
145
 */
David Lawrence's avatar
David Lawrence committed
146 147 148 149 150 151 152 153
#define isc_buffer_base(b)    ((void *)(b)->base)			  /*a*/
#define isc_buffer_current(b) \
		((void *)((unsigned char *)(b)->base + (b)->current))     /*b*/
#define isc_buffer_active(b)  \
		((void *)((unsigned char *)(b)->base + (b)->active))      /*c*/
#define isc_buffer_used(b)    \
		((void *)((unsigned char *)(b)->base + (b)->used))        /*d*/
#define isc_buffer_length(b)  ((b)->length)				  /*e*/
154
/*@}*/
155

156 157
/*@{*/
/*!
158
 * Derived lengths.  (Described in the introductory comment.)
159
 */
160 161 162 163 164
#define isc_buffer_usedlength(b)	((b)->used)		      /* d-a */
#define isc_buffer_consumedlength(b)	((b)->current)		      /* b-a */
#define isc_buffer_remaininglength(b)	((b)->used - (b)->current)    /* d-b */
#define isc_buffer_activelength(b)	((b)->active - (b)->current)  /* c-b */
#define isc_buffer_availablelength(b)	((b)->length - (b)->used)     /* e-d */
165
/*@}*/
166

167
/*!
Bob Halley's avatar
add  
Bob Halley committed
168 169 170 171 172
 * Note that the buffer structure is public.  This is principally so buffer
 * operations can be implemented using macros.  Applications are strongly
 * discouraged from directly manipulating the structure.
 */

173 174 175
struct isc_buffer {
	unsigned int		magic;
	void		       *base;
176
	/*@{*/
177
	/*! The following integers are byte offsets from 'base'. */
178 179 180 181
	unsigned int		length;
	unsigned int		used;
	unsigned int 		current;
	unsigned int 		active;
182
	/*@}*/
183
	/*! linkable */
184
	ISC_LINK(isc_buffer_t)	link;
185
	/*! private internal elements */
186
	isc_mem_t	       *mctx;
187 188
	/* automatically realloc buffer at put* */
	isc_boolean_t		autore;
189 190
};

Bob Halley's avatar
add  
Bob Halley committed
191 192 193 194
/***
 *** Functions
 ***/

195
isc_result_t
196
isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer,
197
		    unsigned int length);
198 199
/*!<
 * \brief Allocate a dynamic linkable buffer which has "length" bytes in the
200 201 202
 * data region.
 *
 * Requires:
203
 *\li	"mctx" is valid.
204
 *
205
 *\li	"dynbuffer" is non-NULL, and "*dynbuffer" is NULL.
206 207
 *
 * Returns:
208 209
 *\li	ISC_R_SUCCESS		- success
 *\li	ISC_R_NOMEMORY		- no memory available
210 211
 *
 * Note:
212
 *\li	Changing the buffer's length field is not permitted.
213 214
 */

215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
isc_result_t
isc_buffer_reallocate(isc_buffer_t **dynbuffer, unsigned int length);
/*!<
 * \brief Reallocate the buffer to be "length" bytes long. The buffer
 * pointer may move when you call this function.
 *
 * Requires:
 *\li	"dynbuffer" is not NULL.
 *
 *\li	"*dynbuffer" is a valid dynamic buffer.
 *
 *\li	'length' > current length of buffer.
 *
 * Returns:
 *\li	ISC_R_SUCCESS		- success
 *\li	ISC_R_NOMEMORY		- no memory available
 *
 * Ensures:
 *\li	"*dynbuffer" will be valid on return and will contain all the
 *	original data. However, the buffer pointer may be moved during
 *	reallocation.
 */

isc_result_t
isc_buffer_reserve(isc_buffer_t **dynbuffer, unsigned int size);
/*!<
 * \brief Make "size" bytes of space available in the buffer. The buffer
 * pointer may move when you call this function.
 *
 * Requires:
 *\li	"dynbuffer" is not NULL.
 *
 *\li	"*dynbuffer" is a valid dynamic buffer.
 *
 * Returns:
 *\li	ISC_R_SUCCESS		- success
 *\li	ISC_R_NOMEMORY		- no memory available
 *
 * Ensures:
 *\li	"*dynbuffer" will be valid on return and will contain all the
 *	original data. However, the buffer pointer may be moved during
 *	reallocation.
 */

259
void
260
isc_buffer_free(isc_buffer_t **dynbuffer);
261 262
/*!<
 * \brief Release resources allocated for a dynamic buffer.
263 264
 *
 * Requires:
265
 *\li	"dynbuffer" is not NULL.
266
 *
267
 *\li	"*dynbuffer" is a valid dynamic buffer.
268 269
 *
 * Ensures:
270
 *\li	"*dynbuffer" will be NULL on return, and all memory associated with
271 272
 *	the dynamic buffer is returned to the memory context used in
 *	isc_buffer_allocate().
273
 */
Bob Halley's avatar
add  
Bob Halley committed
274 275

void
276
isc__buffer_init(isc_buffer_t *b, void *base, unsigned int length);
277 278
/*!<
 * \brief Make 'b' refer to the 'length'-byte region starting at base.
Bob Halley's avatar
add  
Bob Halley committed
279 280 281
 *
 * Requires:
 *
282
 *\li	'length' > 0
Bob Halley's avatar
add  
Bob Halley committed
283
 *
284
 *\li	'base' is a pointer to a sequence of 'length' bytes.
Bob Halley's avatar
add  
Bob Halley committed
285 286
 *
 */
287

288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
void
isc__buffer_initnull(isc_buffer_t *b);
/*!<
 *\brief Initialize a buffer 'b' with a null data and zero length/
 */

void
isc_buffer_reinit(isc_buffer_t *b, void *base, unsigned int length);
/*!<
 * \brief Make 'b' refer to the 'length'-byte region starting at base.
 * Any existing data will be copied.
 *
 * Requires:
 *
 *\li	'length' > 0 AND length >= previous length
 *
 *\li	'base' is a pointer to a sequence of 'length' bytes.
 *
 */

308
void
309
isc__buffer_invalidate(isc_buffer_t *b);
310 311
/*!<
 * \brief Make 'b' an invalid buffer.
312 313
 *
 * Requires:
314
 *\li	'b' is a valid buffer.
315 316
 *
 * Ensures:
317
 *\li	If assertion checking is enabled, future attempts to use 'b' without
318 319
 *	calling isc_buffer_init() on it will cause an assertion failure.
 */
320

321 322 323 324 325 326 327 328 329 330
void
isc_buffer_setautorealloc(isc_buffer_t *b, isc_boolean_t enable);
/*!<
 * \brief Enable or disable autoreallocation on 'b'.
 *
 * Requires:
 *\li	'b' is a valid dynamic buffer (b->mctx != NULL).
 *
 */

Bob Halley's avatar
add  
Bob Halley committed
331
void
332
isc__buffer_region(isc_buffer_t *b, isc_region_t *r);
333 334
/*!<
 * \brief Make 'r' refer to the region of 'b'.
Bob Halley's avatar
add  
Bob Halley committed
335 336 337
 *
 * Requires:
 *
338
 *\li	'b' is a valid buffer.
Bob Halley's avatar
add  
Bob Halley committed
339
 *
340
 *\li	'r' points to a region structure.
Bob Halley's avatar
add  
Bob Halley committed
341 342 343
 */

void
344
isc__buffer_usedregion(isc_buffer_t *b, isc_region_t *r);
345 346
/*!<
 * \brief Make 'r' refer to the used region of 'b'.
Bob Halley's avatar
add  
Bob Halley committed
347 348 349
 *
 * Requires:
 *
350
 *\li	'b' is a valid buffer.
Bob Halley's avatar
add  
Bob Halley committed
351
 *
352
 *\li	'r' points to a region structure.
Bob Halley's avatar
add  
Bob Halley committed
353 354 355
 */

void
356
isc__buffer_availableregion(isc_buffer_t *b, isc_region_t *r);
357 358
/*!<
 * \brief Make 'r' refer to the available region of 'b'.
Bob Halley's avatar
add  
Bob Halley committed
359 360 361
 *
 * Requires:
 *
362
 *\li	'b' is a valid buffer.
Bob Halley's avatar
add  
Bob Halley committed
363
 *
364
 *\li	'r' points to a region structure.
Bob Halley's avatar
add  
Bob Halley committed
365 366 367
 */

void
368
isc__buffer_add(isc_buffer_t *b, unsigned int n);
369 370
/*!<
 * \brief Increase the 'used' region of 'b' by 'n' bytes.
Bob Halley's avatar
add  
Bob Halley committed
371 372 373
 *
 * Requires:
 *
374
 *\li	'b' is a valid buffer
Bob Halley's avatar
add  
Bob Halley committed
375
 *
376
 *\li	used + n <= length
Bob Halley's avatar
add  
Bob Halley committed
377 378 379 380
 *
 */

void
381
isc__buffer_subtract(isc_buffer_t *b, unsigned int n);
382 383
/*!<
 * \brief Decrease the 'used' region of 'b' by 'n' bytes.
Bob Halley's avatar
add  
Bob Halley committed
384 385 386
 *
 * Requires:
 *
387
 *\li	'b' is a valid buffer
Bob Halley's avatar
add  
Bob Halley committed
388
 *
389
 *\li	used >= n
Bob Halley's avatar
add  
Bob Halley committed
390 391 392 393
 *
 */

void
394
isc__buffer_clear(isc_buffer_t *b);
395 396
/*!<
 * \brief Make the used region empty.
Bob Halley's avatar
add  
Bob Halley committed
397 398 399
 *
 * Requires:
 *
400
 *\li	'b' is a valid buffer
Bob Halley's avatar
add  
Bob Halley committed
401 402 403
 *
 * Ensures:
 *
404
 *\li	used = 0
Bob Halley's avatar
add  
Bob Halley committed
405 406 407 408
 *
 */

void
409
isc__buffer_consumedregion(isc_buffer_t *b, isc_region_t *r);
410 411
/*!<
 * \brief Make 'r' refer to the consumed region of 'b'.
Bob Halley's avatar
add  
Bob Halley committed
412 413 414
 *
 * Requires:
 *
415
 *\li	'b' is a valid buffer.
Bob Halley's avatar
add  
Bob Halley committed
416
 *
417
 *\li	'r' points to a region structure.
Bob Halley's avatar
add  
Bob Halley committed
418 419 420
 */

void
421
isc__buffer_remainingregion(isc_buffer_t *b, isc_region_t *r);
422 423
/*!<
 * \brief Make 'r' refer to the remaining region of 'b'.
Bob Halley's avatar
add  
Bob Halley committed
424 425 426
 *
 * Requires:
 *
427
 *\li	'b' is a valid buffer.
Bob Halley's avatar
add  
Bob Halley committed
428
 *
429
 *\li	'r' points to a region structure.
Bob Halley's avatar
add  
Bob Halley committed
430 431
 */

Bob Halley's avatar
Bob Halley committed
432
void
433
isc__buffer_activeregion(isc_buffer_t *b, isc_region_t *r);
434 435
/*!<
 * \brief Make 'r' refer to the active region of 'b'.
Bob Halley's avatar
Bob Halley committed
436 437 438
 *
 * Requires:
 *
439
 *\li	'b' is a valid buffer.
Bob Halley's avatar
Bob Halley committed
440
 *
441
 *\li	'r' points to a region structure.
Bob Halley's avatar
Bob Halley committed
442 443 444
 */

void
445
isc__buffer_setactive(isc_buffer_t *b, unsigned int n);
446 447
/*!<
 * \brief Sets the end of the active region 'n' bytes after current.
Bob Halley's avatar
Bob Halley committed
448 449 450
 *
 * Requires:
 *
451
 *\li	'b' is a valid buffer.
Bob Halley's avatar
Bob Halley committed
452
 *
453
 *\li	current + n <= used
Bob Halley's avatar
Bob Halley committed
454 455
 */

Bob Halley's avatar
add  
Bob Halley committed
456
void
457
isc__buffer_first(isc_buffer_t *b);
458 459
/*!<
 * \brief Make the consumed region empty.
Bob Halley's avatar
add  
Bob Halley committed
460 461 462
 *
 * Requires:
 *
463
 *\li	'b' is a valid buffer
Bob Halley's avatar
add  
Bob Halley committed
464 465 466
 *
 * Ensures:
 *
467
 *\li	current == 0
Bob Halley's avatar
add  
Bob Halley committed
468 469 470 471
 *
 */

void
472
isc__buffer_forward(isc_buffer_t *b, unsigned int n);
473 474
/*!<
 * \brief Increase the 'consumed' region of 'b' by 'n' bytes.
Bob Halley's avatar
add  
Bob Halley committed
475 476 477
 *
 * Requires:
 *
478
 *\li	'b' is a valid buffer
Bob Halley's avatar
add  
Bob Halley committed
479
 *
480
 *\li	current + n <= used
Bob Halley's avatar
add  
Bob Halley committed
481 482 483 484
 *
 */

void
485
isc__buffer_back(isc_buffer_t *b, unsigned int n);
486 487
/*!<
 * \brief Decrease the 'consumed' region of 'b' by 'n' bytes.
Bob Halley's avatar
add  
Bob Halley committed
488 489 490
 *
 * Requires:
 *
491
 *\li	'b' is a valid buffer
Bob Halley's avatar
add  
Bob Halley committed
492
 *
493
 *\li	n <= current
Bob Halley's avatar
add  
Bob Halley committed
494 495 496 497
 *
 */

void
Bob Halley's avatar
Bob Halley committed
498
isc_buffer_compact(isc_buffer_t *b);
499 500
/*!<
 * \brief Compact the used region by moving the remaining region so it occurs
Bob Halley's avatar
add  
Bob Halley committed
501 502 503 504 505
 * at the start of the buffer.  The used region is shrunk by the size of
 * the consumed region, and the consumed region is then made empty.
 *
 * Requires:
 *
506
 *\li	'b' is a valid buffer
Bob Halley's avatar
add  
Bob Halley committed
507 508 509
 *
 * Ensures:
 *
510
 *\li	current == 0
Bob Halley's avatar
add  
Bob Halley committed
511
 *
512
 *\li	The size of the used region is now equal to the size of the remaining
Bob Halley's avatar
add  
Bob Halley committed
513 514 515 516
 *	region (as it was before the call).  The contents of the used region
 *	are those of the remaining region (as it was before the call).
 */

517 518
isc_uint8_t
isc_buffer_getuint8(isc_buffer_t *b);
519 520
/*!<
 * \brief Read an unsigned 8-bit integer from 'b' and return it.
521 522 523
 *
 * Requires:
 *
524
 *\li	'b' is a valid buffer.
525
 *
526
 *\li	The length of the available region of 'b' is at least 1.
527 528 529
 *
 * Ensures:
 *
530
 *\li	The current pointer in 'b' is advanced by 1.
531 532 533
 *
 * Returns:
 *
534
 *\li	A 8-bit unsigned integer.
535 536 537
 */

void
538
isc__buffer_putuint8(isc_buffer_t *b, isc_uint8_t val);
539 540
/*!<
 * \brief Store an unsigned 8-bit integer from 'val' into 'b'.
541 542
 *
 * Requires:
543
 *\li	'b' is a valid buffer.
544
 *
545 546
 *\li	The length of the unused region of 'b' is at least 1
 *	or the buffer has autoreallocation enabled.
547 548
 *
 * Ensures:
549
 *\li	The used pointer in 'b' is advanced by 1.
550 551
 */

Bob Halley's avatar
Bob Halley committed
552 553
isc_uint16_t
isc_buffer_getuint16(isc_buffer_t *b);
554 555
/*!<
 * \brief Read an unsigned 16-bit integer in network byte order from 'b', convert
Bob Halley's avatar
Bob Halley committed
556 557 558 559
 * it to host byte order, and return it.
 *
 * Requires:
 *
560
 *\li	'b' is a valid buffer.
Bob Halley's avatar
Bob Halley committed
561
 *
562 563
 *\li	The length of the available region of 'b' is at least 2
 *	or the buffer has autoreallocation enabled.
Bob Halley's avatar
Bob Halley committed
564 565 566
 *
 * Ensures:
 *
567
 *\li	The current pointer in 'b' is advanced by 2.
Bob Halley's avatar
Bob Halley committed
568 569 570
 *
 * Returns:
 *
571
 *\li	A 16-bit unsigned integer.
Bob Halley's avatar
Bob Halley committed
572 573
 */

574
void
575
isc__buffer_putuint16(isc_buffer_t *b, isc_uint16_t val);
576 577
/*!<
 * \brief Store an unsigned 16-bit integer in host byte order from 'val'
578 579 580
 * into 'b' in network byte order.
 *
 * Requires:
581
 *\li	'b' is a valid buffer.
582
 *
583 584
 *\li	The length of the unused region of 'b' is at least 2
 *	or the buffer has autoreallocation enabled.
585 586
 *
 * Ensures:
587
 *\li	The used pointer in 'b' is advanced by 2.
588 589
 */

Bob Halley's avatar
Bob Halley committed
590 591
isc_uint32_t
isc_buffer_getuint32(isc_buffer_t *b);
592 593
/*!<
 * \brief Read an unsigned 32-bit integer in network byte order from 'b', convert
Bob Halley's avatar
Bob Halley committed
594 595 596 597
 * it to host byte order, and return it.
 *
 * Requires:
 *
598
 *\li	'b' is a valid buffer.
Bob Halley's avatar
Bob Halley committed
599
 *
600
 *\li	The length of the available region of 'b' is at least 4.
Bob Halley's avatar
Bob Halley committed
601 602 603
 *
 * Ensures:
 *
604
 *\li	The current pointer in 'b' is advanced by 4.
Bob Halley's avatar
Bob Halley committed
605 606 607
 *
 * Returns:
 *
608
 *\li	A 32-bit unsigned integer.
Bob Halley's avatar
Bob Halley committed
609 610
 */

611
void
612
isc__buffer_putuint32(isc_buffer_t *b, isc_uint32_t val);
613 614
/*!<
 * \brief Store an unsigned 32-bit integer in host byte order from 'val'
615 616 617
 * into 'b' in network byte order.
 *
 * Requires:
618
 *\li	'b' is a valid buffer.
619
 *
620 621
 *\li	The length of the unused region of 'b' is at least 4
 *	or the buffer has autoreallocation enabled.
622 623
 *
 * Ensures:
624
 *\li	The used pointer in 'b' is advanced by 4.
625 626
 */

627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656
isc_uint64_t
isc_buffer_getuint48(isc_buffer_t *b);
/*!<
 * \brief Read an unsigned 48-bit integer in network byte order from 'b',
 * convert it to host byte order, and return it.
 *
 * Requires:
 *
 *\li	'b' is a valid buffer.
 *
 *\li	The length of the available region of 'b' is at least 6.
 *
 * Ensures:
 *
 *\li	The current pointer in 'b' is advanced by 6.
 *
 * Returns:
 *
 *\li	A 48-bit unsigned integer (stored in a 64-bit integer).
 */

void
isc__buffer_putuint48(isc_buffer_t *b, isc_uint64_t val);
/*!<
 * \brief Store an unsigned 48-bit integer in host byte order from 'val'
 * into 'b' in network byte order.
 *
 * Requires:
 *\li	'b' is a valid buffer.
 *
657 658
 *\li	The length of the unused region of 'b' is at least 6
 *	or the buffer has autoreallocation enabled.
659 660 661 662 663
 *
 * Ensures:
 *\li	The used pointer in 'b' is advanced by 6.
 */

664 665 666 667 668 669 670 671 672
void
isc__buffer_putuint24(isc_buffer_t *b, isc_uint32_t val);
/*!<
 * Store an unsigned 24-bit integer in host byte order from 'val'
 * into 'b' in network byte order.
 *
 * Requires:
 *\li	'b' is a valid buffer.
 *
673 674
 *	The length of the unused region of 'b' is at least 3
 *	or the buffer has autoreallocation enabled.
675 676 677 678 679
 *
 * Ensures:
 *\li	The used pointer in 'b' is advanced by 3.
 */

Andreas Gustafsson's avatar
Andreas Gustafsson committed
680
void
David Lawrence's avatar
David Lawrence committed
681 682
isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base,
		   unsigned int length);
683 684
/*!<
 * \brief Copy 'length' bytes of memory at 'base' into 'b'.
Andreas Gustafsson's avatar
Andreas Gustafsson committed
685 686
 *
 * Requires:
687 688
 *\li	'b' is a valid buffer, and it has at least 'length'
 *	or the buffer has autoreallocation enabled.
Andreas Gustafsson's avatar
Andreas Gustafsson committed
689
 *
690
 *\li	'base' points to 'length' bytes of valid memory.
Andreas Gustafsson's avatar
Andreas Gustafsson committed
691
 *
Mark Andrews's avatar
Mark Andrews committed
692 693
 */

Automatic Updater's avatar
Automatic Updater committed
694
void
David Lawrence's avatar
David Lawrence committed
695
isc__buffer_putstr(isc_buffer_t *b, const char *source);
696 697
/*!<
 * \brief Copy 'source' into 'b', not including terminating NUL.
Mark Andrews's avatar
Mark Andrews committed
698 699
 *
 * Requires:
700
 *\li	'b' is a valid buffer.
Mark Andrews's avatar
Mark Andrews committed
701
 *
702
 *\li	'source' to be a valid NULL terminated string.
Mark Andrews's avatar
Mark Andrews committed
703
 *
704
 *\li	strlen(source) <= isc_buffer_available(b) || b->mctx != NULL
Andreas Gustafsson's avatar
Andreas Gustafsson committed
705 706
 */

Bob Halley's avatar
Bob Halley committed
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'.
Bob Halley's avatar
Bob Halley committed
711 712
 *
 * Requires:
713
 *\li	'b' is a valid buffer.
Bob Halley's avatar
Bob Halley committed
714
 *
715
 *\li	'r' is a valid region.
Bob Halley's avatar
Bob Halley committed
716 717 718
 *
 * Returns:
 *
719 720
 *\li	ISC_R_SUCCESS
 *\li	ISC_R_NOSPACE			The available region of 'b' is not
Bob Halley's avatar
Bob Halley committed
721 722 723
 *					big enough.
 */

David Lawrence's avatar
David Lawrence committed
724 725
ISC_LANG_ENDDECLS

726 727 728 729 730 731 732
/*
 * Inline macro versions of the functions.  These should never be called
 * directly by an application, but will be used by the functions within
 * buffer.c.  The callers should always use "isc_buffer_*()" names, never
 * ones beginning with "isc__"
 */

733
/*! \note
David Lawrence's avatar
David Lawrence committed
734
 * XXXDCL Something more could be done with initializing buffers that
735 736 737 738 739 740
 * point to const data.  For example, isc_buffer_constinit() could
 * set a new boolean flag in the buffer structure indicating whether
 * the buffer was initialized with that function.  * Then if the
 * boolean were true, the isc_buffer_put* functions could assert a
 * contractual requirement for a non-const buffer.
 *
David Lawrence's avatar
David Lawrence committed
741 742 743 744 745 746 747 748 749
 * One drawback is that the isc_buffer_* functions (macros) that return
 * pointers would still need to return non-const pointers to avoid compiler
 * warnings, so it would be up to code that uses them to have to deal
 * with the possibility that the buffer was initialized as const --
 * a problem that they *already* have to deal with but have absolutely
 * no ability to.  With a new isc_buffer_isconst() function returning
 * true/false, they could at least assert a contractual requirement for
 * non-const buffers when needed.
 */
750
#define ISC__BUFFER_INIT(_b, _base, _length) \
751
	do { \
752
		(_b)->base = _base; \
753 754 755 756 757
		(_b)->length = (_length); \
		(_b)->used = 0; \
		(_b)->current = 0; \
		(_b)->active = 0; \
		(_b)->mctx = NULL; \
758
		ISC_LINK_INIT(_b, link); \
David Lawrence's avatar
David Lawrence committed
759
		(_b)->magic = ISC_BUFFER_MAGIC; \
760
		(_b)->autore = ISC_FALSE; \
761 762
	} while (0)

763 764
#define ISC__BUFFER_INITNULL(_b) ISC__BUFFER_INIT(_b, NULL, 0)

765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788
#define ISC__BUFFER_INVALIDATE(_b) \
	do { \
		(_b)->magic = 0; \
		(_b)->base = NULL; \
		(_b)->length = 0; \
		(_b)->used = 0; \
		(_b)->current = 0; \
		(_b)->active = 0; \
	} while (0)

#define ISC__BUFFER_REGION(_b, _r) \
	do { \
		(_r)->base = (_b)->base; \
		(_r)->length = (_b)->length; \
	} while (0)

#define ISC__BUFFER_USEDREGION(_b, _r) \
	do { \
		(_r)->base = (_b)->base; \
		(_r)->length = (_b)->used; \
	} while (0)

#define ISC__BUFFER_AVAILABLEREGION(_b, _r) \
	do { \
David Lawrence's avatar
David Lawrence committed
789 790
		(_r)->base = isc_buffer_used(_b); \
		(_r)->length = isc_buffer_availablelength(_b); \
791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815
	} while (0)

#define ISC__BUFFER_ADD(_b, _n) \
	do { \
		(_b)->used += (_n); \
	} while (0)

#define ISC__BUFFER_SUBTRACT(_b, _n) \
	do { \
		(_b)->used -= (_n); \
		if ((_b)->current > (_b)->used) \
			(_b)->current = (_b)->used; \
		if ((_b)->active > (_b)->used) \
			(_b)->active = (_b)->used; \
	} while (0)

#define ISC__BUFFER_CLEAR(_b) \
	do { \
		(_b)->used = 0; \
		(_b)->current = 0; \
		(_b)->active = 0; \
	} while (0)

#define ISC__BUFFER_CONSUMEDREGION(_b, _r) \
	do { \
816
		(_r)->base = (_b)->base; \
817 818 819 820 821
		(_r)->length = (_b)->current; \
	} while (0)

#define ISC__BUFFER_REMAININGREGION(_b, _r) \
	do { \
David Lawrence's avatar
David Lawrence committed
822 823
		(_r)->base = isc_buffer_current(_b); \
		(_r)->length = isc_buffer_remaininglength(_b); \
824 825 826 827 828
	} while (0)

#define ISC__BUFFER_ACTIVEREGION(_b, _r) \
	do { \
		if ((_b)->current < (_b)->active) { \
David Lawrence's avatar
David Lawrence committed
829 830
			(_r)->base = isc_buffer_current(_b); \
			(_r)->length = isc_buffer_activelength(_b); \
831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856
		} else { \
			(_r)->base = NULL; \
			(_r)->length = 0; \
		} \
	} while (0)

#define ISC__BUFFER_SETACTIVE(_b, _n) \
	do { \
		(_b)->active = (_b)->current + (_n); \
	} while (0)

#define ISC__BUFFER_FIRST(_b) \
	do { \
		(_b)->current = 0; \
	} while (0)

#define ISC__BUFFER_FORWARD(_b, _n) \
	do { \
		(_b)->current += (_n); \
	} while (0)

#define ISC__BUFFER_BACK(_b, _n) \
	do { \
		(_b)->current -= (_n); \
	} while (0)

David Lawrence's avatar
David Lawrence committed
857 858
#define ISC__BUFFER_PUTMEM(_b, _base, _length) \
	do { \
859
		memmove(isc_buffer_used(_b), (_base), (_length)); \
David Lawrence's avatar
David Lawrence committed
860 861 862 863 864 865 866 867 868
		(_b)->used += (_length); \
	} while (0)

#define ISC__BUFFER_PUTSTR(_b, _source) \
	do { \
		unsigned int _length; \
		unsigned char *_cp; \
		_length = strlen(_source); \
		_cp = isc_buffer_used(_b); \
869
		memmove(_cp, (_source), _length); \
David Lawrence's avatar
David Lawrence committed
870 871 872
		(_b)->used += (_length); \
	} while (0)

873 874 875
#define ISC__BUFFER_PUTUINT8(_b, _val) \
	do { \
		unsigned char *_cp; \
876
		isc_uint8_t _val2 = (_val); \
David Lawrence's avatar
David Lawrence committed
877
		_cp = isc_buffer_used(_b); \
878
		(_b)->used++; \
879
		_cp[0] = _val2 & 0x00ff; \
880 881 882 883 884
	} while (0)

#define ISC__BUFFER_PUTUINT16(_b, _val) \
	do { \
		unsigned char *_cp; \
885
		isc_uint16_t _val2 = (_val); \
David Lawrence's avatar
David Lawrence committed
886
		_cp = isc_buffer_used(_b); \
887
		(_b)->used += 2; \
888 889
		_cp[0] = (unsigned char)((_val2 & 0xff00U) >> 8); \
		_cp[1] = (unsigned char)(_val2 & 0x00ffU); \
890 891
	} while (0)

892 893 894 895 896 897 898 899 900 901 902
#define ISC__BUFFER_PUTUINT24(_b, _val) \
	do { \
		unsigned char *_cp; \
		isc_uint32_t _val2 = (_val); \
		_cp = isc_buffer_used(_b); \
		(_b)->used += 3; \
		_cp[0] = (unsigned char)((_val2 & 0xff0000U) >> 16); \
		_cp[1] = (unsigned char)((_val2 & 0xff00U) >> 8); \
		_cp[2] = (unsigned char)(_val2 & 0x00ffU); \
	} while (0)

903 904 905
#define ISC__BUFFER_PUTUINT32(_b, _val) \
	do { \
		unsigned char *_cp; \
906
		isc_uint32_t _val2 = (_val); \
David Lawrence's avatar
David Lawrence committed
907
		_cp = isc_buffer_used(_b); \
908
		(_b)->used += 4; \
909 910 911 912
		_cp[0] = (unsigned char)((_val2 & 0xff000000) >> 24); \
		_cp[1] = (unsigned char)((_val2 & 0x00ff0000) >> 16); \
		_cp[2] = (unsigned char)((_val2 & 0x0000ff00) >> 8); \
		_cp[3] = (unsigned char)((_val2 & 0x000000ff)); \
913 914 915 916
	} while (0)

#if defined(ISC_BUFFER_USEINLINE)
#define isc_buffer_init			ISC__BUFFER_INIT
917
#define isc_buffer_initnull		ISC__BUFFER_INITNULL
918 919 920 921 922 923 924 925 926 927 928 929 930 931
#define isc_buffer_invalidate		ISC__BUFFER_INVALIDATE
#define isc_buffer_region		ISC__BUFFER_REGION
#define isc_buffer_usedregion		ISC__BUFFER_USEDREGION
#define isc_buffer_availableregion	ISC__BUFFER_AVAILABLEREGION
#define isc_buffer_add			ISC__BUFFER_ADD
#define isc_buffer_subtract		ISC__BUFFER_SUBTRACT
#define isc_buffer_clear		ISC__BUFFER_CLEAR
#define isc_buffer_consumedregion	ISC__BUFFER_CONSUMEDREGION
#define isc_buffer_remainingregion	ISC__BUFFER_REMAININGREGION
#define isc_buffer_activeregion		ISC__BUFFER_ACTIVEREGION
#define isc_buffer_setactive		ISC__BUFFER_SETACTIVE
#define isc_buffer_first		ISC__BUFFER_FIRST
#define isc_buffer_forward		ISC__BUFFER_FORWARD
#define isc_buffer_back			ISC__BUFFER_BACK
David Lawrence's avatar
David Lawrence committed
932 933
#define isc_buffer_putmem		ISC__BUFFER_PUTMEM
#define isc_buffer_putstr		ISC__BUFFER_PUTSTR
934 935
#define isc_buffer_putuint8		ISC__BUFFER_PUTUINT8
#define isc_buffer_putuint16		ISC__BUFFER_PUTUINT16
936
#define isc_buffer_putuint24		ISC__BUFFER_PUTUINT24
937 938 939
#define isc_buffer_putuint32		ISC__BUFFER_PUTUINT32
#else
#define isc_buffer_init			isc__buffer_init
940
#define isc_buffer_initnull		isc__buffer_initnull
941 942 943 944 945 946 947 948 949 950 951 952 953 954
#define isc_buffer_invalidate		isc__buffer_invalidate
#define isc_buffer_region		isc__buffer_region
#define isc_buffer_usedregion		isc__buffer_usedregion
#define isc_buffer_availableregion	isc__buffer_availableregion
#define isc_buffer_add			isc__buffer_add
#define isc_buffer_subtract		isc__buffer_subtract
#define isc_buffer_clear		isc__buffer_clear
#define isc_buffer_consumedregion	isc__buffer_consumedregion
#define isc_buffer_remainingregion	isc__buffer_remainingregion
#define isc_buffer_activeregion		isc__buffer_activeregion
#define isc_buffer_setactive		isc__buffer_setactive
#define isc_buffer_first		isc__buffer_first
#define isc_buffer_forward		isc__buffer_forward
#define isc_buffer_back			isc__buffer_back
David Lawrence's avatar
David Lawrence committed
955 956
#define isc_buffer_putmem		isc__buffer_putmem
#define isc_buffer_putstr		isc__buffer_putstr
957 958
#define isc_buffer_putuint8		isc__buffer_putuint8
#define isc_buffer_putuint16		isc__buffer_putuint16
959
#define isc_buffer_putuint24		isc__buffer_putuint24
960 961
#define isc_buffer_putuint32		isc__buffer_putuint32
#endif
Andreas Gustafsson's avatar
Andreas Gustafsson committed
962

963 964 965 966 967 968 969
#define isc_buffer_constinit(_b, _d, _l) \
	do { \
		union { void *_var; const void *_const; } _deconst; \
		_deconst._const = (_d); \
		isc_buffer_init((_b), _deconst._var, (_l)); \
	} while (0)

970 971 972 973 974
/*
 * No inline method for this one (yet).
 */
#define isc_buffer_putuint48		isc__buffer_putuint48

Bob Halley's avatar
add  
Bob Halley committed
975
#endif /* ISC_BUFFER_H */