feat: add filesystem libs
This commit is contained in:
parent
8b743f49d1
commit
6af3c70fce
@ -16,6 +16,10 @@ import me.topchetoeu.jscript.events.Observer;
|
|||||||
import me.topchetoeu.jscript.exceptions.EngineException;
|
import me.topchetoeu.jscript.exceptions.EngineException;
|
||||||
import me.topchetoeu.jscript.exceptions.InterruptException;
|
import me.topchetoeu.jscript.exceptions.InterruptException;
|
||||||
import me.topchetoeu.jscript.exceptions.SyntaxException;
|
import me.topchetoeu.jscript.exceptions.SyntaxException;
|
||||||
|
import me.topchetoeu.jscript.filesystem.MemoryFilesystem;
|
||||||
|
import me.topchetoeu.jscript.filesystem.Mode;
|
||||||
|
import me.topchetoeu.jscript.filesystem.RootFilesystem;
|
||||||
|
import me.topchetoeu.jscript.lib.FilesystemLib;
|
||||||
import me.topchetoeu.jscript.lib.Internals;
|
import me.topchetoeu.jscript.lib.Internals;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
@ -112,6 +116,11 @@ public class Main {
|
|||||||
throw new EngineException("Couldn't open do.js");
|
throw new EngineException("Couldn't open do.js");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var fs = new RootFilesystem(null);
|
||||||
|
fs.protocols.put("file", new MemoryFilesystem(Mode.READ_WRITE));
|
||||||
|
|
||||||
|
environment.global.define((Context)null, "fs", false, new FilesystemLib(fs));
|
||||||
}
|
}
|
||||||
private static void initEngine() {
|
private static void initEngine() {
|
||||||
debugServer.targets.put("target", (ws, req) -> new SimpleDebugger(ws, engine));
|
debugServer.targets.put("target", (ws, req) -> new SimpleDebugger(ws, engine));
|
||||||
|
@ -12,6 +12,7 @@ import me.topchetoeu.jscript.interop.Native;
|
|||||||
import me.topchetoeu.jscript.interop.NativeGetter;
|
import me.topchetoeu.jscript.interop.NativeGetter;
|
||||||
import me.topchetoeu.jscript.interop.NativeSetter;
|
import me.topchetoeu.jscript.interop.NativeSetter;
|
||||||
import me.topchetoeu.jscript.interop.NativeWrapperProvider;
|
import me.topchetoeu.jscript.interop.NativeWrapperProvider;
|
||||||
|
import me.topchetoeu.jscript.permissions.PermissionsManager;
|
||||||
|
|
||||||
public class Environment {
|
public class Environment {
|
||||||
private HashMap<String, ObjectValue> prototypes = new HashMap<>();
|
private HashMap<String, ObjectValue> prototypes = new HashMap<>();
|
||||||
@ -21,6 +22,7 @@ public class Environment {
|
|||||||
|
|
||||||
public GlobalScope global;
|
public GlobalScope global;
|
||||||
public WrappersProvider wrappers;
|
public WrappersProvider wrappers;
|
||||||
|
public PermissionsManager permissions;
|
||||||
|
|
||||||
private static int nextId = 0;
|
private static int nextId = 0;
|
||||||
|
|
||||||
|
88
src/me/topchetoeu/jscript/lib/FileLib.java
Normal file
88
src/me/topchetoeu/jscript/lib/FileLib.java
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
package me.topchetoeu.jscript.lib;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.engine.Context;
|
||||||
|
import me.topchetoeu.jscript.engine.values.ArrayValue;
|
||||||
|
import me.topchetoeu.jscript.engine.values.Values;
|
||||||
|
import me.topchetoeu.jscript.filesystem.File;
|
||||||
|
import me.topchetoeu.jscript.filesystem.FilesystemException;
|
||||||
|
import me.topchetoeu.jscript.interop.Native;
|
||||||
|
import me.topchetoeu.jscript.interop.NativeGetter;
|
||||||
|
|
||||||
|
@Native("File")
|
||||||
|
public class FileLib {
|
||||||
|
public final File file;
|
||||||
|
|
||||||
|
@Native public PromiseLib read(Context ctx, int n) {
|
||||||
|
return PromiseLib.await(ctx, () -> {
|
||||||
|
try {
|
||||||
|
var buff = new byte[n];
|
||||||
|
var res = new ArrayValue();
|
||||||
|
int resI = file.read(buff);
|
||||||
|
|
||||||
|
for (var i = resI - 1; i >= 0; i--) res.set(ctx, i, (int)buff[i]);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
catch (FilesystemException e) { throw e.toEngineException(); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@Native public PromiseLib write(Context ctx, ArrayValue val) {
|
||||||
|
return PromiseLib.await(ctx, () -> {
|
||||||
|
try {
|
||||||
|
var res = new byte[val.size()];
|
||||||
|
|
||||||
|
for (var i = 0; i < val.size(); i++) res[i] = (byte)Values.toNumber(ctx, val.get(i));
|
||||||
|
file.write(res);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
catch (FilesystemException e) { throw e.toEngineException(); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@Native public PromiseLib close(Context ctx) {
|
||||||
|
return PromiseLib.await(ctx, () -> {
|
||||||
|
file.close();
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@NativeGetter public PromiseLib pointer(Context ctx) {
|
||||||
|
return PromiseLib.await(ctx, () -> {
|
||||||
|
try {
|
||||||
|
return file.getPtr();
|
||||||
|
}
|
||||||
|
catch (FilesystemException e) { throw e.toEngineException(); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@Native public PromiseLib setPointer(Context ctx, long ptr) {
|
||||||
|
return PromiseLib.await(ctx, () -> {
|
||||||
|
try {
|
||||||
|
file.setPtr(ptr, 0);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
catch (FilesystemException e) { throw e.toEngineException(); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@NativeGetter("length") public PromiseLib getLength(Context ctx) {
|
||||||
|
return PromiseLib.await(ctx, () -> {
|
||||||
|
try {
|
||||||
|
long curr = file.getPtr();
|
||||||
|
file.setPtr(0, 2);
|
||||||
|
long res = file.getPtr();
|
||||||
|
file.setPtr(curr, 0);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
catch (FilesystemException e) { throw e.toEngineException(); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@NativeGetter("mode") public PromiseLib getMode(Context ctx) {
|
||||||
|
return PromiseLib.await(ctx, () -> {
|
||||||
|
try {
|
||||||
|
return file.mode().name;
|
||||||
|
}
|
||||||
|
catch (FilesystemException e) { throw e.toEngineException(); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileLib(File file) {
|
||||||
|
this.file = file;
|
||||||
|
}
|
||||||
|
}
|
161
src/me/topchetoeu/jscript/lib/FilesystemLib.java
Normal file
161
src/me/topchetoeu/jscript/lib/FilesystemLib.java
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
package me.topchetoeu.jscript.lib;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
|
import me.topchetoeu.jscript.Filename;
|
||||||
|
import me.topchetoeu.jscript.engine.Context;
|
||||||
|
import me.topchetoeu.jscript.engine.values.ObjectValue;
|
||||||
|
import me.topchetoeu.jscript.engine.values.Values;
|
||||||
|
import me.topchetoeu.jscript.filesystem.EntryType;
|
||||||
|
import me.topchetoeu.jscript.filesystem.File;
|
||||||
|
import me.topchetoeu.jscript.filesystem.FileStat;
|
||||||
|
import me.topchetoeu.jscript.filesystem.FilesystemException;
|
||||||
|
import me.topchetoeu.jscript.filesystem.Mode;
|
||||||
|
import me.topchetoeu.jscript.filesystem.RootFilesystem;
|
||||||
|
import me.topchetoeu.jscript.filesystem.FilesystemException.FSCode;
|
||||||
|
import me.topchetoeu.jscript.interop.Native;
|
||||||
|
|
||||||
|
@Native("Filesystem")
|
||||||
|
public class FilesystemLib {
|
||||||
|
public final RootFilesystem fs;
|
||||||
|
|
||||||
|
@Native public PromiseLib open(Context ctx, String _path, String mode) {
|
||||||
|
var filename = Filename.parse(_path);
|
||||||
|
var _mode = Mode.parse(mode);
|
||||||
|
|
||||||
|
return PromiseLib.await(ctx, () -> {
|
||||||
|
try {
|
||||||
|
if (fs.stat(filename.path).type != EntryType.FILE) {
|
||||||
|
throw new FilesystemException(filename.toString(), FSCode.NOT_FILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
var file = fs.open(filename.path, _mode);
|
||||||
|
return new FileLib(file);
|
||||||
|
}
|
||||||
|
catch (FilesystemException e) { throw e.toEngineException(); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@Native public ObjectValue ls(Context ctx, String _path) throws IOException {
|
||||||
|
var filename = Filename.parse(_path);
|
||||||
|
|
||||||
|
return Values.toJSAsyncIterator(ctx, new Iterator<>() {
|
||||||
|
private boolean failed, done;
|
||||||
|
private File file;
|
||||||
|
private String nextLine;
|
||||||
|
|
||||||
|
private void update() {
|
||||||
|
if (done) return;
|
||||||
|
if (!failed) {
|
||||||
|
if (file == null) {
|
||||||
|
if (fs.stat(filename.path).type != EntryType.FOLDER) {
|
||||||
|
throw new FilesystemException(filename.toString(), FSCode.NOT_FOLDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
file = fs.open(filename.path, Mode.READ);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextLine == null) {
|
||||||
|
while (true) {
|
||||||
|
nextLine = file.readLine();
|
||||||
|
if (nextLine == null) {
|
||||||
|
done = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nextLine = nextLine.trim();
|
||||||
|
if (!nextLine.equals("")) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
try {
|
||||||
|
update();
|
||||||
|
return !done && !failed;
|
||||||
|
}
|
||||||
|
catch (FilesystemException e) { throw e.toEngineException(); }
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String next() {
|
||||||
|
try {
|
||||||
|
update();
|
||||||
|
var res = nextLine;
|
||||||
|
nextLine = null;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
catch (FilesystemException e) { throw e.toEngineException(); }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@Native public PromiseLib mkdir(Context ctx, String _path) throws IOException {
|
||||||
|
return PromiseLib.await(ctx, () -> {
|
||||||
|
try {
|
||||||
|
fs.create(Filename.parse(_path).toString(), EntryType.FOLDER);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
catch (FilesystemException e) { throw e.toEngineException(); }
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
@Native public PromiseLib mkfile(Context ctx, String _path) throws IOException {
|
||||||
|
return PromiseLib.await(ctx, () -> {
|
||||||
|
try {
|
||||||
|
fs.create(Filename.parse(_path).toString(), EntryType.FILE);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
catch (FilesystemException e) { throw e.toEngineException(); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@Native public PromiseLib rm(Context ctx, String _path, boolean recursive) throws IOException {
|
||||||
|
return PromiseLib.await(ctx, () -> {
|
||||||
|
try {
|
||||||
|
if (!recursive) fs.create(Filename.parse(_path).toString(), EntryType.NONE);
|
||||||
|
else {
|
||||||
|
var stack = new Stack<String>();
|
||||||
|
stack.push(_path);
|
||||||
|
|
||||||
|
while (!stack.empty()) {
|
||||||
|
var path = Filename.parse(stack.pop()).toString();
|
||||||
|
FileStat stat;
|
||||||
|
|
||||||
|
try { stat = fs.stat(path); }
|
||||||
|
catch (FilesystemException e) { continue; }
|
||||||
|
|
||||||
|
if (stat.type == EntryType.FOLDER) {
|
||||||
|
for (var el : fs.open(path, Mode.READ).readToString().split("\n")) stack.push(el);
|
||||||
|
}
|
||||||
|
else fs.create(path, EntryType.NONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
catch (FilesystemException e) { throw e.toEngineException(); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@Native public PromiseLib stat(Context ctx, String _path) throws IOException {
|
||||||
|
return PromiseLib.await(ctx, () -> {
|
||||||
|
try {
|
||||||
|
var stat = fs.stat(_path);
|
||||||
|
var res = new ObjectValue();
|
||||||
|
|
||||||
|
res.defineProperty(ctx, "type", stat.type.name);
|
||||||
|
res.defineProperty(ctx, "mode", stat.mode.name);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
catch (FilesystemException e) { throw e.toEngineException(); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@Native public PromiseLib exists(Context ctx, String _path) throws IOException {
|
||||||
|
return PromiseLib.await(ctx, () -> {
|
||||||
|
try { fs.stat(_path); return true; }
|
||||||
|
catch (FilesystemException e) { return false; }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public FilesystemLib(RootFilesystem fs) {
|
||||||
|
this.fs = fs;
|
||||||
|
}
|
||||||
|
}
|
@ -39,7 +39,7 @@ import me.topchetoeu.jscript.interop.Native;
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
@Native(thisArg = true) public static String toString(Context ctx, Object func) {
|
@Native(thisArg = true) public static String toString(Context ctx, Object func) {
|
||||||
return "function (...) { ... }";
|
return func.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Native public static FunctionValue async(FunctionValue func) {
|
@Native public static FunctionValue async(FunctionValue func) {
|
||||||
|
Loading…
Reference in New Issue
Block a user