// // Copyright (C) Stanislaw Adaszewski, 2020 // Contact: s.adaszewski@gmail.com // Website: https://adared.ch/wba // License: GNU Affero General Public License, Version 3 // class WBRootDirWrapper { constructor(rootDir, streams) { this.rootDir = rootDir; this.streams = streams; } findDir(path) { if (typeof(path) === 'string') path = path.split('/'); if (path[0] !== '.') throw Error('Path must begin with a dot component'); let dir = this.rootDir; for (let i = 1; i < path.length; i++) { if (!(path[i] in dir)) throw Error('Directory not found'); if (dir[path[i]] instanceof Array) throw Error('Path is a file not directory'); dir = dir[path[i]]; } return dir; } listDirectory(path) { let dir = this.findDir(path); let keys = Object.keys(dir); keys.sort(); let subdirs = keys.filter(k => !(dir[k] instanceof Array)); let files = keys.filter(k => (dir[k] instanceof Array)); let res = subdirs.map(k => [ 'd', k, null ]); res = res.concat(files.map(k => [ 'f', k, dir[k][1] ])); return res; } unescapeName(name) { return name.replace(/(\\\\|\\[0-9]{3})/g, (_, $1) => ($1 === '\\\\' ? '\\' : String.fromCharCode(parseInt($1.substr(1), 8)))); } escapeName(name) { return name.replace(/ /g, '\\040'); } getFile(path) { if (typeof(path) === 'string') path = path.split('/'); if (path.length < 2) throw Error('Invalid file path'); const name = path[path.length - 1]; const dir = this.findDir(path.slice(0, path.length - 1)); if (!(name in dir)) throw Error('File not found'); if (!(dir[name] instanceof Array)) throw Error('Path points to a directory not a file'); const streams = this.streams; let file = dir[name]; file = [ file[0].map(seg => { const stm = streams[seg[0]]; const used = stm.map(loc => !( loc[2] <= seg[1] || loc[1] >= seg[1] + seg[2] ) ); const start = used.indexOf(true); const end = used.lastIndexOf(true) + 1; if (start === -1) return []; const res = []; for (let i = start; i < end; i++) { const loc = stm[i]; res.push([ loc[0], Math.max(0, seg[1] - loc[1]), Math.min(loc[2] - loc[1], seg[1] + seg[2] - loc[1]) ]); } return res; }), file[1] ]; file[0] = file[0].reduce((a, b) => a.concat(b)); return file; } } export default WBRootDirWrapper;