123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353 |
- // check pointer
- owl_bool owl_check_bytarr_pointer(owl_byte * src, owl_umax size)
- {
- return (src != NULL && size >= sizeof(owl_bytarr));
- }
- // check members
- owl_bool owl_check_bytarr_members(owl_byte * ptr, owl_umax size)
- {
- // reuse owl_check_mem_space_members()
- return owl_check_mem_space_members(ptr, size);
- }
- // check all
- owl_bool owl_check_bytarr_all(owl_bytarr * data, owl_umax size)
- {
- return owl_check_bytarr_pointer((void *) data, size)
- && owl_check_bytarr_members(data -> ptr, data -> size);
- }
- // create a bytarr structure
- owl_bytarr * owl_create_bytarr(owl_byte * data, owl_umax size)
- {
- // check parameters (only the size)
- if (size == 0)
- return NULL;
-
- // otherwise create the structure
- owl_bytarr * rtn = (owl_bytarr *) owl_create_mem_space(size);
- if (data != NULL) // copy the bytes from data into the structure
- for (owl_umax i = 0; i < size; i++)
- (rtn -> ptr)[i] = data[i];
- return rtn;
- }
- // function to free a bytarr structure
- owl_umax owl_free_bytarr(owl_bytarr * arr)
- {
- // check params
- if (owl_check_bytarr_all(arr, sizeof(owl_bytarr)) == owl_false)
- return 0;
- return owl_free_mem_space((owl_mem_space *) arr);
- }
- // function to print a bytarr structure
- owl_umax owl_print_bytarr(owl_byte * src, owl_umax size)
- {
- // check params
- printf("OWL_BYTARR struct info:\n");
- printf(" Struct info: %p, %llu\n", src, size);
- if (owl_check_bytarr_pointer(src, size) == owl_false)
- return 0;
-
- // otherwise print the contents of the bytarr
- owl_bytarr * arr = (void *) src;
- printf(" Array pointer: %p\n", arr -> ptr);
- printf(" Array size (bytes): %llu\n", arr -> size);
- printf(" Array contents (hex): ");
- for (owl_umax i = 0; i < (arr -> size); i++) {
- //~ owl_print_char_char((arr -> ptr) + i, (arr -> size) - i);
- owl_print_byte_hex((arr -> ptr) + i, (arr -> size) - i);
- putchar(' ');
- }
- putchar('\n');
- return sizeof(owl_bytarr);
- }
- // compare 2 bytarrs
- owl_char owl_comp_bytarr(owl_byte * arr1, owl_byte * arr2)
- {
- // check params
- owl_bytarr * arr1_tmp = (void *) arr1,
- * arr2_tmp = (void *) arr2;
- // check params
- if (owl_check_bytarr_all(arr1_tmp, sizeof(owl_bytarr)) == owl_false
- || owl_check_bytarr_all(arr2_tmp, sizeof(owl_bytarr)) == owl_false)
- return owl_comp_err;
- // do the comparison, size and byte contents matter
- // size has higher meaning than byte content
- // size
- if (arr1_tmp -> size < arr2_tmp -> size)
- return owl_comp_less;
- else if (arr1_tmp -> size > arr2_tmp -> size)
- return owl_comp_greater;
- // byte comparison if sizes are equal
- // first byte comparison to trigger the < or > expressions
- for (owl_umax i = 0; i < arr1_tmp -> size; i++) {
- if ((arr1_tmp -> ptr)[i] < (arr2_tmp -> ptr)[i])
- return owl_comp_less;
- else if ((arr1_tmp -> ptr)[i] > (arr2_tmp -> ptr)[i])
- return owl_comp_greater;
- }
- // legit real equal bytarrs
- return owl_comp_equal;
- }
- // function to copy a bytarr into another bytarr
- owl_bytarr owl_copy_bytarr(owl_bytarr * src, owl_bytarr * dest)
- {
- // check params
- if (owl_check_bytarr_all(src, sizeof(owl_bytarr)) == owl_false
- || owl_check_bytarr_all(dest, sizeof(owl_bytarr)) == owl_false
- || (src -> size) > (dest -> size))
- return (owl_bytarr) {NULL, 0};
-
- // copy the byte contents of a bytarr into the other
- for (owl_umax i = 0; i < src -> size; i++)
- (dest -> ptr)[i] = (src -> ptr)[i];
-
- // return the last write position on dest as a bytarr struct
- return (owl_bytarr) {(dest -> ptr) + (src -> size),
- (dest -> size) - (src -> size)};
- }
- // get the integer index at which 2 bytarrs start not being equal
- owl_umax owl_get_bytarr_mismatch_index(owl_bytarr * arr1, owl_bytarr * arr2)
- {
- // check params (arr1 -> size will be used for error checking)
- if (owl_check_bytarr_all(arr1, sizeof(owl_bytarr)) == owl_false
- || owl_check_bytarr_all(arr2, sizeof(owl_bytarr)) == owl_false)
- return arr1 -> size;
-
- // else do comparisons until a mismatch
- // get max bytarr size
- owl_umax low_size = arr1 -> size < arr2 -> size ? arr1 -> size : arr2 -> size;
- for (owl_umax i = 0; i < low_size; i++)
- if ((arr1 -> ptr)[i] != (arr2 -> ptr)[i])
- return i;
- // in case the tiniest bytarr is contained within the larger one
- return arr1 -> size;
- }
- // function to ignore certain types of bytes from a bytarr and
- // return the position in which there are no more bytes to skip
- owl_bytarr owl_ignore_bytarr_bytes(owl_bytarr * arr, owl_bytarr * skip)
- {
- // check params (arr -> size will be used for error checking)
- if (owl_check_bytarr_all(arr, sizeof(owl_bytarr)) == owl_false
- || owl_check_bytarr_all(skip, sizeof(owl_bytarr)) == owl_false)
- return (owl_bytarr) {NULL, 0};
- // otherwise, return the integer index
- owl_bool keep_skipping = owl_false;
- for (owl_umax i = 0; i < arr -> size; i++)
- {
- // compare i's element from arr with all the elements from skip
- for (owl_umax j = 0; j < skip -> size; j++)
- keep_skipping = keep_skipping || ((arr -> ptr)[i] == (skip -> ptr)[j]);
- // if none of the bytes from skip matches the i's byte from arr the return the i index
- if (keep_skipping == owl_false)
- return (owl_bytarr) {arr -> ptr + i, arr -> size - i};
- // otherwise, reset the boolean
- keep_skipping = owl_false;
- }
- // in case all the bytes from arr can be found in skip
- return (owl_bytarr) {NULL, 0};
- }
- // function to search if a bytarr is found inside another one
- owl_bytarr owl_search_bytarr(owl_bytarr * src, owl_bytarr * search)
- {
- // check params (src -> size will be used for error checking)
- if (owl_check_bytarr_all(src, sizeof(owl_bytarr)) == owl_false
- || owl_check_bytarr_all(search, sizeof(owl_bytarr)) == owl_false
- || src -> size < search -> size)
- goto err;
-
- // use owl_comp_bytarr() until a match is found
- owl_bytarr tmp = {src -> ptr, search -> size};
- for (owl_umax i = 0; i <= (src -> size - search -> size); i++) {
- // return the i index when a match is found
- owl_bool cmp = owl_comp_bytarr((void *) &tmp, (void *) search);
- if (cmp == owl_comp_equal)
- return (owl_bytarr) {src -> ptr + i, src -> size - i};
- else if (cmp == owl_comp_err)
- goto err;
- else
- (tmp.ptr)++;
- }
-
- // no match found
- err:
- return (owl_bytarr) {NULL, 0};
- }
- // function to reverse the bytes in a bytarr
- owl_umax owl_reverse_bytarr(owl_bytarr * arr)
- {
- // check params
- if (owl_check_bytarr_all(arr, sizeof(owl_bytarr)) == owl_false)
- return 0;
-
- // reverse the bytes
- owl_umax middle_pos = arr -> size / 2;
- for (owl_umax i = 0, tmp = 0; i < middle_pos; i++) {
- tmp = (arr -> ptr)[i];
- (arr -> ptr)[i] = (arr -> ptr)[arr -> size - i - 1];
- (arr -> ptr)[arr -> size - i - 1] = tmp;
- }
- // reverse op was done (return the number of bytes moved)
- return arr -> size;
- }
- // check if a byteshift integer is valid
- owl_bool owl_check_byteshift_dir(owl_byteshift_dir shift)
- {
- return (shift == OWL_BYTESHIFT_LEFT || shift == OWL_BYTESHIFT_RIGHT);
- }
- // make a simple shift on the bytes of data
- owl_umax owl_bytarr_shift(owl_bytarr * arr, owl_byteshift_dir shift)
- {
- // check params
- if (owl_check_bytarr_all(arr, sizeof(owl_bytarr)) == owl_false
- || owl_check_byteshift_dir(shift) == owl_false)
- return 0;
-
- // decide the byteshift direction
- owl_char increment = 1;
- owl_umax arr_index = 0;
- if (shift == OWL_BYTESHIFT_LEFT) {
- increment = -1;
- arr_index = arr -> size - 1;
- }
- // do the byteshift
- owl_byte tmp1 = 0, tmp2 = 0;
- for (owl_umax i = 0; i < arr -> size; i++) {
- tmp1 = (arr -> ptr)[arr_index];
- (arr -> ptr)[arr_index] = tmp2;
- tmp2 = tmp1;
- arr_index += increment;
- }
- // return the number of bytes read
- return arr -> size;
- }
- // just call owl_bytarr_shift() n times
- owl_umax owl_bytarr_n_shift(owl_bytarr * arr, owl_byteshift_dir shift, owl_umax n)
- {
- // check params
- if (owl_check_bytarr_all(arr, sizeof(owl_bytarr)) == owl_false
- || owl_check_byteshift_dir(shift) == owl_false
- || n == 0)
- return 0;
-
- // do the byteshift
- owl_umax tmp = n;
- while (n-- != 0)
- owl_bytarr_shift(arr, shift);
- return tmp * (arr -> size);
- }
- // function to do a circular byteshift on a bytarr
- owl_umax owl_bytarr_circ_shift(owl_bytarr * arr, owl_byteshift_dir shift)
- {
- // check params
- if (owl_check_bytarr_all(arr, sizeof(owl_bytarr)) == owl_false
- || owl_check_byteshift_dir(shift) == owl_false)
- return 0;
-
- // get the byte that will get lost after a call to owl_bytarr_shift
- owl_byte tmp = (arr -> ptr)[arr -> size - 1];
- if (shift == OWL_BYTESHIFT_LEFT)
- tmp = (arr -> ptr)[0];
- // do the byteshift
- owl_bytarr_shift(arr, shift);
- // place the byte where it should be after the circular shift
- if (shift == OWL_BYTESHIFT_RIGHT)
- (arr -> ptr)[0] = tmp;
- else
- (arr -> ptr)[arr -> size - 1] = tmp;
- // return the number of bytes read
- return arr -> size;
- }
- // function to call n times owl_bytarr_circ_shift()
- owl_umax owl_bytarr_n_circ_shift(owl_bytarr * arr, owl_byteshift_dir shift, owl_umax n)
- {
- // check params
- if (owl_check_bytarr_all(arr, sizeof(owl_bytarr)) == owl_false
- || owl_check_byteshift_dir(shift) == owl_false
- || n == 0)
- return 0;
-
- // do the circular byteshift
- owl_umax tmp = n;
- while (n-- != 0)
- owl_bytarr_circ_shift(arr, shift);
- return tmp * (arr -> size);
- }
- // function to insert a bytarr inside another one
- owl_bytarr * owl_ins_bytarr(owl_bytarr * arr, owl_umax arr_ins_pos, owl_bytarr * insert)
- {
- // check params
- owl_bytarr * new = NULL;
- if (owl_check_bytarr_all(arr, sizeof(owl_bytarr)) == owl_false
- || arr_ins_pos > arr -> size
- || owl_check_bytarr_all(insert, sizeof(owl_bytarr)) == owl_false)
- goto err;
-
- // otherwise allocate memory for the new array
- new = owl_create_bytarr(NULL, arr -> size + insert -> size);
- if (new == NULL)
- goto err;
-
- // copy the contents from arr into new until arr_ins_pos
- // then copy the insert byte data and after copy the rest of the bytes on arr
- owl_bytarr tmp1 = *arr, tmp2 = *arr;
- // consider the case in which insertion occurs at the very beginning
- if (arr_ins_pos != 0) {
- tmp1.size = arr_ins_pos;
- tmp1 = owl_copy_bytarr(&tmp1, new);
- if (tmp1.ptr == NULL)
- goto err;
- }
- else
- tmp1 = *new;
- // insert the bytes
- tmp1 = owl_copy_bytarr(insert, &tmp1);
- if (tmp1.ptr == NULL)
- goto err;
- // consider the case in which the bytes are added at the very end
- if (arr_ins_pos != arr -> size) {
- tmp2.ptr += arr_ins_pos;
- tmp2.size = tmp1.size;
- tmp1 = owl_copy_bytarr(&tmp2, &tmp1);
- if (tmp1.ptr == NULL)
- goto err;
- }
-
- // all done, return the new structure
- return new;
- err:
- // free the allocated memory if something wrong happens
- owl_free_bytarr(new);
- return NULL;
- }
- // function to remove bytes from a bytarr
- owl_umax owl_rm_bytarr(owl_bytarr * arr, owl_umax rm_pos, owl_umax rm_size)
- {
- // check params
- if (owl_check_bytarr_all(arr, sizeof(owl_bytarr)) == owl_false
- || rm_size == 0 || rm_size > arr -> size - (rm_pos + 1))
- return 0;
-
- // use bytarr_shift to remove the unwanted bytes
- owl_bytarr tmp = {arr -> ptr + rm_pos, arr -> size - (rm_pos + 1)};
- owl_bytarr_n_shift(&tmp, OWL_BYTESHIFT_LEFT, rm_size);
- return (arr -> size -= rm_size);
- }
|