Annotation of embedaddon/mpd/src/contrib/libpdel/structs/type/structs_type_int.c, revision 1.1.1.1
1.1 misho 1:
2: /*
3: * Copyright (c) 2001-2002 Packet Design, LLC.
4: * All rights reserved.
5: *
6: * Subject to the following obligations and disclaimer of warranty,
7: * use and redistribution of this software, in source or object code
8: * forms, with or without modifications are expressly permitted by
9: * Packet Design; provided, however, that:
10: *
11: * (i) Any and all reproductions of the source or object code
12: * must include the copyright notice above and the following
13: * disclaimer of warranties; and
14: * (ii) No rights are granted, in any manner or form, to use
15: * Packet Design trademarks, including the mark "PACKET DESIGN"
16: * on advertising, endorsements, or otherwise except as such
17: * appears in the above copyright notice or in the software.
18: *
19: * THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
20: * TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
21: * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
22: * THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
23: * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
24: * OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
25: * OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
26: * OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
27: * RELIABILITY OR OTHERWISE. IN NO EVENT SHALL PACKET DESIGN BE
28: * LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
29: * OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
30: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
31: * DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
32: * USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
33: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
35: * THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
36: * THE POSSIBILITY OF SUCH DAMAGE.
37: *
38: * Author: Archie Cobbs <archie@freebsd.org>
39: */
40:
41: #include <sys/types.h>
42:
43: #include <stdio.h>
44: #include <stdlib.h>
45: #include <stdarg.h>
46: #include <string.h>
47: #include <ctype.h>
48: #include <limits.h>
49: #include <errno.h>
50:
51: #include "structs/structs.h"
52: #include "structs/type/array.h"
53: #include "structs/type/int.h"
54: #include "util/typed_mem.h"
55:
56: /*
57: * Integral type methods
58: *
59: * Type-specific arguments:
60: * [int]
61: * 0 = char
62: * 1 = short
63: * 2 = int
64: * 3 = long
65: * 4 = int8
66: * 5 = int16
67: * 6 = int32
68: * 7 = int64
69: * [int]
70: * 0 = unsigned
71: * 1 = signed
72: * 2 = hex
73: */
74:
75: #define INTTYPES(name, size, arg1) \
76: const struct structs_type structs_type_u ## name = { \
77: (size), \
78: "uint", \
79: STRUCTS_TYPE_PRIMITIVE, \
80: structs_region_init, \
81: structs_region_copy, \
82: structs_region_equal, \
83: structs_int_ascify, \
84: structs_int_binify, \
85: structs_region_encode_netorder, \
86: structs_region_decode_netorder, \
87: structs_nothing_free, \
88: { { (void *)(arg1) }, { (void *)0 } } \
89: }; \
90: const struct structs_type structs_type_ ## name = { \
91: (size), \
92: "int", \
93: STRUCTS_TYPE_PRIMITIVE, \
94: structs_region_init, \
95: structs_region_copy, \
96: structs_region_equal, \
97: structs_int_ascify, \
98: structs_int_binify, \
99: structs_region_encode_netorder, \
100: structs_region_decode_netorder, \
101: structs_nothing_free, \
102: { { (void *)(arg1) }, { (void *)1 } } \
103: }; \
104: const struct structs_type structs_type_h ## name = { \
105: (size), \
106: "hint", \
107: STRUCTS_TYPE_PRIMITIVE, \
108: structs_region_init, \
109: structs_region_copy, \
110: structs_region_equal, \
111: structs_int_ascify, \
112: structs_int_binify, \
113: structs_region_encode_netorder, \
114: structs_region_decode_netorder, \
115: structs_nothing_free, \
116: { { (void *)(arg1) }, { (void *)2 } } \
117: }
118:
119: /* Define the types */
120: INTTYPES(char, sizeof(char), 0);
121: INTTYPES(short, sizeof(short), 1);
122: INTTYPES(int, sizeof(int), 2);
123: INTTYPES(long, sizeof(long), 3);
124: INTTYPES(int8, sizeof(int8_t), 4);
125: INTTYPES(int16, sizeof(int16_t), 5);
126: INTTYPES(int32, sizeof(int32_t), 6);
127: INTTYPES(int64, sizeof(int64_t), 7);
128:
129: /*********************************************************************
130: INTEGRAL TYPES
131: *********************************************************************/
132:
133: char *
134: structs_int_ascify(const struct structs_type *type,
135: const char *mtype, const void *data)
136: {
137: const char *const fmts[8][3] = {
138: { "%u", "%d", "0x%02x" }, /* char */
139: { "%u", "%d", "0x%x" }, /* short */
140: { "%u", "%d", "0x%x" }, /* int */
141: { "%lu", "%ld", "0x%lx" }, /* long */
142: { "%u", "%d", "0x%02x" }, /* int8_t */
143: { "%u", "%d", "0x%x" }, /* int16_t */
144: { "%u", "%d", "0x%x" }, /* int32_t */
145: { "%qu", "%qd", "0x%qx" }, /* int64_t */
146: };
147: const char *fmt;
148: char buf[32];
149:
150: fmt = fmts[type->args[0].i][type->args[1].i];
151: switch (type->args[0].i) {
152: case 0:
153: snprintf(buf, sizeof(buf), fmt, (type->args[1].i == 1) ?
154: *((char *)data) : *((u_char *)data));
155: break;
156: case 1:
157: snprintf(buf, sizeof(buf), fmt, (type->args[1].i == 1) ?
158: *((short *)data) : *((u_short *)data));
159: break;
160: case 2:
161: snprintf(buf, sizeof(buf), fmt, (type->args[1].i == 1) ?
162: *((int *)data) : *((u_int *)data));
163: break;
164: case 3:
165: snprintf(buf, sizeof(buf), fmt, (type->args[1].i == 1) ?
166: *((long *)data) : *((u_long *)data));
167: break;
168: case 4:
169: snprintf(buf, sizeof(buf), fmt, (type->args[1].i == 1) ?
170: *((int8_t *)data) : *((u_int8_t *)data));
171: break;
172: case 5:
173: snprintf(buf, sizeof(buf), fmt, (type->args[1].i == 1) ?
174: *((int16_t *)data) : *((u_int16_t *)data));
175: break;
176: case 6:
177: snprintf(buf, sizeof(buf), fmt, (type->args[1].i == 1) ?
178: *((int32_t *)data) : *((u_int32_t *)data));
179: break;
180: case 7:
181: snprintf(buf, sizeof(buf), fmt, (type->args[1].i == 1) ?
182: *((int64_t *)data) : *((u_int64_t *)data));
183: break;
184: default:
185: errno = EDOM;
186: return (NULL);
187: }
188: return (STRDUP(mtype, buf));
189: }
190:
191: int
192: structs_int_binify(const struct structs_type *type,
193: const char *ascii, void *data, char *ebuf, size_t emax)
194: {
195: static const long long bounds[][2] = {
196: { SCHAR_MIN, UCHAR_MAX },
197: { SHRT_MIN, USHRT_MAX },
198: { INT_MIN, UINT_MAX },
199: { LONG_MIN, ULONG_MAX },
200: { -0x7f - 1, 0xff },
201: { -0x7fff - 1, 0xffff },
202: { -0x7fffffff - 1, 0xffffffff },
203: { -0x7fffffffffffffffLL - 1, 0x7fffffffffffffffLL /*XXX*/ },
204: };
205: const int format = type->args[1].i;
206: long long value;
207: char *eptr;
208:
209: /* Sanity check */
210: if (type->args[0].i < 0 || type->args[0].i >= 8) {
211: errno = EDOM;
212: return (-1);
213: }
214:
215: /* Parse value */
216: #if _KERNEL
217: value = strtoq(ascii, &eptr, 0); /* assume quad_t == long long */
218: #else
219: value = strtoll(ascii, &eptr, 0);
220: #endif
221: if (eptr == ascii) {
222: strlcpy(ebuf, "invalid integer value", emax);
223: errno = EINVAL;
224: return (-1);
225: }
226: while (isspace(*eptr))
227: eptr++;
228: if (*eptr != '\0') {
229: errno = EINVAL;
230: return (-1);
231: }
232:
233: /* Check that value is in bounds XXX fails for LLONG_MAX..ULLONG_MAX */
234: if ((errno == ERANGE && (value == LLONG_MIN || value == LLONG_MAX))
235: || (format == 0 && value < 0LL) /* check unsignedness */
236: || value < bounds[type->args[0].i][0]
237: || value > bounds[type->args[0].i][1]) {
238: strlcpy(ebuf, "integer value is out of range", emax);
239: errno = EINVAL;
240: return (-1);
241: }
242:
243: /* Set value */
244: if (type->args[1].i == 1) {
245: switch (type->args[0].i) {
246: case 0:
247: *((char *)data) = (char)value;
248: break;
249: case 1:
250: *((short *)data) = (short)value;
251: break;
252: case 2:
253: *((int *)data) = (int)value;
254: break;
255: case 3:
256: *((long *)data) = (long)value;
257: break;
258: case 4:
259: *((int8_t *)data) = (int8_t)value;
260: break;
261: case 5:
262: *((int16_t *)data) = (int16_t)value;
263: break;
264: case 6:
265: *((int32_t *)data) = (int32_t)value;
266: break;
267: case 7:
268: *((int64_t *)data) = (int64_t)value;
269: break;
270: default:
271: errno = EDOM;
272: return (-1);
273: }
274: } else {
275: switch (type->args[0].i) {
276: case 0:
277: *((u_char *)data) = (u_char)value;
278: break;
279: case 1:
280: *((u_short *)data) = (u_short)value;
281: break;
282: case 2:
283: *((u_int *)data) = (u_int)value;
284: break;
285: case 3:
286: *((u_long *)data) = (u_long)value;
287: break;
288: case 4:
289: *((u_int8_t *)data) = (u_int8_t)value;
290: break;
291: case 5:
292: *((u_int16_t *)data) = (u_int16_t)value;
293: break;
294: case 6:
295: *((u_int32_t *)data) = (u_int32_t)value;
296: break;
297: case 7:
298: *((u_int64_t *)data) = (u_int64_t)value;
299: break;
300: default:
301: errno = EDOM;
302: return (-1);
303: }
304: }
305:
306: /* Done */
307: return (0);
308: }
309:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>