Return to structs_type_int.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / libpdel / structs / type |
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: