+// 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+#include "helper/replacements.h"
#include "log.h"
#include "binarybuffer.h"
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 */
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 */
}
}
- return (uint8_t *)_dst;
+ return _dst;
}
uint32_t flip_u32(uint32_t value, unsigned int num)
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;
}
unsigned *_radix)
{
unsigned radix = *_radix;
- if (0 != radix)
+ if (radix != 0)
return;
const char *str = *_str;
unsigned str_len = *_str_len;
free(qe);
}
}
+
+/**
+ * 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)
+{
+ 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;
+
+ 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;
+}
+
+void buffer_shr(void *_buf, unsigned buf_len, unsigned count)
+{
+ unsigned i;
+ unsigned char *buf = _buf;
+ unsigned bytes_to_remove;
+ unsigned shift;
+
+ bytes_to_remove = count / 8;
+ shift = count - (bytes_to_remove * 8);
+
+ for (i = 0; i < (buf_len - 1); i++)
+ buf[i] = (buf[i] >> shift) | ((buf[i+1] << (8 - shift)) & 0xff);
+
+ 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);
+ }
+}