xref: /minix3/external/bsd/bind/dist/lib/isc/buffer.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: buffer.c,v 1.6 2014/12/10 04:37:59 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2004-2008, 2012, 2014  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  * Copyright (C) 1998-2002  Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek  *
7*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek  *
11*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek  */
19*00b67f09SDavid van Moolenbroek 
20*00b67f09SDavid van Moolenbroek /* Id: buffer.c,v 1.49 2008/09/25 04:02:39 tbox Exp  */
21*00b67f09SDavid van Moolenbroek 
22*00b67f09SDavid van Moolenbroek /*! \file */
23*00b67f09SDavid van Moolenbroek 
24*00b67f09SDavid van Moolenbroek #include <config.h>
25*00b67f09SDavid van Moolenbroek 
26*00b67f09SDavid van Moolenbroek #include <isc/buffer.h>
27*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
28*00b67f09SDavid van Moolenbroek #include <isc/region.h>
29*00b67f09SDavid van Moolenbroek #include <isc/string.h>
30*00b67f09SDavid van Moolenbroek #include <isc/util.h>
31*00b67f09SDavid van Moolenbroek 
32*00b67f09SDavid van Moolenbroek void
isc__buffer_init(isc_buffer_t * b,void * base,unsigned int length)33*00b67f09SDavid van Moolenbroek isc__buffer_init(isc_buffer_t *b, void *base, unsigned int length) {
34*00b67f09SDavid van Moolenbroek 	/*
35*00b67f09SDavid van Moolenbroek 	 * Make 'b' refer to the 'length'-byte region starting at 'base'.
36*00b67f09SDavid van Moolenbroek 	 * XXXDCL see the comment in buffer.h about base being const.
37*00b67f09SDavid van Moolenbroek 	 */
38*00b67f09SDavid van Moolenbroek 
39*00b67f09SDavid van Moolenbroek 	REQUIRE(b != NULL);
40*00b67f09SDavid van Moolenbroek 
41*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_INIT(b, base, length);
42*00b67f09SDavid van Moolenbroek }
43*00b67f09SDavid van Moolenbroek 
44*00b67f09SDavid van Moolenbroek void
isc__buffer_initnull(isc_buffer_t * b)45*00b67f09SDavid van Moolenbroek isc__buffer_initnull(isc_buffer_t *b) {
46*00b67f09SDavid van Moolenbroek 	/*
47*00b67f09SDavid van Moolenbroek 	 * Initialize a new buffer which has no backing store.  This can
48*00b67f09SDavid van Moolenbroek 	 * later be grown as needed and swapped in place.
49*00b67f09SDavid van Moolenbroek 	 */
50*00b67f09SDavid van Moolenbroek 
51*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_INIT(b, NULL, 0);
52*00b67f09SDavid van Moolenbroek }
53*00b67f09SDavid van Moolenbroek 
54*00b67f09SDavid van Moolenbroek void
isc_buffer_reinit(isc_buffer_t * b,void * base,unsigned int length)55*00b67f09SDavid van Moolenbroek isc_buffer_reinit(isc_buffer_t *b, void *base, unsigned int length) {
56*00b67f09SDavid van Moolenbroek 	/*
57*00b67f09SDavid van Moolenbroek 	 * Re-initialize the buffer enough to reconfigure the base of the
58*00b67f09SDavid van Moolenbroek 	 * buffer.  We will swap in the new buffer, after copying any
59*00b67f09SDavid van Moolenbroek 	 * data we contain into the new buffer and adjusting all of our
60*00b67f09SDavid van Moolenbroek 	 * internal pointers.
61*00b67f09SDavid van Moolenbroek 	 *
62*00b67f09SDavid van Moolenbroek 	 * The buffer must not be smaller than the length of the original
63*00b67f09SDavid van Moolenbroek 	 * buffer.
64*00b67f09SDavid van Moolenbroek 	 */
65*00b67f09SDavid van Moolenbroek 	REQUIRE(b->length <= length);
66*00b67f09SDavid van Moolenbroek 	REQUIRE(base != NULL);
67*00b67f09SDavid van Moolenbroek 
68*00b67f09SDavid van Moolenbroek 	(void)memmove(base, b->base, b->length);
69*00b67f09SDavid van Moolenbroek 	b->base = base;
70*00b67f09SDavid van Moolenbroek 	b->length = length;
71*00b67f09SDavid van Moolenbroek }
72*00b67f09SDavid van Moolenbroek 
73*00b67f09SDavid van Moolenbroek void
isc__buffer_invalidate(isc_buffer_t * b)74*00b67f09SDavid van Moolenbroek isc__buffer_invalidate(isc_buffer_t *b) {
75*00b67f09SDavid van Moolenbroek 	/*
76*00b67f09SDavid van Moolenbroek 	 * Make 'b' an invalid buffer.
77*00b67f09SDavid van Moolenbroek 	 */
78*00b67f09SDavid van Moolenbroek 
79*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
80*00b67f09SDavid van Moolenbroek 	REQUIRE(!ISC_LINK_LINKED(b, link));
81*00b67f09SDavid van Moolenbroek 	REQUIRE(b->mctx == NULL);
82*00b67f09SDavid van Moolenbroek 
83*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_INVALIDATE(b);
84*00b67f09SDavid van Moolenbroek }
85*00b67f09SDavid van Moolenbroek 
86*00b67f09SDavid van Moolenbroek void
isc__buffer_region(isc_buffer_t * b,isc_region_t * r)87*00b67f09SDavid van Moolenbroek isc__buffer_region(isc_buffer_t *b, isc_region_t *r) {
88*00b67f09SDavid van Moolenbroek 	/*
89*00b67f09SDavid van Moolenbroek 	 * Make 'r' refer to the region of 'b'.
90*00b67f09SDavid van Moolenbroek 	 */
91*00b67f09SDavid van Moolenbroek 
92*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
93*00b67f09SDavid van Moolenbroek 	REQUIRE(r != NULL);
94*00b67f09SDavid van Moolenbroek 
95*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_REGION(b, r);
96*00b67f09SDavid van Moolenbroek }
97*00b67f09SDavid van Moolenbroek 
98*00b67f09SDavid van Moolenbroek void
isc__buffer_usedregion(isc_buffer_t * b,isc_region_t * r)99*00b67f09SDavid van Moolenbroek isc__buffer_usedregion(isc_buffer_t *b, isc_region_t *r) {
100*00b67f09SDavid van Moolenbroek 	/*
101*00b67f09SDavid van Moolenbroek 	 * Make 'r' refer to the used region of 'b'.
102*00b67f09SDavid van Moolenbroek 	 */
103*00b67f09SDavid van Moolenbroek 
104*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
105*00b67f09SDavid van Moolenbroek 	REQUIRE(r != NULL);
106*00b67f09SDavid van Moolenbroek 
107*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_USEDREGION(b, r);
108*00b67f09SDavid van Moolenbroek }
109*00b67f09SDavid van Moolenbroek 
110*00b67f09SDavid van Moolenbroek void
isc__buffer_availableregion(isc_buffer_t * b,isc_region_t * r)111*00b67f09SDavid van Moolenbroek isc__buffer_availableregion(isc_buffer_t *b, isc_region_t *r) {
112*00b67f09SDavid van Moolenbroek 	/*
113*00b67f09SDavid van Moolenbroek 	 * Make 'r' refer to the available region of 'b'.
114*00b67f09SDavid van Moolenbroek 	 */
115*00b67f09SDavid van Moolenbroek 
116*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
117*00b67f09SDavid van Moolenbroek 	REQUIRE(r != NULL);
118*00b67f09SDavid van Moolenbroek 
119*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_AVAILABLEREGION(b, r);
120*00b67f09SDavid van Moolenbroek }
121*00b67f09SDavid van Moolenbroek 
122*00b67f09SDavid van Moolenbroek void
isc__buffer_add(isc_buffer_t * b,unsigned int n)123*00b67f09SDavid van Moolenbroek isc__buffer_add(isc_buffer_t *b, unsigned int n) {
124*00b67f09SDavid van Moolenbroek 	/*
125*00b67f09SDavid van Moolenbroek 	 * Increase the 'used' region of 'b' by 'n' bytes.
126*00b67f09SDavid van Moolenbroek 	 */
127*00b67f09SDavid van Moolenbroek 
128*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
129*00b67f09SDavid van Moolenbroek 	REQUIRE(b->used + n <= b->length);
130*00b67f09SDavid van Moolenbroek 
131*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_ADD(b, n);
132*00b67f09SDavid van Moolenbroek }
133*00b67f09SDavid van Moolenbroek 
134*00b67f09SDavid van Moolenbroek void
isc__buffer_subtract(isc_buffer_t * b,unsigned int n)135*00b67f09SDavid van Moolenbroek isc__buffer_subtract(isc_buffer_t *b, unsigned int n) {
136*00b67f09SDavid van Moolenbroek 	/*
137*00b67f09SDavid van Moolenbroek 	 * Decrease the 'used' region of 'b' by 'n' bytes.
138*00b67f09SDavid van Moolenbroek 	 */
139*00b67f09SDavid van Moolenbroek 
140*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
141*00b67f09SDavid van Moolenbroek 	REQUIRE(b->used >= n);
142*00b67f09SDavid van Moolenbroek 
143*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_SUBTRACT(b, n);
144*00b67f09SDavid van Moolenbroek }
145*00b67f09SDavid van Moolenbroek 
146*00b67f09SDavid van Moolenbroek void
isc__buffer_clear(isc_buffer_t * b)147*00b67f09SDavid van Moolenbroek isc__buffer_clear(isc_buffer_t *b) {
148*00b67f09SDavid van Moolenbroek 	/*
149*00b67f09SDavid van Moolenbroek 	 * Make the used region empty.
150*00b67f09SDavid van Moolenbroek 	 */
151*00b67f09SDavid van Moolenbroek 
152*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
153*00b67f09SDavid van Moolenbroek 
154*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_CLEAR(b);
155*00b67f09SDavid van Moolenbroek }
156*00b67f09SDavid van Moolenbroek 
157*00b67f09SDavid van Moolenbroek void
isc__buffer_consumedregion(isc_buffer_t * b,isc_region_t * r)158*00b67f09SDavid van Moolenbroek isc__buffer_consumedregion(isc_buffer_t *b, isc_region_t *r) {
159*00b67f09SDavid van Moolenbroek 	/*
160*00b67f09SDavid van Moolenbroek 	 * Make 'r' refer to the consumed region of 'b'.
161*00b67f09SDavid van Moolenbroek 	 */
162*00b67f09SDavid van Moolenbroek 
163*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
164*00b67f09SDavid van Moolenbroek 	REQUIRE(r != NULL);
165*00b67f09SDavid van Moolenbroek 
166*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_CONSUMEDREGION(b, r);
167*00b67f09SDavid van Moolenbroek }
168*00b67f09SDavid van Moolenbroek 
169*00b67f09SDavid van Moolenbroek void
isc__buffer_remainingregion(isc_buffer_t * b,isc_region_t * r)170*00b67f09SDavid van Moolenbroek isc__buffer_remainingregion(isc_buffer_t *b, isc_region_t *r) {
171*00b67f09SDavid van Moolenbroek 	/*
172*00b67f09SDavid van Moolenbroek 	 * Make 'r' refer to the remaining region of 'b'.
173*00b67f09SDavid van Moolenbroek 	 */
174*00b67f09SDavid van Moolenbroek 
175*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
176*00b67f09SDavid van Moolenbroek 	REQUIRE(r != NULL);
177*00b67f09SDavid van Moolenbroek 
178*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_REMAININGREGION(b, r);
179*00b67f09SDavid van Moolenbroek }
180*00b67f09SDavid van Moolenbroek 
181*00b67f09SDavid van Moolenbroek void
isc__buffer_activeregion(isc_buffer_t * b,isc_region_t * r)182*00b67f09SDavid van Moolenbroek isc__buffer_activeregion(isc_buffer_t *b, isc_region_t *r) {
183*00b67f09SDavid van Moolenbroek 	/*
184*00b67f09SDavid van Moolenbroek 	 * Make 'r' refer to the active region of 'b'.
185*00b67f09SDavid van Moolenbroek 	 */
186*00b67f09SDavid van Moolenbroek 
187*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
188*00b67f09SDavid van Moolenbroek 	REQUIRE(r != NULL);
189*00b67f09SDavid van Moolenbroek 
190*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_ACTIVEREGION(b, r);
191*00b67f09SDavid van Moolenbroek }
192*00b67f09SDavid van Moolenbroek 
193*00b67f09SDavid van Moolenbroek void
isc__buffer_setactive(isc_buffer_t * b,unsigned int n)194*00b67f09SDavid van Moolenbroek isc__buffer_setactive(isc_buffer_t *b, unsigned int n) {
195*00b67f09SDavid van Moolenbroek 	/*
196*00b67f09SDavid van Moolenbroek 	 * Sets the end of the active region 'n' bytes after current.
197*00b67f09SDavid van Moolenbroek 	 */
198*00b67f09SDavid van Moolenbroek 
199*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
200*00b67f09SDavid van Moolenbroek 	REQUIRE(b->current + n <= b->used);
201*00b67f09SDavid van Moolenbroek 
202*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_SETACTIVE(b, n);
203*00b67f09SDavid van Moolenbroek }
204*00b67f09SDavid van Moolenbroek 
205*00b67f09SDavid van Moolenbroek void
isc__buffer_first(isc_buffer_t * b)206*00b67f09SDavid van Moolenbroek isc__buffer_first(isc_buffer_t *b) {
207*00b67f09SDavid van Moolenbroek 	/*
208*00b67f09SDavid van Moolenbroek 	 * Make the consumed region empty.
209*00b67f09SDavid van Moolenbroek 	 */
210*00b67f09SDavid van Moolenbroek 
211*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
212*00b67f09SDavid van Moolenbroek 
213*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_FIRST(b);
214*00b67f09SDavid van Moolenbroek }
215*00b67f09SDavid van Moolenbroek 
216*00b67f09SDavid van Moolenbroek void
isc__buffer_forward(isc_buffer_t * b,unsigned int n)217*00b67f09SDavid van Moolenbroek isc__buffer_forward(isc_buffer_t *b, unsigned int n) {
218*00b67f09SDavid van Moolenbroek 	/*
219*00b67f09SDavid van Moolenbroek 	 * Increase the 'consumed' region of 'b' by 'n' bytes.
220*00b67f09SDavid van Moolenbroek 	 */
221*00b67f09SDavid van Moolenbroek 
222*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
223*00b67f09SDavid van Moolenbroek 	REQUIRE(b->current + n <= b->used);
224*00b67f09SDavid van Moolenbroek 
225*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_FORWARD(b, n);
226*00b67f09SDavid van Moolenbroek }
227*00b67f09SDavid van Moolenbroek 
228*00b67f09SDavid van Moolenbroek void
isc__buffer_back(isc_buffer_t * b,unsigned int n)229*00b67f09SDavid van Moolenbroek isc__buffer_back(isc_buffer_t *b, unsigned int n) {
230*00b67f09SDavid van Moolenbroek 	/*
231*00b67f09SDavid van Moolenbroek 	 * Decrease the 'consumed' region of 'b' by 'n' bytes.
232*00b67f09SDavid van Moolenbroek 	 */
233*00b67f09SDavid van Moolenbroek 
234*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
235*00b67f09SDavid van Moolenbroek 	REQUIRE(n <= b->current);
236*00b67f09SDavid van Moolenbroek 
237*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_BACK(b, n);
238*00b67f09SDavid van Moolenbroek }
239*00b67f09SDavid van Moolenbroek 
240*00b67f09SDavid van Moolenbroek void
isc_buffer_compact(isc_buffer_t * b)241*00b67f09SDavid van Moolenbroek isc_buffer_compact(isc_buffer_t *b) {
242*00b67f09SDavid van Moolenbroek 	unsigned int length;
243*00b67f09SDavid van Moolenbroek 	void *src;
244*00b67f09SDavid van Moolenbroek 
245*00b67f09SDavid van Moolenbroek 	/*
246*00b67f09SDavid van Moolenbroek 	 * Compact the used region by moving the remaining region so it occurs
247*00b67f09SDavid van Moolenbroek 	 * at the start of the buffer.  The used region is shrunk by the size
248*00b67f09SDavid van Moolenbroek 	 * of the consumed region, and the consumed region is then made empty.
249*00b67f09SDavid van Moolenbroek 	 */
250*00b67f09SDavid van Moolenbroek 
251*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
252*00b67f09SDavid van Moolenbroek 
253*00b67f09SDavid van Moolenbroek 	src = isc_buffer_current(b);
254*00b67f09SDavid van Moolenbroek 	length = isc_buffer_remaininglength(b);
255*00b67f09SDavid van Moolenbroek 	(void)memmove(b->base, src, (size_t)length);
256*00b67f09SDavid van Moolenbroek 
257*00b67f09SDavid van Moolenbroek 	if (b->active > b->current)
258*00b67f09SDavid van Moolenbroek 		b->active -= b->current;
259*00b67f09SDavid van Moolenbroek 	else
260*00b67f09SDavid van Moolenbroek 		b->active = 0;
261*00b67f09SDavid van Moolenbroek 	b->current = 0;
262*00b67f09SDavid van Moolenbroek 	b->used = length;
263*00b67f09SDavid van Moolenbroek }
264*00b67f09SDavid van Moolenbroek 
265*00b67f09SDavid van Moolenbroek isc_uint8_t
isc_buffer_getuint8(isc_buffer_t * b)266*00b67f09SDavid van Moolenbroek isc_buffer_getuint8(isc_buffer_t *b) {
267*00b67f09SDavid van Moolenbroek 	unsigned char *cp;
268*00b67f09SDavid van Moolenbroek 	isc_uint8_t result;
269*00b67f09SDavid van Moolenbroek 
270*00b67f09SDavid van Moolenbroek 	/*
271*00b67f09SDavid van Moolenbroek 	 * Read an unsigned 8-bit integer from 'b' and return it.
272*00b67f09SDavid van Moolenbroek 	 */
273*00b67f09SDavid van Moolenbroek 
274*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
275*00b67f09SDavid van Moolenbroek 	REQUIRE(b->used - b->current >= 1);
276*00b67f09SDavid van Moolenbroek 
277*00b67f09SDavid van Moolenbroek 	cp = isc_buffer_current(b);
278*00b67f09SDavid van Moolenbroek 	b->current += 1;
279*00b67f09SDavid van Moolenbroek 	result = ((isc_uint8_t)(cp[0]));
280*00b67f09SDavid van Moolenbroek 
281*00b67f09SDavid van Moolenbroek 	return (result);
282*00b67f09SDavid van Moolenbroek }
283*00b67f09SDavid van Moolenbroek 
284*00b67f09SDavid van Moolenbroek void
isc__buffer_putuint8(isc_buffer_t * b,isc_uint8_t val)285*00b67f09SDavid van Moolenbroek isc__buffer_putuint8(isc_buffer_t *b, isc_uint8_t val) {
286*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
287*00b67f09SDavid van Moolenbroek 	REQUIRE(b->used + 1 <= b->length);
288*00b67f09SDavid van Moolenbroek 
289*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_PUTUINT8(b, val);
290*00b67f09SDavid van Moolenbroek }
291*00b67f09SDavid van Moolenbroek 
292*00b67f09SDavid van Moolenbroek isc_uint16_t
isc_buffer_getuint16(isc_buffer_t * b)293*00b67f09SDavid van Moolenbroek isc_buffer_getuint16(isc_buffer_t *b) {
294*00b67f09SDavid van Moolenbroek 	unsigned char *cp;
295*00b67f09SDavid van Moolenbroek 	isc_uint16_t result;
296*00b67f09SDavid van Moolenbroek 
297*00b67f09SDavid van Moolenbroek 	/*
298*00b67f09SDavid van Moolenbroek 	 * Read an unsigned 16-bit integer in network byte order from 'b',
299*00b67f09SDavid van Moolenbroek 	 * convert it to host byte order, and return it.
300*00b67f09SDavid van Moolenbroek 	 */
301*00b67f09SDavid van Moolenbroek 
302*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
303*00b67f09SDavid van Moolenbroek 	REQUIRE(b->used - b->current >= 2);
304*00b67f09SDavid van Moolenbroek 
305*00b67f09SDavid van Moolenbroek 	cp = isc_buffer_current(b);
306*00b67f09SDavid van Moolenbroek 	b->current += 2;
307*00b67f09SDavid van Moolenbroek 	result = ((unsigned int)(cp[0])) << 8;
308*00b67f09SDavid van Moolenbroek 	result |= ((unsigned int)(cp[1]));
309*00b67f09SDavid van Moolenbroek 
310*00b67f09SDavid van Moolenbroek 	return (result);
311*00b67f09SDavid van Moolenbroek }
312*00b67f09SDavid van Moolenbroek 
313*00b67f09SDavid van Moolenbroek void
isc__buffer_putuint16(isc_buffer_t * b,isc_uint16_t val)314*00b67f09SDavid van Moolenbroek isc__buffer_putuint16(isc_buffer_t *b, isc_uint16_t val) {
315*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
316*00b67f09SDavid van Moolenbroek 	REQUIRE(b->used + 2 <= b->length);
317*00b67f09SDavid van Moolenbroek 
318*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_PUTUINT16(b, val);
319*00b67f09SDavid van Moolenbroek }
320*00b67f09SDavid van Moolenbroek 
321*00b67f09SDavid van Moolenbroek void
isc__buffer_putuint24(isc_buffer_t * b,isc_uint32_t val)322*00b67f09SDavid van Moolenbroek isc__buffer_putuint24(isc_buffer_t *b, isc_uint32_t val) {
323*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
324*00b67f09SDavid van Moolenbroek 	REQUIRE(b->used + 3 <= b->length);
325*00b67f09SDavid van Moolenbroek 
326*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_PUTUINT24(b, val);
327*00b67f09SDavid van Moolenbroek }
328*00b67f09SDavid van Moolenbroek 
329*00b67f09SDavid van Moolenbroek isc_uint32_t
isc_buffer_getuint32(isc_buffer_t * b)330*00b67f09SDavid van Moolenbroek isc_buffer_getuint32(isc_buffer_t *b) {
331*00b67f09SDavid van Moolenbroek 	unsigned char *cp;
332*00b67f09SDavid van Moolenbroek 	isc_uint32_t result;
333*00b67f09SDavid van Moolenbroek 
334*00b67f09SDavid van Moolenbroek 	/*
335*00b67f09SDavid van Moolenbroek 	 * Read an unsigned 32-bit integer in network byte order from 'b',
336*00b67f09SDavid van Moolenbroek 	 * convert it to host byte order, and return it.
337*00b67f09SDavid van Moolenbroek 	 */
338*00b67f09SDavid van Moolenbroek 
339*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
340*00b67f09SDavid van Moolenbroek 	REQUIRE(b->used - b->current >= 4);
341*00b67f09SDavid van Moolenbroek 
342*00b67f09SDavid van Moolenbroek 	cp = isc_buffer_current(b);
343*00b67f09SDavid van Moolenbroek 	b->current += 4;
344*00b67f09SDavid van Moolenbroek 	result = ((unsigned int)(cp[0])) << 24;
345*00b67f09SDavid van Moolenbroek 	result |= ((unsigned int)(cp[1])) << 16;
346*00b67f09SDavid van Moolenbroek 	result |= ((unsigned int)(cp[2])) << 8;
347*00b67f09SDavid van Moolenbroek 	result |= ((unsigned int)(cp[3]));
348*00b67f09SDavid van Moolenbroek 
349*00b67f09SDavid van Moolenbroek 	return (result);
350*00b67f09SDavid van Moolenbroek }
351*00b67f09SDavid van Moolenbroek 
352*00b67f09SDavid van Moolenbroek void
isc__buffer_putuint32(isc_buffer_t * b,isc_uint32_t val)353*00b67f09SDavid van Moolenbroek isc__buffer_putuint32(isc_buffer_t *b, isc_uint32_t val) {
354*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
355*00b67f09SDavid van Moolenbroek 	REQUIRE(b->used + 4 <= b->length);
356*00b67f09SDavid van Moolenbroek 
357*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_PUTUINT32(b, val);
358*00b67f09SDavid van Moolenbroek }
359*00b67f09SDavid van Moolenbroek 
360*00b67f09SDavid van Moolenbroek isc_uint64_t
isc_buffer_getuint48(isc_buffer_t * b)361*00b67f09SDavid van Moolenbroek isc_buffer_getuint48(isc_buffer_t *b) {
362*00b67f09SDavid van Moolenbroek 	unsigned char *cp;
363*00b67f09SDavid van Moolenbroek 	isc_uint64_t result;
364*00b67f09SDavid van Moolenbroek 
365*00b67f09SDavid van Moolenbroek 	/*
366*00b67f09SDavid van Moolenbroek 	 * Read an unsigned 48-bit integer in network byte order from 'b',
367*00b67f09SDavid van Moolenbroek 	 * convert it to host byte order, and return it.
368*00b67f09SDavid van Moolenbroek 	 */
369*00b67f09SDavid van Moolenbroek 
370*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
371*00b67f09SDavid van Moolenbroek 	REQUIRE(b->used - b->current >= 6);
372*00b67f09SDavid van Moolenbroek 
373*00b67f09SDavid van Moolenbroek 	cp = isc_buffer_current(b);
374*00b67f09SDavid van Moolenbroek 	b->current += 6;
375*00b67f09SDavid van Moolenbroek 	result = ((isc_int64_t)(cp[0])) << 40;
376*00b67f09SDavid van Moolenbroek 	result |= ((isc_int64_t)(cp[1])) << 32;
377*00b67f09SDavid van Moolenbroek 	result |= ((isc_int64_t)(cp[2])) << 24;
378*00b67f09SDavid van Moolenbroek 	result |= ((isc_int64_t)(cp[3])) << 16;
379*00b67f09SDavid van Moolenbroek 	result |= ((isc_int64_t)(cp[4])) << 8;
380*00b67f09SDavid van Moolenbroek 	result |= ((isc_int64_t)(cp[5]));
381*00b67f09SDavid van Moolenbroek 
382*00b67f09SDavid van Moolenbroek 	return (result);
383*00b67f09SDavid van Moolenbroek }
384*00b67f09SDavid van Moolenbroek 
385*00b67f09SDavid van Moolenbroek void
isc__buffer_putuint48(isc_buffer_t * b,isc_uint64_t val)386*00b67f09SDavid van Moolenbroek isc__buffer_putuint48(isc_buffer_t *b, isc_uint64_t val) {
387*00b67f09SDavid van Moolenbroek 	isc_uint16_t valhi;
388*00b67f09SDavid van Moolenbroek 	isc_uint32_t vallo;
389*00b67f09SDavid van Moolenbroek 
390*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
391*00b67f09SDavid van Moolenbroek 	REQUIRE(b->used + 6 <= b->length);
392*00b67f09SDavid van Moolenbroek 
393*00b67f09SDavid van Moolenbroek 	valhi = (isc_uint16_t)(val >> 32);
394*00b67f09SDavid van Moolenbroek 	vallo = (isc_uint32_t)(val & 0xFFFFFFFF);
395*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_PUTUINT16(b, valhi);
396*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_PUTUINT32(b, vallo);
397*00b67f09SDavid van Moolenbroek }
398*00b67f09SDavid van Moolenbroek 
399*00b67f09SDavid van Moolenbroek void
isc__buffer_putmem(isc_buffer_t * b,const unsigned char * base,unsigned int length)400*00b67f09SDavid van Moolenbroek isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base,
401*00b67f09SDavid van Moolenbroek 		   unsigned int length)
402*00b67f09SDavid van Moolenbroek {
403*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
404*00b67f09SDavid van Moolenbroek 	REQUIRE(b->used + length <= b->length);
405*00b67f09SDavid van Moolenbroek 
406*00b67f09SDavid van Moolenbroek 	ISC__BUFFER_PUTMEM(b, base, length);
407*00b67f09SDavid van Moolenbroek }
408*00b67f09SDavid van Moolenbroek 
409*00b67f09SDavid van Moolenbroek void
isc__buffer_putstr(isc_buffer_t * b,const char * source)410*00b67f09SDavid van Moolenbroek isc__buffer_putstr(isc_buffer_t *b, const char *source) {
411*00b67f09SDavid van Moolenbroek 	unsigned int l;
412*00b67f09SDavid van Moolenbroek 	unsigned char *cp;
413*00b67f09SDavid van Moolenbroek 
414*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
415*00b67f09SDavid van Moolenbroek 	REQUIRE(source != NULL);
416*00b67f09SDavid van Moolenbroek 
417*00b67f09SDavid van Moolenbroek 	/*
418*00b67f09SDavid van Moolenbroek 	 * Do not use ISC__BUFFER_PUTSTR(), so strlen is only done once.
419*00b67f09SDavid van Moolenbroek 	 */
420*00b67f09SDavid van Moolenbroek 	l = strlen(source);
421*00b67f09SDavid van Moolenbroek 
422*00b67f09SDavid van Moolenbroek 	REQUIRE(l <= isc_buffer_availablelength(b));
423*00b67f09SDavid van Moolenbroek 
424*00b67f09SDavid van Moolenbroek 	cp = isc_buffer_used(b);
425*00b67f09SDavid van Moolenbroek 	memmove(cp, source, l);
426*00b67f09SDavid van Moolenbroek 	b->used += l;
427*00b67f09SDavid van Moolenbroek }
428*00b67f09SDavid van Moolenbroek 
429*00b67f09SDavid van Moolenbroek isc_result_t
isc_buffer_copyregion(isc_buffer_t * b,const isc_region_t * r)430*00b67f09SDavid van Moolenbroek isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r) {
431*00b67f09SDavid van Moolenbroek 	unsigned char *base;
432*00b67f09SDavid van Moolenbroek 	unsigned int available;
433*00b67f09SDavid van Moolenbroek 
434*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(b));
435*00b67f09SDavid van Moolenbroek 	REQUIRE(r != NULL);
436*00b67f09SDavid van Moolenbroek 
437*00b67f09SDavid van Moolenbroek 	/*
438*00b67f09SDavid van Moolenbroek 	 * XXXDCL
439*00b67f09SDavid van Moolenbroek 	 */
440*00b67f09SDavid van Moolenbroek 	base = isc_buffer_used(b);
441*00b67f09SDavid van Moolenbroek 	available = isc_buffer_availablelength(b);
442*00b67f09SDavid van Moolenbroek 	if (r->length > available)
443*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOSPACE);
444*00b67f09SDavid van Moolenbroek 	memmove(base, r->base, r->length);
445*00b67f09SDavid van Moolenbroek 	b->used += r->length;
446*00b67f09SDavid van Moolenbroek 
447*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
448*00b67f09SDavid van Moolenbroek }
449*00b67f09SDavid van Moolenbroek 
450*00b67f09SDavid van Moolenbroek isc_result_t
isc_buffer_allocate(isc_mem_t * mctx,isc_buffer_t ** dynbuffer,unsigned int length)451*00b67f09SDavid van Moolenbroek isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer,
452*00b67f09SDavid van Moolenbroek 		    unsigned int length)
453*00b67f09SDavid van Moolenbroek {
454*00b67f09SDavid van Moolenbroek 	isc_buffer_t *dbuf;
455*00b67f09SDavid van Moolenbroek 
456*00b67f09SDavid van Moolenbroek 	REQUIRE(dynbuffer != NULL);
457*00b67f09SDavid van Moolenbroek 	REQUIRE(*dynbuffer == NULL);
458*00b67f09SDavid van Moolenbroek 
459*00b67f09SDavid van Moolenbroek 	dbuf = isc_mem_get(mctx, length + sizeof(isc_buffer_t));
460*00b67f09SDavid van Moolenbroek 	if (dbuf == NULL)
461*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMEMORY);
462*00b67f09SDavid van Moolenbroek 
463*00b67f09SDavid van Moolenbroek 	isc_buffer_init(dbuf, ((unsigned char *)dbuf) + sizeof(isc_buffer_t),
464*00b67f09SDavid van Moolenbroek 			length);
465*00b67f09SDavid van Moolenbroek 	dbuf->mctx = mctx;
466*00b67f09SDavid van Moolenbroek 
467*00b67f09SDavid van Moolenbroek 	*dynbuffer = dbuf;
468*00b67f09SDavid van Moolenbroek 
469*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
470*00b67f09SDavid van Moolenbroek }
471*00b67f09SDavid van Moolenbroek 
472*00b67f09SDavid van Moolenbroek void
isc_buffer_free(isc_buffer_t ** dynbuffer)473*00b67f09SDavid van Moolenbroek isc_buffer_free(isc_buffer_t **dynbuffer) {
474*00b67f09SDavid van Moolenbroek 	unsigned int real_length;
475*00b67f09SDavid van Moolenbroek 	isc_buffer_t *dbuf;
476*00b67f09SDavid van Moolenbroek 	isc_mem_t *mctx;
477*00b67f09SDavid van Moolenbroek 
478*00b67f09SDavid van Moolenbroek 	REQUIRE(dynbuffer != NULL);
479*00b67f09SDavid van Moolenbroek 	REQUIRE(ISC_BUFFER_VALID(*dynbuffer));
480*00b67f09SDavid van Moolenbroek 	REQUIRE((*dynbuffer)->mctx != NULL);
481*00b67f09SDavid van Moolenbroek 
482*00b67f09SDavid van Moolenbroek 	dbuf = *dynbuffer;
483*00b67f09SDavid van Moolenbroek 	*dynbuffer = NULL;	/* destroy external reference */
484*00b67f09SDavid van Moolenbroek 
485*00b67f09SDavid van Moolenbroek 	real_length = dbuf->length + sizeof(isc_buffer_t);
486*00b67f09SDavid van Moolenbroek 	mctx = dbuf->mctx;
487*00b67f09SDavid van Moolenbroek 	dbuf->mctx = NULL;
488*00b67f09SDavid van Moolenbroek 	isc_buffer_invalidate(dbuf);
489*00b67f09SDavid van Moolenbroek 
490*00b67f09SDavid van Moolenbroek 	isc_mem_put(mctx, dbuf, real_length);
491*00b67f09SDavid van Moolenbroek }
492