|
@@ -1,11 +1,79 @@
|
|
|
using Invercargill;
|
|
using Invercargill;
|
|
|
|
|
+using Invercargill.DataStructures;
|
|
|
|
|
|
|
|
namespace Astralis {
|
|
namespace Astralis {
|
|
|
|
|
|
|
|
public interface AsyncOutput : Object {
|
|
public interface AsyncOutput : Object {
|
|
|
|
|
|
|
|
- public abstract async void write(BinaryData data);
|
|
|
|
|
- public abstract async void write_stream(OutputStream stream);
|
|
|
|
|
|
|
+ public abstract async void write(BinaryData data) throws Error;
|
|
|
|
|
+ public abstract async void write_stream(InputStream stream) throws Error;
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public class ConverterAsyncOutput : Object, AsyncOutput {
|
|
|
|
|
+
|
|
|
|
|
+ private AsyncOutput inner;
|
|
|
|
|
+ private Converter converter;
|
|
|
|
|
+
|
|
|
|
|
+ public ConverterAsyncOutput(AsyncOutput output, Converter converter) {
|
|
|
|
|
+ this.inner = output;
|
|
|
|
|
+ this.converter = converter;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public async void write(Invercargill.BinaryData data) throws Error {
|
|
|
|
|
+ var in_buffer = data.to_array();
|
|
|
|
|
+ size_t in_offset = 0;
|
|
|
|
|
+ const size_t BUFFER_SIZE = 4096;
|
|
|
|
|
+
|
|
|
|
|
+ while (in_offset < in_buffer.length) {
|
|
|
|
|
+ uint8[] out_buffer = new uint8[BUFFER_SIZE];
|
|
|
|
|
+ size_t bytes_read = 0;
|
|
|
|
|
+ size_t bytes_written = 0;
|
|
|
|
|
+
|
|
|
|
|
+ ConverterFlags flags = ConverterFlags.NONE;
|
|
|
|
|
+ if (in_offset + bytes_read >= in_buffer.length) {
|
|
|
|
|
+ flags |= ConverterFlags.INPUT_AT_END;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ConverterResult result;
|
|
|
|
|
+ try {
|
|
|
|
|
+ result = converter.convert(
|
|
|
|
|
+ in_buffer[in_offset:in_buffer.length],
|
|
|
|
|
+ out_buffer,
|
|
|
|
|
+ flags,
|
|
|
|
|
+ out bytes_read,
|
|
|
|
|
+ out bytes_written
|
|
|
|
|
+ );
|
|
|
|
|
+ } catch (IOError.NO_SPACE e) {
|
|
|
|
|
+ // Need larger output buffer, try again with bigger buffer
|
|
|
|
|
+ out_buffer = new uint8[BUFFER_SIZE * 2];
|
|
|
|
|
+ result = converter.convert(
|
|
|
|
|
+ in_buffer[in_offset:in_buffer.length],
|
|
|
|
|
+ out_buffer,
|
|
|
|
|
+ flags,
|
|
|
|
|
+ out bytes_read,
|
|
|
|
|
+ out bytes_written
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ in_offset += bytes_read;
|
|
|
|
|
+
|
|
|
|
|
+ if (bytes_written > 0) {
|
|
|
|
|
+ yield inner.write(new ByteBuffer.from_byte_array(out_buffer[0:bytes_written]));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (result == ConverterResult.FINISHED || result == ConverterResult.FLUSHED) {
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public async void write_stream(GLib.InputStream stream) throws Error {
|
|
|
|
|
+ var converter_stream = new ConverterInputStream(stream, converter);
|
|
|
|
|
+ yield inner.write_stream(converter_stream);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|