buffer.h 22.4 KB
Newer Older
Bob Halley's avatar
Bob Halley committed
1
/*
Tinderbox User's avatar
Tinderbox User committed
2
 * Copyright (C) 2004-2008, 2010, 2012, 2014  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

Automatic Updater's avatar
Automatic Updater committed
18
/* $Id: buffer.h,v 1.55 2010/12/20 23:47:21 tbox Exp $ */
David Lawrence's avatar
David Lawrence committed
19

Bob Halley's avatar
add    
Bob Halley committed
20
21
22
23
24
25
26
#ifndef ISC_BUFFER_H
#define ISC_BUFFER_H 1

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

27
/*! \file isc/buffer.h
Bob Halley's avatar
add    
Bob Halley committed
28
 *
29
 * \brief A buffer is a region of memory, together with a set of related subregions.
Bob Halley's avatar
add    
Bob Halley committed
30
31
32
33
34
35
36
37
38
39
40
41
 * 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
42
43
 * 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
44
45
46
 * 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
47
48
49
50
51
52
 * 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.
 *
53
 * \verbatim
54
 *  /------------entire length---------------\
55
56
57
58
59
60
61
62
63
64
65
66
 *  /----- 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
67
 * a-e == entire length of buffer.
68
69
70
71
 * a-d == used region.
 * a-b == consumed region.
 * b-d == remaining region.
 * b-c == optional active region.
72
 *\endverbatim
73
 *
Bob Halley's avatar
add    
Bob Halley committed
74
75
 * The following invariants are maintained by all routines:
 *
76
 *\code
Bob Halley's avatar
add    
Bob Halley committed
77
78
79
80
81
82
 *	length > 0
 *
 *	base is a valid pointer to length bytes of memory
 *
 *	0 <= used <= length
 *
83
 *	0 <= current <= used
Bob Halley's avatar
add    
Bob Halley committed
84
 *
Bob Halley's avatar
Bob Halley committed
85
 *	0 <= active <= used
86
 *	(although active < current implies empty active region)
87
 *\endcode
Bob Halley's avatar
Bob Halley committed
88
 *
89
 * \li MP:
Bob Halley's avatar
add    
Bob Halley committed
90
91
92
 *	Buffers have no synchronization.  Clients must ensure exclusive
 *	access.
 *
93
 * \li Reliability:
Bob Halley's avatar
add    
Bob Halley committed
94
95
 *	No anticipated impact.
 *
96
 * \li Resources:
97
 *	Memory: 1 pointer + 6 unsigned integers per buffer.
Bob Halley's avatar
add    
Bob Halley committed
98
 *
99
 * \li Security:
Bob Halley's avatar
add    
Bob Halley committed
100
101
 *	No anticipated impact.
 *
102
 * \li Standards:
Bob Halley's avatar
add    
Bob Halley committed
103
104
105
106
107
108
109
 *	None.
 */

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

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

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

Bob Halley's avatar
Bob Halley committed
120
121
ISC_LANG_BEGINDECLS

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

130
131
132
133
134
135
136
/*
 * 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.)
 */

137
138
/*@{*/
/*!
139
 * Fundamental buffer elements.  (A through E in the introductory comment.)
140
 */
David Lawrence's avatar
David Lawrence committed
141
142
143
144
145
146
147
148
#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*/
149
/*@}*/
150

151
152
/*@{*/
/*!
153
 * Derived lengths.  (Described in the introductory comment.)
154
 */
155
156
157
158
159
#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 */
160
/*@}*/
161

162
/*!
Bob Halley's avatar
add    
Bob Halley committed
163
164
165
166
167
 * 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.
 */

168
169
170
struct isc_buffer {
	unsigned int		magic;
	void		       *base;
171
	/*@{*/
172
	/*! The following integers are byte offsets from 'base'. */
173
174
175
176
	unsigned int		length;
	unsigned int		used;
	unsigned int 		current;
	unsigned int 		active;
177
	/*@}*/
178
	/*! linkable */
179
	ISC_LINK(isc_buffer_t)	link;
180
	/*! private internal elements */
181
182
183
	isc_mem_t	       *mctx;
};

