* Copyright (C) 2004, 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
- * Copyright (C) 2007,2008 Øyvind Harboe *
+ * Copyright (C) 2007,2008 Øyvind Harboe *
* oyvind.harboe@zylin.com *
* *
* This program is free software; you can redistribute it and/or modify *
#include "config.h"
#endif
-#include <stdlib.h>
-#include <string.h>
-
-#include "types.h"
#include "log.h"
-
#include "binarybuffer.h"
const unsigned char bit_reverse_table256[] =
};
-u8* buf_cpy(u8 *from, u8 *to, int size)
+void* buf_cpy(const void *from, void *_to, unsigned size)
{
- unsigned int num_bytes = CEIL(size, 8);
- unsigned int i;
-
- if (from == NULL)
+ if (NULL == from || NULL == _to)
return NULL;
- for (i = 0; i < num_bytes; i++)
- to[i] = from[i];
+ // copy entire buffer
+ memcpy(_to, from, DIV_ROUND_UP(size, 8));
/* mask out bits that don't belong to the buffer */
- if (size % 8)
+ unsigned trailing_bits = size % 8;
+ if (trailing_bits)
{
- to[size / 8] &= (0xff >> (8 - (size % 8)));
+ uint8_t *to = _to;
+ to[size / 8] &= (1 << trailing_bits) - 1;
}
+ return _to;
+}
- return to;
+static bool buf_cmp_masked(uint8_t a, uint8_t b, uint8_t m)
+{
+ return (a & m) != (b & m);
+}
+static bool buf_cmp_trailing(uint8_t a, uint8_t b, uint8_t m, unsigned trailing)
+{
+ uint8_t mask = (1 << trailing) - 1;
+ return buf_cmp_masked(a, b, mask & m);
}
-int buf_cmp(u8 *buf1, u8 *buf2, int size)
+bool buf_cmp(const void *_buf1, const void *_buf2, unsigned size)
{
- int num_bytes = CEIL(size, 8);
- int i;
+ if (!_buf1 || !_buf2)
+ return _buf1 != _buf2;
- if (!buf1 || !buf2)
- return 1;
+ unsigned last = size / 8;
+ if (memcmp(_buf1, _buf2, last) != 0)
+ return false;
- for (i = 0; i < num_bytes; i++)
- {
- /* last byte */
- /* 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)) != (buf2[i] & ((1 << (size % 8)) - 1)))
- return 1;
- }
- else
- {
- if (buf1[i] != buf2[i])
- return 1;
- }
- }
+ unsigned trailing = size % 8;
+ if (!trailing)
+ return false;
- return 0;
+ const uint8_t *buf1 = _buf1, *buf2 = _buf2;
+ return buf_cmp_trailing(buf1[last], buf2[last], 0xff, trailing);
}
-int buf_cmp_mask(u8 *buf1, u8 *buf2, u8 *mask, int size)
+bool buf_cmp_mask(const void *_buf1, const void *_buf2,
+ const void *_mask, unsigned size)
{
- int num_bytes = CEIL(size, 8);
- int i;
+ if (!_buf1 || !_buf2)
+ return _buf1 != _buf2 || _buf1 != _mask;
- for (i = 0; i < num_bytes; i++)
+ const uint8_t *buf1 = _buf1, *buf2 = _buf2, *mask = _mask;
+ unsigned last = size / 8;
+ for (unsigned i = 0; i < last; i++)
{
- /* last byte */
- /* 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) & mask[i]) !=
- (buf2[i] & ((1 << (size % 8)) - 1) & mask[i]))
- return 1;
- }
- else
- {
- if ((buf1[i] & mask[i]) != (buf2[i] & mask[i]))
- return 1;
- }
+ if (buf_cmp_masked(buf1[i], buf2[i], mask[i]))
+ return true;
}
-
- return 0;
+ unsigned trailing = size % 8;
+ if (!trailing)
+ return false;
+ return buf_cmp_trailing(buf1[last], buf2[last], mask[last], trailing);
}
-u8* buf_set_ones(u8 *buf, int count)
+
+void* buf_set_ones(void *_buf, unsigned size)
{
- int num_bytes = CEIL(count, 8);
- int i;
+ uint8_t *buf = _buf;
+ if (!buf)
+ return NULL;
- for (i = 0; i < num_bytes; i++)
- {
- if (count >= 8)
- buf[i] = 0xff;
- else
- buf[i] = (1 << count) - 1;
+ memset(buf, 0xff, size / 8);
- count -= 8;
- }
+ unsigned trailing_bits = size % 8;
+ if (trailing_bits)
+ buf[size / 8] = (1 << trailing_bits) - 1;
return buf;
}
-u8* buf_set_buf(u8 *src, int src_start, u8 *dst, int dst_start, int len)
+void* buf_set_buf(const void *_src, unsigned src_start,
+ void *_dst, unsigned dst_start, unsigned len)
{
- int src_idx = src_start, dst_idx = dst_start;
- int i;
+ const uint8_t *src = _src;
+ uint8_t *dst = _dst;
- for (i = 0; i < len; i++)
+ unsigned src_idx = src_start, dst_idx = dst_start;
+ for (unsigned i = 0; i < len; i++)
{
- if (((src[src_idx/8] >> (src_idx % 8)) & 1) == 1)
- dst[dst_idx/8] |= 1 << (dst_idx%8);
+ if (((src[src_idx / 8] >> (src_idx % 8)) & 1) == 1)
+ dst[dst_idx / 8] |= 1 << (dst_idx % 8);
else
- dst[dst_idx/8] &= ~(1 << (dst_idx%8));
+ dst[dst_idx / 8] &= ~(1 << (dst_idx % 8));
dst_idx++;
src_idx++;
}
return dst;
}
-u32 flip_u32(u32 value, unsigned int num)
+uint32_t flip_u32(uint32_t value, unsigned int num)
{
- u32 c;
-
- c = (bit_reverse_table256[value & 0xff] << 24) |
+ uint32_t c = (bit_reverse_table256[value & 0xff] << 24) |
(bit_reverse_table256[(value >> 8) & 0xff] << 16) |
(bit_reverse_table256[(value >> 16) & 0xff] << 8) |
(bit_reverse_table256[(value >> 24) & 0xff]);
int ceil_f_to_u32(float x)
{
- u32 y;
-
if (x < 0) /* return zero for negative numbers */
return 0;
- y = x; /* cut off fraction */
+ uint32_t y = x; /* cut off fraction */
if ((x - y) > 0.0) /* if there was a fractional part, increase by one */
y++;
return y;
}
-char* buf_to_str(const u8 *buf, int buf_len, int radix)
+char* buf_to_str(const void *_buf, unsigned buf_len, unsigned 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) */
-
- if (radix == 16)
- {
+ switch (radix) {
+ case 16:
factor = 2.0; /* log(256) / log(16) = 2.0 */
- }
- else if (radix == 10)
- {
+ break;
+ case 10:
factor = 2.40824; /* log(256) / log(10) = 2.40824 */
- }
- else if (radix == 8)
- {
+ break;
+ case 8:
factor = 2.66667; /* log(256) / log(8) = 2.66667 */
- }
- else
+ break;
+ default:
return NULL;
+ }
- str_len = ceil_f_to_u32(CEIL(buf_len, 8) * factor);
- str = calloc(str_len + 1, 1);
+ unsigned str_len = ceil_f_to_u32(DIV_ROUND_UP(buf_len, 8) * factor);
+ char *str = calloc(str_len + 1, 1);
- for (i = b256_len - 1; i >= 0; i--)
+ const uint8_t *buf = _buf;
+ int b256_len = DIV_ROUND_UP(buf_len, 8);
+ for (int i = b256_len - 1; i >= 0; i--)
{
- tmp = buf[i];
- if ((i == (buf_len / 8)) && (buf_len % 8))
+ uint32_t tmp = buf[i];
+ if (((unsigned)i == (buf_len / 8)) && (buf_len % 8))
tmp &= (0xff >> (8 - (buf_len % 8)));
- for (j = str_len; j > 0; j--)
+ /* base-256 digits */
+ for (unsigned j = str_len; j > 0; j--)
{
- tmp += (u32)str[j-1] * 256;
- str[j-1] = (u8)(tmp % radix);
+ tmp += (uint32_t)str[j-1] * 256;
+ str[j-1] = (uint8_t)(tmp % radix);
tmp /= radix;
}
}
- for (j = 0; j < str_len; j++)
+ const char *DIGITS = "0123456789ABCDEF";
+ for (unsigned j = 0; j < str_len; j++)
str[j] = DIGITS[(int)str[j]];
return str;
}
-int str_to_buf(const char *str, int str_len, u8 *buf, int buf_len, int radix)
+/// identify radix, and skip radix-prefix (0, 0x or 0X)
+static void str_radix_guess(const char **_str, unsigned *_str_len,
+ unsigned *_radix)
{
- char *charbuf;
- char tmp;
- float factor;
- u8 *b256_buf;
- int b256_len;
-
- int j; /* base-256 digits */
- int i; /* input digits (ASCII) */
-
- if (radix == 0)
+ unsigned radix = *_radix;
+ if (0 != radix)
+ return;
+ const char *str = *_str;
+ unsigned str_len = *_str_len;
+ if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
{
- /* 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;
- }
+ 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;
+ }
+ *_str = str;
+ *_str_len = str_len;
+ *_radix = radix;
+}
+int str_to_buf(const char *str, unsigned str_len,
+ void *_buf, unsigned buf_len, unsigned radix)
+{
+ str_radix_guess(&str, &str_len, &radix);
+
+ float factor;
if (radix == 16)
factor = 0.5; /* log(16) / log(256) = 0.5 */
else if (radix == 10)
return 0;
/* copy to zero-terminated buffer */
- charbuf = malloc(str_len + 1);
+ char *charbuf = malloc(str_len + 1);
memcpy(charbuf, str, str_len);
charbuf[str_len] = '\0';
/* number of digits in base-256 notation */
- b256_len = ceil_f_to_u32(str_len * factor);
- b256_buf = calloc(b256_len, 1);
+ unsigned b256_len = ceil_f_to_u32(str_len * factor);
+ uint8_t *b256_buf = calloc(b256_len, 1);
/* go through zero terminated buffer */
+ /* input digits (ASCII) */
+ unsigned i;
for (i = 0; charbuf[i]; i++)
{
- tmp = charbuf[i];
+ uint32_t tmp = charbuf[i];
if ((tmp >= '0') && (tmp <= '9'))
tmp = (tmp - '0');
else if ((tmp >= 'a') && (tmp <= 'f'))
if (tmp >= radix)
continue; /* skip digits invalid for the current radix */
- for (j = 0; j < b256_len; j++)
+ /* base-256 digits */
+ for (unsigned j = 0; j < b256_len; j++)
{
- tmp += (u32)b256_buf[j] * radix;
- b256_buf[j] = (u8)(tmp & 0xFF);
+ tmp += (uint32_t)b256_buf[j] * radix;
+ b256_buf[j] = (uint8_t)(tmp & 0xFF);
tmp >>= 8;
}
}
- for (j = 0; j < CEIL(buf_len, 8); j++)
+ uint8_t *buf = _buf;
+ for (unsigned j = 0; j < DIV_ROUND_UP(buf_len, 8); j++)
{
if (j < b256_len)
buf[j] = b256_buf[j];
return i;
}
-
-int buf_to_u32_handler(u8 *in_buf, void *priv, struct scan_field_s *field)
-{
- u32 *dest = priv;
-
- *dest = buf_get_u32(in_buf, 0, 32);
-
- return ERROR_OK;
-}