| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- #ifndef FILE_H
- #define FILE_H
- #include <stdint.h>
- #define CONCAT(a, b) CONCAT_INNER(a, b)
- #define CONCAT_INNER(a, b) a ## b
- #define UNIQUE_NAME(base) CONCAT(base, __COUNTER__)
- enum file_err {
- FILE_ERR_OK,
- FILE_ERR_FAIL_OPEN,
- FILE_ERR_FAIL_SEEK,
- FILE_ERR_FAIL_READ,
- FILE_ERR_FAIL_WRITE,
- FILE_ERR_FAIL_CALLOC,
- FILE_ERR_FAIL_CLOSE,
- FILE_ERR_FILE_EMPTY,
- FILE_ERR_FAIL_WROTE_MORE,
- FILE_ERR_EMPTY,
- };
- struct ret_void_p_err {
- void *f1; /* ptr */
- size_t f2; /* size */
- enum file_err f3; /* err */
- };
- struct ret_void_p_err file_read_all(const char *filepath);
- enum file_err file_save(const char *filepath, const char *str, size_t str_size);
- #if defined(BMP_IMP) || defined(IMP)
- #include <unistd.h>
- #include <fcntl.h>
- struct ret_void_p_err
- file_read_all(const char *filepath)
- {
- enum file_err err = FILE_ERR_OK;
- int32_t fd = open(filepath, O_RDONLY);
- if ( fd < 0 ) {
- err = FILE_ERR_FAIL_OPEN;
- goto err;
- }
- off_t file_size = lseek(fd, 0, SEEK_END);
- if ( file_size < 0 ) {
- err = FILE_ERR_FAIL_SEEK;
- goto err_close;
- }
- lseek(fd, 0, SEEK_SET);
- printf("file->size = %ld\n", file_size);
- if ( file_size == 0 ) {
- err = FILE_ERR_EMPTY;
- goto err_close;
- }
- const size_t buf_size = ((size_t)file_size) + 1;
- uint8_t *buf = calloc(sizeof(uint8_t), buf_size);
- if ( buf == NULL ) {
- err = FILE_ERR_FAIL_CALLOC;
- goto err_close;
- }
- {
- ssize_t rd = read(fd, buf, (size_t)file_size);
- if ( rd < 0 ) {
- err = FILE_ERR_FAIL_READ;
- free(buf);
- goto err_close;
- }
- if ( rd == 0 ) {
- err = FILE_ERR_FILE_EMPTY;
- free(buf);
- goto err_close;
- }
- }
- if ( close(fd) != 0 ) {
- /* It should be possible to handle EIO */
- err = FILE_ERR_FAIL_CLOSE;
- goto err;
- }
- return (struct ret_void_p_err) {
- .f1 = buf,
- .f2 = buf_size,
- .f3 = err
- };
- err_close: ;
- if ( close(fd) != 0 ) {
- /* It should be possible to handle EIO */
- err = FILE_ERR_FAIL_CLOSE;
- goto err;
- }
- err: ;
- return (struct ret_void_p_err) {
- .f1 = NULL,
- .f2 = 0,
- .f3 = err
- };
- }
- enum file_err
- file_save(const char *filepath, const char *str, size_t str_size)
- {
- int32_t fd = open(filepath, O_WRONLY);
- if ( fd < 0 ) {
- return FILE_ERR_FAIL_OPEN;
- }
- ssize_t wrote = write(fd, str, str_size);
- if ( wrote == -1 ) {
- return FILE_ERR_FAIL_WRITE;
- }
- if ( ((size_t) wrote) != str_size ) {
- return FILE_ERR_FAIL_WROTE_MORE;
- }
- if ( close(fd) != 0 ) {
- /* It should be possible to handle EIO */
- return FILE_ERR_FAIL_CLOSE;
- }
- return FILE_ERR_OK;
- }
- #endif
- #endif
|