X-Git-Url: https://git.gag.com/?a=blobdiff_plain;ds=sidebyside;f=src%2Fhelper%2Fbinarybuffer.c;h=5f38b43ae1957f8142d6a41f3cfbce9face47c52;hb=382148e4dd437978997d668f6ec715ddcec1c46e;hp=6fe3664a7fa09e1b94d1bf31623551e2fdad3a63;hpb=4e79b48e2c7e535ef21178a69788c15b571c72ff;p=fw%2Fopenocd diff --git a/src/helper/binarybuffer.c b/src/helper/binarybuffer.c index 6fe3664a7..5f38b43ae 100644 --- a/src/helper/binarybuffer.c +++ b/src/helper/binarybuffer.c @@ -1,30 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * 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 * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * 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., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif +#include "helper/replacements.h" #include "log.h" #include "binarybuffer.h" @@ -47,9 +35,14 @@ 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) + if (!from || !_to) return NULL; /* copy entire buffer */ @@ -148,7 +141,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 +160,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) @@ -196,45 +189,20 @@ static int ceil_f_to_u32(float x) return y; } -char *buf_to_str(const void *_buf, unsigned buf_len, unsigned radix) +char *buf_to_hex_str(const void *_buf, unsigned buf_len) { - float factor; - switch (radix) { - case 16: - factor = 2.0; /* log(256) / log(16) = 2.0 */ - break; - case 10: - factor = 2.40824; /* log(256) / log(10) = 2.40824 */ - break; - case 8: - factor = 2.66667; /* log(256) / log(8) = 2.66667 */ - break; - default: - return NULL; - } - - unsigned str_len = ceil_f_to_u32(DIV_ROUND_UP(buf_len, 8) * factor); - char *str = calloc(str_len + 1, 1); + unsigned len_bytes = DIV_ROUND_UP(buf_len, 8); + char *str = calloc(len_bytes * 2 + 1, 1); const uint8_t *buf = _buf; - int b256_len = DIV_ROUND_UP(buf_len, 8); - for (int i = b256_len - 1; i >= 0; i--) { - uint32_t tmp = buf[i]; - if (((unsigned)i == (buf_len / 8)) && (buf_len % 8)) + for (unsigned i = 0; i < len_bytes; i++) { + uint8_t tmp = buf[len_bytes - i - 1]; + if ((i == 0) && (buf_len % 8)) tmp &= (0xff >> (8 - (buf_len % 8))); - - /* base-256 digits */ - for (unsigned j = str_len; j > 0; j--) { - tmp += (uint32_t)str[j-1] * 256; - str[j-1] = (uint8_t)(tmp % radix); - tmp /= radix; - } + str[2 * i] = hex_digits[tmp >> 4]; + str[2 * i + 1] = hex_digits[tmp & 0xf]; } - const char *DIGITS = "0123456789ABCDEF"; - for (unsigned j = 0; j < str_len; j++) - str[j] = DIGITS[(int)str[j]]; - return str; } @@ -243,7 +211,7 @@ static void str_radix_guess(const char **_str, unsigned *_str_len, unsigned *_radix) { unsigned radix = *_radix; - if (0 != radix) + if (radix != 0) return; const char *str = *_str; unsigned str_len = *_str_len; @@ -371,31 +339,72 @@ 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 < 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; - for (i = 0; i < count; i++) { - if (sscanf(hex + (2 * i), "%02x", &tmp) != 1) - return i; - bin[i] = tmp; + bin[i / 2] |= tmp << (4 * ((i + 1) % 2)); } - return i; + return i / 2; } -int hexify(char *hex, const char *bin, int count, int out_maxlen) +/** + * 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) { - int i, cmd_len = 0; + size_t i; + uint8_t tmp; - /* May use a length, or a null-terminated string as input. */ - if (count == 0) - count = strlen(bin); + if (!length) + return 0; - for (i = 0; i < count; i++) - cmd_len += snprintf(hex + cmd_len, out_maxlen - cmd_len, "%02x", bin[i] & 0xff); + for (i = 0; i < length - 1 && i < 2 * count; i++) { + tmp = (bin[i / 2] >> (4 * ((i + 1) % 2))) & 0x0f; + hex[i] = hex_digits[tmp]; + } - return cmd_len; + hex[i] = 0; + + return i; } void buffer_shr(void *_buf, unsigned buf_len, unsigned count)