diff options
Diffstat (limited to 'src/file_win.c')
| -rw-r--r-- | src/file_win.c | 108 |
1 files changed, 92 insertions, 16 deletions
diff --git a/src/file_win.c b/src/file_win.c index e31e0de..15d2a61 100644 --- a/src/file_win.c +++ b/src/file_win.c @@ -19,9 +19,11 @@ bh_file_t *bh_file_new(const char *path) { bh_file_t *result; + /* Allocate and initialize file object */ result = malloc(sizeof(*result)); if (result && bh_file_init(result, path)) { + /* Something went wrong - free the file object */ free(result); result = NULL; } @@ -31,6 +33,7 @@ bh_file_t *bh_file_new(const char *path) void bh_file_free(bh_file_t *file) { + /* Destroy file object and free allocated memory */ bh_file_destroy(file); free(file); } @@ -38,38 +41,50 @@ void bh_file_free(bh_file_t *file) int bh_file_init(bh_file_t *file, const char *path) { + /* Check if path is not empty */ if (!path) return BH_INVALID; + /* Fill file structure information */ file->handle = INVALID_HANDLE_VALUE; - file->mode = 0; + file->mode = BH_IO_NONE; file->path = strdup(path); file->base.table = &bh_file_table; return BH_OK; } +void bh_file_destroy(bh_file_t *file) +{ + /* Close the file and free allocated memory */ + bh_file_close(file); + free(file->path); +} + int bh_file_open_base(bh_file_t *file, int mode) { DWORD access = 0, how = 0; + /* Check if file is already openned */ + if (file->handle != INVALID_HANDLE_VALUE) + return BH_OK; + + /* Determine read/write access flags */ if (mode & BH_IO_READ) access |= GENERIC_READ; if (mode & BH_IO_WRITE) access |= GENERIC_WRITE; - switch (mode & BH_IO_MASK) + /* Determine open mode flags */ + switch (mode & (BH_IO_CREATE | BH_IO_OPEN)) { + case 0: how = OPEN_ALWAYS; break; + case BH_IO_CREATE: how = CREATE_NEW; break; case BH_IO_OPEN: how = OPEN_EXISTING; break; - case BH_IO_CREATE: how = CREATE_ALWAYS; break; - case BH_IO_APPEND: how = OPEN_ALWAYS; break; - - default: - case BH_IO_TRUNCATE: - return BH_NO_IMPL; } + /* Save mode that we are in and open file */ file->mode = mode; file->handle = CreateFileA(file->path, access, FILE_SHARE_READ, NULL, how, FILE_ATTRIBUTE_NORMAL, NULL); @@ -84,27 +99,30 @@ int bh_file_open_base(bh_file_t *file, } } + /* Truncate file if needed */ + if (mode & BH_IO_TRUNCATE) + SetEndOfFile(file->handle); + return BH_OK; } void bh_file_close_base(bh_file_t *file) { + /* If file is opened - close it */ if (file->handle != INVALID_HANDLE_VALUE) CloseHandle(file->handle); + /* Reset handle and mode values */ file->handle = INVALID_HANDLE_VALUE; + file->mode = BH_IO_NONE; } int bh_file_is_open_base(bh_file_t *file) { + /* If handle is not INVALID_HANDLE_VALUE - file is open */ return file->handle != INVALID_HANDLE_VALUE; } -void bh_file_destroy(bh_file_t *file) -{ - bh_file_close(file); - free(file->path); -} size_t bh_file_read_base(bh_file_t *file, char *data, @@ -112,17 +130,27 @@ size_t bh_file_read_base(bh_file_t *file, { DWORD readed; + /* Check if file is opened */ + if (file->handle == INVALID_HANDLE_VALUE) + { + file->base.flags |= BH_IO_ERROR; + return 0; + } + + /* Read data from the file */ if (!ReadFile(file->handle, data, (DWORD)size, &readed, NULL)) { file->base.flags |= BH_IO_ERROR; return 0; } + /* Check if we reached end of file */ if (!readed) file->base.flags |= BH_IO_EOF; else file->base.flags &= ~BH_IO_EOF; + /* Return readed bytes */ return readed; } @@ -132,25 +160,44 @@ size_t bh_file_write_base(bh_file_t *file, { DWORD written; - if ((file->mode & BH_IO_MASK) == BH_IO_APPEND) + /* Check if file is opened */ + if (file->handle == INVALID_HANDLE_VALUE) + { + file->base.flags |= BH_IO_ERROR; + return 0; + } + + /* Adjust current position in the file to the end */ + if (file->mode & BH_IO_APPEND) bh_file_seek(file, 0, BH_IO_END); + /* Write data to the file */ if (!WriteFile(file->handle, data, (DWORD)size, &written, NULL)) { file->base.flags |= BH_IO_ERROR; return 0; } + /* Check for end of file */ if (!written) file->base.flags |= BH_IO_EOF; else file->base.flags &= ~BH_IO_EOF; + /* Write amount of bytes written */ return written; } void bh_file_flush_base(bh_file_t *file) { + /* Check if file is opened */ + if (file->handle == INVALID_HANDLE_VALUE) + { + file->base.flags |= BH_IO_ERROR; + return; + } + + /* Flush OS buffers */ FlushFileBuffers(file->handle); } @@ -160,6 +207,14 @@ int bh_file_seek_base(bh_file_t *file, { LARGE_INTEGER position; + /* Check if file is opened */ + if (file->handle == INVALID_HANDLE_VALUE) + { + file->base.flags |= BH_IO_ERROR; + return BH_ERROR; + } + + /* Set read/write position in the file */ position.QuadPart = pos; if (SetFilePointerEx(file->handle, position, NULL, dir)) return BH_OK; @@ -169,6 +224,19 @@ int bh_file_seek_base(bh_file_t *file, bh_off_t bh_file_size_base(bh_file_t *file) { + LARGE_INTEGER size; + + /* Check if file is opened */ + if (file->handle == INVALID_HANDLE_VALUE) + { + file->base.flags |= BH_IO_ERROR; + return -1; + } + + /* Get current file size */ + if (GetFileSizeEx(file->handle, &size)) + return size.QuadPart; + return -1; } @@ -176,8 +244,15 @@ bh_off_t bh_file_tell_base(bh_file_t *file) { LARGE_INTEGER dummy, position; - dummy.QuadPart = 0; + /* Check if file is opened */ + if (file->handle == INVALID_HANDLE_VALUE) + { + file->base.flags |= BH_IO_ERROR; + return -1; + } + /* Readback current position in the file */ + dummy.QuadPart = 0; if (SetFilePointerEx(file->handle, dummy, &position, BH_IO_CURRENT)) return position.QuadPart; @@ -186,7 +261,8 @@ bh_off_t bh_file_tell_base(bh_file_t *file) bh_off_t bh_file_available_base(bh_file_t *file) { - return 0; + /* Get available bytes for reading */ + return bh_file_size_base(file) - bh_file_tell_base(file); } void bh_file_clear_base(bh_file_t *file) |
