]>
git.saurik.com Git - apple/xnu.git/blob - bsd/nfs/xdr_subs.h
2 * Copyright (c) 2000-2011 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
28 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
30 * Copyright (c) 1989, 1993
31 * The Regents of the University of California. All rights reserved.
33 * This code is derived from software contributed to Berkeley by
34 * Rick Macklem at The University of Guelph.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. All advertising materials mentioning features or use of this software
45 * must display the following acknowledgement:
46 * This product includes software developed by the University of
47 * California, Berkeley and its contributors.
48 * 4. Neither the name of the University nor the names of its contributors
49 * may be used to endorse or promote products derived from this software
50 * without specific prior written permission.
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
64 * @(#)xdr_subs.h 8.3 (Berkeley) 3/30/95
65 * FreeBSD-Id: xdr_subs.h,v 1.9 1997/02/22 09:42:53 peter Exp $
68 #ifndef _NFS_XDR_SUBS_H_
69 #define _NFS_XDR_SUBS_H_
71 #include <sys/appleapiopts.h>
73 #ifdef __APPLE_API_PRIVATE
75 * Macros used for conversion to/from xdr representation by nfs...
76 * These use the MACHINE DEPENDENT routines ntohl, htonl
77 * As defined by "XDR: External Data Representation Standard" RFC1014
79 * To simplify the implementation, we use ntohl/htonl even on big-endian
80 * machines, and count on them being `#define'd away. Some of these
81 * might be slightly more efficient as quad_t copies on a big-endian,
82 * but we cannot count on their alignment anyway.
85 #define fxdr_unsigned(t, v) ((t)ntohl((uint32_t)(v)))
86 #define txdr_unsigned(v) (htonl((uint32_t)(v)))
88 #define fxdr_hyper(f, t) { \
89 ((uint32_t *)(t))[_QUAD_HIGHWORD] = ntohl(((uint32_t *)(f))[0]); \
90 ((uint32_t *)(t))[_QUAD_LOWWORD] = ntohl(((uint32_t *)(f))[1]); \
92 #define txdr_hyper(f, t) { \
93 ((uint32_t *)(t))[0] = htonl(((uint32_t *)(f))[_QUAD_HIGHWORD]); \
94 ((uint32_t *)(t))[1] = htonl(((uint32_t *)(f))[_QUAD_LOWWORD]); \
101 * generalized functionality for managing the building/dissecting of XDR data
103 typedef enum xdrbuf_type
{
111 char * xbb_base
; /* base address of buffer */
112 size_t xbb_size
; /* size of buffer */
113 size_t xbb_len
; /* length of data in buffer */
116 char * xb_ptr
; /* pointer to current position */
117 size_t xb_left
; /* bytes remaining in current buffer */
118 size_t xb_growsize
; /* bytes to allocate when growing */
119 xdrbuf_type xb_type
; /* type of xdr buffer */
120 uint32_t xb_flags
; /* XB_* (see below) */
123 #define XB_CLEANUP 0x0001 /* needs cleanup */
125 #define XDRWORD 4 /* the basic XDR building block is a 4 byte (32 bit) word */
126 #define xdr_rndup(a) (((a)+3)&(~0x3)) /* round up to XDRWORD size */
127 #define xdr_pad(a) (xdr_rndup(a) - (a)) /* calculate round up padding */
129 void xb_init(struct xdrbuf
*, xdrbuf_type
);
130 void xb_init_buffer(struct xdrbuf
*, char *, size_t);
131 void xb_cleanup(struct xdrbuf
*);
132 void *xb_malloc(size_t);
133 void xb_free(void *);
134 int xb_grow(struct xdrbuf
*);
135 void xb_set_cur_buf_len(struct xdrbuf
*);
136 char *xb_buffer_base(struct xdrbuf
*);
137 int xb_advance(struct xdrbuf
*, size_t);
138 size_t xb_offset(struct xdrbuf
*);
139 int xb_seek(struct xdrbuf
*, size_t);
140 int xb_add_bytes(struct xdrbuf
*, const char *, size_t, int);
141 int xb_get_bytes(struct xdrbuf
*, char *, uint32_t, int);
143 #ifdef _NFS_XDR_SUBS_FUNCS_
146 * basic initialization of xdrbuf structure
149 xb_init(struct xdrbuf
*xbp
, xdrbuf_type type
)
151 bzero(xbp
, sizeof(*xbp
));
153 xbp
->xb_flags
|= XB_CLEANUP
;
157 * initialize a single-buffer xdrbuf
160 xb_init_buffer(struct xdrbuf
*xbp
, char *buf
, size_t buflen
)
162 xb_init(xbp
, XDRBUF_BUFFER
);
163 xbp
->xb_u
.xb_buffer
.xbb_base
= buf
;
164 xbp
->xb_u
.xb_buffer
.xbb_size
= buflen
;
165 xbp
->xb_u
.xb_buffer
.xbb_len
= buflen
;
166 xbp
->xb_growsize
= 512;
168 xbp
->xb_left
= buflen
;
169 if (buf
) { /* when using an existing buffer, xb code should skip cleanup */
170 xbp
->xb_flags
&= ~XB_CLEANUP
;
175 * get the pointer to the single-buffer xdrbuf's buffer
178 xb_buffer_base(struct xdrbuf
*xbp
)
180 return xbp
->xb_u
.xb_buffer
.xbb_base
;
184 * clean up any resources held by an xdrbuf
187 xb_cleanup(struct xdrbuf
*xbp
)
189 if (!(xbp
->xb_flags
& XB_CLEANUP
)) {
192 switch (xbp
->xb_type
) {
194 if (xbp
->xb_u
.xb_buffer
.xbb_base
) {
195 xb_free(xbp
->xb_u
.xb_buffer
.xbb_base
);
201 xbp
->xb_flags
&= ~XB_CLEANUP
;
205 * set the length of valid data in the current buffer to
206 * be up to the current location within the buffer
209 xb_set_cur_buf_len(struct xdrbuf
*xbp
)
211 switch (xbp
->xb_type
) {
213 xbp
->xb_u
.xb_buffer
.xbb_len
= xbp
->xb_ptr
- xbp
->xb_u
.xb_buffer
.xbb_base
;
221 * advance forward through existing data in xdrbuf
224 xb_advance(struct xdrbuf
*xbp
, size_t len
)
229 if (xbp
->xb_left
<= 0) {
232 tlen
= MIN(xbp
->xb_left
, len
);
235 xbp
->xb_left
-= tlen
;
243 * Calculate the current offset in the XDR buffer.
246 xb_offset(struct xdrbuf
*xbp
)
250 switch (xbp
->xb_type
) {
252 offset
= xbp
->xb_ptr
- xbp
->xb_u
.xb_buffer
.xbb_base
;
262 * Seek to the given offset in the existing data in the XDR buffer.
265 xb_seek(struct xdrbuf
*xbp
, size_t offset
)
267 switch (xbp
->xb_type
) {
269 xbp
->xb_ptr
= xbp
->xb_u
.xb_buffer
.xbb_base
+ offset
;
270 xbp
->xb_left
= xbp
->xb_u
.xb_buffer
.xbb_len
- offset
;
283 xb_malloc(size_t size
)
288 MALLOC(buf
, void *, size
, M_TEMP
, M_WAITOK
);
295 * free a chunk of memory allocated with xb_malloc()
308 * Increase space available for new data in XDR buffer.
311 xb_grow(struct xdrbuf
*xbp
)
313 char *newbuf
, *oldbuf
;
314 size_t newsize
, oldsize
;
316 switch (xbp
->xb_type
) {
318 oldsize
= xbp
->xb_u
.xb_buffer
.xbb_size
;
319 oldbuf
= xbp
->xb_u
.xb_buffer
.xbb_base
;
320 newsize
= oldsize
+ xbp
->xb_growsize
;
321 if (newsize
< oldsize
) {
324 newbuf
= xb_malloc(newsize
);
325 if (newbuf
== NULL
) {
328 if (oldbuf
!= NULL
) {
329 bcopy(oldbuf
, newbuf
, oldsize
);
332 xbp
->xb_u
.xb_buffer
.xbb_base
= newbuf
;
333 xbp
->xb_u
.xb_buffer
.xbb_size
= newsize
;
334 xbp
->xb_ptr
= newbuf
+ oldsize
;
335 xbp
->xb_left
= xbp
->xb_growsize
;
347 * Add "count" bytes of opaque data pointed to by "buf" to the given XDR buffer.
350 xb_add_bytes(struct xdrbuf
*xbp
, const char *buf
, size_t count
, int nopad
)
355 len
= nopad
? count
: xdr_rndup(count
);
357 /* copy in "count" bytes and zero out any pad bytes */
359 if (xbp
->xb_left
<= 0) {
360 /* need more space */
361 if ((error
= xb_grow(xbp
))) {
364 if (xbp
->xb_left
<= 0) {
368 tlen
= MIN(xbp
->xb_left
, len
);
374 bcopy(buf
, xbp
->xb_ptr
, tlen
);
376 bzero(xbp
->xb_ptr
, tlen
);
379 xbp
->xb_left
-= tlen
;
393 * Get "count" bytes of opaque data from the given XDR buffer.
396 xb_get_bytes(struct xdrbuf
*xbp
, char *buf
, uint32_t count
, int nopad
)
400 len
= nopad
? count
: xdr_rndup(count
);
402 /* copy in "count" bytes and zero out any pad bytes */
404 if (xbp
->xb_left
<= 0) {
407 tlen
= MIN(xbp
->xb_left
, len
);
413 bcopy(xbp
->xb_ptr
, buf
, tlen
);
416 xbp
->xb_left
-= tlen
;
427 #endif /* _NFS_XDR_SUBS_FUNCS_ */
431 * macros for building XDR data
434 /* finalize the data that has been added to the buffer */
435 #define xb_build_done(E, XB) \
438 xb_set_cur_buf_len(XB); \
441 /* add a 32-bit value */
442 #define xb_add_32(E, XB, VAL) \
446 __tmp = txdr_unsigned(VAL); \
447 (E) = xb_add_bytes((XB), (void*)&__tmp, XDRWORD, 0); \
450 /* add a 64-bit value */
451 #define xb_add_64(E, XB, VAL) \
453 uint64_t __tmp1, __tmp2; \
456 txdr_hyper(&__tmp1, &__tmp2); \
457 (E) = xb_add_bytes((XB), (char*)&__tmp2, 2 * XDRWORD, 0); \
460 /* add an array of XDR words */
461 #define xb_add_word_array(E, XB, A, LEN) \
464 xb_add_32((E), (XB), (LEN)); \
465 for (__i=0; __i < (uint32_t)(LEN); __i++) \
466 xb_add_32((E), (XB), (A)[__i]); \
468 #define xb_add_bitmap(E, XB, B, LEN) xb_add_word_array((E), (XB), (B), (LEN))
470 /* add a file handle */
471 #define xb_add_fh(E, XB, FHP, FHLEN) \
473 xb_add_32((E), (XB), (FHLEN)); \
475 (E) = xb_add_bytes((XB), (char*)(FHP), (FHLEN), 0); \
479 #define xb_add_string(E, XB, S, LEN) \
481 xb_add_32((E), (XB), (LEN)); \
483 (E) = xb_add_bytes((XB), (const char*)(S), (LEN), 0); \
488 * macros for decoding XDR data
491 /* skip past data in the buffer */
492 #define xb_skip(E, XB, LEN) \
495 (E) = xb_advance((XB), (LEN)); \
498 /* get a 32-bit value */
499 #define xb_get_32(E, XB, LVAL) \
502 (LVAL) = (typeof((LVAL))) 0; \
504 (E) = xb_get_bytes((XB), (char*)&__tmp, XDRWORD, 0); \
506 (LVAL) = fxdr_unsigned(uint32_t, __tmp); \
509 /* get a 64-bit value */
510 #define xb_get_64(E, XB, LVAL) \
515 (E) = xb_get_bytes((XB), (char*)&__tmp, 2 * XDRWORD, 0); \
517 fxdr_hyper(&__tmp, &(LVAL)); \
520 /* get an array of XDR words (of a given expected/maximum length) */
521 #define xb_get_word_array(E, XB, A, LEN) \
523 uint32_t __len = 0, __i; \
524 xb_get_32((E), (XB), __len); \
526 for (__i=0; __i < MIN(__len, (uint32_t)(LEN)); __i++) \
527 xb_get_32((E), (XB), (A)[__i]); \
529 for (; __i < __len; __i++) \
530 xb_skip((E), (XB), XDRWORD); \
531 for (; __i < (uint32_t)(LEN); __i++) \
535 #define xb_get_bitmap(E, XB, B, LEN) xb_get_word_array((E), (XB), (B), (LEN))
537 #endif /* __APPLE_API_PRIVATE */
538 #endif /* _NFS_XDR_SUBS_H_ */