123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- // check pointer
- owl_bool owl_check_arr_pointer(owl_byte * src, owl_umax size)
- {
- return (src != NULL && size >= sizeof(owl_arr));
- }
- // check members
- owl_bool owl_check_arr_members(owl_byte * ptr, owl_umax arr_size, owl_type type, owl_umax var_size,
- owl_umax (* print_elem)(owl_byte *, owl_umax size),
- owl_char (* comp_elem)(owl_byte *, owl_byte *))
- {
- return (ptr != NULL && arr_size != 0 && type != OWL_TYPE_NONE
- && var_size != 0 && print_elem != NULL && comp_elem != NULL);
- }
- // check all
- owl_bool owl_check_arr_all(owl_arr * data, owl_umax size)
- {
- return owl_check_arr_pointer((void *) data, size)
- && owl_check_arr_members(data -> arr -> ptr, data -> arr -> size,
- data -> var.type, data -> var.size,
- data -> var.print_elem, data -> var.comp_elem);
- }
- // create
- owl_arr * owl_create_arr(owl_byte * data, owl_umax arr_size, owl_type type, owl_umax var_size,
- owl_umax (* print_elem)(owl_byte *, owl_umax size),
- owl_char (* comp_elem)(owl_byte *, owl_byte *))
- {
- // check params
- owl_arr * arr = NULL;
- owl_mem_space * mem_space = NULL;
- if (owl_check_arr_members(data, arr_size, type, var_size, print_elem, comp_elem) == owl_false)
- goto err;
- // create the structure
- // it will need 2 allocations:
- // - one for the structure itself
- // - the other one for the mem_space inside the struct
- arr = (void *) (owl_create_mem_space(sizeof(owl_arr)) -> ptr);
- if (arr == NULL)
- goto err;
- mem_space = (owl_mem_space *) owl_create_bytarr(data, arr_size * var_size);
- if (mem_space == NULL)
- goto err;
- // assign the rest of the variables
- arr -> arr = mem_space;
- arr -> var.type = type;
- arr -> var.size = var_size;
- arr -> var.print_elem = print_elem;
- arr -> var.comp_elem = comp_elem;
- return arr; // first time returning such a weird struct
-
- // error
- err:
- ;
- owl_free_mem_space(&((owl_mem_space) {(void *) arr, sizeof(owl_arr)}));
- owl_free_mem_space(mem_space);
- return NULL;
- }
- // free
- owl_umax owl_free_arr(owl_arr * arr)
- {
- // check params
- if (owl_check_arr_all((void *) arr, sizeof(owl_arr)) == owl_false)
- goto err;
- // free the memory allocated by the struct
- owl_umax tmp = owl_free_mem_space(arr -> arr);
- if (tmp == 0)
- goto err;
- owl_mem_space sp = {(void *) arr, sizeof(owl_arr)};
- tmp = owl_free_mem_space(&sp);
- if (tmp == 0)
- goto err;
- // return the number of free slots on the mem_space table
- return tmp;
- err:
- return 0;
- }
- // print
- owl_umax owl_print_arr(owl_byte * src, owl_umax size)
- {
- // check params
- printf("OWL_ARR struct info:\n");
- printf(" Struct info: %p, %d\n", src, size);
- if (owl_check_arr_pointer(src, size) == owl_false)
- return 0;
-
- // else print the structure
- owl_arr * arr = (void *) src;
- printf(" Variable type: %u\n", arr -> var.type);
- printf(" Variable size (bytes): %llu\n", arr -> var.size);
- printf(" Print function: %p\n", arr -> var.print_elem);
- printf(" Compare function: %p\n", arr -> var.comp_elem);
- printf(" Array pointer: %p\n", arr -> arr -> ptr);
- printf(" Array size (bytes): %llu\n", arr -> arr -> size);
- printf(" Array contents: ");
- for (owl_umax i = 0; i < (arr -> arr -> size); i += arr -> var.size) {
- arr -> var.print_elem((arr -> arr -> ptr) + i, (arr -> arr -> size) - i);
- putchar(' ');
- }
- putchar('\n');
- return sizeof(owl_arr);
- }
- // compare
- owl_char owl_comp_arr(owl_byte * arr1, owl_byte * arr2)
- {
- // check params
- owl_arr * arr1_tmp = (void *) arr1,
- * arr2_tmp = (void *) arr2;
- // check params
- if (owl_check_arr_all(arr1_tmp, sizeof(owl_arr)) == owl_false
- || owl_check_arr_all(arr2_tmp, sizeof(owl_arr)) == owl_false)
- return owl_comp_err;
- // do the comparison, size and element contents matter
- // arr size -> var size -> var type -> element content
- // arr size
- if (arr1_tmp -> arr -> size < arr2_tmp -> arr -> size)
- return owl_comp_less;
- else if (arr1_tmp -> arr -> size > arr2_tmp -> arr -> size)
- return owl_comp_greater;
- // var size
- if (arr1_tmp -> var.size < arr2_tmp -> var.size)
- return owl_comp_less;
- else if (arr1_tmp -> var.size > arr2_tmp -> var.size)
- return owl_comp_greater;
- // var type
- if (arr1_tmp -> var.type < arr2_tmp -> var.type)
- return owl_comp_less;
- else if (arr1_tmp -> var.type > arr2_tmp -> var.type)
- return owl_comp_greater;
- // element comparison if types are equal
- // first element comparison to trigger the < or > expressions
- for (owl_umax i = 0; i < arr1_tmp -> arr -> size; i += arr1_tmp -> var.size) {
- owl_bool tmp_bool = arr1_tmp -> var.comp_elem(arr1_tmp -> arr -> ptr + i, arr2_tmp -> arr -> ptr + i);
- if (tmp_bool == owl_comp_less || tmp_bool == owl_comp_greater)
- return tmp_bool;
- }
- // legit real equal arrays
- return owl_comp_equal;
- }
- // reverse the contents of an array
- owl_umax owl_reverse_arr(owl_arr * arr)
- {
- // check params
- if (owl_check_arr_all(arr, sizeof(owl_arr)) == owl_false)
- return 0;
- // else do the reversing process
- owl_bytarr * tmp = owl_create_bytarr(NULL, arr -> var.size);
- owl_bytarr tmp1 = {arr -> arr -> ptr, arr -> var.size},
- tmp2 = {arr -> arr -> ptr + arr -> arr -> size - (arr -> var.size), arr -> var.size};
- if (tmp -> ptr == NULL)
- return 0;
- owl_umax middle_pos = (arr -> arr -> size / arr -> var.size) / 2;
- for (owl_umax i = 0; i < middle_pos; i++) {
- owl_copy_bytarr(&tmp1, tmp);
- owl_copy_bytarr(&tmp2, &tmp1);
- owl_copy_bytarr(tmp, &tmp2);
- tmp1.ptr += arr -> var.size;
- tmp2.ptr -= arr -> var.size;
- }
- // return the number of bytes moved
- owl_free_bytarr(tmp);
- return arr -> arr -> size;
- }
- // find an element inside an array
- owl_byte * owl_find_arr_elem(owl_arr * arr, owl_byte * elem, owl_umax size)
- {
- // check params
- if (owl_check_arr_all(arr, sizeof(owl_arr)) == owl_false
- || elem == NULL || size == 0 || size < arr -> var.size)
- return NULL;
- // find the element
- for (owl_umax i = 0; i < arr -> arr -> size; i += arr -> var.size)
- if ((arr -> var.comp_elem(arr -> arr -> ptr + i, elem)) == owl_comp_equal)
- return arr -> arr -> ptr + i;
- // not found
- return NULL;
- }
|