Converted {Incoming,Outgoing}BatchConnection into Runnables.

Also changed the dispose() method of readers/writers/connections to
swallow any exceptions that occur, since the caller can't do anything
except log them.
This commit is contained in:
akwizgran
2011-10-14 16:14:29 +01:00
parent 55182528cf
commit d48c7b6900
14 changed files with 290 additions and 92 deletions

View File

@@ -1,6 +1,5 @@
package net.sf.briar.api.transport; package net.sf.briar.api.transport;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
/** /**
@@ -16,5 +15,5 @@ public interface BatchTransportReader {
* Closes the reader and disposes of any associated state. The argument * Closes the reader and disposes of any associated state. The argument
* should be false if an exception was thrown while using the reader. * should be false if an exception was thrown while using the reader.
*/ */
void dispose(boolean success) throws IOException; void dispose(boolean success);
} }

View File

@@ -1,6 +1,5 @@
package net.sf.briar.api.transport; package net.sf.briar.api.transport;
import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
/** /**
@@ -19,5 +18,5 @@ public interface BatchTransportWriter {
* Closes the writer and disposes of any associated state. The argument * Closes the writer and disposes of any associated state. The argument
* should be false if an exception was thrown while using the writer. * should be false if an exception was thrown while using the writer.
*/ */
void dispose(boolean success) throws IOException; void dispose(boolean success);
} }

View File

@@ -21,5 +21,5 @@ public interface StreamTransportConnection {
* Closes the connection and disposes of any associated state. The argument * Closes the connection and disposes of any associated state. The argument
* should be false if an exception was thrown while using the connection. * should be false if an exception was thrown while using the connection.
*/ */
void dispose(boolean success) throws IOException; void dispose(boolean success);
} }

View File

@@ -0,0 +1,15 @@
package net.sf.briar.api.transport.batch;
import net.sf.briar.api.ContactId;
import net.sf.briar.api.TransportId;
import net.sf.briar.api.transport.BatchTransportReader;
import net.sf.briar.api.transport.BatchTransportWriter;
public interface BatchConnectionFactory {
Runnable createOutgoingConnection(TransportId t, ContactId c,
BatchTransportWriter w);
Runnable createIncomingConnection(ContactId c, BatchTransportReader r,
byte[] encryptedIv);
}

View File

@@ -3,6 +3,8 @@ package net.sf.briar.plugins.bluetooth;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.microedition.io.StreamConnection; import javax.microedition.io.StreamConnection;
@@ -10,6 +12,9 @@ import net.sf.briar.api.transport.StreamTransportConnection;
class BluetoothTransportConnection implements StreamTransportConnection { class BluetoothTransportConnection implements StreamTransportConnection {
private static final Logger LOG =
Logger.getLogger(BluetoothTransportConnection.class.getName());
private final StreamConnection stream; private final StreamConnection stream;
BluetoothTransportConnection(StreamConnection stream) { BluetoothTransportConnection(StreamConnection stream) {
@@ -24,7 +29,11 @@ class BluetoothTransportConnection implements StreamTransportConnection {
return stream.openOutputStream(); return stream.openOutputStream();
} }
public void dispose(boolean success) throws IOException { public void dispose(boolean success) {
stream.close(); try {
stream.close();
} catch(IOException e) {
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
}
} }
} }

View File

@@ -3,11 +3,16 @@ package net.sf.briar.plugins.file;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sf.briar.api.transport.BatchTransportReader; import net.sf.briar.api.transport.BatchTransportReader;
class FileTransportReader implements BatchTransportReader { class FileTransportReader implements BatchTransportReader {
private static final Logger LOG =
Logger.getLogger(FileTransportReader.class.getName());
private final File file; private final File file;
private final InputStream in; private final InputStream in;
private final FilePlugin plugin; private final FilePlugin plugin;
@@ -22,12 +27,15 @@ class FileTransportReader implements BatchTransportReader {
return in; return in;
} }
public void dispose(boolean success) throws IOException { public void dispose(boolean success) {
try { try {
in.close(); in.close();
if(success) plugin.readerFinished(file); } catch(IOException e) {
} finally { if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
}
if(success) {
file.delete(); file.delete();
plugin.readerFinished(file);
} }
} }
} }

