From a43eb70ebe7844db0a4ffece47c22ae12384781b Mon Sep 17 00:00:00 2001 From: quou Date: Sat, 13 Jul 2024 23:45:08 +1000 Subject: Add file API --- plat.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ plat.h | 23 +++++++++++++++++ 2 files changed, 114 insertions(+) diff --git a/plat.c b/plat.c index f0d60ba..09c9444 100644 --- a/plat.c +++ b/plat.c @@ -8,11 +8,15 @@ #define _POSIX_SOURCE #define _GNU_SOURCE +#include #include #include +#include +#include #include #include #include +#include extern int isatty(int); extern int fileno(FILE*); @@ -86,16 +90,103 @@ void pbreak(Error code) { #endif } +struct File { + int handle; + int cursor; + int size; +}; + +File* file_open(const char* name, File_Flags flags) { + File* file; + int handle, f = 0; + struct stat info; + + if (flags & file_flags_write) { + f |= O_WRONLY | O_TRUNC; + } + + if (flags & file_flags_read) { + f |= O_RDONLY; + } + + if (flags & file_flags_read_write) { + f |= O_RDWR; + } + + if (stat(name, &info) < 0) { + info.st_size = 0; + if (flags & file_flags_create) { + f |= O_CREAT | S_IRUSR | S_IWUSR; + } + } + + handle = open(name, f); + if (handle < 0) { + return 0; + } + + file = (File*)malloc(sizeof *file); + file->handle = handle; + file->cursor = 0; + file->size = (int)info.st_size; + + return file; +} + +void file_close(File* file) { + close(file->handle); + free(file); +} + +void file_read(File* file, void* buffer, int size) { + lseek(file->handle, (off_t)file->cursor, SEEK_SET); + read(file->handle, buffer, size); + file->cursor += size; +} + +void file_write(File* file, const void* buffer, int size) { + lseek(file->handle, (off_t)file->cursor, SEEK_SET); + write(file->handle, buffer, size); + file->cursor += size; +} + +void file_seek(File* file, int offset, File_Whence whence) { + switch (whence) { + case file_whence_begin: + file->cursor = offset; + break; + case file_whence_end: + file->cursor = file->size - offset; + break; + case file_whence_cur: + file->cursor += offset; + break; + } +} + +int file_size(File* file) { + return file->size; +} + +int file_exists(const char* name) { + struct stat info; + return stat(name, &info) == 0; +} + + static clockid_t global_clock; static unsigned long global_freq; void init_timer(void) { + struct timespec ts; global_clock = CLOCK_REALTIME; global_freq = 1000000000; #if defined(_POSIX_MONOTONIC_CLOCK) if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { global_clock = CLOCK_MONOTONIC; } +#else + (void)ts; #endif } diff --git a/plat.h b/plat.h index 7e4f445..419d7fe 100644 --- a/plat.h +++ b/plat.h @@ -29,6 +29,29 @@ void print_err(const char* fmt, ...); void print_war(const char* fmt, ...); void pbreak(Error code); +typedef struct File File; + +typedef enum { + file_flags_write = 1 << 0, + file_flags_read = 1 << 1, + file_flags_read_write = 1 << 2, + file_flags_create = 1 << 3 +} File_Flags; + +typedef enum { + file_whence_begin, + file_whence_end, + file_whence_cur +} File_Whence; + +File* file_open(const char* name, File_Flags flags); +void file_close(File* file); +void file_read(File* file, void* buffer, int size); +void file_write(File* file, const void* buffer, int size); +void file_seek(File* file, int offset, File_Whence whence); +int file_size(File* file); +int file_exists(const char* name); + typedef struct { int mpf; int fps; -- cgit v1.2.3-54-g00ecf