29 char name[PC_VFS_NAME_MAX];
31 uint8_t data[PC_VFS_RAM_FILE_SIZE];
47 const pc_vfs_backend *backend =
nullptr;
48 RamFile rf[PC_VFS_RAM_FILES];
49 RamHandle rh[PC_VFS_MAX_OPEN];
53int ram_find(
const char *name)
55 for (
int i = 0; i < PC_VFS_RAM_FILES; i++)
57 if (s_vfs.rf[i].used && strncmp(s_vfs.rf[i].name, name, PC_VFS_NAME_MAX) == 0)
65int ram_create(
const char *name)
67 if (strnlen(name, PC_VFS_NAME_MAX + 1) >= PC_VFS_NAME_MAX)
71 for (
int i = 0; i < PC_VFS_RAM_FILES; i++)
73 if (!s_vfs.rf[i].used)
75 s_vfs.rf[i].used =
true;
76 strncpy(s_vfs.rf[i].name, name, PC_VFS_NAME_MAX - 1);
77 s_vfs.rf[i].name[PC_VFS_NAME_MAX - 1] =
'\0';
85bool ram_handle_ok(
int h)
87 return h >= 0 && h < PC_VFS_MAX_OPEN && s_vfs.rh[h].open;
90int ram_open(
const char *path,
int mode)
96 const pc_vfs_mode m = (pc_vfs_mode)mode;
97 int f = ram_find(path);
98 if (m == pc_vfs_mode::PC_VFS_READ)
109 f = ram_create(path);
115 if (m == pc_vfs_mode::PC_VFS_WRITE)
120 for (
int h = 0; h < PC_VFS_MAX_OPEN; h++)
122 if (!s_vfs.rh[h].open)
124 s_vfs.rh[h].open =
true;
125 s_vfs.rh[h].file = f;
126 s_vfs.rh[h].mode = m;
127 s_vfs.rh[h].pos = (m == pc_vfs_mode::PC_VFS_APPEND) ? s_vfs.rf[f].len : 0;
134int ram_read(
int h,
void *buf,
size_t n)
136 if (!ram_handle_ok(h))
140 RamFile *f = &s_vfs.rf[s_vfs.rh[h].file];
141 size_t avail = (s_vfs.rh[h].pos < f->len) ? (f->len - s_vfs.rh[h].pos) : 0;
142 size_t k = n < avail ? n : avail;
143 memcpy(buf, f->data + s_vfs.rh[h].pos, k);
144 s_vfs.rh[h].pos += k;
148int ram_write(
int h,
const void *buf,
size_t n)
150 if (!ram_handle_ok(h) || s_vfs.rh[h].mode == pc_vfs_mode::PC_VFS_READ)
154 RamFile *f = &s_vfs.rf[s_vfs.rh[h].file];
155 size_t cap = (s_vfs.rh[h].pos < PC_VFS_RAM_FILE_SIZE) ? (PC_VFS_RAM_FILE_SIZE - s_vfs.rh[h].pos) : 0;
156 size_t k = n < cap ? n : cap;
157 memcpy(f->data + s_vfs.rh[h].pos, buf, k);
158 s_vfs.rh[h].pos += k;
159 if (s_vfs.rh[h].pos > f->len)
161 f->len = s_vfs.rh[h].pos;
168 if (h >= 0 && h < PC_VFS_MAX_OPEN)
170 s_vfs.rh[h].open =
false;
174long ram_size(
const char *path)
176 int f = ram_find(path);
177 return f < 0 ? -1 : (long)s_vfs.rf[f].len;
180bool ram_exists(
const char *path)
182 return ram_find(path) >= 0;
185bool ram_remove(
const char *path)
187 int f = ram_find(path);
192 s_vfs.rf[f].used =
false;
196bool ram_rename(
const char *from,
const char *to)
198 if (!from || !to || strnlen(to, PC_VFS_NAME_MAX + 1) >= PC_VFS_NAME_MAX)
202 int f = ram_find(from);
207 int dst = ram_find(to);
210 s_vfs.rf[dst].used =
false;
212 strncpy(s_vfs.rf[f].name, to, PC_VFS_NAME_MAX - 1);
213 s_vfs.rf[f].name[PC_VFS_NAME_MAX - 1] =
'\0';
217const pc_vfs_backend s_ram_backend = {ram_open, ram_read, ram_write, ram_close,
218 ram_size, ram_exists, ram_remove, ram_rename};
221void pc_vfs_mount(
const pc_vfs_backend *backend)
223 s_vfs.backend = backend;
226const pc_vfs_backend *pc_vfs_ram(
void)
228 return &s_ram_backend;
231void pc_vfs_ram_format(
void)
233 for (
int i = 0; i < PC_VFS_RAM_FILES; i++)
235 s_vfs.rf[i].used =
false;
237 for (
int h = 0; h < PC_VFS_MAX_OPEN; h++)
239 s_vfs.rh[h].open =
false;
243int pc_vfs_open(
const char *path, pc_vfs_mode mode)
245 return s_vfs.backend ? s_vfs.backend->open(path, (
int)mode) : -1;
247int pc_vfs_read(
int handle,
void *buf,
size_t n)
249 return s_vfs.backend ? s_vfs.backend->read(handle, buf, n) : -1;
251int pc_vfs_write(
int handle,
const void *buf,
size_t n)
253 return s_vfs.backend ? s_vfs.backend->write(handle, buf, n) : -1;
255void pc_vfs_close(
int handle)
259 s_vfs.backend->close(handle);
262long pc_vfs_size(
const char *path)
264 return s_vfs.backend ? s_vfs.backend->size(path) : -1;
266bool pc_vfs_exists(
const char *path)
268 return s_vfs.backend ? s_vfs.backend->exists(path) :
false;
270bool pc_vfs_remove(
const char *path)
272 return s_vfs.backend ? s_vfs.backend->remove(path) :
false;
274bool pc_vfs_rename(
const char *from,
const char *to)
276 return s_vfs.backend ? s_vfs.backend->rename(from, to) :
false;
279long pc_vfs_read_file(
const char *path,
void *buf,
size_t cap)
281 long sz = pc_vfs_size(path);
282 if (sz < 0 || (
size_t)sz > cap)
286 int h = pc_vfs_open(path, pc_vfs_mode::PC_VFS_READ);
292 uint8_t *out = (uint8_t *)buf;
293 while (total < (
size_t)sz)
295 int r = pc_vfs_read(h, out + total, (
size_t)sz - total);
306bool pc_vfs_write_file(
const char *path,
const void *buf,
size_t n)
308 int h = pc_vfs_open(path, pc_vfs_mode::PC_VFS_WRITE);
314 const uint8_t *in = (
const uint8_t *)buf;
317 int w = pc_vfs_write(h, in + total, n - total);
340 fs::FS *fs =
nullptr;
341 fs::File fsfile[PC_VFS_MAX_OPEN];
342 bool fsopen[PC_VFS_MAX_OPEN];
346int fs_open(
const char *path,
int mode)
348 if (!s_vfs_fs.fs || !path)
352 const pc_vfs_mode md = (pc_vfs_mode)mode;
353 const char *m = (md == pc_vfs_mode::PC_VFS_WRITE) ? FILE_WRITE
354 : (md == pc_vfs_mode::PC_VFS_APPEND) ? FILE_APPEND
356 for (
int h = 0; h < PC_VFS_MAX_OPEN; h++)
358 if (!s_vfs_fs.fsopen[h])
360 s_vfs_fs.fsfile[h] = s_vfs_fs.fs->open(path, m);
361 if (!s_vfs_fs.fsfile[h])
365 s_vfs_fs.fsopen[h] =
true;
371int fs_read(
int h,
void *buf,
size_t n)
373 if (h < 0 || h >= PC_VFS_MAX_OPEN || !s_vfs_fs.fsopen[h])
377 return (
int)s_vfs_fs.fsfile[h].read((uint8_t *)buf, n);
379int fs_write(
int h,
const void *buf,
size_t n)
381 if (h < 0 || h >= PC_VFS_MAX_OPEN || !s_vfs_fs.fsopen[h])
385 return (
int)s_vfs_fs.fsfile[h].write((
const uint8_t *)buf, n);
389 if (h >= 0 && h < PC_VFS_MAX_OPEN && s_vfs_fs.fsopen[h])
391 s_vfs_fs.fsfile[h].close();
392 s_vfs_fs.fsopen[h] =
false;
395long fs_size(
const char *path)
401 fs::File f = s_vfs_fs.fs->open(path, FILE_READ);
406 long sz = (long)f.size();
410bool fs_exists(
const char *path)
412 return s_vfs_fs.fs && s_vfs_fs.fs->exists(path);
414bool fs_remove(
const char *path)
416 return s_vfs_fs.fs && s_vfs_fs.fs->remove(path);
418bool fs_rename(
const char *from,
const char *to)
420 return s_vfs_fs.fs && s_vfs_fs.fs->rename(from, to);
423const pc_vfs_backend s_fs_backend = {fs_open, fs_read, fs_write, fs_close, fs_size, fs_exists, fs_remove, fs_rename};
426const pc_vfs_backend *pc_vfs_fs(fs::FS *filesystem)
428 s_vfs_fs.fs = filesystem;
429 for (
int h = 0; h < PC_VFS_MAX_OPEN; h++)
431 s_vfs_fs.fsopen[h] =
false;
433 return &s_fs_backend;
Unified virtual filesystem wrapper (PC_ENABLE_VFS).