orca/src/platform/platform_io.h

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_