View File

@@ -3,11 +3,16 @@ package net.sf.briar.plugins.file;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sf.briar.api.transport.BatchTransportWriter; import net.sf.briar.api.transport.BatchTransportWriter;
class FileTransportWriter implements BatchTransportWriter { class FileTransportWriter implements BatchTransportWriter {
private static final Logger LOG =
Logger.getLogger(FileTransportWriter.class.getName());
private final File file; private final File file;
private final OutputStream out; private final OutputStream out;
private final long capacity; private final long capacity;
@@ -29,12 +34,13 @@ class FileTransportWriter implements BatchTransportWriter {
return out; return out;
} }
public void dispose(boolean success) throws IOException { public void dispose(boolean success) {
try { try {
out.close(); out.close();
if(success) plugin.writerFinished(file); } catch(IOException e) {
} finally { if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
file.delete();
} }
if(success) plugin.writerFinished(file);
else file.delete();
} }
} }

View File

@@ -4,11 +4,16 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.Socket; import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sf.briar.api.transport.StreamTransportConnection; import net.sf.briar.api.transport.StreamTransportConnection;
class SocketTransportConnection implements StreamTransportConnection { class SocketTransportConnection implements StreamTransportConnection {
private static final Logger LOG =
Logger.getLogger(SocketTransportConnection.class.getName());
private final Socket socket; private final Socket socket;
SocketTransportConnection(Socket socket) { SocketTransportConnection(Socket socket) {
@@ -23,7 +28,11 @@ class SocketTransportConnection implements StreamTransportConnection {
return socket.getOutputStream(); return socket.getOutputStream();
} }
public void dispose(boolean success) throws IOException { public void dispose(boolean success) {
socket.close(); try {
socket.close();
} catch(IOException e) {
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
}
} }
} }

View File

@@ -0,0 +1,47 @@
package net.sf.briar.transport.batch;
import net.sf.briar.api.ContactId;
import net.sf.briar.api.TransportId;
import net.sf.briar.api.db.DatabaseComponent;
import net.sf.briar.api.protocol.ProtocolReaderFactory;
import net.sf.briar.api.protocol.writers.ProtocolWriterFactory;
import net.sf.briar.api.transport.BatchTransportReader;
import net.sf.briar.api.transport.BatchTransportWriter;
import net.sf.briar.api.transport.ConnectionReaderFactory;
import net.sf.briar.api.transport.ConnectionWriterFactory;
import net.sf.briar.api.transport.batch.BatchConnectionFactory;
import com.google.inject.Inject;
class BatchConnectionFactoryImpl implements BatchConnectionFactory {
private final ConnectionReaderFactory connReaderFactory;
private final ConnectionWriterFactory connWriterFactory;
private final DatabaseComponent db;
private final ProtocolReaderFactory protoReaderFactory;
private final ProtocolWriterFactory protoWriterFactory;
@Inject
BatchConnectionFactoryImpl(ConnectionReaderFactory connReaderFactory,
ConnectionWriterFactory connWriterFactory, DatabaseComponent db,
ProtocolReaderFactory protoReaderFactory,
ProtocolWriterFactory protoWriterFactory) {
this.connReaderFactory = connReaderFactory;
this.connWriterFactory = connWriterFactory;
this.db = db;
this.protoReaderFactory = protoReaderFactory;
this.protoWriterFactory = protoWriterFactory;
}
public Runnable createOutgoingConnection(TransportId t, ContactId c,
BatchTransportWriter w) {
return new OutgoingBatchConnection(connWriterFactory, db,
protoWriterFactory, t, c, w);
}
public Runnable createIncomingConnection(ContactId c,
BatchTransportReader r, byte[] encryptedIv) {
return new IncomingBatchConnection(connReaderFactory, db,
protoReaderFactory, c, r, encryptedIv);
}
}

View File

@@ -1,7 +1,8 @@
package net.sf.briar.transport.batch; package net.sf.briar.transport.batch;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.util.logging.Level;
import java.util.logging.Logger;
import net.sf.briar.api.ContactId; import net.sf.briar.api.ContactId;
import net.sf.briar.api.FormatException; import net.sf.briar.api.FormatException;
@@ -13,45 +14,67 @@ import net.sf.briar.api.protocol.ProtocolReader;
import net.sf.briar.api.protocol.ProtocolReaderFactory; import net.sf.briar.api.protocol.ProtocolReaderFactory;
import net.sf.briar.api.protocol.SubscriptionUpdate; import net.sf.briar.api.protocol.SubscriptionUpdate;
import net.sf.briar.api.protocol.TransportUpdate; import net.sf.briar.api.protocol.TransportUpdate;
import net.sf.briar.api.transport.BatchTransportReader;
import net.sf.briar.api.transport.ConnectionReader; import net.sf.briar.api.transport.ConnectionReader;
import net.sf.briar.api.transport.ConnectionReaderFactory;
class IncomingBatchConnection { class IncomingBatchConnection implements Runnable {
private final ConnectionReader conn; private static final Logger LOG =
Logger.getLogger(IncomingBatchConnection.class.getName());
private final ConnectionReaderFactory connFactory;
private final DatabaseComponent db; private final DatabaseComponent db;
private final ProtocolReaderFactory protoFactory; private final ProtocolReaderFactory protoFactory;
private final ContactId contactId; private final ContactId contactId;
private final BatchTransportReader reader;
private final byte[] encryptedIv;
IncomingBatchConnection(ConnectionReader conn, DatabaseComponent db, IncomingBatchConnection(ConnectionReaderFactory connFactory,
ProtocolReaderFactory protoFactory, ContactId contactId) { DatabaseComponent db, ProtocolReaderFactory protoFactory,
this.conn = conn; ContactId contactId, BatchTransportReader reader,
byte[] encryptedIv) {
this.connFactory = connFactory;
this.db = db; this.db = db;
this.protoFactory = protoFactory; this.protoFactory = protoFactory;
this.contactId = contactId; this.contactId = contactId;
this.reader = reader;
this.encryptedIv = encryptedIv;
} }
void read() throws DbException, IOException { public void run() {
InputStream in = conn.getInputStream(); try {
ProtocolReader proto = protoFactory.createProtocolReader(in); byte[] secret = db.getSharedSecret(contactId);
// Read packets until EOF ConnectionReader conn = connFactory.createConnectionReader(
while(!proto.eof()) { reader.getInputStream(), encryptedIv, secret);
if(proto.hasAck()) { ProtocolReader proto = protoFactory.createProtocolReader(
Ack a = proto.readAck(); conn.getInputStream());
db.receiveAck(contactId, a); // Read packets until EOF
} else if(proto.hasBatch()) { while(!proto.eof()) {
Batch b = proto.readBatch(); if(proto.hasAck()) {
db.receiveBatch(contactId, b); Ack a = proto.readAck();
} else if(proto.hasSubscriptionUpdate()) { db.receiveAck(contactId, a);
SubscriptionUpdate s = proto.readSubscriptionUpdate(); } else if(proto.hasBatch()) {
db.receiveSubscriptionUpdate(contactId, s); Batch b = proto.readBatch();
} else if(proto.hasTransportUpdate()) { db.receiveBatch(contactId, b);
TransportUpdate t = proto.readTransportUpdate(); } else if(proto.hasSubscriptionUpdate()) {
db.receiveTransportUpdate(contactId, t); SubscriptionUpdate s = proto.readSubscriptionUpdate();
} else { db.receiveSubscriptionUpdate(contactId, s);
throw new FormatException(); } else if(proto.hasTransportUpdate()) {
TransportUpdate t = proto.readTransportUpdate();
db.receiveTransportUpdate(contactId, t);
} else {
throw new FormatException();
}
} }
} catch(DbException e) {
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
reader.dispose(false);
} catch(IOException e) {
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
reader.dispose(false);
} }
// Close the input stream // Success
in.close(); reader.dispose(true);
} }
} }

