123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476 |
- // C source file with the function definitions to handle byte arrays
- // check_byte_array()
- // function to check the paramaters of a byte array
- bool check_byte_array(byte * arr, umax size)
- {
- return (arr != NULL && size != 0);
- }
- // print_byte_array()
- // function to print a byte array
- umax print_byte_array(byte * arr, umax size)
- {
- // check params
- if (check_byte_array(arr, size) == false)
- return 0;
-
- // print the array
- for (umax i = 0; i < size; i++) {
- print_byte_hex(arr + i, size - i);
- putchar(' ');
- }
- putchar('\n');
- return size;
- }
- // check_byteshift_type()
- // function to check if an integer is a valid byteshift_type
- bool check_byteshift_type(byteshift_type shift)
- {
- return (shift == BYTESHIFT_LEFT || shift == BYTESHIFT_RIGHT);
- }
- // cp_mem_bytes()
- // function to copy bytes from a place to another
- // will return a pointer to the position after the last write position
- byte * cp_mem_bytes(byte * src, umax length, byte * dest)
- {
- // check function parameters
- if (check_byte_array(src, length) == false || check_byte_array(dest, length) == false)
- return NULL;
-
- // otherwise copy the bytes
- for (umax i = 0; i < length; i++)
- dest[i] = src[i];
- return dest + length;
- }
- // comp_bytes_until_mismatch()
- // compares the bytes of 2 arrays until a mismatch is found
- // the function will return an integer indicating the position
- // of the element that interrupts the comparison.
- // If there is no interruption, size will be returned.
- umax comp_bytes_until_mismatch(byte * arr1, byte * arr2, umax size)
- {
- // check params
- if (check_byte_array(arr1, size) == false || check_byte_array(arr2, size) == false)
- return 0;
-
- // make the comparison
- umax int_pos = 0;
- for (umax i = 0; i < size; i++)
- if (*(arr1++) == *(arr2++))
- int_pos++;
- else
- break;
- return int_pos;
- }
- // comp_bytes() function
- // function to compare 2 byte arrays
- bool comp_bytes(byte * arr1, byte * arr2, umax size)
- {
- // check the function parameters
- // reuse comp_bytes_until_mismatch()
- umax int_pos = comp_bytes_until_mismatch(arr1, arr2, size);
- if (int_pos == size)
- return true;
- return false;
- }
- // ignore_bytes() function
- // function to skip bytes found from a position in an array.
- // The function will return the position of the first byte found
- // on data that isn't present on the skip string.
- byte * ignore_bytes(byte * src, umax src_size, byte * skip, umax skip_size)
- {
- // check the function parameters
- if (check_byte_array(src, src_size) == false || check_byte_array(skip, skip_size) == false)
- goto err;
-
- // variable to exit the for loop
- bool ch_skip_read = false;
- for (umax i = 0; i < src_size; i++) {
- // read skip
- for (umax j = 0; j < skip_size; j++)
- ch_skip_read = ch_skip_read || (src[i] == skip[j]);
- // none of the characters in skip was matched
- if (ch_skip_read == false)
- return src + i;
- }
-
- err: // nothing different than skip data was found in src
- return NULL;
- }
- // search_byte_pattern() function
- // function to search for a given byte sequence in a byte array.
- // It will return the first occurrence of the pattern
- byte * search_byte_pattern(byte * src, umax ssize, byte * pattern, umax psize)
- {
- // check function parameters
- if (check_byte_array(src, ssize) == false || check_byte_array(pattern, psize) == false)
- goto err;
-
- // search in array for said pattern
- for (umax i = 0; i + psize <= ssize; i++)
- if (comp_bytes(pattern, src + i, psize))
- return src + i;
-
- // failure
- err:
- return NULL;
- }
- // byte_shift() function
- // shift bytes on memory to the right or the left 1 position
- // it will behave as the bitshift operations but for byte arrays
- bool byte_shift(byte * arr, umax size, byteshift_type shift)
- {
- // check function parameters
- if (check_byte_array(arr, size) == false || check_byteshift_type(shift) == false)
- return false;
-
- // set the variables for the next for loop
- // arr = arr;
- char shift_inc = 1;
- if (shift == BYTESHIFT_LEFT) {
- arr = arr + size - 1;
- shift_inc = -1;
- }
-
- // do the byteshift
- byte new_byte = 0, old_byte = 0;
- for (umax i = 0; i < size; i++) {
- new_byte = *(arr);
- *(arr) = old_byte;
- old_byte = new_byte;
- arr += shift_inc;
- }
- // byte shift done
- return true;
- }
- // byte_n_shift() function
- // reuses byte_shift "n" times
- bool byte_n_shift(byte * arr, umax size, byteshift_type shift, umax n)
- {
- // check n
- if (n == 0)
- return false;
-
- // do n single byte shifts
- while (n-- > 0)
- // if a call of byte_shift cannot be done then end the function
- if (byte_shift(arr, size, shift) == false)
- return false;
-
- // byte shift done
- return true;
- }
- // byte_circ_shift() function
- // shift the bytes of a byte array keeping the bytes that are going to
- // get discarded. These bytes are put (depending on the shift direction) on
- // the end or at the start of the byte array being byte shifted
- bool byte_circ_shift(byte * arr, umax size, byteshift_type shift)
- {
- // check the function parameters
- if (check_byte_array(arr, size) == false || check_byteshift_type(shift) == false)
- return false;
-
- // save the byte that will get lost on the byteshift
- byte princess_byte = (shift == BYTESHIFT_RIGHT ? arr[size - 1] : arr[0]);
- byte_shift(arr, size, shift);
-
- // add the princess byte
- if (shift == BYTESHIFT_LEFT)
- arr[size - 1] = princess_byte;
- else /* BYTESHIFT_RIGHT */
- arr[0] = princess_byte;
-
- // circular byte shift done
- return true;
- }
- // byte_n_circ_shift() function
- // same as byte_circ_shift() but n times
- bool byte_n_circ_shift(byte * arr, umax size, byteshift_type shift, umax n)
- {
- // check n
- if (n == 0)
- return false;
-
- // do n single circular byte shifts
- while (n-- > 0)
- // if a call of byte_shift cannot be done then end the function
- if (byte_circ_shift(arr, size, shift) == false)
- return false;
-
- // circular byte shift done
- return true;
- }
- // create_bytarr()
- // function to create a bytarr structure
- // the arr pointer may be NULL and the function
- // will do the same as create_mem_space()
- bytarr * create_bytarr(byte * arr, umax size)
- {
- // check params
- bytarr * rtn = create_mem_space(size);
- if (rtn == NULL)
- return NULL;
-
- // copy the elements from arr into the structure
- cp_mem_bytes(arr, size, rtn -> ptr);
- return rtn;
- }
- // check_bytarr()
- // function to check if the members of a bytarr structure are valid
- bool check_bytarr(bytarr * arr)
- {
- return (arr != NULL && arr -> ptr != NULL && arr -> size != 0);
- }
- // free_bytarr()
- // function to free the memory used by a bytarr structure
- umax free_bytarr(bytarr * arr)
- {
- return free_mem_space((mem_space *) arr);
- }
- // print_bytarr()
- // function to print the information on a bytarr array
- umax print_bytarr(byte * src, umax size)
- {
- // check params
- if (src == NULL || size < BYTARR_SIZE)
- return 0;
- // print the structure
- bytarr * arr = (bytarr *) src;
- printf("BYTARR structure info:\n");
- printf("Pointer: %p\n", arr -> ptr);
- printf("Size (bytes): %llu\n", arr -> size);
- printf("Contents: ");
- print_byte_array(arr -> ptr, arr -> size);
- putchar('\n');
- return BYTARR_SIZE;
- }
- // cp_bytarr()
- // function to copy the contents of a byte array into another byte array
- // the copy will be successful only if dest -> size is greater or equal to src -> size
- // also, the function will return a "temporal" bytarr with the last write position on dest
- bytarr cp_bytarr(bytarr * src, bytarr * dest)
- {
- // check params
- if (check_bytarr(src) == false
- || check_bytarr(dest) == false
- || src -> size > dest -> size)
- return (bytarr) {NULL, 0};
-
- // do the copy and return the temporal structure
- return (bytarr) {cp_mem_bytes(src -> ptr, src -> size, dest -> ptr), dest -> size - src -> size};
- }
- // comp_bytarrs_until_mismatch()
- // the function will return an integer indicating the first non-equal byte in the comparison
- // the comparison will only be done with the lowest array size
- umax comp_bytarrs_until_mismatch(bytarr * arr1, bytarr * arr2)
- {
- // check params
- if (check_bytarr(arr1) == false || check_bytarr(arr2) == false)
- return 0;
-
- // reuse comp_bytes_until_mismatch()
- return comp_bytes_until_mismatch(arr1 -> ptr,
- arr2 -> ptr,
- arr1 -> size < arr2 -> size ? arr1 -> size : arr2 -> size);
- }
- // comp_bytarrs()
- // function to check if 2 bytarrs are equivalent (contents and size)
- bool comp_bytarrs(bytarr * arr1, bytarr * arr2)
- {
- // check params
- if (check_bytarr(arr1) == false || check_bytarr(arr2) == false || arr1 -> size != arr2 -> size)
- return false;
-
- // reuse comp_bytes()
- return comp_bytes(arr1 -> ptr, arr2 -> ptr, arr1 -> size);
- }
- // ignore_bytarr_bytes()
- // ignore the bytes from a bytarr structure
- // the function will return a bytarr to the part skipped from arr
- bytarr ignore_bytarr_bytes(bytarr * arr, bytarr * skip)
- {
- // check params
- if (check_bytarr(arr) == false || check_bytarr(skip) == false)
- return (bytarr) {NULL, 0};
-
- // reuse ignore_bytes()
- byte * ptr = ignore_bytes(arr -> ptr, arr -> size, skip -> ptr, skip -> size);
- return (ptr == NULL ?
- (bytarr) {NULL, 0} :
- (bytarr) {ptr, arr -> size - (ptr - arr -> ptr)});
- }
- // search_bytarr()
- // functiont to search for a byte array inside another one
- bytarr search_bytarr(bytarr * src, bytarr * search)
- {
- // check params
- if (check_bytarr(src) == false || check_bytarr(search) == false)
- return (bytarr) {NULL, 0};
-
- // reuse search_byte_pattern()
- byte * ptr = search_byte_pattern(src -> ptr, src -> size, search -> ptr, search -> size);
- return (bytarr) {ptr, search -> size};
- }
- // bytarr_shift()
- bool bytarr_shift(bytarr * arr, byteshift_type shift)
- {
- // check params
- if (check_bytarr(arr) == false || check_byteshift_type(shift) == false)
- return false;
-
- // reuse byte_shift()
- return byte_shift(arr -> ptr, arr -> size, shift);
- }
- // bytarr_n_shift()
- bool bytarr_n_shift(bytarr * arr, byteshift_type shift, umax n)
- {
- // check params
- if (check_bytarr(arr) == false || check_byteshift_type(shift) == false || n == 0)
- return false;
-
- // reuse byte_shift()
- return byte_n_shift(arr -> ptr, arr -> size, shift, n);
- }
- // bytarr_circ_shift()
- bool bytarr_circ_shift(bytarr * arr, byteshift_type shift)
- {
- // check params
- if (check_bytarr(arr) == false || check_byteshift_type(shift) == false)
- return false;
-
- // reuse byte_shift()
- return byte_circ_shift(arr -> ptr, arr -> size, shift);
- }
- // bytarr_n_circ_shift()
- bool bytarr_n_circ_shift(bytarr * arr, byteshift_type shift, umax n)
- {
- // check params
- if (check_bytarr(arr) == false || check_byteshift_type(shift) == false || n == 0)
- return false;
-
- // reuse byte_shift()
- return byte_n_circ_shift(arr -> ptr, arr -> size, shift, n);
- }
- // ins_bytarr() function
- // function to insert bytes in a bytarr at some position
- bytarr * ins_bytarr(bytarr * arr, umax arr_ins_pos, bytarr * bytes)
- {
- // check params
- bytarr * new = NULL;
- if (check_bytarr(arr) == false || check_bytarr(bytes) == false || arr_ins_pos > arr -> size)
- goto err;
-
- // allocate space for the new bytarr structure
- new = create_bytarr(NULL, arr -> size + bytes -> size);
- if (check_bytarr(new) == false)
- goto err;
-
- // copy arr into dest up to arr_ins_pos, consider case arr_ins_pos == 0
- bytarr tmp = {arr -> ptr, arr_ins_pos};
- if (arr_ins_pos != 0) {
- tmp = cp_bytarr(&tmp, new);
- } else
- tmp = *new;
- // copy bytes into tmp
- tmp = cp_bytarr(bytes, &tmp);
- // copy the rest of data from arr into dest
- cp_bytarr(&((bytarr) {arr -> ptr + arr_ins_pos, arr -> size - arr_ins_pos}), &tmp);
-
- // free the memory occupied by arr -> ptr (if it was manually allocated)
- free_bytarr(arr);
- return new;
- err: // error
- free_bytarr(new);
- return NULL;
- }
- // rm_bytarr()
- // function to remove a bytarr portion of a bytarr structure
- umax rm_bytarr(bytarr * arr, umax rm_pos, umax rm_size)
- {
- // check params
- if (check_bytarr(arr) == false || (rm_pos + rm_size) > (arr -> size) || rm_size == 0)
- return 0;
-
- // otherwise remove the bytes
- bytarr_n_shift(&((bytarr) {arr -> ptr + rm_pos, arr -> size - rm_pos}), BYTESHIFT_LEFT, rm_size);
- return arr -> size - rm_size;
- }
- //~ // function to insert bytes (from src) in an array (target at insert_pos) loaded in memory
- //~ // the function will return the pointer to the new array allocated
- //~ byte * insert_bytes(byte * target, umax target_size, byte * insert_pos, byte * src, umax src_size)
- //~ {
- //~ // check params
- //~ byte * new = NULL;
- //~ if (target == NULL || target_size == 0 || insert_pos == NULL || src == NULL || src_size == 0)
- //~ goto err;
- //~ // check if insert_pos is actually contained within [target, target + target_size - 1]
- //~ smax tmp = (byte *) insert_pos - (byte *) target;
- //~ if (tmp < 0 || tmp > target_size)
- //~ goto err;
- //~ // get a new container for the new data
- //~ new = allocate_memory(1, target_size + src_size);
- //~ if (new == NULL)
- //~ goto err;
-
- //~ // copy the bytes from target from target to insert_pos
- //~ cp_mem_bytes(target, tmp, new);
- //~ // copy the bytes from src
- //~ cp_mem_bytes(src, src_size, new + tmp);
- //~ // copy the rest of the bytes from insert_pos to target + target_size - 1
- //~ cp_mem_bytes(target + tmp, target_size - tmp, new + tmp + src_size);
-
- //~ // free the memory occupied by target (if it was manually allocated)
- //~ free_memory(target);
- //~ return new;
- //~ err: // error
- //~ free_memory(new);
- //~ return NULL;
- //~ }
- //~ // function to remove bytes (from remove_pos) in an array (data at rm) loaded in memory
- //~ // the function will return the data array changed size
- //~ umax remove_bytes(byte * target, umax target_size, byte * remove_pos, umax remove_size)
- //~ {
- //~ // check params
- //~ if (target == NULL || target_size == 0 || remove_pos == NULL || remove_size == 0)
- //~ goto err;
- //~ // check if remove_pos is actually contained within [target, target + target_size - 1]
- //~ smax tmp = (byte *) remove_pos - (byte *) target;
- //~ if (tmp < 0 || tmp > target_size)
- //~ goto err;
-
- //~ // remove the bytes selected by using the byteshift function
- //~ byte_n_shift(remove_pos, target_size - tmp, BYTESHIFT_LEFT, remove_size);
- //~ // return the "new" size of the array
- //~ return target_size - remove_size;
- //~ err: // error
- //~ return 0;
- //~ }
|