remove cmp checks, added bytearray, added tests for bytearray
Ainclude/cutils/byte_array.h
| @@ -0,0 +1,46 @@ | |||
|---|---|---|---|
| 1 | + | #ifndef BYTE_ARRAY_H | |
| 2 | + | #define BYTE_ARRAY_H | |
| 3 | + | #include <stdlib.h> | |
| 4 | + | #include <string.h> | |
| 5 | + | #include <errno.h> | |
| 6 | + | ||
| 7 | + | #define BYTEARRAY_DEFAULT_SIZE 4 | |
| 8 | + | ||
| 9 | + | #define BT_FIXED 1 | |
| 10 | + | #define BT_FREE_EL 2 | |
| 11 | + | #define BT_FREE_ARRAY 4 | |
| 12 | + | #define BT_FREE_STRUCT 8 | |
| 13 | + | ||
| 14 | + | typedef enum {b_false, b_true} bool_t; | |
| 15 | + | ||
| 16 | + | typedef struct Bytearray | |
| 17 | + | { | |
| 18 | + | char* items; | |
| 19 | + | size_t capacity; | |
| 20 | + | size_t length; | |
| 21 | + | size_t element_size; | |
| 22 | + | short flags; | |
| 23 | + | } Bytearray; | |
| 24 | + | ||
| 25 | + | #define new_bytearray(element_size) bytearray_with_capacity(BYTEARRAY_DEFAULT_SIZE, element_size) | |
| 26 | + | #define bytearray_with_capacity(capacity, element_size) new_bytearray_ext(capacity, element_size, NULL, NULL, BT_FREE_ARRAY | BT_FREE_STRUCT) | |
| 27 | + | Bytearray* new_bytearray_ext(size_t capacity, size_t element_size, char* array_storage, Bytearray* struct_storage, short flags); | |
| 28 | + | void delete_bytearray(Bytearray* bytearray); | |
| 29 | + | void delete_bytearray_ext(Bytearray* bytearray, void(*rmv_el) (void*), void(*rmv_items) (void*), void(*rmv_struct) (void*)); | |
| 30 | + | ||
| 31 | + | void* bytearray_at(const Bytearray* bytearray, size_t index); | |
| 32 | + | #define bytearray_pop(bytearray) bytearray_pop_at(bytearray, bytearray->length-1) | |
| 33 | + | void* bytearray_pop_at(Bytearray* bytearray, size_t index); | |
| 34 | + | ||
| 35 | + | #define bytearray_push(bytearray, item) bytearray_insert(bytearray, bytearray->length, item) | |
| 36 | + | bool_t bytearray_insert(Bytearray* bytearray, size_t index, const void* item); | |
| 37 | + | ||
| 38 | + | void bytearray_remove(Bytearray* bytearray, size_t index, void (*rmv)(void*)); | |
| 39 | + | ||
| 40 | + | bool_t bytearray_adjust_size(Bytearray* bytearray, size_t size); | |
| 41 | + | bool_t bytearray_shrink(Bytearray* bytearray); | |
| 42 | + | size_t* bytearray_find(const Bytearray* haystack, const void* needle, int (*cmp)(const void*, const void*)); | |
| 43 | + | ||
| 44 | + | ||
| 45 | + | #endif /* BYTE_ARRAY_H */ | |
| 46 | + | ||
Minclude/cutils/cutils.h
| @@ -4,5 +4,7 @@ | |||
|---|---|---|---|
| 4 | 4 | #include <cutils/vector.h> | |
| 5 | 5 | #include <cutils/dyn_string.h> | |
| 6 | 6 | #include <cutils/misc.h> | |
| 7 | + | #include <cutils/byte_array.h> | |
| 8 | + | ||
| 7 | 9 | ||
| 8 | 10 | #endif /* CUTILS_H */ | |
Minclude/cutils/dyn_string.h
| @@ -14,16 +14,16 @@ typedef struct String | |||
|---|---|---|---|
| 14 | 14 | size_t length; | |
| 15 | 15 | } String; | |
| 16 | 16 | ||
| 17 | - | #define new_string() string_with_capacity(STRING_DEFAULT_SIZE); | |
| 17 | + | #define new_string() string_with_capacity(STRING_DEFAULT_SIZE) | |
| 18 | 18 | String* string_with_capacity(size_t capacity); | |
| 19 | 19 | void delete_string(String* string); | |
| 20 | 20 | ||
| 21 | 21 | char string_at(const String* string, size_t index); | |
| 22 | - | #define string_pop(string) string_pop_at(string, string->length-1); | |
| 22 | + | #define string_pop(string) string_pop_at(string, string->length-1) | |
| 23 | 23 | char string_pop_at(String* string, size_t index); | |
| 24 | 24 | ||
| 25 | 25 | bool string_insert(String* string, size_t index, char character); | |
| 26 | - | #define string_push(string, character) string_insert(string, string->length, character); | |
| 26 | + | #define string_push(string, character) string_insert(string, string->length, character) | |
| 27 | 27 | ||
| 28 | 28 | void string_remove(String* string, size_t index); | |
| 29 | 29 | ||
Minclude/cutils/vector.h
| @@ -14,16 +14,16 @@ typedef struct Vector | |||
|---|---|---|---|
| 14 | 14 | size_t length; | |
| 15 | 15 | } Vector; | |
| 16 | 16 | ||
| 17 | - | #define new_vector() vector_with_capacity(VECTOR_DEFAULT_SIZE); | |
| 17 | + | #define new_vector() vector_with_capacity(VECTOR_DEFAULT_SIZE) | |
| 18 | 18 | Vector* vector_with_capacity(size_t capacity); | |
| 19 | 19 | void delete_vector(Vector* vector, void(*rmv) (void*)); | |
| 20 | 20 | ||
| 21 | 21 | void* vector_at(const Vector* vector, size_t index); | |
| 22 | - | #define vector_pop(vector) vector_pop_at(vector, vector->length-1); | |
| 22 | + | #define vector_pop(vector) vector_pop_at(vector, vector->length-1) | |
| 23 | 23 | void* vector_pop_at(Vector* vector, size_t index); | |
| 24 | 24 | ||
| 25 | 25 | bool vector_insert(Vector* vector, size_t index, void* item); | |
| 26 | - | #define vector_push(vector, item) vector_insert(vector, vector->length, item); | |
| 26 | + | #define vector_push(vector, item) vector_insert(vector, vector->length, item) | |
| 27 | 27 | ||
| 28 | 28 | void vector_remove(Vector* vector, size_t index, void (*rmv)(void*)); | |
| 29 | 29 | ||
Asrc/byte_array.c
| @@ -0,0 +1,181 @@ | |||
|---|---|---|---|
| 1 | + | #include <cutils/byte_array.h> | |
| 2 | + | ||
| 3 | + | Bytearray* new_bytearray_ext(size_t capacity, size_t element_size, char* array_storage, Bytearray* struct_storage, short flags) | |
| 4 | + | { | |
| 5 | + | Bytearray* bytearray; | |
| 6 | + | ||
| 7 | + | if(struct_storage) | |
| 8 | + | { | |
| 9 | + | bytearray = struct_storage; | |
| 10 | + | } else { | |
| 11 | + | bytearray = malloc(sizeof(*bytearray)); | |
| 12 | + | if(!bytearray) | |
| 13 | + | return NULL; | |
| 14 | + | } | |
| 15 | + | ||
| 16 | + | if(array_storage) | |
| 17 | + | { | |
| 18 | + | bytearray->items = array_storage; | |
| 19 | + | } else { | |
| 20 | + | bytearray->items = malloc(sizeof(*bytearray->items)*capacity*element_size); | |
| 21 | + | if(!bytearray->items) | |
| 22 | + | { | |
| 23 | + | free(bytearray); | |
| 24 | + | return NULL; | |
| 25 | + | } | |
| 26 | + | } | |
| 27 | + | bytearray->length = 0; | |
| 28 | + | bytearray->capacity = capacity; | |
| 29 | + | bytearray->element_size = element_size; | |
| 30 | + | bytearray->flags = flags; | |
| 31 | + | ||
| 32 | + | return bytearray; | |
| 33 | + | } | |
| 34 | + | ||
| 35 | + | void delete_bytearray(Bytearray* bytearray) | |
| 36 | + | { | |
| 37 | + | delete_bytearray_ext(bytearray, | |
| 38 | + | (bytearray->flags & BT_FREE_EL) ? free : NULL, | |
| 39 | + | (bytearray->flags & BT_FREE_ARRAY) ? free : NULL, | |
| 40 | + | (bytearray->flags & BT_FREE_STRUCT) ? free : NULL); | |
| 41 | + | } | |
| 42 | + | ||
| 43 | + | ||
| 44 | + | void delete_bytearray_ext(Bytearray* bytearray, void(*rmv_el) (void*), void(*rmv_items) (void*), void(*rmv_struct) (void*)) | |
| 45 | + | { | |
| 46 | + | if(rmv_el) | |
| 47 | + | { | |
| 48 | + | size_t i; | |
| 49 | + | for(i = 0; i < bytearray->length; i++) | |
| 50 | + | { | |
| 51 | + | rmv_el(&bytearray->items[i*bytearray->element_size]); | |
| 52 | + | } | |
| 53 | + | } | |
| 54 | + | if(rmv_items) | |
| 55 | + | rmv_items(bytearray->items); | |
| 56 | + | if(rmv_struct) | |
| 57 | + | rmv_struct(bytearray); | |
| 58 | + | } | |
| 59 | + | ||
| 60 | + | void* bytearray_at(const Bytearray* bytearray, size_t index) | |
| 61 | + | { | |
| 62 | + | if(index >= bytearray->length) | |
| 63 | + | return NULL; | |
| 64 | + | else | |
| 65 | + | return bytearray->items+(index*bytearray->element_size); | |
| 66 | + | } | |
| 67 | + | ||
| 68 | + | void* bytearray_pop_at(Bytearray* bytearray, size_t index) | |
| 69 | + | { | |
| 70 | + | void *tmp, *ret; | |
| 71 | + | ||
| 72 | + | tmp = bytearray_at(bytearray, index); | |
| 73 | + | if(!tmp) | |
| 74 | + | { | |
| 75 | + | errno = 0; | |
| 76 | + | return NULL; | |
| 77 | + | } | |
| 78 | + | ||
| 79 | + | ret = malloc(bytearray->element_size); | |
| 80 | + | if(!ret) | |
| 81 | + | { | |
| 82 | + | errno = ENOMEM; | |
| 83 | + | return NULL; | |
| 84 | + | } | |
| 85 | + | ||
| 86 | + | memcpy(ret, tmp, bytearray->element_size); | |
| 87 | + | bytearray_remove(bytearray, index, NULL); | |
| 88 | + | return ret; | |
| 89 | + | } | |
| 90 | + | ||
| 91 | + | bool_t bytearray_insert(Bytearray* bytearray, size_t index, const void* item) | |
| 92 | + | { | |
| 93 | + | size_t length = bytearray->length; | |
| 94 | + | size_t size = bytearray->element_size; | |
| 95 | + | ||
| 96 | + | if(index > length || !bytearray_adjust_size(bytearray, length+1)) | |
| 97 | + | return b_false; | |
| 98 | + | ||
| 99 | + | memmove(bytearray->items+index*size+1*size, bytearray->items+index*size, (length*size-index*size)*sizeof(*bytearray->items)); | |
| 100 | + | memcpy(bytearray->items+index*size, item, bytearray->element_size); | |
| 101 | + | ++bytearray->length; | |
| 102 | + | return b_true; | |
| 103 | + | } | |
| 104 | + | ||
| 105 | + | void bytearray_remove(Bytearray* bytearray, size_t index, void (*rmv)(void*)) | |
| 106 | + | { | |
| 107 | + | if(index < bytearray->length) | |
| 108 | + | { | |
| 109 | + | size_t length = bytearray->length; | |
| 110 | + | size_t elsize = bytearray->element_size; | |
| 111 | + | if(rmv) | |
| 112 | + | rmv(&bytearray->items[index*elsize]); | |
| 113 | + | ||
| 114 | + | memmove(bytearray->items+index*elsize, bytearray->items+index*elsize+1*elsize, (length*elsize-index*elsize-1*elsize)*sizeof(*bytearray->items)); | |
| 115 | + | --bytearray->length; | |
| 116 | + | } | |
| 117 | + | } | |
| 118 | + | ||
| 119 | + | bool_t bytearray_adjust_size(Bytearray* bytearray, size_t size) | |
| 120 | + | { | |
| 121 | + | if(bytearray->flags & BT_FIXED) | |
| 122 | + | { | |
| 123 | + | if(bytearray->capacity < size) | |
| 124 | + | return b_false; | |
| 125 | + | else | |
| 126 | + | return b_true; | |
| 127 | + | } | |
| 128 | + | ||
| 129 | + | while(bytearray->capacity < size) | |
| 130 | + | { | |
| 131 | + | size_t capacity = bytearray->capacity; | |
| 132 | + | size_t elsize = bytearray->element_size; | |
| 133 | + | char* tmp = bytearray->items; | |
| 134 | + | bytearray->items = realloc(bytearray->items, capacity*elsize*2*sizeof(*bytearray->items)); | |
| 135 | + | if(!bytearray->items) | |
| 136 | + | { | |
| 137 | + | bytearray->items = tmp; | |
| 138 | + | return b_false; | |
| 139 | + | } | |
| 140 | + | bytearray->capacity *= 2; | |
| 141 | + | } | |
| 142 | + | return b_true; | |
| 143 | + | } | |
| 144 | + | ||
| 145 | + | bool_t bytearray_shrink(Bytearray* bytearray) | |
| 146 | + | { | |
| 147 | + | if(bytearray->flags & BT_FIXED) | |
| 148 | + | return b_false; | |
| 149 | + | ||
| 150 | + | while(bytearray->capacity > bytearray->length*2) | |
| 151 | + | { | |
| 152 | + | size_t capacity = bytearray->capacity; | |
| 153 | + | size_t size = bytearray->element_size; | |
| 154 | + | char* tmp = bytearray->items; | |
| 155 | + | bytearray->items = realloc(bytearray->items, (capacity*size)/(2*sizeof(*bytearray->items))); | |
| 156 | + | if(!bytearray->items) | |
| 157 | + | { | |
| 158 | + | bytearray->items = tmp; | |
| 159 | + | return b_false; | |
| 160 | + | } | |
| 161 | + | bytearray->capacity /= 2; | |
| 162 | + | } | |
| 163 | + | return b_true; | |
| 164 | + | } | |
| 165 | + | ||
| 166 | + | size_t* bytearray_find(const Bytearray* haystack, const void* needle, int (*cmp)(const void*, const void*)) | |
| 167 | + | { | |
| 168 | + | size_t* ret; | |
| 169 | + | size_t i; | |
| 170 | + | ||
| 171 | + | for(i = 0; i < haystack->length; i++) | |
| 172 | + | { | |
| 173 | + | if(cmp(haystack->items+(i*haystack->element_size),needle) == 0) | |
| 174 | + | { | |
| 175 | + | ret = malloc(sizeof(*ret)); | |
| 176 | + | *ret = i; | |
| 177 | + | return ret; | |
| 178 | + | } | |
| 179 | + | } | |
| 180 | + | return NULL; | |
| 181 | + | } | |
Msrc/dyn_string.c
| @@ -22,7 +22,7 @@ void string_remove(String* string, size_t index) | |||
|---|---|---|---|
| 22 | 22 | if(index < string->length) | |
| 23 | 23 | { | |
| 24 | 24 | memmove(string->chars+index, string->chars+index+1, (string->length-index-1)*sizeof(*string->chars)); | |
| 25 | - | string->length--; | |
| 25 | + | --string->length; | |
| 26 | 26 | } | |
| 27 | 27 | } | |
| 28 | 28 | ||
Msrc/meson.build
| @@ -1,4 +1,4 @@ | |||
|---|---|---|---|
| 1 | - | src = ['vector.c', 'dyn_string.c', 'misc.c'] | |
| 1 | + | src = ['vector.c', 'dyn_string.c', 'misc.c', 'byte_array.c'] | |
| 2 | 2 | srctest = src + ['test.c'] | |
| 3 | 3 | ||
| 4 | 4 | cutils_lib = library('cutils', src, include_directories : inc, install: true) | |
| @@ -6,4 +6,4 @@ cutils_lib = library('cutils', src, include_directories : inc, install: true) | |||
|---|---|---|---|
| 6 | 6 | cutils_dep = declare_dependency(link_with : cutils_lib, include_directories : inc) | |
| 7 | 7 | ||
| 8 | 8 | e = executable('test_cutils', srctest, include_directories : inc, c_args: CFLAGS ) | |
| 9 | - | test('test functionality', e) | |
| 9 | + | test('test functionality', e) | |
Msrc/test.c
| @@ -18,97 +18,181 @@ static int cmp_str(const void* str1, const void* str2) | |||
|---|---|---|---|
| 18 | 18 | static void test1(void) | |
| 19 | 19 | { | |
| 20 | 20 | size_t* find; | |
| 21 | - | Vector* test; | |
| 21 | + | Vector* vector; | |
| 22 | 22 | struct test* my_struct; | |
| 23 | 23 | ||
| 24 | 24 | my_struct = malloc(sizeof(*my_struct)); | |
| 25 | - | test = new_vector() | |
| 25 | + | vector = new_vector(); | |
| 26 | 26 | ||
| 27 | 27 | my_struct->a = 5; | |
| 28 | 28 | my_struct->b = 5; | |
| 29 | - | vector_push(test, my_struct); | |
| 29 | + | vector_push(vector, my_struct); | |
| 30 | 30 | ||
| 31 | 31 | my_struct = malloc(sizeof(*my_struct)); | |
| 32 | 32 | my_struct->a = 6; | |
| 33 | 33 | my_struct->b = 6; | |
| 34 | - | vector_push(test, my_struct); | |
| 34 | + | vector_push(vector, my_struct); | |
| 35 | 35 | ||
| 36 | 36 | my_struct = malloc(sizeof(*my_struct)); | |
| 37 | 37 | my_struct->a = 7; | |
| 38 | 38 | my_struct->b = 7; | |
| 39 | - | vector_push(test, my_struct); | |
| 40 | - | assert(test->length == 3); | |
| 39 | + | vector_push(vector, my_struct); | |
| 40 | + | assert(vector->length == 3); | |
| 41 | 41 | ||
| 42 | - | vector_remove(test, 0,free); | |
| 43 | - | assert(test->length == 2); | |
| 42 | + | vector_remove(vector, 0,free); | |
| 43 | + | assert(vector->length == 2); | |
| 44 | 44 | ||
| 45 | 45 | my_struct = malloc(sizeof(*my_struct)); | |
| 46 | 46 | my_struct->a = 8; | |
| 47 | 47 | my_struct->b = 8; | |
| 48 | - | vector_insert(test, 2, my_struct); | |
| 49 | - | assert(test->length == 3); | |
| 48 | + | vector_insert(vector, 2, my_struct); | |
| 49 | + | assert(vector->length == 3); | |
| 50 | 50 | ||
| 51 | 51 | my_struct = malloc(sizeof(*my_struct)); | |
| 52 | 52 | my_struct->a = 8; | |
| 53 | 53 | my_struct->b = 8; | |
| 54 | 54 | ||
| 55 | - | find = vector_find(test, my_struct, cmp_str); | |
| 55 | + | find = vector_find(vector, my_struct, cmp_str); | |
| 56 | 56 | ||
| 57 | 57 | assert(*find == 2); | |
| 58 | 58 | free(find); | |
| 59 | 59 | ||
| 60 | 60 | free(my_struct); | |
| 61 | - | my_struct = vector_pop(test); | |
| 61 | + | my_struct = vector_pop(vector); | |
| 62 | 62 | assert(my_struct->a == 8 && my_struct->b == 8); | |
| 63 | 63 | free(my_struct); | |
| 64 | 64 | ||
| 65 | - | delete_vector(test,free); | |
| 65 | + | delete_vector(vector, free); | |
| 66 | 66 | } | |
| 67 | 67 | ||
| 68 | 68 | static void test2(void) | |
| 69 | 69 | { | |
| 70 | - | String* test; | |
| 71 | - | String* test2; | |
| 70 | + | String* string; | |
| 71 | + | String* string2; | |
| 72 | 72 | char* cstring; | |
| 73 | 73 | ||
| 74 | - | test = new_string(); | |
| 74 | + | string = new_string(); | |
| 75 | 75 | ||
| 76 | - | string_push(test, 'a'); | |
| 77 | - | string_push(test, 'b'); | |
| 78 | - | string_push(test, 'c'); | |
| 79 | - | string_push(test, 'd'); | |
| 80 | - | assert(test->length == 4); | |
| 76 | + | string_push(string, 'a'); | |
| 77 | + | string_push(string, 'b'); | |
| 78 | + | string_push(string, 'c'); | |
| 79 | + | string_push(string, 'd'); | |
| 80 | + | assert(string->length == 4); | |
| 81 | 81 | ||
| 82 | - | cstring = to_cstring(test); | |
| 82 | + | cstring = to_cstring(string); | |
| 83 | 83 | assert(strcmp(cstring, "abcd") == 0); | |
| 84 | 84 | free(cstring); | |
| 85 | 85 | ||
| 86 | - | string_remove(test, 3); | |
| 87 | - | cstring = to_cstring(test); | |
| 86 | + | string_remove(string, 3); | |
| 87 | + | cstring = to_cstring(string); | |
| 88 | 88 | assert(strcmp(cstring, "abc") == 0); | |
| 89 | 89 | free(cstring); | |
| 90 | - | assert(test->length == 3); | |
| 90 | + | assert(string->length == 3); | |
| 91 | 91 | ||
| 92 | - | string_insert(test, 0,'a'); | |
| 93 | - | cstring = to_cstring(test); | |
| 92 | + | string_insert(string, 0,'a'); | |
| 93 | + | cstring = to_cstring(string); | |
| 94 | 94 | assert(strcmp(cstring, "aabc") == 0); | |
| 95 | 95 | free(cstring); | |
| 96 | 96 | ||
| 97 | - | test2 = from_cstring("xyz"); | |
| 97 | + | string2 = from_cstring("xyz"); | |
| 98 | 98 | ||
| 99 | - | string_concat(test,test2); | |
| 100 | - | cstring = to_cstring(test); | |
| 99 | + | string_concat(string,string2); | |
| 100 | + | cstring = to_cstring(string); | |
| 101 | 101 | assert(strcmp(cstring, "aabcxyz") == 0); | |
| 102 | 102 | free(cstring); | |
| 103 | 103 | ||
| 104 | - | delete_string(test2); | |
| 105 | - | delete_string(test); | |
| 104 | + | delete_string(string2); | |
| 105 | + | delete_string(string); | |
| 106 | + | } | |
| 107 | + | ||
| 108 | + | static void test3(void) | |
| 109 | + | { | |
| 110 | + | Bytearray* bt; | |
| 111 | + | void* localarray; | |
| 112 | + | struct test my_struct; | |
| 113 | + | struct test* my_structptr; | |
| 114 | + | char* tmpchar; | |
| 115 | + | ||
| 116 | + | /*test pushing and popping with default constructor and simple values*/ | |
| 117 | + | bt = new_bytearray(1); | |
| 118 | + | bytearray_push(bt, "a"); | |
| 119 | + | bytearray_push(bt, "b"); | |
| 120 | + | bytearray_push(bt, "c"); | |
| 121 | + | bytearray_push(bt, "d"); | |
| 122 | + | bytearray_push(bt, "\0"); | |
| 123 | + | ||
| 124 | + | assert(strcmp(bt->items, "abcd") == 0); | |
| 125 | + | ||
| 126 | + | tmpchar = bytearray_pop(bt); | |
| 127 | + | assert(*tmpchar == '\0'); | |
| 128 | + | free(tmpchar); | |
| 129 | + | ||
| 130 | + | tmpchar = bytearray_pop(bt); | |
| 131 | + | assert(*tmpchar == 'd'); | |
| 132 | + | free(tmpchar); | |
| 133 | + | ||
| 134 | + | tmpchar = bytearray_pop(bt); | |
| 135 | + | assert(*tmpchar == 'c'); | |
| 136 | + | free(tmpchar); | |
| 137 | + | ||
| 138 | + | tmpchar = bytearray_pop(bt); | |
| 139 | + | assert(*tmpchar == 'b'); | |
| 140 | + | free(tmpchar); | |
| 141 | + | ||
| 142 | + | tmpchar = bytearray_pop(bt); | |
| 143 | + | assert(*tmpchar == 'a'); | |
| 144 | + | free(tmpchar); | |
| 145 | + | ||
| 146 | + | tmpchar = bytearray_pop(bt); | |
| 147 | + | assert(tmpchar == NULL); | |
| 148 | + | free(tmpchar); | |
| 149 | + | ||
| 150 | + | bytearray_push(bt, "a"); | |
| 151 | + | tmpchar = bytearray_pop(bt); | |
| 152 | + | assert(*tmpchar == 'a'); | |
| 153 | + | free(tmpchar); | |
| 154 | + | ||
| 155 | + | delete_bytearray(bt); | |
| 156 | + | ||
| 157 | + | /*test pushing and popping with self allocated array and fixed size*/ | |
| 158 | + | localarray = malloc(3*sizeof(struct test)); | |
| 159 | + | my_struct.a = 0; | |
| 160 | + | my_struct.b = 0; | |
| 161 | + | ||
| 162 | + | bt = new_bytearray_ext(3, sizeof(struct test), localarray, NULL, BT_FREE_ARRAY | BT_FIXED | BT_FREE_STRUCT); | |
| 163 | + | bytearray_push(bt, &my_struct); | |
| 164 | + | my_struct.a = 1; | |
| 165 | + | my_struct.b = 1; | |
| 166 | + | bytearray_push(bt, &my_struct); | |
| 167 | + | ||
| 168 | + | my_struct.a = 2; | |
| 169 | + | my_struct.b = 2; | |
| 170 | + | bytearray_push(bt, &my_struct); | |
| 171 | + | ||
| 172 | + | my_struct.a = 3; | |
| 173 | + | my_struct.b = 3; | |
| 174 | + | bytearray_push(bt, &my_struct); | |
| 175 | + | ||
| 176 | + | my_structptr = bytearray_pop(bt); | |
| 177 | + | ||
| 178 | + | my_struct.a = 2; | |
| 179 | + | my_struct.b = 2; | |
| 180 | + | printf("%d\n", my_structptr->a); | |
| 181 | + | assert(my_structptr->a == my_struct.a); | |
| 182 | + | assert(my_structptr->b == my_struct.b); | |
| 183 | + | free(my_structptr); | |
| 184 | + | ||
| 185 | + | ||
| 186 | + | ||
| 187 | + | delete_bytearray(bt); | |
| 188 | + | ||
| 106 | 189 | } | |
| 107 | 190 | ||
| 108 | 191 | int main(int argc, char** argv) | |
| 109 | 192 | { | |
| 110 | 193 | test1(); | |
| 111 | 194 | test2(); | |
| 195 | + | test3(); | |
| 112 | 196 | sleep_ms(1000); | |
| 113 | 197 | return 0; | |
| 114 | 198 | } | |
Msrc/vector.c
| @@ -45,7 +45,7 @@ void vector_remove(Vector* vector, size_t index, void (*rmv)(void*)) | |||
|---|---|---|---|
| 45 | 45 | if(rmv) | |
| 46 | 46 | rmv(vector->items[index]); | |
| 47 | 47 | memmove(vector->items+index, vector->items+index+1, (vector->length-index-1)*sizeof(*vector->items)); | |
| 48 | - | vector->length--; | |
| 48 | + | --vector->length; | |
| 49 | 49 | } | |
| 50 | 50 | } | |
| 51 | 51 | ||
| @@ -56,7 +56,7 @@ size_t* vector_find(const Vector* haystack, const void* needle, int (*cmp)(const | |||
|---|---|---|---|
| 56 | 56 | ||
| 57 | 57 | for(i = 0; i < haystack->length; i++) | |
| 58 | 58 | { | |
| 59 | - | if(cmp ? cmp(haystack->items[i],needle) == 0 : haystack->items[i] == needle) | |
| 59 | + | if(cmp(haystack->items[i],needle) == 0) | |
| 60 | 60 | { | |
| 61 | 61 | ret = malloc(sizeof(*ret)); | |
| 62 | 62 | *ret = i; | |
| @@ -111,11 +111,13 @@ bool vector_shrink(Vector* vector) | |||
|---|---|---|---|
| 111 | 111 | ||
| 112 | 112 | void delete_vector(Vector* vector, void (*rmv)(void*)) | |
| 113 | 113 | { | |
| 114 | - | size_t i; | |
| 115 | - | for(i = 0; i < vector->length; i++) | |
| 114 | + | if(rmv) | |
| 116 | 115 | { | |
| 117 | - | if(rmv) | |
| 116 | + | size_t i; | |
| 117 | + | for(i = 0; i < vector->length; i++) | |
| 118 | + | { | |
| 118 | 119 | rmv(vector->items[i]); | |
| 120 | + | } | |
| 119 | 121 | } | |
| 120 | 122 | free(vector->items); | |
| 121 | 123 | free(vector); | |