From b98e1e643f98531f33404d67e23b691a7d3094d9 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Mon, 24 May 2021 18:56:59 +0200 Subject: Add append mode and fs_seek --- src/filesystem.c | 78 ++++++++++++++++++++------------------------------------ 1 file changed, 28 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/filesystem.c b/src/filesystem.c index cac2805..3fe95ab 100644 --- a/src/filesystem.c +++ b/src/filesystem.c @@ -127,14 +127,19 @@ _fs_update_file_index(u16 index) { } typedef enum { - FS_OPEN_READ, - FS_OPEN_WRITE, - FS_OPEN_APPEND, + FS_OPEN_READ = (1 << 0), + FS_OPEN_WRITE = (1 << 1), + FS_OPEN_APPEND = (1 << 2), } OpenMode; typedef struct File { + // File index offset. u8 index; + // The offset within the file. Must always be valid, and so the File struct + // shouldn't be manaully modified unless we are sure we know what we are + // doing. u16 offset; + // The mode of this file (read/write/append). OpenMode mode; } File; @@ -148,7 +153,8 @@ fs_open_file(char *name, OpenMode mode) { } } - if (mode == FS_OPEN_READ) { + // If read only. + if ((mode & (FS_OPEN_WRITE | FS_OPEN_APPEND)) == 0) { return (File){FS_NULL, 0, mode}; } @@ -202,8 +208,6 @@ _fs_init_new_block(void) { return FS_NULL; } -#include "text.h" - // Recursively free blocks starting at blk_id. To improve performance, the // filesystem header is updated in memory but not written to disk. It is // responsability of the caller to perform the filesystem update. @@ -236,7 +240,8 @@ _fs_free_blocks(u8 blk_id) { // Write to block as a new file. void -_fs_write_to_block(u8 *src, u16 n_bytes, u16 blk_offset, u8 blk_id, u8 prev_blk) { +_fs_write_to_block(u8 *src, u16 n_bytes, u16 blk_offset, + u8 blk_id, u8 prev_blk, bool append) { // Read initial block. FileBlock block; u16 block_pos = FILE_DATA_START + FILE_BLOCK_SIZE * blk_id; @@ -253,7 +258,7 @@ _fs_write_to_block(u8 *src, u16 n_bytes, u16 blk_offset, u8 blk_id, u8 prev_blk) block.next_block = _fs_init_new_block(); } _fs_write_to_block(src + block_capacity, n_bytes - block_capacity, 0, - block.next_block, blk_id); + block.next_block, blk_id, append); } else if (block.next_block != FS_NULL){ // Recursively free unused blocks. _fs_free_blocks(block.next_block); @@ -269,52 +274,27 @@ _fs_write_to_block(u8 *src, u16 n_bytes, u16 blk_offset, u8 blk_id, u8 prev_blk) _fs_write(&block, block_pos, sizeof(FileBlock)); } -// void -// _fs_append_to_block(u8 *src, u16 n_bytes, u8 blk_id, u8 prev_block) { -// // Read initial block. -// FileBlock block; -// size_t block_pos = FILE_DATA_START + FILE_BLOCK_SIZE * blk_id; -// _fs_read(&block, block_pos, sizeof(FileBlock)); -// u16 block_capacity = (FILE_BLOCK_SIZE - sizeof(FileBlock)) - block.size; - -// // Write capacity. -// u16 block_bytes = MIN(block_capacity, n_bytes); -// _fs_write(src, block_pos + sizeof(FileBlock), block_bytes); - -// // txt_printf("cap: %d\n", block_capacity); -// // txt_printf("bytes: %d\n", n_bytes); -// // txt_printf("id: %d\n", blk_id); -// if (n_bytes > block_capacity) { -// if (block.next_block == FS_NULL) { -// // Find new available block and initialize it. -// block.next_block = _fs_init_new_block(); -// // TODO: Don't forget to set the block_prev of the next block as -// // this one. -// } -// _fs_write_to_block( -// src + block_capacity, -// n_bytes - block_capacity, -// block.next_block, -// blk_id); -// } - -// // Update block header. -// if (prev_block != FS_NULL) { -// block.prev_block = prev_bloc7f8k; -// } -// block.size += block_bytes; -// _fs_write(&block, block_pos, sizeof(FileBlock)); -// } +int +fs_seek(File *file, int offset) { + u16 file_size = fs_file_size(file); + u16 new_offset = MAX((int)file->offset + offset, 0); + if (new_offset >= file_size) { + return -1; + } + file->offset = new_offset; + return 0; +} u16 fs_write(u8 *src, u16 n_bytes, File *file) { - if (file->mode != FS_OPEN_WRITE && file->mode != FS_OPEN_APPEND) { + if ((file->mode & (FS_OPEN_WRITE | FS_OPEN_APPEND)) == 0) { return 0; } FileIndex *file_idx = &filesystem.files[file->index]; u8 blk_id = FS_NULL; + u8 blk_prev = FS_NULL; u16 offset = file->offset; if (file_idx->first_block == FS_NULL) { // Check how many blocks will this write requires and if we have enough @@ -352,6 +332,7 @@ fs_write(u8 *src, u16 n_bytes, File *file) { u16 block_pos = FILE_DATA_START + FILE_BLOCK_SIZE * blk_id; _fs_read(&block, block_pos, sizeof(FileBlock)); blk_id = block.next_block; + blk_prev = block.prev_block; if (blk_id == FS_NULL) { return 0; } @@ -361,11 +342,8 @@ fs_write(u8 *src, u16 n_bytes, File *file) { } // Write to block. - if (file->mode == FS_OPEN_WRITE) { - _fs_write_to_block(src, n_bytes, offset, blk_id, FS_NULL); - } else { - // TODO: Append... - } + _fs_write_to_block(src, n_bytes, offset, blk_id, blk_prev, + file->mode == FS_OPEN_APPEND); return n_bytes; } -- cgit v1.2.1