226 lines
5.2 KiB
C
226 lines
5.2 KiB
C
/************************************************************/ /**
|
|
*
|
|
* @file: platform_io.h
|
|
* @author: Martin Fouilleul
|
|
* @date: 25/05/2023
|
|
*
|
|
*****************************************************************/
|
|
#ifndef __PLATFORM_IO_H_
|
|
#define __PLATFORM_IO_H_
|
|
|
|
#include "util/strings.h"
|
|
#include "util/typedefs.h"
|
|
|
|
//----------------------------------------------------------------
|
|
// IO API
|
|
//----------------------------------------------------------------
|
|
|
|
typedef struct
|
|
{
|
|
u64 h;
|
|
} oc_file;
|
|
|
|
typedef u16 oc_file_open_flags;
|
|
|
|
enum oc_file_open_flags_enum
|
|
{
|
|
OC_FILE_OPEN_NONE = 0,
|
|
OC_FILE_OPEN_APPEND = 1 << 1,
|
|
OC_FILE_OPEN_TRUNCATE = 1 << 2,
|
|
OC_FILE_OPEN_CREATE = 1 << 3,
|
|
|
|
OC_FILE_OPEN_SYMLINK = 1 << 4,
|
|
OC_FILE_OPEN_NO_FOLLOW = 1 << 5,
|
|
OC_FILE_OPEN_RESTRICT = 1 << 6,
|
|
//...
|
|
};
|
|
|
|
typedef u16 oc_file_access;
|
|
|
|
enum oc_file_access_enum
|
|
{
|
|
OC_FILE_ACCESS_NONE = 0,
|
|
OC_FILE_ACCESS_READ = 1 << 1,
|
|
OC_FILE_ACCESS_WRITE = 1 << 2,
|
|
};
|
|
|
|
typedef enum
|
|
{
|
|
OC_FILE_SEEK_SET,
|
|
OC_FILE_SEEK_END,
|
|
OC_FILE_SEEK_CURRENT
|
|
} oc_file_whence;
|
|
|
|
typedef u64 oc_io_req_id;
|
|
|
|
typedef u32 oc_io_op;
|
|
|
|
enum oc_io_op_enum
|
|
{
|
|
OC_IO_OPEN_AT = 0,
|
|
OC_IO_CLOSE,
|
|
|
|
OC_IO_FSTAT,
|
|
|
|
OC_IO_SEEK,
|
|
OC_IO_READ,
|
|
OC_IO_WRITE,
|
|
|
|
OC_OC_IO_ERROR,
|
|
//...
|
|
};
|
|
|
|
typedef struct oc_io_req
|
|
{
|
|
oc_io_req_id id;
|
|
oc_io_op op;
|
|
oc_file handle;
|
|
|
|
i64 offset;
|
|
u64 size;
|
|
|
|
union
|
|
{
|
|
char* buffer;
|
|
u64 unused; // This is a horrible hack to get the same layout on wasm and on host
|
|
};
|
|
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
oc_file_access rights;
|
|
oc_file_open_flags flags;
|
|
} open;
|
|
|
|
oc_file_whence whence;
|
|
};
|
|
|
|
} oc_io_req;
|
|
|
|
typedef i32 oc_io_error;
|
|
|
|
enum oc_io_error_enum
|
|
{
|
|
OC_IO_OK = 0,
|
|
OC_IO_ERR_UNKNOWN,
|
|
OC_IO_ERR_OP, // unsupported operation
|
|
OC_IO_ERR_HANDLE, // invalid handle
|
|
OC_IO_ERR_PREV, // previously had a fatal error (last error stored on handle)
|
|
OC_IO_ERR_ARG, // invalid argument or argument combination
|
|
OC_IO_ERR_PERM, // access denied
|
|
OC_IO_ERR_SPACE, // no space left
|
|
OC_IO_ERR_NO_ENTRY, // file or directory does not exist
|
|
OC_IO_ERR_EXISTS, // file already exists
|
|
OC_IO_ERR_NOT_DIR, // path element is not a directory
|
|
OC_IO_ERR_DIR, // attempted to write directory
|
|
OC_IO_ERR_MAX_FILES, // max open files reached
|
|
OC_IO_ERR_MAX_LINKS, // too many symbolic links in path
|
|
OC_IO_ERR_PATH_LENGTH, // path too long
|
|
OC_IO_ERR_FILE_SIZE, // file too big
|
|
OC_IO_ERR_OVERFLOW, // offset too big
|
|
OC_IO_ERR_NOT_READY, // no data ready to be read/written
|
|
OC_IO_ERR_MEM, // failed to allocate memory
|
|
OC_IO_ERR_INTERRUPT, // operation interrupted by a signal
|
|
OC_IO_ERR_PHYSICAL, // physical IO error
|
|
OC_IO_ERR_NO_DEVICE, // device not found
|
|
OC_IO_ERR_WALKOUT, // attempted to walk out of root directory
|
|
|
|
//...
|
|
};
|
|
|
|
typedef struct oc_io_cmp
|
|
{
|
|
oc_io_req_id id;
|
|
oc_io_error error;
|
|
|
|
union
|
|
{
|
|
i64 result;
|
|
u64 size;
|
|
i64 offset;
|
|
oc_file handle;
|
|
//...
|
|
};
|
|
} oc_io_cmp;
|
|
|
|
//----------------------------------------------------------------
|
|
//TODO: complete io queue api
|
|
//----------------------------------------------------------------
|
|
ORCA_API oc_io_cmp oc_io_wait_single_req(oc_io_req* req);
|
|
|
|
//----------------------------------------------------------------
|
|
// File IO wrapper API
|
|
//----------------------------------------------------------------
|
|
|
|
ORCA_API oc_file oc_file_nil();
|
|
ORCA_API bool oc_file_is_nil(oc_file handle);
|
|
|
|
ORCA_API oc_file oc_file_open(oc_str8 path, oc_file_access rights, oc_file_open_flags flags);
|
|
ORCA_API oc_file oc_file_open_at(oc_file dir, oc_str8 path, oc_file_access rights, oc_file_open_flags flags);
|
|
ORCA_API void oc_file_close(oc_file file);
|
|
|
|
ORCA_API i64 oc_file_pos(oc_file file);
|
|
ORCA_API i64 oc_file_seek(oc_file file, i64 offset, oc_file_whence whence);
|
|
|
|
ORCA_API u64 oc_file_write(oc_file file, u64 size, char* buffer);
|
|
ORCA_API u64 oc_file_read(oc_file file, u64 size, char* buffer);
|
|
|
|
ORCA_API oc_io_error oc_file_last_error(oc_file handle);
|
|
|
|
//----------------------------------------------------------------
|
|
// File System wrapper API
|
|
//----------------------------------------------------------------
|
|
|
|
typedef enum oc_file_type
|
|
{
|
|
OC_FILE_UNKNOWN,
|
|
OC_FILE_REGULAR,
|
|
OC_FILE_DIRECTORY,
|
|
OC_FILE_SYMLINK,
|
|
OC_FILE_BLOCK,
|
|
OC_FILE_CHARACTER,
|
|
OC_FILE_FIFO,
|
|
OC_FILE_SOCKET,
|
|
|
|
} oc_file_type;
|
|
|
|
typedef u16 oc_file_perm;
|
|
|
|
enum oc_file_perm
|
|
{
|
|
OC_FILE_OTHER_EXEC = 1 << 0,
|
|
OC_FILE_OTHER_WRITE = 1 << 1,
|
|
OC_FILE_OTHER_READ = 1 << 2,
|
|
|
|
OC_FILE_GROUP_EXEC = 1 << 3,
|
|
OC_FILE_GROUP_WRITE = 1 << 4,
|
|
OC_FILE_GROUP_READ = 1 << 5,
|
|
|
|
OC_FILE_OWNER_EXEC = 1 << 6,
|
|
OC_FILE_OWNER_WRITE = 1 << 7,
|
|
OC_FILE_OWNER_READ = 1 << 8,
|
|
|
|
OC_FILE_STICKY_BIT = 1 << 9,
|
|
OC_FILE_SET_GID = 1 << 10,
|
|
OC_FILE_SET_UID = 1 << 11,
|
|
};
|
|
|
|
typedef struct oc_file_status
|
|
{
|
|
u64 uid;
|
|
oc_file_type type;
|
|
oc_file_perm perm;
|
|
u64 size;
|
|
|
|
//TODO times
|
|
|
|
} oc_file_status;
|
|
|
|
ORCA_API oc_file_status oc_file_get_status(oc_file file);
|
|
ORCA_API u64 oc_file_size(oc_file file);
|
|
|
|
//TODO: Complete as needed...
|
|
|
|
#endif //__PLATFORM_IO_H_
|