diff --git a/examples/array/simple.c b/examples/array/simple.c index e70fc9c0..630ec9c2 100644 --- a/examples/array/simple.c +++ b/examples/array/simple.c @@ -10,25 +10,29 @@ #define TEST_LOOP 100 #define TEST_SIZE 64 -BFDEV_DEFINE_ARRAY(test_array, NULL, TEST_SIZE); int main(int argc, const char *argv[]) { + BFDEV_DEFINE_ARRAY(array, NULL, TEST_SIZE); unsigned int count; - void *array; + + bfdev_array_append(&array, 0, 0); for (count = 0; count < TEST_LOOP; ++count) { unsigned int num; + void *buff; num = rand() % TEST_SIZE; - array = bfdev_array_push(&test_array, num); - memset(array, 0, TEST_SIZE * num); + buff = bfdev_array_push(&array, num); + if (!buff) + return 1; - printf("array bfdev_array_push test: %02u: %u\n", - count, num); + memset(buff, 0, TEST_SIZE * num); + printf("array bfdev_array_push test: %02u: %u\n", count, num); } - bfdev_array_release(&test_array); + bfdev_array_release(&array); + return 0; } diff --git a/include/bfdev/array.h b/include/bfdev/array.h index c75153c0..960d1a2f 100644 --- a/include/bfdev/array.h +++ b/include/bfdev/array.h @@ -152,9 +152,9 @@ extern void * bfdev_array_peek(const bfdev_array_t *array, unsigned long num); /** - * bfdev_array_append() - append memory into the array. + * bfdev_array_append() - append elements into the array. * @array: the array object. - * @data: the data to append. + * @data: the elements to append. * @num: the number of element to append. * * Return 0 on success or a negative error code on failure. @@ -162,6 +162,17 @@ bfdev_array_peek(const bfdev_array_t *array, unsigned long num); extern int bfdev_array_append(bfdev_array_t *array, const void *data, unsigned long num); +/** + * bfdev_array_remove() - remove elements from the array. + * @array: the array object. + * @index: the index of the first elements to remove. + * @num: the number of element to remove. + * + * Return 0 on success or a negative error code on failure. + */ +extern int +bfdev_array_remove(bfdev_array_t *array, unsigned long index, unsigned long num); + /** * bfdev_array_resize() - directly set the number of elements in array. * @array: the array object. diff --git a/include/bfdev/port/string.h b/include/bfdev/port/string.h index fd100bbb..90f6ce86 100644 --- a/include/bfdev/port/string.h +++ b/include/bfdev/port/string.h @@ -14,6 +14,9 @@ BFDEV_BEGIN_DECLS extern void * bfdev_memcpy(void *dest, const void *src, bfdev_size_t n); +extern void * +bfdev_memmove(void *dest, const void *src, bfdev_size_t n); + extern void * bfdev_memset(void *s, int c, bfdev_size_t n); diff --git a/include/port/string.h b/include/port/string.h index dcabeb28..27314c9e 100644 --- a/include/port/string.h +++ b/include/port/string.h @@ -14,6 +14,9 @@ BFDEV_BEGIN_DECLS extern void * bfport_memcpy(void *dest, const void *src, bfdev_size_t n); +extern void * +bfport_memmove(void *dest, const void *src, bfdev_size_t n); + extern void * bfport_memset(void *s, int c, bfdev_size_t n); diff --git a/port/generic/string.c b/port/generic/string.c index 2f11acbb..ce22bfb7 100644 --- a/port/generic/string.c +++ b/port/generic/string.c @@ -21,6 +21,33 @@ bfport_memcpy(void *dest, const void *src, bfdev_size_t n) return dest; } +__bfdev_weak void * +bfport_memmove(void *dest, const void *src, bfdev_size_t n) +{ + char *tmp; + const char *s; + + if (dest <= src) { + tmp = dest; + s = src; + + while (n--) + *tmp++ = *s++; + + return dest; + } + + tmp = dest; + tmp += n; + s = src; + s += n; + + while (n--) + *--tmp = *--s; + + return dest; +} + __bfdev_weak void * bfport_memset(void *s, int c, bfdev_size_t n) { @@ -41,7 +68,8 @@ bfport_memcmp(const void *s1, const void *s2, bfdev_size_t n) res = 0; for (su1 = s1, su2 = s2; 0 < n; ++su1, ++su2, n--) { - if ((res = *su1 - *su2) != 0) + res = *su1 - *su2; + if (res != 0) break; } @@ -117,8 +145,7 @@ bfport_strcpy(char *dest, const char *src) unsigned char *tmp; tmp = dest; - while ((*tmp++ = *src++) != '\0') - ; + while ((*tmp++ = *src++) != '\0'); return dest; } diff --git a/port/posix/string.c b/port/posix/string.c index 8c3f4c6e..28fee713 100644 --- a/port/posix/string.c +++ b/port/posix/string.c @@ -18,6 +18,12 @@ bfport_memcpy(void *dest, const void *src, bfdev_size_t n) return memcpy(dest, src, n); } +void * +bfport_memmove(void *dest, const void *src, bfdev_size_t n) +{ + return memmove(dest, src, n); +} + void * bfport_memset(void *s, int c, bfdev_size_t n) { diff --git a/src/array.c b/src/array.c index f6a4f3c5..3ce50de9 100644 --- a/src/array.c +++ b/src/array.c @@ -121,6 +121,34 @@ bfdev_array_append(bfdev_array_t *array, const void *data, unsigned long num) return -BFDEV_ENOERR; } +export int +bfdev_array_remove(bfdev_array_t *array, unsigned long index, unsigned long num) +{ + unsigned long cut; + void *start, *end; + bfdev_size_t behind; + bfdev_bool overflow; + + if (bfdev_unlikely(index >= array->index)) + return -BFDEV_EFBIG; + + overflow = bfdev_overflow_check_add(index, num, &cut); + if (bfdev_unlikely(overflow)) + return -BFDEV_EOVERFLOW; + + if (bfdev_unlikely(cut > array->index)) + return -BFDEV_EFBIG; + + start = array->data + bfdev_array_offset(array, index); + end = array->data + bfdev_array_offset(array, cut); + behind = bfdev_array_offset(array, array->index - cut); + + bfdev_memmove(start, end, behind); + array->index -= num; + + return -BFDEV_ENOERR; +} + export int bfdev_array_resize(bfdev_array_t *array, unsigned long num) { diff --git a/src/port/string.c b/src/port/string.c index 51bd2676..64e44ea3 100644 --- a/src/port/string.c +++ b/src/port/string.c @@ -13,6 +13,12 @@ bfdev_memcpy(void *dest, const void *src, bfdev_size_t n) return bfport_memcpy(dest, src, n); } +export void * +bfdev_memmove(void *dest, const void *src, bfdev_size_t n) +{ + return bfport_memmove(dest, src, n); +} + export void * bfdev_memset(void *s, int c, bfdev_size_t n) {