/** * This is used to ensure that there is enough space in the buffer * to allow for more bytes to be added. If the buffer is already * larger than the required capacity the this will do nothing. * * @param capacity the minimum size needed for the buffer */ private void expand(int capacity) throws IOException { if(capacity > limit) { throw new TransportException("Capacity limit exceeded"); } byte[] temp = new byte[capacity]; int start = capacity - count; int shift = pos - mark ; if(count > 0) { System.arraycopy(buffer, pos, temp, start, count); } pos = capacity - count; mark = pos - shift; buffer = temp; }
/** * Constructor for the <code>TransportException</code> object. If * there is a problem sending or reading from a transport then it * will throw a transport exception to report the error. * * @param message this is the message associated with the error * @param cause this is the cause of the producer exception */ public TransportException(String message, Throwable cause) { super(message); initCause(cause); } }
/** * This is used to ensure that there is enough space in the buffer * to allow for more bytes to be added. If the buffer is already * larger than the required capacity the this will do nothing. * * @param capacity the minimum size needed for the buffer */ private void expand(int capacity) throws IOException { if(capacity > limit) { throw new TransportException("Capacity limit exceeded"); } byte[] temp = new byte[capacity]; int start = capacity - count; int shift = pos - mark ; if(count > 0) { System.arraycopy(buffer, pos, temp, start, count); } pos = capacity - count; mark = pos - shift; buffer = temp; }
/** * Constructor for the <code>TransportException</code> object. If * there is a problem sending or reading from a transport then it * will throw a transport exception to report the error. * * @param message this is the message associated with the error * @param cause this is the cause of the producer exception */ public TransportException(String message, Throwable cause) { super(message); initCause(cause); } }
/** * This is used to determine if the buffer is ready to be written * to. A buffer is ready when it does not hold a reference to * any other buffer internally. The the <code>flush</code> method * must return true for a buffer to be considered ready. * * @return returns true if the buffer is ready to write to */ public synchronized boolean ready() throws IOException { if(closed) { throw new TransportException("Buffer has been closed"); } if(reference != null) { int remaining = reference.remaining(); if(remaining <= 0) { reference = null; return true; } return false; } return true; }
/** * Constructor for the <code>TransportException</code> object. If * there is a problem sending or reading from a transport then it * will throw a transport exception to report the error. * * @param message this is the message associated with the error * @param cause this is the cause of the producer exception */ public TransportException(String message, Throwable cause) { super(message); initCause(cause); } }
/** * This is used to determine if the buffer is ready to be written * to. A buffer is ready when it does not hold a reference to * any other buffer internally. The the <code>flush</code> method * must return true for a buffer to be considered ready. * * @return returns true if the buffer is ready to write to */ public synchronized boolean ready() throws IOException { if(closed) { throw new TransportException("Buffer has been closed"); } if(reference != null) { int remaining = reference.remaining(); if(remaining <= 0) { reference = null; return true; } return false; } return true; }
/** * This is used to ensure that there is enough space in the buffer * to allow for more bytes to be added. If the buffer is already * larger than the required capacity the this will do nothing. * * @param capacity the minimum size needed for the buffer */ private void expand(int capacity) throws IOException { if(capacity > limit) { throw new TransportException("Capacity limit exceeded"); } byte[] temp = new byte[capacity]; int start = capacity - count; int shift = pos - mark ; if(count > 0) { System.arraycopy(buffer, pos, temp, start, count); } pos = capacity - count; mark = pos - shift; buffer = temp; }
/** * This is used to listen for a notification from the reactor to * tell the thread that the write operation has completed. If * the thread is interrupted upon this call then this will throw * an <code>IOException</code> with the root cause. */ private void listen() throws IOException { try { if(!closed) { trace.trace(WRITE_BLOCKING); lock.wait(120000); } } catch(Exception e) { throw new TransportException("Schedule error", e); } if(closed) { throw new TransportException("Socket closed"); } }
/** * This method is used to flush the contents of the buffer to * the client. This method will block until such time as all of * the data has been sent to the client. If at any point there * is an error sending the content an exception is thrown. */ public void flush() throws IOException { if(closed) { throw new TransportException("Transport is closed"); } transport.flush(); }
/** * This method is used to flush the contents of the buffer to * the client. This method will block until such time as all of * the data has been sent to the client. If at any point there * is an error sending the content an exception is thrown. */ public void flush() throws IOException { if(closed) { throw new TransportException("Transport is closed"); } transport.flush(); }
/** * This is used to listen for a notification from the reactor to * tell the thread that the write operation has completed. If * the thread is interrupted upon this call then this will throw * an <code>IOException</code> with the root cause. */ private void listen() throws IOException { if(flushing) { throw new TransportException("Socket already flushing"); } try { if(!closed) { try { flushing = true; trace.trace(WRITE_BLOCKING); lock.wait(120000); } finally { flushing = false; } } } catch(Exception e) { throw new TransportException("Could not schedule for flush", e); } if(closed) { throw new TransportException("Socket closed"); } }
/** * This is used to flush the internal buffer to the underlying * socket. Flushing with this method is always non-blocking, so * if the socket is not write ready and the buffer can be queued * it will be queued and the calling thread will return. */ public void flush() throws IOException { if(closed) { throw new TransportException("Transport is closed"); } writer.flush(); }
/** * This is used to listen for a notification from the reactor to * tell the thread that the write operation has completed. If * the thread is interrupted upon this call then this will throw * an <code>IOException</code> with the root cause. */ private void listen() throws IOException { if(flushing) { throw new TransportException("Socket already flushing"); } try { if(!closed) { try { flushing = true; trace.trace(WRITE_BLOCKING); lock.wait(120000); } finally { flushing = false; } } } catch(Exception e) { throw new TransportException("Could not schedule for flush", e); } if(closed) { throw new TransportException("Socket closed"); } }
/** * This method is used to flush the contents of the buffer to * the client. This method will block until such time as all of * the data has been sent to the client. If at any point there * is an error sending the content an exception is thrown. */ public void flush() throws IOException { if(closed) { throw new TransportException("Transport is closed"); } transport.flush(); }
/** * This is used to flush the internal buffer to the underlying * socket. Flushing with this method is always non-blocking, so * if the socket is not write ready and the buffer can be queued * it will be queued and the calling thread will return. */ public void flush() throws IOException { if(closed) { throw new TransportException("Transport is closed"); } writer.flush(); }
/** * This will append bytes within the transport to the given buffer. * Once invoked the buffer will contain the transport bytes, which * will have been drained from the buffer. This effectively moves * the bytes in the buffer to the end of the packet instance. * * @param buffer this is the buffer containing the bytes * @param count this is the number of bytes that should be used * * @return returns the number of bytes that have been moved */ private int append(ByteBuffer buffer, int count) throws IOException { ByteBuffer segment = input.slice(); if(closed) { throw new TransportException("Transport is closed"); } int mark = input.position(); int size = mark + count; if(count > 0) { input.position(size); segment.limit(count); buffer.put(segment); } return count; }
/** * This method is used to deliver the provided buffer of bytes to * the underlying transport. Depending on the connection type the * array may be encoded for SSL transport or send directly. This * will buffer the bytes within the internal buffer to ensure * that the response fragments are sufficiently large for the * network. Smaller packets result poorer performance. * * @param data this is the array of bytes to send to the client */ public void write(ByteBuffer data) throws IOException{ if(closed) { throw new TransportException("Transport is closed"); } writer.write(data); }
/** * This method is used to deliver the provided buffer of bytes to * the underlying transport. Depending on the connection type the * array may be encoded for SSL transport or send directly. This * will buffer the bytes within the internal buffer to ensure * that the response fragments are sufficiently large for the * network. Smaller packets result poorer performance. * * @param data this is the array of bytes to send to the client */ public void write(ByteBuffer data) throws IOException{ if(closed) { throw new TransportException("Transport is closed"); } writer.write(data); }
/** * This is used to perform a non-blocking read on the transport. * If there are no bytes available on the input buffers then * this method will return zero and the buffer will remain the * same. If there is data and the buffer can be filled then this * will return the number of bytes read. Finally if the socket * is closed this will return a -1 value. */ private void receive() throws IOException { int count = swap.remaining(); while(count > 0) { SSLEngineResult result = engine.unwrap(swap, input); Status status = result.getStatus(); switch(status) { case BUFFER_OVERFLOW: case BUFFER_UNDERFLOW: return; case CLOSED: throw new TransportException("Transport error " + result); } count = swap.remaining(); if(count <= 0) { break; } } }