|
|
@@ -1,433 +0,0 @@
|
|
|
-/*
|
|
|
- * @author Ranides Atterwim <ranides@gmail.com>
|
|
|
- * @copyright Ranides Atterwim
|
|
|
- * @license WTFPL
|
|
|
- * @url http://ranides.net/projects/assira
|
|
|
- */
|
|
|
-package net.ranides.assira.io;
|
|
|
-
|
|
|
-import java.io.IOException;
|
|
|
-import java.io.InputStream;
|
|
|
-import java.io.OutputStream;
|
|
|
-import net.ranides.assira.annotations.Meta;
|
|
|
-import net.ranides.assira.events.EventListener;
|
|
|
-import net.ranides.assira.events.EventRouter;
|
|
|
-import net.ranides.assira.events.EventReactor;
|
|
|
-import net.ranides.assira.events.ReflectEventListener;
|
|
|
-import net.ranides.assira.trace.AdvLogger;
|
|
|
-import net.ranides.assira.trace.LoggerUtils;
|
|
|
-
|
|
|
-/**
|
|
|
- *
|
|
|
- * @author ranides
|
|
|
- */
|
|
|
-public final class AsyncStream {
|
|
|
-
|
|
|
- private AsyncStream() {
|
|
|
- // utility class
|
|
|
- }
|
|
|
-
|
|
|
- public static OutputStream create(OutputStream ostream, String logger) {
|
|
|
- return create(ostream, LoggerUtils.getLogger(logger));
|
|
|
- }
|
|
|
-
|
|
|
- public static OutputStream create(OutputStream ostream, final AdvLogger logger) {
|
|
|
- return create(ostream, new OutputListener(ostream) {
|
|
|
- @Override
|
|
|
- public void handleEvent(IOEvent event) {
|
|
|
- if(event instanceof IOEvent.Failure) {
|
|
|
- logger.error( ((IOEvent.Failure)event).cause() );
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- public static OutputStream create(OutputStream ostream, final EventListener<? super IOEvent> listener) {
|
|
|
- return create(new OutputListener(ostream) {
|
|
|
- @Override
|
|
|
- public void handleEvent(IOEvent event) {
|
|
|
- listener.handleEvent(event);
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- public static OutputStream create(OutputListener listener) {
|
|
|
-
|
|
|
- final EventRouter router = EventReactor.newInstance("OutputStreamer", Integer.MAX_VALUE, Integer.MAX_VALUE);
|
|
|
-
|
|
|
- router.addEventListener(IORequest.class, new OutputDevice(listener));
|
|
|
-
|
|
|
- return new OutputDriver() {
|
|
|
- @Override
|
|
|
- public void handleEvent(IORequest event) {
|
|
|
- router.handleEvent(event);
|
|
|
- }
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- public static InputStream create(final InputStream ostream, String logger) {
|
|
|
- return create(ostream, LoggerUtils.getLogger(logger));
|
|
|
- }
|
|
|
-
|
|
|
- public static InputStream create(final InputStream ostream, final AdvLogger logger) {
|
|
|
- return create(ostream, new InputListener(ostream) {
|
|
|
- @Override
|
|
|
- public void handleEvent(IOEvent event) {
|
|
|
- if(event instanceof IOEvent.Failure) {
|
|
|
- logger.error( ((IOEvent.Failure)event).cause() );
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- public static InputStream create(final InputStream ostream, final EventListener<? super IOEvent> listener) {
|
|
|
- return new InputListener(ostream) {
|
|
|
- @Override
|
|
|
- public void handleEvent(IOEvent event) {
|
|
|
- listener.handleEvent(event);
|
|
|
- }
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Transformacja: {@code read -> stream.read -> handle(IOEvent)}
|
|
|
- */
|
|
|
- public static abstract class InputListener extends InputStream implements EventListener<IOEvent> {
|
|
|
-
|
|
|
- private final InputStream istream;
|
|
|
-
|
|
|
- public InputListener(final InputStream istream) {
|
|
|
- this.istream = istream;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public abstract void handleEvent(IOEvent event);
|
|
|
-
|
|
|
- @Override
|
|
|
- public int read() throws IOException {
|
|
|
- try {
|
|
|
- int data = istream.read();
|
|
|
- handleEvent(IOEvent.read(data));
|
|
|
- return data;
|
|
|
- } catch(IOException cause) {
|
|
|
- handleEvent(IOEvent.failure(cause));
|
|
|
- throw cause;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public int read(byte array[]) throws IOException {
|
|
|
- try {
|
|
|
- int delta = istream.read(array);
|
|
|
- handleEvent(IOEvent.read(array, 0, delta));
|
|
|
- return delta;
|
|
|
- } catch(IOException cause) {
|
|
|
- handleEvent(IOEvent.failure(cause));
|
|
|
- throw cause;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public int read(byte array[], int offset, int length) throws IOException {
|
|
|
- try {
|
|
|
- int delta = istream.read(array, offset, length);
|
|
|
- handleEvent(IOEvent.read(array, offset, delta));
|
|
|
- return delta;
|
|
|
- } catch(IOException cause) {
|
|
|
- handleEvent(IOEvent.failure(cause));
|
|
|
- throw cause;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public long skip(long n) throws IOException {
|
|
|
- try {
|
|
|
- long delta = istream.skip(n);
|
|
|
- handleEvent(IOEvent.skip(delta));
|
|
|
- return delta;
|
|
|
- } catch(IOException cause) {
|
|
|
- handleEvent(IOEvent.failure(cause));
|
|
|
- throw cause;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public int available() throws IOException {
|
|
|
- try {
|
|
|
- return istream.available();
|
|
|
- } catch(IOException cause) {
|
|
|
- handleEvent(IOEvent.failure(cause));
|
|
|
- throw cause;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void close() throws IOException {
|
|
|
- try {
|
|
|
- istream.close();
|
|
|
- handleEvent(IOEvent.close());
|
|
|
- } catch(IOException cause) {
|
|
|
- handleEvent(IOEvent.failure(cause));
|
|
|
- throw cause;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public synchronized void mark(int readlimit) {
|
|
|
- istream.mark(readlimit);
|
|
|
- handleEvent(IOEvent.mark(readlimit));
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public synchronized void reset() throws IOException {
|
|
|
- try {
|
|
|
- istream.reset();
|
|
|
- handleEvent(IOEvent.reset());
|
|
|
- } catch(IOException cause) {
|
|
|
- handleEvent(IOEvent.failure(cause));
|
|
|
- throw cause;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public boolean markSupported() {
|
|
|
- return istream.markSupported();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Transformacja: {@code handle(IORequest) -> stream.read}
|
|
|
- */
|
|
|
- public static class InputDevice extends ReflectEventListener<IORequest> {
|
|
|
-
|
|
|
- private final InputListener device;
|
|
|
-
|
|
|
- public InputDevice(InputListener device) {
|
|
|
- this.device = device;
|
|
|
- }
|
|
|
-
|
|
|
- @Meta.EventHandler
|
|
|
- void onEvent(IORequest.ReadByte event) {
|
|
|
- try {
|
|
|
- device.read();
|
|
|
- } catch(IOException cause) {
|
|
|
- device.handleEvent(IOEvent.failure(cause));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Meta.EventHandler
|
|
|
- void onEvent(IORequest.ReadByteArray event) {
|
|
|
- try {
|
|
|
- byte[] target = new byte[event.count()];
|
|
|
- device.read(target);
|
|
|
- } catch(IOException cause) {
|
|
|
- device.handleEvent(IOEvent.failure(cause));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Meta.EventHandler
|
|
|
- void onEvent(IORequest.Skip event) {
|
|
|
- try {
|
|
|
- device.skip(event.delta());
|
|
|
- } catch(IOException cause) {
|
|
|
- device.handleEvent(IOEvent.failure(cause));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Meta.EventHandler
|
|
|
- void onEvent(IORequest.Close event) {
|
|
|
- try {
|
|
|
- device.close();
|
|
|
- } catch(IOException cause) {
|
|
|
- device.handleEvent(IOEvent.failure(cause));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Meta.EventHandler
|
|
|
- void onEvent(IORequest.Mark event) {
|
|
|
- device.mark(event.limit());
|
|
|
- }
|
|
|
-
|
|
|
- @Meta.EventHandler
|
|
|
- void onEvent(IORequest.Reset event) {
|
|
|
- try {
|
|
|
- device.reset();
|
|
|
- } catch(IOException cause) {
|
|
|
- device.handleEvent(IOEvent.failure(cause));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Meta.EventHandler
|
|
|
- void onEvent(IOEvent.Failure event) {
|
|
|
- device.handleEvent(event);
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Transformacja: {@code write -> stream.write -> handle(IOEvent)}
|
|
|
- */
|
|
|
- public static abstract class OutputListener extends OutputStream implements EventListener<IOEvent> {
|
|
|
-
|
|
|
- private final OutputStream ostream;
|
|
|
-
|
|
|
- public OutputListener(OutputStream ostream) {
|
|
|
- this.ostream = ostream;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public abstract void handleEvent(IOEvent event);
|
|
|
-
|
|
|
- @Override
|
|
|
- public void write(int value) throws IOException {
|
|
|
- try {
|
|
|
- ostream.write(value);
|
|
|
- handleEvent(IOEvent.write(value));
|
|
|
- } catch(IOException cause) {
|
|
|
- handleEvent(IOEvent.failure(cause));
|
|
|
- throw cause;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void write(byte array[]) throws IOException {
|
|
|
- try {
|
|
|
- ostream.write(array);
|
|
|
- handleEvent(IOEvent.write(array));
|
|
|
- } catch(IOException cause) {
|
|
|
- handleEvent(IOEvent.failure(cause));
|
|
|
- throw cause;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void write(byte array[], int offset, int length) throws IOException {
|
|
|
- try {
|
|
|
- ostream.write(array, offset, length);
|
|
|
- handleEvent(IOEvent.write(array, offset, length));
|
|
|
- } catch(IOException cause) {
|
|
|
- handleEvent(IOEvent.failure(cause));
|
|
|
- throw cause;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void flush() throws IOException {
|
|
|
- try {
|
|
|
- ostream.flush();
|
|
|
- handleEvent(IOEvent.flush());
|
|
|
- } catch(IOException cause) {
|
|
|
- handleEvent(IOEvent.failure(cause));
|
|
|
- throw cause;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void close() throws IOException {
|
|
|
- try {
|
|
|
- ostream.close();
|
|
|
- handleEvent(IOEvent.close());
|
|
|
- } catch(IOException cause) {
|
|
|
- handleEvent(IOEvent.failure(cause));
|
|
|
- throw cause;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Transformacja: {@code write -> handle(IORequest)}
|
|
|
- * <ul>
|
|
|
- * <li>metody nie sygnalizują błędów wyjątkami</li>
|
|
|
- * <li>błędy są sygnalizowane jako {@link IOEvent.Failure IOEvent.Failure}</li>
|
|
|
- * </ul>
|
|
|
- */
|
|
|
- public static abstract class OutputDriver extends OutputStream implements EventListener<IORequest> {
|
|
|
-
|
|
|
- public OutputDriver() {
|
|
|
- // do nothing
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public abstract void handleEvent(IORequest event);
|
|
|
-
|
|
|
- @Override
|
|
|
- public void write(int value) {
|
|
|
- handleEvent(IORequest.write(value));
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void write(byte array[]) {
|
|
|
- handleEvent(IORequest.write(array));
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void write(byte array[], int offset, int length) {
|
|
|
- handleEvent(IORequest.write(array, offset, length));
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void flush() {
|
|
|
- handleEvent(IORequest.flush());
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void close() {
|
|
|
- handleEvent(IORequest.close());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Transformacja: {@code handle(IORequest) -> stream.write}
|
|
|
- */
|
|
|
- public static class OutputDevice extends ReflectEventListener<IORequest> {
|
|
|
-
|
|
|
- private final OutputListener device;
|
|
|
-
|
|
|
- public OutputDevice(OutputListener ostream) {
|
|
|
- this.device = ostream;
|
|
|
- }
|
|
|
-
|
|
|
- @Meta.EventHandler
|
|
|
- void onEvent(IORequest.WriteByte event) {
|
|
|
- try {
|
|
|
- device.write(event.data());
|
|
|
- } catch(IOException cause) {
|
|
|
- device.handleEvent(IOEvent.failure(cause));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Meta.EventHandler
|
|
|
- void onEvent(IORequest.WriteByteArray event) {
|
|
|
- try {
|
|
|
- device.write(event.data());
|
|
|
- } catch(IOException cause) {
|
|
|
- device.handleEvent(IOEvent.failure(cause));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Meta.EventHandler
|
|
|
- void onEvent(IORequest.Flush event) {
|
|
|
- try {
|
|
|
- device.flush();
|
|
|
- } catch(IOException cause) {
|
|
|
- device.handleEvent(IOEvent.failure(cause));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Meta.EventHandler
|
|
|
- void onEvent(IORequest.Close event) {
|
|
|
- try {
|
|
|
- device.close();
|
|
|
- } catch(IOException cause) {
|
|
|
- device.handleEvent(IOEvent.failure(cause));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Meta.EventHandler
|
|
|
- void onEvent(IOEvent.Failure event) {
|
|
|
- device.handleEvent(event);
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-}
|