"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FsaNodeCore = void 0; const util_1 = require("../node/util"); const util_2 = require("./util"); const constants_1 = require("../node/constants"); const FsaNodeFsOpenFile_1 = require("./FsaNodeFsOpenFile"); const util = require("../node/util"); class FsaNodeCore { constructor(root, syncAdapter) { this.root = root; this.syncAdapter = syncAdapter; this.fds = new Map(); /** * A list of reusable (opened and closed) file descriptors, that should be * used first before creating a new file descriptor. */ this.releasedFds = []; if (root instanceof Promise) { root .then(root => { this.root = root; }) .catch(error => { }); } } getSyncAdapter() { const adapter = this.syncAdapter; if (!adapter) throw new Error('No sync adapter'); return adapter; } newFdNumber() { const releasedFd = this.releasedFds.pop(); return typeof releasedFd === 'number' ? releasedFd : FsaNodeCore.fd--; } /** * @param path Path from root to the new folder. * @param create Whether to create the folders if they don't exist. */ async getDir(path, create, funcName) { let curr = await this.root; const options = { create }; try { for (const name of path) { curr = await curr.getDirectoryHandle(name, options); } } catch (error) { if (error && typeof error === 'object') { switch (error.name) { case 'TypeMismatchError': throw (0, util_1.createError)('ENOTDIR', funcName, path.join("/" /* FsaToNodeConstants.Separator */)); case 'NotFoundError': throw (0, util_1.createError)('ENOENT', funcName, path.join("/" /* FsaToNodeConstants.Separator */)); } } throw error; } return curr; } async getFile(path, name, funcName, create) { const dir = await this.getDir(path, false, funcName); const file = await dir.getFileHandle(name, { create }); return file; } async getFileOrDir(path, name, funcName) { const dir = await this.getDir(path, false, funcName); if (!name) return dir; try { const file = await dir.getFileHandle(name); return file; } catch (error) { if (error && typeof error === 'object') { switch (error.name) { case 'TypeMismatchError': try { return await dir.getDirectoryHandle(name); } catch (error2) { if (error2 && typeof error2 === 'object') { switch (error2.name) { case 'TypeMismatchError': throw (0, util_1.createError)('ENOTDIR', funcName, path.join("/" /* FsaToNodeConstants.Separator */)); case 'NotFoundError': throw (0, util_1.createError)('ENOENT', funcName, path.join("/" /* FsaToNodeConstants.Separator */)); } } } case 'NotFoundError': throw (0, util_1.createError)('ENOENT', funcName, path.join("/" /* FsaToNodeConstants.Separator */)); } } throw error; } } getFileByFd(fd, funcName) { if (!(0, util_1.isFd)(fd)) throw TypeError(constants_1.ERRSTR.FD); const file = this.fds.get(fd); if (!file) throw (0, util_1.createError)('EBADF', funcName); return file; } async getFileByFdAsync(fd, funcName) { return this.getFileByFd(fd, funcName); } async __getFileById(id, funcName) { if (typeof id === 'number') return (await this.getFileByFd(id, funcName)).file; const filename = (0, util_1.pathToFilename)(id); const [folder, name] = (0, util_2.pathToLocation)(filename); return await this.getFile(folder, name, funcName); } async getFileByIdOrCreate(id, funcName) { if (typeof id === 'number') return (await this.getFileByFd(id, funcName)).file; const filename = (0, util_1.pathToFilename)(id); const [folder, name] = (0, util_2.pathToLocation)(filename); const dir = await this.getDir(folder, false, funcName); return await dir.getFileHandle(name, { create: true }); } async __open(filename, flags, mode) { const [folder, name] = (0, util_2.pathToLocation)(filename); const throwIfExists = !!(flags & 128 /* FLAG.O_EXCL */); if (throwIfExists) { try { await this.getFile(folder, name, 'open', false); throw util.createError('EEXIST', 'writeFile'); } catch (error) { const file404 = error && typeof error === 'object' && (error.code === 'ENOENT' || error.name === 'NotFoundError'); if (!file404) { if (error && typeof error === 'object') { switch (error.name) { case 'TypeMismatchError': throw (0, util_1.createError)('ENOTDIR', 'open', filename); case 'NotFoundError': throw (0, util_1.createError)('ENOENT', 'open', filename); } } throw error; } } } try { const createIfMissing = !!(flags & 64 /* FLAG.O_CREAT */); const fsaFile = await this.getFile(folder, name, 'open', createIfMissing); return this.__open2(fsaFile, filename, flags, mode); } catch (error) { if (error && typeof error === 'object') { switch (error.name) { case 'TypeMismatchError': throw (0, util_1.createError)('ENOTDIR', 'open', filename); case 'NotFoundError': throw (0, util_1.createError)('ENOENT', 'open', filename); } } throw error; } } __open2(fsaFile, filename, flags, mode) { const fd = this.newFdNumber(); const file = new FsaNodeFsOpenFile_1.FsaNodeFsOpenFile(fd, mode, flags, fsaFile, filename); this.fds.set(fd, file); return file; } async __close(fd) { const openFile = await this.getFileByFdAsync(fd, 'close'); await openFile.close(); const deleted = this.fds.delete(fd); if (deleted) this.releasedFds.push(fd); } getFileName(id) { if (typeof id === 'number') { const openFile = this.fds.get(id); if (!openFile) throw (0, util_1.createError)('EBADF', 'readFile'); return openFile.filename; } return (0, util_1.pathToFilename)(id); } } exports.FsaNodeCore = FsaNodeCore; FsaNodeCore.fd = 0x7fffffff; //# sourceMappingURL=FsaNodeCore.js.map