ref: 8b5f8089f293105a48fdd41d976988f1b98a4c19
dir: /src/helpers/barray.c/
#include "internal/barray.h" #include <string.h> void *bit_array_create(size_t size) { size_t bsize = ((size + 7) >> 3) + sizeof(size_t); void *ret = calloc(1, bsize); if (ret) *(size_t *)ret = size; return ret; } void bit_array_destroy(void *array) { if (array) free(array); } void *bit_array_dup(void *array) { if (array) { size_t *size = (size_t *)array; size_t bsize = ((*size + 7) >> 3) + sizeof(*size); void *ret = malloc(bsize); if (ret) memcpy(ret, array, bsize); return ret; } return NULL; } void bit_array_reset(void *array) { if (array) { size_t *size = (size_t *)array; size_t bsize = (*size + 7) >> 3; memset(size + 1, 0, bsize); } } void bit_array_set(void *array, size_t bit) { if (array) { size_t *size = (size_t *)array; if (bit < *size) { unsigned char *ptr = (unsigned char *)(size + 1); ptr[bit >> 3] |= (1U << (bit & 7)); } } } void bit_array_set_range(void *array, size_t bit, size_t count) { if (array && count) { size_t *size = (size_t *)array; if (bit < *size) { unsigned char *ptr = (unsigned char *)(size + 1); size_t i; for (i = bit; i < *size && i < bit + count; ++i) ptr[i >> 3] |= (1U << (i & 7)); } } } int bit_array_test(void *array, size_t bit) { if (array) { size_t *size = (size_t *)array; if (bit < *size) { unsigned char *ptr = (unsigned char *)(size + 1); if (ptr[bit >> 3] & (1U << (bit & 7))) { return 1; } } } return 0; } int bit_array_test_range(void *array, size_t bit, size_t count) { if (array) { size_t *size = (size_t *)array; if (bit < *size) { unsigned char *ptr = (unsigned char *)(size + 1); if ((bit & 7) && (count > 8)) { while ((bit < *size) && count && (bit & 7)) { if (ptr[bit >> 3] & (1U << (bit & 7))) return 1; bit++; count--; } } if (!(bit & 7)) { while (((*size - bit) >= 8) && (count >= 8)) { if (ptr[bit >> 3]) return 1; bit += 8; count -= 8; } } while ((bit < *size) && count) { if (ptr[bit >> 3] & (1U << (bit & 7))) return 1; bit++; count--; } } } return 0; } void bit_array_clear(void *array, size_t bit) { if (array) { size_t *size = (size_t *)array; if (bit < *size) { unsigned char *ptr = (unsigned char *)(size + 1); ptr[bit >> 3] &= ~(1U << (bit & 7)); } } } void bit_array_clear_range(void *array, size_t bit, size_t count) { if (array && count) { size_t *size = (size_t *)array; if (bit < *size) { unsigned char *ptr = (unsigned char *)(size + 1); size_t i; for (i = bit; i < *size && i < bit + count; ++i) ptr[i >> 3] &= ~(1U << (i & 7)); } } } void bit_array_merge(void *dest, void *source, size_t offset) { if (dest && source) { size_t *dsize = (size_t *)dest; size_t *ssize = (size_t *)source; size_t soffset = 0; while (offset < *dsize && soffset < *ssize) { if (bit_array_test(source, soffset)) { bit_array_set(dest, offset); } soffset++; offset++; } } } void bit_array_mask(void *dest, void *source, size_t offset) { if (dest && source) { size_t *dsize = (size_t *)dest; size_t *ssize = (size_t *)source; size_t soffset = 0; while (offset < *dsize && soffset < *ssize) { if (bit_array_test(source, soffset)) { bit_array_clear(dest, offset); } soffset++; offset++; } } }