diff options
Diffstat (limited to 'src/filesystem.c')
-rw-r--r-- | src/filesystem.c | 61 |
1 files changed, 46 insertions, 15 deletions
diff --git a/src/filesystem.c b/src/filesystem.c index 327b613..ee55dcf 100644 --- a/src/filesystem.c +++ b/src/filesystem.c | |||
@@ -117,7 +117,7 @@ fs_init(void) { | |||
117 | void | 117 | void |
118 | _fs_update_filesystem_header(void) { | 118 | _fs_update_filesystem_header(void) { |
119 | _fs_write(&filesystem, 0, offsetof(FileSystem, files)); | 119 | _fs_write(&filesystem, 0, offsetof(FileSystem, files)); |
120 | }; | 120 | } |
121 | 121 | ||
122 | void | 122 | void |
123 | _fs_update_file_index(u16 index) { | 123 | _fs_update_file_index(u16 index) { |
@@ -238,7 +238,6 @@ _fs_free_blocks(u8 blk_id) { | |||
238 | _fs_free_blocks(next_block); | 238 | _fs_free_blocks(next_block); |
239 | } | 239 | } |
240 | 240 | ||
241 | // Write to block as a new file. | ||
242 | void | 241 | void |
243 | _fs_write_to_block(u8 *src, u16 n_bytes, u16 blk_offset, | 242 | _fs_write_to_block(u8 *src, u16 n_bytes, u16 blk_offset, |
244 | u8 blk_id, u8 prev_blk, bool append) { | 243 | u8 blk_id, u8 prev_blk, bool append) { |
@@ -295,7 +294,7 @@ fs_seek(File *file, int offset, SeekMode mode) { | |||
295 | new_offset = MAX((int)file_size - 1 + offset, 0); | 294 | new_offset = MAX((int)file_size - 1 + offset, 0); |
296 | } break; | 295 | } break; |
297 | } | 296 | } |
298 | if (new_offset >= file_size) { | 297 | if (new_offset != 0 && new_offset >= file_size) { |
299 | return -1; | 298 | return -1; |
300 | } | 299 | } |
301 | file->offset = new_offset; | 300 | file->offset = new_offset; |
@@ -365,22 +364,54 @@ fs_write(u8 *src, u16 n_bytes, File *file) { | |||
365 | return n_bytes; | 364 | return n_bytes; |
366 | } | 365 | } |
367 | 366 | ||
367 | void | ||
368 | _fs_read_from_block(u8 *dst, u16 n_bytes, u16 blk_offset, u8 blk_id) { | ||
369 | // Read initial block. | ||
370 | FileBlock block; | ||
371 | u16 block_pos = FILE_DATA_START + FILE_BLOCK_SIZE * blk_id; | ||
372 | _fs_read(&block, block_pos, sizeof(FileBlock)); | ||
373 | |||
374 | u16 read_bytes = MIN(block.size - blk_offset, n_bytes); | ||
375 | _fs_read(dst, block_pos + blk_offset + sizeof(FileBlock), read_bytes); | ||
376 | |||
377 | u16 remaining_bytes = n_bytes - read_bytes; | ||
378 | if (block.next_block != FS_NULL && remaining_bytes > 0) { | ||
379 | _fs_read_from_block(dst + read_bytes, remaining_bytes, 0, block.next_block); | ||
380 | } | ||
381 | } | ||
382 | |||
368 | u16 | 383 | u16 |
369 | fs_read(u8 *dst, u16 n_bytes, u16 offset, File *file) { | 384 | fs_read(u8 *dst, u16 n_bytes, File *file) { |
370 | // File *file = &filesystem.files[file_index]; | 385 | if ((file->mode & FS_OPEN_READ) == 0) { |
386 | return 0; | ||
387 | } | ||
388 | |||
389 | // If there is an offset find the block index and relative offset. | ||
390 | u8 blk_id = filesystem.files[file->index].first_block; | ||
391 | u16 offset = file->offset; | ||
371 | 392 | ||
372 | // // Check if the offset is within limits. | 393 | // Read as much as we can from the file after the offset. |
373 | // if (file->size == 0 || offset >= file->size - 1) { | 394 | u16 file_size = fs_file_size(file); |
374 | // return 0; | 395 | if (offset + n_bytes >= file_size) { |
375 | // } | 396 | n_bytes = file_size - offset; |
397 | } | ||
376 | 398 | ||
377 | // // Read as much as we can. | 399 | if (offset >= FILE_BLOCK_CAPACITY) { |
378 | // if (offset + n_bytes > file->size) { | 400 | u16 n_blocks_offset = offset / FILE_BLOCK_CAPACITY; |
379 | // n_bytes = file->size - offset; | 401 | for (size_t i = 0; i < n_blocks_offset; ++i) { |
380 | // } | 402 | FileBlock block; |
403 | u16 block_pos = FILE_DATA_START + FILE_BLOCK_SIZE * blk_id; | ||
404 | _fs_read(&block, block_pos, sizeof(FileBlock)); | ||
405 | blk_id = block.next_block; | ||
406 | if (blk_id == FS_NULL) { | ||
407 | return 0; | ||
408 | } | ||
409 | } | ||
410 | offset = offset % FILE_BLOCK_CAPACITY; | ||
411 | } | ||
381 | 412 | ||
382 | // // Copy n_bytes to destination. | 413 | // Copy n_bytes to destination. |
383 | // _fs_read(dst, FILE_DATA_OFFSET + FILE_MAX_SIZE * file_index + offset, n_bytes); | 414 | _fs_read_from_block(dst, n_bytes, offset, blk_id); |
384 | 415 | ||
385 | return n_bytes; | 416 | return n_bytes; |
386 | } | 417 | } |