diff options
Diffstat (limited to 'src/Platform/Win32/File.c')
| -rw-r--r-- | src/Platform/Win32/File.c | 370 |
1 files changed, 141 insertions, 229 deletions
diff --git a/src/Platform/Win32/File.c b/src/Platform/Win32/File.c index 3cb1972..05a0d56 100644 --- a/src/Platform/Win32/File.c +++ b/src/Platform/Win32/File.c @@ -6,195 +6,87 @@ typedef struct BH_File { - char *path; - int mode; + BH_IO parent; int flags; + int mode; HANDLE handle; } BH_File; -static int BH_FileInfo(BH_File *file, - size_t *size, - const char **name); - - -static int BH_FileInit(BH_File *file, - const char *path); - - -static int BH_FileDestroy(BH_File *file); - - -static int BH_FileOpen(BH_File *file, - int *mode); - - -static int BH_FileClose(BH_File *file); - - -static int BH_FileRead(BH_File *file, - char *data, - size_t *size); - - -static int BH_FileWrite(BH_File *file, - const char *data, - size_t *size); - - -static int BH_FilePeek(BH_File* file, - char *data, - size_t *size); - - -static int BH_FileFlush(BH_File *file); - - -static int BH_FileSeek(BH_File *file, - int64_t *pos, - int *dir); - - -static int BH_FileTell(BH_File *file, - int64_t *pos); - - -static int BH_FileSize(BH_File *file, - int64_t *size); - - -static int BH_FileFlags(BH_File *file); - - -static int BH_FileClear(BH_File *file); - - -static int BH_FileInfo(BH_File *file, - size_t *size, - const char **name) +static int fileInit(BH_File *file, + const char *path, + int mode) { - static const char classname[] = BH_FILE_CLASSNAME; - - if (size) - *size = sizeof(*file); - if (name) - *name = classname; - - return BH_OK; -} - + DWORD access = 0, how = 0; -static int BH_FileInit(BH_File *file, - const char *path) -{ /* Check if path is valid */ if (!path) return BH_ERROR; - /* Duplicate path string and initialize the file struct */ - file->path = strdup(path); - file->mode = 0; - file->handle = INVALID_HANDLE_VALUE; - file->flags = 0; - - return BH_OK; -} - - -static int BH_FileDestroy(BH_File *file) -{ - /* Close the file handle on destruction */ - if (file->handle != INVALID_HANDLE_VALUE) - BH_FileClose(file); - - /* Free path string */ - free(file->path); - - return BH_OK; -} - - -static int BH_FileOpen(BH_File *file, - int *mode) -{ - DWORD access = 0, how = 0; - - /* Check if file is already openned */ - if (file->handle != INVALID_HANDLE_VALUE) - return BH_ERROR; - /* Determine read/write access flags */ - if (*mode & BH_IO_READ) + if (mode & BH_FILE_READ) access |= GENERIC_READ; - if (*mode & BH_IO_WRITE) + if (mode & BH_FILE_WRITE) access |= GENERIC_WRITE; if (!access) return BH_ERROR; /* Determine open mode flags */ - if (*mode & BH_IO_TRUNCATE) + if (mode & BH_FILE_TRUNCATE) { - switch (*mode & (BH_IO_CREATE | BH_IO_EXIST)) + switch (mode & (BH_FILE_CREATE | BH_FILE_EXIST)) { - case 0: how = CREATE_ALWAYS; break; - case BH_IO_CREATE: how = CREATE_NEW; break; - case BH_IO_EXIST: how = TRUNCATE_EXISTING; break; - default: return BH_ERROR; + case 0: how = CREATE_ALWAYS; break; + case BH_FILE_CREATE: how = CREATE_NEW; break; + case BH_FILE_EXIST: how = TRUNCATE_EXISTING; break; + default: return BH_ERROR; } } else { - switch (*mode & (BH_IO_CREATE | BH_IO_EXIST)) + switch (mode & (BH_FILE_CREATE | BH_FILE_EXIST)) { - case 0: how = OPEN_ALWAYS; break; - case BH_IO_CREATE: how = CREATE_NEW; break; - case BH_IO_EXIST: how = OPEN_EXISTING; break; - default: return BH_ERROR; + case 0: how = OPEN_ALWAYS; break; + case BH_FILE_CREATE: how = CREATE_NEW; break; + case BH_FILE_EXIST: how = OPEN_EXISTING; break; + default: return BH_ERROR; } } /* 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); + file->flags = 0; + file->mode = mode; + file->handle = CreateFileA(path, access, FILE_SHARE_READ, NULL, how, FILE_ATTRIBUTE_NORMAL, NULL); if (file->handle == INVALID_HANDLE_VALUE) return BH_ERROR; /* Truncate file if needed */ - if (*mode & BH_IO_TRUNCATE) + if (mode & BH_FILE_TRUNCATE) SetEndOfFile(file->handle); return BH_OK; } -static int BH_FileClose(BH_File *file) +static int fileDestroy(BH_File *file) { - /* If file is opened - close it */ - if (file->handle == INVALID_HANDLE_VALUE) - return BH_ERROR; - - /* Reset handle and mode values */ + /* Close the file handle on destruction */ CloseHandle(file->handle); - file->handle = INVALID_HANDLE_VALUE; - file->mode = 0; + free(file); + return BH_OK; } -static int BH_FileRead(BH_File *file, - char *data, - size_t *size) +static int fileRead(BH_File *file, + BH_IOReadInfo *info) { DWORD readed; - /* Check if file is opened */ - if (file->handle == INVALID_HANDLE_VALUE) - goto error; - /* Read data from the file */ - if (!ReadFile(file->handle, data, (DWORD)*size, &readed, NULL)) + if (!ReadFile(file->handle, info->data, (DWORD)info->size, &readed, NULL)) goto error; /* Check if we reached end of file */ @@ -203,7 +95,9 @@ static int BH_FileRead(BH_File *file, else file->flags &= ~BH_IO_FLAG_EOF; - *size = readed; + if (info->actual) + *info->actual = readed; + return BH_OK; error: @@ -212,28 +106,22 @@ error: } -static int BH_FileWrite(BH_File *file, - const char *data, - size_t *size) +static int fileWrite(BH_File *file, + BH_IOWriteInfo *info) { DWORD written; - - /* Check if file is opened */ - if (file->handle == INVALID_HANDLE_VALUE) - goto error; + LARGE_INTEGER position; /* Adjust current position in the file to the end */ - if (file->mode & BH_IO_APPEND) + if (file->mode & BH_FILE_APPEND) { - LARGE_INTEGER position; - position.QuadPart = 0; if (!SetFilePointerEx(file->handle, position, NULL, FILE_END)) goto error; } /* Write data to the file */ - if (!WriteFile(file->handle, data, (DWORD)*size, &written, NULL)) + if (!WriteFile(file->handle, info->data, (DWORD)info->size, &written, NULL)) goto error; /* Check for end of file */ @@ -242,7 +130,9 @@ static int BH_FileWrite(BH_File *file, else file->flags &= ~BH_IO_FLAG_EOF; - *size = written; + if (info->actual) + *info->actual = written; + return BH_OK; error: @@ -251,56 +141,22 @@ error: } -static int BH_FilePeek(BH_File *file, - char *data, - size_t *size) -{ - int64_t position; - int direction; - - /* Read data from the file */ - if (BH_FileRead(file, data, size)) - return BH_ERROR; - - /* Backtrack by the read amount */ - position = -((int64_t)*size); - direction = BH_IO_SEEK_CUR; - if (BH_FileSeek(file, &position, &direction)) - return BH_ERROR; - - return BH_OK; -} - - -static int BH_FileFlush(BH_File *file) +static int fileFlush(BH_File *file) { - /* Check if file is opened */ - if (file->handle == INVALID_HANDLE_VALUE) - goto error; - /* Flush OS buffers */ FlushFileBuffers(file->handle); return BH_OK; - -error: - file->flags |= BH_IO_FLAG_ERROR; - return BH_ERROR; } -static int BH_FileSeek(BH_File *file, - int64_t *pos, - int *dir) +static int fileSeek(BH_File *file, + BH_IOSeekInfo *info) { LARGE_INTEGER position; - /* Check if file is opened */ - if (file->handle == INVALID_HANDLE_VALUE) - goto error; - /* Set read/write position in the file */ - position.QuadPart = *pos; - if (!SetFilePointerEx(file->handle, position, NULL, *dir)) + position.QuadPart = info->offset; + if (!SetFilePointerEx(file->handle, position, NULL, info->whence)) goto error; return BH_OK; @@ -311,15 +167,11 @@ error: } -static int BH_FileTell(BH_File *file, - int64_t *pos) +static int fileTell(BH_File *file, + int64_t *pos) { LARGE_INTEGER dummy, position; - /* Check if file is opened */ - if (file->handle == INVALID_HANDLE_VALUE) - goto error; - /* Readback current position in the file */ dummy.QuadPart = 0; if (!SetFilePointerEx(file->handle, dummy, &position, BH_IO_SEEK_CUR)) @@ -334,15 +186,11 @@ error: } -static int BH_FileSize(BH_File *file, - int64_t *size) +static int fileSize(BH_File *file, + int64_t *size) { LARGE_INTEGER dummy; - /* Check if file is opened */ - if (file->handle == INVALID_HANDLE_VALUE) - goto error; - /* Get current file size */ if (!GetFileSizeEx(file->handle, &dummy)) goto error; @@ -356,50 +204,114 @@ error: } -static int BH_FileFlags(BH_File *file) +static int fileFlags(BH_File *file, + int *flags) { - /* If file handle is valid - append IO_OPEN flag */ - if (file->handle != INVALID_HANDLE_VALUE) - return file->flags | BH_IO_FLAG_OPEN; - return file->flags; + *flags = file->flags; + return BH_OK; } -static int BH_FileClear(BH_File *file) +static int fileClear(BH_File *file) { - /* Clear IO_ERROR flag */ + /* Clear BH_IO_FLAG_ERROR flag */ file->flags &= ~BH_IO_FLAG_ERROR; return BH_OK; } -static int BH_FileCallback(BH_File *file, - int type, - void *arg1, - void *arg2) +static int fileCap(BH_File *file, + int *op) +{ + BH_UNUSED(file); + + /* Return operations supported by the file input/output device */ + switch (*op) + { + case BH_IO_CTL_FLAGS: + case BH_IO_CTL_CLEAR: + case BH_IO_CTL_FLUSH: + case BH_IO_CTL_SIZE: + case BH_IO_CTL_TELL: + case BH_IO_CTL_SEEK: + return BH_OK; + + default: + return BH_NOIMPL; + } +} + + +static int fileCtl(BH_File *file, + BH_IOCtlInfo *info) { + /* Handle supported operations */ + switch (info->op) + { + case BH_IO_CTL_FLAGS: + return fileFlags(file, (int *)(info->arg)); + + case BH_IO_CTL_CLEAR: + return fileClear(file); + + case BH_IO_CTL_FLUSH: + return fileFlush(file); + + case BH_IO_CTL_SIZE: + return fileSize(file, (int64_t *)(info->arg)); + + case BH_IO_CTL_TELL: + return fileTell(file, (int64_t *)(info->arg)); + + case BH_IO_CTL_SEEK: + return fileSeek(file, (BH_IOSeekInfo *)(info->arg)); + + default: + return BH_NOIMPL; + } +} + + +static int fileCallback(BH_File *file, + int type, + void *arg) +{ + /* Handle basic input/output operations */ switch (type) { - case BH_IO_INFO_CB: return BH_FileInfo(file, (size_t *)arg1, (const char **)arg2); - case BH_IO_INIT_CB: return BH_FileInit(file, (const char *)arg1); - case BH_IO_DESTROY_CB: return BH_FileDestroy(file); - case BH_IO_OPEN_CB: return BH_FileOpen(file, (int *)arg1); - case BH_IO_CLOSE_CB: return BH_FileClose(file); - case BH_IO_READ_CB: return BH_FileRead(file, (char *)arg1, (size_t *)arg2); - case BH_IO_WRITE_CB: return BH_FileWrite(file, (const char *)arg1, (size_t *)arg2); - case BH_IO_PEEK_CB: return BH_FilePeek(file, (char *)arg1, (size_t *)arg2); - case BH_IO_FLUSH_CB: return BH_FileFlush(file); - case BH_IO_SEEK_CB: return BH_FileSeek(file, (int64_t *)arg1, (int *)arg2); - case BH_IO_TELL_CB: return BH_FileTell(file, (int64_t *)arg1); - case BH_IO_SIZE_CB: return BH_FileSize(file, (int64_t *)arg1); - case BH_IO_FLAGS_CB: return BH_FileFlags(file); - case BH_IO_CLEAR_CB: return BH_FileClear(file); + case BH_IO_OP_DESTROY: return fileDestroy(file); + case BH_IO_OP_READ: return fileRead(file, (BH_IOReadInfo *)arg); + case BH_IO_OP_WRITE: return fileWrite(file, (BH_IOWriteInfo *)arg); + case BH_IO_OP_CTL: return fileCtl(file, (BH_IOCtlInfo *)arg); + case BH_IO_OP_CAP: return fileCap(file, (int*)arg); default: return BH_NOIMPL; } } -BH_IO *BH_FileNew(const char *path) +BH_IO *BH_FileNew(const char *path, + int mode, + int *result) { - return BH_IONew((BH_IOCallback)BH_FileCallback, (void *)path); + BH_File *file; + int code; + + code = BH_OOM; + + /* Allocate new file object and initialize it */ + if ((file = malloc(sizeof(*file)))) + { + file->parent.callback = (BH_IOCallback)fileCallback; + if ((code = fileInit(file, path, mode))) + { + free(file); + file = NULL; + } + } + + /* Report error code */ + if (result) + *result = code; + + return (BH_IO*)file; } |
