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>