X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fhelper%2Fbinarybuffer.c;h=76f657f8df8eb9b88758ff80b29b6370ee092e12;hb=d303a2864df74117f6d0b2fae3f461fb0ee72226;hp=a90ec7b01ebab7dc3b928104df4badb77d38e59a;hpb=adb8ec32dc7439aa3e34ab19f026e390ec129c10;p=openocd.git diff --git a/src/helper/binarybuffer.c b/src/helper/binarybuffer.c index a90ec7b01e..76f657f8df 100644 --- a/src/helper/binarybuffer.c +++ b/src/helper/binarybuffer.c @@ -16,9 +16,7 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * along with this program. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -47,6 +45,11 @@ static const unsigned char bit_reverse_table256[] = { 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF }; +static const char hex_digits[] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f' +}; + void *buf_cpy(const void *from, void *_to, unsigned size) { if (NULL == from || NULL == _to) @@ -148,7 +151,7 @@ void *buf_set_buf(const void *_src, unsigned src_start, if ((sq == 0) && (dq == 0) && (lq == 0)) { for (i = 0; i < lb; i++) *dst++ = *src++; - return (uint8_t *)_dst; + return _dst; } /* fallback to slow bit copy */ @@ -167,7 +170,7 @@ void *buf_set_buf(const void *_src, unsigned src_start, } } - return (uint8_t *)_dst; + return _dst; } uint32_t flip_u32(uint32_t value, unsigned int num) @@ -231,7 +234,7 @@ char *buf_to_str(const void *_buf, unsigned buf_len, unsigned radix) } } - const char *DIGITS = "0123456789ABCDEF"; + const char * const DIGITS = "0123456789ABCDEF"; for (unsigned j = 0; j < str_len; j++) str[j] = DIGITS[(int)str[j]]; @@ -371,29 +374,91 @@ void bit_copy_discard(struct bit_copy_queue *q) } } -int unhexify(char *bin, const char *hex, int count) +/** + * Convert a string of hexadecimal pairs into its binary + * representation. + * + * @param[out] bin Buffer to store binary representation. The buffer size must + * be at least @p count. + * @param[in] hex String with hexadecimal pairs to convert into its binary + * representation. + * @param[in] count Number of hexadecimal pairs to convert. + * + * @return The number of converted hexadecimal pairs. + */ +size_t unhexify(uint8_t *bin, const char *hex, size_t count) { - int i, tmp; + size_t i; + char tmp; + + if (!bin || !hex) + return 0; + + memset(bin, 0, count); - for (i = 0; i < count; i++) { - if (sscanf(hex + (2 * i), "%02x", &tmp) != 1) - return i; - bin[i] = tmp; + for (i = 0; i < 2 * count; i++) { + if (hex[i] >= 'a' && hex[i] <= 'f') + tmp = hex[i] - 'a' + 10; + else if (hex[i] >= 'A' && hex[i] <= 'F') + tmp = hex[i] - 'A' + 10; + else if (hex[i] >= '0' && hex[i] <= '9') + tmp = hex[i] - '0'; + else + return i / 2; + + bin[i / 2] |= tmp << (4 * ((i + 1) % 2)); } + return i / 2; +} + +/** + * Convert binary data into a string of hexadecimal pairs. + * + * @param[out] hex Buffer to store string of hexadecimal pairs. The buffer size + * must be at least @p length. + * @param[in] bin Buffer with binary data to convert into hexadecimal pairs. + * @param[in] count Number of bytes to convert. + * @param[in] length Maximum number of characters, including null-terminator, + * to store into @p hex. + * + * @returns The length of the converted string excluding null-terminator. + */ +size_t hexify(char *hex, const uint8_t *bin, size_t count, size_t length) +{ + size_t i; + uint8_t tmp; + + if (!length) + return 0; + + for (i = 0; i < length - 1 && i < 2 * count; i++) { + tmp = (bin[i / 2] >> (4 * ((i + 1) % 2))) & 0x0f; + hex[i] = hex_digits[tmp]; + } + + hex[i] = 0; + return i; } -int hexify(char *hex, const char *bin, int count, int out_maxlen) +void buffer_shr(void *_buf, unsigned buf_len, unsigned count) { - int i, cmd_len = 0; + unsigned i; + unsigned char *buf = _buf; + unsigned bytes_to_remove; + unsigned shift; - /* May use a length, or a null-terminated string as input. */ - if (count == 0) - count = strlen(bin); + bytes_to_remove = count / 8; + shift = count - (bytes_to_remove * 8); - for (i = 0; i < count; i++) - cmd_len += snprintf(hex + cmd_len, out_maxlen - cmd_len, "%02x", bin[i]); + for (i = 0; i < (buf_len - 1); i++) + buf[i] = (buf[i] >> shift) | ((buf[i+1] << (8 - shift)) & 0xff); - return cmd_len; + buf[(buf_len - 1)] = buf[(buf_len - 1)] >> shift; + + if (bytes_to_remove) { + memmove(buf, &buf[bytes_to_remove], buf_len - bytes_to_remove); + memset(&buf[buf_len - bytes_to_remove], 0, bytes_to_remove); + } }