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