Annotation of embedaddon/mpd/src/contrib/libpdel/structs/type/structs_type_int.c, revision 1.1.1.2
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:
1.1.1.2 ! misho 133: #ifdef __clang__
! 134: #pragma clang diagnostic push
! 135: #pragma clang diagnostic ignored "-Wformat-nonliteral"
! 136: #endif
! 137:
1.1 misho 138: char *
139: structs_int_ascify(const struct structs_type *type,
140: const char *mtype, const void *data)
141: {
142: const char *const fmts[8][3] = {
143: { "%u", "%d", "0x%02x" }, /* char */
144: { "%u", "%d", "0x%x" }, /* short */
145: { "%u", "%d", "0x%x" }, /* int */
146: { "%lu", "%ld", "0x%lx" }, /* long */
147: { "%u", "%d", "0x%02x" }, /* int8_t */
148: { "%u", "%d", "0x%x" }, /* int16_t */
149: { "%u", "%d", "0x%x" }, /* int32_t */
150: { "%qu", "%qd", "0x%qx" }, /* int64_t */
151: };
152: const char *fmt;
153: char buf[32];
154:
155: fmt = fmts[type->args[0].i][type->args[1].i];
156: switch (type->args[0].i) {
157: case 0:
158: snprintf(buf, sizeof(buf), fmt, (type->args[1].i == 1) ?
1.1.1.2 ! misho 159: *((const char *)data) : *((const u_char *)data));
1.1 misho 160: break;
161: case 1:
162: snprintf(buf, sizeof(buf), fmt, (type->args[1].i == 1) ?
1.1.1.2 ! misho 163: *((const short *)data) : *((const u_short *)data));
1.1 misho 164: break;
165: case 2:
166: snprintf(buf, sizeof(buf), fmt, (type->args[1].i == 1) ?
1.1.1.2 ! misho 167: *((const int *)data) : *((const u_int *)data));
1.1 misho 168: break;
169: case 3:
170: snprintf(buf, sizeof(buf), fmt, (type->args[1].i == 1) ?
1.1.1.2 ! misho 171: *((const long *)data) : *((const u_long *)data));
1.1 misho 172: break;
173: case 4:
174: snprintf(buf, sizeof(buf), fmt, (type->args[1].i == 1) ?
1.1.1.2 ! misho 175: *((const int8_t *)data) : *((const u_int8_t *)data));
1.1 misho 176: break;
177: case 5:
178: snprintf(buf, sizeof(buf), fmt, (type->args[1].i == 1) ?
1.1.1.2 ! misho 179: *((const int16_t *)data) : *((const u_int16_t *)data));
1.1 misho 180: break;
181: case 6:
182: snprintf(buf, sizeof(buf), fmt, (type->args[1].i == 1) ?
1.1.1.2 ! misho 183: *((const int32_t *)data) : *((const u_int32_t *)data));
1.1 misho 184: break;
185: case 7:
186: snprintf(buf, sizeof(buf), fmt, (type->args[1].i == 1) ?
1.1.1.2 ! misho 187: *((const int64_t *)data) : *((const u_int64_t *)data));
1.1 misho 188: break;
189: default:
190: errno = EDOM;
191: return (NULL);
192: }
193: return (STRDUP(mtype, buf));
194: }
195:
1.1.1.2 ! misho 196: #ifdef __clang__
! 197: #pragma clang diagnostic pop
! 198: #endif
! 199:
1.1 misho 200: int
201: structs_int_binify(const struct structs_type *type,
202: const char *ascii, void *data, char *ebuf, size_t emax)
203: {
204: static const long long bounds[][2] = {
205: { SCHAR_MIN, UCHAR_MAX },
206: { SHRT_MIN, USHRT_MAX },
207: { INT_MIN, UINT_MAX },
208: { LONG_MIN, ULONG_MAX },
209: { -0x7f - 1, 0xff },
210: { -0x7fff - 1, 0xffff },
211: { -0x7fffffff - 1, 0xffffffff },
212: { -0x7fffffffffffffffLL - 1, 0x7fffffffffffffffLL /*XXX*/ },
213: };
214: const int format = type->args[1].i;
215: long long value;
216: char *eptr;
217:
218: /* Sanity check */
219: if (type->args[0].i < 0 || type->args[0].i >= 8) {
220: errno = EDOM;
221: return (-1);
222: }
223:
224: /* Parse value */
225: #if _KERNEL
226: value = strtoq(ascii, &eptr, 0); /* assume quad_t == long long */
227: #else
228: value = strtoll(ascii, &eptr, 0);
229: #endif
230: if (eptr == ascii) {
231: strlcpy(ebuf, "invalid integer value", emax);
232: errno = EINVAL;
233: return (-1);
234: }
235: while (isspace(*eptr))
236: eptr++;
237: if (*eptr != '\0') {
238: errno = EINVAL;
239: return (-1);
240: }
241:
242: /* Check that value is in bounds XXX fails for LLONG_MAX..ULLONG_MAX */
243: if ((errno == ERANGE && (value == LLONG_MIN || value == LLONG_MAX))
244: || (format == 0 && value < 0LL) /* check unsignedness */
245: || value < bounds[type->args[0].i][0]
246: || value > bounds[type->args[0].i][1]) {
247: strlcpy(ebuf, "integer value is out of range", emax);
248: errno = EINVAL;
249: return (-1);
250: }
251:
252: /* Set value */
253: if (type->args[1].i == 1) {
254: switch (type->args[0].i) {
255: case 0:
256: *((char *)data) = (char)value;
257: break;
258: case 1:
259: *((short *)data) = (short)value;
260: break;
261: case 2:
262: *((int *)data) = (int)value;
263: break;
264: case 3:
265: *((long *)data) = (long)value;
266: break;
267: case 4:
268: *((int8_t *)data) = (int8_t)value;
269: break;
270: case 5:
271: *((int16_t *)data) = (int16_t)value;
272: break;
273: case 6:
274: *((int32_t *)data) = (int32_t)value;
275: break;
276: case 7:
277: *((int64_t *)data) = (int64_t)value;
278: break;
279: default:
280: errno = EDOM;
281: return (-1);
282: }
283: } else {
284: switch (type->args[0].i) {
285: case 0:
286: *((u_char *)data) = (u_char)value;
287: break;
288: case 1:
289: *((u_short *)data) = (u_short)value;
290: break;
291: case 2:
292: *((u_int *)data) = (u_int)value;
293: break;
294: case 3:
295: *((u_long *)data) = (u_long)value;
296: break;
297: case 4:
298: *((u_int8_t *)data) = (u_int8_t)value;
299: break;
300: case 5:
301: *((u_int16_t *)data) = (u_int16_t)value;
302: break;
303: case 6:
304: *((u_int32_t *)data) = (u_int32_t)value;
305: break;
306: case 7:
307: *((u_int64_t *)data) = (u_int64_t)value;
308: break;
309: default:
310: errno = EDOM;
311: return (-1);
312: }
313: }
314:
315: /* Done */
316: return (0);
317: }
318:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>