|
@@ -1,131 +0,0 @@
|
|
|
-#include "pocketpy/interpreter/vfs.h"
|
|
|
|
|
-#include "pocketpy/interpreter/vm.h"
|
|
|
|
|
-
|
|
|
|
|
-#define SMALLMAP_T__SOURCE
|
|
|
|
|
-#define K c11_sv
|
|
|
|
|
-#define V VfsEntry
|
|
|
|
|
-#define NAME VfsDir
|
|
|
|
|
-#define less(a, b) (c11_sv__cmp((a), (b)) < 0)
|
|
|
|
|
-#define equal(a, b) (c11_sv__cmp((a), (b)) == 0)
|
|
|
|
|
-#include "pocketpy/xmacros/smallmap.h"
|
|
|
|
|
-#undef SMALLMAP_T__SOURCE
|
|
|
|
|
-
|
|
|
|
|
-static VfsEntry* Vfs__get(const char* path) {
|
|
|
|
|
- c11_vector /*T=c11_sv*/ cpnts = c11_sv__split((c11_sv){path, strlen(path)}, '/');
|
|
|
|
|
-
|
|
|
|
|
- VfsEntry* root = &pk_current_vm->__vfs.root;
|
|
|
|
|
- for(int i = 0; i < cpnts.count; i++) {
|
|
|
|
|
- c11_sv cpnt = c11__getitem(c11_sv, &cpnts, i);
|
|
|
|
|
- VfsEntry* entry = VfsDir__try_get(&root->_dir, cpnt);
|
|
|
|
|
- if(entry == NULL) {
|
|
|
|
|
- c11_vector__dtor(&cpnts);
|
|
|
|
|
- return NULL;
|
|
|
|
|
- }
|
|
|
|
|
- if(entry->is_file) {
|
|
|
|
|
- VfsEntry* retval = i == cpnts.count - 1 ? entry : NULL;
|
|
|
|
|
- c11_vector__dtor(&cpnts);
|
|
|
|
|
- return retval;
|
|
|
|
|
- } else {
|
|
|
|
|
- root = entry;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- c11_vector__dtor(&cpnts);
|
|
|
|
|
- return root;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-static void VfsDir__delete_recursively(VfsDir* self) {
|
|
|
|
|
- for(int i = 0; i < self->count; i++) {
|
|
|
|
|
- VfsDir_KV* kv = c11__at(VfsDir_KV, self, i);
|
|
|
|
|
- free((char*)kv->key.data);
|
|
|
|
|
- if(kv->value.is_file) {
|
|
|
|
|
- free(kv->value._file.data);
|
|
|
|
|
- } else {
|
|
|
|
|
- VfsDir__delete_recursively(&kv->value._dir);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- VfsDir__dtor(self);
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-void Vfs__ctor(Vfs* self) {
|
|
|
|
|
- self->root.is_file = false;
|
|
|
|
|
- VfsDir__ctor(&self->root._dir);
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-void Vfs__dtor(Vfs* self) { VfsDir__delete_recursively(&self->root._dir); }
|
|
|
|
|
-
|
|
|
|
|
-unsigned char* py_vfsread(const char* path, int* size) {
|
|
|
|
|
- VfsEntry* entry = Vfs__get(path);
|
|
|
|
|
- if(entry == NULL || !entry->is_file) return NULL;
|
|
|
|
|
- *size = entry->_file.size;
|
|
|
|
|
- unsigned char* retval = malloc(*size);
|
|
|
|
|
- memcpy(retval, entry->_file.data, *size);
|
|
|
|
|
- return retval;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-static void VfsDir__dupset(VfsDir* self, c11_sv key, VfsEntry value) {
|
|
|
|
|
- char* p = malloc(key.size);
|
|
|
|
|
- memcpy(p, key.data, key.size);
|
|
|
|
|
- VfsDir__set(self, (c11_sv){p, key.size}, value);
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-bool py_vfswrite(const char* path, unsigned char* data, int size) {
|
|
|
|
|
- c11_vector /*T=c11_sv*/ cpnts = c11_sv__split((c11_sv){path, strlen(path)}, '/');
|
|
|
|
|
- VfsEntry* root = &pk_current_vm->__vfs.root;
|
|
|
|
|
- for(int i = 0; i < cpnts.count; i++) {
|
|
|
|
|
- c11_sv cpnt = c11__getitem(c11_sv, &cpnts, i);
|
|
|
|
|
- VfsEntry* entry = VfsDir__try_get(&root->_dir, cpnt);
|
|
|
|
|
- if(entry == NULL) {
|
|
|
|
|
- if(i == cpnts.count - 1) {
|
|
|
|
|
- // create file
|
|
|
|
|
- VfsEntry entry = {
|
|
|
|
|
- .is_file = true,
|
|
|
|
|
- ._file.size = size,
|
|
|
|
|
- ._file.data = data,
|
|
|
|
|
- };
|
|
|
|
|
- VfsDir__dupset(&root->_dir, cpnt, entry);
|
|
|
|
|
- c11_vector__dtor(&cpnts);
|
|
|
|
|
- return true;
|
|
|
|
|
- } else {
|
|
|
|
|
- // create missing directory
|
|
|
|
|
- VfsEntry entry = {
|
|
|
|
|
- .is_file = false,
|
|
|
|
|
- };
|
|
|
|
|
- VfsDir__ctor(&entry._dir);
|
|
|
|
|
- VfsDir__dupset(&root->_dir, cpnt, entry);
|
|
|
|
|
- }
|
|
|
|
|
- } else {
|
|
|
|
|
- if(i == cpnts.count - 1) {
|
|
|
|
|
- if(!entry->is_file) break;
|
|
|
|
|
- // update file
|
|
|
|
|
- free(entry->_file.data);
|
|
|
|
|
- entry->_file.size = size;
|
|
|
|
|
- entry->_file.data = data;
|
|
|
|
|
- c11_vector__dtor(&cpnts);
|
|
|
|
|
- return true;
|
|
|
|
|
- } else {
|
|
|
|
|
- if(entry->is_file) break;
|
|
|
|
|
- root = entry;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- c11_vector__dtor(&cpnts);
|
|
|
|
|
- return false;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-char** py_vfslist(const char* path, int* length) {
|
|
|
|
|
- VfsEntry* entry = Vfs__get(path);
|
|
|
|
|
- if(entry == NULL || entry->is_file) return NULL;
|
|
|
|
|
- *length = 0;
|
|
|
|
|
- char** ret = malloc(sizeof(char*) * entry->_dir.count);
|
|
|
|
|
- for(int i = 0; i < entry->_dir.count; i++) {
|
|
|
|
|
- VfsDir_KV* child = c11__at(VfsDir_KV, &entry->_dir, i);
|
|
|
|
|
- if(child->value.is_file) {
|
|
|
|
|
- int size = child->key.size;
|
|
|
|
|
- ret[i] = malloc(size + 1);
|
|
|
|
|
- memcpy(ret[i], child->key.data, size);
|
|
|
|
|
- ret[i][size] = '\0';
|
|
|
|
|
- (*length)++;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return ret;
|
|
|
|
|
-}
|
|
|