diff options
Diffstat (limited to 'src/user/knob/file.c')
-rw-r--r-- | src/user/knob/file.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/user/knob/file.c b/src/user/knob/file.c new file mode 100644 index 0000000..8ab7acd --- /dev/null +++ b/src/user/knob/file.c @@ -0,0 +1,82 @@ +#include <pland/syscall.h> +#include <knob/format.h> +#include <knob/heap.h> +#include <knob/env.h> + +struct file { + _file_handle_t handle; + uint32_t position; + uint32_t length; +}; + +static const char *try_remove_prefix(const char *path, uint8_t *dn_out) { + if ((path[0] != 's') || (path[1] != 'd')) + return 0; + + const char *num_part = path + 2; + for (uint32_t i = 0; num_part[i]; ++i) + if (num_part[i] == ':') { + + uint32_t dn_large; + if (!try_sntoi(num_part, i, &dn_large) || dn_large > 255) + return 0; + + *dn_out = (uint8_t)dn_large; + return num_part + i + 1; + } + + return 0; +} + +struct file *open_file(const char *path) { + uint8_t dn; + const char *path_part = try_remove_prefix(path, &dn); + if (path_part) + path = path_part; + else + dn = current_drive; + + _file_handle_t h = _open_file(dn, path); + if (!h) + return 0; + + struct file *f = get_block(sizeof(struct file)); + f->handle = h; + f->position = 0; + f->length = _file_size(h); + + return f; +} + +void close_file(struct file *f) { + _close_file(f->handle); + free_block(f); +} + +uint32_t read_from_file(struct file *f, uint32_t max, void *buf) { + if (f->position + max > f->length) + max = f->length - f->position; + + uint32_t read = _file_read(f->handle, f->position, max, buf); + + f->position += read; + return read; +} + +uint32_t seek_file_to(struct file *f, uint32_t to) { + if (to > f->length) + to = f->length; + return f->position = to; +} + +int32_t seek_file_by(struct file *f, int32_t by) { + uint32_t old = f->position; + uint32_t to = old + by > f->length ? f->length : old + by; + f->position = to; + return to - old; +} + +__attribute__ ((pure)) +uint32_t file_size(struct file *f) { + return f->length; +}
\ No newline at end of file |