Bob Halley's avatar
add    
Bob Halley committed
184
185
186
187
/***
 *** Functions
 ***/

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

208
void
209
isc_buffer_free(isc_buffer_t **dynbuffer);
210
211
/*!<
 * \brief Release resources allocated for a dynamic buffer.
212
213
 *
 * Requires:
214
 *\li	"dynbuffer" is not NULL.
215
 *
216
 *\li	"*dynbuffer" is a valid dynamic buffer.
217
218
 *
 * Ensures:
219
 *\li	"*dynbuffer" will be NULL on return, and all memory associated with
220
221
 *	the dynamic buffer is returned to the memory context used in
 *	isc_buffer_allocate().
222
 */
Bob Halley's avatar
add    
Bob Halley committed
223
224

void
225
isc__buffer_init(isc_buffer_t *b, void *base, unsigned int length);
226
227
/*!<
 * \brief Make 'b' refer to the 'length'-byte region starting at base.
Bob Halley's avatar
add    
Bob Halley committed
228
229
230
 *
 * Requires:
 *
231
 *\li	'length' > 0
Bob Halley's avatar
add    
Bob Halley committed
232
 *
233
 *\li	'base' is a pointer to a sequence of 'length' bytes.
Bob Halley's avatar
add    
Bob Halley committed
234
235
 *
 */
236

237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
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.
 *
 */

257
void
258
isc__buffer_invalidate(isc_buffer_t *b);
259
260
/*!<
 * \brief Make 'b' an invalid buffer.
261
262
 *
 * Requires:
263
 *\li	'b' is a valid buffer.
264
265
 *
 * Ensures:
266
 *\li	If assertion checking is enabled, future attempts to use 'b' without
267
268
 *	calling isc_buffer_init() on it will cause an assertion failure.
 */
269

Bob Halley's avatar
add    
Bob Halley committed
270
void
271
isc__buffer_region(isc_buffer_t *b, isc_region_t *r);
272
273
/*!<
 * \brief Make 'r' refer to the region of 'b'.
Bob Halley's avatar
add    
Bob Halley committed
274
275
276
 *
 * Requires:
 *
277
 *\li	'b' is a valid buffer.
Bob Halley's avatar
add    
Bob Halley committed
278
 *
279
 *\li	'r' points to a region structure.
Bob Halley's avatar
add    
Bob Halley committed
280
281
282
 */

void
283
isc__buffer_usedregion(isc_buffer_t *b, isc_region_t *r);
284
285
/*!<
 * \brief Make 'r' refer to the used region of 'b'.
Bob Halley's avatar
add    
Bob Halley committed
286
287
288
 *
 * Requires:
 *
289
 *\li	'b' is a valid buffer.
Bob Halley's avatar
add    
Bob Halley committed
290
 *
291
 *\li	'r' points to a region structure.
Bob Halley's avatar
add    
Bob Halley committed
292
293
294
 */

void
295
isc__buffer_availableregion(isc_buffer_t *b, isc_region_t *r);
296
297
/*!<
 * \brief Make 'r' refer to the available region of 'b'.
Bob Halley's avatar
add    
Bob Halley committed
298
299
300
 *
 * Requires:
 *
301
 *\li	'b' is a valid buffer.
Bob Halley's avatar
add    
Bob Halley committed
302
 *
303
 *\li	'r' points to a region structure.
Bob Halley's avatar
add    
Bob Halley committed
304
305
306
 */

void
307
isc__buffer_add(isc_buffer_t *b, unsigned int n);
308
309
/*!<
 * \brief Increase the 'used' region of 'b' by 'n' bytes.
Bob Halley's avatar
add    
Bob Halley committed
310
311
312
 *
 * Requires:
 *
313
 *\li	'b' is a valid buffer
Bob Halley's avatar
add    
Bob Halley committed
314
 *
315
 *\li	used + n <= length
Bob Halley's avatar
add    
Bob Halley committed
316
317
318
319
 *
 */

