openocd: fix SPDX tag format for files .c
[fw/openocd] / src / helper / binarybuffer.c
index a3c993d3ea47f7821344719b3284adf7ba5f9415..5f38b43ae1957f8142d6a41f3cfbce9face47c52 100644 (file)
@@ -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 */
@@ -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)