aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-05-24 18:56:59 +0200
committerBad Diode <bd@badd10de.dev>2021-05-24 18:56:59 +0200
commitb98e1e643f98531f33404d67e23b691a7d3094d9 (patch)
treed0590e9a2fa8c984e9f71b13f5f52913435c64b9 /src
parentf4dd03dd800d7cf2d42169b6f30c10585c5a78c4 (diff)
downloaduxngba-b98e1e643f98531f33404d67e23b691a7d3094d9.tar.gz
uxngba-b98e1e643f98531f33404d67e23b691a7d3094d9.zip
Add append mode and fs_seek
Diffstat (limited to 'src')
-rw-r--r--src/filesystem.c78
1 files changed, 28 insertions, 50 deletions
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) {
127} 127}
128 128
129typedef enum { 129typedef enum {
130 FS_OPEN_READ, 130 FS_OPEN_READ = (1 << 0),
131 FS_OPEN_WRITE, 131 FS_OPEN_WRITE = (1 << 1),
132 FS_OPEN_APPEND, 132 FS_OPEN_APPEND = (1 << 2),
133} OpenMode; 133} OpenMode;
134 134
135typedef struct File { 135typedef struct File {
136 // File index offset.
136 u8 index; 137 u8 index;
138 // The offset within the file. Must always be valid, and so the File struct
139 // shouldn't be manaully modified unless we are sure we know what we are
140 // doing.
137 u16 offset; 141 u16 offset;
142 // The mode of this file (read/write/append).
138 OpenMode mode; 143 OpenMode mode;
139} File; 144} File;
140 145
@@ -148,7 +153,8 @@ fs_open_file(char *name, OpenMode mode) {
148 } 153 }
149 } 154 }
150 155
151 if (mode == FS_OPEN_READ) { 156 // If read only.
157 if ((mode & (FS_OPEN_WRITE | FS_OPEN_APPEND)) == 0) {
152 return (File){FS_NULL, 0, mode}; 158 return (File){FS_NULL, 0, mode};
153 } 159 }
154 160
@@ -202,8 +208,6 @@ _fs_init_new_block(void) {
202 return FS_NULL; 208 return FS_NULL;
203} 209}
204 210
205#include "text.h"
206
207// Recursively free blocks starting at blk_id. To improve performance, the 211// Recursively free blocks starting at blk_id. To improve performance, the
208// filesystem header is updated in memory but not written to disk. It is 212// filesystem header is updated in memory but not written to disk. It is
209// responsability of the caller to perform the filesystem update. 213// responsability of the caller to perform the filesystem update.
@@ -236,7 +240,8 @@ _fs_free_blocks(u8 blk_id) {
236 240
237// Write to block as a new file. 241// Write to block as a new file.
238void 242void
239_fs_write_to_block(u8 *src, u16 n_bytes, u16 blk_offset, u8 blk_id, u8 prev_blk) { 243_fs_write_to_block(u8 *src, u16 n_bytes, u16 blk_offset,
244 u8 blk_id, u8 prev_blk, bool append) {
240 // Read initial block. 245 // Read initial block.
241 FileBlock block; 246 FileBlock block;
242 u16 block_pos = FILE_DATA_START + FILE_BLOCK_SIZE * blk_id; 247 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)
253 block.next_block = _fs_init_new_block(); 258 block.next_block = _fs_init_new_block();
254 } 259 }
255 _fs_write_to_block(src + block_capacity, n_bytes - block_capacity, 0, 260 _fs_write_to_block(src + block_capacity, n_bytes - block_capacity, 0,
256 block.next_block, blk_id); 261 block.next_block, blk_id, append);
257 } else if (block.next_block != FS_NULL){ 262 } else if (block.next_block != FS_NULL){
258 // Recursively free unused blocks. 263 // Recursively free unused blocks.
259 _fs_free_blocks(block.next_block); 264 _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)
269 _fs_write(&block, block_pos, sizeof(FileBlock)); 274 _fs_write(&block, block_pos, sizeof(FileBlock));
270} 275}
271 276
272// void 277int
273// _fs_append_to_block(u8 *src, u16 n_bytes, u8 blk_id, u8 prev_block) { 278fs_seek(File *file, int offset) {
274// // Read initial block. 279 u16 file_size = fs_file_size(file);
275// FileBlock block; 280 u16 new_offset = MAX((int)file->offset + offset, 0);
276// size_t block_pos = FILE_DATA_START + FILE_BLOCK_SIZE * blk_id; 281 if (new_offset >= file_size) {
277// _fs_read(&block, block_pos, sizeof(FileBlock)); 282 return -1;
278// u16 block_capacity = (FILE_BLOCK_SIZE - sizeof(FileBlock)) - block.size; 283 }
279 284 file->offset = new_offset;
280// // Write capacity. 285 return 0;
281// u16 block_bytes = MIN(block_capacity, n_bytes); 286}
282// _fs_write(src, block_pos + sizeof(FileBlock), block_bytes);
283
284// // txt_printf("cap: %d\n", block_capacity);
285// // txt_printf("bytes: %d\n", n_bytes);
286// // txt_printf("id: %d\n", blk_id);
287// if (n_bytes > block_capacity) {
288// if (block.next_block == FS_NULL) {
289// // Find new available block and initialize it.
290// block.next_block = _fs_init_new_block();
291// // TODO: Don't forget to set the block_prev of the next block as
292// // this one.
293// }
294// _fs_write_to_block(
295// src + block_capacity,
296// n_bytes - block_capacity,
297// block.next_block,
298// blk_id);
299// }
300
301// // Update block header.
302// if (prev_block != FS_NULL) {
303// block.prev_block = prev_bloc7f8k;
304// }
305// block.size += block_bytes;
306// _fs_write(&block, block_pos, sizeof(FileBlock));
307// }
308 287
309u16 288u16
310fs_write(u8 *src, u16 n_bytes, File *file) { 289fs_write(u8 *src, u16 n_bytes, File *file) {
311 if (file->mode != FS_OPEN_WRITE && file->mode != FS_OPEN_APPEND) { 290 if ((file->mode & (FS_OPEN_WRITE | FS_OPEN_APPEND)) == 0) {
312 return 0; 291 return 0;
313 } 292 }
314 293
315 FileIndex *file_idx = &filesystem.files[file->index]; 294 FileIndex *file_idx = &filesystem.files[file->index];
316 295
317 u8 blk_id = FS_NULL; 296 u8 blk_id = FS_NULL;
297 u8 blk_prev = FS_NULL;
318 u16 offset = file->offset; 298 u16 offset = file->offset;
319 if (file_idx->first_block == FS_NULL) { 299 if (file_idx->first_block == FS_NULL) {
320 // Check how many blocks will this write requires and if we have enough 300 // 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) {
352 u16 block_pos = FILE_DATA_START + FILE_BLOCK_SIZE * blk_id; 332 u16 block_pos = FILE_DATA_START + FILE_BLOCK_SIZE * blk_id;
353 _fs_read(&block, block_pos, sizeof(FileBlock)); 333 _fs_read(&block, block_pos, sizeof(FileBlock));
354 blk_id = block.next_block; 334 blk_id = block.next_block;
335 blk_prev = block.prev_block;
355 if (blk_id == FS_NULL) { 336 if (blk_id == FS_NULL) {
356 return 0; 337 return 0;
357 } 338 }
@@ -361,11 +342,8 @@ fs_write(u8 *src, u16 n_bytes, File *file) {
361 } 342 }
362 343
363 // Write to block. 344 // Write to block.
364 if (file->mode == FS_OPEN_WRITE) { 345 _fs_write_to_block(src, n_bytes, offset, blk_id, blk_prev,
365 _fs_write_to_block(src, n_bytes, offset, blk_id, FS_NULL); 346 file->mode == FS_OPEN_APPEND);
366 } else {
367 // TODO: Append...
368 }
369 347
370 return n_bytes; 348 return n_bytes;
371} 349}