void
320
isc__buffer_subtract(isc_buffer_t *b, unsigned int n);
321
322
/*!<
 * \brief Decrease the 'used' region of 'b' by 'n' bytes.
Bob Halley's avatar
add    
Bob Halley committed
323
324
325
 *
 * Requires:
 *
326
 *\li	'b' is a valid buffer
Bob Halley's avatar
add    
Bob Halley committed
327
 *
328
 *\li	used >= n
Bob Halley's avatar
add    
Bob Halley committed
329
330
331
332
 *
 */

void
333
isc__buffer_clear(isc_buffer_t *b);
334
335
/*!<
 * \brief Make the used region empty.
Bob Halley's avatar
add    
Bob Halley committed
336
337
338
 *
 * Requires:
 *
339
 *\li	'b' is a valid buffer
Bob Halley's avatar
add    
Bob Halley committed
340
341
342
 *
 * Ensures:
 *
343
 *\li	used = 0
Bob Halley's avatar
add    
Bob Halley committed
344
345
346
347
 *
 */

void
348
isc__buffer_consumedregion(isc_buffer_t *b, isc_region_t *r);
349
350
/*!<
 * \brief Make 'r' refer to the consumed region of 'b'.
Bob Halley's avatar
add    
Bob Halley committed
351
352
353
 *
 * Requires:
 *
354
 *\li	'b' is a valid buffer.
Bob Halley's avatar
add    
Bob Halley committed
355
 *
356
 *\li	'r' points to a region structure.
Bob Halley's avatar
add    
Bob Halley committed
357
358
359
 */

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

Bob Halley's avatar
Bob Halley committed
371
void
372
isc__buffer_activeregion(isc_buffer_t *b, isc_region_t *r);
373
374
/*!<
 * \brief Make 'r' refer to the active region of 'b'.
Bob Halley's avatar
Bob Halley committed
375
376
377
 *
 * Requires:
 *
378
 *\li	'b' is a valid buffer.
Bob Halley's avatar
Bob Halley committed
379
 *
380
 *\li	'r' points to a region structure.
Bob Halley's avatar
Bob Halley committed
381
382
383
 */

void
384
isc__buffer_setactive(isc_buffer_t *b, unsigned int n);
385
386
/*!<
 * \brief Sets the end of the active region 'n' bytes after current.
Bob Halley's avatar
Bob Halley committed
387
388
389
 *
 * Requires:
 *
390
 *\li	'b' is a valid buffer.
Bob Halley's avatar
Bob Halley committed
391
 *
392
 *\li	current + n <= used
Bob Halley's avatar
Bob Halley committed
393
394
 */

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

void
411
isc__buffer_forward(isc_buffer_t *b, unsigned int n);
412
413
/*!<
 * \brief Increase the 'consumed' region of 'b' by 'n' bytes.
Bob Halley's avatar
add    
Bob Halley committed
414
415
416
 *
 * Requires:
 *
417
 *\li	'b' is a valid buffer
Bob Halley's avatar
add    
Bob Halley committed
418
 *
419
 *\li	current + n <= used
Bob Halley's avatar
add    
Bob Halley committed
420
421
422
423
 *
 */

void
424
isc__buffer_back(isc_buffer_t *b, unsigned int n);
425
426
/*!<
 * \brief Decrease the 'consumed' region of 'b' by 'n' bytes.
Bob Halley's avatar
add    
Bob Halley committed
427
428
429
 *
 * Requires:
 *
430
 *\li	'b' is a valid buffer
Bob Halley's avatar
add    
Bob Halley committed
431
 *
432
 *\li	n <= current
Bob Halley's avatar
add    
Bob Halley committed
433
434
435
436
 *
 */

void
Bob Halley's avatar
Bob Halley committed
437
isc_buffer_compact(isc_buffer_t *b);
438
439
/*!<
 * \brief Compact the used region by moving the remaining region so it occurs
Bob Halley's avatar
add    
Bob Halley committed
440
441
442
443
444
 * 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:
 *
445
 *\li	'b' is a valid buffer
Bob Halley's avatar
add    
Bob Halley committed
446
447
448
 *
 * Ensures:
 *
449
 *\li	current == 0
Bob Halley's avatar
add    
Bob Halley committed
450
 *
451
 *\li	The size of the used region is now equal to the size of the remaining
Bob Halley's avatar
add    
Bob Halley committed
452
453
454
455
 *	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).
 */

