// vim:fileencoding=utf-8:foldmethod=marker #include "file_win.h" #include "../../../common/platform/platform.h" #ifdef WAPP_PLATFORM_WINDOWS #include "../file.h" #include "../../cpath/cpath.h" #include "../../../common/aliases/aliases.h" #include "../../../base/array/array.h" #include "../../../base/strings/str8/str8.h" #define WIN32_LEAN_AND_MEAN #include #include #include wapp_intern DWORD file_accesses[FILE_ACCESS_MODE_COUNT] = { [WAPP_ACCESS_READ] = FILE_READ_DATA, [WAPP_ACCESS_WRITE] = FILE_WRITE_DATA, [WAPP_ACCESS_APPEND] = FILE_APPEND_DATA, [WAPP_ACCESS_READ_EX] = FILE_READ_DATA | FILE_WRITE_DATA, [WAPP_ACCESS_WRITE_EX] = FILE_READ_DATA | FILE_WRITE_DATA, [WAPP_ACCESS_APPEND_EX] = FILE_READ_DATA | FILE_APPEND_DATA, [WAPP_ACCESS_WRITE_FAIL_ON_EXIST] = FILE_WRITE_DATA, [WAPP_ACCESS_WRITE_FAIL_ON_EXIST_EX] = FILE_READ_DATA | FILE_WRITE_DATA, }; wapp_intern DWORD creation_dispositions[FILE_ACCESS_MODE_COUNT] = { [WAPP_ACCESS_READ] = OPEN_EXISTING, [WAPP_ACCESS_WRITE] = CREATE_ALWAYS, [WAPP_ACCESS_APPEND] = OPEN_ALWAYS, [WAPP_ACCESS_READ_EX] = OPEN_EXISTING, [WAPP_ACCESS_WRITE_EX] = CREATE_ALWAYS, [WAPP_ACCESS_APPEND_EX] = OPEN_ALWAYS, [WAPP_ACCESS_WRITE_FAIL_ON_EXIST] = CREATE_NEW, [WAPP_ACCESS_WRITE_FAIL_ON_EXIST_EX] = CREATE_NEW, }; wapp_intern DWORD sharing_modes[FILE_ACCESS_MODE_COUNT] = { [WAPP_ACCESS_READ] = FILE_SHARE_READ | FILE_SHARE_WRITE, [WAPP_ACCESS_WRITE] = FILE_SHARE_READ, [WAPP_ACCESS_APPEND] = FILE_SHARE_READ, [WAPP_ACCESS_READ_EX] = FILE_SHARE_READ | FILE_SHARE_WRITE, [WAPP_ACCESS_WRITE_EX] = FILE_SHARE_READ, [WAPP_ACCESS_APPEND_EX] = FILE_SHARE_READ, [WAPP_ACCESS_WRITE_FAIL_ON_EXIST] = FILE_SHARE_READ, [WAPP_ACCESS_WRITE_FAIL_ON_EXIST_EX] = FILE_SHARE_READ, }; wapp_intern DWORD file_seek_origins[FILE_SEEK_ORIGIN_COUNT] = { [WAPP_SEEK_START] = FILE_BEGIN, [WAPP_SEEK_CURRENT] = FILE_CURRENT, [WAPP_SEEK_END] = FILE_END, }; WFile *_file_open(const Allocator *allocator, Str8RO *filepath, FileAccessMode mode) { wapp_persist c8 tmp[WAPP_PATH_MAX] = {0}; memset(tmp, 0, WAPP_PATH_MAX); memcpy(tmp, filepath->buf, filepath->size); HANDLE fh = CreateFileA((LPCSTR)tmp, file_accesses[mode], sharing_modes[mode], NULL, creation_dispositions[mode], FILE_ATTRIBUTE_NORMAL, NULL); if (fh == INVALID_HANDLE_VALUE) { return NULL; } WFile *output = wapp_mem_allocator_alloc(allocator, sizeof(WFile)); if (output) { output->fh = fh; } return output; } i64 _file_seek(WFile *file, i64 offset, FileSeekOrigin origin) { LARGE_INTEGER distance = {0}; LARGE_INTEGER output = {0}; distance.QuadPart = offset; if (!SetFilePointerEx(file->fh, distance, &output, file_seek_origins[origin])) { return -1; } return output.QuadPart; } u64 _file_read(void* dst_buf, u64 byte_count, WFile* file, u64 file_length) { u64 copy_byte_count = file_length <= byte_count ? file_length : byte_count; wapp_debug_assert(copy_byte_count <= DWORD_MAX, "Attempting to read large number of bytes at once"); DWORD read_count = 0; if (!ReadFile(file->fh, dst_buf, (DWORD)copy_byte_count, &read_count, NULL)) { return 0; } return (u64)read_count; } i64 _file_write(const void *src_buf, WFile *file, u64 byte_count) { wapp_debug_assert(byte_count <= DWORD_MAX, "Attempting to write large number of bytes at once"); DWORD write_count = 0; if (!WriteFile(file->fh, src_buf, (DWORD)byte_count, &write_count, NULL)) { return 0; } return (i64)write_count; } i32 _file_flush(WFile *file) { if (!FlushFileBuffers(file->fh)) { return -1; } return 0; } i32 _file_close(WFile *file) { if (!CloseHandle(file->fh)) { return -1; } return 0; } i32 _file_rename(Str8RO *old_filepath, Str8RO *new_filepath) { wapp_persist c8 old_tmp[WAPP_PATH_MAX] = {0}; wapp_persist c8 new_tmp[WAPP_PATH_MAX] = {0}; 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); if (!MoveFile((LPCSTR)old_tmp, (LPCSTR)new_tmp)) { return -1; } return 0; } i32 _file_remove(Str8RO *filepath) { wapp_persist c8 tmp[WAPP_PATH_MAX] = {0}; memset(tmp, 0, WAPP_PATH_MAX); memcpy(tmp, filepath->buf, filepath->size); if (!DeleteFile((LPCSTR)tmp)) { return -1; } return 0; } #endif // !WAPP_PLATFORM_WINDOWS