View File

@@ -4,8 +4,11 @@ import static net.sf.briar.api.protocol.ProtocolConstants.MAX_PACKET_LENGTH;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sf.briar.api.ContactId; import net.sf.briar.api.ContactId;
import net.sf.briar.api.TransportId;
import net.sf.briar.api.db.DatabaseComponent; import net.sf.briar.api.db.DatabaseComponent;
import net.sf.briar.api.db.DbException; import net.sf.briar.api.db.DbException;
import net.sf.briar.api.protocol.writers.AckWriter; import net.sf.briar.api.protocol.writers.AckWriter;
@@ -13,52 +16,77 @@ import net.sf.briar.api.protocol.writers.BatchWriter;
import net.sf.briar.api.protocol.writers.ProtocolWriterFactory; import net.sf.briar.api.protocol.writers.ProtocolWriterFactory;
import net.sf.briar.api.protocol.writers.SubscriptionWriter; import net.sf.briar.api.protocol.writers.SubscriptionWriter;
import net.sf.briar.api.protocol.writers.TransportWriter; import net.sf.briar.api.protocol.writers.TransportWriter;
import net.sf.briar.api.transport.BatchTransportWriter;
import net.sf.briar.api.transport.ConnectionWriter; import net.sf.briar.api.transport.ConnectionWriter;
import net.sf.briar.api.transport.ConnectionWriterFactory;
class OutgoingBatchConnection { class OutgoingBatchConnection implements Runnable {
private final ConnectionWriter conn; private static final Logger LOG =
Logger.getLogger(OutgoingBatchConnection.class.getName());
private final ConnectionWriterFactory connFactory;
private final DatabaseComponent db; private final DatabaseComponent db;
private final ProtocolWriterFactory protoFactory; private final ProtocolWriterFactory protoFactory;
private final TransportId transportId;
private final ContactId contactId; private final ContactId contactId;
private final BatchTransportWriter writer;
OutgoingBatchConnection(ConnectionWriter conn, DatabaseComponent db, OutgoingBatchConnection(ConnectionWriterFactory connFactory,
ProtocolWriterFactory protoFactory, ContactId contactId) { DatabaseComponent db, ProtocolWriterFactory protoFactory,
this.conn = conn; TransportId transportId, ContactId contactId,
BatchTransportWriter writer) {
this.connFactory = connFactory;
this.db = db; this.db = db;
this.protoFactory = protoFactory; this.protoFactory = protoFactory;
this.transportId = transportId;
this.contactId = contactId; this.contactId = contactId;
this.writer = writer;
} }
void write() throws DbException, IOException { public void run() {
OutputStream out = conn.getOutputStream(); try {
// There should be enough space for a packet byte[] secret = db.getSharedSecret(contactId);
long capacity = conn.getRemainingCapacity(); long connection = db.getConnectionNumber(contactId, transportId);
if(capacity < MAX_PACKET_LENGTH) throw new IOException(); ConnectionWriter conn = connFactory.createConnectionWriter(
// Write a transport update writer.getOutputStream(), writer.getCapacity(), true,
TransportWriter t = protoFactory.createTransportWriter(out); transportId, connection, secret);
db.generateTransportUpdate(contactId, t); OutputStream out = conn.getOutputStream();
// If there's space, write a subscription update // There should be enough space for a packet
capacity = conn.getRemainingCapacity(); long capacity = conn.getRemainingCapacity();
if(capacity >= MAX_PACKET_LENGTH) { if(capacity < MAX_PACKET_LENGTH) throw new IOException();
SubscriptionWriter s = protoFactory.createSubscriptionWriter(out); // Write a transport update
db.generateSubscriptionUpdate(contactId, s); TransportWriter t = protoFactory.createTransportWriter(out);
db.generateTransportUpdate(contactId, t);
// If there's space, write a subscription update
capacity = conn.getRemainingCapacity();
if(capacity >= MAX_PACKET_LENGTH) {
SubscriptionWriter s =
protoFactory.createSubscriptionWriter(out);
db.generateSubscriptionUpdate(contactId, s);
}
// Write acks until you can't write acks no more
AckWriter a = protoFactory.createAckWriter(out);
do {
capacity = conn.getRemainingCapacity();
int max = (int) Math.min(MAX_PACKET_LENGTH, capacity);
a.setMaxPacketLength(max);
} while(db.generateAck(contactId, a));
// Write batches until you can't write batches no more
BatchWriter b = protoFactory.createBatchWriter(out);
do {
capacity = conn.getRemainingCapacity();
int max = (int) Math.min(MAX_PACKET_LENGTH, capacity);
b.setMaxPacketLength(max);
} while(db.generateBatch(contactId, b));
} catch(DbException e) {
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
writer.dispose(false);
} catch(IOException e) {
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.getMessage());
writer.dispose(false);
} }
// Write acks until you can't write acks no more // Success
AckWriter a = protoFactory.createAckWriter(out); writer.dispose(true);
do {
capacity = conn.getRemainingCapacity();
int max = (int) Math.min(MAX_PACKET_LENGTH, capacity);
a.setMaxPacketLength(max);
} while(db.generateAck(contactId, a));
// Write batches until you can't write batches no more
BatchWriter b = protoFactory.createBatchWriter(out);
do {
capacity = conn.getRemainingCapacity();
int max = (int) Math.min(MAX_PACKET_LENGTH, capacity);
b.setMaxPacketLength(max);
} while(db.generateBatch(contactId, b));
// Close the output stream
out.close();
} }
} }

