diff --git a/scripts/cellfs.cm b/scripts/cellfs.cm index 71400232..bce009da 100644 --- a/scripts/cellfs.cm +++ b/scripts/cellfs.cm @@ -9,6 +9,8 @@ var miniz = use('miniz') // Internal state var mounts = [] // Array of {source, type, handle, name} +var writepath = "." + // Helper to normalize paths function normalize_path(path) { if (!path) return "" @@ -102,40 +104,27 @@ function resolve(path, must_exist) { } if (must_exist) { - // throw new Error("File not found in any mount: " + path) - return null + throw new Error("File not found in any mount: " + path) } - - return null } // Mount a source function mount(source, name) { // Check if source exists - var st = null - try { - st = fd.stat(source) - } catch (e) { - throw new Error("Mount source not found: " + source) - } + var st = fd.stat(source) var mount_info = { source: source, name: name || null, type: 'fs', - handle: null + handle: null, + zip_blob: null } if (st.isDirectory) { mount_info.type = 'fs' } else if (st.isFile) { - // Assume zip - var zip_data = null - // Always read as bytes for zip - var f = fd.open(source, 'r') - var s = fd.fstat(f) - zip_data = fd.read(f, s.size) - fd.close(f) + var zip_data = fd.slurp(source) var zip = miniz.read(zip_data) if (!zip || typeof zip.count != 'function') { @@ -144,6 +133,7 @@ function mount(source, name) { mount_info.type = 'zip' mount_info.handle = zip + mount_info.zip_blob = zip_data // keep blob alive for lifetime of mount } else { throw new Error("Unsupported mount source type: " + source) } @@ -177,37 +167,9 @@ function slurp(path) { } } -// Read file as bytes -function slurpbytes(path) { - var res = resolve(path, true) - if (!res) throw new Error("File not found: " + path) - - if (res.mount.type == 'zip') { - return res.mount.handle.slurp(res.path) - } else { - var full_path = join_paths(res.mount.source, res.path) - var f = fd.open(full_path, 'r') - var s = fd.fstat(f) - var data = fd.read(f, s.size) - fd.close(f) - return data - } -} - // Write file function slurpwrite(path, data) { - if (!path.startsWith("@")) { - throw new Error("slurpwrite requires a named mount (e.g. @name/file.txt)") - } - - var res = resolve(path, false) - // For named mounts, resolve returns the mount even if file doesn't exist - - if (res.mount.type == 'zip') { - throw new Error("Cannot write to zip mount: @" + res.mount.name) - } - - var full_path = join_paths(res.mount.source, res.path) + var full_path = writepath + "/" + path var f = fd.open(full_path, 'w') fd.write(f, data) @@ -248,21 +210,31 @@ function stat(path) { // Get search paths function searchpath() { - var paths = [] - for (var mount of mounts) { - paths.push(mount.source) - } - return paths + return mounts.slice() } -// Initialize -mount('.', 'cwd') +// Mount a package using the shop system +function mount_package(name) { + if (name == null) { + mount('.', null) + return + } + + var shop = use('shop') + var dir = shop.get_module_dir(name) + + if (!dir) { + throw new Error("Package not found: " + name) + } + + mount(dir, name) +} // Exports cellfs.mount = mount +cellfs.mount_package = mount_package cellfs.unmount = unmount cellfs.slurp = slurp -cellfs.slurpbytes = slurpbytes cellfs.slurpwrite = slurpwrite cellfs.exists = exists cellfs.stat = stat diff --git a/tests/cellfs.ce b/tests/cellfs.ce index 0b486c77..3505bec7 100644 --- a/tests/cellfs.ce +++ b/tests/cellfs.ce @@ -6,6 +6,7 @@ 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("=================================") @@ -22,8 +23,7 @@ io.mount('.') var io_paths = io.searchpath() log.console(io_paths) -log.console(io_paths.length) -log.console(typeof io_paths) + for (var i = 0; i < io_paths.length; i++) { var path = io_paths[i] try { @@ -53,7 +53,7 @@ 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.slurpbytes(test_file) + var content = cellfs.slurp(test_file) } var cellfs_time = time.number() - start_time log.console(`CellFS slurpbytes (100 iterations): ${cellfs_time}ms`) @@ -110,28 +110,29 @@ 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("test.txt", content_bytes) +zip_writer.add_file("test2.txt", content_bytes) zip_writer = null // Close it // Mount the ZIP with io -io.mount("test_archive.zip", "/test_zip") +io.mount("test_archive.zip") // Mount the ZIP with cellfs -cellfs.mount("test_archive.zip", "/test_zip") +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("test.txt") + 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("test.txt") + var content = cellfs.slurp("test2.txt") } + cellfs_time = time.number() - start_time log.console(`CellFS ZIP read (100 iterations): ${cellfs_time}ms`) @@ -160,10 +161,9 @@ for (var i = 0; i < 10; i++) { io_time = time.number() - start_time log.console(`IO large file read (10 iterations): ${io_time}ms`) -// Test cellfs.slurpbytes start_time = time.number() for (var i = 0; i < 10; i++) { - var large_content = cellfs.slurpbytes(large_file) + var large_content = cellfs.slurp(large_file) } cellfs_time = time.number() - start_time log.console(`CellFS large file read (10 iterations): ${cellfs_time}ms`) diff --git a/tests/miniz.ce b/tests/miniz.ce new file mode 100644 index 00000000..0d913290 --- /dev/null +++ b/tests/miniz.ce @@ -0,0 +1,51 @@ +var fd = use("fd") +var miniz = use("miniz") +var utf8 = use("utf8") + +var ZIP_PATH = "miniz_test.zip" +var SOURCE_PATH = "miniz_source.txt" +var ENTRY_PATH = "sample/hello.txt" +var PAYLOAD = "Miniz integration test payload." + +function write_text_file(path, text) { + var handle = fd.open(path, "w") + fd.write(handle, text) + fd.close(handle) +} + +function main() { + log.console("[miniz] creating source file via fd module...") + write_text_file(SOURCE_PATH, PAYLOAD) + + log.console("[miniz] creating zip via fd-backed filesystem...") + var source_blob = fd.slurp(SOURCE_PATH) + var writer = miniz.write(ZIP_PATH) + writer.add_file(ENTRY_PATH, source_blob) + writer = null + + log.console("[miniz] zip written; reading back through fd module") + var zip_blob = fd.slurp(ZIP_PATH) + var reader = miniz.read(zip_blob) + + if (!reader.exists(ENTRY_PATH)) + throw new Error("miniz test: entry missing in archive") + + var extracted_blob = reader.slurp(ENTRY_PATH) + var extracted_text = utf8.decode(extracted_blob) + log.console(reader.list()) + log.console(extracted_text); + + if (extracted_text != PAYLOAD) + throw new Error("miniz test: extracted text mismatch") + + var listed = reader.list() + if (listed.length != reader.count()) + throw new Error("miniz test: list/count mismatch") + if (listed.length != 1 || listed[0] != ENTRY_PATH) + throw new Error("miniz test: unexpected entries in archive") + + log.console(`miniz read success: ${listed[0]} => ${extracted_text}`) + $_.stop() +} + +main()