| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- using Invercargill;
- using Invercargill.DataStructures;
- namespace Astralis {
- internal class ServerOutput : Object, AsyncOutput {
- const int MAX_CHUNKS = 5;
- private BinaryData current_chunk = null;
- private Series<ByteBuffer> chunks = new Series<ByteBuffer>();
- internal signal void on_new_chunk();
- internal signal void on_chunk_poped();
- private delegate void Handler();
- private bool _connected = true;
- public bool connected { get { return _connected; } }
- public bool write_would_block {
- get {
- return chunks.length > MAX_CHUNKS;
- }
- }
- internal void close_connection() {
- _connected = false;
- }
- public async void write (Invercargill.BinaryData data) throws Error {
- if (!_connected) {
- throw new IOError.CLOSED("Cannot write to disconnected client");
- }
-
- while(chunks.length > MAX_CHUNKS) {
- ulong handler_id = 0;
- handler_id = on_chunk_poped.connect(() => {
- SignalHandler.disconnect(this, handler_id);
- Idle.add(write.callback);
- });
- yield;
- }
- var buffer = data.to_byte_buffer();
- if(buffer.length > 0) {
- chunks.add(buffer);
- on_new_chunk();
- }
- }
- internal size_t read_chunk(void* buffer, size_t max_size) {
- if(current_chunk != null && current_chunk.peek_count() == 0) {
- current_chunk = null;
- }
- if(current_chunk == null && chunks.length == 0) {
- return 0;
- }
- if(current_chunk == null) {
- current_chunk = chunks.pop_start ();
- on_chunk_poped();
- }
-
- var size = current_chunk.write_to (buffer, max_size);
- current_chunk = current_chunk.skip((uint)size);
- return size;
- }
- }
- }
|