BYTE_ARR.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. // C source file with the function definitions to handle byte arrays
  2. // check_byte_array()
  3. // function to check the paramaters of a byte array
  4. bool check_byte_array(byte * arr, umax size)
  5. {
  6. return (arr != NULL && size != 0);
  7. }
  8. // print_byte_array()
  9. // function to print a byte array
  10. umax print_byte_array(byte * arr, umax size)
  11. {
  12. // check params
  13. if (check_byte_array(arr, size) == false)
  14. return 0;
  15. // print the array
  16. for (umax i = 0; i < size; i++) {
  17. print_byte_hex(arr + i, size - i);
  18. putchar(' ');
  19. }
  20. putchar('\n');
  21. return size;
  22. }
  23. // check_byteshift_type()
  24. // function to check if an integer is a valid byteshift_type
  25. bool check_byteshift_type(byteshift_type shift)
  26. {
  27. return (shift == BYTESHIFT_LEFT || shift == BYTESHIFT_RIGHT);
  28. }
  29. // cp_mem_bytes()
  30. // function to copy bytes from a place to another
  31. // will return a pointer to the position after the last write position
  32. byte * cp_mem_bytes(byte * src, umax length, byte * dest)
  33. {
  34. // check function parameters
  35. if (check_byte_array(src, length) == false || check_byte_array(dest, length) == false)
  36. return NULL;
  37. // otherwise copy the bytes
  38. for (umax i = 0; i < length; i++)
  39. dest[i] = src[i];
  40. return dest + length;
  41. }
  42. // comp_bytes_until_mismatch()
  43. // compares the bytes of 2 arrays until a mismatch is found
  44. // the function will return an integer indicating the position
  45. // of the element that interrupts the comparison.
  46. // If there is no interruption, size will be returned.
  47. umax comp_bytes_until_mismatch(byte * arr1, byte * arr2, umax size)
  48. {
  49. // check params
  50. if (check_byte_array(arr1, size) == false || check_byte_array(arr2, size) == false)
  51. return 0;
  52. // make the comparison
  53. umax int_pos = 0;
  54. for (umax i = 0; i < size; i++)
  55. if (*(arr1++) == *(arr2++))
  56. int_pos++;
  57. else
  58. break;
  59. return int_pos;
  60. }
  61. // comp_bytes() function
  62. // function to compare 2 byte arrays
  63. bool comp_bytes(byte * arr1, byte * arr2, umax size)
  64. {
  65. // check the function parameters
  66. // reuse comp_bytes_until_mismatch()
  67. umax int_pos = comp_bytes_until_mismatch(arr1, arr2, size);
  68. if (int_pos == size)
  69. return true;
  70. return false;
  71. }
  72. // ignore_bytes() function
  73. // function to skip bytes found from a position in an array.
  74. // The function will return the position of the first byte found
  75. // on data that isn't present on the skip string.
  76. byte * ignore_bytes(byte * src, umax src_size, byte * skip, umax skip_size)
  77. {
  78. // check the function parameters
  79. if (check_byte_array(src, src_size) == false || check_byte_array(skip, skip_size) == false)
  80. goto err;
  81. // variable to exit the for loop
  82. bool ch_skip_read = false;
  83. for (umax i = 0; i < src_size; i++) {
  84. // read skip
  85. for (umax j = 0; j < skip_size; j++)
  86. ch_skip_read = ch_skip_read || (src[i] == skip[j]);
  87. // none of the characters in skip was matched
  88. if (ch_skip_read == false)
  89. return src + i;
  90. }
  91. err: // nothing different than skip data was found in src
  92. return NULL;
  93. }
  94. // search_byte_pattern() function
  95. // function to search for a given byte sequence in a byte array.
  96. // It will return the first occurrence of the pattern
  97. byte * search_byte_pattern(byte * src, umax ssize, byte * pattern, umax psize)
  98. {
  99. // check function parameters
  100. if (check_byte_array(src, ssize) == false || check_byte_array(pattern, psize) == false)
  101. goto err;
  102. // search in array for said pattern
  103. for (umax i = 0; i + psize <= ssize; i++)
  104. if (comp_bytes(pattern, src + i, psize))
  105. return src + i;
  106. // failure
  107. err:
  108. return NULL;
  109. }
  110. // byte_shift() function
  111. // shift bytes on memory to the right or the left 1 position
  112. // it will behave as the bitshift operations but for byte arrays
  113. bool byte_shift(byte * arr, umax size, byteshift_type shift)
  114. {
  115. // check function parameters
  116. if (check_byte_array(arr, size) == false || check_byteshift_type(shift) == false)
  117. return false;
  118. // set the variables for the next for loop
  119. // arr = arr;
  120. char shift_inc = 1;
  121. if (shift == BYTESHIFT_LEFT) {
  122. arr = arr + size - 1;
  123. shift_inc = -1;
  124. }
  125. // do the byteshift
  126. byte new_byte = 0, old_byte = 0;
  127. for (umax i = 0; i < size; i++) {
  128. new_byte = *(arr);
  129. *(arr) = old_byte;
  130. old_byte = new_byte;
  131. arr += shift_inc;
  132. }
  133. // byte shift done
  134. return true;
  135. }
  136. // byte_n_shift() function
  137. // reuses byte_shift "n" times
  138. bool byte_n_shift(byte * arr, umax size, byteshift_type shift, umax n)
  139. {
  140. // check n
  141. if (n == 0)
  142. return false;
  143. // do n single byte shifts
  144. while (n-- > 0)
  145. // if a call of byte_shift cannot be done then end the function
  146. if (byte_shift(arr, size, shift) == false)
  147. return false;
  148. // byte shift done
  149. return true;
  150. }
  151. // byte_circ_shift() function
  152. // shift the bytes of a byte array keeping the bytes that are going to
  153. // get discarded. These bytes are put (depending on the shift direction) on
  154. // the end or at the start of the byte array being byte shifted
  155. bool byte_circ_shift(byte * arr, umax size, byteshift_type shift)
  156. {
  157. // check the function parameters
  158. if (check_byte_array(arr, size) == false || check_byteshift_type(shift) == false)
  159. return false;
  160. // save the byte that will get lost on the byteshift
  161. byte princess_byte = (shift == BYTESHIFT_RIGHT ? arr[size - 1] : arr[0]);
  162. byte_shift(arr, size, shift);
  163. // add the princess byte
  164. if (shift == BYTESHIFT_LEFT)
  165. arr[size - 1] = princess_byte;
  166. else /* BYTESHIFT_RIGHT */
  167. arr[0] = princess_byte;
  168. // circular byte shift done
  169. return true;
  170. }
  171. // byte_n_circ_shift() function
  172. // same as byte_circ_shift() but n times
  173. bool byte_n_circ_shift(byte * arr, umax size, byteshift_type shift, umax n)
  174. {
  175. // check n
  176. if (n == 0)
  177. return false;
  178. // do n single circular byte shifts
  179. while (n-- > 0)
  180. // if a call of byte_shift cannot be done then end the function
  181. if (byte_circ_shift(arr, size, shift) == false)
  182. return false;
  183. // circular byte shift done
  184. return true;
  185. }
  186. // create_bytarr()
  187. // function to create a bytarr structure
  188. // the arr pointer may be NULL and the function
  189. // will do the same as create_mem_space()
  190. bytarr * create_bytarr(byte * arr, umax size)
  191. {
  192. // check params
  193. bytarr * rtn = create_mem_space(size);
  194. if (rtn == NULL)
  195. return NULL;
  196. // copy the elements from arr into the structure
  197. cp_mem_bytes(arr, size, rtn -> ptr);
  198. return rtn;
  199. }
  200. // check_bytarr()
  201. // function to check if the members of a bytarr structure are valid
  202. bool check_bytarr(bytarr * arr)
  203. {
  204. return (arr != NULL && arr -> ptr != NULL && arr -> size != 0);
  205. }
  206. // free_bytarr()
  207. // function to free the memory used by a bytarr structure
  208. umax free_bytarr(bytarr * arr)
  209. {
  210. return free_mem_space((mem_space *) arr);
  211. }
  212. // print_bytarr()
  213. // function to print the information on a bytarr array
  214. umax print_bytarr(byte * src, umax size)
  215. {
  216. // check params
  217. if (src == NULL || size < BYTARR_SIZE)
  218. return 0;
  219. // print the structure
  220. bytarr * arr = (bytarr *) src;
  221. printf("BYTARR structure info:\n");
  222. printf("Pointer: %p\n", arr -> ptr);
  223. printf("Size (bytes): %llu\n", arr -> size);
  224. printf("Contents: ");
  225. print_byte_array(arr -> ptr, arr -> size);
  226. putchar('\n');
  227. return BYTARR_SIZE;
  228. }
  229. // cp_bytarr()
  230. // function to copy the contents of a byte array into another byte array
  231. // the copy will be successful only if dest -> size is greater or equal to src -> size
  232. // also, the function will return a "temporal" bytarr with the last write position on dest
  233. bytarr cp_bytarr(bytarr * src, bytarr * dest)
  234. {
  235. // check params
  236. if (check_bytarr(src) == false
  237. || check_bytarr(dest) == false
  238. || src -> size > dest -> size)
  239. return (bytarr) {NULL, 0};
  240. // do the copy and return the temporal structure
  241. return (bytarr) {cp_mem_bytes(src -> ptr, src -> size, dest -> ptr), dest -> size - src -> size};
  242. }
  243. // comp_bytarrs_until_mismatch()
  244. // the function will return an integer indicating the first non-equal byte in the comparison
  245. // the comparison will only be done with the lowest array size
  246. umax comp_bytarrs_until_mismatch(bytarr * arr1, bytarr * arr2)
  247. {
  248. // check params
  249. if (check_bytarr(arr1) == false || check_bytarr(arr2) == false)
  250. return 0;
  251. // reuse comp_bytes_until_mismatch()
  252. return comp_bytes_until_mismatch(arr1 -> ptr,
  253. arr2 -> ptr,
  254. arr1 -> size < arr2 -> size ? arr1 -> size : arr2 -> size);
  255. }
  256. // comp_bytarrs()
  257. // function to check if 2 bytarrs are equivalent (contents and size)
  258. bool comp_bytarrs(bytarr * arr1, bytarr * arr2)
  259. {
  260. // check params
  261. if (check_bytarr(arr1) == false || check_bytarr(arr2) == false || arr1 -> size != arr2 -> size)
  262. return false;
  263. // reuse comp_bytes()
  264. return comp_bytes(arr1 -> ptr, arr2 -> ptr, arr1 -> size);
  265. }
  266. // ignore_bytarr_bytes()
  267. // ignore the bytes from a bytarr structure
  268. // the function will return a bytarr to the part skipped from arr
  269. bytarr ignore_bytarr_bytes(bytarr * arr, bytarr * skip)
  270. {
  271. // check params
  272. if (check_bytarr(arr) == false || check_bytarr(skip) == false)
  273. return (bytarr) {NULL, 0};
  274. // reuse ignore_bytes()
  275. byte * ptr = ignore_bytes(arr -> ptr, arr -> size, skip -> ptr, skip -> size);
  276. return (ptr == NULL ?
  277. (bytarr) {NULL, 0} :
  278. (bytarr) {ptr, arr -> size - (ptr - arr -> ptr)});
  279. }
  280. // search_bytarr()
  281. // functiont to search for a byte array inside another one
  282. bytarr search_bytarr(bytarr * src, bytarr * search)
  283. {
  284. // check params
  285. if (check_bytarr(src) == false || check_bytarr(search) == false)
  286. return (bytarr) {NULL, 0};
  287. // reuse search_byte_pattern()
  288. byte * ptr = search_byte_pattern(src -> ptr, src -> size, search -> ptr, search -> size);
  289. return (bytarr) {ptr, search -> size};
  290. }
  291. // bytarr_shift()
  292. bool bytarr_shift(bytarr * arr, byteshift_type shift)
  293. {
  294. // check params
  295. if (check_bytarr(arr) == false || check_byteshift_type(shift) == false)
  296. return false;
  297. // reuse byte_shift()
  298. return byte_shift(arr -> ptr, arr -> size, shift);
  299. }
  300. // bytarr_n_shift()
  301. bool bytarr_n_shift(bytarr * arr, byteshift_type shift, umax n)
  302. {
  303. // check params
  304. if (check_bytarr(arr) == false || check_byteshift_type(shift) == false || n == 0)
  305. return false;
  306. // reuse byte_shift()
  307. return byte_n_shift(arr -> ptr, arr -> size, shift, n);
  308. }
  309. // bytarr_circ_shift()
  310. bool bytarr_circ_shift(bytarr * arr, byteshift_type shift)
  311. {
  312. // check params
  313. if (check_bytarr(arr) == false || check_byteshift_type(shift) == false)
  314. return false;
  315. // reuse byte_shift()
  316. return byte_circ_shift(arr -> ptr, arr -> size, shift);
  317. }
  318. // bytarr_n_circ_shift()
  319. bool bytarr_n_circ_shift(bytarr * arr, byteshift_type shift, umax n)
  320. {
  321. // check params
  322. if (check_bytarr(arr) == false || check_byteshift_type(shift) == false || n == 0)
  323. return false;
  324. // reuse byte_shift()
  325. return byte_n_circ_shift(arr -> ptr, arr -> size, shift, n);
  326. }
  327. // ins_bytarr() function
  328. // function to insert bytes in a bytarr at some position
  329. bytarr * ins_bytarr(bytarr * arr, umax arr_ins_pos, bytarr * bytes)
  330. {
  331. // check params
  332. bytarr * new = NULL;
  333. if (check_bytarr(arr) == false || check_bytarr(bytes) == false || arr_ins_pos > arr -> size)
  334. goto err;
  335. // allocate space for the new bytarr structure
  336. new = create_bytarr(NULL, arr -> size + bytes -> size);
  337. if (check_bytarr(new) == false)
  338. goto err;
  339. // copy arr into dest up to arr_ins_pos, consider case arr_ins_pos == 0
  340. bytarr tmp = {arr -> ptr, arr_ins_pos};
  341. if (arr_ins_pos != 0) {
  342. tmp = cp_bytarr(&tmp, new);
  343. } else
  344. tmp = *new;
  345. // copy bytes into tmp
  346. tmp = cp_bytarr(bytes, &tmp);
  347. // copy the rest of data from arr into dest
  348. cp_bytarr(&((bytarr) {arr -> ptr + arr_ins_pos, arr -> size - arr_ins_pos}), &tmp);
  349. // free the memory occupied by arr -> ptr (if it was manually allocated)
  350. free_bytarr(arr);
  351. return new;
  352. err: // error
  353. free_bytarr(new);
  354. return NULL;
  355. }
  356. // rm_bytarr()
  357. // function to remove a bytarr portion of a bytarr structure
  358. umax rm_bytarr(bytarr * arr, umax rm_pos, umax rm_size)
  359. {
  360. // check params
  361. if (check_bytarr(arr) == false || (rm_pos + rm_size) > (arr -> size) || rm_size == 0)
  362. return 0;
  363. // otherwise remove the bytes
  364. bytarr_n_shift(&((bytarr) {arr -> ptr + rm_pos, arr -> size - rm_pos}), BYTESHIFT_LEFT, rm_size);
  365. return arr -> size - rm_size;
  366. }
  367. //~ // function to insert bytes (from src) in an array (target at insert_pos) loaded in memory
  368. //~ // the function will return the pointer to the new array allocated
  369. //~ byte * insert_bytes(byte * target, umax target_size, byte * insert_pos, byte * src, umax src_size)
  370. //~ {
  371. //~ // check params
  372. //~ byte * new = NULL;
  373. //~ if (target == NULL || target_size == 0 || insert_pos == NULL || src == NULL || src_size == 0)
  374. //~ goto err;
  375. //~ // check if insert_pos is actually contained within [target, target + target_size - 1]
  376. //~ smax tmp = (byte *) insert_pos - (byte *) target;
  377. //~ if (tmp < 0 || tmp > target_size)
  378. //~ goto err;
  379. //~ // get a new container for the new data
  380. //~ new = allocate_memory(1, target_size + src_size);
  381. //~ if (new == NULL)
  382. //~ goto err;
  383. //~ // copy the bytes from target from target to insert_pos
  384. //~ cp_mem_bytes(target, tmp, new);
  385. //~ // copy the bytes from src
  386. //~ cp_mem_bytes(src, src_size, new + tmp);
  387. //~ // copy the rest of the bytes from insert_pos to target + target_size - 1
  388. //~ cp_mem_bytes(target + tmp, target_size - tmp, new + tmp + src_size);
  389. //~ // free the memory occupied by target (if it was manually allocated)
  390. //~ free_memory(target);
  391. //~ return new;
  392. //~ err: // error
  393. //~ free_memory(new);
  394. //~ return NULL;
  395. //~ }
  396. //~ // function to remove bytes (from remove_pos) in an array (data at rm) loaded in memory
  397. //~ // the function will return the data array changed size
  398. //~ umax remove_bytes(byte * target, umax target_size, byte * remove_pos, umax remove_size)
  399. //~ {
  400. //~ // check params
  401. //~ if (target == NULL || target_size == 0 || remove_pos == NULL || remove_size == 0)
  402. //~ goto err;
  403. //~ // check if remove_pos is actually contained within [target, target + target_size - 1]
  404. //~ smax tmp = (byte *) remove_pos - (byte *) target;
  405. //~ if (tmp < 0 || tmp > target_size)
  406. //~ goto err;
  407. //~ // remove the bytes selected by using the byteshift function
  408. //~ byte_n_shift(remove_pos, target_size - tmp, BYTESHIFT_LEFT, remove_size);
  409. //~ // return the "new" size of the array
  410. //~ return target_size - remove_size;
  411. //~ err: // error
  412. //~ return 0;
  413. //~ }