FILE.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. // C source file with the function definitions to handle files
  2. // wrappers to some stdio.h functions
  3. // def_fopen() function
  4. // wrapper for fopen() to check errors
  5. FILE * def_fopen(char * fpath, char * open_mode)
  6. {
  7. // create fp
  8. FILE * fp = fopen(fpath, open_mode);
  9. // check if the file could be opened
  10. if (fp == NULL) {
  11. printf("\nFailed to open %s\n", fpath);
  12. perror("Error");
  13. printf("\n");
  14. exit(1);
  15. }
  16. // return fp
  17. return fp;
  18. }
  19. // def_fgetc() function
  20. // wrapper for fgetc()
  21. smax def_fgetc(FILE * fp)
  22. {
  23. // this wrapper exists in case
  24. // I need it for something
  25. return (smax) fgetc(fp);
  26. }
  27. // def_fseek() function
  28. // wrapper for fseek() to check errors
  29. void def_fseek(FILE * fp, smax offset, smax whence)
  30. {
  31. if (fseek(fp, offset, whence) != 0)
  32. {
  33. printf("\nFailed seeking in a file.\n");
  34. printf("Terminating program.\n");
  35. exit(1);
  36. }
  37. }
  38. // def_fputc() function
  39. // wrapper for fputc() to check errors
  40. void def_fputc(smax ch, FILE * fp)
  41. {
  42. if (fputc(ch, fp) == EOF)
  43. {
  44. printf("\nFailed to write data on file.\n");
  45. perror("Error");
  46. printf("\n");
  47. exit(1);
  48. }
  49. }
  50. // def_fclose() function
  51. // wrapper for fclose() to check errors
  52. void def_fclose(FILE * fp)
  53. {
  54. if (fclose(fp) == EOF)
  55. {
  56. printf("\nFailed to close a file.\n");
  57. printf("Terminating program.\n");
  58. exit(1);
  59. }
  60. }
  61. // path string related functions
  62. // get_fpath() function
  63. // get the path of a file into another string array the function will
  64. // return a pointer to the last element written (NULL character)
  65. char * get_file_dir(char * fpath, char * out_file_dir)
  66. {
  67. // check params
  68. if (fpath == NULL || out_file_dir == NULL)
  69. goto err;
  70. // get the string size
  71. umax str_size = get_str_byte_length(fpath, FILE_PATH_ENC);
  72. if (str_size == 0)
  73. goto err;
  74. // search for the first indicator of a path
  75. for (umax i = 0; i < str_size; i++)
  76. // first slash found when reading from right to left
  77. if (fpath[str_size - i] == '/' || fpath[str_size - i] == '\\')
  78. // copy the path into out_file_dir and return a pointer to the last element
  79. return cp_mem_bytes(fpath, str_size - i, out_file_dir);
  80. // no slash found? that means it is
  81. // in the same directory (probably)
  82. return out_file_dir;
  83. // failure
  84. err:
  85. return NULL;
  86. }
  87. // get_file_ext() function
  88. // this function will get the file extension of a file path string
  89. // (a pointer to the start of the extension, without the dot).
  90. // if no extension is found the function will return the
  91. // pointer to the terminating null character
  92. char * get_file_ext(char * fpath)
  93. {
  94. // check params
  95. if (fpath == NULL)
  96. goto err;
  97. // get string length
  98. umax str_size = get_str_byte_length(fpath, FILE_PATH_ENC);
  99. if (str_size == 0)
  100. goto err;
  101. // read string from right to left to search for the first dot
  102. for (umax i = 0; i < str_size; i++) {
  103. // dot found
  104. if (fpath[str_size - i] == '.')
  105. return fpath + str_size - i + 1;
  106. // if a slash is found before a dot then the file has no extension
  107. else if (fpath[str_size - i] == '/' || fpath[str_size - i] == '\\')
  108. goto end;
  109. }
  110. // if no slash is found and no point is found,
  111. // still, return a pointer to the null character
  112. end:
  113. return fpath + str_size - 1;
  114. // failure
  115. err:
  116. return NULL;
  117. }
  118. // get_file_size() function
  119. // function that gets the size in bytes of a file
  120. umax get_file_size(char * fpath)
  121. {
  122. // check params
  123. if (fpath == NULL)
  124. return 0;
  125. // open file
  126. FILE * fp = def_fopen(fpath, "rb");
  127. // read it completely
  128. umax size = 0;
  129. while (def_fgetc(fp) != EOF)
  130. size++;
  131. // close file
  132. def_fclose(fp);
  133. return size;
  134. }
  135. // get_fdata_array() function
  136. // get bytes from a file and store them on a manually allocated memory array
  137. void * get_fbytes(char * fpath, umax pos, umax size)
  138. {
  139. // check params
  140. byte * fbytes = NULL, * ptr = NULL;
  141. if (fpath == NULL || size == 0)
  142. goto end;
  143. // load the file and go to array_pos
  144. fbytes = load_file_mem(fpath);
  145. umax fsize = get_file_size(fpath);
  146. if (fbytes == NULL)
  147. goto end;
  148. // nono, you can't just do that
  149. if (fsize < pos + size)
  150. goto end;
  151. // copy desired bytes into the array to return
  152. ptr = allocate_memory(size, 1); // variable to return
  153. if (ptr == NULL)
  154. goto end;
  155. cp_mem_bytes(fbytes + pos, size, ptr);
  156. // done!
  157. end:
  158. free_memory(fbytes);
  159. return ptr;
  160. }
  161. // load_file_mem() function
  162. // function that opens a file and loads it on memory
  163. void * load_file_mem(char * fpath)
  164. {
  165. // check params
  166. if (fpath == NULL)
  167. goto err;
  168. // open file
  169. FILE * fp = def_fopen(fpath, "rb");
  170. // create space for file in memory (remember to free it!)
  171. // size is larger by 1 since it helps for reading
  172. byte * fdata = allocate_memory(get_file_size(fpath), 1);
  173. if (fdata == NULL) {
  174. def_fclose(fp);
  175. goto err;
  176. }
  177. // load it on memory
  178. smax ch = 0;
  179. for (umax i = 0; (ch = def_fgetc(fp)) != EOF; i++)
  180. fdata[i] = ch;
  181. // close file
  182. def_fclose(fp);
  183. // return pointer
  184. return fdata;
  185. // failure
  186. err:
  187. return NULL;
  188. }
  189. // dump_mem_file() function
  190. // function to dump the contents of memory (bytes) into a file
  191. umax dump_mem_file(char * fpath, umax file_size, void * fdata)
  192. {
  193. // check params
  194. if (fpath == NULL || file_size == 0 || fdata == NULL)
  195. return 0;
  196. // create file
  197. FILE * fp = def_fopen(fpath, "wb");
  198. // cast fdata pointer
  199. byte * data = fdata;
  200. // dump everything from
  201. // data into the new file
  202. for (umax i = 0; i < file_size; i++)
  203. def_fputc(data[i], fp);
  204. // close the file and indicate
  205. // that the file was created
  206. def_fclose(fp);
  207. printf("File %s was created.\n", fpath);
  208. // done!
  209. return file_size;
  210. }