usbmodeswitch: Updated to v.1.2.6 from shibby's branch.
[tomato.git] / release / src-rt / shared / bcm_xdr.c
blobbbeeec3615f8b0a32c8a5e6d02acc8a0685c2fbc
1 /*
2 * Utilites for XDR encode and decode of data
4 * Copyright (C) 2010, Broadcom Corporation
5 * All Rights Reserved.
6 *
7 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
8 * the contents of this file may not be disclosed to third parties, copied
9 * or duplicated in any form, in whole or in part, without the prior
10 * written permission of Broadcom Corporation.
12 * $Id: bcm_xdr.c,v 1.7 2008-11-07 20:26:33 Exp $
15 #include <osl.h>
16 #include <typedefs.h>
17 #include <bcmendian.h>
18 #include <bcm_xdr.h>
20 void
21 bcm_xdr_buf_init(bcm_xdr_buf_t *b, void *buf, size_t len)
23 b->buf = b->origbuf = buf;
24 b->size = b->origsize = (uint)len;
27 int
28 bcm_xdr_pack_uint8_vec(bcm_xdr_buf_t *b, uint8 *vec, uint32 elems)
30 int err = 0;
31 err = bcm_xdr_pack_opaque(b, elems, vec);
33 return err;
36 int
37 bcm_xdr_unpack_uint8_vec(bcm_xdr_buf_t *b, uint8 *vec, uint32 elems)
39 int err = 0;
40 err = bcm_xdr_unpack_opaque_cpy(b, elems, vec);
42 return err;
45 /* Pack 16-bit vectors */
46 int
47 bcm_xdr_pack_uint16_vec(bcm_xdr_buf_t *b, uint len, void *vec)
49 size_t tot_len, r;
50 int i;
51 uint16 *vec16 = (uint16*)vec, *buf16 = (uint16*)b->buf;
52 ASSERT((len % sizeof(uint16)) == 0);
54 /* calc residual padding to 4 bytes */
55 r = (4 - len) & 3;
57 tot_len = len + r;
59 if (b->size < tot_len)
60 return -1;
62 /* Do the 16 bit swap and copy */
63 for (i = 0; i < (int)(len/sizeof(uint16)); i++)
64 buf16[i] = htol16(vec16[i]);
66 /* Padding */
67 memset(b->buf + len, 0, r);
69 b->size -= tot_len;
70 b->buf += tot_len;
72 return 0;
75 /* Unpack 16-bit vectors */
76 int
77 bcm_xdr_unpack_uint16_vec(bcm_xdr_buf_t *b, uint len, void *vec)
79 int err = 0, i;
80 uint16 *vec16 = (uint16*)vec;
81 ASSERT((len % sizeof(uint16)) == 0);
83 err = bcm_xdr_unpack_opaque_cpy(b, len, vec);
85 /* Do the 16 bit swapping in the copied buffer */
86 for (i = 0; i < (int)(len/sizeof(uint16)); i++)
87 vec16[i] = ltoh16(vec16[i]);
89 return err;
92 /* Pack 32-bit vectors */
93 int
94 bcm_xdr_pack_uint32_vec(bcm_xdr_buf_t *b, uint len, void *vec)
96 int i;
97 uint32 *vec32 = (uint32*)vec, *buf32 = (uint32*)b->buf;
98 ASSERT((len % sizeof(uint32)) == 0);
100 if (b->size < len)
101 return -1;
103 /* Do the 32 bit swap and copy */
104 for (i = 0; i < (int)(len/sizeof(uint32)); i++)
105 buf32[i] = htol32(vec32[i]);
107 b->size -= len;
108 b->buf += len;
110 return 0;
113 /* Unpack 32-bit vectors */
115 bcm_xdr_unpack_uint32_vec(bcm_xdr_buf_t *b, uint len, void *vec)
117 int err = 0, i;
118 uint32 *vec32 = (uint32*)vec;
119 ASSERT((len % sizeof(uint32)) == 0);
121 err = bcm_xdr_unpack_opaque_cpy(b, len, vec);
123 /* Do the 32 bit swapping in the copied buffer */
124 for (i = 0; i < (int)(len/sizeof(uint32)); i++)
125 vec32[i] = ltoh32(vec32[i]);
127 return err;
131 bcm_xdr_pack_uint32(bcm_xdr_buf_t *b, uint32 val)
133 if (b->size < 4)
134 return -1;
136 *(uint32*)(b->buf) = htol32((uint32)val);
137 b->size -= 4;
138 b->buf += 4;
140 return 0;
144 bcm_xdr_unpack_uint32(bcm_xdr_buf_t *b, uint32 *pval)
146 if (b->size < 4)
147 return -1;
149 *pval = ltoh32(*(uint32*)(b->buf));
151 b->size -= 4;
152 b->buf += 4;
154 return 0;
158 bcm_xdr_pack_int32(bcm_xdr_buf_t *b, int32 val)
160 return bcm_xdr_pack_uint32(b, (uint32)val);
164 bcm_xdr_unpack_int32(bcm_xdr_buf_t *b, int32 *pval)
166 return bcm_xdr_unpack_uint32(b, (uint32*)pval);
170 bcm_xdr_pack_int8(bcm_xdr_buf_t *b, int8 val)
172 return bcm_xdr_pack_uint32(b, (uint32)val);
176 bcm_xdr_unpack_int8(bcm_xdr_buf_t *b, int8 *pval)
178 uint32 val = 0;
179 int err;
181 err = bcm_xdr_unpack_uint32(b, &val);
182 *pval = (int8)val;
184 return err;
188 bcm_xdr_pack_opaque_raw(bcm_xdr_buf_t *b, uint len, void *data)
190 if (b->size < len)
191 return -1;
192 memcpy(b->buf, data, len);
194 b->size -= len;
195 b->buf += len;
197 return 0;
200 /* Pad 0 at the remaining part of a rpc buffer */
202 bcm_xdr_pack_opaque_pad(bcm_xdr_buf_t *b)
204 size_t len;
205 size_t r;
207 /* calc residual padding to 4 bytes */
208 len = (size_t)(b->buf - b->origbuf);
209 r = (4 - len) & 0x3;
211 if (r == 0)
212 return 0;
214 if (b->size < r)
215 return -1;
217 memset(b->buf, 0, r);
219 b->size -= r;
220 b->buf += r;
222 return 0;
225 /* pack a word-aligned buffer without dealing with the endianess, pad 0 at the end and make
226 * it word-aligned if len is not multiple of 4
229 bcm_xdr_pack_opaque(bcm_xdr_buf_t *b, uint len, void *data)
231 size_t tot_len;
232 size_t r;
234 /* calc residual padding to 4 bytes */
235 r = (4 - len) & 3;
237 tot_len = len + r;
239 if (b->size < tot_len)
240 return -1;
242 memcpy(b->buf, data, len);
243 memset(b->buf + len, 0, r);
245 b->size -= tot_len;
246 b->buf += tot_len;
248 return 0;
252 bcm_xdr_unpack_opaque(bcm_xdr_buf_t *b, uint len, void **pdata)
254 size_t tot_len;
255 size_t r;
257 /* calc residual padding to 4 bytes */
258 r = (4 - len) & 3;
259 tot_len = len + r;
261 if (b->size < tot_len)
262 return -1;
264 *pdata = b->buf;
266 b->size -= tot_len;
267 b->buf += tot_len;
269 return 0;
273 bcm_xdr_unpack_opaque_cpy(bcm_xdr_buf_t *b, uint len, void *data)
275 void *xdr_data;
276 int err;
278 err = bcm_xdr_unpack_opaque(b, len, &xdr_data);
279 if (err)
280 return err;
282 memcpy(data, xdr_data, len);
284 return 0;
288 bcm_xdr_pack_opaque_varlen(bcm_xdr_buf_t *b, uint len, void *data)
290 int err;
292 err = bcm_xdr_pack_uint32(b, len);
293 if (err)
294 return err;
296 return bcm_xdr_pack_opaque(b, len, data);
300 bcm_xdr_unpack_opaque_varlen(bcm_xdr_buf_t *b, uint *plen, void **pdata)
302 int err;
304 err = bcm_xdr_unpack_uint32(b, plen);
305 if (err)
306 return err;
308 return bcm_xdr_unpack_opaque(b, *plen, pdata);
312 bcm_xdr_pack_string(bcm_xdr_buf_t *b, char *str)
314 return bcm_xdr_pack_opaque_varlen(b, strlen(str), str);
318 bcm_xdr_unpack_string(bcm_xdr_buf_t *b, uint *plen, char **pstr)
320 return bcm_xdr_unpack_opaque_varlen(b, plen, (void**)pstr);