aboutsummaryrefslogtreecommitdiff
path: root/src/Platform/Win32/File.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Platform/Win32/File.c')
-rw-r--r--src/Platform/Win32/File.c370
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;
}