private void invokeOnComplete(final IoCallback callback) { inCall = true; try { callback.onComplete(exchange, this); } finally { inCall = false; } while (next != null || pendingFile != null) { ByteBuffer[] next = this.next; IoCallback queuedCallback = this.queuedCallback; FileChannel file = this.pendingFile; this.next = null; this.queuedCallback = null; this.pendingFile = null; if (next != null) { for (ByteBuffer buffer : next) { writeBuffer(buffer, queuedCallback); } } else if (file != null) { performTransfer(file, queuedCallback); } inCall = true; try { queuedCallback.onComplete(exchange, this); } finally { inCall = false; } } }
private boolean writeBuffer(final ByteBuffer[] buffers, final IoCallback callback) { if (outputStream instanceof BufferWritableOutputStream) { // fast path, if the stream can take a buffer directly just write to it try { ((BufferWritableOutputStream) outputStream).write(buffers); return true; } catch (IOException e) { callback.onException(exchange, this, e); return false; } } for (ByteBuffer buffer : buffers) { if (buffer.hasArray()) { try { outputStream.write(buffer.array(), buffer.arrayOffset(), buffer.remaining()); } catch (IOException e) { callback.onException(exchange, this, e); return false; } } else { byte[] b = new byte[BUFFER_SIZE]; while (buffer.hasRemaining()) { int toRead = Math.min(buffer.remaining(), BUFFER_SIZE); buffer.get(b, 0, toRead); try { outputStream.write(b, 0, toRead); } catch (IOException e) { callback.onException(exchange, this, e); return false; } } } } return true; }
private void performTransfer(FileChannel source, IoCallback callback) { if (outputStream instanceof BufferWritableOutputStream) { try { ((BufferWritableOutputStream) outputStream).transferFrom(source); } catch (IOException e) { callback.onException(exchange, this, e); } } else { ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE); try { long pos = source.position(); long size = source.size(); while (size - pos > 0) { int ret = source.read(buffer); if (ret <= 0) { break; } pos += ret; outputStream.write(buffer.array(), buffer.arrayOffset(), ret); buffer.clear(); } if (pos != size) { throw new EOFException("Unexpected EOF reading file"); } } catch (IOException e) { callback.onException(exchange, this, e); } } }
@Override public void close(final IoCallback callback) { try { outputStream.close(); invokeOnComplete(callback); } catch (IOException e) { callback.onException(exchange, this, e); } }
@Override public void send(final String data, final IoCallback callback) { if (inCall) { queue(new ByteBuffer[] {ByteBuffer.wrap(data.getBytes(utf8))}, callback); return; } try { outputStream.write(data.getBytes(utf8)); invokeOnComplete(callback); } catch (IOException e) { callback.onException(exchange, this, e); } }