Thrift: C# Bindings.
Summary:
C# generator, library, and MS Build task contributed by imeem.
Reviewed By: mcslee
Test Plan:
Built the Thrift compiler and generated some C# code.
I'd love to say I installed Mono or Portable.NET and built the C# code,
but I did not.
Revert Plan: ok
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665421 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs b/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..4375a52
--- /dev/null
+++ b/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ThriftMSBuildTask")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ThriftMSBuildTask")]
+[assembly: AssemblyCopyright("Copyright © 2007")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("5095e09d-7b95-4be1-b250-e1c1db1c485e")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/lib/csharp/ThriftMSBuildTask/ThriftBuild.cs b/lib/csharp/ThriftMSBuildTask/ThriftBuild.cs
new file mode 100644
index 0000000..9cf5f41
--- /dev/null
+++ b/lib/csharp/ThriftMSBuildTask/ThriftBuild.cs
@@ -0,0 +1,202 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+using Microsoft.Build.Tasks;
+using System.IO;
+using System.Diagnostics;
+
+namespace ThriftMSBuildTask
+{
+ /// <summary>
+ /// MSBuild Task to generate csharp from .thrift files, and compile the code into a library: ThriftImpl.dll
+ /// </summary>
+ public class ThriftBuild : Task
+ {
+ /// <summary>
+ /// The full path to the thrift.exe compiler
+ /// </summary>
+ [Required]
+ public ITaskItem ThriftExecutable
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// The full path to a thrift.dll C# library
+ /// </summary>
+ [Required]
+ public ITaskItem ThriftLibrary
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// A direcotry containing .thrift files
+ /// </summary>
+ [Required]
+ public ITaskItem ThriftDefinitionDir
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// The name of the auto-gen and compiled thrift library. It will placed in
+ /// the same directory as ThriftLibrary
+ /// </summary>
+ [Required]
+ public ITaskItem OutputName
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// The full path to the compiled ThriftLibrary. This allows msbuild tasks to use this
+ /// output as a variable for use elsewhere.
+ /// </summary>
+ [Output]
+ public ITaskItem ThriftImplementation
+ {
+ get { return thriftImpl; }
+ }
+
+ private ITaskItem thriftImpl;
+ private const string lastCompilationName = "LAST_COMP_TIMESTAMP";
+
+ //use the Message Build Task to write something to build log
+ private void LogMessage(string text, MessageImportance importance)
+ {
+ Message m = new Message();
+ m.Text = text;
+ m.Importance = importance.ToString();
+ m.BuildEngine = this.BuildEngine;
+ m.Execute();
+ }
+
+ //recursively find .cs files in srcDir, paths should initially be non-null and empty
+ private void FindSourcesHelper(string srcDir, List<string> paths)
+ {
+ string[] files = Directory.GetFiles(srcDir, "*.cs");
+ foreach (string f in files)
+ {
+ paths.Add(f);
+ }
+ string[] dirs = Directory.GetDirectories(srcDir);
+ foreach (string dir in dirs)
+ {
+ FindSourcesHelper(dir, paths);
+ }
+ }
+
+ /// <summary>
+ /// Quote paths with spaces
+ /// </summary>
+ private string SafePath(string path)
+ {
+ if (path.Contains(' ') && !path.StartsWith("\""))
+ {
+ return "\"" + path + "\"";
+ }
+ return path;
+ }
+
+ private ITaskItem[] FindSources(string srcDir)
+ {
+ List<string> files = new List<string>();
+ FindSourcesHelper(srcDir, files);
+ ITaskItem[] items = new ITaskItem[files.Count];
+ for (int i = 0; i < items.Length; i++)
+ {
+ items[i] = new TaskItem(files[i]);
+ }
+ return items;
+ }
+
+ private string LastWriteTime(string defDir)
+ {
+ string[] files = Directory.GetFiles(defDir, "*.thrift");
+ DateTime d = (new DirectoryInfo(defDir)).LastWriteTime;
+ foreach(string file in files)
+ {
+ FileInfo f = new FileInfo(file);
+ DateTime curr = f.LastWriteTime;
+ if (DateTime.Compare(curr, d) > 0)
+ {
+ d = curr;
+ }
+ }
+ return d.ToFileTimeUtc().ToString();
+ }
+
+ public override bool Execute()
+ {
+ string defDir = SafePath(ThriftDefinitionDir.ItemSpec);
+ //look for last compilation timestamp
+ string lastBuildPath = Path.Combine(defDir, lastCompilationName);
+ DirectoryInfo defDirInfo = new DirectoryInfo(defDir);
+ string lastWrite = LastWriteTime(defDir);
+ if (File.Exists(lastBuildPath))
+ {
+ string lastComp = File.ReadAllText(lastBuildPath);
+
+ if (lastComp == lastWrite)
+ {
+ //the .thrift dir hasn't been written to since last compilation, don't need to do anything
+ LogMessage("ThriftImpl up-to-date", MessageImportance.Normal);
+ return true;
+ }
+ }
+
+ //find the directory of the thriftlibrary (that's where output will go)
+ FileInfo thriftLibInfo = new FileInfo(SafePath(ThriftLibrary.ItemSpec));
+ string thriftDir = thriftLibInfo.Directory.FullName;
+
+ string genDir = Path.Combine(thriftDir, "gen-csharp");
+ if (Directory.Exists(genDir))
+ {
+ Directory.Delete(genDir, true);
+ }
+
+ //run the thrift executable to generate C#
+ foreach (string thriftFile in Directory.GetFiles(defDir, "*.thrift"))
+ {
+ LogMessage("Generating code for: " + thriftFile, MessageImportance.Normal);
+ Process p = new Process();
+ p.StartInfo.FileName = SafePath(ThriftExecutable.ItemSpec);
+ p.StartInfo.Arguments = "-csharp -o " + SafePath(thriftDir) + " -r " + thriftFile;
+ p.StartInfo.UseShellExecute = false;
+ p.StartInfo.CreateNoWindow = true;
+ p.StartInfo.RedirectStandardOutput = false;
+ p.Start();
+ p.WaitForExit();
+ }
+
+ Csc csc = new Csc();
+ csc.TargetType = "library";
+ csc.References = new ITaskItem[] { new TaskItem(ThriftLibrary.ItemSpec) };
+ csc.EmitDebugInformation = true;
+ string outputPath = Path.Combine(thriftDir, OutputName.ItemSpec);
+ csc.OutputAssembly = new TaskItem(outputPath);
+ csc.Sources = FindSources(Path.Combine(thriftDir, "gen-csharp"));
+ csc.BuildEngine = this.BuildEngine;
+ LogMessage("Compiling generated cs...", MessageImportance.Normal);
+ if (!csc.Execute())
+ {
+ return false;
+ }
+
+ //write file to defDir to indicate a build was successfully completed
+ File.WriteAllText(lastBuildPath, lastWrite);
+
+ thriftImpl = new TaskItem(outputPath);
+
+ return true;
+ }
+ }
+}
diff --git a/lib/csharp/ThriftMSBuildTask/ThriftMSBuildTask.csproj b/lib/csharp/ThriftMSBuildTask/ThriftMSBuildTask.csproj
new file mode 100644
index 0000000..68c6bd1
--- /dev/null
+++ b/lib/csharp/ThriftMSBuildTask/ThriftMSBuildTask.csproj
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.21022</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{EC0A0231-66EA-4593-A792-C6CA3BB8668E}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>ThriftMSBuildTask</RootNamespace>
+ <AssemblyName>ThriftMSBuildTask</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <SccProjectName>SAK</SccProjectName>
+ <SccLocalPath>SAK</SccLocalPath>
+ <SccAuxPath>SAK</SccAuxPath>
+ <SccProvider>SAK</SccProvider>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Microsoft.Build.Framework" />
+ <Reference Include="Microsoft.Build.Tasks" />
+ <Reference Include="Microsoft.Build.Utilities" />
+ <Reference Include="System" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Xml.Linq">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data.DataSetExtensions">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ThriftBuild.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file
diff --git a/lib/csharp/src/Protocol/TBinaryProtocol.cs b/lib/csharp/src/Protocol/TBinaryProtocol.cs
new file mode 100644
index 0000000..36f03d0
--- /dev/null
+++ b/lib/csharp/src/Protocol/TBinaryProtocol.cs
@@ -0,0 +1,386 @@
+//
+// TBinaryProtocol.cs
+//
+// Begin: Aug 19, 2007
+// Authors:
+// Todd Berman <tberman@imeem.com>
+// Will Palmeri <will@imeem.com>
+//
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/using
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Thrift.Transport;
+
+namespace Thrift.Protocol
+{
+ public class TBinaryProtocol : TProtocol
+ {
+ protected const uint VERSION_MASK = 0xffff0000;
+ protected const uint VERSION_1 = 0x80010000;
+
+ protected bool strictRead_ = false;
+ protected bool strictWrite_ = true;
+
+ protected int readLength_;
+ protected bool checkReadLength_ = false;
+
+
+ #region BinaryProtocol Factory
+ /**
+ * Factory
+ */
+ public class Factory : TProtocolFactory {
+
+ protected bool strictRead_ = false;
+ protected bool strictWrite_ = true;
+
+ public Factory()
+ :this(false, true)
+ {
+ }
+
+ public Factory(bool strictRead, bool strictWrite)
+ {
+ strictRead_ = strictRead;
+ strictWrite_ = strictWrite;
+ }
+
+ public TProtocol GetProtocol(TTransport trans) {
+ return new TBinaryProtocol(trans, strictRead_, strictWrite_);
+ }
+ }
+
+ #endregion
+
+ public TBinaryProtocol(TTransport trans)
+ : this(trans, false, true)
+ {
+ }
+
+ public TBinaryProtocol(TTransport trans, bool strictRead, bool strictWrite)
+ :base(trans)
+ {
+ strictRead_ = strictRead;
+ strictWrite_ = strictWrite;
+ }
+
+ #region Write Methods
+
+ public override void WriteMessageBegin(TMessage message)
+ {
+ if (strictWrite_)
+ {
+ uint version = VERSION_1 | (uint)(message.Type);
+ WriteI32((int)version);
+ WriteString(message.Name);
+ WriteI32(message.SeqID);
+ }
+ else
+ {
+ WriteString(message.Name);
+ WriteByte((byte)message.Type);
+ WriteI32(message.SeqID);
+ }
+ }
+
+ public override void WriteMessageEnd()
+ {
+ }
+
+ public override void WriteStructBegin(TStruct struc)
+ {
+ }
+
+ public override void WriteStructEnd()
+ {
+ }
+
+ public override void WriteFieldBegin(TField field)
+ {
+ WriteByte((byte)field.Type);
+ WriteI16(field.ID);
+ }
+
+ public override void WriteFieldEnd()
+ {
+ }
+
+ public override void WriteFieldStop()
+ {
+ WriteByte((byte)TType.Stop);
+ }
+
+ public override void WriteMapBegin(TMap map)
+ {
+ WriteByte((byte)map.KeyType);
+ WriteByte((byte)map.ValueType);
+ WriteI32(map.Count);
+ }
+
+ public override void WriteMapEnd()
+ {
+ }
+
+ public override void WriteListBegin(TList list)
+ {
+ WriteByte((byte)list.ElementType);
+ WriteI32(list.Count);
+ }
+
+ public override void WriteListEnd()
+ {
+ }
+
+ public override void WriteSetBegin(TSet set)
+ {
+ WriteByte((byte)set.ElementType);
+ WriteI32(set.Count);
+ }
+
+ public override void WriteSetEnd()
+ {
+ }
+
+ public override void WriteBool(bool b)
+ {
+ WriteByte(b ? (byte)1 : (byte)0);
+ }
+
+ private byte[] bout = new byte[1];
+ public override void WriteByte(byte b)
+ {
+ bout[0] = b;
+ trans.Write(bout, 0, 1);
+ }
+
+ private byte[] i16out = new byte[2];
+ public override void WriteI16(short s)
+ {
+ i16out[0] = (byte)(0xff & (s >> 8));
+ i16out[1] = (byte)(0xff & s);
+ trans.Write(i16out, 0, 2);
+ }
+
+ private byte[] i32out = new byte[4];
+ public override void WriteI32(int i32)
+ {
+ i32out[0] = (byte)(0xff & (i32 >> 24));
+ i32out[1] = (byte)(0xff & (i32 >> 16));
+ i32out[2] = (byte)(0xff & (i32 >> 8));
+ i32out[3] = (byte)(0xff & i32);
+ trans.Write(i32out, 0, 4);
+ }
+
+ private byte[] i64out = new byte[8];
+ public override void WriteI64(long i64)
+ {
+ i64out[0] = (byte)(0xff & (i64 >> 56));
+ i64out[1] = (byte)(0xff & (i64 >> 48));
+ i64out[2] = (byte)(0xff & (i64 >> 40));
+ i64out[3] = (byte)(0xff & (i64 >> 32));
+ i64out[4] = (byte)(0xff & (i64 >> 24));
+ i64out[5] = (byte)(0xff & (i64 >> 16));
+ i64out[6] = (byte)(0xff & (i64 >> 8));
+ i64out[7] = (byte)(0xff & i64);
+ trans.Write(i64out, 0, 8);
+ }
+
+ public override void WriteDouble(double d)
+ {
+ WriteI64(BitConverter.DoubleToInt64Bits(d));
+ }
+
+ public override void WriteString(string s)
+ {
+ byte[] b = Encoding.UTF8.GetBytes(s);
+ WriteI32(b.Length);
+ trans.Write(b, 0, b.Length);
+ }
+
+ #endregion
+
+ #region ReadMethods
+
+ public override TMessage ReadMessageBegin()
+ {
+ TMessage message = new TMessage();
+ int size = ReadI32();
+ if (size < 0)
+ {
+ uint version = (uint)size & VERSION_MASK;
+ if (version != VERSION_1)
+ {
+ throw new TProtocolException(TProtocolException.BAD_VERSION, "Bad version in ReadMessageBegin: " + version);
+ }
+ message.Type = (TMessageType)(size & 0x000000ff);
+ message.Name = ReadString();
+ message.SeqID = ReadI32();
+ }
+ else
+ {
+ if (strictRead_)
+ {
+ throw new TProtocolException(TProtocolException.BAD_VERSION, "Missing version in readMessageBegin, old client?");
+ }
+ message.Name = ReadStringBody(size);
+ message.Type = (TMessageType)ReadByte();
+ message.SeqID = ReadI32();
+ }
+ return message;
+ }
+
+ public override void ReadMessageEnd()
+ {
+ }
+
+ public override TStruct ReadStructBegin()
+ {
+ return new TStruct();
+ }
+
+ public override void ReadStructEnd()
+ {
+ }
+
+ public override TField ReadFieldBegin()
+ {
+ TField field = new TField();
+ field.Type = (TType)ReadByte();
+
+ if (field.Type != TType.Stop)
+ {
+ field.ID = ReadI16();
+ }
+
+ return field;
+ }
+
+ public override void ReadFieldEnd()
+ {
+ }
+
+ public override TMap ReadMapBegin()
+ {
+ TMap map = new TMap();
+ map.KeyType = (TType)ReadByte();
+ map.ValueType = (TType)ReadByte();
+ map.Count = ReadI32();
+
+ return map;
+ }
+
+ public override void ReadMapEnd()
+ {
+ }
+
+ public override TList ReadListBegin()
+ {
+ TList list = new TList();
+ list.ElementType = (TType)ReadByte();
+ list.Count = ReadI32();
+
+ return list;
+ }
+
+ public override void ReadListEnd()
+ {
+ }
+
+ public override TSet ReadSetBegin()
+ {
+ TSet set = new TSet();
+ set.ElementType = (TType)ReadByte();
+ set.Count = ReadI32();
+
+ return set;
+ }
+
+ public override void ReadSetEnd()
+ {
+ }
+
+ public override bool ReadBool()
+ {
+ return ReadByte() == 1;
+ }
+
+ private byte[] bin = new byte[1];
+ public override byte ReadByte()
+ {
+ ReadAll(bin, 0, 1);
+ return bin[0];
+ }
+
+ private byte[] i16in = new byte[2];
+ public override short ReadI16()
+ {
+ ReadAll(i16in, 0, 2);
+ return (short)(((i16in[0] & 0xff) << 8) | ((i16in[1] & 0xff)));
+ }
+
+ private byte[] i32in = new byte[4];
+ public override int ReadI32()
+ {
+ ReadAll(i32in, 0, 4);
+ return (int)(((i32in[0] & 0xff) << 24) | ((i32in[1] & 0xff) << 16) | ((i32in[2] & 0xff) << 8) | ((i32in[3] & 0xff)));
+ }
+
+ private byte[] i64in = new byte[8];
+ public override long ReadI64()
+ {
+ ReadAll(i64in, 0, 8);
+ return (long)(((long)(i64in[0] & 0xff) << 56) | ((long)(i64in[1] & 0xff) << 48) | ((long)(i64in[2] & 0xff) << 40) | ((long)(i64in[3] & 0xff) << 32) |
+ ((long)(i64in[4] & 0xff) << 24) | ((long)(i64in[5] & 0xff) << 16) | ((long)(i64in[6] & 0xff) << 8) | ((long)(i64in[7] & 0xff)));
+ }
+
+ public override double ReadDouble()
+ {
+ return BitConverter.Int64BitsToDouble(ReadI64());
+ }
+
+ public void SetReadLength(int readLength)
+ {
+ readLength_ = readLength;
+ checkReadLength_ = true;
+ }
+
+ protected void CheckReadLength(int length)
+ {
+ if (checkReadLength_)
+ {
+ readLength_ -= length;
+ if (readLength_ < 0)
+ {
+ throw new Exception("Message length exceeded: " + length);
+ }
+ }
+ }
+
+ public override string ReadString()
+ {
+ int size = ReadI32();
+ return ReadStringBody(size);
+ }
+
+ public string ReadStringBody(int size)
+ {
+ CheckReadLength(size);
+ byte[] buf = new byte[size];
+ trans.ReadAll(buf, 0, size);
+ return Encoding.UTF8.GetString(buf);
+ }
+
+ private int ReadAll(byte[] buf, int off, int len)
+ {
+ CheckReadLength(len);
+ return trans.ReadAll(buf, off, len);
+ }
+
+ #endregion
+ }
+}
diff --git a/lib/csharp/src/Protocol/TField.cs b/lib/csharp/src/Protocol/TField.cs
new file mode 100644
index 0000000..f18381f
--- /dev/null
+++ b/lib/csharp/src/Protocol/TField.cs
@@ -0,0 +1,50 @@
+//
+// TField.cs
+//
+// Begin: Aug 19, 2007
+// Authors:
+// Todd Berman <tberman@imeem.com>
+//
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/using
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Thrift.Protocol
+{
+ public class TField
+ {
+ public TField()
+ {
+ }
+
+ public TField(string name, TType type, short id)
+ {
+ Name = name;
+ Type = type;
+ ID = id;
+ }
+
+ public string Name
+ {
+ get;
+ set;
+ }
+
+ public TType Type
+ {
+ get;
+ set;
+ }
+
+ public short ID
+ {
+ get;
+ set;
+ }
+ }
+}
diff --git a/lib/csharp/src/Protocol/TList.cs b/lib/csharp/src/Protocol/TList.cs
new file mode 100644
index 0000000..ff6aa53
--- /dev/null
+++ b/lib/csharp/src/Protocol/TList.cs
@@ -0,0 +1,43 @@
+//
+// TList.cs
+//
+// Begin: Aug 19, 2007
+// Authors:
+// Todd Berman <tberman@imeem.com>
+//
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/using
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Thrift.Protocol
+{
+ public class TList
+ {
+ public TList()
+ {
+ }
+
+ public TList(TType elementType, int count)
+ {
+ ElementType = elementType;
+ Count = count;
+ }
+
+ public TType ElementType
+ {
+ get;
+ set;
+ }
+
+ public int Count
+ {
+ get;
+ set;
+ }
+ }
+}
diff --git a/lib/csharp/src/Protocol/TMap.cs b/lib/csharp/src/Protocol/TMap.cs
new file mode 100644
index 0000000..495bf7c
--- /dev/null
+++ b/lib/csharp/src/Protocol/TMap.cs
@@ -0,0 +1,50 @@
+//
+// TMap.cs
+//
+// Begin: Aug 19, 2007
+// Authors:
+// Todd Berman <tberman@imeem.com>
+//
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/using
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Thrift.Protocol
+{
+ public class TMap
+ {
+ public TMap()
+ {
+ }
+
+ public TMap(TType keyType, TType valueType, int count)
+ {
+ KeyType = keyType;
+ ValueType = valueType;
+ Count = count;
+ }
+
+ public TType KeyType
+ {
+ get;
+ set;
+ }
+
+ public TType ValueType
+ {
+ get;
+ set;
+ }
+
+ public int Count
+ {
+ get;
+ set;
+ }
+ }
+}
diff --git a/lib/csharp/src/Protocol/TMessage.cs b/lib/csharp/src/Protocol/TMessage.cs
new file mode 100644
index 0000000..60df660
--- /dev/null
+++ b/lib/csharp/src/Protocol/TMessage.cs
@@ -0,0 +1,50 @@
+//
+// TMessage.cs
+//
+// Begin: Aug 19, 2007
+// Authors:
+// Todd Berman <tberman@imeem.com>
+//
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/using
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Thrift.Protocol
+{
+ public class TMessage
+ {
+ public TMessage()
+ {
+ }
+
+ public TMessage(string name, TMessageType type, int seqid)
+ {
+ Name = name;
+ Type = type;
+ SeqID = seqid;
+ }
+
+ public string Name
+ {
+ get;
+ set;
+ }
+
+ public TMessageType Type
+ {
+ get;
+ set;
+ }
+
+ public int SeqID
+ {
+ get;
+ set;
+ }
+ }
+}
diff --git a/lib/csharp/src/Protocol/TMessageType.cs b/lib/csharp/src/Protocol/TMessageType.cs
new file mode 100644
index 0000000..1cadf31
--- /dev/null
+++ b/lib/csharp/src/Protocol/TMessageType.cs
@@ -0,0 +1,25 @@
+//
+// TMessageType.cs
+//
+// Begin: Aug 19, 2007
+// Authors:
+// Todd Berman <tberman@imeem.com>
+//
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/using
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Thrift.Protocol
+{
+ public enum TMessageType
+ {
+ Call = 1,
+ Reply = 2,
+ Exception = 3
+ }
+}
diff --git a/lib/csharp/src/Protocol/TProtocol.cs b/lib/csharp/src/Protocol/TProtocol.cs
new file mode 100644
index 0000000..f46b6d1
--- /dev/null
+++ b/lib/csharp/src/Protocol/TProtocol.cs
@@ -0,0 +1,75 @@
+//
+// TProtocol.cs
+//
+// Begin: Aug 19, 2007
+// Authors:
+// Todd Berman <tberman@imeem.com>
+//
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/using
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Thrift.Transport;
+
+namespace Thrift.Protocol
+{
+ public abstract class TProtocol
+ {
+ protected TTransport trans;
+
+ protected TProtocol(TTransport trans)
+ {
+ this.trans = trans;
+ }
+
+ public TTransport Transport
+ {
+ get { return trans; }
+ }
+
+ public abstract void WriteMessageBegin(TMessage message);
+ public abstract void WriteMessageEnd();
+ public abstract void WriteStructBegin(TStruct struc);
+ public abstract void WriteStructEnd();
+ public abstract void WriteFieldBegin(TField field);
+ public abstract void WriteFieldEnd();
+ public abstract void WriteFieldStop();
+ public abstract void WriteMapBegin(TMap map);
+ public abstract void WriteMapEnd();
+ public abstract void WriteListBegin(TList list);
+ public abstract void WriteListEnd();
+ public abstract void WriteSetBegin(TSet set);
+ public abstract void WriteSetEnd();
+ public abstract void WriteBool(bool b);
+ public abstract void WriteByte(byte b);
+ public abstract void WriteI16(short i16);
+ public abstract void WriteI32(int i32);
+ public abstract void WriteI64(long i64);
+ public abstract void WriteDouble(double d);
+ public abstract void WriteString(string s);
+
+ public abstract TMessage ReadMessageBegin();
+ public abstract void ReadMessageEnd();
+ public abstract TStruct ReadStructBegin();
+ public abstract void ReadStructEnd();
+ public abstract TField ReadFieldBegin();
+ public abstract void ReadFieldEnd();
+ public abstract TMap ReadMapBegin();
+ public abstract void ReadMapEnd();
+ public abstract TList ReadListBegin();
+ public abstract void ReadListEnd();
+ public abstract TSet ReadSetBegin();
+ public abstract void ReadSetEnd();
+ public abstract bool ReadBool();
+ public abstract byte ReadByte();
+ public abstract short ReadI16();
+ public abstract int ReadI32();
+ public abstract long ReadI64();
+ public abstract double ReadDouble();
+ public abstract string ReadString();
+ }
+}
diff --git a/lib/csharp/src/Protocol/TProtocolException.cs b/lib/csharp/src/Protocol/TProtocolException.cs
new file mode 100644
index 0000000..0941a81
--- /dev/null
+++ b/lib/csharp/src/Protocol/TProtocolException.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Thrift.Protocol
+{
+ class TProtocolException : Exception
+ {
+ public const int UNKNOWN = 0;
+ public const int INVALID_DATA = 1;
+ public const int NEGATIVE_SIZE = 2;
+ public const int SIZE_LIMIT = 3;
+ public const int BAD_VERSION = 4;
+
+ protected int type_ = UNKNOWN;
+
+ public TProtocolException()
+ : base()
+ {
+ }
+
+ public TProtocolException(int type)
+ : base()
+ {
+ type_ = type;
+ }
+
+ public TProtocolException(int type, String message)
+ : base(message)
+ {
+ type_ = type;
+ }
+
+ public TProtocolException(String message)
+ : base(message)
+ {
+ }
+
+ public int getType()
+ {
+ return type_;
+ }
+ }
+}
diff --git a/lib/csharp/src/Protocol/TProtocolFactory.cs b/lib/csharp/src/Protocol/TProtocolFactory.cs
new file mode 100644
index 0000000..5434da9
--- /dev/null
+++ b/lib/csharp/src/Protocol/TProtocolFactory.cs
@@ -0,0 +1,23 @@
+//
+// TProtocolFactory.cs
+//
+// Begin: Dec 3, 2007
+// Authors:
+// Will Palmeri <wpalmeri@imeem.com>
+//
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/using
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Thrift.Transport;
+
+namespace Thrift.Protocol
+{
+ public interface TProtocolFactory
+ {
+ TProtocol GetProtocol(TTransport trans);
+ }
+}
diff --git a/lib/csharp/src/Protocol/TProtocolUtil.cs b/lib/csharp/src/Protocol/TProtocolUtil.cs
new file mode 100644
index 0000000..67f0ce6
--- /dev/null
+++ b/lib/csharp/src/Protocol/TProtocolUtil.cs
@@ -0,0 +1,88 @@
+//
+// TProtocolUtil.cs
+//
+// Begin: Aug 19, 2007
+// Authors:
+// Todd Berman <tberman@imeem.com>
+//
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/using
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Thrift.Protocol
+{
+ public static class TProtocolUtil
+ {
+ public static void Skip(TProtocol prot, TType type)
+ {
+ switch (type)
+ {
+ case TType.Bool:
+ prot.ReadBool();
+ break;
+ case TType.Byte:
+ prot.ReadByte();
+ break;
+ case TType.I16:
+ prot.ReadI16();
+ break;
+ case TType.I32:
+ prot.ReadI32();
+ break;
+ case TType.I64:
+ prot.ReadI64();
+ break;
+ case TType.Double:
+ prot.ReadDouble();
+ break;
+ case TType.String:
+ prot.ReadString();
+ break;
+ case TType.Struct:
+ prot.ReadStructBegin();
+ while (true)
+ {
+ TField field = prot.ReadFieldBegin();
+ if (field.Type == TType.Stop)
+ {
+ break;
+ }
+ Skip(prot, field.Type);
+ prot.ReadFieldEnd();
+ }
+ prot.ReadStructEnd();
+ break;
+ case TType.Map:
+ TMap map = prot.ReadMapBegin();
+ for (int i = 0; i < map.Count; i++)
+ {
+ Skip(prot, map.KeyType);
+ Skip(prot, map.ValueType);
+ }
+ prot.ReadMapEnd();
+ break;
+ case TType.Set:
+ TSet set = prot.ReadSetBegin();
+ for (int i = 0; i < set.Count; i++)
+ {
+ Skip(prot, set.ElementType);
+ }
+ prot.ReadSetEnd();
+ break;
+ case TType.List:
+ TList list = prot.ReadListBegin();
+ for (int i = 0; i < list.Count; i++)
+ {
+ Skip(prot, list.ElementType);
+ }
+ prot.ReadListEnd();
+ break;
+ }
+ }
+ }
+}
diff --git a/lib/csharp/src/Protocol/TSet.cs b/lib/csharp/src/Protocol/TSet.cs
new file mode 100644
index 0000000..c4c6fc3
--- /dev/null
+++ b/lib/csharp/src/Protocol/TSet.cs
@@ -0,0 +1,43 @@
+//
+// TSet.cs
+//
+// Begin: Aug 19, 2007
+// Authors:
+// Todd Berman <tberman@imeem.com>
+//
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/using
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Thrift.Protocol
+{
+ public class TSet
+ {
+ public TSet()
+ {
+ }
+
+ public TSet(TType elementType, int count)
+ {
+ ElementType = elementType;
+ Count = count;
+ }
+
+ public TType ElementType
+ {
+ get;
+ set;
+ }
+
+ public int Count
+ {
+ get;
+ set;
+ }
+ }
+}
diff --git a/lib/csharp/src/Protocol/TStruct.cs b/lib/csharp/src/Protocol/TStruct.cs
new file mode 100644
index 0000000..88f12df
--- /dev/null
+++ b/lib/csharp/src/Protocol/TStruct.cs
@@ -0,0 +1,35 @@
+//
+// TStruct.cs
+//
+// Begin: Aug 19, 2007
+// Authors:
+// Todd Berman <tberman@imeem.com>
+//
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/using
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Thrift.Protocol
+{
+ public class TStruct
+ {
+ public TStruct()
+ {
+ }
+
+ public TStruct(string name)
+ {
+ Name = name;
+ }
+
+ public string Name
+ {
+ get;
+ set;
+ }
+ }
+}
diff --git a/lib/csharp/src/Protocol/TType.cs b/lib/csharp/src/Protocol/TType.cs
new file mode 100644
index 0000000..0badb33
--- /dev/null
+++ b/lib/csharp/src/Protocol/TType.cs
@@ -0,0 +1,35 @@
+//
+// TType.cs
+//
+// Begin: Aug 19, 2007
+// Authors:
+// Todd Berman <tberman@imeem.com>
+//
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/using
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Thrift.Protocol
+{
+ public enum TType : byte
+ {
+ Stop = 0,
+ Void = 1,
+ Bool = 2,
+ Byte = 3,
+ Double = 4,
+ I16 = 6,
+ I32 = 8,
+ I64 = 10,
+ String = 11,
+ Struct = 12,
+ Map = 13,
+ Set = 14,
+ List = 15
+ }
+}
diff --git a/lib/csharp/src/Server/TServer.cs b/lib/csharp/src/Server/TServer.cs
new file mode 100644
index 0000000..3e70b11
--- /dev/null
+++ b/lib/csharp/src/Server/TServer.cs
@@ -0,0 +1,108 @@
+//
+// TServer.cs
+//
+// Begin: Dec 3, 2007
+// Authors:
+// Will Palmeri <wpalmeri@imeem.com>
+//
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/using
+
+using System;
+using System.Collections.Generic;
+using Thrift.Protocol;
+using Thrift.Transport;
+
+namespace Thrift.Server
+{
+ public abstract class TServer
+ {
+ /**
+ * Core processor
+ */
+ protected TProcessor processor;
+
+ /**
+ * Server transport
+ */
+ protected TServerTransport serverTransport;
+
+ /**
+ * Input Transport Factory
+ */
+ protected TTransportFactory inputTransportFactory;
+
+ /**
+ * Output Transport Factory
+ */
+ protected TTransportFactory outputTransportFactory;
+
+ /**
+ * Input Protocol Factory
+ */
+ protected TProtocolFactory inputProtocolFactory;
+
+ /**
+ * Output Protocol Factory
+ */
+ protected TProtocolFactory outputProtocolFactory;
+
+ /**
+ * Default constructors.
+ */
+
+ public TServer(TProcessor processor,
+ TServerTransport serverTransport)
+ :this(processor, serverTransport, new TTransportFactory(), new TTransportFactory(), new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory())
+ {
+ }
+
+ public TServer(TProcessor processor,
+ TServerTransport serverTransport,
+ TTransportFactory transportFactory)
+ :this(processor,
+ serverTransport,
+ transportFactory,
+ transportFactory,
+ new TBinaryProtocol.Factory(),
+ new TBinaryProtocol.Factory())
+ {
+ }
+
+ public TServer(TProcessor processor,
+ TServerTransport serverTransport,
+ TTransportFactory transportFactory,
+ TProtocolFactory protocolFactory)
+ :this(processor,
+ serverTransport,
+ transportFactory,
+ transportFactory,
+ protocolFactory,
+ protocolFactory)
+ {
+ }
+
+ public TServer(TProcessor processor,
+ TServerTransport serverTransport,
+ TTransportFactory inputTransportFactory,
+ TTransportFactory outputTransportFactory,
+ TProtocolFactory inputProtocolFactory,
+ TProtocolFactory outputProtocolFactory)
+ {
+ this.processor = processor;
+ this.serverTransport = serverTransport;
+ this.inputTransportFactory = inputTransportFactory;
+ this.outputTransportFactory = outputTransportFactory;
+ this.inputProtocolFactory = inputProtocolFactory;
+ this.outputProtocolFactory = outputProtocolFactory;
+ }
+
+ /**
+ * The run method fires up the server and gets things going.
+ */
+ public abstract void Serve();
+ }
+}
+
diff --git a/lib/csharp/src/Server/TSimpleServer.cs b/lib/csharp/src/Server/TSimpleServer.cs
new file mode 100644
index 0000000..c3461ef
--- /dev/null
+++ b/lib/csharp/src/Server/TSimpleServer.cs
@@ -0,0 +1,108 @@
+//
+// TSimpleServer.cs
+//
+// Begin: Dec 3, 2007
+// Authors:
+// Will Palmeri <wpalmeri@imeem.com>
+//
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/using
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Thrift.Transport;
+using Thrift.Protocol;
+
+namespace Thrift.Server
+{
+ /// <summary>
+ /// Simple single-threaded server for testing
+ /// </summary>
+ class TSimpleServer : TServer
+ {
+ public TSimpleServer(TProcessor processor,
+ TServerTransport serverTransport)
+ :base(processor, serverTransport, new TTransportFactory(), new TTransportFactory(), new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory())
+ {
+ }
+
+ public TSimpleServer(TProcessor processor,
+ TServerTransport serverTransport,
+ TTransportFactory transportFactory)
+ :base(processor,
+ serverTransport,
+ transportFactory,
+ transportFactory,
+ new TBinaryProtocol.Factory(),
+ new TBinaryProtocol.Factory())
+ {
+ }
+
+ public TSimpleServer(TProcessor processor,
+ TServerTransport serverTransport,
+ TTransportFactory transportFactory,
+ TProtocolFactory protocolFactory)
+ :base(processor,
+ serverTransport,
+ transportFactory,
+ transportFactory,
+ protocolFactory,
+ protocolFactory)
+ {
+ }
+
+ public override void Serve()
+ {
+ try
+ {
+ serverTransport.Listen();
+ }
+ catch (TTransportException ttx)
+ {
+ Console.Error.WriteLine(ttx);
+ return;
+ }
+
+ while (true)
+ {
+ TTransport client = null;
+ TTransport inputTransport = null;
+ TTransport outputTransport = null;
+ TProtocol inputProtocol = null;
+ TProtocol outputProtocol = null;
+ try
+ {
+ client = serverTransport.Accept();
+ if (client != null)
+ {
+ inputTransport = inputTransportFactory.GetTransport(client);
+ outputTransport = outputTransportFactory.GetTransport(client);
+ inputProtocol = inputProtocolFactory.GetProtocol(inputTransport);
+ outputProtocol = outputProtocolFactory.GetProtocol(outputTransport);
+ while (processor.Process(inputProtocol, outputProtocol)) { }
+ }
+ }
+ catch (TTransportException ttx)
+ {
+ // Client died, just move on
+ }
+ catch (Exception x)
+ {
+ Console.Error.WriteLine(x);
+ }
+
+ if (inputTransport != null)
+ {
+ inputTransport.Close();
+ }
+
+ if (outputTransport != null)
+ {
+ outputTransport.Close();
+ }
+ }
+ }
+ }
+}
diff --git a/lib/csharp/src/Server/TThreadPoolServer.cs b/lib/csharp/src/Server/TThreadPoolServer.cs
new file mode 100644
index 0000000..c42d348
--- /dev/null
+++ b/lib/csharp/src/Server/TThreadPoolServer.cs
@@ -0,0 +1,143 @@
+//
+// TThreadPoolServer.cs
+//
+// Begin: Dec 3, 2007
+// Authors:
+// Will Palmeri <wpalmeri@imeem.com>
+//
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/using
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading;
+using Thrift.Protocol;
+using Thrift.Transport;
+
+namespace Thrift.Server
+{
+ /// <summary>
+ /// Server that uses C# built-in ThreadPool to spawn threads when handling requests
+ /// </summary>
+ public class TThreadPoolServer : TServer
+ {
+ private const int DEFAULT_MIN_THREADS = 10;
+ private const int DEFAULT_MAX_THREADS = 100;
+
+ public TThreadPoolServer(TProcessor processor, TServerTransport serverTransport)
+ :this(processor, serverTransport,
+ new TTransportFactory(), new TTransportFactory(),
+ new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(),
+ DEFAULT_MIN_THREADS, DEFAULT_MAX_THREADS)
+ {
+ }
+
+ public TThreadPoolServer(TProcessor processor,
+ TServerTransport serverTransport,
+ TTransportFactory transportFactory,
+ TProtocolFactory protocolFactory)
+ :this(processor, serverTransport,
+ transportFactory, transportFactory,
+ protocolFactory, protocolFactory,
+ DEFAULT_MIN_THREADS, DEFAULT_MAX_THREADS)
+ {
+ }
+
+ public TThreadPoolServer(TProcessor processor,
+ TServerTransport serverTransport,
+ TTransportFactory inputTransportFactory,
+ TTransportFactory outputTransportFactory,
+ TProtocolFactory inputProtocolFactory,
+ TProtocolFactory outputProtocolFactory,
+ int minThreadPoolThreads, int maxThreadPoolThreads)
+ :base(processor, serverTransport, inputTransportFactory, outputTransportFactory,
+ inputProtocolFactory, outputProtocolFactory)
+ {
+ if (!ThreadPool.SetMinThreads(minThreadPoolThreads, minThreadPoolThreads))
+ {
+ throw new Exception("Error: could not SetMinThreads in ThreadPool");
+ }
+ if (!ThreadPool.SetMaxThreads(maxThreadPoolThreads, maxThreadPoolThreads))
+ {
+ throw new Exception("Error: could not SetMaxThreads in ThreadPool");
+ }
+
+ }
+
+ /// <summary>
+ /// Use new ThreadPool thread for each new client connection
+ /// </summary>
+ public override void Serve()
+ {
+ try
+ {
+ serverTransport.Listen();
+ }
+ catch (TTransportException ttx)
+ {
+ Console.Error.WriteLine("Error, could not listen on ServerTransport: " + ttx);
+ return;
+ }
+
+ while (true)
+ {
+ int failureCount = 0;
+ try
+ {
+ TTransport client = serverTransport.Accept();
+ ThreadPool.QueueUserWorkItem(this.Execute, client);
+ }
+ catch (TTransportException ttx)
+ {
+ ++failureCount;
+ Console.Error.WriteLine(ttx);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Loops on processing a client forever
+ /// threadContext will be a TTransport instance
+ /// </summary>
+ /// <param name="threadContext"></param>
+ private void Execute(Object threadContext)
+ {
+ TTransport client = (TTransport)threadContext;
+ TTransport inputTransport = null;
+ TTransport outputTransport = null;
+ TProtocol inputProtocol = null;
+ TProtocol outputProtocol = null;
+ try
+ {
+ inputTransport = inputTransportFactory.GetTransport(client);
+ outputTransport = outputTransportFactory.GetTransport(client);
+ inputProtocol = inputProtocolFactory.GetProtocol(inputTransport);
+ outputProtocol = outputProtocolFactory.GetProtocol(outputTransport);
+ while (processor.Process(inputProtocol, outputProtocol))
+ {
+ //keep processing requests until client disconnects
+ }
+ }
+ catch (TTransportException ttx)
+ {
+ // Assume the client died and continue silently
+ }
+
+ catch (Exception x)
+ {
+ Console.Error.WriteLine("Error: " + x);
+ }
+
+ if (inputTransport != null)
+ {
+ inputTransport.Close();
+ }
+ if (outputTransport != null)
+ {
+ outputTransport.Close();
+ }
+ }
+ }
+}
diff --git a/lib/csharp/src/TApplicationException.cs b/lib/csharp/src/TApplicationException.cs
new file mode 100644
index 0000000..e4f3acf
--- /dev/null
+++ b/lib/csharp/src/TApplicationException.cs
@@ -0,0 +1,127 @@
+//
+// TApplicationException.cs
+//
+// Begin: Aug 19, 2007
+// Authors:
+// Todd Berman <tberman@imeem.com>
+//
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/using
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Thrift.Protocol;
+
+namespace Thrift
+{
+ public class TApplicationException : Exception
+ {
+ protected ExceptionType type;
+
+ public TApplicationException()
+ {
+ }
+
+ public TApplicationException(ExceptionType type)
+ {
+ this.type = type;
+ }
+
+ public TApplicationException(ExceptionType type, string message)
+ : base(message)
+ {
+ this.type = type;
+ }
+
+ public static TApplicationException Read(TProtocol iprot)
+ {
+ TField field;
+ TStruct struc = iprot.ReadStructBegin();
+
+ string message = null;
+ ExceptionType type = ExceptionType.Unknown;
+
+ while (true)
+ {
+ field = iprot.ReadFieldBegin();
+ if (field.Type == TType.Stop)
+ {
+ break;
+ }
+
+ switch (field.ID)
+ {
+ case 1:
+ if (field.Type == TType.String)
+ {
+ message = iprot.ReadString();
+ }
+ else
+ {
+ TProtocolUtil.Skip(iprot, field.Type);
+ }
+ break;
+ case 2:
+ if (field.Type == TType.I32)
+ {
+ type = (ExceptionType)iprot.ReadI32();
+ }
+ else
+ {
+ TProtocolUtil.Skip(iprot, field.Type);
+ }
+ break;
+ default:
+ TProtocolUtil.Skip(iprot, field.Type);
+ break;
+ }
+
+ iprot.ReadFieldEnd();
+ }
+
+ iprot.ReadStructEnd();
+
+ return new TApplicationException(type, message);
+ }
+
+ public void Write(TProtocol oprot)
+ {
+ TStruct struc = new TStruct("TApplicationException");
+ TField field = new TField();
+
+ oprot.WriteStructBegin(struc);
+
+ if (!String.IsNullOrEmpty(Message))
+ {
+ field.Name = "message";
+ field.Type = TType.String;
+ field.ID = 1;
+ oprot.WriteFieldBegin(field);
+ oprot.WriteString(Message);
+ oprot.WriteFieldEnd();
+ }
+
+ field.Name = "type";
+ field.Type = TType.I32;
+ field.ID = 2;
+ oprot.WriteFieldBegin(field);
+ oprot.WriteI32((int)type);
+ oprot.WriteFieldEnd();
+ oprot.WriteFieldStop();
+ oprot.WriteStructEnd();
+ }
+
+ public enum ExceptionType
+ {
+ Unknown,
+ UnknownMethod,
+ InvalidMessageType,
+ WrongMethodName,
+ BadSequenceID,
+ MissingResult
+ }
+ }
+}
diff --git a/lib/csharp/src/TProcessor.cs b/lib/csharp/src/TProcessor.cs
new file mode 100644
index 0000000..7567820
--- /dev/null
+++ b/lib/csharp/src/TProcessor.cs
@@ -0,0 +1,24 @@
+//
+// TProcessor.cs
+//
+// Begin: Aug 19, 2007
+// Authors:
+// Todd Berman <tberman@imeem.com>
+//
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/using
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Thrift.Protocol;
+
+namespace Thrift
+{
+ public interface TProcessor
+ {
+ bool Process(TProtocol iprot, TProtocol oprot);
+ }
+}
diff --git a/lib/csharp/src/Thrift.csproj b/lib/csharp/src/Thrift.csproj
new file mode 100644
index 0000000..4b407b1
--- /dev/null
+++ b/lib/csharp/src/Thrift.csproj
@@ -0,0 +1,79 @@
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{499EB63C-D74C-47E8-AE48-A2FC94538E9D}</ProjectGuid>
+ <ProductVersion>9.0.21022</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <OutputType>Library</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>Thrift</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <RootNamespace>Thrift</RootNamespace>
+ <SccProjectName>SAK</SccProjectName>
+ <SccLocalPath>SAK</SccLocalPath>
+ <SccAuxPath>SAK</SccAuxPath>
+ <SccProvider>SAK</SccProvider>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Xml.Linq" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Protocol\TBinaryProtocol.cs" />
+ <Compile Include="Protocol\TField.cs" />
+ <Compile Include="Protocol\TList.cs" />
+ <Compile Include="Protocol\TMap.cs" />
+ <Compile Include="Protocol\TMessage.cs" />
+ <Compile Include="Protocol\TMessageType.cs" />
+ <Compile Include="Protocol\TProtocol.cs" />
+ <Compile Include="Protocol\TProtocolException.cs" />
+ <Compile Include="Protocol\TProtocolFactory.cs" />
+ <Compile Include="Protocol\TProtocolUtil.cs" />
+ <Compile Include="Protocol\TSet.cs" />
+ <Compile Include="Protocol\TStruct.cs" />
+ <Compile Include="Protocol\TType.cs" />
+ <Compile Include="Server\TServer.cs" />
+ <Compile Include="Server\TSimpleServer.cs" />
+ <Compile Include="Server\TThreadPoolServer.cs" />
+ <Compile Include="TApplicationException.cs" />
+ <Compile Include="TProcessor.cs" />
+ <Compile Include="Transport\TServerSocket.cs" />
+ <Compile Include="Transport\TServerTransport.cs" />
+ <Compile Include="Transport\TSocket.cs" />
+ <Compile Include="Transport\TStreamTransport.cs" />
+ <Compile Include="Transport\TTransport.cs" />
+ <Compile Include="Transport\TTransportException.cs" />
+ <Compile Include="Transport\TTransportFactory.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/lib/csharp/src/Thrift.sln b/lib/csharp/src/Thrift.sln
new file mode 100644
index 0000000..cb7342c
--- /dev/null
+++ b/lib/csharp/src/Thrift.sln
@@ -0,0 +1,51 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Thrift", "Thrift.csproj", "{499EB63C-D74C-47E8-AE48-A2FC94538E9D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThriftTest", "..\..\..\test\csharp\ThriftTest\ThriftTest.csproj", "{48DD757F-CA95-4DD7-BDA4-58DB6F108C2C}"
+ ProjectSection(ProjectDependencies) = postProject
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D} = {499EB63C-D74C-47E8-AE48-A2FC94538E9D}
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThriftMSBuildTask", "..\ThriftMSBuildTask\ThriftMSBuildTask.csproj", "{EC0A0231-66EA-4593-A792-C6CA3BB8668E}"
+EndProject
+Global
+ GlobalSection(SourceCodeControl) = preSolution
+ SccNumberOfProjects = 4
+ SccProjectName0 = Perforce\u0020Project
+ SccLocalPath0 = ..\\..\\..
+ SccProvider0 = MSSCCI:Perforce\u0020SCM
+ SccProjectFilePathRelativizedFromConnection0 = lib\\csharp\\src\\
+ SccProjectUniqueName1 = Thrift.csproj
+ SccLocalPath1 = ..\\..\\..
+ SccProjectFilePathRelativizedFromConnection1 = lib\\csharp\\src\\
+ SccProjectUniqueName2 = ..\\..\\..\\test\\csharp\\ThriftTest\\ThriftTest.csproj
+ SccLocalPath2 = ..\\..\\..
+ SccProjectFilePathRelativizedFromConnection2 = test\\csharp\\ThriftTest\\
+ SccProjectUniqueName3 = ..\\ThriftMSBuildTask\\ThriftMSBuildTask.csproj
+ SccLocalPath3 = ..\\..\\..
+ SccProjectFilePathRelativizedFromConnection3 = lib\\csharp\\ThriftMSBuildTask\\
+ EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {48DD757F-CA95-4DD7-BDA4-58DB6F108C2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {48DD757F-CA95-4DD7-BDA4-58DB6F108C2C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {48DD757F-CA95-4DD7-BDA4-58DB6F108C2C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {48DD757F-CA95-4DD7-BDA4-58DB6F108C2C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EC0A0231-66EA-4593-A792-C6CA3BB8668E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EC0A0231-66EA-4593-A792-C6CA3BB8668E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EC0A0231-66EA-4593-A792-C6CA3BB8668E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EC0A0231-66EA-4593-A792-C6CA3BB8668E}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/lib/csharp/src/Transport/TServerSocket.cs b/lib/csharp/src/Transport/TServerSocket.cs
new file mode 100644
index 0000000..cb4a84f
--- /dev/null
+++ b/lib/csharp/src/Transport/TServerSocket.cs
@@ -0,0 +1,131 @@
+//
+// TServerTransport.cs
+//
+// Begin: Dec 3, 2007
+// Authors:
+// Will Palmeri <wpalmeri@imeem.com>
+//
+// Copyright (C) 2007 imeem, inc. <http://www.imeem.com>
+// All rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Net.Sockets;
+
+
+namespace Thrift.Transport
+{
+ public class TServerSocket : TServerTransport
+ {
+ /**
+ * Underlying server with socket
+ */
+ private TcpListener server = null;
+
+ /**
+ * Port to listen on
+ */
+ private int port = 0;
+
+ /**
+ * Timeout for client sockets from accept
+ */
+ private int clientTimeout = 0;
+
+ /**
+ * Creates a server socket from underlying socket object
+ */
+ public TServerSocket(TcpListener listener)
+ :this(listener, 0)
+ {
+ }
+
+ /**
+ * Creates a server socket from underlying socket object
+ */
+ public TServerSocket(TcpListener listener, int clientTimeout)
+ {
+ this.server = listener;
+ this.clientTimeout = clientTimeout;
+ }
+
+ /**
+ * Creates just a port listening server socket
+ */
+ public TServerSocket(int port)
+ : this(port, 0)
+ {
+ }
+
+ /**
+ * Creates just a port listening server socket
+ */
+ public TServerSocket(int port, int clientTimeout)
+ {
+ this.port = port;
+ this.clientTimeout = clientTimeout;
+ try
+ {
+ // Make server socket
+ server = new TcpListener(System.Net.IPAddress.Any, this.port);
+ }
+ catch (Exception e)
+ {
+ server = null;
+ throw new TTransportException("Could not create ServerSocket on port " + port + ".");
+ }
+ }
+
+ public override void Listen()
+ {
+ // Make sure not to block on accept
+ if (server != null)
+ {
+ try
+ {
+ server.Start();
+ }
+ catch (SocketException sx)
+ {
+ Console.Error.WriteLine(sx);
+ }
+ }
+ }
+
+ protected override TTransport AcceptImpl()
+ {
+ if (server == null)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen, "No underlying server socket.");
+ }
+ try
+ {
+ TcpClient result = server.AcceptTcpClient();
+ TSocket result2 = new TSocket(result);
+ result2.Timeout = clientTimeout;
+ return result2;
+ }
+ catch (Exception ex)
+ {
+ throw new TTransportException(ex.ToString());
+ }
+ }
+
+ public override void Close()
+ {
+ if (server != null)
+ {
+ try
+ {
+ server.Stop();
+ }
+ catch (Exception ex)
+ {
+ Console.Error.WriteLine("WARNING: Could not close server socket: " + ex);
+ }
+ server = null;
+ }
+ }
+ }
+}
diff --git a/lib/csharp/src/Transport/TServerTransport.cs b/lib/csharp/src/Transport/TServerTransport.cs
new file mode 100644
index 0000000..b4f5f07
--- /dev/null
+++ b/lib/csharp/src/Transport/TServerTransport.cs
@@ -0,0 +1,31 @@
+//
+// TServerTransport.cs
+//
+// Begin: Dec 3, 2007
+// Authors:
+// Will Palmeri <wpalmeri@imeem.com>
+//
+// Copyright (C) 2007 imeem, inc. <http://www.imeem.com>
+// All rights reserved.
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Thrift.Transport
+{
+ public abstract class TServerTransport
+ {
+ public abstract void Listen();
+ public abstract void Close();
+ protected abstract TTransport AcceptImpl();
+
+ public TTransport Accept()
+ {
+ TTransport transport = AcceptImpl();
+ if (transport == null) {
+ throw new TTransportException("accept() may not return NULL");
+ }
+ return transport;
+ }
+ }
+}
diff --git a/lib/csharp/src/Transport/TSocket.cs b/lib/csharp/src/Transport/TSocket.cs
new file mode 100644
index 0000000..c05d587
--- /dev/null
+++ b/lib/csharp/src/Transport/TSocket.cs
@@ -0,0 +1,122 @@
+//
+// TSocket.cs
+//
+// Begin: Aug 19, 2007
+// Authors:
+// Todd Berman <tberman@imeem.com>
+//
+// Copyright (C) 2007 imeem, inc. <http://www.imeem.com>
+// All rights reserved.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Net.Sockets;
+
+namespace Thrift.Transport
+{
+ public class TSocket : TStreamTransport
+ {
+ private TcpClient client = null;
+ private string host = null;
+ private int port = 0;
+ private int timeout = 0;
+
+ public TSocket(TcpClient client)
+ {
+ this.client = client;
+
+ if (IsOpen)
+ {
+ inputStream = client.GetStream();
+ outputStream = client.GetStream();
+ }
+ }
+
+ public TSocket(string host, int port) : this(host, port, 0)
+ {
+ }
+
+ public TSocket(string host, int port, int timeout)
+ {
+ this.host = host;
+ this.port = port;
+ this.timeout = timeout;
+
+ InitSocket();
+ }
+
+ private void InitSocket()
+ {
+ client = new TcpClient();
+ client.ReceiveTimeout = client.SendTimeout = timeout;
+ }
+
+ public int Timeout
+ {
+ set
+ {
+ client.ReceiveTimeout = client.SendTimeout = timeout = value;
+ }
+ }
+
+ public TcpClient TcpClient
+ {
+ get
+ {
+ return client;
+ }
+ }
+
+ public override bool IsOpen
+ {
+ get
+ {
+ if (client == null)
+ {
+ return false;
+ }
+
+ return client.Connected;
+ }
+ }
+
+ public override void Open()
+ {
+ if (IsOpen)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.AlreadyOpen, "Socket already connected");
+ }
+
+ if (String.IsNullOrEmpty(host))
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open null host");
+ }
+
+ if (port <= 0)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open without port");
+ }
+
+ if (client == null)
+ {
+ InitSocket();
+ }
+
+ client.Connect(host, port);
+ inputStream = client.GetStream();
+ outputStream = client.GetStream();
+ }
+
+ public override void Close()
+ {
+ base.Close();
+ if (client != null)
+ {
+ client.Close();
+ client = null;
+ }
+ }
+ }
+}
diff --git a/lib/csharp/src/Transport/TStreamTransport.cs b/lib/csharp/src/Transport/TStreamTransport.cs
new file mode 100644
index 0000000..1715b6a
--- /dev/null
+++ b/lib/csharp/src/Transport/TStreamTransport.cs
@@ -0,0 +1,87 @@
+//
+// TStreamTransport.cs
+//
+// Begin: Aug 19, 2007
+// Authors:
+// Todd Berman <tberman@imeem.com>
+//
+// Copyright (C) 2007 imeem, inc. <http://www.imeem.com>
+// All rights reserved.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+
+namespace Thrift.Transport
+{
+ public class TStreamTransport : TTransport
+ {
+ protected Stream inputStream;
+ protected Stream outputStream;
+
+ public TStreamTransport()
+ {
+ }
+
+ public TStreamTransport(Stream inputStream, Stream outputStream)
+ {
+ this.inputStream = inputStream;
+ this.outputStream = outputStream;
+ }
+
+ public override bool IsOpen
+ {
+ get { return true; }
+ }
+
+ public override void Open()
+ {
+ }
+
+ public override void Close()
+ {
+ if (inputStream != null)
+ {
+ inputStream.Close();
+ inputStream = null;
+ }
+ if (outputStream != null)
+ {
+ outputStream.Close();
+ outputStream = null;
+ }
+ }
+
+ public override int Read(byte[] buf, int off, int len)
+ {
+ if (inputStream == null)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot read from null inputstream");
+ }
+
+ return inputStream.Read(buf, off, len);
+ }
+
+ public override void Write(byte[] buf, int off, int len)
+ {
+ if (outputStream == null)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot write to null outputstream");
+ }
+
+ outputStream.Write(buf, off, len);
+ }
+
+ public override void Flush()
+ {
+ if (outputStream == null)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot flush null outputstream");
+ }
+
+ outputStream.Flush();
+ }
+ }
+}
diff --git a/lib/csharp/src/Transport/TTransport.cs b/lib/csharp/src/Transport/TTransport.cs
new file mode 100644
index 0000000..90f7e74
--- /dev/null
+++ b/lib/csharp/src/Transport/TTransport.cs
@@ -0,0 +1,60 @@
+//
+// TTransport.cs
+//
+// Begin: Aug 19, 2007
+// Authors:
+// Todd Berman <tberman@imeem.com>
+//
+// Copyright (C) 2007 imeem, inc. <http://www.imeem.com>
+// All rights reserved.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Thrift.Transport
+{
+ public abstract class TTransport
+ {
+ public abstract bool IsOpen
+ {
+ get;
+ }
+
+ public bool Peek()
+ {
+ return IsOpen;
+ }
+
+ public abstract void Open();
+
+ public abstract void Close();
+
+ public abstract int Read(byte[] buf, int off, int len);
+
+ public int ReadAll(byte[] buf, int off, int len)
+ {
+ int got = 0;
+ int ret = 0;
+
+ while (got < len)
+ {
+ ret = Read(buf, off + got, len - got);
+ if (ret <= 0)
+ {
+ throw new TTransportException("Cannot read, Remote side has closed");
+ }
+ got += ret;
+ }
+
+ return got;
+ }
+
+ public abstract void Write(byte[] buf, int off, int len);
+
+ public virtual void Flush()
+ {
+ }
+ }
+}
diff --git a/lib/csharp/src/Transport/TTransportException.cs b/lib/csharp/src/Transport/TTransportException.cs
new file mode 100644
index 0000000..d59c46e
--- /dev/null
+++ b/lib/csharp/src/Transport/TTransportException.cs
@@ -0,0 +1,58 @@
+//
+// TTransportException.cs
+//
+// Begin: Aug 19, 2007
+// Authors:
+// Todd Berman <tberman@imeem.com>
+//
+// Copyright (C) 2007 imeem, inc. <http://www.imeem.com>
+// All rights reserved.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Thrift.Transport
+{
+ public class TTransportException : Exception
+ {
+ protected ExceptionType type;
+
+ public TTransportException()
+ : base()
+ {
+ }
+
+ public TTransportException(ExceptionType type)
+ : this()
+ {
+ this.type = type;
+ }
+
+ public TTransportException(ExceptionType type, string message)
+ : base(message)
+ {
+ this.type = type;
+ }
+
+ public TTransportException(string message)
+ : base(message)
+ {
+ }
+
+ public ExceptionType Type
+ {
+ get { return type; }
+ }
+
+ public enum ExceptionType
+ {
+ Unknown,
+ NotOpen,
+ AlreadyOpen,
+ TimedOut,
+ EndOfFile
+ }
+ }
+}
diff --git a/lib/csharp/src/Transport/TTransportFactory.cs b/lib/csharp/src/Transport/TTransportFactory.cs
new file mode 100644
index 0000000..456140d
--- /dev/null
+++ b/lib/csharp/src/Transport/TTransportFactory.cs
@@ -0,0 +1,32 @@
+//
+// TTransportFactory.cs
+//
+// Begin: Dec 3, 2007
+// Authors:
+// Will Palmeri <wpalmeri@imeem.com>
+//
+// Copyright (C) 2007 imeem, inc. <http://www.imeem.com>
+// All rights reserved.
+//
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+
+namespace Thrift.Transport
+{
+ /// <summary>
+ /// From Mark Slee & Aditya Agarwal of Facebook:
+ /// Factory class used to create wrapped instance of Transports.
+ /// This is used primarily in servers, which get Transports from
+ /// a ServerTransport and then may want to mutate them (i.e. create
+ /// a BufferedTransport from the underlying base transport)
+ /// </summary>
+ public class TTransportFactory
+ {
+ public TTransport GetTransport(TTransport trans)
+ {
+ return trans;
+ }
+ }
+}