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>