456
457
isc_uint8_t
isc_buffer_getuint8(isc_buffer_t *b);
458
459
/*!<
 * \brief Read an unsigned 8-bit integer from 'b' and return it.
460
461
462
 *
 * Requires:
 *
463
 *\li	'b' is a valid buffer.
464
 *
465
 *\li	The length of the available region of 'b' is at least 1.
466
467
468
 *
 * Ensures:
 *
469
 *\li	The current pointer in 'b' is advanced by 1.
470
471
472
 *
 * Returns:
 *
473
 *\li	A 8-bit unsigned integer.
474
475
476
 */

void
477
isc__buffer_putuint8(isc_buffer_t *b, isc_uint8_t val);
478
479
/*!<
 * \brief Store an unsigned 8-bit integer from 'val' into 'b'.
480
481
 *
 * Requires:
482
 *\li	'b' is a valid buffer.
483
 *
484
 *\li	The length of the unused region of 'b' is at least 1.
485
486
 *
 * Ensures:
487
 *\li	The used pointer in 'b' is advanced by 1.
488
489
 */

Bob Halley's avatar
Bob Halley committed
490
491
isc_uint16_t
isc_buffer_getuint16(isc_buffer_t *b);
492
493
/*!<
 * \brief Read an unsigned 16-bit integer in network byte order from 'b', convert
Bob Halley's avatar
Bob Halley committed
494
495
496
497
 * it to host byte order, and return it.
 *
 * Requires:
 *
498
 *\li	'b' is a valid buffer.
Bob Halley's avatar
Bob Halley committed
499
 *
500
 *\li	The length of the available region of 'b' is at least 2.
Bob Halley's avatar
Bob Halley committed
501
502
503
 *
 * Ensures:
 *
504
 *\li	The current pointer in 'b' is advanced by 2.
Bob Halley's avatar
Bob Halley committed
505
506
507
 *
 * Returns:
 *
508
 *\li	A 16-bit unsigned integer.
Bob Halley's avatar
Bob Halley committed
509
510
 */

511
void
512
isc__buffer_putuint16(isc_buffer_t *b, isc_uint16_t val);
513
514
/*!<
 * \brief Store an unsigned 16-bit integer in host byte order from 'val'
515
516
517
 * into 'b' in network byte order.
 *
 * Requires:
518
 *\li	'b' is a valid buffer.
519
 *
520
 *\li	The length of the unused region of 'b' is at least 2.
521
522
 *
 * Ensures:
523
 *\li	The used pointer in 'b' is advanced by 2.
524
525
 */

Bob Halley's avatar
Bob Halley committed
526
527
isc_uint32_t
isc_buffer_getuint32(isc_buffer_t *b);
528
529
/*!<
 * \brief Read an unsigned 32-bit integer in network byte order from 'b', convert
Bob Halley's avatar
Bob Halley committed
530
531
532
533
 * it to host byte order, and return it.
 *
 * Requires:
 *
534
 *\li	'b' is a valid buffer.
Bob Halley's avatar
Bob Halley committed
535
 *
536
 *\li	The length of the available region of 'b' is at least 4.
Bob Halley's avatar
Bob Halley committed
537
538
539
 *
 * Ensures:
 *
540
 *\li	The current pointer in 'b' is advanced by 4.
Bob Halley's avatar
Bob Halley committed
541
542
543
 *
 * Returns:
 *
544
 *\li	A 32-bit unsigned integer.
Bob Halley's avatar
Bob Halley committed
545
546
 */

547
void
548
isc__buffer_putuint32(isc_buffer_t *b, isc_uint32_t val);
549
550
/*!<
 * \brief Store an unsigned 32-bit integer in host byte order from 'val'
551
552
553
 * into 'b' in network byte order.
 *
 * Requires:
554
 *\li	'b' is a valid buffer.
555
 *
556
 *\li	The length of the unused region of 'b' is at least 4.
557
558
 *
 * Ensures:
559
 *\li	The used pointer in 'b' is advanced by 4.
560
561
 */