View File

@@ -0,0 +1,15 @@
package net.sf.briar.transport.batch;
import net.sf.briar.api.transport.batch.BatchConnectionFactory;
import com.google.inject.AbstractModule;
import com.google.inject.Singleton;
public class TransportBatchModule extends AbstractModule {
@Override
protected void configure() {
bind(BatchConnectionFactory.class).to(
BatchConnectionFactoryImpl.class).in(Singleton.class);
}
}

View File

@@ -282,10 +282,11 @@ public class RemovableDrivePluginTest extends TestCase {
out.flush(); out.flush();
out.close(); out.close();
assertEquals(123L, files[0].length()); assertEquals(123L, files[0].length());
// Disposing of the writer should delete the file // Successfully disposing of the writer should not delete the file
writer.dispose(true); writer.dispose(true);
files = drive1.listFiles(); files = drive1.listFiles();
assertTrue(files == null || files.length == 0); assertEquals(1, files.length);
assertEquals(123L, files[0].length());
context.assertIsSatisfied(); context.assertIsSatisfied();
} }

View File

@@ -5,6 +5,8 @@ import static net.sf.briar.api.transport.TransportConstants.IV_LENGTH;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
@@ -20,11 +22,11 @@ import net.sf.briar.api.protocol.Message;
import net.sf.briar.api.protocol.MessageEncoder; import net.sf.briar.api.protocol.MessageEncoder;
import net.sf.briar.api.protocol.ProtocolReaderFactory; import net.sf.briar.api.protocol.ProtocolReaderFactory;
import net.sf.briar.api.protocol.writers.ProtocolWriterFactory; import net.sf.briar.api.protocol.writers.ProtocolWriterFactory;
import net.sf.briar.api.transport.ConnectionReader; import net.sf.briar.api.transport.BatchTransportReader;
import net.sf.briar.api.transport.BatchTransportWriter;
import net.sf.briar.api.transport.ConnectionReaderFactory; import net.sf.briar.api.transport.ConnectionReaderFactory;
import net.sf.briar.api.transport.ConnectionRecogniser; import net.sf.briar.api.transport.ConnectionRecogniser;
import net.sf.briar.api.transport.ConnectionRecogniserFactory; import net.sf.briar.api.transport.ConnectionRecogniserFactory;
import net.sf.briar.api.transport.ConnectionWriter;
import net.sf.briar.api.transport.ConnectionWriterFactory; import net.sf.briar.api.transport.ConnectionWriterFactory;
import net.sf.briar.crypto.CryptoModule; import net.sf.briar.crypto.CryptoModule;
import net.sf.briar.db.DatabaseModule; import net.sf.briar.db.DatabaseModule;
@@ -101,15 +103,13 @@ public class BatchConnectionReadWriteTest extends TestCase {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
ConnectionWriterFactory connFactory = ConnectionWriterFactory connFactory =
alice.getInstance(ConnectionWriterFactory.class); alice.getInstance(ConnectionWriterFactory.class);
long connection = db.getConnectionNumber(contactId, transportId);
ConnectionWriter conn = connFactory.createConnectionWriter(out,
Long.MAX_VALUE, true, transportId, connection, aliceSecret);
ProtocolWriterFactory protoFactory = ProtocolWriterFactory protoFactory =
alice.getInstance(ProtocolWriterFactory.class); alice.getInstance(ProtocolWriterFactory.class);
OutgoingBatchConnection batchOut = new OutgoingBatchConnection(conn, db, BatchTransportWriter writer = new TestBatchTransportWriter(out);
protoFactory, contactId); OutgoingBatchConnection batchOut = new OutgoingBatchConnection(
connFactory, db, protoFactory, transportId, contactId, writer);
// Write whatever needs to be written // Write whatever needs to be written
batchOut.write(); batchOut.run();
// Close Alice's database // Close Alice's database
db.close(); db.close();
// Return the contents of the batch connection // Return the contents of the batch connection
@@ -139,16 +139,15 @@ public class BatchConnectionReadWriteTest extends TestCase {
// Create an incoming batch connection // Create an incoming batch connection
ConnectionReaderFactory connFactory = ConnectionReaderFactory connFactory =
bob.getInstance(ConnectionReaderFactory.class); bob.getInstance(ConnectionReaderFactory.class);
ConnectionReader conn = connFactory.createConnectionReader(in,
encryptedIv, bobSecret);
ProtocolReaderFactory protoFactory = ProtocolReaderFactory protoFactory =
bob.getInstance(ProtocolReaderFactory.class); bob.getInstance(ProtocolReaderFactory.class);
IncomingBatchConnection batchIn = new IncomingBatchConnection(conn, BatchTransportReader reader = new TestBatchTransportReader(in);
db, protoFactory, contactId); IncomingBatchConnection batchIn = new IncomingBatchConnection(
connFactory, db, protoFactory, contactId, reader, encryptedIv);
// No messages should have been added yet // No messages should have been added yet
assertFalse(listener.messagesAdded); assertFalse(listener.messagesAdded);
// Read whatever needs to be read // Read whatever needs to be read
batchIn.read(); batchIn.run();
// The private message from Alice should have been added // The private message from Alice should have been added
assertTrue(listener.messagesAdded); assertTrue(listener.messagesAdded);
// Close Bob's database // Close Bob's database
@@ -168,4 +167,44 @@ public class BatchConnectionReadWriteTest extends TestCase {
if(e == Event.MESSAGES_ADDED) messagesAdded = true; if(e == Event.MESSAGES_ADDED) messagesAdded = true;
} }
} }
private static class TestBatchTransportWriter
implements BatchTransportWriter {
private final OutputStream out;
private TestBatchTransportWriter(OutputStream out) {
this.out = out;
}
public long getCapacity() {
return Long.MAX_VALUE;
}
public OutputStream getOutputStream() {
return out;
}
public void dispose(boolean success) {
assertTrue(success);
}
}
private static class TestBatchTransportReader
implements BatchTransportReader {
private final InputStream in;
private TestBatchTransportReader(InputStream in) {
this.in = in;
}
public InputStream getInputStream() {
return in;
}
public void dispose(boolean success) {
assertTrue(success);
}
}
} }