26 char name[DETWS_VFS_NAME_MAX];
28 uint8_t data[DETWS_VFS_RAM_FILE_SIZE];
44 const DetwsVfsBackend *backend =
nullptr;
45 RamFile rf[DETWS_VFS_RAM_FILES];
46 RamHandle rh[DETWS_VFS_MAX_OPEN];
50int ram_find(
const char *name)
52 for (
int i = 0; i < DETWS_VFS_RAM_FILES; i++)
53 if (s_vfs.rf[i].used && strncmp(s_vfs.rf[i].name, name, DETWS_VFS_NAME_MAX) == 0)
58int ram_create(
const char *name)
60 if (strnlen(name, DETWS_VFS_NAME_MAX + 1) >= DETWS_VFS_NAME_MAX)
62 for (
int i = 0; i < DETWS_VFS_RAM_FILES; i++)
63 if (!s_vfs.rf[i].used)
65 s_vfs.rf[i].used =
true;
66 strncpy(s_vfs.rf[i].name, name, DETWS_VFS_NAME_MAX - 1);
67 s_vfs.rf[i].name[DETWS_VFS_NAME_MAX - 1] =
'\0';
74bool ram_handle_ok(
int h)
76 return h >= 0 && h < DETWS_VFS_MAX_OPEN && s_vfs.rh[h].open;
79int ram_open(
const char *path,
int mode)
83 const DetwsVfsMode m = (DetwsVfsMode)mode;
84 int f = ram_find(path);
85 if (m == DetwsVfsMode::DETWS_VFS_READ)
96 if (m == DetwsVfsMode::DETWS_VFS_WRITE)
99 for (
int h = 0; h < DETWS_VFS_MAX_OPEN; h++)
100 if (!s_vfs.rh[h].open)
102 s_vfs.rh[h].open =
true;
103 s_vfs.rh[h].file = f;
104 s_vfs.rh[h].mode = m;
105 s_vfs.rh[h].pos = (m == DetwsVfsMode::DETWS_VFS_APPEND) ? s_vfs.rf[f].len : 0;
111int ram_read(
int h,
void *buf,
size_t n)
113 if (!ram_handle_ok(h))
115 RamFile *f = &s_vfs.rf[s_vfs.rh[h].file];
116 size_t avail = (s_vfs.rh[h].pos < f->len) ? (f->len - s_vfs.rh[h].pos) : 0;
117 size_t k = n < avail ? n : avail;
118 memcpy(buf, f->data + s_vfs.rh[h].pos, k);
119 s_vfs.rh[h].pos += k;
123int ram_write(
int h,
const void *buf,
size_t n)
125 if (!ram_handle_ok(h) || s_vfs.rh[h].mode == DetwsVfsMode::DETWS_VFS_READ)
127 RamFile *f = &s_vfs.rf[s_vfs.rh[h].file];
128 size_t cap = (s_vfs.rh[h].pos < DETWS_VFS_RAM_FILE_SIZE) ? (DETWS_VFS_RAM_FILE_SIZE - s_vfs.rh[h].pos) : 0;
129 size_t k = n < cap ? n : cap;
130 memcpy(f->data + s_vfs.rh[h].pos, buf, k);
131 s_vfs.rh[h].pos += k;
132 if (s_vfs.rh[h].pos > f->len)
133 f->len = s_vfs.rh[h].pos;
139 if (h >= 0 && h < DETWS_VFS_MAX_OPEN)
140 s_vfs.rh[h].open =
false;
143long ram_size(
const char *path)
145 int f = ram_find(path);
146 return f < 0 ? -1 : (long)s_vfs.rf[f].len;
149bool ram_exists(
const char *path)
151 return ram_find(path) >= 0;
154bool ram_remove(
const char *path)
156 int f = ram_find(path);
159 s_vfs.rf[f].used =
false;
163bool ram_rename(
const char *from,
const char *to)
165 if (!from || !to || strnlen(to, DETWS_VFS_NAME_MAX + 1) >= DETWS_VFS_NAME_MAX)
167 int f = ram_find(from);
170 int dst = ram_find(to);
172 s_vfs.rf[dst].used =
false;
173 strncpy(s_vfs.rf[f].name, to, DETWS_VFS_NAME_MAX - 1);
174 s_vfs.rf[f].name[DETWS_VFS_NAME_MAX - 1] =
'\0';
178const DetwsVfsBackend s_ram_backend = {ram_open, ram_read, ram_write, ram_close,
179 ram_size, ram_exists, ram_remove, ram_rename};
182void detws_vfs_mount(
const DetwsVfsBackend *backend)
184 s_vfs.backend = backend;
187const DetwsVfsBackend *detws_vfs_ram(
void)
189 return &s_ram_backend;
192void detws_vfs_ram_format(
void)
194 for (
int i = 0; i < DETWS_VFS_RAM_FILES; i++)
195 s_vfs.rf[i].used =
false;
196 for (
int h = 0; h < DETWS_VFS_MAX_OPEN; h++)
197 s_vfs.rh[h].open =
false;
200int detws_vfs_open(
const char *path, DetwsVfsMode mode)
202 return s_vfs.backend ? s_vfs.backend->open(path, (
int)mode) : -1;
204int detws_vfs_read(
int handle,
void *buf,
size_t n)
206 return s_vfs.backend ? s_vfs.backend->read(handle, buf, n) : -1;
208int detws_vfs_write(
int handle,
const void *buf,
size_t n)
210 return s_vfs.backend ? s_vfs.backend->write(handle, buf, n) : -1;
212void detws_vfs_close(
int handle)
215 s_vfs.backend->close(handle);
217long detws_vfs_size(
const char *path)
219 return s_vfs.backend ? s_vfs.backend->size(path) : -1;
221bool detws_vfs_exists(
const char *path)
223 return s_vfs.backend ? s_vfs.backend->exists(path) :
false;
225bool detws_vfs_remove(
const char *path)
227 return s_vfs.backend ? s_vfs.backend->remove(path) :
false;
229bool detws_vfs_rename(
const char *from,
const char *to)
231 return s_vfs.backend ? s_vfs.backend->rename(from, to) :
false;
234long detws_vfs_read_file(
const char *path,
void *buf,
size_t cap)
236 long sz = detws_vfs_size(path);
237 if (sz < 0 || (
size_t)sz > cap)
239 int h = detws_vfs_open(path, DetwsVfsMode::DETWS_VFS_READ);
243 uint8_t *out = (uint8_t *)buf;
244 while (total < (
size_t)sz)
246 int r = detws_vfs_read(h, out + total, (
size_t)sz - total);
255bool detws_vfs_write_file(
const char *path,
const void *buf,
size_t n)
257 int h = detws_vfs_open(path, DetwsVfsMode::DETWS_VFS_WRITE);
261 const uint8_t *in = (
const uint8_t *)buf;
264 int w = detws_vfs_write(h, in + total, n - total);
287 fs::FS *fs =
nullptr;
288 fs::File fsfile[DETWS_VFS_MAX_OPEN];
289 bool fsopen[DETWS_VFS_MAX_OPEN];
293int fs_open(
const char *path,
int mode)
295 if (!s_vfs_fs.fs || !path)
297 const DetwsVfsMode md = (DetwsVfsMode)mode;
298 const char *m = (md == DetwsVfsMode::DETWS_VFS_WRITE) ? FILE_WRITE
299 : (md == DetwsVfsMode::DETWS_VFS_APPEND) ? FILE_APPEND
301 for (
int h = 0; h < DETWS_VFS_MAX_OPEN; h++)
302 if (!s_vfs_fs.fsopen[h])
304 s_vfs_fs.fsfile[h] = s_vfs_fs.fs->open(path, m);
305 if (!s_vfs_fs.fsfile[h])
307 s_vfs_fs.fsopen[h] =
true;
312int fs_read(
int h,
void *buf,
size_t n)
314 if (h < 0 || h >= DETWS_VFS_MAX_OPEN || !s_vfs_fs.fsopen[h])
316 return (
int)s_vfs_fs.fsfile[h].read((uint8_t *)buf, n);
318int fs_write(
int h,
const void *buf,
size_t n)
320 if (h < 0 || h >= DETWS_VFS_MAX_OPEN || !s_vfs_fs.fsopen[h])
322 return (
int)s_vfs_fs.fsfile[h].write((
const uint8_t *)buf, n);
326 if (h >= 0 && h < DETWS_VFS_MAX_OPEN && s_vfs_fs.fsopen[h])
328 s_vfs_fs.fsfile[h].close();
329 s_vfs_fs.fsopen[h] =
false;
332long fs_size(
const char *path)
336 fs::File f = s_vfs_fs.fs->open(path, FILE_READ);
339 long sz = (long)f.size();
343bool fs_exists(
const char *path)
345 return s_vfs_fs.fs && s_vfs_fs.fs->exists(path);
347bool fs_remove(
const char *path)
349 return s_vfs_fs.fs && s_vfs_fs.fs->remove(path);
351bool fs_rename(
const char *from,
const char *to)
353 return s_vfs_fs.fs && s_vfs_fs.fs->rename(from, to);
356const DetwsVfsBackend s_fs_backend = {fs_open, fs_read, fs_write, fs_close, fs_size, fs_exists, fs_remove, fs_rename};
359const DetwsVfsBackend *detws_vfs_fs(fs::FS *filesystem)
361 s_vfs_fs.fs = filesystem;
362 for (
int h = 0; h < DETWS_VFS_MAX_OPEN; h++)
363 s_vfs_fs.fsopen[h] =
false;
364 return &s_fs_backend;
Unified virtual filesystem wrapper (DETWS_ENABLE_VFS).