Annotation of embedaddon/ntp/lib/isc/hex.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
! 3: * Copyright (C) 2000-2003 Internet Software Consortium.
! 4: *
! 5: * Permission to use, copy, modify, and/or distribute this software for any
! 6: * purpose with or without fee is hereby granted, provided that the above
! 7: * copyright notice and this permission notice appear in all copies.
! 8: *
! 9: * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
! 10: * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
! 11: * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
! 12: * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
! 13: * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
! 14: * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
! 15: * PERFORMANCE OF THIS SOFTWARE.
! 16: */
! 17:
! 18: /* $Id: hex.c,v 1.20 2008/09/25 04:02:39 tbox Exp $ */
! 19:
! 20: /*! \file */
! 21:
! 22: #include <config.h>
! 23:
! 24: #include <ctype.h>
! 25:
! 26: #include <isc/buffer.h>
! 27: #include <isc/hex.h>
! 28: #include <isc/lex.h>
! 29: #include <isc/string.h>
! 30: #include <isc/util.h>
! 31:
! 32: #define RETERR(x) do { \
! 33: isc_result_t _r = (x); \
! 34: if (_r != ISC_R_SUCCESS) \
! 35: return (_r); \
! 36: } while (0)
! 37:
! 38:
! 39: /*
! 40: * BEW: These static functions are copied from lib/dns/rdata.c.
! 41: */
! 42: static isc_result_t
! 43: str_totext(const char *source, isc_buffer_t *target);
! 44:
! 45: static isc_result_t
! 46: mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length);
! 47:
! 48: static const char hex[] = "0123456789ABCDEF";
! 49:
! 50: isc_result_t
! 51: isc_hex_totext(isc_region_t *source, int wordlength,
! 52: const char *wordbreak, isc_buffer_t *target)
! 53: {
! 54: char buf[3];
! 55: unsigned int loops = 0;
! 56:
! 57: if (wordlength < 2)
! 58: wordlength = 2;
! 59:
! 60: memset(buf, 0, sizeof(buf));
! 61: while (source->length > 0) {
! 62: buf[0] = hex[(source->base[0] >> 4) & 0xf];
! 63: buf[1] = hex[(source->base[0]) & 0xf];
! 64: RETERR(str_totext(buf, target));
! 65: isc_region_consume(source, 1);
! 66:
! 67: loops++;
! 68: if (source->length != 0 &&
! 69: (int)((loops + 1) * 2) >= wordlength)
! 70: {
! 71: loops = 0;
! 72: RETERR(str_totext(wordbreak, target));
! 73: }
! 74: }
! 75: return (ISC_R_SUCCESS);
! 76: }
! 77:
! 78: /*%
! 79: * State of a hex decoding process in progress.
! 80: */
! 81: typedef struct {
! 82: int length; /*%< Desired length of binary data or -1 */
! 83: isc_buffer_t *target; /*%< Buffer for resulting binary data */
! 84: int digits; /*%< Number of buffered hex digits */
! 85: int val[2];
! 86: } hex_decode_ctx_t;
! 87:
! 88: static inline void
! 89: hex_decode_init(hex_decode_ctx_t *ctx, int length, isc_buffer_t *target)
! 90: {
! 91: ctx->digits = 0;
! 92: ctx->length = length;
! 93: ctx->target = target;
! 94: }
! 95:
! 96: static inline isc_result_t
! 97: hex_decode_char(hex_decode_ctx_t *ctx, int c) {
! 98: char *s;
! 99:
! 100: if ((s = strchr(hex, toupper(c))) == NULL)
! 101: return (ISC_R_BADHEX);
! 102: ctx->val[ctx->digits++] = s - hex;
! 103: if (ctx->digits == 2) {
! 104: unsigned char num;
! 105:
! 106: num = (ctx->val[0] << 4) + (ctx->val[1]);
! 107: RETERR(mem_tobuffer(ctx->target, &num, 1));
! 108: if (ctx->length >= 0) {
! 109: if (ctx->length == 0)
! 110: return (ISC_R_BADHEX);
! 111: else
! 112: ctx->length -= 1;
! 113: }
! 114: ctx->digits = 0;
! 115: }
! 116: return (ISC_R_SUCCESS);
! 117: }
! 118:
! 119: static inline isc_result_t
! 120: hex_decode_finish(hex_decode_ctx_t *ctx) {
! 121: if (ctx->length > 0)
! 122: return (ISC_R_UNEXPECTEDEND);
! 123: if (ctx->digits != 0)
! 124: return (ISC_R_BADHEX);
! 125: return (ISC_R_SUCCESS);
! 126: }
! 127:
! 128: isc_result_t
! 129: isc_hex_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) {
! 130: hex_decode_ctx_t ctx;
! 131: isc_textregion_t *tr;
! 132: isc_token_t token;
! 133: isc_boolean_t eol;
! 134:
! 135: hex_decode_init(&ctx, length, target);
! 136:
! 137: while (ctx.length != 0) {
! 138: unsigned int i;
! 139:
! 140: if (length > 0)
! 141: eol = ISC_FALSE;
! 142: else
! 143: eol = ISC_TRUE;
! 144: RETERR(isc_lex_getmastertoken(lexer, &token,
! 145: isc_tokentype_string, eol));
! 146: if (token.type != isc_tokentype_string)
! 147: break;
! 148: tr = &token.value.as_textregion;
! 149: for (i = 0; i < tr->length; i++)
! 150: RETERR(hex_decode_char(&ctx, tr->base[i]));
! 151: }
! 152: if (ctx.length < 0)
! 153: isc_lex_ungettoken(lexer, &token);
! 154: RETERR(hex_decode_finish(&ctx));
! 155: return (ISC_R_SUCCESS);
! 156: }
! 157:
! 158: isc_result_t
! 159: isc_hex_decodestring(const char *cstr, isc_buffer_t *target) {
! 160: hex_decode_ctx_t ctx;
! 161:
! 162: hex_decode_init(&ctx, -1, target);
! 163: for (;;) {
! 164: int c = *cstr++;
! 165: if (c == '\0')
! 166: break;
! 167: if (c == ' ' || c == '\t' || c == '\n' || c== '\r')
! 168: continue;
! 169: RETERR(hex_decode_char(&ctx, c));
! 170: }
! 171: RETERR(hex_decode_finish(&ctx));
! 172: return (ISC_R_SUCCESS);
! 173: }
! 174:
! 175: static isc_result_t
! 176: str_totext(const char *source, isc_buffer_t *target) {
! 177: unsigned int l;
! 178: isc_region_t region;
! 179:
! 180: isc_buffer_availableregion(target, ®ion);
! 181: l = strlen(source);
! 182:
! 183: if (l > region.length)
! 184: return (ISC_R_NOSPACE);
! 185:
! 186: memcpy(region.base, source, l);
! 187: isc_buffer_add(target, l);
! 188: return (ISC_R_SUCCESS);
! 189: }
! 190:
! 191: static isc_result_t
! 192: mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) {
! 193: isc_region_t tr;
! 194:
! 195: isc_buffer_availableregion(target, &tr);
! 196: if (length > tr.length)
! 197: return (ISC_R_NOSPACE);
! 198: memcpy(tr.base, base, length);
! 199: isc_buffer_add(target, length);
! 200: return (ISC_R_SUCCESS);
! 201: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>