THRIFT-210. c#: Add support for TFramedTransport

author: Michael Greene (euphoria)


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@835006 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/csharp/Makefile.am b/lib/csharp/Makefile.am
index 4047011..039db74 100644
--- a/lib/csharp/Makefile.am
+++ b/lib/csharp/Makefile.am
@@ -42,6 +42,7 @@
             src/Transport/TSocket.cs \
             src/Transport/TTransportException.cs \
             src/Transport/TStreamTransport.cs \
+            src/Transport/TFramedTransport.cs \
             src/Transport/TServerTransport.cs \
             src/Transport/TServerSocket.cs \
             src/Transport/TTransportFactory.cs \
diff --git a/lib/csharp/src/Thrift.csproj b/lib/csharp/src/Thrift.csproj
index f38d315..b7e2108 100644
--- a/lib/csharp/src/Thrift.csproj
+++ b/lib/csharp/src/Thrift.csproj
@@ -58,6 +58,7 @@
     <Compile Include="TApplicationException.cs" />
     <Compile Include="TProcessor.cs" />
     <Compile Include="Transport\TBufferedTransport.cs" />
+    <Compile Include="Transport\TFramedTransport.cs" />
     <Compile Include="Transport\TServerSocket.cs" />
     <Compile Include="Transport\TServerTransport.cs" />
     <Compile Include="Transport\TSocket.cs" />
@@ -70,4 +71,4 @@
   <ProjectExtensions>
     <VisualStudio AllowExistingFolder="true" />
   </ProjectExtensions>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/lib/csharp/src/Transport/TFramedTransport.cs b/lib/csharp/src/Transport/TFramedTransport.cs
new file mode 100644
index 0000000..b7ad5f2
--- /dev/null
+++ b/lib/csharp/src/Transport/TFramedTransport.cs
@@ -0,0 +1,114 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+using System.IO;
+
+namespace Thrift.Transport
+{
+	public class TFramedTransport : TTransport
+	{
+		protected TTransport transport = null;
+		protected MemoryStream writeBuffer = new MemoryStream(1024);
+		protected MemoryStream readBuffer = null;
+
+		public class Factory : TTransportFactory
+		{
+			public override TTransport GetTransport(TTransport trans)
+			{
+				return new TFramedTransport(trans);
+			}
+		}
+
+		public TFramedTransport(TTransport transport)
+		{
+			this.transport = transport;
+		}
+
+		public override void Open()
+		{
+			transport.Open();
+		}
+
+		public override bool IsOpen
+		{
+			get
+			{
+				return transport.IsOpen;
+			}
+		}
+
+		public override void Close()
+		{
+			transport.Close();
+		}
+
+		public override int Read(byte[] buf, int off, int 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()
+		{
+			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 MemoryStream(buff);
+		}
+
+		public override void Write(byte[] buf, int off, int len)
+		{
+			writeBuffer.Write(buf, off, len);
+		}
+
+		public override void Flush()
+		{
+			byte[] buf = writeBuffer.GetBuffer();
+			int len = (int)writeBuffer.Length;
+			writeBuffer = new MemoryStream(writeBuffer.Capacity);
+
+			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();
+		}
+	}
+}