Methods Summary |
---|
protected abstract void | cryptoIn(java.nio.ByteBuffer source_buffer, java.nio.ByteBuffer target_buffer)
|
protected abstract void | cryptoOut(java.nio.ByteBuffer source_buffer, java.nio.ByteBuffer target_buffer)
|
public TransportHelper | getHelper()
return( transport );
|
public boolean | hasBufferedRead()
return false;
|
public boolean | hasBufferedWrite()
return( write_buffer_pending_db != null ||
write_buffer_pending_byte != null ||
transport.hasDelayedWrite());
|
public long | read(java.nio.ByteBuffer[] buffers, int array_offset, int length)
int total_read = 0;
DirectByteBuffer[] copy_db = new DirectByteBuffer[buffers.length];
ByteBuffer[] copy = new ByteBuffer[buffers.length];
try{
for (int i=array_offset;i<array_offset+length;i++){
ByteBuffer buffer = buffers[i];
int size = buffer.remaining();
if ( size > 0 ){
copy_db[i] = DirectByteBufferPool.getBuffer( DirectByteBuffer.AL_NET_CRYPT, size );
copy[i] = copy_db[i].getBuffer( DirectByteBuffer.SS_NET );
}else{
copy[i] = ByteBuffer.allocate(0);
}
}
total_read += transport.read( copy, array_offset, length );
for (int i=array_offset;i<array_offset+length;i++){
ByteBuffer source_buffer = copy[i];
if ( source_buffer != null ){
ByteBuffer target_buffer = buffers[i];
int source_position = source_buffer.position();
if ( source_position > 0 ){
source_buffer.flip();
cryptoIn( source_buffer, target_buffer );
}
}
}
// System.out.println( "...read " + total_read );
return( total_read );
}finally{
for (int i=0;i<copy_db.length;i++){
if ( copy_db[i] != null ){
copy_db[i].returnToPool();
}
}
}
|
public void | setTrace(boolean on)
transport.setTrace( on );
|
public long | write(java.nio.ByteBuffer[] buffers, int array_offset, int length)
// deal with any outstanding cached crypted data first
if ( write_buffer_pending_byte != null ){
if ( transport.write( write_buffer_pending_byte, false ) == 0 ){
return( 0 );
}
write_buffer_pending_byte = null;
}
long total_written = 0;
if ( write_buffer_pending_db != null ){
ByteBuffer write_buffer_pending = write_buffer_pending_db.getBuffer( DirectByteBuffer.SS_NET );
int max_writable = 0;
for (int i=array_offset;i<array_offset+length;i++){
ByteBuffer source_buffer = buffers[i];
int position = source_buffer.position();
int limit = source_buffer.limit();
int size = limit - position;
max_writable += size;
}
int pending_position = write_buffer_pending.position();
int pending_limit = write_buffer_pending.limit();
int pending_writable = pending_limit - pending_position;
if ( pending_writable > max_writable ){
pending_writable = max_writable;
write_buffer_pending.limit( pending_position + pending_writable );
}
int written = transport.write( write_buffer_pending, false );
write_buffer_pending.limit( pending_limit );
if ( written > 0 ){
total_written = written;
if ( write_buffer_pending.remaining() == 0 ){
write_buffer_pending_db.returnToPool();
write_buffer_pending_db = null;
}
// skip "written" bytes in the source
int skip = written;
for (int i=array_offset;i<array_offset+length;i++){
ByteBuffer source_buffer = buffers[i];
int position = source_buffer.position();
int limit = source_buffer.limit();
int size = limit - position;
if ( size <= skip ){
source_buffer.position( limit );
skip -= size;
}else{
source_buffer.position( position + skip );
skip = 0;
break;
}
}
if ( skip != 0 ){
throw( new IOException( "skip inconsistent - " + skip ));
}
}
// if write came up short or we've filled the source buffer then we can't do
// any more
if ( total_written < pending_writable || total_written == max_writable ){
return( total_written );
}
}
// problem - we must only crypt stuff once and when crypted it *has*
// to be sent (else the stream will get out of sync).
// so we have to turn this into single buffer operations
for (int i=array_offset;i<array_offset+length;i++){
ByteBuffer source_buffer = buffers[i];
int position = source_buffer.position();
int limit = source_buffer.limit();
int size = limit - position;
if ( size == 0 ){
continue;
}
DirectByteBuffer target_buffer_db = DirectByteBufferPool.getBuffer( DirectByteBuffer.AL_NET_CRYPT, size );
try{
ByteBuffer target_buffer = target_buffer_db.getBuffer( DirectByteBuffer.SS_NET );
cryptoOut( source_buffer, target_buffer );
target_buffer.position( 0 );
boolean partial_write = false;
for (int j=i+1;j<array_offset+length;j++){
if ( buffers[j].hasRemaining()){
partial_write = true;
}
}
int written = transport.write( target_buffer, partial_write );
total_written += written;
source_buffer.position( position + written );
if ( written < size ){
write_buffer_pending_db = target_buffer_db;
target_buffer_db = null;
if ( written == 0 ){
// we gotta pretend at least 1 byte was written to
// guarantee that the caller writes the rest
write_buffer_pending_byte = ByteBuffer.wrap(new byte[]{target_buffer.get()});
source_buffer.get();
total_written++;
}
break;
}
}finally{
if ( target_buffer_db != null ){
target_buffer_db.returnToPool();
}
}
}
// System.out.println( "...write " + total_written );
return( total_written );
|