X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fhelper%2Fbinarybuffer.c;h=081cc037ebd6c346ae2b360124f81f463914a99c;hp=95e084efa41da465bc8d0d1d855484d4de834f54;hb=4d8d1d32d0f0e0b8866a06cb1d3f304563fa6796;hpb=5a43bd2e185bf469561a8370dcd543cc4813c33f diff --git a/src/helper/binarybuffer.c b/src/helper/binarybuffer.c index 95e084efa4..081cc037eb 100644 --- a/src/helper/binarybuffer.c +++ b/src/helper/binarybuffer.c @@ -48,89 +48,94 @@ 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) { - if (from == NULL) + if (NULL == from || NULL == _to) return NULL; - for (unsigned i = 0, num_bytes = CEIL(size, 8); 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) { - if (!buf1 || !buf2) - return 1; + if (!_buf1 || !_buf2) + return _buf1 != _buf2; - for (unsigned i = 0, num_bytes = CEIL(size, 8); 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 last = size / 8; + if (memcmp(_buf1, _buf2, last) != 0) + return false; + + 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) { - for (unsigned i = 0, num_bytes = CEIL(size, 8); i < num_bytes; i++) + if (!_buf1 || !_buf2) + return _buf1 != _buf2 || _buf1 != _mask; + + 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) { - for (unsigned i = 0, num_bytes = CEIL(count, 8); i < num_bytes; i++) - { - if (count >= 8) - buf[i] = 0xff; - else - buf[i] = (1 << count) - 1; + uint8_t *buf = _buf; + if (!buf) + return NULL; - count -= 8; - } + memset(buf, 0xff, size / 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; + const uint8_t *src = _src; + uint8_t *dst = _dst; - for (int 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); @@ -169,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); @@ -213,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) @@ -261,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')) @@ -281,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); @@ -293,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];