Implement POSIX file IO

This commit is contained in:
2026-01-02 22:57:12 +00:00
parent a07f05d1a3
commit c2ca99cac4
8 changed files with 274 additions and 136 deletions

View File

@@ -6,160 +6,72 @@
#include "../../common/aliases/aliases.h"
#include "../../base/array/array.h"
#include "../../base/strings/str8/str8.h"
#include <stdio.h>
WFile *wapp_file_open(Str8RO *filepath, FileAccessMode mode) {
wapp_debug_assert(filepath != NULL, "`filepath` should not be NULL");
wapp_persist const char *modes[FILE_ACCESS_MODE_COUNT] = {
[WAPP_FA_MODE_R] = "r",
[WAPP_FA_MODE_W] = "w",
[WAPP_FA_MODE_A] = "a",
[WAPP_FA_MODE_R_EX] = "r+",
[WAPP_FA_MODE_W_EX] = "w+",
[WAPP_FA_MODE_A_EX] = "a+",
[WAPP_FA_MODE_RB] = "rb",
[WAPP_FA_MODE_WB] = "wb",
[WAPP_FA_MODE_AB] = "ab",
[WAPP_FA_MODE_RB_EX] = "rb+",
[WAPP_FA_MODE_WB_EX] = "wb+",
[WAPP_FA_MODE_AB_EX] = "ab+",
[WAPP_FA_MODE_WX] = "wx",
[WAPP_FA_MODE_WX_EX] = "wx+",
[WAPP_FA_MODE_WBX] = "wbx",
[WAPP_FA_MODE_WBX_EX] = "wbx+",
};
wapp_persist c8 tmp[WAPP_PATH_MAX] = {0};
WFile *wapp_file_open(const Allocator *allocator, Str8RO *filepath, FileAccessMode mode) {
wapp_debug_assert(allocator != NULL && filepath != NULL, "`allocator` and `filepath` should not be NULL");
wapp_debug_assert(filepath->size < WAPP_PATH_MAX, "`filepath` exceeds max path limit.");
memset(tmp, 0, WAPP_PATH_MAX);
memcpy(tmp, filepath->buf, filepath->size);
return fopen((const char *)tmp, modes[mode]);
return _file_open(allocator, filepath, mode);
}
i64 wapp_file_get_current_position(WFile *file) {
wapp_debug_assert(file != NULL, "`file` should not be NULL.");
return ftell(file);
return _file_get_current_position(file);
}
i32 wapp_file_seek(WFile *file, u64 offset, FileSeekOrigin origin) {
i64 wapp_file_seek(WFile *file, i64 offset, FileSeekOrigin origin) {
wapp_debug_assert(file != NULL, "`file` should not be NULL.");
// TODO (Abdelrahman): Revisit conversion to long
return fseek(file, (long)offset, origin);
return _file_seek(file, offset, origin);
}
i64 wapp_file_get_length(WFile *file) {
wapp_debug_assert(file != NULL, "`file` should not be NULL.");
i64 current = wapp_file_get_current_position(file);
wapp_file_seek(file, 0, WAPP_SEEK_END);
i64 output = wapp_file_get_current_position(file);
// Restore position
wapp_file_seek(file, current, WAPP_SEEK_START);
return output;
return _file_get_length(file);
}
u64 wapp_file_read(void *dst_buf, WFile *file, u64 byte_count) {
wapp_debug_assert(dst_buf != NULL && file != NULL,
"`dst_buf` and `file` should not be NULL.");
u64 file_length = wapp_file_get_length(file);
u64 copy_byte_count = file_length <= byte_count ? file_length : byte_count;
u64 count = fread(dst_buf, sizeof(u8), copy_byte_count, file);
if (ferror(file)) { return 0; }
return count;
return _file_read(dst_buf, file, byte_count);
}
u64 wapp_file_write(const void *src_buf, WFile *file, u64 byte_count) {
i64 wapp_file_write(const void *src_buf, WFile *file, u64 byte_count) {
wapp_debug_assert(src_buf != NULL && file != NULL,
"`src_buf` and `file` should not be NULL.");
return fwrite(src_buf, sizeof(u8), byte_count, file);
return _file_write(src_buf, file, byte_count);
}
u64 wapp_file_read_array(GenericArray dst_buf, WFile *file, u64 item_count) {
wapp_debug_assert(dst_buf != NULL && file != NULL,
"`dst_buf` and `file` should not be NULL.");
u64 file_length = wapp_file_get_length(file);
u64 item_size = wapp_array_item_size(dst_buf);
u64 dst_byte_capacity = wapp_array_capacity(dst_buf) * item_size;
u64 req_byte_count = item_count * item_size;
u64 copy_byte_count = 0;
if (req_byte_count <= file_length && req_byte_count <= dst_byte_capacity) {
copy_byte_count = req_byte_count;
} else {
copy_byte_count = file_length <= dst_byte_capacity ? file_length : dst_byte_capacity;
}
u64 byte_count = wapp_file_read(dst_buf, file, copy_byte_count);
if (byte_count == 0) {
return 0;
}
wapp_array_set_count(dst_buf, byte_count / item_size);
return wapp_array_count(dst_buf);
return _file_read_array(dst_buf, file, item_count);
}
u64 wapp_file_write_array(const GenericArray src_buf, WFile *file, u64 item_count) {
i64 wapp_file_write_array(const GenericArray src_buf, WFile *file, u64 item_count) {
wapp_debug_assert(src_buf != NULL && file != NULL,
"`src_buf` and `file` should not be NULL.");
u64 item_size = wapp_array_item_size(src_buf);
u64 src_byte_count = wapp_array_count(src_buf) * item_size;
u64 req_byte_count = item_count * item_size;
u64 to_copy = req_byte_count <= src_byte_count ? req_byte_count : src_byte_count;
u64 byte_count = wapp_file_write(src_buf, file, to_copy);
return byte_count / item_size;
return _file_write_array(src_buf, file, item_count);
}
i32 wapp_file_flush(WFile *file) {
wapp_debug_assert(file != NULL, "`file` should not be NULL.");
return fflush(file);
return _file_flush(file);
}
i32 wapp_file_close(WFile *file) {
wapp_debug_assert(file != NULL, "`file` should not be NULL.");
return fclose(file);
return _file_close(file);
}
i32 wapp_file_rename(Str8RO *old_filepath, Str8RO *new_filepath) {
wapp_debug_assert(old_filepath != NULL && new_filepath != NULL,
"`old_filepath` and `new_filepath` should not be NULL");
wapp_persist c8 old_tmp[WAPP_PATH_MAX] = {0};
wapp_debug_assert(old_filepath->size < WAPP_PATH_MAX, "`old_filepath` exceeds max path limit.");
wapp_persist c8 new_tmp[WAPP_PATH_MAX] = {0};
wapp_debug_assert(new_filepath->size < WAPP_PATH_MAX, "`new_filepath` exceeds max path limit.");
memset(old_tmp, 0, WAPP_PATH_MAX);
memcpy(old_tmp, old_filepath->buf, old_filepath->size);
memset(new_tmp, 0, WAPP_PATH_MAX);
memcpy(new_tmp, new_filepath->buf, new_filepath->size);
return rename((const char *)old_tmp, (const char *)new_tmp);
return _file_rename(old_filepath, new_filepath);
}
i32 wapp_file_remove(Str8RO *filepath) {
wapp_debug_assert(filepath != NULL, "`filepath` should not be NULL");
wapp_persist c8 tmp[WAPP_PATH_MAX] = {0};
wapp_debug_assert(filepath->size < WAPP_PATH_MAX, "`filepath` exceeds max path limit.");
memset(tmp, 0, WAPP_PATH_MAX);
memcpy(tmp, filepath->buf, filepath->size);
return remove((const char *)tmp);
return _file_remove(filepath);
}