562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
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.
 *
 *\li	The length of the unused region of 'b' is at least 6.
 *
 * Ensures:
 *\li	The used pointer in 'b' is advanced by 6.
 */

598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
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.
 *
 *	The length of the unused region of 'b' is at least 3.
 *
 * Ensures:
 *\li	The used pointer in 'b' is advanced by 3.
 */

Andreas Gustafsson's avatar
Andreas Gustafsson committed
613
void
David Lawrence's avatar
David Lawrence committed
614
615
isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base,
		   unsigned int length);
616
617
/*!<
 * \brief Copy 'length' bytes of memory at 'base' into 'b'.
Andreas Gustafsson's avatar
Andreas Gustafsson committed
618
619
 *
 * Requires:
620
 *\li	'b' is a valid buffer.
Andreas Gustafsson's avatar
Andreas Gustafsson committed
621
 *
622
 *\li	'base' points to 'length' bytes of valid memory.
Andreas Gustafsson's avatar
Andreas Gustafsson committed
623
 *
Mark Andrews's avatar
Mark Andrews committed
624
625
 */

Automatic Updater's avatar
Automatic Updater committed
626
void
David Lawrence's avatar
David Lawrence committed
627
isc__buffer_putstr(isc_buffer_t *b, const char *source);
628
629
/*!<
 * \brief Copy 'source' into 'b', not including terminating NUL.
Mark Andrews's avatar
Mark Andrews committed
630
631
 *
 * Requires:
632
 *\li	'b' is a valid buffer.
Mark Andrews's avatar
Mark Andrews committed
633
 *
634
 *\li	'source' to be a valid NULL terminated string.
Mark Andrews's avatar
Mark Andrews committed
635
 *
636
 *\li	strlen(source) <= isc_buffer_available(b)
Andreas Gustafsson's avatar
Andreas Gustafsson committed
637
638
 */

Bob Halley's avatar
Bob Halley committed
639
isc_result_t
640
isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r);
641
642
/*!<
 * \brief Copy the contents of 'r' into 'b'.
Bob Halley's avatar
Bob Halley committed
643
644
 *
 * Requires:
645
 *\li	'b' is a valid buffer.
Bob Halley's avatar
Bob Halley committed
646
 *
647
 *\li	'r' is a valid region.
Bob Halley's avatar
Bob Halley committed
648
649
650
 *
 * Returns:
 *
651
652
 *\li	ISC_R_SUCCESS
 *\li	ISC_R_NOSPACE			The available region of 'b' is not
Bob Halley's avatar
Bob Halley committed
653
654
655
 *					big enough.
 */

David Lawrence's avatar
David Lawrence committed
656
657
ISC_LANG_ENDDECLS

658
659
660
661
662
663
664
/*
 * 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__"
 */

665
/*! \note
David Lawrence's avatar
David Lawrence committed
666
 * XXXDCL Something more could be done with initializing buffers that
667
668
669
670
671
672
 * 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
673
674
675
676
677
678
679
680
681
 * 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.
 */
682
#define ISC__BUFFER_INIT(_b, _base, _length) \
683
	do { \
684
		(_b)->base = _base; \
685
686
687
688
689
		(_b)->length = (_length); \
		(_b)->used = 0; \
		(_b)->current = 0; \
		(_b)->active = 0; \
		(_b)->mctx = NULL; \
690
		ISC_LINK_INIT(_b, link); \
David Lawrence's avatar
David Lawrence committed
691
		(_b)->magic = ISC_BUFFER_MAGIC; \
692
693
	} while (0)

694
695
#define ISC__BUFFER_INITNULL(_b) ISC__BUFFER_INIT(_b, NULL, 0)

696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
#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
720
721
		(_r)->base = isc_buffer_used(_b); \
		(_r)->length = isc_buffer_availablelength(_b); \
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
	} 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 { \
747
		(_r)->base = (_b)->base; \
748
749
750
751
752
		(_r)->length = (_b)->current; \
	} while (0)

