X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fhelper%2Fbinarybuffer.c;h=081cc037ebd6c346ae2b360124f81f463914a99c;hp=e0e7ac167ab870311db638082dc1562aa77c07a8;hb=4d8d1d32d0f0e0b8866a06cb1d3f304563fa6796;hpb=4d4b2958a5fdf0dfa0f8199535ccd9bd4e66d4af diff --git a/src/helper/binarybuffer.c b/src/helper/binarybuffer.c index e0e7ac167a..081cc037eb 100644 --- a/src/helper/binarybuffer.c +++ b/src/helper/binarybuffer.c @@ -48,107 +48,99 @@ const unsigned char bit_reverse_table256[] = }; -uint8_t* buf_cpy(const uint8_t *from, uint8_t *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(const uint8_t *buf1, const uint8_t *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(const uint8_t *buf1, const uint8_t *buf2, const uint8_t *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); } -uint8_t* buf_set_ones(uint8_t *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; } -uint8_t* buf_set_buf(const uint8_t *src, int src_start, uint8_t *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++; } @@ -158,9 +150,7 @@ uint8_t* buf_set_buf(const uint8_t *src, int src_start, uint8_t *dst, int dst_st uint32_t flip_u32(uint32_t value, unsigned int num) { - uint32_t 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]); @@ -173,12 +163,10 @@ uint32_t flip_u32(uint32_t value, unsigned int num) int ceil_f_to_u32(float x) { - uint32_t 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++; @@ -186,43 +174,36 @@ int ceil_f_to_u32(float x) return y; } -char* buf_to_str(const uint8_t *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); - uint32_t 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 += (uint32_t)str[j-1] * 256; str[j-1] = (uint8_t)(tmp % radix); @@ -230,44 +211,49 @@ char* buf_to_str(const uint8_t *buf, int buf_len, int 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, uint8_t *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; - uint32_t tmp; - float factor; - uint8_t *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) @@ -278,18 +264,20 @@ int str_to_buf(const char *str, int str_len, uint8_t *buf, int buf_len, int radi 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')) @@ -298,10 +286,11 @@ int str_to_buf(const char *str, int str_len, uint8_t *buf, int buf_len, int radi tmp = (tmp - 'A' + 10); else continue; /* skip characters other than [0-9,a-f,A-F] */ - if (tmp >= (uint32_t)radix) + 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 += (uint32_t)b256_buf[j] * radix; b256_buf[j] = (uint8_t)(tmp & 0xFF); @@ -310,7 +299,8 @@ int str_to_buf(const char *str, int str_len, uint8_t *buf, int buf_len, int radi } - 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]; @@ -327,12 +317,3 @@ int str_to_buf(const char *str, int str_len, uint8_t *buf, int buf_len, int radi return i; } - -int buf_to_u32_handler(uint8_t *in_buf, void *priv, struct scan_field *field) -{ - uint32_t *dest = priv; - - *dest = buf_get_u32(in_buf, 0, 32); - - return ERROR_OK; -}