2019-02-19 20:26:06 +00:00
|
|
|
/* eslint no-unused-vars: ["error", { "argsIgnorePattern": "^_" }] */
|
|
|
|
|
2019-02-21 23:35:59 +00:00
|
|
|
import { BadState } from "./wsfs/bad_state.js";
|
|
|
|
import { FileMode } from "./wsfs/file_mode.js";
|
|
|
|
import { Provider } from "./wsfs/provider.js";
|
2019-01-28 21:08:37 +00:00
|
|
|
|
2019-02-21 23:35:59 +00:00
|
|
|
export class FileSystemProvider extends Provider {
|
2019-01-28 21:08:37 +00:00
|
|
|
constructor(root) {
|
2019-02-21 23:35:59 +00:00
|
|
|
super();
|
|
|
|
|
2019-01-28 21:08:37 +00:00
|
|
|
this.root = root;
|
2019-02-02 13:25:57 +00:00
|
|
|
this._inodes = { };
|
|
|
|
|
|
|
|
this._walk(this.root, (entry) => { this._inodes[entry.inode] = entry; });
|
|
|
|
}
|
|
|
|
|
2019-02-21 23:35:59 +00:00
|
|
|
setView(view) {
|
|
|
|
this._view = view;
|
|
|
|
}
|
|
|
|
|
|
|
|
connected() {
|
|
|
|
if (this._view) { this._view.onConnectionOpened(); }
|
|
|
|
}
|
|
|
|
|
|
|
|
disconnected() {
|
|
|
|
if (this._view) { this._view.onConnectionClosed(); }
|
|
|
|
}
|
|
|
|
|
2019-02-02 13:25:57 +00:00
|
|
|
_walk(node, callback) {
|
|
|
|
callback(node);
|
|
|
|
|
|
|
|
const entries = node.entries;
|
|
|
|
if (entries) {
|
|
|
|
for(let entry of Object.entries(entries)) {
|
|
|
|
this._walk(entry[1], callback);
|
|
|
|
}
|
|
|
|
}
|
2019-01-28 21:08:37 +00:00
|
|
|
}
|
2019-02-03 18:10:05 +00:00
|
|
|
|
|
|
|
|
2019-02-21 23:35:59 +00:00
|
|
|
async lookup(parent, name) {
|
2019-02-03 18:10:05 +00:00
|
|
|
const parentEntry = this._inodes[parent];
|
2019-02-03 17:12:14 +00:00
|
|
|
const entry = (parentEntry && parentEntry.entries && parentEntry.entries[name]) || null;
|
|
|
|
if (entry) {
|
|
|
|
return {
|
|
|
|
inode: entry.inode,
|
|
|
|
mode: entry.mode || parseInt("755", 8),
|
2019-02-13 20:09:43 +00:00
|
|
|
type: entry.type || "file",
|
2019-02-03 17:12:14 +00:00
|
|
|
size: entry.size || (entry.contents && entry.contents.length) || 0,
|
|
|
|
atime: entry.atime || 0,
|
|
|
|
mtime: entry.mtime || 0,
|
|
|
|
ctime: entry.ctime || 0
|
|
|
|
};
|
|
|
|
}
|
|
|
|
else {
|
2019-02-21 23:35:59 +00:00
|
|
|
throw new BadState(BadState.NO_ENTRY);
|
2019-02-03 17:12:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-02-21 23:35:59 +00:00
|
|
|
async getattr(inode) {
|
2019-02-03 18:10:05 +00:00
|
|
|
let entry = this._inodes[inode];
|
2019-01-28 21:08:37 +00:00
|
|
|
if (entry) {
|
|
|
|
return {
|
|
|
|
mode: entry.mode || parseInt("755", 8),
|
2019-02-13 20:09:43 +00:00
|
|
|
type: entry.type || "file",
|
2019-01-28 21:08:37 +00:00
|
|
|
size: entry.size || (entry.contents && entry.contents.length) || 0,
|
|
|
|
atime: entry.atime || 0,
|
|
|
|
mtime: entry.mtime || 0,
|
|
|
|
ctime: entry.ctime || 0
|
|
|
|
};
|
|
|
|
}
|
|
|
|
else {
|
2019-02-21 23:35:59 +00:00
|
|
|
throw new BadState(BadState.NO_ENTRY);
|
2019-01-28 21:08:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-21 23:35:59 +00:00
|
|
|
async readdir(inode) {
|
2019-02-03 18:10:05 +00:00
|
|
|
let entry = this._inodes[inode];
|
2019-01-28 21:08:37 +00:00
|
|
|
|
|
|
|
if ((entry) && ("dir" === entry.type)) {
|
2019-02-21 23:35:59 +00:00
|
|
|
let result = [
|
2019-02-13 20:09:43 +00:00
|
|
|
{name: ".", inode: entry.inode},
|
|
|
|
{name: "..", inode: entry.inode}
|
2019-02-03 17:12:14 +00:00
|
|
|
];
|
|
|
|
for(let subdir of Object.entries(entry.entries)) {
|
|
|
|
const name = subdir[0];
|
|
|
|
const inode = subdir[1].inode;
|
2019-02-13 20:09:43 +00:00
|
|
|
result.push({name, inode});
|
2019-01-28 21:08:37 +00:00
|
|
|
}
|
2019-02-21 23:35:59 +00:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
throw new BadState(BadState.NO_ENTRY);
|
2019-01-28 21:08:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-02-21 23:35:59 +00:00
|
|
|
async open(inode, mode) {
|
2019-02-03 18:10:05 +00:00
|
|
|
let entry = this._inodes[inode];
|
2019-01-28 21:08:37 +00:00
|
|
|
|
2019-02-13 20:09:43 +00:00
|
|
|
if (entry.type === "file") {
|
2019-02-21 23:35:59 +00:00
|
|
|
if ((mode & FileMode.ACCESS_MODE) === FileMode.READONLY) {
|
|
|
|
return {handle: 1337};
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
throw new BadState(BadState.NO_ACCESS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
throw new BadState(BadState.NO_ENTRY);
|
|
|
|
}
|
2019-01-28 21:08:37 +00:00
|
|
|
}
|
|
|
|
|
2019-02-19 20:26:06 +00:00
|
|
|
close(_inode, _handle, _mode) {
|
2019-01-29 22:47:08 +00:00
|
|
|
// do nothing
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-02-21 23:35:59 +00:00
|
|
|
async read(inode, handle, offset, length) {
|
2019-02-03 18:10:05 +00:00
|
|
|
let entry = this._inodes[inode];
|
2019-01-28 21:08:37 +00:00
|
|
|
|
2019-02-13 20:09:43 +00:00
|
|
|
if (entry.type === "file") {
|
2019-02-21 23:35:59 +00:00
|
|
|
const end = Math.min(offset + length, entry.contents.length);
|
|
|
|
const data = (offset < entry.contents.length) ? entry.contents.substring(offset, end) : "";
|
|
|
|
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
throw new BadState(BadState.NO_ENTRY);
|
|
|
|
}
|
2019-01-28 21:08:37 +00:00
|
|
|
}
|
|
|
|
}
|