#define ISC__BUFFER_REMAININGREGION(_b, _r) \
	do { \
David Lawrence's avatar
David Lawrence committed
753
754
		(_r)->base = isc_buffer_current(_b); \
		(_r)->length = isc_buffer_remaininglength(_b); \
755
756
757
758
759
	} while (0)

#define ISC__BUFFER_ACTIVEREGION(_b, _r) \
	do { \
		if ((_b)->current < (_b)->active) { \
David Lawrence's avatar
David Lawrence committed
760
761
			(_r)->base = isc_buffer_current(_b); \
			(_r)->length = isc_buffer_activelength(_b); \
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
		} 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
788
789
#define ISC__BUFFER_PUTMEM(_b, _base, _length) \
	do { \
790
		memmove(isc_buffer_used(_b), (_base), (_length)); \
David Lawrence's avatar
David Lawrence committed
791
792
793
794
795
796
797
798
799
		(_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); \
800
		memmove(_cp, (_source), _length); \
David Lawrence's avatar
David Lawrence committed
801
802
803
		(_b)->used += (_length); \
	} while (0)

804
805
806
#define ISC__BUFFER_PUTUINT8(_b, _val) \
	do { \
		unsigned char *_cp; \
807
		isc_uint8_t _val2 = (_val); \
David Lawrence's avatar
David Lawrence committed
808
		_cp = isc_buffer_used(_b); \
809
		(_b)->used++; \
810
		_cp[0] = _val2 & 0x00ff; \
811
812
813
814
815
	} while (0)

#define ISC__BUFFER_PUTUINT16(_b, _val) \
	do { \
		unsigned char *_cp; \
816
		isc_uint16_t _val2 = (_val); \
David Lawrence's avatar
David Lawrence committed
817
		_cp = isc_buffer_used(_b); \
818
		(_b)->used += 2; \
819
820
		_cp[0] = (unsigned char)((_val2 & 0xff00U) >> 8); \
		_cp[1] = (unsigned char)(_val2 & 0x00ffU); \
821
822
	} while (0)

823
824
825
826
827
828
829
830
831
832
833
#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)

834
835
836
#define ISC__BUFFER_PUTUINT32(_b, _val) \
	do { \
		unsigned char *_cp; \
837
		isc_uint32_t _val2 = (_val); \
David Lawrence's avatar
David Lawrence committed
838
		_cp = isc_buffer_used(_b); \
839
		(_b)->used += 4; \
840
841
842
843
		_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)); \
844
845
846
847
	} while (0)

#if defined(ISC_BUFFER_USEINLINE)
#define isc_buffer_init			ISC__BUFFER_INIT
848
#define isc_buffer_initnull		ISC__BUFFER_INITNULL
849
850
851
852
853
854
855
856
857
858
859
860
861
862
#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
863
864
#define isc_buffer_putmem		ISC__BUFFER_PUTMEM
#define isc_buffer_putstr		ISC__BUFFER_PUTSTR
865
866
#define isc_buffer_putuint8		ISC__BUFFER_PUTUINT8
#define isc_buffer_putuint16		ISC__BUFFER_PUTUINT16
867
#define isc_buffer_putuint24		ISC__BUFFER_PUTUINT24
868
869
870
#define isc_buffer_putuint32		ISC__BUFFER_PUTUINT32
#else
#define isc_buffer_init			isc__buffer_init
871
#define isc_buffer_initnull		isc__buffer_initnull
872
873
874
875
876
877
878
879
880
881
882
883
884
885
#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
886
887
#define isc_buffer_putmem		isc__buffer_putmem
#define isc_buffer_putstr		isc__buffer_putstr
888
889
#define isc_buffer_putuint8		isc__buffer_putuint8
#define isc_buffer_putuint16		isc__buffer_putuint16
890
#define isc_buffer_putuint24		isc__buffer_putuint24
891
892
#define isc_buffer_putuint32		isc__buffer_putuint32
#endif
Andreas Gustafsson's avatar
Andreas Gustafsson committed
893

894
895
896
897
898
899
900
#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)

901
902
903
904
905
/*
 * No inline method for this one (yet).
 */
#define isc_buffer_putuint48		isc__buffer_putuint48

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