X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fhelper%2Fbinarybuffer.c;h=a3b1cbd59f07e6dce34f4fa0f5283c8decbfd7c3;hp=ce33f138f7a1a7ed4f25418edc65b714e6650558;hb=526fe3d83e118d87af34353a7140c02f3f1a3c19;hpb=82d2633b5f550115e9e7c7d0520babb6680aa38f diff --git a/src/helper/binarybuffer.c b/src/helper/binarybuffer.c index ce33f138f7..a3b1cbd59f 100644 --- a/src/helper/binarybuffer.c +++ b/src/helper/binarybuffer.c @@ -2,6 +2,9 @@ * Copyright (C) 2004, 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * + * Copyright (C) 2007,2008 Øyvind Harboe * + * oyvind.harboe@zylin.com * + * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * @@ -29,10 +32,6 @@ #include "binarybuffer.h" -int buf_set_u32(u8* buffer, unsigned int first, unsigned int num, u32 value); -u32 buf_get_u32(u8* buffer, unsigned int first, unsigned int num); -u32 flip_u32(u32 value, unsigned int num); - const unsigned char bit_reverse_table256[] = { 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, @@ -53,43 +52,6 @@ const unsigned char bit_reverse_table256[] = 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF }; -int buf_set_u32(u8* buffer, unsigned int first, unsigned int num, u32 value) -{ - unsigned int i; - - if (!buffer) - return ERROR_INVALID_ARGUMENTS; - - for (i=first; i> (i-first))&1) == 1) - buffer[i/8] |= 1 << (i%8); - else - buffer[i/8] &= ~(1 << (i%8)); - } - - return ERROR_OK; -} - -u32 buf_get_u32(u8* buffer, unsigned int first, unsigned int num) -{ - u32 result = 0; - unsigned int i; - - if (!buffer) - { - ERROR("buffer not initialized"); - return 0; - } - - for (i=first; i>(i%8))&1) == 1) - result |= 1 << (i-first); - } - - return result; -} u8* buf_cpy(u8 *from, u8 *to, int size) { @@ -101,6 +63,12 @@ u8* buf_cpy(u8 *from, u8 *to, int size) for (i = 0; i < num_bytes; i++) to[i] = from[i]; + + /* mask out bits that don't belong to the buffer */ + if (size % 8) + { + to[size / 8] &= (0xff >> (8 - (size % 8))); + } return to; } @@ -143,8 +111,8 @@ int buf_cmp_mask(u8 *buf1, u8 *buf2, u8 *mask, int size) /* mask out bits that don't really belong to the buffer if size isn't a multiple of 8 bits */ if ((size % 8) && (i == num_bytes -1 )) { - if (((buf1[i] & ((1 << (size % 8)) - 1)) & ((1 << (size % 8)) - 1)) != - ((buf2[i] & ((1 << (size % 8)) - 1)) & ((1 << (size % 8)) - 1))) + if ((buf1[i] & ((1 << (size % 8)) - 1) & mask[i]) != + (buf2[i] & ((1 << (size % 8)) - 1) & mask[i])) return 1; } else @@ -208,59 +176,164 @@ u32 flip_u32(u32 value, unsigned int num) return c; } -char* buf_to_char(u8 *buf, int size) +int ceil_f_to_u32(float x) { - int char_len = CEIL(size, 8) * 2; - char *char_buf = malloc(char_len + 1); - int i; - int bits_left = size; + u32 y; + + if (x < 0) /* return zero for negative numbers */ + return 0; + + y = x; /* cut off fraction */ + + if ((x - y) > 0.0) /* if there was a fractional part, increase by one */ + y++; - char_buf[char_len] = 0; + return y; +} + +char* buf_to_str(const u8 *buf, int buf_len, int radix) +{ + const char *DIGITS = "0123456789abcdef"; + float factor; + char *str; + int str_len; + int b256_len = CEIL(buf_len, 8); + u32 tmp; + + int j; /* base-256 digits */ + int i; /* output digits (radix) */ - for (i = 0; i < CEIL(size, 8); i++) + if (radix == 16) { - if (bits_left < 8) - { - buf[i] &= ((1 << bits_left) - 1); - } - - if (((buf[i] & 0x0f) >= 0) && ((buf[i] & 0x0f) <= 9)) - char_buf[char_len - 2*i - 1] = '0' + (buf[i] & 0xf); - else - char_buf[char_len - 2*i - 1] = 'a' + (buf[i] & 0xf) - 10; - - if (((buf[i] & 0xf0) >> 4 >= 0) && ((buf[i] & 0xf0) >> 4 <= 9)) - char_buf[char_len - 2*i - 2] = '0' + ((buf[i] & 0xf0) >> 4); - else - char_buf[char_len - 2*i - 2] = 'a' + ((buf[i] & 0xf0) >> 4) - 10; - + factor = 2.0; /* log(256) / log(16) = 2.0 */ + } + else if (radix == 10) + { + factor = 2.40824; /* log(256) / log(10) = 2.40824 */ + } + else if (radix == 8) + { + factor = 2.66667; /* log(256) / log(8) = 2.66667 */ } + else + return NULL; + + str_len = ceil_f_to_u32(CEIL(buf_len, 8) * factor); + str = calloc(str_len + 1, 1); + + for (i = b256_len - 1; i >= 0; i--) + { + tmp = buf[i]; + if ((i == (buf_len / 8)) && (buf_len % 8)) + tmp &= (0xff >> (8 - (buf_len % 8))); - return char_buf; + for (j = str_len; j > 0; j--) + { + tmp += (u32)str[j-1] * 256; + str[j-1] = (u8)(tmp % radix); + tmp /= radix; + } + } + + for (j = 0; j < str_len; j++) + str[j] = DIGITS[(int)str[j]]; + + return str; } -int char_to_buf(char *buf, int len, u8 *bin_buf, int buf_size) +int str_to_buf(const char *str, int str_len, u8 *buf, int buf_len, int radix) { - int bin_len = CEIL(len, 2); - int i; + char *charbuf; + u32 tmp; + float factor; + u8 *b256_buf; + int b256_len; - if (buf_size < CEIL(bin_len, 8)) - return 0; + int j; /* base-256 digits */ + int i; /* input digits (ASCII) */ + + if (radix == 0) + { + /* identify radix, and skip radix-prefix (0, 0x or 0X) */ + if ((str[0] == '0') && (str[1] && ((str[1] == 'x') || (str[1] == 'X')))) + { + radix = 16; + str += 2; + str_len -= 2; + } + else if ((str[0] == '0') && (str_len != 1)) + { + radix = 8; + str += 1; + str_len -= 1; + } + else + { + radix = 10; + } + } - if (len % 2) + if (radix == 16) + factor = 0.5; /* log(16) / log(256) = 0.5 */ + else if (radix == 10) + factor = 0.41524; /* log(10) / log(256) = 0.41524 */ + else if (radix == 8) + factor = 0.375; /* log(8) / log(256) = 0.375 */ + else return 0; + + /* copy to zero-terminated buffer */ + charbuf = malloc(str_len + 1); + memcpy(charbuf, str, str_len); + charbuf[str_len] = '\0'; - for (i = 0; i < strlen(buf); i++) + /* number of digits in base-256 notation */ + b256_len = ceil_f_to_u32(str_len * factor); + b256_buf = calloc(b256_len, 1); + + /* go through zero terminated buffer */ + for (i = 0; charbuf[i]; i++) + { + tmp = charbuf[i]; + if ((tmp >= '0') && (tmp <= '9')) + tmp = (tmp - '0'); + else if ((tmp >= 'a') && (tmp <= 'f')) + tmp = (tmp - 'a' + 10); + else if ((tmp >= 'A') && (tmp <= 'F')) + tmp = (tmp - 'A' + 10); + else continue; /* skip characters other than [0-9,a-f,A-F] */ + + if (tmp >= radix) + continue; /* skip digits invalid for the current radix */ + + for (j = 0; j < b256_len; j++) + { + tmp += (u32)b256_buf[j] * radix; + b256_buf[j] = (u8)(tmp & 0xFF); + tmp >>= 8; + } + + } + + for (j = 0; j < CEIL(buf_len, 8); j++) { - u32 tmp; - sscanf(buf + 2*i, "%2x", &tmp); - bin_buf[i] = tmp & 0xff; + if (j < b256_len) + buf[j] = b256_buf[j]; + else + buf[j] = 0; } + + /* mask out bits that don't belong to the buffer */ + if (buf_len % 8) + buf[(buf_len / 8)] &= 0xff >> (8 - (buf_len % 8)); + + free(b256_buf); + free(charbuf); - return bin_len * 8; + return i; } -int buf_to_u32_handler(u8 *in_buf, void *priv) +int buf_to_u32_handler(u8 *in_buf, void *priv, struct scan_field_s *field) { u32 *dest = priv;