diff --git a/loader/jrunscript/io.fifty.ts b/loader/jrunscript/io.fifty.ts index ba67a9537..b1c1b0e10 100644 --- a/loader/jrunscript/io.fifty.ts +++ b/loader/jrunscript/io.fifty.ts @@ -5,12 +5,27 @@ // END LICENSE namespace slime.jrunscript.runtime.io { + export interface Context { + _streams: slime.jrunscript.native.inonit.script.runtime.io.Streams + api: { + java: Pick + Resource: any + } + } + + export namespace test { + export const subject = (function(fifty: slime.fifty.test.Kit) { + return fifty.global.jsh.unit.$slime.io; + //@ts-ignore + })(fifty); + } + type byte = number export namespace input { export interface ReaderConfiguration { charset: string - LINE_SEPARATOR: string + LINE_SEPARATOR?: string } } @@ -230,21 +245,6 @@ namespace slime.jrunscript.runtime.io { readText: () => Reader } - export interface Context { - _streams: slime.jrunscript.native.inonit.script.runtime.io.Streams - api: { - java: slime.jrunscript.java.Exports - Resource: any - } - } - - export namespace test { - export const subject = (function(fifty: slime.fifty.test.Kit) { - return fifty.global.jsh.unit.$slime.io; - //@ts-ignore - })(fifty); - } - type BinaryCopyMode = { onFinish: (i: slime.jrunscript.native.java.io.InputStream, o: slime.jrunscript.native.java.io.OutputStream) => void } @@ -442,15 +442,29 @@ namespace slime.jrunscript.runtime.io { //@ts-ignore )(fifty); + export interface Events { + progress: T + done: void + } + + export interface Exports { + character: { + default: { + all: slime.$api.fp.world.Means> + lines: slime.$api.fp.world.Means> + } + } + } ( function( Packages: slime.jrunscript.Packages, fifty: slime.fifty.test.Kit ) { - const { jsh } = fifty.global; + const { $api, jsh } = fifty.global; fifty.tests.manual = {}; + fifty.tests.manual.charsets = function() { var _map = Packages.java.nio.charset.Charset.availableCharsets(); var _keys = _map.keySet().iterator(); @@ -459,6 +473,42 @@ namespace slime.jrunscript.runtime.io { } var _default = Packages.java.nio.charset.Charset.defaultCharset(); jsh.shell.console(String(_default)); + }; + + fifty.tests.manual.character = fifty.test.Parent(); + + fifty.tests.manual.character.default = fifty.test.Parent(); + + fifty.tests.manual.character.default.all = function() { + var me = fifty.jsh.file.object.getRelativePath("io.fifty.ts").java.adapt(); + var _is = new Packages.java.io.FileInputStream(me); + var input = test.subject.InputStream.from.java(_is); + var all; + $api.fp.world.Means.now({ + means: test.subject.character.default.all, + order: input, + handlers: { + progress: function(e) { + all = e.detail; + } + } + }); + jsh.shell.console(all); + } + + fifty.tests.manual.character.default.lines = function() { + var me = fifty.jsh.file.object.getRelativePath("io.fifty.ts").java.adapt(); + var _is = new Packages.java.io.FileInputStream(me); + var input = test.subject.InputStream.from.java(_is); + $api.fp.world.Means.now({ + means: test.subject.character.default.lines, + order: input, + handlers: { + progress: function(e) { + jsh.shell.console("LINE: " + e.detail); + } + } + }); } } //@ts-ignore diff --git a/loader/jrunscript/io.js b/loader/jrunscript/io.js index aab4f46d6..af6baa214 100644 --- a/loader/jrunscript/io.js +++ b/loader/jrunscript/io.js @@ -10,12 +10,13 @@ * * @param { any } $platform * @param { slime.jrunscript.Packages } Packages + * @param { any } JavaAdapter * @param { any } XMLList * @param { slime.$api.Global } $api * @param { slime.jrunscript.runtime.io.Context } $context * @param { slime.loader.Export } $export */ - function($platform,Packages,XMLList,$api,$context,$export) { + function($platform,Packages,JavaAdapter,XMLList,$api,$context,$export) { var LINE_SEPARATOR = String(Packages.java.lang.System.getProperty("line.separator")); var _java = $context._streams; @@ -393,8 +394,62 @@ delimiter: { line: LINE_SEPARATOR } + }, + character: { + default: { + all: function(input) { + return function(events) { + // TODO or use Packages.java.nio.charset.StandardCharsets.UTF_8? + var charset = String(Packages.java.nio.charset.Charset.defaultCharset().name()); + var reader = input.character({ charset: charset }); + $context._streams.readAll( + reader.java.adapt(), + new JavaAdapter( + Packages.inonit.script.runtime.io.Streams.ReadEvents, + { + progress: function(string) { + events.fire("progress", string); + }, + error: function(e) { + // TODO improve + throw new Error(); + }, + done: function() { + events.fire("done"); + } + } + ) + ); + } + }, + lines: function(input) { + return function(events) { + var charset = String(Packages.java.nio.charset.Charset.defaultCharset().name()); + var reader = input.character({ charset: charset }); + $context._streams.readLines( + reader.java.adapt(), + "\n", + new JavaAdapter( + Packages.inonit.script.runtime.io.Streams.ReadEvents, + { + progress: function(string) { + events.fire("progress", string); + }, + error: function(e) { + // TODO improve + throw new Error(); + }, + done: function() { + events.fire("done"); + } + } + ) + ); + } + } + } } }); } //@ts-ignore -)($platform, Packages, (function() { return this.XMLList })(), $api, $context, $export); +)($platform, Packages, JavaAdapter, (function() { return this.XMLList })(), $api, $context, $export); diff --git a/rhino/system/java/inonit/script/runtime/io/Streams.fifty.ts b/rhino/system/java/inonit/script/runtime/io/Streams.fifty.ts index 16a985098..d365e4e75 100644 --- a/rhino/system/java/inonit/script/runtime/io/Streams.fifty.ts +++ b/rhino/system/java/inonit/script/runtime/io/Streams.fifty.ts @@ -5,6 +5,12 @@ // END LICENSE namespace slime.jrunscript.native.inonit.script.runtime.io { + export namespace Streams { + export interface Events { + // opaque to JavaScript + } + } + export interface Streams { /** * Creates an output stream that, when written to, will write the content written to each of two output streams. @@ -18,6 +24,16 @@ namespace slime.jrunscript.native.inonit.script.runtime.io { // TODO we don't really have a great way currently to represent bytes readBytes: (input: java.io.InputStream) => slime.jrunscript.Array + readString: (reader: slime.jrunscript.native.java.io.Reader) => slime.jrunscript.native.java.lang.String + + readAll: { + (reader: slime.jrunscript.native.java.io.Reader, events: slime.jrunscript.native.inonit.script.runtime.io.Streams.Events): void + } + + readLines: { + (reader: slime.jrunscript.native.java.io.Reader, delimiter: string, events: slime.jrunscript.native.inonit.script.runtime.io.Streams.Events): void + } + copy: { (i: slime.jrunscript.native.java.io.InputStream, o: slime.jrunscript.native.java.io.OutputStream, closeInputStream?: boolean): void (r: slime.jrunscript.native.java.io.Reader, w: slime.jrunscript.native.java.io.Writer): void diff --git a/rhino/system/java/inonit/script/runtime/io/Streams.java b/rhino/system/java/inonit/script/runtime/io/Streams.java index c26baae39..bb6f10491 100644 --- a/rhino/system/java/inonit/script/runtime/io/Streams.java +++ b/rhino/system/java/inonit/script/runtime/io/Streams.java @@ -68,6 +68,23 @@ public void writeString(String string, OutputStream out) throws IOException { writer.flush(); } + public static abstract class ReadEvents { + public abstract void progress(T t); + public abstract void error(IOException e); + public abstract void done(); + } + + public void readAll(java.io.Reader reader, ReadEvents events) { + try { + String string = readString(reader); + events.progress(string); + } catch (IOException e) { + events.error(e); + } finally { + events.done(); + } + } + public String readLine(java.io.Reader reader, String lineTerminator) throws IOException { String rv = ""; while(true) { @@ -83,6 +100,32 @@ public String readLine(java.io.Reader reader, String lineTerminator) throws IOEx } } + public void readLines(java.io.Reader reader, String lineTerminator, ReadEvents events) { + boolean more = true; + String rv = ""; + while(more) { + int i; + try { + i = reader.read(); + } catch (IOException e) { + events.error(e); + return; + } + if (i != -1) { + char c = (char)i; + rv += c; + } + if (i == -1 || rv.endsWith(lineTerminator)) { + events.progress(rv); + rv = ""; + } + if (i == -1) { + more = false; + } + } + events.done(); + } + public static class Null { public static final InputStream INPUT_STREAM = new InputStream() { public int read() {