Annotation of embedaddon/libpdel/structs/type/structs_type_int.c, revision 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>