diff --git a/src/components/volatileFilesystem.c b/src/components/volatileFilesystem.c index 83fc6d1..27e9ed1 100644 --- a/src/components/volatileFilesystem.c +++ b/src/components/volatileFilesystem.c @@ -1,7 +1,5 @@ #include "../neonucleus.h" -// TODO: finish - // Data structures typedef struct nn_vfnode { @@ -556,7 +554,39 @@ nn_size_t nn_vfs_seek(nn_vfilesystem *fs, nn_vfhandle *handle, const char *whenc return handle->position; } -// main funciton +typedef struct nn_vfilesystemImage { + nn_vfilesystemImageNode *nodes; + nn_size_t ptr; +} nn_vfilesystemImage; + +static nn_vfilesystemImageNode nni_vfsimg_nextNode(nn_vfilesystemImage *stream) { + nn_vfilesystemImageNode node = stream->nodes[stream->ptr]; + stream->ptr++; + return node; +} + +static nn_vfnode *nni_vfsimg_parseNode(nn_vfilesystem *fs, nn_vfilesystemImage *stream) { + // TODO: make this handle OOMs + nn_vfilesystemImageNode node = nni_vfsimg_nextNode(stream); + if(node.data == NULL) { + // directory!!!!! + nn_vfnode *dir = nn_vf_allocDirectory(fs, node.name); + dir->len = node.len; + for(int i = 0; i < node.len; i++) { + nn_vfnode *entry = nni_vfsimg_parseNode(fs, stream); + dir->entries[i] = entry; + } + return dir; + } + // file!!!!! + nn_vfnode *file = nn_vf_allocFile(fs, node.name); + nn_vf_ensureFileCapacity(file, node.len); + file->len = node.len; + nn_memcpy(file->data, node.data, node.len); + return file; +} + +// constructor nn_filesystem *nn_volatileFilesystem(nn_Context *context, nn_vfilesystemOptions opts, nn_filesystemControl control) { // TODO: handle OOM @@ -567,6 +597,20 @@ nn_filesystem *nn_volatileFilesystem(nn_Context *context, nn_vfilesystemOptions fs->birthday = time; fs->opts = opts; fs->root = nn_vf_allocDirectory(fs, "/"); + + if(opts.image != NULL) { + nn_vfilesystemImage stream = { + .nodes = opts.image, + .ptr = 0, + }; + // we got supplied an image, shit + fs->root->len = opts.rootEntriesInImage; + for(int i = 0; i < opts.rootEntriesInImage; i++) { + nn_vfnode *entry = nni_vfsimg_parseNode(fs, &stream); + fs->root->entries[i] = entry; + } + } + nn_filesystemTable table = { .userdata = fs, .deinit = (void *)nn_vfs_deinit, diff --git a/src/emulator.c b/src/emulator.c index 3e8e785..3ab7df2 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -671,6 +671,14 @@ int main() { nn_filesystem *genericFS = nn_newFilesystem(&ctx, genericFSTable, ne_fs_ctrl); nn_addFileSystem(computer, NULL, 1, genericFS); + nn_vfilesystemImageNode tmpfsImg[] = { + (nn_vfilesystemImageNode) { + .name = "testScript.lua", + .data = "print('Hello, world!')", + .len = nn_strlen("print('Hello, world!')"), + }, + }; + nn_vfilesystemOptions tmpfsOpts = { .isReadOnly = false, .capacity = 64*1024, @@ -678,6 +686,8 @@ int main() { .labelLen = 5, .creationTime = 0, // we are at the start of time .maxDirEntries = 64, + .image = tmpfsImg, + .rootEntriesInImage = 1, }; nn_filesystem *tmpFS = nn_volatileFilesystem(&ctx, tmpfsOpts, ne_fs_ctrl); diff --git a/src/neonucleus.h b/src/neonucleus.h index d247368..28cb79b 100644 --- a/src/neonucleus.h +++ b/src/neonucleus.h @@ -727,6 +727,14 @@ typedef struct nn_filesystemTable { typedef struct nn_filesystem nn_filesystem; +typedef struct nn_vfilesystemImageNode { + const char *name; + // if NULL, the node is a directory + const char *data; + // if it is a directory, this is the amount of entries encoded afterwards + nn_size_t len; +} nn_vfilesystemImageNode; + typedef struct nn_vfilesystemOptions { // used to compute lastModified nn_size_t creationTime; @@ -735,6 +743,9 @@ typedef struct nn_vfilesystemOptions { nn_bool_t isReadOnly; char label[NN_LABEL_SIZE]; nn_size_t labelLen; + // loading the files into the tmpfs + nn_vfilesystemImageNode *image; + nn_size_t rootEntriesInImage; } nn_vfilesystemOptions; nn_filesystem *nn_newFilesystem(nn_Context *context, nn_filesystemTable table, nn_filesystemControl control);