Annotation of embedaddon/libpdel/structs/type/structs_type_data.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: #include <sys/socket.h>
! 43: #include <netinet/in.h>
! 44: #include <arpa/inet.h>
! 45: #include <net/ethernet.h>
! 46:
! 47: #include <stdlib.h>
! 48: #include <stdio.h>
! 49: #include <stdarg.h>
! 50: #include <string.h>
! 51: #include <limits.h>
! 52: #include <assert.h>
! 53: #include <ctype.h>
! 54: #include <errno.h>
! 55: #include <time.h>
! 56:
! 57: #include "structs/structs.h"
! 58: #include "structs/type/array.h"
! 59: #include "structs/type/data.h"
! 60: #include "io/filter.h"
! 61: #include "io/base64.h"
! 62: #include "util/typed_mem.h"
! 63:
! 64: #define HEXVAL(c) (isdigit(c) ? (c) - '0' : tolower(c) - 'a' + 10)
! 65:
! 66: static const char hexchars[] = "0123456789abcdef";
! 67:
! 68: /*********************************************************************
! 69: BINARY DATA TYPE
! 70: *********************************************************************/
! 71:
! 72: int
! 73: structs_data_copy(const struct structs_type *type, const void *from, void *to)
! 74: {
! 75: const char *const mtype = type->args[1].v;
! 76: const struct structs_data *const fdata = from;
! 77: struct structs_data *const tdata = to;
! 78: u_char *copy;
! 79:
! 80: if (fdata->length == 0) {
! 81: memset(tdata, 0, sizeof(*tdata));
! 82: return (0);
! 83: }
! 84: if ((copy = MALLOC(mtype, fdata->length)) == NULL)
! 85: return (-1);
! 86: memcpy(copy, fdata->data, fdata->length);
! 87: tdata->data = copy;
! 88: tdata->length = fdata->length;
! 89: return (0);
! 90: }
! 91:
! 92: int
! 93: structs_data_equal(const struct structs_type *type,
! 94: const void *v1, const void *v2)
! 95: {
! 96: const struct structs_data *const d1 = v1;
! 97: const struct structs_data *const d2 = v2;
! 98:
! 99: return (d1->length == d2->length
! 100: && memcmp(d1->data, d2->data, d1->length) == 0);
! 101: }
! 102:
! 103: char *
! 104: structs_data_ascify(const struct structs_type *type,
! 105: const char *mtype, const void *data)
! 106: {
! 107: const char *const charmap = type->args[0].v;
! 108: const struct structs_data *const d = data;
! 109: struct filter *encoder;
! 110: char *edata;
! 111: int elen;
! 112: int i;
! 113:
! 114: /* Handle hex encoding */
! 115: if (charmap != NULL && *charmap == '\0') {
! 116: if ((edata = MALLOC(mtype, d->length * 2 + 1)) == NULL)
! 117: return (NULL);
! 118: for (i = 0; i < d->length; i++) {
! 119: edata[i * 2] = hexchars[(d->data[i] >> 4) & 0x0f];
! 120: edata[i * 2 + 1] = hexchars[d->data[i] & 0x0f];
! 121: }
! 122: edata[i * 2] = '\0';
! 123: return (edata);
! 124: }
! 125:
! 126: /* Get encoding filter */
! 127: if ((encoder = b64_encoder_create(charmap)) == NULL)
! 128: return (NULL);
! 129:
! 130: /* Encode data */
! 131: elen = filter_process(encoder, d->data,
! 132: d->length, 1, (u_char **)&edata, mtype);
! 133: filter_destroy(&encoder);
! 134: if (elen == -1)
! 135: return (NULL);
! 136:
! 137: /* Return encoded data as a string */
! 138: edata[elen] = '\0';
! 139: return (edata);
! 140: }
! 141:
! 142: int
! 143: structs_data_binify(const struct structs_type *type,
! 144: const char *ascii, void *data, char *ebuf, size_t emax)
! 145: {
! 146: const char *const charmap = type->args[0].v;
! 147: const char *const mtype = type->args[1].v;
! 148: struct structs_data *const d = data;
! 149: struct filter *decoder;
! 150: u_char *bdata;
! 151: int blen;
! 152: int i;
! 153:
! 154: /* Handle hex encoding */
! 155: if (charmap != NULL && *charmap == '\0') {
! 156: if ((bdata = MALLOC(mtype, (strlen(ascii) + 1) / 2)) == NULL)
! 157: return (-1);
! 158: for (blen = 0; *ascii != '\0'; blen++) {
! 159: while (isspace(*ascii))
! 160: ascii++;
! 161: if (*ascii == '\0')
! 162: break;
! 163: bdata[blen] = 0;
! 164: for (i = 4; i >= 0; i -= 4) {
! 165: if (!isxdigit(*ascii)) {
! 166: strlcpy(ebuf, *ascii == '\0' ?
! 167: "odd length hex sequence" :
! 168: "non-hex character seen", emax);
! 169: FREE(mtype, bdata);
! 170: return (-1);
! 171: }
! 172: bdata[blen] |= HEXVAL(*ascii) << i;
! 173: ascii++;
! 174: }
! 175: }
! 176: goto done;
! 177: }
! 178:
! 179: /* Get decoding filter */
! 180: if ((decoder = b64_decoder_create(charmap, 1)) == NULL)
! 181: return (-1);
! 182:
! 183: /* Decode data */
! 184: blen = filter_process(decoder, ascii, strlen(ascii), 1, &bdata, mtype);
! 185: filter_destroy(&decoder);
! 186: if (blen == -1) {
! 187: strlcpy(ebuf, "invalid encoded binary data", emax);
! 188: return (-1);
! 189: }
! 190:
! 191: done:
! 192: /* Fill in structure */
! 193: d->length = blen;
! 194: d->data = bdata;
! 195: return (0);
! 196: }
! 197:
! 198: void
! 199: structs_data_free(const struct structs_type *type, void *data)
! 200: {
! 201: const char *const mtype = type->args[1].v;
! 202: struct structs_data *const d = data;
! 203:
! 204: FREE(mtype, d->data);
! 205: memset(d, 0, sizeof(*d));
! 206: }
! 207:
! 208: int
! 209: structs_data_encode(const struct structs_type *type, const char *mtype,
! 210: struct structs_data *code, const void *data)
! 211: {
! 212: const struct structs_data *const d = data;
! 213: u_int32_t elength;
! 214:
! 215: if ((code->data = MALLOC(mtype, 4 + d->length)) == NULL)
! 216: return (-1);
! 217: elength = htonl(d->length);
! 218: memcpy(code->data, &elength, 4);
! 219: memcpy(code->data + 4, d->data, d->length);
! 220: code->length = 4 + d->length;
! 221: return (0);
! 222: }
! 223:
! 224: int
! 225: structs_data_decode(const struct structs_type *type, const u_char *code,
! 226: size_t cmax, void *data, char *ebuf, size_t emax)
! 227: {
! 228: const char *const mtype = type->args[1].v;
! 229: struct structs_data *const d = data;
! 230: u_int32_t elength;
! 231:
! 232: if (cmax < 4)
! 233: goto bogus;
! 234: memcpy(&elength, code, 4);
! 235: d->length = ntohl(elength);
! 236: if (cmax < d->length) {
! 237: bogus: strlcpy(ebuf, "encoded data is corrupted", emax);
! 238: errno = EINVAL;
! 239: return (-1);
! 240: }
! 241: if ((d->data = MALLOC(mtype, d->length)) == NULL)
! 242: return (-1);
! 243: memcpy(d->data, code + 4, d->length);
! 244: return (4 + d->length);
! 245: }
! 246:
! 247: const struct structs_type structs_type_data =
! 248: STRUCTS_DATA_TYPE(NULL, STRUCTS_DATA_MEMTYPE);
! 249:
! 250: const struct structs_type structs_type_hexdata =
! 251: STRUCTS_DATA_TYPE("", STRUCTS_DATA_MEMTYPE);
! 252:
! 253: /*********************************************************************
! 254: FIXED LENGTH BINARY DATA TYPE
! 255: *********************************************************************/
! 256:
! 257: char *
! 258: structs_fixeddata_ascify(const struct structs_type *type,
! 259: const char *mtype, const void *data)
! 260: {
! 261: const u_char *bytes = data;
! 262: char *s;
! 263: int i;
! 264:
! 265: if ((s = MALLOC(mtype, type->size * 2 + 1)) == NULL)
! 266: return (NULL);
! 267: for (i = 0; i < type->size; i++) {
! 268: s[i * 2] = hexchars[(bytes[i] >> 4) & 0x0f];
! 269: s[i * 2 + 1] = hexchars[bytes[i] & 0x0f];
! 270: }
! 271: s[i * 2] = '\0';
! 272: return (s);
! 273: }
! 274:
! 275: int
! 276: structs_fixeddata_binify(const struct structs_type *type,
! 277: const char *ascii, void *data, char *ebuf, size_t emax)
! 278: {
! 279: u_char *bytes = data;
! 280: int i;
! 281: int j;
! 282:
! 283: for (i = 0; i < type->size; i++) {
! 284: bytes[i] = 0;
! 285: for (j = 4; j >= 0; j -= 4) {
! 286: while (isspace(*ascii))
! 287: ascii++;
! 288: if (!isxdigit(*ascii)) {
! 289: strlcpy(ebuf, *ascii == '\0' ?
! 290: "hex string is too short" :
! 291: "non-hex character seen", emax);
! 292: goto fail;
! 293: }
! 294: bytes[i] |= HEXVAL(*ascii) << j;
! 295: ascii++;
! 296: }
! 297: }
! 298: while (isspace(*ascii))
! 299: ascii++;
! 300: if (*ascii != '\0') {
! 301: strlcpy(ebuf, "hex string is too long", emax);
! 302: fail: errno = EINVAL;
! 303: return (-1);
! 304: }
! 305: return (0);
! 306: }
! 307:
! 308: int
! 309: structs_fixeddata_encode(const struct structs_type *type, const char *mtype,
! 310: struct structs_data *code, const void *data)
! 311: {
! 312: if ((code->data = MALLOC(mtype, type->size)) == NULL)
! 313: return (-1);
! 314: memcpy(code->data, data, type->size);
! 315: code->length = type->size;
! 316: return (0);
! 317: }
! 318:
! 319: int
! 320: structs_fixeddata_decode(const struct structs_type *type, const u_char *code,
! 321: size_t cmax, void *data, char *ebuf, size_t emax)
! 322: {
! 323: if (cmax < type->size) {
! 324: strlcpy(ebuf, "encoded data is truncated", emax);
! 325: errno = EINVAL;
! 326: return (-1);
! 327: }
! 328: memcpy(data, code, type->size);
! 329: return (type->size);
! 330: }
! 331:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>