Clean up Java Thrift transport code
Summary: More robust error checking
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664845 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/java/src/transport/TFramedTransport.java b/lib/java/src/transport/TFramedTransport.java
new file mode 100644
index 0000000..260fd80
--- /dev/null
+++ b/lib/java/src/transport/TFramedTransport.java
@@ -0,0 +1,152 @@
+package com.facebook.thrift.transport;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Socket implementation of the TTransport interface. To be commented soon!
+ *
+ * @author Mark Slee <mcslee@facebook.com>
+ */
+public class TFramedTransport extends TTransport {
+
+ /**
+ * Underlying transport
+ */
+ private TTransport transport_ = null;
+
+ /**
+ * Class that allows access to the underlying buf without doing deep
+ * copies on it.
+ */
+ private static class MyByteArrayOutputStream extends ByteArrayOutputStream {
+ public MyByteArrayOutputStream(int size) {
+ super(size);
+ }
+
+ public byte[] get() {
+ return buf;
+ }
+
+ public int len() {
+ return count;
+ }
+ }
+
+ /**
+ * Buffer for output
+ */
+ private final MyByteArrayOutputStream writeBuffer_ =
+ new MyByteArrayOutputStream(1024);
+
+ /**
+ * Buffer for input
+ */
+ private ByteArrayInputStream readBuffer_ = null;
+
+ /**
+ * Whether to frame input
+ */
+ private boolean frameRead_ = true;
+
+ /**
+ * Whether to frame output
+ */
+ private boolean frameWrite_ = true;
+
+ /**
+ * Constructor wraps around another tranpsort
+ */
+ public TFramedTransport(TTransport transport) {
+ this(transport, true, true);
+ }
+
+ /**
+ * Constructor wraps around another tranpsort
+ */
+ public TFramedTransport(TTransport transport, boolean in, boolean out) {
+ transport_ = transport;
+ frameRead_ = in;
+ frameWrite_ = out;
+ }
+
+ public void setFrameRead(boolean frameRead) {
+ frameRead_ = frameRead;
+ }
+
+ public void setFrameWrite(boolean frameWrite) {
+ frameWrite_ = frameWrite;
+ }
+
+ public void open() throws TTransportException {
+ transport_.open();
+ }
+
+ public boolean isOpen() {
+ return transport_.isOpen();
+ }
+
+ public void close() {
+ transport_.close();
+ }
+
+ public int read(byte[] buf, int off, int len) throws TTransportException {
+ if (!frameRead_) {
+ return transport_.read(buf, off, len);
+ }
+
+ if (readBuffer_ != null) {
+ int got = readBuffer_.read(buf, off, len);
+ if (got > 0) {
+ return got;
+ }
+ }
+
+ // Read another frame of data
+ readFrame();
+
+ return readBuffer_.read(buf, off, len);
+ }
+
+ private void readFrame() throws TTransportException {
+ byte[] i32rd = new byte[4];
+ transport_.readAll(i32rd, 0, 4);
+ int size =
+ ((i32rd[0] & 0xff) << 24) |
+ ((i32rd[1] & 0xff) << 16) |
+ ((i32rd[2] & 0xff) << 8) |
+ ((i32rd[3] & 0xff));
+
+ byte[] buff = new byte[size];
+ transport_.readAll(buff, 0, size);
+ readBuffer_ = new ByteArrayInputStream(buff);
+ }
+
+ public void write(byte[] buf, int off, int len) throws TTransportException {
+ if (!frameWrite_) {
+ transport_.write(buf, off, len);
+ return;
+ }
+ writeBuffer_.write(buf, off, len);
+ }
+
+ public void flush() throws TTransportException {
+ if (!frameWrite_) {
+ transport_.flush();
+ return;
+ }
+
+ byte[] buf = writeBuffer_.get();
+ int len = writeBuffer_.len();
+ writeBuffer_.reset();
+
+ byte[] i32out = new byte[4];
+ i32out[0] = (byte)(0xff & (len >> 24));
+ i32out[1] = (byte)(0xff & (len >> 16));
+ i32out[2] = (byte)(0xff & (len >> 8));
+ i32out[3] = (byte)(0xff & (len));
+ transport_.write(i32out, 0, 4);
+ transport_.write(buf, 0, len);
+ transport_.flush();
+ }
+}
diff --git a/lib/java/src/transport/TTransport.java b/lib/java/src/transport/TTransport.java
index 00610df..4664f3f 100644
--- a/lib/java/src/transport/TTransport.java
+++ b/lib/java/src/transport/TTransport.java
@@ -55,7 +55,7 @@
int ret = 0;
while (got < len) {
ret = read(buf, off+got, len-got);
- if (ret == -1) {
+ if (ret <= 0) {
throw new TTransportException("Cannot read. Remote side has closed.");
}
got += ret;