remove physfs; cellfs now is at parity
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
var nota = use('nota')
|
||||
var os = use('os')
|
||||
var io = use('io')
|
||||
var io = use('cellfs')
|
||||
|
||||
var ll = io.slurp('benchmarks/nota.json')
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ The ```config.js``` module must return a single object that describes your game.
|
||||
| **url** | `"https://github.com/johnbrethauer/prosperon"` | string | URL link associated with the project, such as a repository or official homepage. |
|
||||
|
||||
|
||||
With the engine configured, prosperon starts ```main.js``` as the first **actor** of the game. Actors are created from files that **do not** return a value. An actor executes the statements in its script. Initialization should happen here. An actor can pull in other chunks of code by importing modules. Modules are imported with the ```use``` statement. ```use``` returns the value the module returned, and it can be assigned to any variable. To use the internal ```io``` module, for example, you might say ```var io = use('io')```.
|
||||
With the engine configured, prosperon starts ```main.js``` as the first **actor** of the game. Actors are created from files that **do not** return a value. An actor executes the statements in its script. Initialization should happen here. An actor can pull in other chunks of code by importing modules. Modules are imported with the ```use``` statement. ```use``` returns the value the module returned, and it can be assigned to any variable. To use the internal ```io``` module, for example, you might say ```var io = use('cellfs')```.
|
||||
|
||||
Actors exist until they are explicitly killed, by invoking their ```kill``` function. Because the actor created from ```main.js``` is the root actor for the entire game, when it is killed, the program exits. In an actor script file, ```this``` is set to the actor being spawned from the script.
|
||||
|
||||
|
||||
12
meson.build
12
meson.build
@@ -175,18 +175,8 @@ else
|
||||
deps += miniz_dep
|
||||
endif
|
||||
|
||||
# Try to find system-installed physfs first
|
||||
physfs_dep = dependency('physfs', static: true, required: false)
|
||||
if not physfs_dep.found()
|
||||
message('⚙ System physfs not found, building subproject...')
|
||||
deps += dependency('physfs', static:true)
|
||||
else
|
||||
deps += physfs_dep
|
||||
endif
|
||||
|
||||
deps += dependency('threads')
|
||||
|
||||
|
||||
# Try to find system-installed chipmunk first
|
||||
chipmunk_dep = dependency('chipmunk', static: true, required: false)
|
||||
if not chipmunk_dep.found()
|
||||
@@ -276,7 +266,7 @@ src += [
|
||||
'jsffi.c',
|
||||
'cell.c',
|
||||
'wildmatch.c',
|
||||
'qjs_io.c',
|
||||
'qjs_wildstar.c',
|
||||
'qjs_fd.c',
|
||||
'qjs_qop.c',
|
||||
'qjs_os.c',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// cell build – Compile all .cm and .ce files to bytecode
|
||||
|
||||
var io = use('io')
|
||||
var io = use('cellfs')
|
||||
var js = use('js')
|
||||
var time = use('time')
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ var cellfs = this
|
||||
|
||||
var fd = use('fd')
|
||||
var miniz = use('miniz')
|
||||
var wildstar = use('wildstar')
|
||||
|
||||
// Internal state
|
||||
var mounts = [] // Array of {source, type, handle, name}
|
||||
@@ -54,7 +55,28 @@ function mount_exists(mount, path) {
|
||||
var full_path = join_paths(mount.source, path)
|
||||
try {
|
||||
var st = fd.stat(full_path)
|
||||
return st.isFile
|
||||
return st.isFile || st.isDirectory
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if a path refers to a directory in a specific mount
|
||||
function is_directory(path) {
|
||||
var res = resolve(path)
|
||||
var mount = res.mount
|
||||
if (mount.type == 'zip') {
|
||||
try {
|
||||
return mount.handle.is_directory(path);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
} else { // fs
|
||||
var full_path = join_paths(mount.source, path)
|
||||
try {
|
||||
var st = fd.stat(full_path)
|
||||
return st.isDirectory
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
@@ -230,6 +252,137 @@ function mount_package(name) {
|
||||
mount(dir, name)
|
||||
}
|
||||
|
||||
// New functions for qjs_io compatibility
|
||||
|
||||
function match(str, pattern) {
|
||||
return wildstar.match(pattern, str, wildstar.WM_PATHNAME | wildstar.WM_PERIOD | wildstar.WM_WILDSTAR)
|
||||
}
|
||||
|
||||
function rm(path) {
|
||||
var res = resolve(path, true)
|
||||
if (res.mount.type != 'fs') throw new Error("Cannot delete from non-fs mount")
|
||||
|
||||
var full_path = join_paths(res.mount.source, res.path)
|
||||
var st = fd.stat(full_path)
|
||||
if (st.isDirectory) fd.rmdir(full_path)
|
||||
else fd.unlink(full_path)
|
||||
}
|
||||
|
||||
function mkdir(path) {
|
||||
var full = join_paths(writepath, path)
|
||||
fd.mkdir(full)
|
||||
}
|
||||
|
||||
function set_writepath(path) {
|
||||
writepath = path
|
||||
}
|
||||
|
||||
function basedir() {
|
||||
return fd.getcwd()
|
||||
}
|
||||
|
||||
function prefdir(org, app) {
|
||||
return "./"
|
||||
}
|
||||
|
||||
function realdir(path) {
|
||||
var res = resolve(path, false)
|
||||
if (!res) return null
|
||||
return join_paths(res.mount.source, res.path)
|
||||
}
|
||||
|
||||
function enumerate(path, recurse) {
|
||||
if (path == null) path = ""
|
||||
|
||||
var res = resolve(path, true)
|
||||
var results = []
|
||||
|
||||
function visit(curr_full, rel_prefix) {
|
||||
var list = fd.readdir(curr_full)
|
||||
if (!list) return
|
||||
|
||||
for (var item of list) {
|
||||
var item_rel = rel_prefix ? rel_prefix + "/" + item : item
|
||||
results.push(item_rel)
|
||||
|
||||
if (recurse) {
|
||||
var st = fd.stat(join_paths(curr_full, item))
|
||||
if (st.isDirectory) {
|
||||
visit(join_paths(curr_full, item), item_rel)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (res.mount.type == 'fs') {
|
||||
var full = join_paths(res.mount.source, res.path)
|
||||
var st = fd.stat(full)
|
||||
if (st && st.isDirectory) {
|
||||
visit(full, "")
|
||||
}
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
function globfs(globs, dir) {
|
||||
if (dir == null) dir = ""
|
||||
var res = resolve(dir, true)
|
||||
var results = []
|
||||
|
||||
function check_neg(path) {
|
||||
for (var g of globs) {
|
||||
if (g.startsWith("!") && wildstar.match(g.substring(1), path, wildstar.WM_WILDSTAR)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function check_pos(path) {
|
||||
for (var g of globs) {
|
||||
if (!g.startsWith("!") && wildstar.match(g, path, wildstar.WM_WILDSTAR)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function visit(curr_full, rel_prefix) {
|
||||
if (rel_prefix && check_neg(rel_prefix)) return
|
||||
|
||||
var list = fd.readdir(curr_full)
|
||||
if (!list) return
|
||||
|
||||
for (var item of list) {
|
||||
var item_rel = rel_prefix ? rel_prefix + "/" + item : item
|
||||
|
||||
var child_full = join_paths(curr_full, item)
|
||||
var st = fd.stat(child_full)
|
||||
|
||||
if (st.isDirectory) {
|
||||
if (!check_neg(item_rel)) {
|
||||
visit(child_full, item_rel)
|
||||
}
|
||||
} else {
|
||||
if (!check_neg(item_rel) && check_pos(item_rel)) {
|
||||
results.push(item_rel)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (res.mount.type == 'fs') {
|
||||
var full = join_paths(res.mount.source, res.path)
|
||||
var st = fd.stat(full)
|
||||
if (st && st.isDirectory) {
|
||||
visit(full, "")
|
||||
}
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
function slurpbytes(path) {
|
||||
return slurp(path)
|
||||
}
|
||||
|
||||
// Exports
|
||||
cellfs.mount = mount
|
||||
cellfs.mount_package = mount_package
|
||||
@@ -237,7 +390,20 @@ cellfs.unmount = unmount
|
||||
cellfs.slurp = slurp
|
||||
cellfs.slurpwrite = slurpwrite
|
||||
cellfs.exists = exists
|
||||
cellfs.is_directory = is_directory
|
||||
cellfs.stat = stat
|
||||
cellfs.searchpath = searchpath
|
||||
cellfs.match = match
|
||||
cellfs.enumerate = enumerate
|
||||
cellfs.globfs = globfs
|
||||
cellfs.rm = rm
|
||||
cellfs.mkdir = mkdir
|
||||
cellfs.writepath = set_writepath
|
||||
cellfs.basedir = basedir
|
||||
cellfs.prefdir = prefdir
|
||||
cellfs.realdir = realdir
|
||||
cellfs.slurpbytes = slurpbytes
|
||||
|
||||
cellfs.mount('.')
|
||||
|
||||
return cellfs
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// cell clean - Remove build artifacts from modules/
|
||||
|
||||
var io = use('io')
|
||||
var io = use('cellfs')
|
||||
|
||||
log.console(io.searchpath())
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// cell config - Manage system and actor configurations
|
||||
|
||||
var io = use('io')
|
||||
var io = use('cellfs')
|
||||
var toml = use('toml')
|
||||
var shop = use('shop')
|
||||
var text = use('text')
|
||||
|
||||
@@ -150,7 +150,6 @@ function disrupt(err)
|
||||
actor_mod.on_exception(disrupt)
|
||||
|
||||
var js = use_embed('js')
|
||||
var io = use_embed('io')
|
||||
|
||||
var use_cache = {}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
var graphics = this
|
||||
|
||||
var io = use('io')
|
||||
var io = use('cellfs')
|
||||
var time = use('time')
|
||||
var res = use('resources')
|
||||
var json = use('json')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// cell init - Initialize a new .cell program shop
|
||||
|
||||
var io = use('io')
|
||||
var io = use('cellfs')
|
||||
var shop = use('shop')
|
||||
|
||||
// Initialize the .cell directory structure
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
var json = {}
|
||||
var utf8 = use('utf8')
|
||||
|
||||
json.encode = function encode(val,replacer,space = 1,whitelist)
|
||||
{
|
||||
@@ -13,6 +14,10 @@ If the space input is true, then line breaks and extra whitespace will be includ
|
||||
|
||||
json.decode = function decode(text,reviver)
|
||||
{
|
||||
if (typeof text != 'string') {
|
||||
text = utf8.decode(text)
|
||||
if (!text) throw new Error("couldn't parse text: not a string")
|
||||
}
|
||||
return JSON.parse(text,reviver)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
var shop = use('shop')
|
||||
var io = use('io')
|
||||
var io = use('cellfs')
|
||||
|
||||
// Initialize shop if needed
|
||||
if (!shop.init()) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// cell patch <module> - Create a patch for a module
|
||||
|
||||
var io = use('io')
|
||||
var io = use('cellfs')
|
||||
var shop = use('shop')
|
||||
|
||||
if (args.length < 1) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var io = use('io')
|
||||
var io = use('cellfs')
|
||||
|
||||
Object.defineProperty(Function.prototype, "hashify", {
|
||||
value: function () {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// cell vendor - Copy all dependencies into modules/ for hermetic builds
|
||||
|
||||
var io = use('io')
|
||||
var io = use('cellfs')
|
||||
var shop = use('shop')
|
||||
|
||||
if (!io.exists('.cell/shop.toml')) {
|
||||
|
||||
@@ -991,8 +991,6 @@ int main(int argc, char **argv)
|
||||
tracy_profiling_enabled = profile_enabled;
|
||||
#endif
|
||||
|
||||
PHYSFS_init(argv[0]);
|
||||
|
||||
/* Load QOP package attached to executable - this is now mandatory! */
|
||||
int mounted = prosperon_mount_core();
|
||||
if (!mounted) {
|
||||
@@ -1014,7 +1012,6 @@ int main(int argc, char **argv)
|
||||
for (int i = 1; i < actor_argc; i++)
|
||||
wota_write_text(&startwota, actor_argv[i]);
|
||||
|
||||
|
||||
/* Initialize synchronization primitives */
|
||||
ready_sem = SDL_CreateSemaphore(0);
|
||||
main_sem = SDL_CreateSemaphore(0);
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include "qjs_geometry.h"
|
||||
#include "qjs_transform.h"
|
||||
#include "qjs_sprite.h"
|
||||
#include "qjs_io.h"
|
||||
#include "qjs_sdl_gpu.h"
|
||||
#include "qjs_os.h"
|
||||
#include "qjs_actor.h"
|
||||
@@ -49,7 +48,7 @@
|
||||
#include "qjs_fit.h"
|
||||
#include "qjs_text.h"
|
||||
#include "qjs_staef.h"
|
||||
#include "qjs_io.h"
|
||||
#include "qjs_wildstar.h"
|
||||
#include "qjs_fd.h"
|
||||
|
||||
#include "qjs_qop.h"
|
||||
@@ -1120,7 +1119,7 @@ void ffi_load(JSContext *js)
|
||||
arrput(rt->module_registry, MISTLINE(blob));
|
||||
|
||||
// extra
|
||||
arrput(rt->module_registry, ((ModuleEntry){"io", js_io_use}));
|
||||
arrput(rt->module_registry, MISTLINE(wildstar));
|
||||
arrput(rt->module_registry, ((ModuleEntry){"fd", js_fd_use}));
|
||||
arrput(rt->module_registry, ((ModuleEntry){"qop", js_qop_use}));
|
||||
arrput(rt->module_registry, ((ModuleEntry){"os", js_os_use}));
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <windows.h>
|
||||
#define mkdir(path, mode) _mkdir(path)
|
||||
#define rmdir _rmdir
|
||||
#define unlink _unlink
|
||||
#define getcwd _getcwd
|
||||
#define PATH_MAX _MAX_PATH
|
||||
#define fsync(fd) _commit(fd)
|
||||
@@ -206,6 +207,11 @@ JSC_SCALL(fd_mkdir,
|
||||
ret = JS_ThrowReferenceError(js, "could not make directory %s: %s", str, strerror(errno));
|
||||
)
|
||||
|
||||
JSC_SCALL(fd_unlink,
|
||||
if (unlink(str) != 0)
|
||||
ret = JS_ThrowReferenceError(js, "could not remove file %s: %s", str, strerror(errno));
|
||||
)
|
||||
|
||||
JSC_CCALL(fd_fsync,
|
||||
int fd = js2fd(js, argv[0]);
|
||||
if (fd < 0) return JS_EXCEPTION;
|
||||
@@ -304,6 +310,41 @@ JSC_SCALL(fd_stat,
|
||||
return obj;
|
||||
)
|
||||
|
||||
JSC_SCALL(fd_readdir,
|
||||
#ifdef _WIN32
|
||||
WIN32_FIND_DATA ffd;
|
||||
char path[PATH_MAX];
|
||||
snprintf(path, sizeof(path), "%s\\*", str);
|
||||
HANDLE hFind = FindFirstFile(path, &ffd);
|
||||
if (hFind == INVALID_HANDLE_VALUE) {
|
||||
ret = JS_ThrowReferenceError(js, "FindFirstFile failed for %s", path);
|
||||
} else {
|
||||
ret = JS_NewArray(js);
|
||||
int i = 0;
|
||||
do {
|
||||
if (strcmp(ffd.cFileName, ".") == 0 || strcmp(ffd.cFileName, "..") == 0) continue;
|
||||
JS_SetPropertyUint32(js, ret, i++, JS_NewString(js, ffd.cFileName));
|
||||
} while (FindNextFile(hFind, &ffd) != 0);
|
||||
FindClose(hFind);
|
||||
}
|
||||
#else
|
||||
DIR *d;
|
||||
struct dirent *dir;
|
||||
d = opendir(str);
|
||||
if (d) {
|
||||
ret = JS_NewArray(js);
|
||||
int i = 0;
|
||||
while ((dir = readdir(d)) != NULL) {
|
||||
if (strcmp(dir->d_name, ".") == 0 || strcmp(dir->d_name, "..") == 0) continue;
|
||||
JS_SetPropertyUint32(js, ret, i++, JS_NewString(js, dir->d_name));
|
||||
}
|
||||
closedir(d);
|
||||
} else {
|
||||
ret = JS_ThrowReferenceError(js, "opendir failed for %s: %s", str, strerror(errno));
|
||||
}
|
||||
#endif
|
||||
)
|
||||
|
||||
static const JSCFunctionListEntry js_fd_funcs[] = {
|
||||
MIST_FUNC_DEF(fd, open, 2),
|
||||
MIST_FUNC_DEF(fd, write, 2),
|
||||
@@ -312,11 +353,13 @@ static const JSCFunctionListEntry js_fd_funcs[] = {
|
||||
MIST_FUNC_DEF(fd, lseek, 3),
|
||||
MIST_FUNC_DEF(fd, getcwd, 0),
|
||||
MIST_FUNC_DEF(fd, rmdir, 1),
|
||||
MIST_FUNC_DEF(fd, unlink, 1),
|
||||
MIST_FUNC_DEF(fd, mkdir, 1),
|
||||
MIST_FUNC_DEF(fd, fsync, 1),
|
||||
MIST_FUNC_DEF(fd, close, 1),
|
||||
MIST_FUNC_DEF(fd, stat, 1),
|
||||
MIST_FUNC_DEF(fd, fstat, 1),
|
||||
MIST_FUNC_DEF(fd, readdir, 1),
|
||||
};
|
||||
|
||||
JSValue js_fd_use(JSContext *js) {
|
||||
|
||||
429
source/qjs_io.c
429
source/qjs_io.c
@@ -1,429 +0,0 @@
|
||||
#include "qjs_io.h"
|
||||
#include "jsffi.h"
|
||||
#include "qjs_macros.h"
|
||||
#include "cell.h"
|
||||
|
||||
#include "qjs_blob.h"
|
||||
|
||||
#include <physfs.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "wildmatch.h"
|
||||
|
||||
// Helper function for array length using QuickJS
|
||||
// JS_ArrayLength removed - use JS_ArrayLength directly
|
||||
|
||||
// PHYSFS_File free function
|
||||
static void PHYSFS_File_free(JSRuntime *rt, PHYSFS_File *f)
|
||||
{
|
||||
PHYSFS_close(f);
|
||||
}
|
||||
|
||||
// Class definition for PHYSFS_File
|
||||
QJSCLASS(PHYSFS_File,)
|
||||
|
||||
// Helper function for writing to PHYSFS
|
||||
static size_t js_physfs_write(JSContext *js, PHYSFS_File *f, JSValue val)
|
||||
{
|
||||
size_t len;
|
||||
size_t wrote;
|
||||
if (JS_IsString(val)) {
|
||||
const char *data = JS_ToCStringLen(js,&len,val);
|
||||
wrote = PHYSFS_writeBytes(f,data,len);
|
||||
JS_FreeCString(js,data);
|
||||
} else {
|
||||
unsigned char *data = js_get_blob_data(js,&len,val);
|
||||
wrote = PHYSFS_writeBytes(f,data,len);
|
||||
}
|
||||
|
||||
if (wrote < len) wrote = -1;
|
||||
return wrote;
|
||||
}
|
||||
|
||||
// Glob data structure for filesystem operations
|
||||
struct globdata {
|
||||
JSContext *js;
|
||||
JSValue arr;
|
||||
char **globs;
|
||||
char *glob;
|
||||
int idx;
|
||||
int recurse;
|
||||
};
|
||||
|
||||
// Callback for enumerate
|
||||
static int enumerate_cb(void *udata, const char *dir, const char *fname)
|
||||
{
|
||||
struct globdata *data = (struct globdata*)udata;
|
||||
char *path;
|
||||
int needfree = 0;
|
||||
|
||||
if (dir[0] == 0) path = (char*)fname;
|
||||
else {
|
||||
size_t dlen = strlen(dir);
|
||||
int ends_slash = (dlen && dir[dlen - 1] == '/');
|
||||
path = malloc(dlen + strlen(fname) + (ends_slash ? 1 : 2));
|
||||
if (ends_slash) sprintf(path, "%s%s", dir, fname); else sprintf(path, "%s/%s", dir, fname);
|
||||
needfree = 1;
|
||||
}
|
||||
|
||||
PHYSFS_Stat st;
|
||||
if (!PHYSFS_stat(path, &st)) {
|
||||
if (needfree) free(path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* If it's a directory and we're recursing, enumerate it further. */
|
||||
if (st.filetype == PHYSFS_FILETYPE_DIRECTORY && data->recurse)
|
||||
PHYSFS_enumerate(path, enumerate_cb, data);
|
||||
|
||||
/* Add this item (file or directory) to the JS array. */
|
||||
JS_SetPropertyUint32(data->js, data->arr, data->idx++, JS_NewString(data->js, path));
|
||||
|
||||
if (needfree) free(path);
|
||||
return 1; /* continue enumerating */
|
||||
}
|
||||
|
||||
// I/O FUNCTIONS
|
||||
|
||||
JSC_SCALL(io_rm,
|
||||
if (!PHYSFS_delete(str)) ret = JS_ThrowReferenceError(js,"could not remove %s. %s", str, PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
)
|
||||
|
||||
JSC_SCALL(io_mkdir,
|
||||
if (!PHYSFS_mkdir(str)) ret = JS_ThrowReferenceError(js,"could not make directory %s. %s", str, PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
)
|
||||
|
||||
JSC_SCALL(io_exists, ret = JS_NewBool(js,PHYSFS_exists(str)); )
|
||||
|
||||
JSC_SCALL(io_stat,
|
||||
PHYSFS_Stat stat;
|
||||
if (!PHYSFS_stat(str, &stat))
|
||||
return JS_ThrowReferenceError(js, "%s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
|
||||
ret = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js,ret,"filesize", number2js(js,stat.filesize));
|
||||
JS_SetPropertyStr(js,ret,"modtime", number2js(js,stat.modtime));
|
||||
JS_SetPropertyStr(js,ret,"createtime", number2js(js,stat.createtime));
|
||||
JS_SetPropertyStr(js,ret,"accesstime", number2js(js,stat.accesstime));
|
||||
)
|
||||
|
||||
JSC_SCALL(io_slurpbytes,
|
||||
PHYSFS_File *f = PHYSFS_openRead(str);
|
||||
if (!f) {
|
||||
ret = JS_ThrowReferenceError(js,"physfs error when slurping %s: %s", str, PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
goto END;
|
||||
}
|
||||
PHYSFS_Stat stat;
|
||||
PHYSFS_stat(str,&stat);
|
||||
void *data = malloc(stat.filesize);
|
||||
PHYSFS_readBytes(f,data,stat.filesize);
|
||||
PHYSFS_close(f);
|
||||
ret = js_new_blob_stoned_copy(js,data,stat.filesize);
|
||||
|
||||
END:
|
||||
)
|
||||
|
||||
JSC_SCALL(io_slurp,
|
||||
PHYSFS_File *f = PHYSFS_openRead(str);
|
||||
if (!f) {
|
||||
ret = JS_ThrowReferenceError(js,"physfs error when slurping %s: %s", str, PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
goto END;
|
||||
}
|
||||
PHYSFS_Stat stat;
|
||||
PHYSFS_stat(str,&stat);
|
||||
void *data = malloc(stat.filesize);
|
||||
PHYSFS_readBytes(f,data,stat.filesize);
|
||||
PHYSFS_close(f);
|
||||
ret = JS_NewStringLen(js,data, stat.filesize);
|
||||
|
||||
free(data);
|
||||
|
||||
END:
|
||||
)
|
||||
|
||||
JSC_SCALL(io_slurpwrite,
|
||||
PHYSFS_File *f = PHYSFS_openWrite(str);
|
||||
if (!f) {
|
||||
ret = JS_ThrowReferenceError(js,"could not write to %s: %s", str, PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
goto END;
|
||||
}
|
||||
size_t wrote = js_physfs_write(js,f,argv[1]);
|
||||
|
||||
PHYSFS_close(f);
|
||||
if (wrote == -1)
|
||||
ret = JS_ThrowReferenceError(js,"%s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
|
||||
END:
|
||||
)
|
||||
|
||||
JSC_CCALL(io_mount,
|
||||
const char *src = JS_ToCString(js, argv[0]);
|
||||
const char *mountpoint;
|
||||
if (JS_IsNull(argv[1]))
|
||||
mountpoint = NULL;
|
||||
else
|
||||
mountpoint = JS_ToCString(js, argv[1]);
|
||||
|
||||
int prepend = 0;
|
||||
|
||||
if (argc > 2 && !JS_IsNull(argv[2]))
|
||||
prepend = JS_ToBool(js, argv[2]);
|
||||
|
||||
if (!PHYSFS_mount(src, mountpoint, prepend))
|
||||
ret = JS_ThrowReferenceError(js,"Unable to mount %s at %s: %s", src, mountpoint, PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
|
||||
JS_FreeCString(js, src);
|
||||
if (mountpoint)
|
||||
JS_FreeCString(js, mountpoint);
|
||||
)
|
||||
|
||||
JSC_SCALL(io_unmount,
|
||||
if (!PHYSFS_unmount(str)) ret = JS_ThrowReferenceError(js,"%s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
)
|
||||
|
||||
JSC_SCALL(io_writepath,
|
||||
if (!PHYSFS_setWriteDir(str)) ret = JS_ThrowReferenceError(js,"%s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
)
|
||||
|
||||
JSC_SSCALL(io_match,
|
||||
if (wildmatch(str, str2, WM_PATHNAME | WM_PERIOD | WM_WILDSTAR) == WM_MATCH)
|
||||
ret = JS_NewBool(js,1);
|
||||
else
|
||||
ret = JS_NewBool(js,0);
|
||||
)
|
||||
|
||||
// Callback for globfs, with support for negative patterns (e.g. "!**/.git")
|
||||
static int globfs_cb(struct globdata *data, char *dir, char *file)
|
||||
{
|
||||
int needfree = 0;
|
||||
char *path;
|
||||
PHYSFS_Stat stat;
|
||||
char **glob;
|
||||
|
||||
if (dir[0] == 0)
|
||||
path = file;
|
||||
else {
|
||||
path = malloc(strlen(dir) + strlen(file) + 2);
|
||||
path[0] = 0;
|
||||
strcat(path, dir);
|
||||
strcat(path, "/");
|
||||
strcat(path, file);
|
||||
needfree = 1;
|
||||
}
|
||||
|
||||
// Grab filetype now
|
||||
PHYSFS_stat(path, &stat);
|
||||
|
||||
if (stat.filetype == PHYSFS_FILETYPE_DIRECTORY) {
|
||||
// Check negative patterns first: if directory matches a "!…" pattern, skip it
|
||||
for (glob = data->globs; *glob != NULL; glob++) {
|
||||
if ((*glob)[0] == '!') {
|
||||
const char *neg_pattern = (*glob) + 1;
|
||||
if (wildmatch(neg_pattern, path, WM_WILDSTAR) == WM_MATCH)
|
||||
goto END;
|
||||
}
|
||||
}
|
||||
// Not excluded: recurse into this directory
|
||||
PHYSFS_enumerate(path, globfs_cb, data);
|
||||
goto END;
|
||||
}
|
||||
|
||||
// It's a file—first see if it matches any negative pattern
|
||||
for (glob = data->globs; *glob != NULL; glob++) {
|
||||
if ((*glob)[0] == '!') {
|
||||
const char *neg_pattern = (*glob) + 1;
|
||||
if (wildmatch(neg_pattern, path, WM_WILDSTAR) == WM_MATCH)
|
||||
goto END;
|
||||
}
|
||||
}
|
||||
|
||||
// Now check positive patterns ("**/*.cm", "**/*.ce", etc.)
|
||||
for (glob = data->globs; *glob != NULL; glob++) {
|
||||
if ((*glob)[0] == '!')
|
||||
continue;
|
||||
if (wildmatch(*glob, path, WM_WILDSTAR) == WM_MATCH) {
|
||||
JS_SetPropertyUint32(data->js,
|
||||
data->arr,
|
||||
data->idx++,
|
||||
JS_NewString(data->js, path));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
END:
|
||||
if (needfree)
|
||||
free(path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// arg0: glob patterns (array of strings)
|
||||
// arg1: directory (string)
|
||||
JSC_CCALL(io_globfs,
|
||||
ret = JS_NewArray(js);
|
||||
struct globdata data;
|
||||
data.js = js;
|
||||
data.arr = ret;
|
||||
data.idx = 0;
|
||||
int globs_len = JS_ArrayLength(js,argv[0]);
|
||||
const char *globs[globs_len+1];
|
||||
for (int i = 0; i < globs_len; i++) {
|
||||
JSValue g = JS_GetPropertyUint32(js,argv[0],i);
|
||||
globs[i] = JS_ToCString(js,g);
|
||||
JS_FreeValue(js,g);
|
||||
}
|
||||
|
||||
globs[globs_len] = NULL;
|
||||
data.globs = globs;
|
||||
|
||||
const char *path = NULL;
|
||||
if (!JS_IsNull(argv[1])) path = JS_ToCString(js,argv[1]);
|
||||
PHYSFS_enumerate(path, globfs_cb, &data);
|
||||
|
||||
for (int i = 0; i < globs_len; i++)
|
||||
JS_FreeCString(js,globs[i]);
|
||||
|
||||
ret = data.arr;
|
||||
JS_FreeCString(js,path);
|
||||
)
|
||||
|
||||
JSC_SCALL(io_enumerate,
|
||||
/* First argument: str (directory name) */
|
||||
/* Second argument: boolean => recurse or not */
|
||||
ret = JS_NewArray(js);
|
||||
|
||||
struct globdata data;
|
||||
data.js = js;
|
||||
data.arr = ret;
|
||||
data.idx = 0;
|
||||
data.glob = NULL; /* not used here */
|
||||
data.globs = NULL; /* not used here */
|
||||
data.recurse = 0;
|
||||
|
||||
if (!JS_IsNull(argv[1])) /* parse second arg if provided */
|
||||
data.recurse = JS_ToBool(js, argv[1]);
|
||||
|
||||
/* Enumerate the directory given by 'str'. */
|
||||
PHYSFS_enumerate(str, enumerate_cb, &data);
|
||||
|
||||
/* Return the JS array we filled. */
|
||||
ret = data.arr;
|
||||
)
|
||||
|
||||
JSC_CCALL(io_basedir, return JS_NewString(js,PHYSFS_getBaseDir()))
|
||||
|
||||
JSC_SSCALL(io_prefdir, return JS_NewString(js,PHYSFS_getPrefDir(str, str2)))
|
||||
|
||||
JSC_SCALL(io_open,
|
||||
PHYSFS_File *f = PHYSFS_openWrite(str);
|
||||
if (!f)
|
||||
ret = JS_ThrowReferenceError(js,"%s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
else
|
||||
ret = PHYSFS_File2js(js,f);
|
||||
)
|
||||
|
||||
JSC_SCALL(io_realdir,
|
||||
const char *real = PHYSFS_getRealDir(str);
|
||||
if (!real)
|
||||
ret = JS_NULL;
|
||||
else
|
||||
ret = JS_NewString(js,real);
|
||||
)
|
||||
|
||||
JSC_CCALL(io_searchpath,
|
||||
ret = JS_NewArray(js);
|
||||
char **paths = PHYSFS_getSearchPath();
|
||||
for (int i = 0; paths[i] != NULL; i++)
|
||||
JS_SetPropertyUint32(js,ret,i,JS_NewString(js,paths[i]));
|
||||
PHYSFS_freeList(paths);
|
||||
)
|
||||
|
||||
JSC_SCALL(io_is_directory,
|
||||
PHYSFS_Stat stat;
|
||||
int good = PHYSFS_stat(str, &stat);
|
||||
if (!good)
|
||||
ret = JS_NewBool(js, 0);
|
||||
else
|
||||
ret = JS_NewBool(js, stat.filetype == PHYSFS_FILETYPE_DIRECTORY);
|
||||
)
|
||||
|
||||
// FILE FUNCTIONS
|
||||
|
||||
JSC_CCALL(file_close,
|
||||
PHYSFS_File *f = js2PHYSFS_File(js,self);
|
||||
PHYSFS_close(f);
|
||||
)
|
||||
|
||||
JSC_CCALL(file_write,
|
||||
PHYSFS_File *f = js2PHYSFS_File(js,self);
|
||||
size_t wrote = js_physfs_write(js,f,argv[0]);
|
||||
if (wrote == -1)
|
||||
return JS_ThrowReferenceError(js,"%s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
)
|
||||
|
||||
JSC_CCALL(file_buffer,
|
||||
PHYSFS_File *f = js2PHYSFS_File(js,self);
|
||||
size_t size = js2number(js,argv[0]);
|
||||
if (!PHYSFS_setBuffer(f,size))
|
||||
return JS_ThrowReferenceError(js,"%s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
)
|
||||
|
||||
JSC_CCALL(file_tell,
|
||||
PHYSFS_File *f = js2PHYSFS_File(js,self);
|
||||
size_t tell = PHYSFS_tell(f);
|
||||
if (tell == -1)
|
||||
return JS_ThrowReferenceError(js,"%s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
|
||||
|
||||
return number2js(js,tell);
|
||||
)
|
||||
|
||||
JSC_CCALL(file_eof,
|
||||
PHYSFS_File *f = js2PHYSFS_File(js,self);
|
||||
return JS_NewBool(js, PHYSFS_eof(f));
|
||||
)
|
||||
|
||||
JSC_CCALL(io_mountpoint,
|
||||
const char *path = JS_ToCString(js,argv[0]);
|
||||
const char *point = PHYSFS_getMountPoint(path);
|
||||
if (point)
|
||||
return JS_NewString(js,point);
|
||||
)
|
||||
|
||||
static const JSCFunctionListEntry js_io_funcs[] = {
|
||||
MIST_FUNC_DEF(io, rm, 1),
|
||||
MIST_FUNC_DEF(io, mkdir, 1),
|
||||
MIST_FUNC_DEF(io,stat,1),
|
||||
MIST_FUNC_DEF(io, globfs, 2),
|
||||
MIST_FUNC_DEF(io, match, 2),
|
||||
MIST_FUNC_DEF(io, exists, 1),
|
||||
MIST_FUNC_DEF(io, mount, 3),
|
||||
MIST_FUNC_DEF(io,unmount,1),
|
||||
MIST_FUNC_DEF(io,slurp,1),
|
||||
MIST_FUNC_DEF(io,slurpbytes,1),
|
||||
MIST_FUNC_DEF(io,slurpwrite,2),
|
||||
MIST_FUNC_DEF(io,writepath, 1),
|
||||
MIST_FUNC_DEF(io,basedir, 0),
|
||||
MIST_FUNC_DEF(io, prefdir, 2),
|
||||
MIST_FUNC_DEF(io, realdir, 1),
|
||||
MIST_FUNC_DEF(io, open, 1),
|
||||
MIST_FUNC_DEF(io, searchpath, 0),
|
||||
MIST_FUNC_DEF(io, enumerate, 2),
|
||||
MIST_FUNC_DEF(io, is_directory, 1),
|
||||
MIST_FUNC_DEF(io, mountpoint, 1),
|
||||
};
|
||||
|
||||
static const JSCFunctionListEntry js_PHYSFS_File_funcs[] = {
|
||||
MIST_FUNC_DEF(file, close, 0),
|
||||
MIST_FUNC_DEF(file, write, 1),
|
||||
MIST_FUNC_DEF(file, buffer, 1),
|
||||
MIST_FUNC_DEF(file, tell, 0),
|
||||
MIST_FUNC_DEF(file, eof, 0),
|
||||
};
|
||||
|
||||
JSValue js_io_use(JSContext *js) {
|
||||
QJSCLASSPREP_FUNCS(PHYSFS_File);
|
||||
|
||||
JSValue mod = JS_NewObject(js);
|
||||
JS_SetPropertyFunctionList(js,mod,js_io_funcs,countof(js_io_funcs));
|
||||
|
||||
return mod;
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#ifndef QJS_IO_H
|
||||
#define QJS_IO_H
|
||||
|
||||
#include "cell.h"
|
||||
|
||||
JSValue js_io_use(JSContext *ctx);
|
||||
|
||||
#endif /* QJS_IO_H */
|
||||
37
source/qjs_wildstar.c
Normal file
37
source/qjs_wildstar.c
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "qjs_wildstar.h"
|
||||
#include "wildmatch.h"
|
||||
#include "jsffi.h"
|
||||
#include "qjs_macros.h"
|
||||
|
||||
JSC_CCALL(wildstar_match,
|
||||
const char *pattern = JS_ToCString(js, argv[0]);
|
||||
const char *string = JS_ToCString(js, argv[1]);
|
||||
int flags = 0;
|
||||
if (argc > 2)
|
||||
flags = js2number(js, argv[2]);
|
||||
|
||||
int result = wildmatch(pattern, string, flags);
|
||||
|
||||
JS_FreeCString(js, pattern);
|
||||
JS_FreeCString(js, string);
|
||||
|
||||
return JS_NewBool(js, result == WM_MATCH);
|
||||
)
|
||||
|
||||
static const JSCFunctionListEntry js_wildstar_funcs[] = {
|
||||
MIST_FUNC_DEF(wildstar, match, 3),
|
||||
JS_PROP_INT32_DEF("WM_MATCH", WM_MATCH, JS_PROP_CONFIGURABLE),
|
||||
JS_PROP_INT32_DEF("WM_NOMATCH", WM_NOMATCH, JS_PROP_CONFIGURABLE),
|
||||
JS_PROP_INT32_DEF("WM_NOESCAPE", WM_NOESCAPE, JS_PROP_CONFIGURABLE),
|
||||
JS_PROP_INT32_DEF("WM_PATHNAME", WM_PATHNAME, JS_PROP_CONFIGURABLE),
|
||||
JS_PROP_INT32_DEF("WM_PERIOD", WM_PERIOD, JS_PROP_CONFIGURABLE),
|
||||
JS_PROP_INT32_DEF("WM_LEADING_DIR", WM_LEADING_DIR, JS_PROP_CONFIGURABLE),
|
||||
JS_PROP_INT32_DEF("WM_CASEFOLD", WM_CASEFOLD, JS_PROP_CONFIGURABLE),
|
||||
JS_PROP_INT32_DEF("WM_WILDSTAR", WM_WILDSTAR, JS_PROP_CONFIGURABLE),
|
||||
};
|
||||
|
||||
JSValue js_wildstar_use(JSContext *js) {
|
||||
JSValue mod = JS_NewObject(js);
|
||||
JS_SetPropertyFunctionList(js, mod, js_wildstar_funcs, countof(js_wildstar_funcs));
|
||||
return mod;
|
||||
}
|
||||
8
source/qjs_wildstar.h
Normal file
8
source/qjs_wildstar.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef QJS_WILDSTAR_H
|
||||
#define QJS_WILDSTAR_H
|
||||
|
||||
#include "quickjs.h"
|
||||
|
||||
JSValue js_wildstar_use(JSContext *js);
|
||||
|
||||
#endif
|
||||
@@ -1,13 +0,0 @@
|
||||
[wrap-file]
|
||||
directory = physfs-release-3.2.0
|
||||
source_url = https://github.com/icculus/physfs/archive/refs/tags/release-3.2.0.zip
|
||||
source_filename = physfs-release-3.2.0.zip
|
||||
source_hash = 18adad9a2d5e165a709588d1d942d73e3ffcb0495244b108cfe402690489990c
|
||||
patch_filename = physfs_3.2.0-2_patch.zip
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/physfs_3.2.0-2/get_patch
|
||||
patch_hash = 7c51a672081f2a82bb789f40a68a9b7c1750659843a74c6853646d0d546718f7
|
||||
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/physfs_3.2.0-2/physfs-release-3.2.0.zip
|
||||
wrapdb_version = 3.2.0-2
|
||||
|
||||
[provide]
|
||||
physfs = physfs_dep
|
||||
192
tests/cellfs.ce
192
tests/cellfs.ce
@@ -1,192 +0,0 @@
|
||||
// CellFS vs IO Performance Test
|
||||
// Compares the speed of cellfs (miniz + fd) vs physfs-based io
|
||||
|
||||
var cellfs = use('cellfs')
|
||||
var io = use('io')
|
||||
var time = use('time')
|
||||
var json = use('json')
|
||||
var blob = use('blob')
|
||||
var utf8 = use('utf8')
|
||||
|
||||
log.console("CellFS vs IO Performance Test")
|
||||
log.console("=================================")
|
||||
|
||||
// Test file operations
|
||||
var test_file = "test.txt"
|
||||
var test_content = "Hello, World! This is a test file for performance comparison.\n"
|
||||
|
||||
// Create test data
|
||||
log.console("Creating test file...")
|
||||
io.writepath('.')
|
||||
|
||||
io.mount('.')
|
||||
|
||||
var io_paths = io.searchpath()
|
||||
log.console(io_paths)
|
||||
|
||||
for (var i = 0; i < io_paths.length; i++) {
|
||||
var path = io_paths[i]
|
||||
try {
|
||||
|
||||
cellfs.mount(path)
|
||||
} catch (e) {
|
||||
// Some paths might not be mountable, skip them
|
||||
}
|
||||
}
|
||||
|
||||
io.slurpwrite(test_file, test_content)
|
||||
|
||||
// Verify both systems have the same search paths
|
||||
log.console(`IO search paths: ${json.encode(io.searchpath())}`)
|
||||
log.console(`CellFS search paths: ${json.encode(cellfs.searchpath())}`)
|
||||
|
||||
log.console("Testing read operations...")
|
||||
|
||||
// Test io.slurpbytes
|
||||
var start_time = time.number()
|
||||
for (var i = 0; i < 100; i++) {
|
||||
var content = io.slurpbytes(test_file)
|
||||
}
|
||||
var io_time = time.number() - start_time
|
||||
log.console(`IO slurpbytes (100 iterations): ${io_time}ms`)
|
||||
|
||||
// Test cellfs.slurpbytes
|
||||
start_time = time.number()
|
||||
for (var i = 0; i < 100; i++) {
|
||||
var content = cellfs.slurp(test_file)
|
||||
}
|
||||
var cellfs_time = time.number() - start_time
|
||||
log.console(`CellFS slurpbytes (100 iterations): ${cellfs_time}ms`)
|
||||
|
||||
// Compare results
|
||||
var speedup = io_time / cellfs_time
|
||||
log.console(`CellFS is ${speedup.toFixed(2)}x ${speedup > 1 ? "faster" : "slower"} than IO for reading`)
|
||||
|
||||
// Test stat operations
|
||||
log.console("\nTesting stat operations...")
|
||||
|
||||
start_time = time.number()
|
||||
for (var i = 0; i < 1000; i++) {
|
||||
var stats = io.stat(test_file)
|
||||
}
|
||||
io_time = time.number() - start_time
|
||||
log.console(`IO stat (1000 iterations): ${io_time}ms`)
|
||||
|
||||
start_time = time.number()
|
||||
for (var i = 0; i < 1000; i++) {
|
||||
var stats = cellfs.stat(test_file)
|
||||
}
|
||||
cellfs_time = time.number() - start_time
|
||||
log.console(`CellFS stat (1000 iterations): ${cellfs_time}ms`)
|
||||
|
||||
speedup = io_time / cellfs_time
|
||||
log.console(`CellFS is ${speedup.toFixed(2)}x ${speedup > 1 ? "faster" : "slower"} than IO for stat`)
|
||||
|
||||
// Test exists operations
|
||||
log.console("\nTesting exists operations...")
|
||||
|
||||
start_time = time.number()
|
||||
for (var i = 0; i < 1000; i++) {
|
||||
var exists = io.exists(test_file)
|
||||
}
|
||||
io_time = time.number() - start_time
|
||||
log.console(`IO exists (1000 iterations): ${io_time}ms`)
|
||||
|
||||
start_time = time.number()
|
||||
for (var i = 0; i < 1000; i++) {
|
||||
var exists = cellfs.exists(test_file)
|
||||
}
|
||||
cellfs_time = time.number() - start_time
|
||||
log.console(`CellFS exists (1000 iterations): ${cellfs_time}ms`)
|
||||
|
||||
speedup = io_time / cellfs_time
|
||||
log.console(`CellFS is ${speedup.toFixed(2)}x ${speedup > 1 ? "faster" : "slower"} than IO for exists`)
|
||||
|
||||
// Test ZIP archive operations
|
||||
log.console("\nTesting ZIP archive operations...")
|
||||
|
||||
// Create a test ZIP file using miniz
|
||||
var miniz = use('miniz')
|
||||
var zip_writer = miniz.write("test_archive.zip")
|
||||
// Use io.slurpbytes to get content as ArrayBuffer for miniz
|
||||
var content_bytes = io.slurpbytes(test_file)
|
||||
zip_writer.add_file("test2.txt", content_bytes)
|
||||
zip_writer = null // Close it
|
||||
|
||||
// Mount the ZIP with io
|
||||
io.mount("test_archive.zip")
|
||||
|
||||
// Mount the ZIP with cellfs
|
||||
cellfs.mount("test_archive.zip")
|
||||
|
||||
log.console("Testing ZIP file reading...")
|
||||
|
||||
start_time = time.number()
|
||||
for (var i = 0; i < 100; i++) {
|
||||
var content = io.slurp("test2.txt")
|
||||
}
|
||||
io_time = time.number() - start_time
|
||||
log.console(`IO ZIP read (100 iterations): ${io_time}ms`)
|
||||
|
||||
start_time = time.number()
|
||||
for (var i = 0; i < 100; i++) {
|
||||
var content = cellfs.slurp("test2.txt")
|
||||
}
|
||||
|
||||
cellfs_time = time.number() - start_time
|
||||
log.console(`CellFS ZIP read (100 iterations): ${cellfs_time}ms`)
|
||||
|
||||
speedup = io_time / cellfs_time
|
||||
log.console(`CellFS is ${speedup.toFixed(2)}x ${speedup > 1 ? "faster" : "slower"} than IO for ZIP reading`)
|
||||
|
||||
// Test large file operations
|
||||
log.console("\nTesting large file operations...")
|
||||
|
||||
var large_file = "large_test.bin"
|
||||
var size_mb = 10
|
||||
var size_bits = size_mb * 1024 * 1024 * 8
|
||||
log.console(`Creating ${size_mb}MB large file...`)
|
||||
|
||||
var blob = new blob(size_bits, function() { return Math.floor(Math.random() * (1 << 52)) })
|
||||
stone(blob)
|
||||
io.slurpwrite(large_file, blob)
|
||||
|
||||
log.console("Testing large file reading...")
|
||||
|
||||
// Test io.slurpbytes
|
||||
start_time = time.number()
|
||||
for (var i = 0; i < 10; i++) {
|
||||
var large_content = io.slurpbytes(large_file)
|
||||
}
|
||||
io_time = time.number() - start_time
|
||||
log.console(`IO large file read (10 iterations): ${io_time}ms`)
|
||||
|
||||
start_time = time.number()
|
||||
for (var i = 0; i < 10; i++) {
|
||||
var large_content = cellfs.slurp(large_file)
|
||||
}
|
||||
cellfs_time = time.number() - start_time
|
||||
log.console(`CellFS large file read (10 iterations): ${cellfs_time}ms`)
|
||||
|
||||
speedup = io_time / cellfs_time
|
||||
log.console(`CellFS is ${speedup.toFixed(2)}x ${speedup > 1 ? "faster" : "slower"} than IO for large file reading`)
|
||||
|
||||
// Cleanup
|
||||
io.rm(test_file)
|
||||
io.rm("test_archive.zip")
|
||||
io.rm(large_file)
|
||||
//io.unmount("/test_zip")
|
||||
//cellfs.unmount("/test_zip")
|
||||
|
||||
// Unmount all the paths we mounted in cellfs
|
||||
for (var path of io_paths) {
|
||||
try {
|
||||
cellfs.unmount(path)
|
||||
} catch (e) {
|
||||
// Ignore unmount errors
|
||||
}
|
||||
}
|
||||
|
||||
log.console("\nTest completed!")
|
||||
|
||||
$_.stop()
|
||||
@@ -2,7 +2,7 @@ var fd = use('fd')
|
||||
var time = use('time')
|
||||
var blob = use('blob')
|
||||
|
||||
var io = use('io')
|
||||
var io = use('cellfs')
|
||||
|
||||
var data = new blob
|
||||
var st = time.number()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
var http = use('http')
|
||||
var text = use('text')
|
||||
var time = use('time')
|
||||
var io = use('io')
|
||||
var io = use('cellfs')
|
||||
|
||||
try {
|
||||
var st = time.number()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Test script for the module system
|
||||
|
||||
var io = use('io')
|
||||
var io = use('cellfs')
|
||||
var shop = use('shop')
|
||||
var time = use('time')
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
var qr = use('qr')
|
||||
var os = use('os')
|
||||
var io = use('io')
|
||||
var io = use('cellfs')
|
||||
|
||||
var myqr = qr.encode("HELLO WORLD", {
|
||||
version:14,
|
||||
|
||||
@@ -35,7 +35,7 @@ var ioguy = {
|
||||
__ACTORDATA__: { id: actor.ioactor() }
|
||||
}
|
||||
|
||||
var io = use('io')
|
||||
var io = use('cellfs')
|
||||
io.mount('/')
|
||||
var miniz = use('miniz')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user