summaryrefslogtreecommitdiffstats
path: root/src/jaegertracing/thrift/lib/csharp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
commit19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch)
tree42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/jaegertracing/thrift/lib/csharp
parentInitial commit. (diff)
downloadceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.tar.xz
ceph-19fcec84d8d7d21e796c7624e521b60d28ee21ed.zip
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/jaegertracing/thrift/lib/csharp')
-rw-r--r--src/jaegertracing/thrift/lib/csharp/Makefile.am114
-rw-r--r--src/jaegertracing/thrift/lib/csharp/README.md32
-rw-r--r--src/jaegertracing/thrift/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs60
-rw-r--r--src/jaegertracing/thrift/lib/csharp/ThriftMSBuildTask/ThriftBuild.cs246
-rw-r--r--src/jaegertracing/thrift/lib/csharp/ThriftMSBuildTask/ThriftMSBuildTask.csproj118
-rw-r--r--src/jaegertracing/thrift/lib/csharp/coding_standards.md6
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Collections/TCollections.cs94
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Collections/THashSet.cs160
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Net35/ExtensionsNet35.cs31
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Properties/AssemblyInfo.cs55
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Protocol/TAbstractBase.cs29
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Protocol/TBase.cs29
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Protocol/TBase64Utils.cs100
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Protocol/TBinaryProtocol.cs395
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Protocol/TCompactProtocol.cs849
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Protocol/TField.cs62
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Protocol/TJSONProtocol.cs1124
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Protocol/TList.cs54
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Protocol/TMap.cs62
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Protocol/TMessage.cs62
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Protocol/TMessageType.cs31
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Protocol/TMultiplexedProcessor.cs183
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Protocol/TMultiplexedProtocol.cs103
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Protocol/TProtocol.cs142
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Protocol/TProtocolDecorator.cs261
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Protocol/TProtocolException.cs67
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Protocol/TProtocolFactory.cs33
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Protocol/TProtocolUtil.cs108
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Protocol/TSet.cs59
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Protocol/TStruct.cs46
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Protocol/TType.cs44
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Server/TServer.cs155
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Server/TServerEventHandler.cs53
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Server/TSimpleServer.cs180
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Server/TThreadPoolServer.cs295
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Server/TThreadedServer.cs282
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/TApplicationException.cs146
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/TAsyncProcessor.cs38
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/TControllingHandler.cs29
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/TException.cs40
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/TProcessor.cs33
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/TProcessorFactory.cs30
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/TPrototypeProcessorFactory.cs55
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/TSingletonProcessorFactory.cs43
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Thrift.45.csproj138
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Thrift.csproj166
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Thrift.sln47
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Transport/TBufferedTransport.cs194
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Transport/TFramedTransport.cs205
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Transport/THttpClient.cs486
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Transport/THttpHandler.cs102
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Transport/THttpTaskAsyncHandler.cs97
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Transport/TMemoryBuffer.cs117
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Transport/TNamedPipeClientTransport.cs111
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Transport/TNamedPipeServerTransport.cs296
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Transport/TServerSocket.cs176
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Transport/TServerTransport.cs44
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Transport/TSilverlightSocket.cs393
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Transport/TSocket.cs245
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Transport/TSocketVersionizer.cs78
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Transport/TStreamTransport.cs128
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Transport/TTLSServerSocket.cs223
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Transport/TTLSSocket.cs445
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Transport/TTransport.cs146
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Transport/TTransportException.cs69
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/Transport/TTransportFactory.cs42
-rw-r--r--src/jaegertracing/thrift/lib/csharp/src/thrift.snkbin0 -> 596 bytes
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/JSON/JSONTest.csproj85
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/JSON/Program.cs95
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/JSON/Properties/AssemblyInfo.cs55
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/JSON/app.config21
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/Multiplex/Client/Multiplex.Test.Client.cs82
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/Multiplex/Client/MultiplexClient.csproj148
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/Multiplex/Client/Properties/AssemblyInfo.cs55
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/Multiplex/Makefile.am63
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/Multiplex/Multiplex.Test.Common.cs40
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/Multiplex/Server/Multiplex.Test.Server.cs107
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/Multiplex/Server/MultiplexServer.csproj148
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/Multiplex/Server/Properties/AssemblyInfo.cs55
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/App_Start/FilterConfig.cs31
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/App_Start/RouteConfig.cs39
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/AsyncHttpHandler.cs32
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Controllers/HomeController.cs70
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Global.asax19
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Global.asax.cs34
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Properties/AssemblyInfo.cs53
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/SecondServiceImpl.cs37
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/SyncHttpHandler.cs32
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/ThriftMVCTest.csproj200
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Views/Home/Index.cshtml25
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Views/Shared/_Layout.cshtml30
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Views/Web.config60
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Views/_ViewStart.cshtml22
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Web.Debug.config45
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Web.Release.config46
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Web.config92
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/favicon.icobin0 -> 32038 bytes
-rw-r--r--src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/packages.config25
98 files changed, 11932 insertions, 0 deletions
diff --git a/src/jaegertracing/thrift/lib/csharp/Makefile.am b/src/jaegertracing/thrift/lib/csharp/Makefile.am
new file mode 100644
index 000000000..cc2bbc96c
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/Makefile.am
@@ -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.
+#
+
+SUBDIRS = . test/Multiplex
+
+THRIFTCODE = \
+ src/Collections/THashSet.cs \
+ src/Collections/TCollections.cs \
+ src/Properties/AssemblyInfo.cs \
+ src/Protocol/TAbstractBase.cs \
+ src/Protocol/TBase.cs \
+ src/Protocol/TBase64Utils.cs \
+ src/Protocol/TJSONProtocol.cs \
+ src/Protocol/TProtocolException.cs \
+ src/Protocol/TProtocolFactory.cs \
+ src/Protocol/TList.cs \
+ src/Protocol/TSet.cs \
+ src/Protocol/TMap.cs \
+ src/Protocol/TProtocolUtil.cs \
+ src/Protocol/TMessageType.cs \
+ src/Protocol/TProtocol.cs \
+ src/Protocol/TProtocolDecorator.cs \
+ src/Protocol/TMultiplexedProtocol.cs \
+ src/Protocol/TMultiplexedProcessor.cs \
+ src/Protocol/TType.cs \
+ src/Protocol/TField.cs \
+ src/Protocol/TMessage.cs \
+ src/Protocol/TStruct.cs \
+ src/Protocol/TBinaryProtocol.cs \
+ src/Protocol/TCompactProtocol.cs \
+ src/Server/TThreadedServer.cs \
+ src/Server/TThreadPoolServer.cs \
+ src/Server/TSimpleServer.cs \
+ src/Server/TServer.cs \
+ src/Server/TServerEventHandler.cs \
+ src/Transport/TBufferedTransport.cs \
+ src/Transport/TTransport.cs \
+ src/Transport/TSocket.cs \
+ src/Transport/TSocketVersionizer.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 \
+ src/Transport/THttpClient.cs \
+ src/Transport/THttpHandler.cs \
+ src/Transport/TMemoryBuffer.cs \
+ src/Transport/TNamedPipeClientTransport.cs \
+ src/Transport/TNamedPipeServerTransport.cs \
+ src/Transport/TTLSSocket.cs \
+ src/Transport/TTLSServerSocket.cs \
+ src/TProcessor.cs \
+ src/TProcessorFactory.cs \
+ src/TSingletonProcessorFactory.cs \
+ src/TPrototypeProcessorFactory.cs \
+ src/TControllingHandler.cs \
+ src/TException.cs \
+ src/TApplicationException.cs
+
+if MONO_MCS
+export CSC = mcs
+else
+export CSC = gmcs
+endif
+
+if NET_2_0
+export CSC_DEFINES = -d:NET_2_0
+endif
+
+all-local: Thrift.dll Thrift.45.dll
+
+Thrift.dll: $(THRIFTCODE)
+ $(CSC) $(CSC_DEFINES) -out:$@ -target:library -reference:System.Web $(THRIFTCODE)
+
+Thrift.45.dll: $(THRIFTCODE)
+ $(CSC) $(CSC_DEFINES) -out:$@ -target:library -reference:System.Web $(THRIFTCODE)
+
+CLEANFILES = \
+ Thrift.dll \
+ Thrift.45.dll
+
+DISTCLEANFILES = \
+ Makefile.in
+
+EXTRA_DIST = \
+ $(THRIFTCODE) \
+ ThriftMSBuildTask \
+ src/Thrift.csproj \
+ src/Thrift.45.csproj \
+ src/Thrift.sln \
+ src/Net35/ExtensionsNet35.cs \
+ src/Transport/TSilverlightSocket.cs \
+ src/Transport/THttpTaskAsyncHandler.cs \
+ src/TAsyncProcessor.cs \
+ test \
+ coding_standards.md \
+ README.md
diff --git a/src/jaegertracing/thrift/lib/csharp/README.md b/src/jaegertracing/thrift/lib/csharp/README.md
new file mode 100644
index 000000000..5fc14cb3c
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/README.md
@@ -0,0 +1,32 @@
+Thrift C# Software Library
+
+Deprecation notice
+=======
+
+Per [THRIFT-4723](https://issues.apache.org/jira/browse/THRIFT-4723), both CSharp and Netcore targets are deprecated
+and will be removed with the next release. Migrate to the [NetStd language target](../netstd/README.md) instead.
+
+License
+=======
+
+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 Thrift with C#
+====================
+
+Thrift requires Mono >= 1.2.6 or .NET framework >= 3.5
diff --git a/src/jaegertracing/thrift/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs b/src/jaegertracing/thrift/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..6e99dd9fd
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs
@@ -0,0 +1,60 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+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("MSBuild Task to generate csharp from .thrift files, and compile the code into a library: ThriftImpl.dll")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("ThriftMSBuildTask")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+//@TODO where to put License information?
+
+// 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("0.13.0.*")]
+[assembly: AssemblyFileVersion("0.13.0.*")]
diff --git a/src/jaegertracing/thrift/lib/csharp/ThriftMSBuildTask/ThriftBuild.cs b/src/jaegertracing/thrift/lib/csharp/ThriftMSBuildTask/ThriftBuild.cs
new file mode 100644
index 000000000..4e6d30112
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/ThriftMSBuildTask/ThriftBuild.cs
@@ -0,0 +1,246 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+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);
+ //don't recompile if the thrift library has been updated since lastComp
+ FileInfo f = new FileInfo(ThriftLibrary.ItemSpec);
+ string thriftLibTime = f.LastWriteTimeUtc.ToFileTimeUtc().ToString();
+ if (lastComp.CompareTo(thriftLibTime) < 0)
+ {
+ //new thrift library, do a compile
+ lastWrite = thriftLibTime;
+ }
+ else if (lastComp == lastWrite || (lastComp == thriftLibTime && lastComp.CompareTo(lastWrite) > 0))
+ {
+ //the .thrift dir hasn't been written to since last compilation, don't need to do anything
+ LogMessage("ThriftImpl up-to-date", MessageImportance.High);
+ 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))
+ {
+ try
+ {
+ Directory.Delete(genDir, true);
+ }
+ catch { /*eh i tried, just over-write now*/}
+ }
+
+ //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 = "--gen csharp -o " + SafePath(thriftDir) + " -r " + thriftFile;
+ p.StartInfo.UseShellExecute = false;
+ p.StartInfo.CreateNoWindow = true;
+ p.StartInfo.RedirectStandardOutput = false;
+ p.Start();
+ p.WaitForExit();
+ if (p.ExitCode != 0)
+ {
+ LogMessage("thrift.exe failed to compile " + thriftFile, MessageImportance.High);
+ return false;
+ }
+ if (p.ExitCode != 0)
+ {
+ LogMessage("thrift.exe failed to compile " + thriftFile, MessageImportance.High);
+ return false;
+ }
+ }
+
+ 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/src/jaegertracing/thrift/lib/csharp/ThriftMSBuildTask/ThriftMSBuildTask.csproj b/src/jaegertracing/thrift/lib/csharp/ThriftMSBuildTask/ThriftMSBuildTask.csproj
new file mode 100644
index 000000000..f4a26de45
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/ThriftMSBuildTask/ThriftMSBuildTask.csproj
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<Project ToolsVersion="4.0" 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>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <UpgradeBackupLocation />
+ <PublishUrl>publish\</PublishUrl>
+ <Install>true</Install>
+ <InstallFrom>Disk</InstallFrom>
+ <UpdateEnabled>false</UpdateEnabled>
+ <UpdateMode>Foreground</UpdateMode>
+ <UpdateInterval>7</UpdateInterval>
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+ <UpdatePeriodically>false</UpdatePeriodically>
+ <UpdateRequired>false</UpdateRequired>
+ <MapFileExtensions>true</MapFileExtensions>
+ <ApplicationRevision>0</ApplicationRevision>
+ <ApplicationVersion>0.13.0.0</ApplicationVersion>
+ <IsWebBootstrapper>false</IsWebBootstrapper>
+ <UseApplicationTrust>false</UseApplicationTrust>
+ <BootstrapperEnabled>true</BootstrapperEnabled>
+ </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>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </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>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </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>
+ <ItemGroup>
+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+ <Visible>False</Visible>
+ <ProductName>Windows Installer 3.1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ </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>
diff --git a/src/jaegertracing/thrift/lib/csharp/coding_standards.md b/src/jaegertracing/thrift/lib/csharp/coding_standards.md
new file mode 100644
index 000000000..dc87190bf
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/coding_standards.md
@@ -0,0 +1,6 @@
+## C# Coding Standards
+
+Please follow:
+ * [Thrift General Coding Standards](/doc/coding_standards.md)
+ * [MSDN C# Coding Conventions](http://msdn.microsoft.com/en-us/library/ff926074.aspx)
+ * [C# Coding Guidelines](http://csharpguidelines.codeplex.com/)
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Collections/TCollections.cs b/src/jaegertracing/thrift/lib/csharp/src/Collections/TCollections.cs
new file mode 100644
index 000000000..84afb6a62
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Collections/TCollections.cs
@@ -0,0 +1,94 @@
+/**
+ * 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;
+using System.Collections;
+
+namespace Thrift.Collections
+{
+ public class TCollections
+ {
+ /// <summary>
+ /// This will return true if the two collections are value-wise the same.
+ /// If the collection contains a collection, the collections will be compared using this method.
+ /// </summary>
+ public static bool Equals (IEnumerable first, IEnumerable second)
+ {
+ if (first == null && second == null)
+ {
+ return true;
+ }
+ if (first == null || second == null)
+ {
+ return false;
+ }
+ IEnumerator fiter = first.GetEnumerator ();
+ IEnumerator siter = second.GetEnumerator ();
+
+ bool fnext = fiter.MoveNext ();
+ bool snext = siter.MoveNext ();
+ while (fnext && snext)
+ {
+ IEnumerable fenum = fiter.Current as IEnumerable;
+ IEnumerable senum = siter.Current as IEnumerable;
+ if (fenum != null && senum != null)
+ {
+ if (!Equals(fenum, senum))
+ {
+ return false;
+ }
+ }
+ else if (fenum == null ^ senum == null)
+ {
+ return false;
+ }
+ else if (!Equals(fiter.Current, siter.Current))
+ {
+ return false;
+ }
+ fnext = fiter.MoveNext();
+ snext = siter.MoveNext();
+ }
+
+ return fnext == snext;
+ }
+
+ /// <summary>
+ /// This returns a hashcode based on the value of the enumerable.
+ /// </summary>
+ public static int GetHashCode (IEnumerable enumerable)
+ {
+ if (enumerable == null)
+ {
+ return 0;
+ }
+
+ int hashcode = 0;
+ foreach (object obj in enumerable)
+ {
+ IEnumerable enum2 = obj as IEnumerable;
+ int objHash = enum2 == null ? obj.GetHashCode () : GetHashCode (enum2);
+ unchecked
+ {
+ hashcode = (hashcode * 397) ^ (objHash);
+ }
+ }
+ return hashcode;
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Collections/THashSet.cs b/src/jaegertracing/thrift/lib/csharp/src/Collections/THashSet.cs
new file mode 100644
index 000000000..e29271a93
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Collections/THashSet.cs
@@ -0,0 +1,160 @@
+/**
+ * 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;
+using System.Collections;
+using System.Collections.Generic;
+
+#if SILVERLIGHT
+using System.Runtime.Serialization;
+#endif
+
+namespace Thrift.Collections
+{
+#if SILVERLIGHT
+ [DataContract]
+#else
+ [Serializable]
+#endif
+ public class THashSet<T> : ICollection<T>
+ {
+#if NET_2_0 || SILVERLIGHT
+#if SILVERLIGHT
+ [DataMember]
+#endif
+ TDictSet<T> set = new TDictSet<T>();
+#else
+ HashSet<T> set = new HashSet<T>();
+#endif
+ public int Count
+ {
+ get { return set.Count; }
+ }
+
+ public bool IsReadOnly
+ {
+ get { return false; }
+ }
+
+ public void Add(T item)
+ {
+ set.Add(item);
+ }
+
+ public void Clear()
+ {
+ set.Clear();
+ }
+
+ public bool Contains(T item)
+ {
+ return set.Contains(item);
+ }
+
+ public void CopyTo(T[] array, int arrayIndex)
+ {
+ set.CopyTo(array, arrayIndex);
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return set.GetEnumerator();
+ }
+
+ IEnumerator<T> IEnumerable<T>.GetEnumerator()
+ {
+ return ((IEnumerable<T>)set).GetEnumerator();
+ }
+
+ public bool Remove(T item)
+ {
+ return set.Remove(item);
+ }
+
+#if NET_2_0 || SILVERLIGHT
+#if SILVERLIGHT
+ [DataContract]
+#endif
+ private class TDictSet<V> : ICollection<V>
+ {
+#if SILVERLIGHT
+ [DataMember]
+#endif
+ Dictionary<V, TDictSet<V>> dict = new Dictionary<V, TDictSet<V>>();
+
+ public int Count
+ {
+ get { return dict.Count; }
+ }
+
+ public bool IsReadOnly
+ {
+ get { return false; }
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return ((IEnumerable)dict.Keys).GetEnumerator();
+ }
+
+ IEnumerator<V> IEnumerable<V>.GetEnumerator()
+ {
+ return dict.Keys.GetEnumerator();
+ }
+
+ public bool Add(V item)
+ {
+ if (!dict.ContainsKey(item))
+ {
+ dict[item] = this;
+ return true;
+ }
+
+ return false;
+ }
+
+ void ICollection<V>.Add(V item)
+ {
+ Add(item);
+ }
+
+ public void Clear()
+ {
+ dict.Clear();
+ }
+
+ public bool Contains(V item)
+ {
+ return dict.ContainsKey(item);
+ }
+
+ public void CopyTo(V[] array, int arrayIndex)
+ {
+ dict.Keys.CopyTo(array, arrayIndex);
+ }
+
+ public bool Remove(V item)
+ {
+ return dict.Remove(item);
+ }
+ }
+#endif
+ }
+
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Net35/ExtensionsNet35.cs b/src/jaegertracing/thrift/lib/csharp/src/Net35/ExtensionsNet35.cs
new file mode 100644
index 000000000..73a423288
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Net35/ExtensionsNet35.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+#if (!NET45)
+namespace Thrift
+{
+ static class StreamExtensionsNet35
+ {
+ // CopyTo() has been added in 4.0
+ public static long CopyTo(this Stream source, Stream target)
+ {
+ byte[] buffer = new byte[8192]; // multiple of 4096
+ long nTotal = 0;
+ while (true)
+ {
+ int nRead = source.Read(buffer, 0, buffer.Length);
+ if (nRead <= 0) // done?
+ return nTotal;
+
+ target.Write(buffer, 0, nRead);
+ nTotal += nRead;
+ }
+ }
+ }
+
+}
+#endif
+
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Properties/AssemblyInfo.cs b/src/jaegertracing/thrift/lib/csharp/src/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..ace031045
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Properties/AssemblyInfo.cs
@@ -0,0 +1,55 @@
+/**
+ * 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.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("Thrift")]
+[assembly: AssemblyDescription("C# bindings for the Apache Thrift RPC system")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("Thrift")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+//@TODO where to put License information?
+
+// 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("df3f8ef0-e0a3-4c86-a65b-8ec84e016b1d")]
+
+// 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("0.13.0.0")]
+[assembly: AssemblyFileVersion("0.13.0.0")]
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Protocol/TAbstractBase.cs b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TAbstractBase.cs
new file mode 100644
index 000000000..f5a61cd44
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TAbstractBase.cs
@@ -0,0 +1,29 @@
+/**
+ * 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.
+ */
+
+namespace Thrift.Protocol
+{
+ public interface TAbstractBase
+ {
+ /// <summary>
+ /// Writes the objects out to the protocol.
+ /// </summary>
+ void Write(TProtocol tProtocol);
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Protocol/TBase.cs b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TBase.cs
new file mode 100644
index 000000000..411e4d95f
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TBase.cs
@@ -0,0 +1,29 @@
+/**
+ * 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.
+ */
+
+namespace Thrift.Protocol
+{
+ public interface TBase : TAbstractBase
+ {
+ /// <summary>
+ /// Reads the TObject from the given input protocol.
+ /// </summary>
+ void Read(TProtocol tProtocol);
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Protocol/TBase64Utils.cs b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TBase64Utils.cs
new file mode 100644
index 000000000..9eaaebdda
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TBase64Utils.cs
@@ -0,0 +1,100 @@
+/**
+ * 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;
+
+namespace Thrift.Protocol
+{
+ internal static class TBase64Utils
+ {
+ internal const string ENCODE_TABLE =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+ internal static void encode(byte[] src, int srcOff, int len, byte[] dst,
+ int dstOff)
+ {
+ dst[dstOff] = (byte)ENCODE_TABLE[(src[srcOff] >> 2) & 0x3F];
+ if (len == 3)
+ {
+ dst[dstOff + 1] =
+ (byte)ENCODE_TABLE[
+ ((src[srcOff] << 4) & 0x30) | ((src[srcOff + 1] >> 4) & 0x0F)];
+ dst[dstOff + 2] =
+ (byte)ENCODE_TABLE[
+ ((src[srcOff + 1] << 2) & 0x3C) | ((src[srcOff + 2] >> 6) & 0x03)];
+ dst[dstOff + 3] =
+ (byte)ENCODE_TABLE[src[srcOff + 2] & 0x3F];
+ }
+ else if (len == 2)
+ {
+ dst[dstOff + 1] =
+ (byte)ENCODE_TABLE[
+ ((src[srcOff] << 4) & 0x30) | ((src[srcOff + 1] >> 4) & 0x0F)];
+ dst[dstOff + 2] =
+ (byte)ENCODE_TABLE[(src[srcOff + 1] << 2) & 0x3C];
+
+ }
+ else
+ { // len == 1) {
+ dst[dstOff + 1] =
+ (byte)ENCODE_TABLE[(src[srcOff] << 4) & 0x30];
+ }
+ }
+
+ private static int[] DECODE_TABLE = {
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,
+ 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,
+ 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,
+ -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
+ 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+ };
+
+ internal static void decode(byte[] src, int srcOff, int len, byte[] dst,
+ int dstOff)
+ {
+ dst[dstOff] = (byte)
+ ((DECODE_TABLE[src[srcOff] & 0x0FF] << 2) |
+ (DECODE_TABLE[src[srcOff + 1] & 0x0FF] >> 4));
+ if (len > 2)
+ {
+ dst[dstOff + 1] = (byte)
+ (((DECODE_TABLE[src[srcOff + 1] & 0x0FF] << 4) & 0xF0) |
+ (DECODE_TABLE[src[srcOff + 2] & 0x0FF] >> 2));
+ if (len > 3)
+ {
+ dst[dstOff + 2] = (byte)
+ (((DECODE_TABLE[src[srcOff + 2] & 0x0FF] << 6) & 0xC0) |
+ DECODE_TABLE[src[srcOff + 3] & 0x0FF]);
+ }
+ }
+ }
+
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Protocol/TBinaryProtocol.cs b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TBinaryProtocol.cs
new file mode 100644
index 000000000..a4faa946f
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TBinaryProtocol.cs
@@ -0,0 +1,395 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+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;
+
+ #region BinaryProtocol 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((sbyte)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((sbyte)field.Type);
+ WriteI16(field.ID);
+ }
+
+ public override void WriteFieldEnd()
+ {
+ }
+
+ public override void WriteFieldStop()
+ {
+ WriteByte((sbyte)TType.Stop);
+ }
+
+ public override void WriteMapBegin(TMap map)
+ {
+ WriteByte((sbyte)map.KeyType);
+ WriteByte((sbyte)map.ValueType);
+ WriteI32(map.Count);
+ }
+
+ public override void WriteMapEnd()
+ {
+ }
+
+ public override void WriteListBegin(TList list)
+ {
+ WriteByte((sbyte)list.ElementType);
+ WriteI32(list.Count);
+ }
+
+ public override void WriteListEnd()
+ {
+ }
+
+ public override void WriteSetBegin(TSet set)
+ {
+ WriteByte((sbyte)set.ElementType);
+ WriteI32(set.Count);
+ }
+
+ public override void WriteSetEnd()
+ {
+ }
+
+ public override void WriteBool(bool b)
+ {
+ WriteByte(b ? (sbyte)1 : (sbyte)0);
+ }
+
+ private byte[] bout = new byte[1];
+ public override void WriteByte(sbyte b)
+ {
+ bout[0] = (byte)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)
+ {
+#if !SILVERLIGHT
+ WriteI64(BitConverter.DoubleToInt64Bits(d));
+#else
+ var bytes = BitConverter.GetBytes(d);
+ WriteI64(BitConverter.ToInt64(bytes, 0));
+#endif
+ }
+
+ public override void WriteBinary(byte[] b)
+ {
+ 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 sbyte ReadByte()
+ {
+ ReadAll(bin, 0, 1);
+ return (sbyte)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)));
+ }
+
+#pragma warning disable 675
+
+ private byte[] i64in = new byte[8];
+ public override long ReadI64()
+ {
+ ReadAll(i64in, 0, 8);
+ unchecked
+ {
+ 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)));
+ }
+ }
+
+#pragma warning restore 675
+
+ public override double ReadDouble()
+ {
+#if !SILVERLIGHT
+ return BitConverter.Int64BitsToDouble(ReadI64());
+#else
+ var value = ReadI64();
+ var bytes = BitConverter.GetBytes(value);
+ return BitConverter.ToDouble(bytes, 0);
+#endif
+ }
+
+ public override byte[] ReadBinary()
+ {
+ int size = ReadI32();
+ byte[] buf = new byte[size];
+ trans.ReadAll(buf, 0, size);
+ return buf;
+ }
+ private string ReadStringBody(int size)
+ {
+ byte[] buf = new byte[size];
+ trans.ReadAll(buf, 0, size);
+ return Encoding.UTF8.GetString(buf, 0, buf.Length);
+ }
+
+ private int ReadAll(byte[] buf, int off, int len)
+ {
+ return trans.ReadAll(buf, off, len);
+ }
+
+ #endregion
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Protocol/TCompactProtocol.cs b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TCompactProtocol.cs
new file mode 100644
index 000000000..ff673975e
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TCompactProtocol.cs
@@ -0,0 +1,849 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.Text;
+using Thrift.Transport;
+using System.Collections;
+using System.IO;
+using System.Collections.Generic;
+
+namespace Thrift.Protocol
+{
+ public class TCompactProtocol : TProtocol
+ {
+ private static TStruct ANONYMOUS_STRUCT = new TStruct("");
+ private static TField TSTOP = new TField("", TType.Stop, (short)0);
+
+ private static byte[] ttypeToCompactType = new byte[16];
+
+ private const byte PROTOCOL_ID = 0x82;
+ private const byte VERSION = 1;
+ private const byte VERSION_MASK = 0x1f; // 0001 1111
+ private const byte TYPE_MASK = 0xE0; // 1110 0000
+ private const byte TYPE_BITS = 0x07; // 0000 0111
+ private const int TYPE_SHIFT_AMOUNT = 5;
+
+ /// <summary>
+ /// All of the on-wire type codes.
+ /// </summary>
+ private static class Types
+ {
+ public const byte STOP = 0x00;
+ public const byte BOOLEAN_TRUE = 0x01;
+ public const byte BOOLEAN_FALSE = 0x02;
+ public const byte BYTE = 0x03;
+ public const byte I16 = 0x04;
+ public const byte I32 = 0x05;
+ public const byte I64 = 0x06;
+ public const byte DOUBLE = 0x07;
+ public const byte BINARY = 0x08;
+ public const byte LIST = 0x09;
+ public const byte SET = 0x0A;
+ public const byte MAP = 0x0B;
+ public const byte STRUCT = 0x0C;
+ }
+
+ /// <summary>
+ /// Used to keep track of the last field for the current and previous structs,
+ /// so we can do the delta stuff.
+ /// </summary>
+ private Stack<short> lastField_ = new Stack<short>(15);
+
+ private short lastFieldId_ = 0;
+
+ /// <summary>
+ /// If we encounter a boolean field begin, save the TField here so it can
+ /// have the value incorporated.
+ /// </summary>
+ private Nullable<TField> booleanField_;
+
+ /// <summary>
+ /// If we Read a field header, and it's a boolean field, save the boolean
+ /// value here so that ReadBool can use it.
+ /// </summary>
+ private Nullable<Boolean> boolValue_;
+
+
+ #region CompactProtocol Factory
+
+ public class Factory : TProtocolFactory
+ {
+ public Factory() { }
+
+ public TProtocol GetProtocol(TTransport trans)
+ {
+ return new TCompactProtocol(trans);
+ }
+ }
+
+ #endregion
+
+ public TCompactProtocol(TTransport trans)
+ : base(trans)
+ {
+ ttypeToCompactType[(int)TType.Stop] = Types.STOP;
+ ttypeToCompactType[(int)TType.Bool] = Types.BOOLEAN_TRUE;
+ ttypeToCompactType[(int)TType.Byte] = Types.BYTE;
+ ttypeToCompactType[(int)TType.I16] = Types.I16;
+ ttypeToCompactType[(int)TType.I32] = Types.I32;
+ ttypeToCompactType[(int)TType.I64] = Types.I64;
+ ttypeToCompactType[(int)TType.Double] = Types.DOUBLE;
+ ttypeToCompactType[(int)TType.String] = Types.BINARY;
+ ttypeToCompactType[(int)TType.List] = Types.LIST;
+ ttypeToCompactType[(int)TType.Set] = Types.SET;
+ ttypeToCompactType[(int)TType.Map] = Types.MAP;
+ ttypeToCompactType[(int)TType.Struct] = Types.STRUCT;
+ }
+
+ public void reset()
+ {
+ lastField_.Clear();
+ lastFieldId_ = 0;
+ }
+
+ #region Write Methods
+
+ /// <summary>
+ /// Writes a byte without any possibility of all that field header nonsense.
+ /// Used internally by other writing methods that know they need to Write a byte.
+ /// </summary>
+ private byte[] byteDirectBuffer = new byte[1];
+
+ private void WriteByteDirect(byte b)
+ {
+ byteDirectBuffer[0] = b;
+ trans.Write(byteDirectBuffer);
+ }
+
+ /// <summary>
+ /// Writes a byte without any possibility of all that field header nonsense.
+ /// </summary>
+ private void WriteByteDirect(int n)
+ {
+ WriteByteDirect((byte)n);
+ }
+
+ /// <summary>
+ /// Write an i32 as a varint. Results in 1-5 bytes on the wire.
+ /// TODO: make a permanent buffer like WriteVarint64?
+ /// </summary>
+ byte[] i32buf = new byte[5];
+
+ private void WriteVarint32(uint n)
+ {
+ int idx = 0;
+ while (true)
+ {
+ if ((n & ~0x7F) == 0)
+ {
+ i32buf[idx++] = (byte)n;
+ // WriteByteDirect((byte)n);
+ break;
+ // return;
+ }
+ else
+ {
+ i32buf[idx++] = (byte)((n & 0x7F) | 0x80);
+ // WriteByteDirect((byte)((n & 0x7F) | 0x80));
+ n >>= 7;
+ }
+ }
+ trans.Write(i32buf, 0, idx);
+ }
+
+ /// <summary>
+ /// Write a message header to the wire. Compact Protocol messages contain the
+ /// protocol version so we can migrate forwards in the future if need be.
+ /// </summary>
+ public override void WriteMessageBegin(TMessage message)
+ {
+ WriteByteDirect(PROTOCOL_ID);
+ WriteByteDirect((byte)((VERSION & VERSION_MASK) | ((((uint)message.Type) << TYPE_SHIFT_AMOUNT) & TYPE_MASK)));
+ WriteVarint32((uint)message.SeqID);
+ WriteString(message.Name);
+ }
+
+ /// <summary>
+ /// Write a struct begin. This doesn't actually put anything on the wire. We
+ /// use it as an opportunity to put special placeholder markers on the field
+ /// stack so we can get the field id deltas correct.
+ /// </summary>
+ public override void WriteStructBegin(TStruct strct)
+ {
+ lastField_.Push(lastFieldId_);
+ lastFieldId_ = 0;
+ }
+
+ /// <summary>
+ /// Write a struct end. This doesn't actually put anything on the wire. We use
+ /// this as an opportunity to pop the last field from the current struct off
+ /// of the field stack.
+ /// </summary>
+ public override void WriteStructEnd()
+ {
+ lastFieldId_ = lastField_.Pop();
+ }
+
+ /// <summary>
+ /// Write a field header containing the field id and field type. If the
+ /// difference between the current field id and the last one is small (&lt; 15),
+ /// then the field id will be encoded in the 4 MSB as a delta. Otherwise, the
+ /// field id will follow the type header as a zigzag varint.
+ /// </summary>
+ public override void WriteFieldBegin(TField field)
+ {
+ if (field.Type == TType.Bool)
+ {
+ // we want to possibly include the value, so we'll wait.
+ booleanField_ = field;
+ }
+ else
+ {
+ WriteFieldBeginInternal(field, 0xFF);
+ }
+ }
+
+ /// <summary>
+ /// The workhorse of WriteFieldBegin. It has the option of doing a
+ /// 'type override' of the type header. This is used specifically in the
+ /// boolean field case.
+ /// </summary>
+ private void WriteFieldBeginInternal(TField field, byte typeOverride)
+ {
+ // short lastField = lastField_.Pop();
+
+ // if there's a type override, use that.
+ byte typeToWrite = typeOverride == 0xFF ? getCompactType(field.Type) : typeOverride;
+
+ // check if we can use delta encoding for the field id
+ if (field.ID > lastFieldId_ && field.ID - lastFieldId_ <= 15)
+ {
+ // Write them together
+ WriteByteDirect((field.ID - lastFieldId_) << 4 | typeToWrite);
+ }
+ else
+ {
+ // Write them separate
+ WriteByteDirect(typeToWrite);
+ WriteI16(field.ID);
+ }
+
+ lastFieldId_ = field.ID;
+ // lastField_.push(field.id);
+ }
+
+ /// <summary>
+ /// Write the STOP symbol so we know there are no more fields in this struct.
+ /// </summary>
+ public override void WriteFieldStop()
+ {
+ WriteByteDirect(Types.STOP);
+ }
+
+ /// <summary>
+ /// Write a map header. If the map is empty, omit the key and value type
+ /// headers, as we don't need any additional information to skip it.
+ /// </summary>
+ public override void WriteMapBegin(TMap map)
+ {
+ if (map.Count == 0)
+ {
+ WriteByteDirect(0);
+ }
+ else
+ {
+ WriteVarint32((uint)map.Count);
+ WriteByteDirect(getCompactType(map.KeyType) << 4 | getCompactType(map.ValueType));
+ }
+ }
+
+ /// <summary>
+ /// Write a list header.
+ /// </summary>
+ public override void WriteListBegin(TList list)
+ {
+ WriteCollectionBegin(list.ElementType, list.Count);
+ }
+
+ /// <summary>
+ /// Write a set header.
+ /// </summary>
+ public override void WriteSetBegin(TSet set)
+ {
+ WriteCollectionBegin(set.ElementType, set.Count);
+ }
+
+ /// <summary>
+ /// Write a boolean value. Potentially, this could be a boolean field, in
+ /// which case the field header info isn't written yet. If so, decide what the
+ /// right type header is for the value and then Write the field header.
+ /// Otherwise, Write a single byte.
+ /// </summary>
+ public override void WriteBool(Boolean b)
+ {
+ if (booleanField_ != null)
+ {
+ // we haven't written the field header yet
+ WriteFieldBeginInternal(booleanField_.Value, b ? Types.BOOLEAN_TRUE : Types.BOOLEAN_FALSE);
+ booleanField_ = null;
+ }
+ else
+ {
+ // we're not part of a field, so just Write the value.
+ WriteByteDirect(b ? Types.BOOLEAN_TRUE : Types.BOOLEAN_FALSE);
+ }
+ }
+
+ /// <summary>
+ /// Write a byte. Nothing to see here!
+ /// </summary>
+ public override void WriteByte(sbyte b)
+ {
+ WriteByteDirect((byte)b);
+ }
+
+ /// <summary>
+ /// Write an I16 as a zigzag varint.
+ /// </summary>
+ public override void WriteI16(short i16)
+ {
+ WriteVarint32(intToZigZag(i16));
+ }
+
+ /// <summary>
+ /// Write an i32 as a zigzag varint.
+ /// </summary>
+ public override void WriteI32(int i32)
+ {
+ WriteVarint32(intToZigZag(i32));
+ }
+
+ /// <summary>
+ /// Write an i64 as a zigzag varint.
+ /// </summary>
+ public override void WriteI64(long i64)
+ {
+ WriteVarint64(longToZigzag(i64));
+ }
+
+ /// <summary>
+ /// Write a double to the wire as 8 bytes.
+ /// </summary>
+ public override void WriteDouble(double dub)
+ {
+ byte[] data = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
+ fixedLongToBytes(BitConverter.DoubleToInt64Bits(dub), data, 0);
+ trans.Write(data);
+ }
+
+ /// <summary>
+ /// Write a string to the wire with a varint size preceding.
+ /// </summary>
+ public override void WriteString(string str)
+ {
+ byte[] bytes = UTF8Encoding.UTF8.GetBytes(str);
+ WriteBinary(bytes, 0, bytes.Length);
+ }
+
+ /// <summary>
+ /// Write a byte array, using a varint for the size.
+ /// </summary>
+ public override void WriteBinary(byte[] bin)
+ {
+ WriteBinary(bin, 0, bin.Length);
+ }
+
+ private void WriteBinary(byte[] buf, int offset, int length)
+ {
+ WriteVarint32((uint)length);
+ trans.Write(buf, offset, length);
+ }
+
+ //
+ // These methods are called by structs, but don't actually have any wire
+ // output or purpose.
+ //
+
+ public override void WriteMessageEnd() { }
+ public override void WriteMapEnd() { }
+ public override void WriteListEnd() { }
+ public override void WriteSetEnd() { }
+ public override void WriteFieldEnd() { }
+
+ //
+ // Internal writing methods
+ //
+
+ /// <summary>
+ /// Abstract method for writing the start of lists and sets. List and sets on
+ /// the wire differ only by the type indicator.
+ /// </summary>
+ protected void WriteCollectionBegin(TType elemType, int size)
+ {
+ if (size <= 14)
+ {
+ WriteByteDirect(size << 4 | getCompactType(elemType));
+ }
+ else
+ {
+ WriteByteDirect(0xf0 | getCompactType(elemType));
+ WriteVarint32((uint)size);
+ }
+ }
+
+ /// <summary>
+ /// Write an i64 as a varint. Results in 1-10 bytes on the wire.
+ /// </summary>
+ byte[] varint64out = new byte[10];
+ private void WriteVarint64(ulong n)
+ {
+ int idx = 0;
+ while (true)
+ {
+ if ((n & ~(ulong)0x7FL) == 0)
+ {
+ varint64out[idx++] = (byte)n;
+ break;
+ }
+ else
+ {
+ varint64out[idx++] = ((byte)((n & 0x7F) | 0x80));
+ n >>= 7;
+ }
+ }
+ trans.Write(varint64out, 0, idx);
+ }
+
+ /// <summary>
+ /// Convert l into a zigzag long. This allows negative numbers to be
+ /// represented compactly as a varint.
+ /// </summary>
+ private ulong longToZigzag(long n)
+ {
+ return (ulong)(n << 1) ^ (ulong)(n >> 63);
+ }
+
+ /// <summary>
+ /// Convert n into a zigzag int. This allows negative numbers to be
+ /// represented compactly as a varint.
+ /// </summary>
+ private uint intToZigZag(int n)
+ {
+ return (uint)(n << 1) ^ (uint)(n >> 31);
+ }
+
+ /// <summary>
+ /// Convert a long into little-endian bytes in buf starting at off and going
+ /// until off+7.
+ /// </summary>
+ private void fixedLongToBytes(long n, byte[] buf, int off)
+ {
+ buf[off + 0] = (byte)(n & 0xff);
+ buf[off + 1] = (byte)((n >> 8) & 0xff);
+ buf[off + 2] = (byte)((n >> 16) & 0xff);
+ buf[off + 3] = (byte)((n >> 24) & 0xff);
+ buf[off + 4] = (byte)((n >> 32) & 0xff);
+ buf[off + 5] = (byte)((n >> 40) & 0xff);
+ buf[off + 6] = (byte)((n >> 48) & 0xff);
+ buf[off + 7] = (byte)((n >> 56) & 0xff);
+ }
+
+ #endregion
+
+ #region ReadMethods
+
+ /// <summary>
+ /// Read a message header.
+ /// </summary>
+ public override TMessage ReadMessageBegin()
+ {
+ byte protocolId = (byte)ReadByte();
+ if (protocolId != PROTOCOL_ID)
+ {
+ throw new TProtocolException("Expected protocol id " + PROTOCOL_ID.ToString("X") + " but got " + protocolId.ToString("X"));
+ }
+ byte versionAndType = (byte)ReadByte();
+ byte version = (byte)(versionAndType & VERSION_MASK);
+ if (version != VERSION)
+ {
+ throw new TProtocolException("Expected version " + VERSION + " but got " + version);
+ }
+ byte type = (byte)((versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS);
+ int seqid = (int)ReadVarint32();
+ string messageName = ReadString();
+ return new TMessage(messageName, (TMessageType)type, seqid);
+ }
+
+ /// <summary>
+ /// Read a struct begin. There's nothing on the wire for this, but it is our
+ /// opportunity to push a new struct begin marker onto the field stack.
+ /// </summary>
+ public override TStruct ReadStructBegin()
+ {
+ lastField_.Push(lastFieldId_);
+ lastFieldId_ = 0;
+ return ANONYMOUS_STRUCT;
+ }
+
+ /// <summary>
+ /// Doesn't actually consume any wire data, just removes the last field for
+ /// this struct from the field stack.
+ /// </summary>
+ public override void ReadStructEnd()
+ {
+ // consume the last field we Read off the wire.
+ lastFieldId_ = lastField_.Pop();
+ }
+
+ /// <summary>
+ /// Read a field header off the wire.
+ /// </summary>
+ public override TField ReadFieldBegin()
+ {
+ byte type = (byte)ReadByte();
+
+ // if it's a stop, then we can return immediately, as the struct is over.
+ if (type == Types.STOP)
+ {
+ return TSTOP;
+ }
+
+ short fieldId;
+
+ // mask off the 4 MSB of the type header. it could contain a field id delta.
+ short modifier = (short)((type & 0xf0) >> 4);
+ if (modifier == 0)
+ {
+ // not a delta. look ahead for the zigzag varint field id.
+ fieldId = ReadI16();
+ }
+ else
+ {
+ // has a delta. add the delta to the last Read field id.
+ fieldId = (short)(lastFieldId_ + modifier);
+ }
+
+ TField field = new TField("", getTType((byte)(type & 0x0f)), fieldId);
+
+ // if this happens to be a boolean field, the value is encoded in the type
+ if (isBoolType(type))
+ {
+ // save the boolean value in a special instance variable.
+ boolValue_ = (byte)(type & 0x0f) == Types.BOOLEAN_TRUE ? true : false;
+ }
+
+ // push the new field onto the field stack so we can keep the deltas going.
+ lastFieldId_ = field.ID;
+ return field;
+ }
+
+ /// <summary>
+ /// Read a map header off the wire. If the size is zero, skip Reading the key
+ /// and value type. This means that 0-length maps will yield TMaps without the
+ /// "correct" types.
+ /// </summary>
+ public override TMap ReadMapBegin()
+ {
+ int size = (int)ReadVarint32();
+ byte keyAndValueType = size == 0 ? (byte)0 : (byte)ReadByte();
+ return new TMap(getTType((byte)(keyAndValueType >> 4)), getTType((byte)(keyAndValueType & 0xf)), size);
+ }
+
+ /// <summary>
+ /// Read a list header off the wire. If the list size is 0-14, the size will
+ /// be packed into the element type header. If it's a longer list, the 4 MSB
+ /// of the element type header will be 0xF, and a varint will follow with the
+ /// true size.
+ /// </summary>
+ public override TList ReadListBegin()
+ {
+ byte size_and_type = (byte)ReadByte();
+ int size = (size_and_type >> 4) & 0x0f;
+ if (size == 15)
+ {
+ size = (int)ReadVarint32();
+ }
+ TType type = getTType(size_and_type);
+ return new TList(type, size);
+ }
+
+ /// <summary>
+ /// Read a set header off the wire. If the set size is 0-14, the size will
+ /// be packed into the element type header. If it's a longer set, the 4 MSB
+ /// of the element type header will be 0xF, and a varint will follow with the
+ /// true size.
+ /// </summary>
+ public override TSet ReadSetBegin()
+ {
+ return new TSet(ReadListBegin());
+ }
+
+ /// <summary>
+ /// Read a boolean off the wire. If this is a boolean field, the value should
+ /// already have been Read during ReadFieldBegin, so we'll just consume the
+ /// pre-stored value. Otherwise, Read a byte.
+ /// </summary>
+ public override Boolean ReadBool()
+ {
+ if (boolValue_ != null)
+ {
+ bool result = boolValue_.Value;
+ boolValue_ = null;
+ return result;
+ }
+ return ReadByte() == Types.BOOLEAN_TRUE;
+ }
+
+ byte[] byteRawBuf = new byte[1];
+ /// <summary>
+ /// Read a single byte off the wire. Nothing interesting here.
+ /// </summary>
+ public override sbyte ReadByte()
+ {
+ trans.ReadAll(byteRawBuf, 0, 1);
+ return (sbyte)byteRawBuf[0];
+ }
+
+ /// <summary>
+ /// Read an i16 from the wire as a zigzag varint.
+ /// </summary>
+ public override short ReadI16()
+ {
+ return (short)zigzagToInt(ReadVarint32());
+ }
+
+ /// <summary>
+ /// Read an i32 from the wire as a zigzag varint.
+ /// </summary>
+ public override int ReadI32()
+ {
+ return zigzagToInt(ReadVarint32());
+ }
+
+ /// <summary>
+ /// Read an i64 from the wire as a zigzag varint.
+ /// </summary>
+ public override long ReadI64()
+ {
+ return zigzagToLong(ReadVarint64());
+ }
+
+ /// <summary>
+ /// No magic here - just Read a double off the wire.
+ /// </summary>
+ public override double ReadDouble()
+ {
+ byte[] longBits = new byte[8];
+ trans.ReadAll(longBits, 0, 8);
+ return BitConverter.Int64BitsToDouble(bytesToLong(longBits));
+ }
+
+ /// <summary>
+ /// Reads a byte[] (via ReadBinary), and then UTF-8 decodes it.
+ /// </summary>
+ public override string ReadString()
+ {
+ int length = (int)ReadVarint32();
+
+ if (length == 0)
+ {
+ return "";
+ }
+
+ return Encoding.UTF8.GetString(ReadBinary(length));
+ }
+
+ /// <summary>
+ /// Read a byte[] from the wire.
+ /// </summary>
+ public override byte[] ReadBinary()
+ {
+ int length = (int)ReadVarint32();
+ if (length == 0) return new byte[0];
+
+ byte[] buf = new byte[length];
+ trans.ReadAll(buf, 0, length);
+ return buf;
+ }
+
+ /// <summary>
+ /// Read a byte[] of a known length from the wire.
+ /// </summary>
+ private byte[] ReadBinary(int length)
+ {
+ if (length == 0) return new byte[0];
+
+ byte[] buf = new byte[length];
+ trans.ReadAll(buf, 0, length);
+ return buf;
+ }
+
+ //
+ // These methods are here for the struct to call, but don't have any wire
+ // encoding.
+ //
+ public override void ReadMessageEnd() { }
+ public override void ReadFieldEnd() { }
+ public override void ReadMapEnd() { }
+ public override void ReadListEnd() { }
+ public override void ReadSetEnd() { }
+
+ //
+ // Internal Reading methods
+ //
+
+ /// <summary>
+ /// Read an i32 from the wire as a varint. The MSB of each byte is set
+ /// if there is another byte to follow. This can Read up to 5 bytes.
+ /// </summary>
+ private uint ReadVarint32()
+ {
+ uint result = 0;
+ int shift = 0;
+ while (true)
+ {
+ byte b = (byte)ReadByte();
+ result |= (uint)(b & 0x7f) << shift;
+ if ((b & 0x80) != 0x80) break;
+ shift += 7;
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Read an i64 from the wire as a proper varint. The MSB of each byte is set
+ /// if there is another byte to follow. This can Read up to 10 bytes.
+ /// </summary>
+ private ulong ReadVarint64()
+ {
+ int shift = 0;
+ ulong result = 0;
+ while (true)
+ {
+ byte b = (byte)ReadByte();
+ result |= (ulong)(b & 0x7f) << shift;
+ if ((b & 0x80) != 0x80) break;
+ shift += 7;
+ }
+
+ return result;
+ }
+
+ #endregion
+
+ //
+ // encoding helpers
+ //
+
+ /// <summary>
+ /// Convert from zigzag int to int.
+ /// </summary>
+ private int zigzagToInt(uint n)
+ {
+ return (int)(n >> 1) ^ (-(int)(n & 1));
+ }
+
+ /// <summary>
+ /// Convert from zigzag long to long.
+ /// </summary>
+ private long zigzagToLong(ulong n)
+ {
+ return (long)(n >> 1) ^ (-(long)(n & 1));
+ }
+
+ /// <summary>
+ /// Note that it's important that the mask bytes are long literals,
+ /// otherwise they'll default to ints, and when you shift an int left 56 bits,
+ /// you just get a messed up int.
+ /// </summary>
+ private long bytesToLong(byte[] bytes)
+ {
+ return
+ ((bytes[7] & 0xffL) << 56) |
+ ((bytes[6] & 0xffL) << 48) |
+ ((bytes[5] & 0xffL) << 40) |
+ ((bytes[4] & 0xffL) << 32) |
+ ((bytes[3] & 0xffL) << 24) |
+ ((bytes[2] & 0xffL) << 16) |
+ ((bytes[1] & 0xffL) << 8) |
+ ((bytes[0] & 0xffL));
+ }
+
+ //
+ // type testing and converting
+ //
+
+ private Boolean isBoolType(byte b)
+ {
+ int lowerNibble = b & 0x0f;
+ return lowerNibble == Types.BOOLEAN_TRUE || lowerNibble == Types.BOOLEAN_FALSE;
+ }
+
+ /// <summary>
+ /// Given a TCompactProtocol.Types constant, convert it to its corresponding
+ /// TType value.
+ /// </summary>
+ private TType getTType(byte type)
+ {
+ switch ((byte)(type & 0x0f))
+ {
+ case Types.STOP:
+ return TType.Stop;
+ case Types.BOOLEAN_FALSE:
+ case Types.BOOLEAN_TRUE:
+ return TType.Bool;
+ case Types.BYTE:
+ return TType.Byte;
+ case Types.I16:
+ return TType.I16;
+ case Types.I32:
+ return TType.I32;
+ case Types.I64:
+ return TType.I64;
+ case Types.DOUBLE:
+ return TType.Double;
+ case Types.BINARY:
+ return TType.String;
+ case Types.LIST:
+ return TType.List;
+ case Types.SET:
+ return TType.Set;
+ case Types.MAP:
+ return TType.Map;
+ case Types.STRUCT:
+ return TType.Struct;
+ default:
+ throw new TProtocolException("don't know what type: " + (byte)(type & 0x0f));
+ }
+ }
+
+ /// <summary>
+ /// Given a TType value, find the appropriate TCompactProtocol.Types constant.
+ /// </summary>
+ private byte getCompactType(TType ttype)
+ {
+ return ttypeToCompactType[(int)ttype];
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Protocol/TField.cs b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TField.cs
new file mode 100644
index 000000000..81795577e
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TField.cs
@@ -0,0 +1,62 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Thrift.Protocol
+{
+ public struct TField
+ {
+ private string name;
+ private TType type;
+ private short id;
+
+ public TField(string name, TType type, short id)
+ :this()
+ {
+ this.name = name;
+ this.type = type;
+ this.id = id;
+ }
+
+ public string Name
+ {
+ get { return name; }
+ set { name = value; }
+ }
+
+ public TType Type
+ {
+ get { return type; }
+ set { type = value; }
+ }
+
+ public short ID
+ {
+ get { return id; }
+ set { id = value; }
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Protocol/TJSONProtocol.cs b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TJSONProtocol.cs
new file mode 100644
index 000000000..9dbdea9aa
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TJSONProtocol.cs
@@ -0,0 +1,1124 @@
+/**
+ * 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;
+using System.IO;
+using System.Text;
+using System.Collections.Generic;
+
+using Thrift.Transport;
+using System.Globalization;
+
+namespace Thrift.Protocol
+{
+ /// <summary>
+ /// JSON protocol implementation for thrift.
+ /// <para/>
+ /// This is a full-featured protocol supporting Write and Read.
+ /// <para/>
+ /// Please see the C++ class header for a detailed description of the
+ /// protocol's wire format.
+ /// <para/>
+ /// Adapted from the Java version.
+ /// </summary>
+ public class TJSONProtocol : TProtocol
+ {
+ /// <summary>
+ /// Factory for JSON protocol objects.
+ /// </summary>
+ public class Factory : TProtocolFactory
+ {
+ public TProtocol GetProtocol(TTransport trans)
+ {
+ return new TJSONProtocol(trans);
+ }
+ }
+
+ private static byte[] COMMA = new byte[] { (byte)',' };
+ private static byte[] COLON = new byte[] { (byte)':' };
+ private static byte[] LBRACE = new byte[] { (byte)'{' };
+ private static byte[] RBRACE = new byte[] { (byte)'}' };
+ private static byte[] LBRACKET = new byte[] { (byte)'[' };
+ private static byte[] RBRACKET = new byte[] { (byte)']' };
+ private static byte[] QUOTE = new byte[] { (byte)'"' };
+ private static byte[] BACKSLASH = new byte[] { (byte)'\\' };
+
+ private byte[] ESCSEQ = new byte[] { (byte)'\\', (byte)'u', (byte)'0', (byte)'0' };
+
+ private const long VERSION = 1;
+ private byte[] JSON_CHAR_TABLE = {
+ 0, 0, 0, 0, 0, 0, 0, 0,(byte)'b',(byte)'t',(byte)'n', 0,(byte)'f',(byte)'r', 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1,(byte)'"', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ };
+
+ private char[] ESCAPE_CHARS = "\"\\/bfnrt".ToCharArray();
+
+ private byte[] ESCAPE_CHAR_VALS = {
+ (byte)'"', (byte)'\\', (byte)'/', (byte)'\b', (byte)'\f', (byte)'\n', (byte)'\r', (byte)'\t',
+ };
+
+ private const int DEF_STRING_SIZE = 16;
+
+ private static byte[] NAME_BOOL = new byte[] { (byte)'t', (byte)'f' };
+ private static byte[] NAME_BYTE = new byte[] { (byte)'i', (byte)'8' };
+ private static byte[] NAME_I16 = new byte[] { (byte)'i', (byte)'1', (byte)'6' };
+ private static byte[] NAME_I32 = new byte[] { (byte)'i', (byte)'3', (byte)'2' };
+ private static byte[] NAME_I64 = new byte[] { (byte)'i', (byte)'6', (byte)'4' };
+ private static byte[] NAME_DOUBLE = new byte[] { (byte)'d', (byte)'b', (byte)'l' };
+ private static byte[] NAME_STRUCT = new byte[] { (byte)'r', (byte)'e', (byte)'c' };
+ private static byte[] NAME_STRING = new byte[] { (byte)'s', (byte)'t', (byte)'r' };
+ private static byte[] NAME_MAP = new byte[] { (byte)'m', (byte)'a', (byte)'p' };
+ private static byte[] NAME_LIST = new byte[] { (byte)'l', (byte)'s', (byte)'t' };
+ private static byte[] NAME_SET = new byte[] { (byte)'s', (byte)'e', (byte)'t' };
+
+ private static byte[] GetTypeNameForTypeID(TType typeID)
+ {
+ switch (typeID)
+ {
+ case TType.Bool:
+ return NAME_BOOL;
+ case TType.Byte:
+ return NAME_BYTE;
+ case TType.I16:
+ return NAME_I16;
+ case TType.I32:
+ return NAME_I32;
+ case TType.I64:
+ return NAME_I64;
+ case TType.Double:
+ return NAME_DOUBLE;
+ case TType.String:
+ return NAME_STRING;
+ case TType.Struct:
+ return NAME_STRUCT;
+ case TType.Map:
+ return NAME_MAP;
+ case TType.Set:
+ return NAME_SET;
+ case TType.List:
+ return NAME_LIST;
+ default:
+ throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED,
+ "Unrecognized type");
+ }
+ }
+
+ private static TType GetTypeIDForTypeName(byte[] name)
+ {
+ TType result = TType.Stop;
+ if (name.Length > 1)
+ {
+ switch (name[0])
+ {
+ case (byte)'d':
+ result = TType.Double;
+ break;
+ case (byte)'i':
+ switch (name[1])
+ {
+ case (byte)'8':
+ result = TType.Byte;
+ break;
+ case (byte)'1':
+ result = TType.I16;
+ break;
+ case (byte)'3':
+ result = TType.I32;
+ break;
+ case (byte)'6':
+ result = TType.I64;
+ break;
+ }
+ break;
+ case (byte)'l':
+ result = TType.List;
+ break;
+ case (byte)'m':
+ result = TType.Map;
+ break;
+ case (byte)'r':
+ result = TType.Struct;
+ break;
+ case (byte)'s':
+ if (name[1] == (byte)'t')
+ {
+ result = TType.String;
+ }
+ else if (name[1] == (byte)'e')
+ {
+ result = TType.Set;
+ }
+ break;
+ case (byte)'t':
+ result = TType.Bool;
+ break;
+ }
+ }
+ if (result == TType.Stop)
+ {
+ throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED,
+ "Unrecognized type");
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Base class for tracking JSON contexts that may require
+ /// inserting/Reading additional JSON syntax characters
+ /// This base context does nothing.
+ /// </summary>
+ protected class JSONBaseContext
+ {
+ protected TJSONProtocol proto;
+
+ public JSONBaseContext(TJSONProtocol proto)
+ {
+ this.proto = proto;
+ }
+
+ public virtual void Write() { }
+
+ public virtual void Read() { }
+
+ public virtual bool EscapeNumbers() { return false; }
+ }
+
+ /// <summary>
+ /// Context for JSON lists. Will insert/Read commas before each item except
+ /// for the first one
+ /// </summary>
+ protected class JSONListContext : JSONBaseContext
+ {
+ public JSONListContext(TJSONProtocol protocol)
+ : base(protocol)
+ {
+
+ }
+
+ private bool first = true;
+
+ public override void Write()
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ proto.trans.Write(COMMA);
+ }
+ }
+
+ public override void Read()
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ proto.ReadJSONSyntaxChar(COMMA);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Context for JSON records. Will insert/Read colons before the value portion
+ /// of each record pair, and commas before each key except the first. In
+ /// addition, will indicate that numbers in the key position need to be
+ /// escaped in quotes (since JSON keys must be strings).
+ /// </summary>
+ protected class JSONPairContext : JSONBaseContext
+ {
+ public JSONPairContext(TJSONProtocol proto)
+ : base(proto)
+ {
+
+ }
+
+ private bool first = true;
+ private bool colon = true;
+
+ public override void Write()
+ {
+ if (first)
+ {
+ first = false;
+ colon = true;
+ }
+ else
+ {
+ proto.trans.Write(colon ? COLON : COMMA);
+ colon = !colon;
+ }
+ }
+
+ public override void Read()
+ {
+ if (first)
+ {
+ first = false;
+ colon = true;
+ }
+ else
+ {
+ proto.ReadJSONSyntaxChar(colon ? COLON : COMMA);
+ colon = !colon;
+ }
+ }
+
+ public override bool EscapeNumbers()
+ {
+ return colon;
+ }
+ }
+
+ /// <summary>
+ /// Holds up to one byte from the transport
+ /// </summary>
+ protected class LookaheadReader
+ {
+ protected TJSONProtocol proto;
+
+ public LookaheadReader(TJSONProtocol proto)
+ {
+ this.proto = proto;
+ }
+
+ private bool hasData;
+ private byte[] data = new byte[1];
+
+ /// <summary>
+ /// Return and consume the next byte to be Read, either taking it from the
+ /// data buffer if present or getting it from the transport otherwise.
+ /// </summary>
+ public byte Read()
+ {
+ if (hasData)
+ {
+ hasData = false;
+ }
+ else
+ {
+ proto.trans.ReadAll(data, 0, 1);
+ }
+ return data[0];
+ }
+
+ /// <summary>
+ /// Return the next byte to be Read without consuming, filling the data
+ /// buffer if it has not been filled alReady.
+ /// </summary>
+ public byte Peek()
+ {
+ if (!hasData)
+ {
+ proto.trans.ReadAll(data, 0, 1);
+ }
+ hasData = true;
+ return data[0];
+ }
+ }
+
+ // Default encoding
+ protected Encoding utf8Encoding = UTF8Encoding.UTF8;
+
+ // Stack of nested contexts that we may be in
+ protected Stack<JSONBaseContext> contextStack = new Stack<JSONBaseContext>();
+
+ // Current context that we are in
+ protected JSONBaseContext context;
+
+ // Reader that manages a 1-byte buffer
+ protected LookaheadReader reader;
+
+ /// <summary>
+ /// Push a new JSON context onto the stack.
+ /// </summary>
+ protected void PushContext(JSONBaseContext c)
+ {
+ contextStack.Push(context);
+ context = c;
+ }
+
+ /// <summary>
+ /// Pop the last JSON context off the stack
+ /// </summary>
+ protected void PopContext()
+ {
+ context = contextStack.Pop();
+ }
+
+ /// <summary>
+ /// TJSONProtocol Constructor
+ /// </summary>
+ public TJSONProtocol(TTransport trans)
+ : base(trans)
+ {
+ context = new JSONBaseContext(this);
+ reader = new LookaheadReader(this);
+ }
+
+ // Temporary buffer used by several methods
+ private byte[] tempBuffer = new byte[4];
+
+ /// <summary>
+ /// Read a byte that must match b[0]; otherwise an exception is thrown.
+ /// Marked protected to avoid synthetic accessor in JSONListContext.Read
+ /// and JSONPairContext.Read
+ /// </summary>
+ protected void ReadJSONSyntaxChar(byte[] b)
+ {
+ byte ch = reader.Read();
+ if (ch != b[0])
+ {
+ throw new TProtocolException(TProtocolException.INVALID_DATA,
+ "Unexpected character:" + (char)ch);
+ }
+ }
+
+ /// <summary>
+ /// Convert a byte containing a hex char ('0'-'9' or 'a'-'f') into its
+ /// corresponding hex value
+ /// </summary>
+ private static byte HexVal(byte ch)
+ {
+ if ((ch >= '0') && (ch <= '9'))
+ {
+ return (byte)((char)ch - '0');
+ }
+ else if ((ch >= 'a') && (ch <= 'f'))
+ {
+ ch += 10;
+ return (byte)((char)ch - 'a');
+ }
+ else
+ {
+ throw new TProtocolException(TProtocolException.INVALID_DATA,
+ "Expected hex character");
+ }
+ }
+
+ /// <summary>
+ /// Convert a byte containing a hex value to its corresponding hex character
+ /// </summary>
+ private static byte HexChar(byte val)
+ {
+ val &= 0x0F;
+ if (val < 10)
+ {
+ return (byte)((char)val + '0');
+ }
+ else
+ {
+ val -= 10;
+ return (byte)((char)val + 'a');
+ }
+ }
+
+ /// <summary>
+ /// Write the bytes in array buf as a JSON characters, escaping as needed
+ /// </summary>
+ private void WriteJSONString(byte[] b)
+ {
+ context.Write();
+ trans.Write(QUOTE);
+ int len = b.Length;
+ for (int i = 0; i < len; i++)
+ {
+ if ((b[i] & 0x00FF) >= 0x30)
+ {
+ if (b[i] == BACKSLASH[0])
+ {
+ trans.Write(BACKSLASH);
+ trans.Write(BACKSLASH);
+ }
+ else
+ {
+ trans.Write(b, i, 1);
+ }
+ }
+ else
+ {
+ tempBuffer[0] = JSON_CHAR_TABLE[b[i]];
+ if (tempBuffer[0] == 1)
+ {
+ trans.Write(b, i, 1);
+ }
+ else if (tempBuffer[0] > 1)
+ {
+ trans.Write(BACKSLASH);
+ trans.Write(tempBuffer, 0, 1);
+ }
+ else
+ {
+ trans.Write(ESCSEQ);
+ tempBuffer[0] = HexChar((byte)(b[i] >> 4));
+ tempBuffer[1] = HexChar(b[i]);
+ trans.Write(tempBuffer, 0, 2);
+ }
+ }
+ }
+ trans.Write(QUOTE);
+ }
+
+ /// <summary>
+ /// Write out number as a JSON value. If the context dictates so, it will be
+ /// wrapped in quotes to output as a JSON string.
+ /// </summary>
+ private void WriteJSONInteger(long num)
+ {
+ context.Write();
+ string str = num.ToString();
+
+ bool escapeNum = context.EscapeNumbers();
+ if (escapeNum)
+ trans.Write(QUOTE);
+
+ trans.Write(utf8Encoding.GetBytes(str));
+
+ if (escapeNum)
+ trans.Write(QUOTE);
+ }
+
+ /// <summary>
+ /// Write out a double as a JSON value. If it is NaN or infinity or if the
+ /// context dictates escaping, Write out as JSON string.
+ /// </summary>
+ private void WriteJSONDouble(double num)
+ {
+ context.Write();
+ string str = num.ToString("G17", CultureInfo.InvariantCulture);
+ bool special = false;
+
+ switch (str[0])
+ {
+ case 'N': // NaN
+ case 'I': // Infinity
+ special = true;
+ break;
+ case '-':
+ if (str[1] == 'I')
+ { // -Infinity
+ special = true;
+ }
+ break;
+ }
+
+ bool escapeNum = special || context.EscapeNumbers();
+
+ if (escapeNum)
+ trans.Write(QUOTE);
+
+ trans.Write(utf8Encoding.GetBytes(str));
+
+ if (escapeNum)
+ trans.Write(QUOTE);
+ }
+ /// <summary>
+ /// Write out contents of byte array b as a JSON string with base-64 encoded
+ /// data
+ /// </summary>
+ private void WriteJSONBase64(byte[] b)
+ {
+ context.Write();
+ trans.Write(QUOTE);
+
+ int len = b.Length;
+ int off = 0;
+
+ while (len >= 3)
+ {
+ // Encode 3 bytes at a time
+ TBase64Utils.encode(b, off, 3, tempBuffer, 0);
+ trans.Write(tempBuffer, 0, 4);
+ off += 3;
+ len -= 3;
+ }
+ if (len > 0)
+ {
+ // Encode remainder
+ TBase64Utils.encode(b, off, len, tempBuffer, 0);
+ trans.Write(tempBuffer, 0, len + 1);
+ }
+
+ trans.Write(QUOTE);
+ }
+
+ private void WriteJSONObjectStart()
+ {
+ context.Write();
+ trans.Write(LBRACE);
+ PushContext(new JSONPairContext(this));
+ }
+
+ private void WriteJSONObjectEnd()
+ {
+ PopContext();
+ trans.Write(RBRACE);
+ }
+
+ private void WriteJSONArrayStart()
+ {
+ context.Write();
+ trans.Write(LBRACKET);
+ PushContext(new JSONListContext(this));
+ }
+
+ private void WriteJSONArrayEnd()
+ {
+ PopContext();
+ trans.Write(RBRACKET);
+ }
+
+ public override void WriteMessageBegin(TMessage message)
+ {
+ WriteJSONArrayStart();
+ WriteJSONInteger(VERSION);
+
+ byte[] b = utf8Encoding.GetBytes(message.Name);
+ WriteJSONString(b);
+
+ WriteJSONInteger((long)message.Type);
+ WriteJSONInteger(message.SeqID);
+ }
+
+ public override void WriteMessageEnd()
+ {
+ WriteJSONArrayEnd();
+ }
+
+ public override void WriteStructBegin(TStruct str)
+ {
+ WriteJSONObjectStart();
+ }
+
+ public override void WriteStructEnd()
+ {
+ WriteJSONObjectEnd();
+ }
+
+ public override void WriteFieldBegin(TField field)
+ {
+ WriteJSONInteger(field.ID);
+ WriteJSONObjectStart();
+ WriteJSONString(GetTypeNameForTypeID(field.Type));
+ }
+
+ public override void WriteFieldEnd()
+ {
+ WriteJSONObjectEnd();
+ }
+
+ public override void WriteFieldStop() { }
+
+ public override void WriteMapBegin(TMap map)
+ {
+ WriteJSONArrayStart();
+ WriteJSONString(GetTypeNameForTypeID(map.KeyType));
+ WriteJSONString(GetTypeNameForTypeID(map.ValueType));
+ WriteJSONInteger(map.Count);
+ WriteJSONObjectStart();
+ }
+
+ public override void WriteMapEnd()
+ {
+ WriteJSONObjectEnd();
+ WriteJSONArrayEnd();
+ }
+
+ public override void WriteListBegin(TList list)
+ {
+ WriteJSONArrayStart();
+ WriteJSONString(GetTypeNameForTypeID(list.ElementType));
+ WriteJSONInteger(list.Count);
+ }
+
+ public override void WriteListEnd()
+ {
+ WriteJSONArrayEnd();
+ }
+
+ public override void WriteSetBegin(TSet set)
+ {
+ WriteJSONArrayStart();
+ WriteJSONString(GetTypeNameForTypeID(set.ElementType));
+ WriteJSONInteger(set.Count);
+ }
+
+ public override void WriteSetEnd()
+ {
+ WriteJSONArrayEnd();
+ }
+
+ public override void WriteBool(bool b)
+ {
+ WriteJSONInteger(b ? (long)1 : (long)0);
+ }
+
+ public override void WriteByte(sbyte b)
+ {
+ WriteJSONInteger((long)b);
+ }
+
+ public override void WriteI16(short i16)
+ {
+ WriteJSONInteger((long)i16);
+ }
+
+ public override void WriteI32(int i32)
+ {
+ WriteJSONInteger((long)i32);
+ }
+
+ public override void WriteI64(long i64)
+ {
+ WriteJSONInteger(i64);
+ }
+
+ public override void WriteDouble(double dub)
+ {
+ WriteJSONDouble(dub);
+ }
+
+ public override void WriteString(string str)
+ {
+ byte[] b = utf8Encoding.GetBytes(str);
+ WriteJSONString(b);
+ }
+
+ public override void WriteBinary(byte[] bin)
+ {
+ WriteJSONBase64(bin);
+ }
+
+ /**
+ * Reading methods.
+ */
+
+ /// <summary>
+ /// Read in a JSON string, unescaping as appropriate.. Skip Reading from the
+ /// context if skipContext is true.
+ /// </summary>
+ private byte[] ReadJSONString(bool skipContext)
+ {
+ MemoryStream buffer = new MemoryStream();
+ List<char> codeunits = new List<char>();
+
+
+ if (!skipContext)
+ {
+ context.Read();
+ }
+ ReadJSONSyntaxChar(QUOTE);
+ while (true)
+ {
+ byte ch = reader.Read();
+ if (ch == QUOTE[0])
+ {
+ break;
+ }
+
+ // escaped?
+ if (ch != ESCSEQ[0])
+ {
+ buffer.Write(new byte[] { (byte)ch }, 0, 1);
+ continue;
+ }
+
+ // distinguish between \uXXXX and \?
+ ch = reader.Read();
+ if (ch != ESCSEQ[1]) // control chars like \n
+ {
+ int off = Array.IndexOf(ESCAPE_CHARS, (char)ch);
+ if (off == -1)
+ {
+ throw new TProtocolException(TProtocolException.INVALID_DATA,
+ "Expected control char");
+ }
+ ch = ESCAPE_CHAR_VALS[off];
+ buffer.Write(new byte[] { (byte)ch }, 0, 1);
+ continue;
+ }
+
+
+ // it's \uXXXX
+ trans.ReadAll(tempBuffer, 0, 4);
+ var wch = (short)((HexVal((byte)tempBuffer[0]) << 12) +
+ (HexVal((byte)tempBuffer[1]) << 8) +
+ (HexVal((byte)tempBuffer[2]) << 4) +
+ HexVal(tempBuffer[3]));
+ if (Char.IsHighSurrogate((char)wch))
+ {
+ if (codeunits.Count > 0)
+ {
+ throw new TProtocolException(TProtocolException.INVALID_DATA,
+ "Expected low surrogate char");
+ }
+ codeunits.Add((char)wch);
+ }
+ else if (Char.IsLowSurrogate((char)wch))
+ {
+ if (codeunits.Count == 0)
+ {
+ throw new TProtocolException(TProtocolException.INVALID_DATA,
+ "Expected high surrogate char");
+ }
+ codeunits.Add((char)wch);
+ var tmp = utf8Encoding.GetBytes(codeunits.ToArray());
+ buffer.Write(tmp, 0, tmp.Length);
+ codeunits.Clear();
+ }
+ else
+ {
+ var tmp = utf8Encoding.GetBytes(new char[] { (char)wch });
+ buffer.Write(tmp, 0, tmp.Length);
+ }
+ }
+
+
+ if (codeunits.Count > 0)
+ {
+ throw new TProtocolException(TProtocolException.INVALID_DATA,
+ "Expected low surrogate char");
+ }
+
+ return buffer.ToArray();
+ }
+
+ /// <summary>
+ /// Return true if the given byte could be a valid part of a JSON number.
+ /// </summary>
+ private bool IsJSONNumeric(byte b)
+ {
+ switch (b)
+ {
+ case (byte)'+':
+ case (byte)'-':
+ case (byte)'.':
+ case (byte)'0':
+ case (byte)'1':
+ case (byte)'2':
+ case (byte)'3':
+ case (byte)'4':
+ case (byte)'5':
+ case (byte)'6':
+ case (byte)'7':
+ case (byte)'8':
+ case (byte)'9':
+ case (byte)'E':
+ case (byte)'e':
+ return true;
+ }
+ return false;
+ }
+
+ /// <summary>
+ /// Read in a sequence of characters that are all valid in JSON numbers. Does
+ /// not do a complete regex check to validate that this is actually a number.
+ /// </summary>
+ private string ReadJSONNumericChars()
+ {
+ StringBuilder strbld = new StringBuilder();
+ while (true)
+ {
+ byte ch = reader.Peek();
+ if (!IsJSONNumeric(ch))
+ {
+ break;
+ }
+ strbld.Append((char)reader.Read());
+ }
+ return strbld.ToString();
+ }
+
+ /// <summary>
+ /// Read in a JSON number. If the context dictates, Read in enclosing quotes.
+ /// </summary>
+ private long ReadJSONInteger()
+ {
+ context.Read();
+ if (context.EscapeNumbers())
+ {
+ ReadJSONSyntaxChar(QUOTE);
+ }
+
+ string str = ReadJSONNumericChars();
+ if (context.EscapeNumbers())
+ {
+ ReadJSONSyntaxChar(QUOTE);
+ }
+
+ try
+ {
+ return Int64.Parse(str);
+ }
+ catch (FormatException fex)
+ {
+ throw new TProtocolException(TProtocolException.INVALID_DATA,
+ "Bad data encounted in numeric data", fex);
+ }
+ }
+
+ /// <summary>
+ /// Read in a JSON double value. Throw if the value is not wrapped in quotes
+ /// when expected or if wrapped in quotes when not expected.
+ /// </summary>
+ private double ReadJSONDouble()
+ {
+ context.Read();
+ if (reader.Peek() == QUOTE[0])
+ {
+ byte[] arr = ReadJSONString(true);
+ double dub = Double.Parse(utf8Encoding.GetString(arr, 0, arr.Length), CultureInfo.InvariantCulture);
+
+ if (!context.EscapeNumbers() && !Double.IsNaN(dub) && !Double.IsInfinity(dub))
+ {
+ // Throw exception -- we should not be in a string in this case
+ throw new TProtocolException(TProtocolException.INVALID_DATA,
+ "Numeric data unexpectedly quoted");
+ }
+ return dub;
+ }
+ else
+ {
+ if (context.EscapeNumbers())
+ {
+ // This will throw - we should have had a quote if escapeNum == true
+ ReadJSONSyntaxChar(QUOTE);
+ }
+ try
+ {
+ return Double.Parse(ReadJSONNumericChars(), CultureInfo.InvariantCulture);
+ }
+ catch (FormatException fex)
+ {
+ throw new TProtocolException(TProtocolException.INVALID_DATA,
+ "Bad data encounted in numeric data", fex);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Read in a JSON string containing base-64 encoded data and decode it.
+ /// </summary>
+ private byte[] ReadJSONBase64()
+ {
+ byte[] b = ReadJSONString(false);
+ int len = b.Length;
+ int off = 0;
+ int size = 0;
+ // reduce len to ignore fill bytes
+ while ((len > 0) && (b[len - 1] == '='))
+ {
+ --len;
+ }
+ // read & decode full byte triplets = 4 source bytes
+ while (len > 4)
+ {
+ // Decode 4 bytes at a time
+ TBase64Utils.decode(b, off, 4, b, size); // NB: decoded in place
+ off += 4;
+ len -= 4;
+ size += 3;
+ }
+ // Don't decode if we hit the end or got a single leftover byte (invalid
+ // base64 but legal for skip of regular string type)
+ if (len > 1)
+ {
+ // Decode remainder
+ TBase64Utils.decode(b, off, len, b, size); // NB: decoded in place
+ size += len - 1;
+ }
+ // Sadly we must copy the byte[] (any way around this?)
+ byte[] result = new byte[size];
+ Array.Copy(b, 0, result, 0, size);
+ return result;
+ }
+
+ private void ReadJSONObjectStart()
+ {
+ context.Read();
+ ReadJSONSyntaxChar(LBRACE);
+ PushContext(new JSONPairContext(this));
+ }
+
+ private void ReadJSONObjectEnd()
+ {
+ ReadJSONSyntaxChar(RBRACE);
+ PopContext();
+ }
+
+ private void ReadJSONArrayStart()
+ {
+ context.Read();
+ ReadJSONSyntaxChar(LBRACKET);
+ PushContext(new JSONListContext(this));
+ }
+
+ private void ReadJSONArrayEnd()
+ {
+ ReadJSONSyntaxChar(RBRACKET);
+ PopContext();
+ }
+
+ public override TMessage ReadMessageBegin()
+ {
+ TMessage message = new TMessage();
+ ReadJSONArrayStart();
+ if (ReadJSONInteger() != VERSION)
+ {
+ throw new TProtocolException(TProtocolException.BAD_VERSION,
+ "Message contained bad version.");
+ }
+
+ var buf = ReadJSONString(false);
+ message.Name = utf8Encoding.GetString(buf, 0, buf.Length);
+ message.Type = (TMessageType)ReadJSONInteger();
+ message.SeqID = (int)ReadJSONInteger();
+ return message;
+ }
+
+ public override void ReadMessageEnd()
+ {
+ ReadJSONArrayEnd();
+ }
+
+ public override TStruct ReadStructBegin()
+ {
+ ReadJSONObjectStart();
+ return new TStruct();
+ }
+
+ public override void ReadStructEnd()
+ {
+ ReadJSONObjectEnd();
+ }
+
+ public override TField ReadFieldBegin()
+ {
+ TField field = new TField();
+ byte ch = reader.Peek();
+ if (ch == RBRACE[0])
+ {
+ field.Type = TType.Stop;
+ }
+ else
+ {
+ field.ID = (short)ReadJSONInteger();
+ ReadJSONObjectStart();
+ field.Type = GetTypeIDForTypeName(ReadJSONString(false));
+ }
+ return field;
+ }
+
+ public override void ReadFieldEnd()
+ {
+ ReadJSONObjectEnd();
+ }
+
+ public override TMap ReadMapBegin()
+ {
+ TMap map = new TMap();
+ ReadJSONArrayStart();
+ map.KeyType = GetTypeIDForTypeName(ReadJSONString(false));
+ map.ValueType = GetTypeIDForTypeName(ReadJSONString(false));
+ map.Count = (int)ReadJSONInteger();
+ ReadJSONObjectStart();
+ return map;
+ }
+
+ public override void ReadMapEnd()
+ {
+ ReadJSONObjectEnd();
+ ReadJSONArrayEnd();
+ }
+
+ public override TList ReadListBegin()
+ {
+ TList list = new TList();
+ ReadJSONArrayStart();
+ list.ElementType = GetTypeIDForTypeName(ReadJSONString(false));
+ list.Count = (int)ReadJSONInteger();
+ return list;
+ }
+
+ public override void ReadListEnd()
+ {
+ ReadJSONArrayEnd();
+ }
+
+ public override TSet ReadSetBegin()
+ {
+ TSet set = new TSet();
+ ReadJSONArrayStart();
+ set.ElementType = GetTypeIDForTypeName(ReadJSONString(false));
+ set.Count = (int)ReadJSONInteger();
+ return set;
+ }
+
+ public override void ReadSetEnd()
+ {
+ ReadJSONArrayEnd();
+ }
+
+ public override bool ReadBool()
+ {
+ return (ReadJSONInteger() == 0 ? false : true);
+ }
+
+ public override sbyte ReadByte()
+ {
+ return (sbyte)ReadJSONInteger();
+ }
+
+ public override short ReadI16()
+ {
+ return (short)ReadJSONInteger();
+ }
+
+ public override int ReadI32()
+ {
+ return (int)ReadJSONInteger();
+ }
+
+ public override long ReadI64()
+ {
+ return (long)ReadJSONInteger();
+ }
+
+ public override double ReadDouble()
+ {
+ return ReadJSONDouble();
+ }
+
+ public override string ReadString()
+ {
+ var buf = ReadJSONString(false);
+ return utf8Encoding.GetString(buf, 0, buf.Length);
+ }
+
+ public override byte[] ReadBinary()
+ {
+ return ReadJSONBase64();
+ }
+
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Protocol/TList.cs b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TList.cs
new file mode 100644
index 000000000..0c8f2144a
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TList.cs
@@ -0,0 +1,54 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Thrift.Protocol
+{
+ public struct TList
+ {
+ private TType elementType;
+ private int count;
+
+ public TList(TType elementType, int count)
+ :this()
+ {
+ this.elementType = elementType;
+ this.count = count;
+ }
+
+ public TType ElementType
+ {
+ get { return elementType; }
+ set { elementType = value; }
+ }
+
+ public int Count
+ {
+ get { return count; }
+ set { count = value; }
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Protocol/TMap.cs b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TMap.cs
new file mode 100644
index 000000000..aba9d3a95
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TMap.cs
@@ -0,0 +1,62 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Thrift.Protocol
+{
+ public struct TMap
+ {
+ private TType keyType;
+ private TType valueType;
+ private int count;
+
+ public TMap(TType keyType, TType valueType, int count)
+ :this()
+ {
+ this.keyType = keyType;
+ this.valueType = valueType;
+ this.count = count;
+ }
+
+ public TType KeyType
+ {
+ get { return keyType; }
+ set { keyType = value; }
+ }
+
+ public TType ValueType
+ {
+ get { return valueType; }
+ set { valueType = value; }
+ }
+
+ public int Count
+ {
+ get { return count; }
+ set { count = value; }
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Protocol/TMessage.cs b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TMessage.cs
new file mode 100644
index 000000000..348263c37
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TMessage.cs
@@ -0,0 +1,62 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Thrift.Protocol
+{
+ public struct TMessage
+ {
+ private string name;
+ private TMessageType type;
+ private int seqID;
+
+ public TMessage(string name, TMessageType type, int seqid)
+ :this()
+ {
+ this.name = name;
+ this.type = type;
+ this.seqID = seqid;
+ }
+
+ public string Name
+ {
+ get { return name; }
+ set { name = value; }
+ }
+
+ public TMessageType Type
+ {
+ get { return type; }
+ set { type = value; }
+ }
+
+ public int SeqID
+ {
+ get { return seqID; }
+ set { seqID = value; }
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Protocol/TMessageType.cs b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TMessageType.cs
new file mode 100644
index 000000000..c7091fede
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TMessageType.cs
@@ -0,0 +1,31 @@
+/**
+ * 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;
+
+namespace Thrift.Protocol
+{
+ public enum TMessageType
+ {
+ Call = 1,
+ Reply = 2,
+ Exception = 3,
+ Oneway = 4
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Protocol/TMultiplexedProcessor.cs b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TMultiplexedProcessor.cs
new file mode 100644
index 000000000..aa91c527f
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TMultiplexedProcessor.cs
@@ -0,0 +1,183 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.Text;
+using Thrift.Transport;
+using System.Collections.Generic;
+using System.IO;
+
+namespace Thrift.Protocol
+{
+ /// <summary>
+ /// <see cref="TMultiplexedProcessor"/> is a <see cref="TProcessor"/> allowing a single <see cref="Thrift.Server.TServer"/>
+ /// to provide multiple services.
+ /// <para/>
+ /// To do so, you instantiate the processor and then register additional processors with it,
+ /// as shown in the following example:
+ /// <para/>
+ /// <code>
+ /// TMultiplexedProcessor processor = new TMultiplexedProcessor();
+ ///
+ /// processor.registerProcessor(
+ /// "Calculator",
+ /// new Calculator.Processor(new CalculatorHandler()));
+ ///
+ /// processor.registerProcessor(
+ /// "WeatherReport",
+ /// new WeatherReport.Processor(new WeatherReportHandler()));
+ ///
+ /// TServerTransport t = new TServerSocket(9090);
+ /// TSimpleServer server = new TSimpleServer(processor, t);
+ ///
+ /// server.serve();
+ /// </code>
+ /// </summary>
+ public class TMultiplexedProcessor : TProcessor
+ {
+ private Dictionary<string, TProcessor> ServiceProcessorMap = new Dictionary<string, TProcessor>();
+
+ /// <summary>
+ /// 'Register' a service with this TMultiplexedProcessor. This allows us to broker
+ /// requests to individual services by using the service name to select them at request time.
+ ///
+ /// Args:
+ /// - serviceName Name of a service, has to be identical to the name
+ /// declared in the Thrift IDL, e.g. "WeatherReport".
+ /// - processor Implementation of a service, usually referred to as "handlers",
+ /// e.g. WeatherReportHandler implementing WeatherReport.Iface.
+ /// </summary>
+ public void RegisterProcessor(string serviceName, TProcessor processor)
+ {
+ ServiceProcessorMap.Add(serviceName, processor);
+ }
+
+
+ private void Fail(TProtocol oprot, TMessage message, TApplicationException.ExceptionType extype, string etxt)
+ {
+ TApplicationException appex = new TApplicationException(extype, etxt);
+
+ TMessage newMessage = new TMessage(message.Name, TMessageType.Exception, message.SeqID);
+
+ oprot.WriteMessageBegin(newMessage);
+ appex.Write(oprot);
+ oprot.WriteMessageEnd();
+ oprot.Transport.Flush();
+ }
+
+
+ /// <summary>
+ /// This implementation of process performs the following steps:
+ ///
+ /// - Read the beginning of the message.
+ /// - Extract the service name from the message.
+ /// - Using the service name to locate the appropriate processor.
+ /// - Dispatch to the processor, with a decorated instance of TProtocol
+ /// that allows readMessageBegin() to return the original TMessage.
+ /// <para/>
+ /// Throws an exception if
+ /// - the message type is not CALL or ONEWAY,
+ /// - the service name was not found in the message, or
+ /// - the service name has not been RegisterProcessor()ed.
+ /// </summary>
+ public bool Process(TProtocol iprot, TProtocol oprot)
+ {
+ /* Use the actual underlying protocol (e.g. TBinaryProtocol) to read the
+ message header. This pulls the message "off the wire", which we'll
+ deal with at the end of this method. */
+
+ try
+ {
+ TMessage message = iprot.ReadMessageBegin();
+
+ if ((message.Type != TMessageType.Call) && (message.Type != TMessageType.Oneway))
+ {
+ Fail(oprot, message,
+ TApplicationException.ExceptionType.InvalidMessageType,
+ "Message type CALL or ONEWAY expected");
+ return false;
+ }
+
+ // Extract the service name
+ int index = message.Name.IndexOf(TMultiplexedProtocol.SEPARATOR);
+ if (index < 0)
+ {
+ Fail(oprot, message,
+ TApplicationException.ExceptionType.InvalidProtocol,
+ "Service name not found in message name: " + message.Name + ". " +
+ "Did you forget to use a TMultiplexProtocol in your client?");
+ return false;
+ }
+
+ // Create a new TMessage, something that can be consumed by any TProtocol
+ string serviceName = message.Name.Substring(0, index);
+ TProcessor actualProcessor;
+ if (!ServiceProcessorMap.TryGetValue(serviceName, out actualProcessor))
+ {
+ Fail(oprot, message,
+ TApplicationException.ExceptionType.InternalError,
+ "Service name not found: " + serviceName + ". " +
+ "Did you forget to call RegisterProcessor()?");
+ return false;
+ }
+
+ // Create a new TMessage, removing the service name
+ TMessage newMessage = new TMessage(
+ message.Name.Substring(serviceName.Length + TMultiplexedProtocol.SEPARATOR.Length),
+ message.Type,
+ message.SeqID);
+
+ // Dispatch processing to the stored processor
+ return actualProcessor.Process(new StoredMessageProtocol(iprot, newMessage), oprot);
+
+ }
+ catch (IOException)
+ {
+ return false; // similar to all other processors
+ }
+
+ }
+
+ /// <summary>
+ /// Our goal was to work with any protocol. In order to do that, we needed
+ /// to allow them to call readMessageBegin() and get a TMessage in exactly
+ /// the standard format, without the service name prepended to TMessage.name.
+ /// </summary>
+ private class StoredMessageProtocol : TProtocolDecorator
+ {
+ TMessage MsgBegin;
+
+ public StoredMessageProtocol(TProtocol protocol, TMessage messageBegin)
+ : base(protocol)
+ {
+ this.MsgBegin = messageBegin;
+ }
+
+ public override TMessage ReadMessageBegin()
+ {
+ return MsgBegin;
+ }
+ }
+
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Protocol/TMultiplexedProtocol.cs b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TMultiplexedProtocol.cs
new file mode 100644
index 000000000..1bd420fcc
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TMultiplexedProtocol.cs
@@ -0,0 +1,103 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.Text;
+using Thrift.Transport;
+using System.Collections.Generic;
+
+namespace Thrift.Protocol
+{
+
+ /// <summary>
+ /// TMultiplexedProtocol is a protocol-independent concrete decorator that allows a Thrift
+ /// client to communicate with a multiplexing Thrift server, by prepending the service name
+ /// to the function name during function calls.
+ /// <para/>
+ /// NOTE: THIS IS NOT TO BE USED BY SERVERS.
+ /// On the server, use TMultiplexedProcessor to handle requests from a multiplexing client.
+ /// <para/>
+ /// This example uses a single socket transport to invoke two services:
+ /// <code>
+ /// TSocket transport = new TSocket("localhost", 9090);
+ /// transport.open();
+ ///
+ /// TBinaryProtocol protocol = new TBinaryProtocol(transport);
+ ///
+ /// TMultiplexedProtocol mp = new TMultiplexedProtocol(protocol, "Calculator");
+ /// Calculator.Client service = new Calculator.Client(mp);
+ ///
+ /// TMultiplexedProtocol mp2 = new TMultiplexedProtocol(protocol, "WeatherReport");
+ /// WeatherReport.Client service2 = new WeatherReport.Client(mp2);
+ ///
+ /// System.out.println(service.add(2,2));
+ /// System.out.println(service2.getTemperature());
+ /// </code>
+ /// </summary>
+ public class TMultiplexedProtocol : TProtocolDecorator
+ {
+
+ /// <summary>
+ /// Used to delimit the service name from the function name.
+ /// </summary>
+ public static string SEPARATOR = ":";
+
+ private string ServiceName;
+
+ /// <summary>
+ /// Wrap the specified protocol, allowing it to be used to communicate with a
+ /// multiplexing server. The <paramref name="serviceName"/> is required as it is
+ /// prepended to the message header so that the multiplexing server can broker
+ /// the function call to the proper service.
+ /// </summary>
+ /// <param name="protocol">Your communication protocol of choice, e.g. <see cref="TBinaryProtocol"/>.</param>
+ /// <param name="serviceName">The service name of the service communicating via this protocol.</param>
+ public TMultiplexedProtocol(TProtocol protocol, string serviceName)
+ : base(protocol)
+ {
+ ServiceName = serviceName;
+ }
+
+ /// <summary>
+ /// Prepends the service name to the function name, separated by TMultiplexedProtocol.SEPARATOR.
+ /// </summary>
+ /// <param name="tMessage">The original message.</param>
+ public override void WriteMessageBegin(TMessage tMessage)
+ {
+ switch (tMessage.Type)
+ {
+ case TMessageType.Call:
+ case TMessageType.Oneway:
+ base.WriteMessageBegin(new TMessage(
+ ServiceName + SEPARATOR + tMessage.Name,
+ tMessage.Type,
+ tMessage.SeqID));
+ break;
+
+ default:
+ base.WriteMessageBegin(tMessage);
+ break;
+ }
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Protocol/TProtocol.cs b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TProtocol.cs
new file mode 100644
index 000000000..dd7a6e062
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TProtocol.cs
@@ -0,0 +1,142 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.Text;
+using Thrift.Transport;
+
+namespace Thrift.Protocol
+{
+ public abstract class TProtocol : IDisposable
+ {
+ private const int DEFAULT_RECURSION_DEPTH = 64;
+
+ protected TTransport trans;
+ protected int recursionLimit;
+ protected int recursionDepth;
+
+ protected TProtocol(TTransport trans)
+ {
+ this.trans = trans;
+ this.recursionLimit = DEFAULT_RECURSION_DEPTH;
+ this.recursionDepth = 0;
+ }
+
+ public TTransport Transport
+ {
+ get { return trans; }
+ }
+
+ public int RecursionLimit
+ {
+ get { return recursionLimit; }
+ set { recursionLimit = value; }
+ }
+
+ public void IncrementRecursionDepth()
+ {
+ if (recursionDepth < recursionLimit)
+ ++recursionDepth;
+ else
+ throw new TProtocolException(TProtocolException.DEPTH_LIMIT, "Depth limit exceeded");
+ }
+
+ public void DecrementRecursionDepth()
+ {
+ --recursionDepth;
+ }
+
+ #region " IDisposable Support "
+ private bool _IsDisposed;
+
+ // IDisposable
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_IsDisposed)
+ {
+ if (disposing)
+ {
+ if (trans is IDisposable)
+ (trans as IDisposable).Dispose();
+ }
+ }
+ _IsDisposed = true;
+ }
+ #endregion
+
+ 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(sbyte 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 virtual void WriteString(string s)
+ {
+ WriteBinary(Encoding.UTF8.GetBytes(s));
+ }
+ public abstract void WriteBinary(byte[] b);
+
+ 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 sbyte ReadByte();
+ public abstract short ReadI16();
+ public abstract int ReadI32();
+ public abstract long ReadI64();
+ public abstract double ReadDouble();
+ public virtual string ReadString()
+ {
+ var buf = ReadBinary();
+ return Encoding.UTF8.GetString(buf, 0, buf.Length);
+ }
+ public abstract byte[] ReadBinary();
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Protocol/TProtocolDecorator.cs b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TProtocolDecorator.cs
new file mode 100644
index 000000000..86000027f
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TProtocolDecorator.cs
@@ -0,0 +1,261 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.Text;
+using Thrift.Transport;
+using System.Collections.Generic;
+
+namespace Thrift.Protocol
+{
+ /// <summary>
+ /// <see cref="TProtocolDecorator"/> forwards all requests to an enclosed <see cref="TProtocol"/> instance,
+ /// providing a way to author concise concrete decorator subclasses. While it has
+ /// no abstract methods, it is marked abstract as a reminder that by itself,
+ /// it does not modify the behaviour of the enclosed <see cref="TProtocol"/>.
+ /// <para/>
+ /// See p.175 of Design Patterns (by Gamma et al.)
+ /// </summary>
+ /// <seealso cref="TMultiplexedProtocol"/>
+ public abstract class TProtocolDecorator : TProtocol
+ {
+ private TProtocol WrappedProtocol;
+
+ /// <summary>
+ /// Encloses the specified protocol.
+ /// </summary>
+ /// <param name="protocol">All operations will be forward to this protocol. Must be non-null.</param>
+ public TProtocolDecorator(TProtocol protocol)
+ : base(protocol.Transport)
+ {
+
+ WrappedProtocol = protocol;
+ }
+
+ public override void WriteMessageBegin(TMessage tMessage)
+ {
+ WrappedProtocol.WriteMessageBegin(tMessage);
+ }
+
+ public override void WriteMessageEnd()
+ {
+ WrappedProtocol.WriteMessageEnd();
+ }
+
+ public override void WriteStructBegin(TStruct tStruct)
+ {
+ WrappedProtocol.WriteStructBegin(tStruct);
+ }
+
+ public override void WriteStructEnd()
+ {
+ WrappedProtocol.WriteStructEnd();
+ }
+
+ public override void WriteFieldBegin(TField tField)
+ {
+ WrappedProtocol.WriteFieldBegin(tField);
+ }
+
+ public override void WriteFieldEnd()
+ {
+ WrappedProtocol.WriteFieldEnd();
+ }
+
+ public override void WriteFieldStop()
+ {
+ WrappedProtocol.WriteFieldStop();
+ }
+
+ public override void WriteMapBegin(TMap tMap)
+ {
+ WrappedProtocol.WriteMapBegin(tMap);
+ }
+
+ public override void WriteMapEnd()
+ {
+ WrappedProtocol.WriteMapEnd();
+ }
+
+ public override void WriteListBegin(TList tList)
+ {
+ WrappedProtocol.WriteListBegin(tList);
+ }
+
+ public override void WriteListEnd()
+ {
+ WrappedProtocol.WriteListEnd();
+ }
+
+ public override void WriteSetBegin(TSet tSet)
+ {
+ WrappedProtocol.WriteSetBegin(tSet);
+ }
+
+ public override void WriteSetEnd()
+ {
+ WrappedProtocol.WriteSetEnd();
+ }
+
+ public override void WriteBool(bool b)
+ {
+ WrappedProtocol.WriteBool(b);
+ }
+
+ public override void WriteByte(sbyte b)
+ {
+ WrappedProtocol.WriteByte(b);
+ }
+
+ public override void WriteI16(short i)
+ {
+ WrappedProtocol.WriteI16(i);
+ }
+
+ public override void WriteI32(int i)
+ {
+ WrappedProtocol.WriteI32(i);
+ }
+
+ public override void WriteI64(long l)
+ {
+ WrappedProtocol.WriteI64(l);
+ }
+
+ public override void WriteDouble(double v)
+ {
+ WrappedProtocol.WriteDouble(v);
+ }
+
+ public override void WriteString(string s)
+ {
+ WrappedProtocol.WriteString(s);
+ }
+
+ public override void WriteBinary(byte[] bytes)
+ {
+ WrappedProtocol.WriteBinary(bytes);
+ }
+
+ public override TMessage ReadMessageBegin()
+ {
+ return WrappedProtocol.ReadMessageBegin();
+ }
+
+ public override void ReadMessageEnd()
+ {
+ WrappedProtocol.ReadMessageEnd();
+ }
+
+ public override TStruct ReadStructBegin()
+ {
+ return WrappedProtocol.ReadStructBegin();
+ }
+
+ public override void ReadStructEnd()
+ {
+ WrappedProtocol.ReadStructEnd();
+ }
+
+ public override TField ReadFieldBegin()
+ {
+ return WrappedProtocol.ReadFieldBegin();
+ }
+
+ public override void ReadFieldEnd()
+ {
+ WrappedProtocol.ReadFieldEnd();
+ }
+
+ public override TMap ReadMapBegin()
+ {
+ return WrappedProtocol.ReadMapBegin();
+ }
+
+ public override void ReadMapEnd()
+ {
+ WrappedProtocol.ReadMapEnd();
+ }
+
+ public override TList ReadListBegin()
+ {
+ return WrappedProtocol.ReadListBegin();
+ }
+
+ public override void ReadListEnd()
+ {
+ WrappedProtocol.ReadListEnd();
+ }
+
+ public override TSet ReadSetBegin()
+ {
+ return WrappedProtocol.ReadSetBegin();
+ }
+
+ public override void ReadSetEnd()
+ {
+ WrappedProtocol.ReadSetEnd();
+ }
+
+ public override bool ReadBool()
+ {
+ return WrappedProtocol.ReadBool();
+ }
+
+ public override sbyte ReadByte()
+ {
+ return WrappedProtocol.ReadByte();
+ }
+
+ public override short ReadI16()
+ {
+ return WrappedProtocol.ReadI16();
+ }
+
+ public override int ReadI32()
+ {
+ return WrappedProtocol.ReadI32();
+ }
+
+ public override long ReadI64()
+ {
+ return WrappedProtocol.ReadI64();
+ }
+
+ public override double ReadDouble()
+ {
+ return WrappedProtocol.ReadDouble();
+ }
+
+ public override string ReadString()
+ {
+ return WrappedProtocol.ReadString();
+ }
+
+ public override byte[] ReadBinary()
+ {
+ return WrappedProtocol.ReadBinary();
+ }
+ }
+
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Protocol/TProtocolException.cs b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TProtocolException.cs
new file mode 100644
index 000000000..7bef23685
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TProtocolException.cs
@@ -0,0 +1,67 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+
+namespace Thrift.Protocol
+{
+ public class TProtocolException : TException
+ {
+ 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;
+ public const int NOT_IMPLEMENTED = 5;
+ public const int DEPTH_LIMIT = 6;
+
+ protected int type_ = UNKNOWN;
+
+ public TProtocolException()
+ : base()
+ {
+ }
+
+ public TProtocolException(int type, Exception inner = null)
+ : base(string.Empty, inner)
+ {
+ type_ = type;
+ }
+
+ public TProtocolException(int type, string message, Exception inner = null)
+ : base(message, inner)
+ {
+ type_ = type;
+ }
+
+ public TProtocolException(string message, Exception inner = null)
+ : base(message, inner)
+ {
+ }
+
+ public int getType()
+ {
+ return type_;
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Protocol/TProtocolFactory.cs b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TProtocolFactory.cs
new file mode 100644
index 000000000..71360a19a
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TProtocolFactory.cs
@@ -0,0 +1,33 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using Thrift.Transport;
+
+namespace Thrift.Protocol
+{
+ public interface TProtocolFactory
+ {
+ TProtocol GetProtocol(TTransport trans);
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Protocol/TProtocolUtil.cs b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TProtocolUtil.cs
new file mode 100644
index 000000000..d995c6ce7
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TProtocolUtil.cs
@@ -0,0 +1,108 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+
+namespace Thrift.Protocol
+{
+ public static class TProtocolUtil
+ {
+ public static void Skip(TProtocol prot, TType type)
+ {
+ prot.IncrementRecursionDepth();
+ try
+ {
+ 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:
+ // Don't try to decode the string, just skip it.
+ prot.ReadBinary();
+ 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;
+ default:
+ throw new TProtocolException(TProtocolException.INVALID_DATA, "Unknown data type " + type.ToString("d"));
+ }
+ }
+ finally
+ {
+ prot.DecrementRecursionDepth();
+ }
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Protocol/TSet.cs b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TSet.cs
new file mode 100644
index 000000000..a918ab537
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TSet.cs
@@ -0,0 +1,59 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Thrift.Protocol
+{
+ public struct TSet
+ {
+ private TType elementType;
+ private int count;
+
+ public TSet(TType elementType, int count)
+ :this()
+ {
+ this.elementType = elementType;
+ this.count = count;
+ }
+
+ public TSet(TList list)
+ : this(list.ElementType, list.Count)
+ {
+ }
+
+ public TType ElementType
+ {
+ get { return elementType; }
+ set { elementType = value; }
+ }
+
+ public int Count
+ {
+ get { return count; }
+ set { count = value; }
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Protocol/TStruct.cs b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TStruct.cs
new file mode 100644
index 000000000..f4844a4c9
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TStruct.cs
@@ -0,0 +1,46 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Thrift.Protocol
+{
+ public struct TStruct
+ {
+ private string name;
+
+ public TStruct(string name)
+ :this()
+ {
+ this.name = name;
+ }
+
+ public string Name
+ {
+ get { return name; }
+ set { name = value; }
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Protocol/TType.cs b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TType.cs
new file mode 100644
index 000000000..9ce915e08
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Protocol/TType.cs
@@ -0,0 +1,44 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+
+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/src/jaegertracing/thrift/lib/csharp/src/Server/TServer.cs b/src/jaegertracing/thrift/lib/csharp/src/Server/TServer.cs
new file mode 100644
index 000000000..2bc04f3a0
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Server/TServer.cs
@@ -0,0 +1,155 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using Thrift.Protocol;
+using Thrift.Transport;
+using System.IO;
+
+namespace Thrift.Server
+{
+ public abstract class TServer
+ {
+ //Attributes
+ protected TProcessorFactory processorFactory;
+ protected TServerTransport serverTransport;
+ protected TTransportFactory inputTransportFactory;
+ protected TTransportFactory outputTransportFactory;
+ protected TProtocolFactory inputProtocolFactory;
+ protected TProtocolFactory outputProtocolFactory;
+ protected TServerEventHandler serverEventHandler = null;
+
+ //Methods
+ public void setEventHandler(TServerEventHandler seh)
+ {
+ serverEventHandler = seh;
+ }
+ public TServerEventHandler getEventHandler()
+ {
+ return serverEventHandler;
+ }
+
+ //Log delegation
+ public delegate void LogDelegate(string str);
+ private LogDelegate _logDelegate;
+ protected LogDelegate logDelegate
+ {
+ get { return _logDelegate; }
+ set { _logDelegate = (value != null) ? value : DefaultLogDelegate; }
+ }
+ protected static void DefaultLogDelegate(string s)
+ {
+ Console.Error.WriteLine(s);
+ }
+
+ //Construction
+ public TServer(TProcessor processor,
+ TServerTransport serverTransport)
+ : this(processor, serverTransport,
+ new TTransportFactory(),
+ new TTransportFactory(),
+ new TBinaryProtocol.Factory(),
+ new TBinaryProtocol.Factory(),
+ DefaultLogDelegate)
+ {
+ }
+
+ public TServer(TProcessor processor,
+ TServerTransport serverTransport,
+ LogDelegate logDelegate)
+ : this(processor,
+ serverTransport,
+ new TTransportFactory(),
+ new TTransportFactory(),
+ new TBinaryProtocol.Factory(),
+ new TBinaryProtocol.Factory(),
+ logDelegate)
+ {
+ }
+
+ public TServer(TProcessor processor,
+ TServerTransport serverTransport,
+ TTransportFactory transportFactory)
+ : this(processor,
+ serverTransport,
+ transportFactory,
+ transportFactory,
+ new TBinaryProtocol.Factory(),
+ new TBinaryProtocol.Factory(),
+ DefaultLogDelegate)
+ {
+ }
+
+ public TServer(TProcessor processor,
+ TServerTransport serverTransport,
+ TTransportFactory transportFactory,
+ TProtocolFactory protocolFactory)
+ : this(processor,
+ serverTransport,
+ transportFactory,
+ transportFactory,
+ protocolFactory,
+ protocolFactory,
+ DefaultLogDelegate)
+ {
+ }
+
+ public TServer(TProcessor processor,
+ TServerTransport serverTransport,
+ TTransportFactory inputTransportFactory,
+ TTransportFactory outputTransportFactory,
+ TProtocolFactory inputProtocolFactory,
+ TProtocolFactory outputProtocolFactory,
+ LogDelegate logDelegate)
+ {
+ this.processorFactory = new TSingletonProcessorFactory(processor);
+ this.serverTransport = serverTransport;
+ this.inputTransportFactory = inputTransportFactory;
+ this.outputTransportFactory = outputTransportFactory;
+ this.inputProtocolFactory = inputProtocolFactory;
+ this.outputProtocolFactory = outputProtocolFactory;
+ this.logDelegate = (logDelegate != null) ? logDelegate : DefaultLogDelegate;
+ }
+
+ public TServer(TProcessorFactory processorFactory,
+ TServerTransport serverTransport,
+ TTransportFactory inputTransportFactory,
+ TTransportFactory outputTransportFactory,
+ TProtocolFactory inputProtocolFactory,
+ TProtocolFactory outputProtocolFactory,
+ LogDelegate logDelegate)
+ {
+ this.processorFactory = processorFactory;
+ this.serverTransport = serverTransport;
+ this.inputTransportFactory = inputTransportFactory;
+ this.outputTransportFactory = outputTransportFactory;
+ this.inputProtocolFactory = inputProtocolFactory;
+ this.outputProtocolFactory = outputProtocolFactory;
+ this.logDelegate = (logDelegate != null) ? logDelegate : DefaultLogDelegate;
+ }
+
+ //Abstract Interface
+ public abstract void Serve();
+ public abstract void Stop();
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Server/TServerEventHandler.cs b/src/jaegertracing/thrift/lib/csharp/src/Server/TServerEventHandler.cs
new file mode 100644
index 000000000..e81efc6af
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Server/TServerEventHandler.cs
@@ -0,0 +1,53 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+
+namespace Thrift.Server
+{
+ /// <summary>
+ /// Interface implemented by server users to handle events from the server.
+ /// </summary>
+ public interface TServerEventHandler
+ {
+ /// <summary>
+ /// Called before the server begins.
+ /// </summary>
+ void preServe();
+
+ /// <summary>
+ /// Called when a new client has connected and is about to being processing.
+ /// </summary>
+ object createContext(Thrift.Protocol.TProtocol input, Thrift.Protocol.TProtocol output);
+
+ /// <summary>
+ /// Called when a client has finished request-handling to delete server context.
+ /// </summary>
+ void deleteContext(object serverContext, Thrift.Protocol.TProtocol input, Thrift.Protocol.TProtocol output);
+
+ /// <summary>
+ /// Called when a client is about to call the processor.
+ /// </summary>
+ void processContext(object serverContext, Thrift.Transport.TTransport transport);
+ };
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Server/TSimpleServer.cs b/src/jaegertracing/thrift/lib/csharp/src/Server/TSimpleServer.cs
new file mode 100644
index 000000000..4e7ea96f4
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Server/TSimpleServer.cs
@@ -0,0 +1,180 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using Thrift.Transport;
+using Thrift.Protocol;
+
+namespace Thrift.Server
+{
+ /// <summary>
+ /// Simple single-threaded server for testing.
+ /// </summary>
+ public class TSimpleServer : TServer
+ {
+ private bool stop = false;
+
+ public TSimpleServer(TProcessor processor,
+ TServerTransport serverTransport)
+ : base(processor, serverTransport, new TTransportFactory(), new TTransportFactory(), new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(), DefaultLogDelegate)
+ {
+ }
+
+ public TSimpleServer(TProcessor processor,
+ TServerTransport serverTransport,
+ LogDelegate logDel)
+ : base(processor, serverTransport, new TTransportFactory(), new TTransportFactory(), new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(), logDel)
+ {
+ }
+
+ public TSimpleServer(TProcessor processor,
+ TServerTransport serverTransport,
+ TTransportFactory transportFactory)
+ : base(processor,
+ serverTransport,
+ transportFactory,
+ transportFactory,
+ new TBinaryProtocol.Factory(),
+ new TBinaryProtocol.Factory(),
+ DefaultLogDelegate)
+ {
+ }
+
+ public TSimpleServer(TProcessor processor,
+ TServerTransport serverTransport,
+ TTransportFactory transportFactory,
+ TProtocolFactory protocolFactory)
+ : base(processor,
+ serverTransport,
+ transportFactory,
+ transportFactory,
+ protocolFactory,
+ protocolFactory,
+ DefaultLogDelegate)
+ {
+ }
+
+ public TSimpleServer(TProcessorFactory processorFactory,
+ TServerTransport serverTransport,
+ TTransportFactory transportFactory,
+ TProtocolFactory protocolFactory)
+ : base(processorFactory,
+ serverTransport,
+ transportFactory,
+ transportFactory,
+ protocolFactory,
+ protocolFactory,
+ DefaultLogDelegate)
+ {
+ }
+
+ public override void Serve()
+ {
+ try
+ {
+ serverTransport.Listen();
+ }
+ catch (TTransportException ttx)
+ {
+ logDelegate(ttx.ToString());
+ return;
+ }
+
+ //Fire the preServe server event when server is up but before any client connections
+ if (serverEventHandler != null)
+ serverEventHandler.preServe();
+
+ while (!stop)
+ {
+ TProcessor processor = null;
+ TTransport client = null;
+ TTransport inputTransport = null;
+ TTransport outputTransport = null;
+ TProtocol inputProtocol = null;
+ TProtocol outputProtocol = null;
+ object connectionContext = null;
+ try
+ {
+ using (client = serverTransport.Accept())
+ {
+ processor = processorFactory.GetProcessor(client);
+ if (client != null)
+ {
+ using (inputTransport = inputTransportFactory.GetTransport(client))
+ {
+ using (outputTransport = outputTransportFactory.GetTransport(client))
+ {
+ inputProtocol = inputProtocolFactory.GetProtocol(inputTransport);
+ outputProtocol = outputProtocolFactory.GetProtocol(outputTransport);
+
+ //Recover event handler (if any) and fire createContext server event when a client connects
+ if (serverEventHandler != null)
+ connectionContext = serverEventHandler.createContext(inputProtocol, outputProtocol);
+
+ //Process client requests until client disconnects
+ while (!stop)
+ {
+ if (!inputTransport.Peek())
+ break;
+
+ //Fire processContext server event
+ //N.B. This is the pattern implemented in C++ and the event fires provisionally.
+ //That is to say it may be many minutes between the event firing and the client request
+ //actually arriving or the client may hang up without ever makeing a request.
+ if (serverEventHandler != null)
+ serverEventHandler.processContext(connectionContext, inputTransport);
+ //Process client request (blocks until transport is readable)
+ if (!processor.Process(inputProtocol, outputProtocol))
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (TTransportException ttx)
+ {
+ if (!stop || ttx.Type != TTransportException.ExceptionType.Interrupted)
+ {
+ logDelegate(ttx.ToString());
+ }
+ }
+ catch (Exception x)
+ {
+ //Unexpected
+ logDelegate(x.ToString());
+ }
+
+ //Fire deleteContext server event after client disconnects
+ if (serverEventHandler != null)
+ serverEventHandler.deleteContext(connectionContext, inputProtocol, outputProtocol);
+ }
+ }
+
+ public override void Stop()
+ {
+ stop = true;
+ serverTransport.Close();
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Server/TThreadPoolServer.cs b/src/jaegertracing/thrift/lib/csharp/src/Server/TThreadPoolServer.cs
new file mode 100644
index 000000000..a494ce7bd
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Server/TThreadPoolServer.cs
@@ -0,0 +1,295 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+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 = -1; // use .NET ThreadPool defaults
+ private const int DEFAULT_MAX_THREADS = -1; // use .NET ThreadPool defaults
+ private volatile bool stop = false;
+
+ public struct Configuration
+ {
+ public int MinWorkerThreads;
+ public int MaxWorkerThreads;
+ public int MinIOThreads;
+ public int MaxIOThreads;
+
+ public Configuration(int min = DEFAULT_MIN_THREADS, int max = DEFAULT_MAX_THREADS)
+ {
+ MinWorkerThreads = min;
+ MaxWorkerThreads = max;
+ MinIOThreads = min;
+ MaxIOThreads = max;
+ }
+
+ public Configuration(int minWork, int maxWork, int minIO, int maxIO)
+ {
+ MinWorkerThreads = minWork;
+ MaxWorkerThreads = maxWork;
+ MinIOThreads = minIO;
+ MaxIOThreads = maxIO;
+ }
+ }
+
+ public TThreadPoolServer(TProcessor processor, TServerTransport serverTransport)
+ : this(new TSingletonProcessorFactory(processor), serverTransport,
+ new TTransportFactory(), new TTransportFactory(),
+ new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(),
+ new Configuration(), DefaultLogDelegate)
+ {
+ }
+
+ public TThreadPoolServer(TProcessor processor, TServerTransport serverTransport, LogDelegate logDelegate)
+ : this(new TSingletonProcessorFactory(processor), serverTransport,
+ new TTransportFactory(), new TTransportFactory(),
+ new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(),
+ new Configuration(), logDelegate)
+ {
+ }
+
+ public TThreadPoolServer(TProcessor processor,
+ TServerTransport serverTransport,
+ TTransportFactory transportFactory,
+ TProtocolFactory protocolFactory)
+ : this(new TSingletonProcessorFactory(processor), serverTransport,
+ transportFactory, transportFactory,
+ protocolFactory, protocolFactory,
+ new Configuration(), DefaultLogDelegate)
+ {
+ }
+
+ public TThreadPoolServer(TProcessorFactory processorFactory,
+ TServerTransport serverTransport,
+ TTransportFactory transportFactory,
+ TProtocolFactory protocolFactory)
+ : this(processorFactory, serverTransport,
+ transportFactory, transportFactory,
+ protocolFactory, protocolFactory,
+ new Configuration(), DefaultLogDelegate)
+ {
+ }
+
+ public TThreadPoolServer(TProcessorFactory processorFactory,
+ TServerTransport serverTransport,
+ TTransportFactory inputTransportFactory,
+ TTransportFactory outputTransportFactory,
+ TProtocolFactory inputProtocolFactory,
+ TProtocolFactory outputProtocolFactory,
+ int minThreadPoolThreads, int maxThreadPoolThreads, LogDelegate logDel)
+ : this(processorFactory, serverTransport, inputTransportFactory, outputTransportFactory,
+ inputProtocolFactory, outputProtocolFactory,
+ new Configuration(minThreadPoolThreads, maxThreadPoolThreads),
+ logDel)
+ {
+ }
+
+ public TThreadPoolServer(TProcessorFactory processorFactory,
+ TServerTransport serverTransport,
+ TTransportFactory inputTransportFactory,
+ TTransportFactory outputTransportFactory,
+ TProtocolFactory inputProtocolFactory,
+ TProtocolFactory outputProtocolFactory,
+ Configuration threadConfig,
+ LogDelegate logDel)
+ : base(processorFactory, serverTransport, inputTransportFactory, outputTransportFactory,
+ inputProtocolFactory, outputProtocolFactory, logDel)
+ {
+ lock (typeof(TThreadPoolServer))
+ {
+ if ((threadConfig.MaxWorkerThreads > 0) || (threadConfig.MaxIOThreads > 0))
+ {
+ int work, comm;
+ ThreadPool.GetMaxThreads(out work, out comm);
+ if (threadConfig.MaxWorkerThreads > 0)
+ work = threadConfig.MaxWorkerThreads;
+ if (threadConfig.MaxIOThreads > 0)
+ comm = threadConfig.MaxIOThreads;
+ if (!ThreadPool.SetMaxThreads(work, comm))
+ throw new Exception("Error: could not SetMaxThreads in ThreadPool");
+ }
+
+ if ((threadConfig.MinWorkerThreads > 0) || (threadConfig.MinIOThreads > 0))
+ {
+ int work, comm;
+ ThreadPool.GetMinThreads(out work, out comm);
+ if (threadConfig.MinWorkerThreads > 0)
+ work = threadConfig.MinWorkerThreads;
+ if (threadConfig.MinIOThreads > 0)
+ comm = threadConfig.MinIOThreads;
+ if (!ThreadPool.SetMinThreads(work, comm))
+ throw new Exception("Error: could not SetMinThreads in ThreadPool");
+ }
+ }
+ }
+
+
+ /// <summary>
+ /// Use new ThreadPool thread for each new client connection.
+ /// </summary>
+ public override void Serve()
+ {
+ try
+ {
+ serverTransport.Listen();
+ }
+ catch (TTransportException ttx)
+ {
+ logDelegate("Error, could not listen on ServerTransport: " + ttx);
+ return;
+ }
+
+ //Fire the preServe server event when server is up but before any client connections
+ if (serverEventHandler != null)
+ serverEventHandler.preServe();
+
+ while (!stop)
+ {
+ int failureCount = 0;
+ try
+ {
+ TTransport client = serverTransport.Accept();
+ ThreadPool.QueueUserWorkItem(this.Execute, client);
+ }
+ catch (TTransportException ttx)
+ {
+ if (!stop || ttx.Type != TTransportException.ExceptionType.Interrupted)
+ {
+ ++failureCount;
+ logDelegate(ttx.ToString());
+ }
+
+ }
+ }
+
+ if (stop)
+ {
+ try
+ {
+ serverTransport.Close();
+ }
+ catch (TTransportException ttx)
+ {
+ logDelegate("TServerTransport failed on close: " + ttx.Message);
+ }
+ stop = false;
+ }
+ }
+
+ /// <summary>
+ /// Loops on processing a client forever
+ /// threadContext will be a TTransport instance
+ /// </summary>
+ /// <param name="threadContext"></param>
+ private void Execute(object threadContext)
+ {
+ using (TTransport client = (TTransport)threadContext)
+ {
+ TProcessor processor = processorFactory.GetProcessor(client, this);
+ TTransport inputTransport = null;
+ TTransport outputTransport = null;
+ TProtocol inputProtocol = null;
+ TProtocol outputProtocol = null;
+ object connectionContext = null;
+ try
+ {
+ try
+ {
+ inputTransport = inputTransportFactory.GetTransport(client);
+ outputTransport = outputTransportFactory.GetTransport(client);
+ inputProtocol = inputProtocolFactory.GetProtocol(inputTransport);
+ outputProtocol = outputProtocolFactory.GetProtocol(outputTransport);
+
+ //Recover event handler (if any) and fire createContext server event when a client connects
+ if (serverEventHandler != null)
+ connectionContext = serverEventHandler.createContext(inputProtocol, outputProtocol);
+
+ //Process client requests until client disconnects
+ while (!stop)
+ {
+ if (!inputTransport.Peek())
+ break;
+
+ //Fire processContext server event
+ //N.B. This is the pattern implemented in C++ and the event fires provisionally.
+ //That is to say it may be many minutes between the event firing and the client request
+ //actually arriving or the client may hang up without ever makeing a request.
+ if (serverEventHandler != null)
+ serverEventHandler.processContext(connectionContext, inputTransport);
+ //Process client request (blocks until transport is readable)
+ if (!processor.Process(inputProtocol, outputProtocol))
+ break;
+ }
+ }
+ catch (TTransportException)
+ {
+ //Usually a client disconnect, expected
+ }
+ catch (Exception x)
+ {
+ //Unexpected
+ logDelegate("Error: " + x);
+ }
+
+ //Fire deleteContext server event after client disconnects
+ if (serverEventHandler != null)
+ serverEventHandler.deleteContext(connectionContext, inputProtocol, outputProtocol);
+
+ }
+ finally
+ {
+ //Close transports
+ if (inputTransport != null)
+ inputTransport.Close();
+ if (outputTransport != null)
+ outputTransport.Close();
+
+ // disposable stuff should be disposed
+ if (inputProtocol != null)
+ inputProtocol.Dispose();
+ if (outputProtocol != null)
+ outputProtocol.Dispose();
+ if (inputTransport != null)
+ inputTransport.Dispose();
+ if (outputTransport != null)
+ outputTransport.Dispose();
+ }
+ }
+ }
+
+ public override void Stop()
+ {
+ stop = true;
+ serverTransport.Close();
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Server/TThreadedServer.cs b/src/jaegertracing/thrift/lib/csharp/src/Server/TThreadedServer.cs
new file mode 100644
index 000000000..cc051a33b
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Server/TThreadedServer.cs
@@ -0,0 +1,282 @@
+/**
+ * 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;
+using System.Collections.Generic;
+using System.Threading;
+using Thrift.Collections;
+using Thrift.Protocol;
+using Thrift.Transport;
+
+namespace Thrift.Server
+{
+ /// <summary>
+ /// Server that uses C# threads (as opposed to the ThreadPool) when handling requests.
+ /// </summary>
+ public class TThreadedServer : TServer
+ {
+ private const int DEFAULT_MAX_THREADS = 100;
+ private volatile bool stop = false;
+ private readonly int maxThreads;
+
+ private Queue<TTransport> clientQueue;
+ private THashSet<Thread> clientThreads;
+ private object clientLock;
+ private Thread workerThread;
+
+ public int ClientThreadsCount
+ {
+ get { return clientThreads.Count; }
+ }
+
+ public TThreadedServer(TProcessor processor, TServerTransport serverTransport)
+ : this(new TSingletonProcessorFactory(processor), serverTransport,
+ new TTransportFactory(), new TTransportFactory(),
+ new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(),
+ DEFAULT_MAX_THREADS, DefaultLogDelegate)
+ {
+ }
+
+ public TThreadedServer(TProcessor processor, TServerTransport serverTransport, LogDelegate logDelegate)
+ : this(new TSingletonProcessorFactory(processor), serverTransport,
+ new TTransportFactory(), new TTransportFactory(),
+ new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(),
+ DEFAULT_MAX_THREADS, logDelegate)
+ {
+ }
+
+
+ public TThreadedServer(TProcessor processor,
+ TServerTransport serverTransport,
+ TTransportFactory transportFactory,
+ TProtocolFactory protocolFactory)
+ : this(new TSingletonProcessorFactory(processor), serverTransport,
+ transportFactory, transportFactory,
+ protocolFactory, protocolFactory,
+ DEFAULT_MAX_THREADS, DefaultLogDelegate)
+ {
+ }
+
+ public TThreadedServer(TProcessorFactory processorFactory,
+ TServerTransport serverTransport,
+ TTransportFactory transportFactory,
+ TProtocolFactory protocolFactory)
+ : this(processorFactory, serverTransport,
+ transportFactory, transportFactory,
+ protocolFactory, protocolFactory,
+ DEFAULT_MAX_THREADS, DefaultLogDelegate)
+ {
+ }
+ public TThreadedServer(TProcessorFactory processorFactory,
+ TServerTransport serverTransport,
+ TTransportFactory inputTransportFactory,
+ TTransportFactory outputTransportFactory,
+ TProtocolFactory inputProtocolFactory,
+ TProtocolFactory outputProtocolFactory,
+ int maxThreads, LogDelegate logDel)
+ : base(processorFactory, serverTransport, inputTransportFactory, outputTransportFactory,
+ inputProtocolFactory, outputProtocolFactory, logDel)
+ {
+ this.maxThreads = maxThreads;
+ clientQueue = new Queue<TTransport>();
+ clientLock = new object();
+ clientThreads = new THashSet<Thread>();
+ }
+
+ /// <summary>
+ /// Use new Thread for each new client connection. block until numConnections &lt; maxThreads.
+ /// </summary>
+ public override void Serve()
+ {
+ try
+ {
+ //start worker thread
+ workerThread = new Thread(new ThreadStart(Execute));
+ workerThread.Start();
+ serverTransport.Listen();
+ }
+ catch (TTransportException ttx)
+ {
+ logDelegate("Error, could not listen on ServerTransport: " + ttx);
+ return;
+ }
+
+ //Fire the preServe server event when server is up but before any client connections
+ if (serverEventHandler != null)
+ serverEventHandler.preServe();
+
+ while (!stop)
+ {
+ int failureCount = 0;
+ try
+ {
+ TTransport client = serverTransport.Accept();
+ lock (clientLock)
+ {
+ clientQueue.Enqueue(client);
+ Monitor.Pulse(clientLock);
+ }
+ }
+ catch (TTransportException ttx)
+ {
+ if (!stop || ttx.Type != TTransportException.ExceptionType.Interrupted)
+ {
+ ++failureCount;
+ logDelegate(ttx.ToString());
+ }
+
+ }
+ }
+
+ if (stop)
+ {
+ try
+ {
+ serverTransport.Close();
+ }
+ catch (TTransportException ttx)
+ {
+ logDelegate("TServeTransport failed on close: " + ttx.Message);
+ }
+ stop = false;
+ }
+ }
+
+ /// <summary>
+ /// Loops on processing a client forever
+ /// </summary>
+ private void Execute()
+ {
+ while (!stop)
+ {
+ TTransport client;
+ Thread t;
+ lock (clientLock)
+ {
+ //don't dequeue if too many connections
+ while (clientThreads.Count >= maxThreads)
+ {
+ Monitor.Wait(clientLock);
+ }
+
+ while (clientQueue.Count == 0)
+ {
+ Monitor.Wait(clientLock);
+ }
+
+ client = clientQueue.Dequeue();
+ t = new Thread(new ParameterizedThreadStart(ClientWorker));
+ clientThreads.Add(t);
+ }
+ //start processing requests from client on new thread
+ t.Start(client);
+ }
+ }
+
+ private void ClientWorker(object context)
+ {
+ using (TTransport client = (TTransport)context)
+ {
+ TProcessor processor = processorFactory.GetProcessor(client);
+ TTransport inputTransport = null;
+ TTransport outputTransport = null;
+ TProtocol inputProtocol = null;
+ TProtocol outputProtocol = null;
+ object connectionContext = null;
+ try
+ {
+ try
+ {
+ inputTransport = inputTransportFactory.GetTransport(client);
+ outputTransport = outputTransportFactory.GetTransport(client);
+ inputProtocol = inputProtocolFactory.GetProtocol(inputTransport);
+ outputProtocol = outputProtocolFactory.GetProtocol(outputTransport);
+
+ //Recover event handler (if any) and fire createContext server event when a client connects
+ if (serverEventHandler != null)
+ connectionContext = serverEventHandler.createContext(inputProtocol, outputProtocol);
+
+ //Process client requests until client disconnects
+ while (!stop)
+ {
+ if (!inputTransport.Peek())
+ break;
+
+ //Fire processContext server event
+ //N.B. This is the pattern implemented in C++ and the event fires provisionally.
+ //That is to say it may be many minutes between the event firing and the client request
+ //actually arriving or the client may hang up without ever makeing a request.
+ if (serverEventHandler != null)
+ serverEventHandler.processContext(connectionContext, inputTransport);
+ //Process client request (blocks until transport is readable)
+ if (!processor.Process(inputProtocol, outputProtocol))
+ break;
+ }
+ }
+ catch (TTransportException)
+ {
+ //Usually a client disconnect, expected
+ }
+ catch (Exception x)
+ {
+ //Unexpected
+ logDelegate("Error: " + x);
+ }
+
+ //Fire deleteContext server event after client disconnects
+ if (serverEventHandler != null)
+ serverEventHandler.deleteContext(connectionContext, inputProtocol, outputProtocol);
+
+ lock (clientLock)
+ {
+ clientThreads.Remove(Thread.CurrentThread);
+ Monitor.Pulse(clientLock);
+ }
+
+ }
+ finally
+ {
+ //Close transports
+ if (inputTransport != null)
+ inputTransport.Close();
+ if (outputTransport != null)
+ outputTransport.Close();
+
+ // disposable stuff should be disposed
+ if (inputProtocol != null)
+ inputProtocol.Dispose();
+ if (outputProtocol != null)
+ outputProtocol.Dispose();
+ }
+ }
+ }
+
+ public override void Stop()
+ {
+ stop = true;
+ serverTransport.Close();
+ //clean up all the threads myself
+ workerThread.Abort();
+ foreach (Thread t in clientThreads)
+ {
+ t.Abort();
+ }
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/TApplicationException.cs b/src/jaegertracing/thrift/lib/csharp/src/TApplicationException.cs
new file mode 100644
index 000000000..8dd7ae578
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/TApplicationException.cs
@@ -0,0 +1,146 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using Thrift.Protocol;
+
+namespace Thrift
+{
+ public class TApplicationException : TException
+ {
+ protected ExceptionType type;
+
+ public TApplicationException()
+ {
+ }
+
+ public TApplicationException(ExceptionType type)
+ {
+ this.type = type;
+ }
+
+ public TApplicationException(ExceptionType type, string message)
+ : base(message, null) // TApplicationException is serializable, but we never serialize InnerException
+ {
+ this.type = type;
+ }
+
+ public static TApplicationException Read(TProtocol iprot)
+ {
+ TField field;
+
+ string message = null;
+ ExceptionType type = ExceptionType.Unknown;
+
+ iprot.ReadStructBegin();
+ 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,
+ InternalError,
+ ProtocolError,
+ InvalidTransform,
+ InvalidProtocol,
+ UnsupportedClientType
+ }
+
+ public ExceptionType Type
+ {
+ get { return type; }
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/TAsyncProcessor.cs b/src/jaegertracing/thrift/lib/csharp/src/TAsyncProcessor.cs
new file mode 100644
index 000000000..ab432255b
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/TAsyncProcessor.cs
@@ -0,0 +1,38 @@
+/**
+ * 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.Threading.Tasks;
+using Thrift.Protocol;
+
+namespace Thrift
+{
+ /// <summary>
+ /// Processes a message asynchronously.
+ /// </summary>
+ public interface TAsyncProcessor
+ {
+ /// <summary>
+ /// Processes the next part of the message.
+ /// </summary>
+ /// <param name="iprot">The input protocol.</param>
+ /// <param name="oprot">The output protocol.</param>
+ /// <returns>true if there's more to process, false otherwise.</returns>
+ Task<bool> ProcessAsync(TProtocol iprot, TProtocol oprot);
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/TControllingHandler.cs b/src/jaegertracing/thrift/lib/csharp/src/TControllingHandler.cs
new file mode 100644
index 000000000..7b5203a5f
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/TControllingHandler.cs
@@ -0,0 +1,29 @@
+/*
+ * 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;
+using Thrift.Server;
+
+namespace Thrift
+{
+ public interface TControllingHandler
+ {
+ TServer server { get; set; }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/TException.cs b/src/jaegertracing/thrift/lib/csharp/src/TException.cs
new file mode 100644
index 000000000..b9fae6e9f
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/TException.cs
@@ -0,0 +1,40 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+
+namespace Thrift
+{
+ public class TException : Exception
+ {
+ public TException()
+ {
+ }
+
+ public TException(string message, Exception inner = null)
+ : base(message, inner)
+ {
+ }
+
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/TProcessor.cs b/src/jaegertracing/thrift/lib/csharp/src/TProcessor.cs
new file mode 100644
index 000000000..71ce75508
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/TProcessor.cs
@@ -0,0 +1,33 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using Thrift.Protocol;
+
+namespace Thrift
+{
+ public interface TProcessor
+ {
+ bool Process(TProtocol iprot, TProtocol oprot);
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/TProcessorFactory.cs b/src/jaegertracing/thrift/lib/csharp/src/TProcessorFactory.cs
new file mode 100644
index 000000000..fdf631bc7
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/TProcessorFactory.cs
@@ -0,0 +1,30 @@
+/*
+ * 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;
+using Thrift.Server;
+using Thrift.Transport;
+
+namespace Thrift
+{
+ public interface TProcessorFactory
+ {
+ TProcessor GetProcessor(TTransport trans, TServer server = null);
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/TPrototypeProcessorFactory.cs b/src/jaegertracing/thrift/lib/csharp/src/TPrototypeProcessorFactory.cs
new file mode 100644
index 000000000..0b47261fb
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/TPrototypeProcessorFactory.cs
@@ -0,0 +1,55 @@
+/*
+ * 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;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Thrift.Server;
+using Thrift.Transport;
+
+namespace Thrift
+{
+ public class TPrototypeProcessorFactory<P, H> : TProcessorFactory where P : TProcessor
+ {
+ object[] handlerArgs = null;
+
+ public TPrototypeProcessorFactory()
+ {
+ handlerArgs = new object[0];
+ }
+
+ public TPrototypeProcessorFactory(params object[] handlerArgs)
+ {
+ this.handlerArgs = handlerArgs;
+ }
+
+ public TProcessor GetProcessor(TTransport trans, TServer server = null)
+ {
+ H handler = (H)Activator.CreateInstance(typeof(H), handlerArgs);
+
+ TControllingHandler handlerServerRef = handler as TControllingHandler;
+ if (handlerServerRef != null)
+ {
+ handlerServerRef.server = server;
+ }
+ return Activator.CreateInstance(typeof(P), new object[] { handler }) as TProcessor;
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/TSingletonProcessorFactory.cs b/src/jaegertracing/thrift/lib/csharp/src/TSingletonProcessorFactory.cs
new file mode 100644
index 000000000..ed2897ba3
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/TSingletonProcessorFactory.cs
@@ -0,0 +1,43 @@
+/*
+ * 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;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Thrift.Server;
+using Thrift.Transport;
+
+namespace Thrift
+{
+ public class TSingletonProcessorFactory : TProcessorFactory
+ {
+ private readonly TProcessor processor_;
+
+ public TSingletonProcessorFactory(TProcessor processor)
+ {
+ processor_ = processor;
+ }
+
+ public TProcessor GetProcessor(TTransport trans, TServer server = null)
+ {
+ return processor_;
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Thrift.45.csproj b/src/jaegertracing/thrift/lib/csharp/src/Thrift.45.csproj
new file mode 100644
index 000000000..146e7f8ed
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Thrift.45.csproj
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{EBCE35DA-CF6A-42BC-A357-A9C09B534299}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Thrift</RootNamespace>
+ <AssemblyName>Thrift45</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>portable</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>TRACE;DEBUG;NET45</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>portable</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE;NET45</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup>
+ <SignAssembly>true</SignAssembly>
+ </PropertyGroup>
+ <PropertyGroup>
+ <AssemblyOriginatorKeyFile>thrift.snk</AssemblyOriginatorKeyFile>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Collections\TCollections.cs" />
+ <Compile Include="Collections\THashSet.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Protocol\TAbstractBase.cs" />
+ <Compile Include="Protocol\TBase.cs" />
+ <Compile Include="Protocol\TBase64Utils.cs" />
+ <Compile Include="Protocol\TBinaryProtocol.cs" />
+ <Compile Include="Protocol\TCompactProtocol.cs" />
+ <Compile Include="Protocol\TField.cs" />
+ <Compile Include="Protocol\TJSONProtocol.cs" />
+ <Compile Include="Protocol\TList.cs" />
+ <Compile Include="Protocol\TMap.cs" />
+ <Compile Include="Protocol\TMessage.cs" />
+ <Compile Include="Protocol\TMessageType.cs" />
+ <Compile Include="Protocol\TMultiplexedProcessor.cs" />
+ <Compile Include="Protocol\TMultiplexedProtocol.cs" />
+ <Compile Include="Protocol\TProtocol.cs" />
+ <Compile Include="Protocol\TProtocolDecorator.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\TServerEventHandler.cs" />
+ <Compile Include="Server\TSimpleServer.cs" />
+ <Compile Include="Server\TThreadedServer.cs" />
+ <Compile Include="Server\TThreadPoolServer.cs" />
+ <Compile Include="TApplicationException.cs" />
+ <Compile Include="TAsyncProcessor.cs" />
+ <Compile Include="TControllingHandler.cs" />
+ <Compile Include="TException.cs" />
+ <Compile Include="TProcessor.cs" />
+ <Compile Include="TProcessorFactory.cs" />
+ <Compile Include="TPrototypeProcessorFactory.cs" />
+ <Compile Include="Transport\TBufferedTransport.cs" />
+ <Compile Include="Transport\TFramedTransport.cs" />
+ <Compile Include="Transport\THttpClient.cs" />
+ <Compile Include="Transport\THttpHandler.cs" />
+ <Compile Include="Transport\THttpTaskAsyncHandler.cs" />
+ <Compile Include="Transport\TMemoryBuffer.cs" />
+ <Compile Include="Transport\TNamedPipeClientTransport.cs" />
+ <Compile Include="Transport\TNamedPipeServerTransport.cs" />
+ <Compile Include="Transport\TServerSocket.cs" />
+ <Compile Include="Transport\TServerTransport.cs" />
+ <Compile Include="Transport\TSilverlightSocket.cs" />
+ <Compile Include="Transport\TSocket.cs" />
+ <Compile Include="Transport\TSocketVersionizer.cs" />
+ <Compile Include="Transport\TStreamTransport.cs" />
+ <Compile Include="Transport\TTLSServerSocket.cs" />
+ <Compile Include="Transport\TTLSSocket.cs" />
+ <Compile Include="Transport\TTransport.cs" />
+ <Compile Include="Transport\TTransportException.cs" />
+ <Compile Include="Transport\TTransportFactory.cs" />
+ <Compile Include="TSingletonProcessorFactory.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="Server\Collections\" />
+ <Folder Include="Server\Protocol\" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="thrift.snk" />
+ </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/src/jaegertracing/thrift/lib/csharp/src/Thrift.csproj b/src/jaegertracing/thrift/lib/csharp/src/Thrift.csproj
new file mode 100644
index 000000000..da69554d1
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Thrift.csproj
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<Project ToolsVersion="4.0" 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>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <UpgradeBackupLocation />
+ <PublishUrl>publish\</PublishUrl>
+ <Install>true</Install>
+ <InstallFrom>Disk</InstallFrom>
+ <UpdateEnabled>false</UpdateEnabled>
+ <UpdateMode>Foreground</UpdateMode>
+ <UpdateInterval>7</UpdateInterval>
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+ <UpdatePeriodically>false</UpdatePeriodically>
+ <UpdateRequired>false</UpdateRequired>
+ <MapFileExtensions>true</MapFileExtensions>
+ <ApplicationRevision>0</ApplicationRevision>
+ <ApplicationVersion>0.13.0.0</ApplicationVersion>
+ <IsWebBootstrapper>false</IsWebBootstrapper>
+ <UseApplicationTrust>false</UseApplicationTrust>
+ <BootstrapperEnabled>true</BootstrapperEnabled>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>portable</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>TRACE;DEBUG</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>portable</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>
+ </DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup>
+ <SignAssembly>true</SignAssembly>
+ </PropertyGroup>
+ <PropertyGroup>
+ <AssemblyOriginatorKeyFile>thrift.snk</AssemblyOriginatorKeyFile>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Web" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Collections\TCollections.cs" />
+ <Compile Include="Collections\THashSet.cs" />
+ <Compile Include="Net35\ExtensionsNet35.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Protocol\TAbstractBase.cs" />
+ <Compile Include="Protocol\TBase.cs" />
+ <Compile Include="Protocol\TBase64Utils.cs" />
+ <Compile Include="Protocol\TBinaryProtocol.cs" />
+ <Compile Include="Protocol\TCompactProtocol.cs" />
+ <Compile Include="Protocol\TField.cs" />
+ <Compile Include="Protocol\TJSONProtocol.cs" />
+ <Compile Include="Protocol\TList.cs" />
+ <Compile Include="Protocol\TMap.cs" />
+ <Compile Include="Protocol\TMessage.cs" />
+ <Compile Include="Protocol\TMessageType.cs" />
+ <Compile Include="Protocol\TMultiplexedProcessor.cs" />
+ <Compile Include="Protocol\TMultiplexedProtocol.cs" />
+ <Compile Include="Protocol\TProtocol.cs" />
+ <Compile Include="Protocol\TProtocolDecorator.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\TServerEventHandler.cs" />
+ <Compile Include="Server\TSimpleServer.cs" />
+ <Compile Include="Server\TThreadedServer.cs" />
+ <Compile Include="Server\TThreadPoolServer.cs" />
+ <Compile Include="TApplicationException.cs" />
+ <Compile Include="TControllingHandler.cs" />
+ <Compile Include="TException.cs" />
+ <Compile Include="TProcessor.cs" />
+ <Compile Include="TProcessorFactory.cs" />
+ <Compile Include="TPrototypeProcessorFactory.cs" />
+ <Compile Include="Transport\TBufferedTransport.cs" />
+ <Compile Include="Transport\TFramedTransport.cs" />
+ <Compile Include="Transport\THttpClient.cs" />
+ <Compile Include="Transport\THttpHandler.cs" />
+ <Compile Include="Transport\TMemoryBuffer.cs" />
+ <Compile Include="Transport\TNamedPipeClientTransport.cs" />
+ <Compile Include="Transport\TNamedPipeServerTransport.cs" />
+ <Compile Include="Transport\TServerSocket.cs" />
+ <Compile Include="Transport\TServerTransport.cs" />
+ <Compile Include="Transport\TSocket.cs" />
+ <Compile Include="Transport\TSocketVersionizer.cs" />
+ <Compile Include="Transport\TStreamTransport.cs" />
+ <Compile Include="Transport\TTLSServerSocket.cs" />
+ <Compile Include="Transport\TTLSSocket.cs" />
+ <Compile Include="Transport\TTransport.cs" />
+ <Compile Include="Transport\TTransportException.cs" />
+ <Compile Include="Transport\TTransportFactory.cs" />
+ <Compile Include="TSingletonProcessorFactory.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+ <Visible>False</Visible>
+ <ProductName>Windows Installer 3.1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="thrift.snk" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project> \ No newline at end of file
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Thrift.sln b/src/jaegertracing/thrift/lib/csharp/src/Thrift.sln
new file mode 100644
index 000000000..a29e46882
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Thrift.sln
@@ -0,0 +1,47 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Thrift", "Thrift.csproj", "{499EB63C-D74C-47E8-AE48-A2FC94538E9D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThriftTest", "..\test\ThriftTest\ThriftTest.csproj", "{48DD757F-CA95-4DD7-BDA4-58DB6F108C2C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThriftMSBuildTask", "..\ThriftMSBuildTask\ThriftMSBuildTask.csproj", "{EC0A0231-66EA-4593-A792-C6CA3BB8668E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Thrift.45", "Thrift.45.csproj", "{EBCE35DA-CF6A-42BC-A357-A9C09B534299}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThriftMVCTest", "..\test\ThriftMVCTest\ThriftMVCTest.csproj", "{891B4487-C7BA-427E-BBC8-4C596C229A10}"
+EndProject
+Global
+ 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
+ {EBCE35DA-CF6A-42BC-A357-A9C09B534299}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EBCE35DA-CF6A-42BC-A357-A9C09B534299}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EBCE35DA-CF6A-42BC-A357-A9C09B534299}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EBCE35DA-CF6A-42BC-A357-A9C09B534299}.Release|Any CPU.Build.0 = Release|Any CPU
+ {891B4487-C7BA-427E-BBC8-4C596C229A10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {891B4487-C7BA-427E-BBC8-4C596C229A10}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {891B4487-C7BA-427E-BBC8-4C596C229A10}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {891B4487-C7BA-427E-BBC8-4C596C229A10}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(MonoDevelopProperties) = preSolution
+ StartupItem = Thrift.csproj
+ EndGlobalSection
+EndGlobal
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Transport/TBufferedTransport.cs b/src/jaegertracing/thrift/lib/csharp/src/Transport/TBufferedTransport.cs
new file mode 100644
index 000000000..887098810
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Transport/TBufferedTransport.cs
@@ -0,0 +1,194 @@
+/**
+ * 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;
+using System.IO;
+
+namespace Thrift.Transport
+{
+ public class TBufferedTransport : TTransport, IDisposable
+ {
+ private readonly int bufSize;
+ private readonly MemoryStream inputBuffer = new MemoryStream(0);
+ private readonly MemoryStream outputBuffer = new MemoryStream(0);
+ private readonly TTransport transport;
+
+ public TBufferedTransport(TTransport transport, int bufSize = 1024)
+ {
+ if (transport == null)
+ throw new ArgumentNullException("transport");
+ if (bufSize <= 0)
+ throw new ArgumentException("bufSize", "Buffer size must be a positive number.");
+ this.transport = transport;
+ this.bufSize = bufSize;
+ }
+
+ public TTransport UnderlyingTransport
+ {
+ get
+ {
+ CheckNotDisposed();
+ return transport;
+ }
+ }
+
+ public override bool IsOpen
+ {
+ get
+ {
+ // We can legitimately throw here but be nice a bit.
+ // CheckNotDisposed();
+ return !_IsDisposed && transport.IsOpen;
+ }
+ }
+
+ public override void Open()
+ {
+ CheckNotDisposed();
+ transport.Open();
+ }
+
+ public override void Close()
+ {
+ CheckNotDisposed();
+ transport.Close();
+ }
+
+ public override int Read(byte[] buf, int off, int len)
+ {
+ CheckNotDisposed();
+ ValidateBufferArgs(buf, off, len);
+ if (!IsOpen)
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+
+ if (inputBuffer.Capacity < bufSize)
+ inputBuffer.Capacity = bufSize;
+
+ while (true)
+ {
+ int got = inputBuffer.Read(buf, off, len);
+ if (got > 0)
+ return got;
+
+ inputBuffer.Seek(0, SeekOrigin.Begin);
+ inputBuffer.SetLength(inputBuffer.Capacity);
+ int filled = transport.Read(inputBuffer.GetBuffer(), 0, (int)inputBuffer.Length);
+ inputBuffer.SetLength(filled);
+ if (filled == 0)
+ return 0;
+ }
+ }
+
+ public override void Write(byte[] buf, int off, int len)
+ {
+ CheckNotDisposed();
+ ValidateBufferArgs(buf, off, len);
+ if (!IsOpen)
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+ // Relative offset from "off" argument
+ int offset = 0;
+ if (outputBuffer.Length > 0)
+ {
+ int capa = (int)(outputBuffer.Capacity - outputBuffer.Length);
+ int writeSize = capa <= len ? capa : len;
+ outputBuffer.Write(buf, off, writeSize);
+ offset += writeSize;
+ if (writeSize == capa)
+ {
+ transport.Write(outputBuffer.GetBuffer(), 0, (int)outputBuffer.Length);
+ outputBuffer.SetLength(0);
+ }
+ }
+ while (len - offset >= bufSize)
+ {
+ transport.Write(buf, off + offset, bufSize);
+ offset += bufSize;
+ }
+ int remain = len - offset;
+ if (remain > 0)
+ {
+ if (outputBuffer.Capacity < bufSize)
+ outputBuffer.Capacity = bufSize;
+ outputBuffer.Write(buf, off + offset, remain);
+ }
+ }
+
+ private void InternalFlush()
+ {
+ if (!IsOpen)
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+ if (outputBuffer.Length > 0)
+ {
+ transport.Write(outputBuffer.GetBuffer(), 0, (int)outputBuffer.Length);
+ outputBuffer.SetLength(0);
+ }
+ }
+
+ public override void Flush()
+ {
+ CheckNotDisposed();
+ InternalFlush();
+
+ transport.Flush();
+ }
+
+ public override IAsyncResult BeginFlush(AsyncCallback callback, object state)
+ {
+ CheckNotDisposed();
+ InternalFlush();
+
+ return transport.BeginFlush( callback, state);
+ }
+
+ public override void EndFlush(IAsyncResult asyncResult)
+ {
+ transport.EndFlush( asyncResult);
+ }
+
+
+
+ protected void CheckNotDisposed()
+ {
+ if (_IsDisposed)
+ throw new ObjectDisposedException("TBufferedTransport");
+ }
+
+ #region " IDisposable Support "
+ protected bool _IsDisposed { get; private set; }
+
+ // IDisposable
+ protected override void Dispose(bool disposing)
+ {
+ if (!_IsDisposed)
+ {
+ if (disposing)
+ {
+ if (inputBuffer != null)
+ inputBuffer.Dispose();
+ if (outputBuffer != null)
+ outputBuffer.Dispose();
+ if (transport != null)
+ transport.Dispose();
+ }
+ }
+ _IsDisposed = true;
+ }
+ #endregion
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Transport/TFramedTransport.cs b/src/jaegertracing/thrift/lib/csharp/src/Transport/TFramedTransport.cs
new file mode 100644
index 000000000..a746a3223
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Transport/TFramedTransport.cs
@@ -0,0 +1,205 @@
+/**
+ * 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;
+using System.IO;
+
+namespace Thrift.Transport
+{
+ public class TFramedTransport : TTransport, IDisposable
+ {
+ private readonly TTransport transport;
+ private readonly MemoryStream writeBuffer = new MemoryStream(1024);
+ private readonly MemoryStream readBuffer = new MemoryStream(1024);
+
+ private const int HeaderSize = 4;
+ private readonly byte[] headerBuf = new byte[HeaderSize];
+
+ public class Factory : TTransportFactory
+ {
+ public override TTransport GetTransport(TTransport trans)
+ {
+ return new TFramedTransport(trans);
+ }
+ }
+
+ public TFramedTransport(TTransport transport)
+ {
+ if (transport == null)
+ throw new ArgumentNullException("transport");
+ this.transport = transport;
+ InitWriteBuffer();
+ }
+
+ public override void Open()
+ {
+ CheckNotDisposed();
+ transport.Open();
+ }
+
+ public override bool IsOpen
+ {
+ get
+ {
+ // We can legitimately throw here but be nice a bit.
+ // CheckNotDisposed();
+ return !_IsDisposed && transport.IsOpen;
+ }
+ }
+
+ public override void Close()
+ {
+ CheckNotDisposed();
+ transport.Close();
+ }
+
+ public override int Read(byte[] buf, int off, int len)
+ {
+ CheckNotDisposed();
+ ValidateBufferArgs(buf, off, len);
+ if (!IsOpen)
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+ 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()
+ {
+ transport.ReadAll(headerBuf, 0, HeaderSize);
+ int size = DecodeFrameSize(headerBuf);
+
+ readBuffer.SetLength(size);
+ readBuffer.Seek(0, SeekOrigin.Begin);
+ byte[] buff = readBuffer.GetBuffer();
+ transport.ReadAll(buff, 0, size);
+ }
+
+ public override void Write(byte[] buf, int off, int len)
+ {
+ CheckNotDisposed();
+ ValidateBufferArgs(buf, off, len);
+ if (!IsOpen)
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+ if (writeBuffer.Length + (long)len > (long)int.MaxValue)
+ Flush();
+ writeBuffer.Write(buf, off, len);
+ }
+
+ private void InternalFlush()
+ {
+ CheckNotDisposed();
+ if (!IsOpen)
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+ byte[] buf = writeBuffer.GetBuffer();
+ int len = (int)writeBuffer.Length;
+ int data_len = len - HeaderSize;
+ if (data_len < 0)
+ throw new System.InvalidOperationException(); // logic error actually
+
+ // Inject message header into the reserved buffer space
+ EncodeFrameSize(data_len, buf);
+
+ // Send the entire message at once
+ transport.Write(buf, 0, len);
+
+ InitWriteBuffer();
+ }
+
+ public override void Flush()
+ {
+ CheckNotDisposed();
+ InternalFlush();
+
+ transport.Flush();
+ }
+
+ public override IAsyncResult BeginFlush(AsyncCallback callback, object state)
+ {
+ CheckNotDisposed();
+ InternalFlush();
+
+ return transport.BeginFlush( callback, state);
+ }
+
+ public override void EndFlush(IAsyncResult asyncResult)
+ {
+ transport.EndFlush( asyncResult);
+ }
+
+ private void InitWriteBuffer()
+ {
+ // Reserve space for message header to be put right before sending it out
+ writeBuffer.SetLength(HeaderSize);
+ writeBuffer.Seek(0, SeekOrigin.End);
+ }
+
+ private static void EncodeFrameSize(int frameSize, byte[] buf)
+ {
+ buf[0] = (byte)(0xff & (frameSize >> 24));
+ buf[1] = (byte)(0xff & (frameSize >> 16));
+ buf[2] = (byte)(0xff & (frameSize >> 8));
+ buf[3] = (byte)(0xff & (frameSize));
+ }
+
+ private static int DecodeFrameSize(byte[] buf)
+ {
+ return
+ ((buf[0] & 0xff) << 24) |
+ ((buf[1] & 0xff) << 16) |
+ ((buf[2] & 0xff) << 8) |
+ ((buf[3] & 0xff));
+ }
+
+
+ private void CheckNotDisposed()
+ {
+ if (_IsDisposed)
+ throw new ObjectDisposedException("TFramedTransport");
+ }
+
+ #region " IDisposable Support "
+ private bool _IsDisposed;
+
+ // IDisposable
+ protected override void Dispose(bool disposing)
+ {
+ if (!_IsDisposed)
+ {
+ if (disposing)
+ {
+ if (readBuffer != null)
+ readBuffer.Dispose();
+ if (writeBuffer != null)
+ writeBuffer.Dispose();
+ if (transport != null)
+ transport.Dispose();
+ }
+ }
+ _IsDisposed = true;
+ }
+ #endregion
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Transport/THttpClient.cs b/src/jaegertracing/thrift/lib/csharp/src/Transport/THttpClient.cs
new file mode 100644
index 000000000..986799cd2
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Transport/THttpClient.cs
@@ -0,0 +1,486 @@
+/**
+ * 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;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Threading;
+using System.Linq;
+using System.Security.Cryptography.X509Certificates;
+using System.IO.Compression;
+
+namespace Thrift.Transport
+{
+ public class THttpClient : TTransport, IDisposable
+ {
+ private readonly Uri uri;
+ private readonly X509Certificate[] certificates;
+ private Stream inputStream;
+ private MemoryStream outputStream = new MemoryStream();
+
+ // Timeouts in milliseconds
+ private int connectTimeout = 30000;
+
+ private int readTimeout = 30000;
+
+ private IDictionary<string, string> customHeaders = new Dictionary<string, string>();
+ private string userAgent = "C#/THttpClient";
+
+#if !SILVERLIGHT
+ private IWebProxy proxy = WebRequest.DefaultWebProxy;
+#endif
+
+ public THttpClient(Uri u)
+ : this(u, Enumerable.Empty<X509Certificate>())
+ {
+ }
+ public THttpClient(Uri u, string userAgent)
+ : this(u, userAgent, Enumerable.Empty<X509Certificate>())
+ {
+ }
+
+ public THttpClient(Uri u, IEnumerable<X509Certificate> certificates)
+ {
+ uri = u;
+ this.certificates = (certificates ?? Enumerable.Empty<X509Certificate>()).ToArray();
+ }
+ public THttpClient(Uri u, string userAgent, IEnumerable<X509Certificate> certificates)
+ {
+ uri = u;
+ this.userAgent = userAgent;
+ this.certificates = (certificates ?? Enumerable.Empty<X509Certificate>()).ToArray();
+ }
+
+ public int ConnectTimeout
+ {
+ set
+ {
+ connectTimeout = value;
+ }
+ }
+
+ public int ReadTimeout
+ {
+ set
+ {
+ readTimeout = value;
+ }
+ }
+
+ public IDictionary<string, string> CustomHeaders
+ {
+ get
+ {
+ return customHeaders;
+ }
+ }
+
+#if !SILVERLIGHT
+ public IWebProxy Proxy
+ {
+ set
+ {
+ proxy = value;
+ }
+ }
+#endif
+
+ 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, "No request has been sent");
+ }
+
+ try
+ {
+ int ret = inputStream.Read(buf, off, len);
+
+ if (ret == -1)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.EndOfFile, "No more data available");
+ }
+
+ return ret;
+ }
+ catch (IOException iox)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.Unknown, iox.ToString(), iox);
+ }
+ }
+
+ public override void Write(byte[] buf, int off, int len)
+ {
+ outputStream.Write(buf, off, len);
+ }
+
+#if !SILVERLIGHT
+ public override void Flush()
+ {
+ try
+ {
+ SendRequest();
+ }
+ finally
+ {
+ outputStream = new MemoryStream();
+ }
+ }
+
+ private void SendRequest()
+ {
+ try
+ {
+ HttpWebRequest connection = CreateRequest();
+ connection.Headers.Add("Accept-Encoding", "gzip, deflate");
+
+ byte[] data = outputStream.ToArray();
+ connection.ContentLength = data.Length;
+
+ using (Stream requestStream = connection.GetRequestStream())
+ {
+ requestStream.Write(data, 0, data.Length);
+
+ // Resolve HTTP hang that can happens after successive calls by making sure
+ // that we release the response and response stream. To support this, we copy
+ // the response to a memory stream.
+ using (var response = connection.GetResponse())
+ {
+ using (var responseStream = response.GetResponseStream())
+ {
+ // Copy the response to a memory stream so that we can
+ // cleanly close the response and response stream.
+ inputStream = new MemoryStream();
+ byte[] buffer = new byte[8192]; // multiple of 4096
+ int bytesRead;
+ while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0)
+ {
+ inputStream.Write(buffer, 0, bytesRead);
+ }
+ inputStream.Seek(0, 0);
+ }
+
+ var encodings = response.Headers.GetValues("Content-Encoding");
+ if (encodings != null)
+ {
+ foreach (var encoding in encodings)
+ {
+ switch (encoding)
+ {
+ case "gzip":
+ DecompressGZipped(ref inputStream);
+ break;
+ case "deflate":
+ DecompressDeflated(ref inputStream);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (IOException iox)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.Unknown, iox.ToString(), iox);
+ }
+ catch (WebException wx)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.Unknown, "Couldn't connect to server: " + wx, wx);
+ }
+ }
+
+ private void DecompressDeflated(ref Stream inputStream)
+ {
+ var tmp = new MemoryStream();
+ using (var decomp = new DeflateStream(inputStream, CompressionMode.Decompress))
+ {
+ decomp.CopyTo(tmp);
+ }
+ inputStream.Dispose();
+ inputStream = tmp;
+ inputStream.Seek(0, 0);
+ }
+
+ private void DecompressGZipped(ref Stream inputStream)
+ {
+ var tmp = new MemoryStream();
+ using (var decomp = new GZipStream(inputStream, CompressionMode.Decompress))
+ {
+ decomp.CopyTo(tmp);
+ }
+ inputStream.Dispose();
+ inputStream = tmp;
+ inputStream.Seek(0, 0);
+ }
+#endif
+ private HttpWebRequest CreateRequest()
+ {
+ HttpWebRequest connection = (HttpWebRequest)WebRequest.Create(uri);
+
+
+#if !SILVERLIGHT
+ // Adding certificates through code is not supported with WP7 Silverlight
+ // see "Windows Phone 7 and Certificates_FINAL_121610.pdf"
+ connection.ClientCertificates.AddRange(certificates);
+
+ if (connectTimeout > 0)
+ {
+ connection.Timeout = connectTimeout;
+ }
+ if (readTimeout > 0)
+ {
+ connection.ReadWriteTimeout = readTimeout;
+ }
+#endif
+ // Make the request
+ connection.ContentType = "application/x-thrift";
+ connection.Accept = "application/x-thrift";
+ connection.UserAgent = userAgent;
+ connection.Method = "POST";
+#if !SILVERLIGHT
+ connection.ProtocolVersion = HttpVersion.Version10;
+#endif
+
+ //add custom headers here
+ foreach (KeyValuePair<string, string> item in customHeaders)
+ {
+#if !SILVERLIGHT
+ connection.Headers.Add(item.Key, item.Value);
+#else
+ connection.Headers[item.Key] = item.Value;
+#endif
+ }
+
+#if !SILVERLIGHT
+ connection.Proxy = proxy;
+#endif
+
+ return connection;
+ }
+
+ public override IAsyncResult BeginFlush(AsyncCallback callback, object state)
+ {
+ // Extract request and reset buffer
+ var data = outputStream.ToArray();
+
+ //requestBuffer_ = new MemoryStream();
+
+ try
+ {
+ // Create connection object
+ var flushAsyncResult = new FlushAsyncResult(callback, state);
+ flushAsyncResult.Connection = CreateRequest();
+
+ flushAsyncResult.Data = data;
+
+
+ flushAsyncResult.Connection.BeginGetRequestStream(GetRequestStreamCallback, flushAsyncResult);
+ return flushAsyncResult;
+
+ }
+ catch (IOException iox)
+ {
+ throw new TTransportException(iox.ToString(), iox);
+ }
+ }
+
+ public override void EndFlush(IAsyncResult asyncResult)
+ {
+ try
+ {
+ var flushAsyncResult = (FlushAsyncResult)asyncResult;
+
+ if (!flushAsyncResult.IsCompleted)
+ {
+ var waitHandle = flushAsyncResult.AsyncWaitHandle;
+ waitHandle.WaitOne(); // blocking INFINITEly
+ waitHandle.Close();
+ }
+
+ if (flushAsyncResult.AsyncException != null)
+ {
+ throw flushAsyncResult.AsyncException;
+ }
+ }
+ finally
+ {
+ outputStream = new MemoryStream();
+ }
+
+ }
+
+ private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
+ {
+ var flushAsyncResult = (FlushAsyncResult)asynchronousResult.AsyncState;
+ try
+ {
+ var reqStream = flushAsyncResult.Connection.EndGetRequestStream(asynchronousResult);
+ reqStream.Write(flushAsyncResult.Data, 0, flushAsyncResult.Data.Length);
+ reqStream.Flush();
+ reqStream.Close();
+
+ // Start the asynchronous operation to get the response
+ flushAsyncResult.Connection.BeginGetResponse(GetResponseCallback, flushAsyncResult);
+ }
+ catch (Exception exception)
+ {
+ flushAsyncResult.AsyncException = new TTransportException(exception.ToString(), exception);
+ flushAsyncResult.UpdateStatusToComplete();
+ flushAsyncResult.NotifyCallbackWhenAvailable();
+ }
+ }
+
+ private void GetResponseCallback(IAsyncResult asynchronousResult)
+ {
+ var flushAsyncResult = (FlushAsyncResult)asynchronousResult.AsyncState;
+ try
+ {
+ inputStream = flushAsyncResult.Connection.EndGetResponse(asynchronousResult).GetResponseStream();
+ }
+ catch (Exception exception)
+ {
+ flushAsyncResult.AsyncException = new TTransportException(exception.ToString(), exception);
+ }
+ flushAsyncResult.UpdateStatusToComplete();
+ flushAsyncResult.NotifyCallbackWhenAvailable();
+ }
+
+ // Based on http://msmvps.com/blogs/luisabreu/archive/2009/06/15/multithreading-implementing-the-iasyncresult-interface.aspx
+ class FlushAsyncResult : IAsyncResult
+ {
+ private volatile Boolean _isCompleted;
+ private ManualResetEvent _evt;
+ private readonly AsyncCallback _cbMethod;
+ private readonly object _state;
+
+ public FlushAsyncResult(AsyncCallback cbMethod, object state)
+ {
+ _cbMethod = cbMethod;
+ _state = state;
+ }
+
+ internal byte[] Data { get; set; }
+ internal HttpWebRequest Connection { get; set; }
+ internal TTransportException AsyncException { get; set; }
+
+ public object AsyncState
+ {
+ get { return _state; }
+ }
+ public WaitHandle AsyncWaitHandle
+ {
+ get { return GetEvtHandle(); }
+ }
+ public bool CompletedSynchronously
+ {
+ get { return false; }
+ }
+ public bool IsCompleted
+ {
+ get { return _isCompleted; }
+ }
+ private readonly object _locker = new object();
+ private ManualResetEvent GetEvtHandle()
+ {
+ lock (_locker)
+ {
+ if (_evt == null)
+ {
+ _evt = new ManualResetEvent(false);
+ }
+ if (_isCompleted)
+ {
+ _evt.Set();
+ }
+ }
+ return _evt;
+ }
+ internal void UpdateStatusToComplete()
+ {
+ _isCompleted = true; //1. set _iscompleted to true
+ lock (_locker)
+ {
+ if (_evt != null)
+ {
+ _evt.Set(); //2. set the event, when it exists
+ }
+ }
+ }
+
+ internal void NotifyCallbackWhenAvailable()
+ {
+ if (_cbMethod != null)
+ {
+ _cbMethod(this);
+ }
+ }
+ }
+
+ #region " IDisposable Support "
+ private bool _IsDisposed;
+
+ // IDisposable
+ protected override void Dispose(bool disposing)
+ {
+ if (!_IsDisposed)
+ {
+ if (disposing)
+ {
+ if (inputStream != null)
+ inputStream.Dispose();
+ if (outputStream != null)
+ outputStream.Dispose();
+ }
+ }
+ _IsDisposed = true;
+ }
+ #endregion
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Transport/THttpHandler.cs b/src/jaegertracing/thrift/lib/csharp/src/Transport/THttpHandler.cs
new file mode 100644
index 000000000..4115ef95a
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Transport/THttpHandler.cs
@@ -0,0 +1,102 @@
+/**
+ * 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;
+using System.Web;
+using System.Net;
+using System.IO;
+
+using Thrift.Protocol;
+
+namespace Thrift.Transport
+{
+ public class THttpHandler : IHttpHandler
+ {
+ protected TProcessor processor;
+
+ protected TProtocolFactory inputProtocolFactory;
+ protected TProtocolFactory outputProtocolFactory;
+
+ protected const string contentType = "application/x-thrift";
+ protected System.Text.Encoding encoding = System.Text.Encoding.UTF8;
+
+ public THttpHandler(TProcessor processor)
+ : this(processor, new TBinaryProtocol.Factory())
+ {
+
+ }
+
+ public THttpHandler(TProcessor processor, TProtocolFactory protocolFactory)
+ : this(processor, protocolFactory, protocolFactory)
+ {
+
+ }
+
+ public THttpHandler(TProcessor processor, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory)
+ {
+ this.processor = processor;
+ this.inputProtocolFactory = inputProtocolFactory;
+ this.outputProtocolFactory = outputProtocolFactory;
+ }
+
+ public void ProcessRequest(HttpListenerContext context)
+ {
+ context.Response.ContentType = contentType;
+ context.Response.ContentEncoding = encoding;
+ ProcessRequest(context.Request.InputStream, context.Response.OutputStream);
+ }
+
+ public void ProcessRequest(HttpContext context)
+ {
+ context.Response.ContentType = contentType;
+ context.Response.ContentEncoding = encoding;
+ ProcessRequest(context.Request.InputStream, context.Response.OutputStream);
+ }
+
+ public void ProcessRequest(Stream input, Stream output)
+ {
+ TTransport transport = new TStreamTransport(input,output);
+
+ try
+ {
+ var inputProtocol = inputProtocolFactory.GetProtocol(transport);
+ var outputProtocol = outputProtocolFactory.GetProtocol(transport);
+
+ while (processor.Process(inputProtocol, outputProtocol))
+ {
+ }
+ }
+ catch (TTransportException)
+ {
+ // Client died, just move on
+ }
+ finally
+ {
+ transport.Close();
+ }
+ }
+
+ public bool IsReusable
+ {
+ get { return true; }
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Transport/THttpTaskAsyncHandler.cs b/src/jaegertracing/thrift/lib/csharp/src/Transport/THttpTaskAsyncHandler.cs
new file mode 100644
index 000000000..e491f32cb
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Transport/THttpTaskAsyncHandler.cs
@@ -0,0 +1,97 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System.Threading.Tasks;
+using System.Web;
+using Thrift.Protocol;
+
+namespace Thrift.Transport
+{
+ /// <summary>
+ /// An async task based HTTP handler for processing thrift services.
+ /// </summary>
+ public class THttpTaskAsyncHandler : HttpTaskAsyncHandler
+ {
+ private readonly TAsyncProcessor _processor;
+ private readonly TProtocolFactory _inputProtocolFactory;
+ private readonly TProtocolFactory _outputProtocolFactory;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="THttpTaskAsyncHandler"/> class
+ /// using the <see cref="TBinaryProtocol.Factory"/> for both input and output streams.
+ /// </summary>
+ /// <param name="processor">The async processor implementation.</param>
+ public THttpTaskAsyncHandler(TAsyncProcessor processor)
+ : this(processor, new TBinaryProtocol.Factory())
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="THttpTaskAsyncHandler"/> class
+ /// using <paramref name="protocolFactory"/> for both input and output streams.
+ /// </summary>
+ /// <param name="processor">The async processor implementation.</param>
+ /// <param name="protocolFactory">The protocol factory.</param>
+ public THttpTaskAsyncHandler(TAsyncProcessor processor, TProtocolFactory protocolFactory)
+ : this(processor, protocolFactory, protocolFactory)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="THttpTaskAsyncHandler"/> class.
+ /// </summary>
+ /// <param name="processor">The async processor implementation.</param>
+ /// <param name="inputProtocolFactory">The input protocol factory.</param>
+ /// <param name="outputProtocolFactory">The output protocol factory.</param>
+ public THttpTaskAsyncHandler(TAsyncProcessor processor, TProtocolFactory inputProtocolFactory,
+ TProtocolFactory outputProtocolFactory)
+ {
+ _processor = processor;
+ _inputProtocolFactory = inputProtocolFactory;
+ _outputProtocolFactory = outputProtocolFactory;
+ }
+
+ public override async Task ProcessRequestAsync(HttpContext context)
+ {
+ var transport = new TStreamTransport(context.Request.InputStream, context.Response.OutputStream);
+
+ try
+ {
+ var input = _inputProtocolFactory.GetProtocol(transport);
+ var output = _outputProtocolFactory.GetProtocol(transport);
+
+ while (await _processor.ProcessAsync(input, output))
+ {
+ }
+ }
+ catch (TTransportException)
+ {
+ // Client died, just move on
+ }
+ finally
+ {
+ transport.Close();
+ }
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Transport/TMemoryBuffer.cs b/src/jaegertracing/thrift/lib/csharp/src/Transport/TMemoryBuffer.cs
new file mode 100644
index 000000000..303d08329
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Transport/TMemoryBuffer.cs
@@ -0,0 +1,117 @@
+/**
+ * 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;
+using System.IO;
+using System.Reflection;
+using Thrift.Protocol;
+
+namespace Thrift.Transport
+{
+ public class TMemoryBuffer : TTransport
+ {
+
+ private readonly MemoryStream byteStream;
+
+ public TMemoryBuffer()
+ {
+ byteStream = new MemoryStream();
+ }
+
+ public TMemoryBuffer(byte[] buf)
+ {
+ byteStream = new MemoryStream(buf);
+ }
+
+ public override void Open()
+ {
+ /** do nothing **/
+ }
+
+ public override void Close()
+ {
+ /** do nothing **/
+ }
+
+ public override int Read(byte[] buf, int off, int len)
+ {
+ return byteStream.Read(buf, off, len);
+ }
+
+ public override void Write(byte[] buf, int off, int len)
+ {
+ byteStream.Write(buf, off, len);
+ }
+
+ public byte[] GetBuffer()
+ {
+ return byteStream.ToArray();
+ }
+
+
+ public override bool IsOpen
+ {
+ get { return true; }
+ }
+
+ public static byte[] Serialize(TAbstractBase s)
+ {
+ var t = new TMemoryBuffer();
+ var p = new TBinaryProtocol(t);
+
+ s.Write(p);
+
+ return t.GetBuffer();
+ }
+
+ public static T DeSerialize<T>(byte[] buf) where T : TAbstractBase
+ {
+ var trans = new TMemoryBuffer(buf);
+ var p = new TBinaryProtocol(trans);
+ if (typeof(TBase).IsAssignableFrom(typeof(T)))
+ {
+ var method = typeof(T).GetMethod("Read", BindingFlags.Instance | BindingFlags.Public);
+ var t = Activator.CreateInstance<T>();
+ method.Invoke(t, new object[] { p });
+ return t;
+ }
+ else
+ {
+ var method = typeof(T).GetMethod("Read", BindingFlags.Static | BindingFlags.Public);
+ return (T)method.Invoke(null, new object[] { p });
+ }
+ }
+
+ private bool _IsDisposed;
+
+ // IDisposable
+ protected override void Dispose(bool disposing)
+ {
+ if (!_IsDisposed)
+ {
+ if (disposing)
+ {
+ if (byteStream != null)
+ byteStream.Dispose();
+ }
+ }
+ _IsDisposed = true;
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Transport/TNamedPipeClientTransport.cs b/src/jaegertracing/thrift/lib/csharp/src/Transport/TNamedPipeClientTransport.cs
new file mode 100644
index 000000000..49a50aa5b
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Transport/TNamedPipeClientTransport.cs
@@ -0,0 +1,111 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.IO.Pipes;
+using System.Threading;
+
+namespace Thrift.Transport
+{
+ public class TNamedPipeClientTransport : TTransport
+ {
+ private NamedPipeClientStream client;
+ private string ServerName;
+ private string PipeName;
+ private int ConnectTimeout;
+
+ public TNamedPipeClientTransport(string pipe, int timeout = Timeout.Infinite)
+ {
+ ServerName = ".";
+ PipeName = pipe;
+ ConnectTimeout = timeout;
+ }
+
+ public TNamedPipeClientTransport(string server, string pipe, int timeout = Timeout.Infinite)
+ {
+ ServerName = (server != "") ? server : ".";
+ PipeName = pipe;
+ ConnectTimeout = timeout;
+ }
+
+ public override bool IsOpen
+ {
+ get { return client != null && client.IsConnected; }
+ }
+
+ public override void Open()
+ {
+ if (IsOpen)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.AlreadyOpen);
+ }
+ client = new NamedPipeClientStream(ServerName, PipeName, PipeDirection.InOut, PipeOptions.None);
+ client.Connect(ConnectTimeout);
+ }
+
+ public override void Close()
+ {
+ if (client != null)
+ {
+ client.Close();
+ client = null;
+ }
+ }
+
+ public override int Read(byte[] buf, int off, int len)
+ {
+ if (client == null)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+ }
+
+ return client.Read(buf, off, len);
+ }
+
+ public override void Write(byte[] buf, int off, int len)
+ {
+ if (client == null)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+ }
+
+ // if necessary, send the data in chunks
+ // there's a system limit around 0x10000 bytes that we hit otherwise
+ // MSDN: "Pipe write operations across a network are limited to 65,535 bytes per write. For more information regarding pipes, see the Remarks section."
+ var nBytes = Math.Min(len, 15 * 4096); // 16 would exceed the limit
+ while (nBytes > 0)
+ {
+ client.Write(buf, off, nBytes);
+
+ off += nBytes;
+ len -= nBytes;
+ nBytes = Math.Min(len, nBytes);
+ }
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ client.Dispose();
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Transport/TNamedPipeServerTransport.cs b/src/jaegertracing/thrift/lib/csharp/src/Transport/TNamedPipeServerTransport.cs
new file mode 100644
index 000000000..32215cfc1
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Transport/TNamedPipeServerTransport.cs
@@ -0,0 +1,296 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.IO.Pipes;
+using System.Threading;
+using System.Security.Principal;
+
+namespace Thrift.Transport
+{
+ public class TNamedPipeServerTransport : TServerTransport
+ {
+ /// <summary>
+ /// This is the address of the Pipe on the localhost.
+ /// </summary>
+ private readonly string pipeAddress;
+ private NamedPipeServerStream stream = null;
+ private bool asyncMode = true;
+
+ public TNamedPipeServerTransport(string pipeAddress)
+ {
+ this.pipeAddress = pipeAddress;
+ }
+
+ public override void Listen()
+ {
+ // nothing to do here
+ }
+
+ public override void Close()
+ {
+ if (stream != null)
+ {
+ try
+ {
+ stream.Close();
+ stream.Dispose();
+ }
+ finally
+ {
+ stream = null;
+ }
+ }
+ }
+
+ private void EnsurePipeInstance()
+ {
+ if (stream == null)
+ {
+ var direction = PipeDirection.InOut;
+ var maxconn = NamedPipeServerStream.MaxAllowedServerInstances;
+ var mode = PipeTransmissionMode.Byte;
+ var options = asyncMode ? PipeOptions.Asynchronous : PipeOptions.None;
+ const int INBUF_SIZE = 4096;
+ const int OUTBUF_SIZE = 4096;
+
+ // security
+ var security = new PipeSecurity();
+ security.AddAccessRule(
+ new PipeAccessRule(
+ new SecurityIdentifier(WellKnownSidType.WorldSid, null),
+ PipeAccessRights.Read | PipeAccessRights.Write | PipeAccessRights.Synchronize | PipeAccessRights.CreateNewInstance,
+ System.Security.AccessControl.AccessControlType.Allow
+ )
+ );
+
+ try
+ {
+ stream = new NamedPipeServerStream(pipeAddress, direction, maxconn, mode, options, INBUF_SIZE, OUTBUF_SIZE, security);
+ }
+ catch (NotImplementedException) // Mono still does not support async, fallback to sync
+ {
+ if (asyncMode)
+ {
+ options &= (~PipeOptions.Asynchronous);
+ stream = new NamedPipeServerStream(pipeAddress, direction, maxconn, mode, options, INBUF_SIZE, OUTBUF_SIZE, security);
+ asyncMode = false;
+ }
+ else
+ {
+ throw;
+ }
+ }
+
+ }
+ }
+
+ protected override TTransport AcceptImpl()
+ {
+ try
+ {
+ EnsurePipeInstance();
+
+ if (asyncMode)
+ {
+ var evt = new ManualResetEvent(false);
+ Exception eOuter = null;
+
+ stream.BeginWaitForConnection(asyncResult =>
+ {
+ try
+ {
+ if (stream != null)
+ stream.EndWaitForConnection(asyncResult);
+ else
+ eOuter = new TTransportException(TTransportException.ExceptionType.Interrupted);
+ }
+ catch (Exception e)
+ {
+ if (stream != null)
+ eOuter = e;
+ else
+ eOuter = new TTransportException(TTransportException.ExceptionType.Interrupted, e.Message, e);
+ }
+ evt.Set();
+ }, null);
+
+ evt.WaitOne();
+
+ if (eOuter != null)
+ throw eOuter; // rethrow exception
+ }
+ else
+ {
+ stream.WaitForConnection();
+ }
+
+ var trans = new ServerTransport(stream,asyncMode);
+ stream = null; // pass ownership to ServerTransport
+ return trans;
+ }
+ catch (TTransportException)
+ {
+ Close();
+ throw;
+ }
+ catch (Exception e)
+ {
+ Close();
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen, e.Message, e);
+ }
+ }
+
+ private class ServerTransport : TTransport
+ {
+ private NamedPipeServerStream stream;
+ private bool asyncMode;
+
+ public ServerTransport(NamedPipeServerStream stream, bool asyncMode)
+ {
+ this.stream = stream;
+ this.asyncMode = asyncMode;
+ }
+
+ public override bool IsOpen
+ {
+ get { return stream != null && stream.IsConnected; }
+ }
+
+ public override void Open()
+ {
+ }
+
+ public override void Close()
+ {
+ if (stream != null)
+ stream.Close();
+ }
+
+ public override int Read(byte[] buf, int off, int len)
+ {
+ if (stream == null)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+ }
+
+ if (asyncMode)
+ {
+ Exception eOuter = null;
+ var evt = new ManualResetEvent(false);
+ int retval = 0;
+
+ stream.BeginRead(buf, off, len, asyncResult =>
+ {
+ try
+ {
+ if (stream != null)
+ retval = stream.EndRead(asyncResult);
+ else
+ eOuter = new TTransportException(TTransportException.ExceptionType.Interrupted);
+ }
+ catch (Exception e)
+ {
+ if (stream != null)
+ eOuter = e;
+ else
+ eOuter = new TTransportException(TTransportException.ExceptionType.Interrupted, e.Message, e);
+ }
+ evt.Set();
+ }, null);
+
+ evt.WaitOne();
+
+ if (eOuter != null)
+ throw eOuter; // rethrow exception
+ else
+ return retval;
+ }
+ else
+ {
+ return stream.Read(buf, off, len);
+ }
+ }
+
+ public override void Write(byte[] buf, int off, int len)
+ {
+ if (stream == null)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+ }
+
+ // if necessary, send the data in chunks
+ // there's a system limit around 0x10000 bytes that we hit otherwise
+ // MSDN: "Pipe write operations across a network are limited to 65,535 bytes per write. For more information regarding pipes, see the Remarks section."
+ var nBytes = Math.Min(len, 15 * 4096); // 16 would exceed the limit
+ while (nBytes > 0)
+ {
+
+ if (asyncMode)
+ {
+ Exception eOuter = null;
+ var evt = new ManualResetEvent(false);
+
+ stream.BeginWrite(buf, off, nBytes, asyncResult =>
+ {
+ try
+ {
+ if (stream != null)
+ stream.EndWrite(asyncResult);
+ else
+ eOuter = new TTransportException(TTransportException.ExceptionType.Interrupted);
+ }
+ catch (Exception e)
+ {
+ if (stream != null)
+ eOuter = e;
+ else
+ eOuter = new TTransportException(TTransportException.ExceptionType.Interrupted, e.Message, e);
+ }
+ evt.Set();
+ }, null);
+
+ evt.WaitOne();
+
+ if (eOuter != null)
+ throw eOuter; // rethrow exception
+ }
+ else
+ {
+ stream.Write(buf, off, nBytes);
+ }
+
+ off += nBytes;
+ len -= nBytes;
+ nBytes = Math.Min(len, nBytes);
+ }
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (stream != null)
+ stream.Dispose();
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Transport/TServerSocket.cs b/src/jaegertracing/thrift/lib/csharp/src/Transport/TServerSocket.cs
new file mode 100644
index 000000000..d8ec62ab3
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Transport/TServerSocket.cs
@@ -0,0 +1,176 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.Net.Sockets;
+
+
+namespace Thrift.Transport
+{
+ public class TServerSocket : TServerTransport
+ {
+ /// <summary>
+ /// Underlying server with socket.
+ /// </summary>
+ private TcpListener server = null;
+
+ /// <summary>
+ /// Port to listen on.
+ /// </summary>
+ private int port = 0;
+
+ /// <summary>
+ /// Timeout for client sockets from accept.
+ /// </summary>
+ private int clientTimeout = 0;
+
+ /// <summary>
+ /// Whether or not to wrap new TSocket connections in buffers.
+ /// </summary>
+ private bool useBufferedSockets = false;
+
+ /// <summary>
+ /// Creates a server socket from underlying socket object.
+ /// </summary>
+ public TServerSocket(TcpListener listener)
+ : this(listener, 0)
+ {
+ }
+
+ /// <summary>
+ /// Creates a server socket from underlying socket object.
+ /// </summary>
+ public TServerSocket(TcpListener listener, int clientTimeout)
+ {
+ this.server = listener;
+ this.clientTimeout = clientTimeout;
+ }
+
+ /// <summary>
+ /// Creates just a port listening server socket.
+ /// </summary>
+ public TServerSocket(int port)
+ : this(port, 0)
+ {
+ }
+
+ /// <summary>
+ /// Creates just a port listening server socket.
+ /// </summary>
+ public TServerSocket(int port, int clientTimeout)
+ : this(port, clientTimeout, false)
+ {
+ }
+
+ public TServerSocket(int port, int clientTimeout, bool useBufferedSockets)
+ {
+ this.port = port;
+ this.clientTimeout = clientTimeout;
+ this.useBufferedSockets = useBufferedSockets;
+ try
+ {
+ // Make server socket
+ this.server = TSocketVersionizer.CreateTcpListener(this.port);
+ this.server.Server.NoDelay = true;
+ }
+ catch (Exception ex)
+ {
+ server = null;
+ throw new TTransportException("Could not create ServerSocket on port " + this.port + ".", ex);
+ }
+ }
+
+ public override void Listen()
+ {
+ // Make sure not to block on accept
+ if (server != null)
+ {
+ try
+ {
+ server.Start();
+ }
+ catch (SocketException sx)
+ {
+ throw new TTransportException("Could not accept on listening socket: " + sx.Message, sx);
+ }
+ }
+ }
+
+ protected override TTransport AcceptImpl()
+ {
+ if (server == null)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen, "No underlying server socket.");
+ }
+ try
+ {
+ TSocket result2 = null;
+ TcpClient result = server.AcceptTcpClient();
+ try
+ {
+ result2 = new TSocket(result);
+ result2.Timeout = clientTimeout;
+ if (useBufferedSockets)
+ {
+ TBufferedTransport result3 = new TBufferedTransport(result2);
+ return result3;
+ }
+ else
+ {
+ return result2;
+ }
+ }
+ catch (System.Exception)
+ {
+ // If a TSocket was successfully created, then let
+ // it do proper cleanup of the TcpClient object.
+ if (result2 != null)
+ result2.Dispose();
+ else // Otherwise, clean it up ourselves.
+ ((IDisposable)result).Dispose();
+ throw;
+ }
+ }
+ catch (Exception ex)
+ {
+ throw new TTransportException(ex.ToString(), ex);
+ }
+ }
+
+ public override void Close()
+ {
+ if (server != null)
+ {
+ try
+ {
+ server.Stop();
+ }
+ catch (Exception ex)
+ {
+ throw new TTransportException("WARNING: Could not close server socket: " + ex, ex);
+ }
+ server = null;
+ }
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Transport/TServerTransport.cs b/src/jaegertracing/thrift/lib/csharp/src/Transport/TServerTransport.cs
new file mode 100644
index 000000000..e63880be1
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Transport/TServerTransport.cs
@@ -0,0 +1,44 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+
+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/src/jaegertracing/thrift/lib/csharp/src/Transport/TSilverlightSocket.cs b/src/jaegertracing/thrift/lib/csharp/src/Transport/TSilverlightSocket.cs
new file mode 100644
index 000000000..40469ab40
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Transport/TSilverlightSocket.cs
@@ -0,0 +1,393 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+/* only for silverlight */
+#if SILVERLIGHT
+
+using System;
+using System.Net.Sockets;
+using System.IO;
+using System.Net;
+using System.Threading;
+
+namespace Thrift.Transport
+{
+ public class TSilverlightSocket : TTransport
+ {
+ Socket socket = null;
+ static ManualResetEvent readAsyncComplete = new ManualResetEvent(false);
+ public event EventHandler<SocketAsyncEventArgs> connectHandler = null;
+
+ // memory stream for write cache.
+ private MemoryStream outputStream = new MemoryStream();
+
+ private string host = null;
+ private int port = 0;
+ private int timeout = 0;
+
+ // constructor
+ public TSilverlightSocket(string host, int port)
+ : this(host, port, 0)
+ {
+ }
+
+ // constructor
+ public TSilverlightSocket(string host, int port, int timeout)
+ {
+ this.host = host;
+ this.port = port;
+ this.timeout = timeout;
+
+ InitSocket();
+ }
+
+ private void InitSocket()
+ {
+ // Create a stream-based, TCP socket using the InterNetwork Address Family.
+ socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ socket.NoDelay = true;
+ }
+
+ public int Timeout
+ {
+ set
+ {
+ timeout = value;
+ }
+ }
+
+ public string Host
+ {
+ get
+ {
+ return host;
+ }
+ }
+
+ public int Port
+ {
+ get
+ {
+ return port;
+ }
+ }
+
+ public override bool IsOpen
+ {
+ get
+ {
+ if (socket == null)
+ {
+ return false;
+ }
+
+ return socket.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 (socket == null)
+ {
+ InitSocket();
+ }
+
+ if (timeout == 0) // no timeout -> infinite
+ {
+ timeout = 10000; // set a default timeout for WP.
+ }
+
+ {
+ // Create DnsEndPoint. The hostName and port are passed in to this method.
+ DnsEndPoint hostEntry = new DnsEndPoint(this.host, this.port);
+
+ // Create a SocketAsyncEventArgs object to be used in the connection request
+ SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
+ socketEventArg.RemoteEndPoint = hostEntry;
+
+ // Inline event handler for the Completed event.
+ // Note: This event handler was implemented inline in order to make this method self-contained.
+ socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
+ {
+ if (connectHandler != null)
+ {
+ connectHandler(this, e);
+ }
+ });
+
+ // Make an asynchronous Connect request over the socket
+ socket.ConnectAsync(socketEventArg);
+ }
+ }
+
+ public override int Read(byte[] buf, int off, int len)
+ {
+ bool _timeout = true;
+ string _error = null;
+ int _recvBytes = -1;
+
+ if (socket == null)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Socket is not open");
+ }
+
+ // Create SocketAsyncEventArgs context object
+ SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
+ socketEventArg.RemoteEndPoint = socket.RemoteEndPoint;
+
+ // Setup the buffer to receive the data
+ socketEventArg.SetBuffer(buf, off, len);
+
+ // Inline event handler for the Completed event.
+ // Note: This even handler was implemented inline in order to make
+ // this method self-contained.
+ socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
+ {
+ _timeout = false;
+
+ if (e.SocketError == SocketError.Success)
+ {
+ _recvBytes = e.BytesTransferred;
+ }
+ else
+ {
+ _error = e.SocketError.ToString();
+ }
+
+ readAsyncComplete.Set();
+ });
+
+ // Sets the state of the event to nonsignaled, causing threads to block
+ readAsyncComplete.Reset();
+
+ // Make an asynchronous Receive request over the socket
+ socket.ReceiveAsync(socketEventArg);
+
+ // Block the UI thread for a maximum of TIMEOUT_MILLISECONDS milliseconds.
+ // If no response comes back within this time then proceed
+ readAsyncComplete.WaitOne(this.timeout);
+
+ if (_timeout)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.TimedOut, "Socket recv timeout");
+ }
+
+ if (_error != null)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.Unknown, _error);
+ }
+
+ return _recvBytes;
+ }
+
+ public override void Write(byte[] buf, int off, int len)
+ {
+ outputStream.Write(buf, off, len);
+ }
+
+ private void beginFlush_Completed(object sender, SocketAsyncEventArgs e)
+ {
+ FlushAsyncResult flushAsyncResult = e.UserToken as FlushAsyncResult;
+ flushAsyncResult.UpdateStatusToComplete();
+ flushAsyncResult.NotifyCallbackWhenAvailable();
+
+ if (e.SocketError != SocketError.Success)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.Unknown, e.SocketError.ToString());
+ }
+ }
+
+ public override IAsyncResult BeginFlush(AsyncCallback callback, object state)
+ {
+ // Extract request and reset buffer
+ byte[] data = outputStream.ToArray();
+
+ FlushAsyncResult flushAsyncResult = new FlushAsyncResult(callback, state);
+
+ SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
+ socketEventArg.RemoteEndPoint = socket.RemoteEndPoint;
+ socketEventArg.UserToken = flushAsyncResult;
+
+ socketEventArg.Completed += beginFlush_Completed;
+ socketEventArg.SetBuffer(data, 0, data.Length);
+
+ socket.SendAsync(socketEventArg);
+
+ return flushAsyncResult;
+ }
+
+ public override void EndFlush(IAsyncResult asyncResult)
+ {
+ try
+ {
+ var flushAsyncResult = (FlushAsyncResult)asyncResult;
+
+ if (!flushAsyncResult.IsCompleted)
+ {
+ var waitHandle = flushAsyncResult.AsyncWaitHandle;
+ waitHandle.WaitOne();
+ waitHandle.Close();
+ }
+
+ if (flushAsyncResult.AsyncException != null)
+ {
+ throw flushAsyncResult.AsyncException;
+ }
+ }
+ finally
+ {
+ outputStream = new MemoryStream();
+ }
+ }
+
+ // Copy from impl from THttpClient.cs
+ // Based on http://msmvps.com/blogs/luisabreu/archive/2009/06/15/multithreading-implementing-the-iasyncresult-interface.aspx
+ class FlushAsyncResult : IAsyncResult
+ {
+ private volatile Boolean _isCompleted;
+ private ManualResetEvent _evt;
+ private readonly AsyncCallback _cbMethod;
+ private readonly object _state;
+
+ public FlushAsyncResult(AsyncCallback cbMethod, object state)
+ {
+ _cbMethod = cbMethod;
+ _state = state;
+ }
+
+ internal byte[] Data { get; set; }
+ internal Socket Connection { get; set; }
+ internal TTransportException AsyncException { get; set; }
+
+ public object AsyncState
+ {
+ get { return _state; }
+ }
+
+ public WaitHandle AsyncWaitHandle
+ {
+ get { return GetEvtHandle(); }
+ }
+
+ public bool CompletedSynchronously
+ {
+ get { return false; }
+ }
+
+ public bool IsCompleted
+ {
+ get { return _isCompleted; }
+ }
+
+ private readonly object _locker = new object();
+
+ private ManualResetEvent GetEvtHandle()
+ {
+ lock (_locker)
+ {
+ if (_evt == null)
+ {
+ _evt = new ManualResetEvent(false);
+ }
+ if (_isCompleted)
+ {
+ _evt.Set();
+ }
+ }
+ return _evt;
+ }
+
+ internal void UpdateStatusToComplete()
+ {
+ _isCompleted = true; //1. set _iscompleted to true
+ lock (_locker)
+ {
+ if (_evt != null)
+ {
+ _evt.Set(); //2. set the event, when it exists
+ }
+ }
+ }
+
+ internal void NotifyCallbackWhenAvailable()
+ {
+ if (_cbMethod != null)
+ {
+ _cbMethod(this);
+ }
+ }
+ }
+
+ public override void Close()
+ {
+ if (socket != null)
+ {
+ socket.Close();
+ socket = null;
+ }
+ }
+
+#region " IDisposable Support "
+ private bool _IsDisposed;
+
+ // IDisposable
+ protected override void Dispose(bool disposing)
+ {
+ if (!_IsDisposed)
+ {
+ if (disposing)
+ {
+ if (outputStream != null)
+ {
+ outputStream.Dispose();
+ }
+ outputStream = null;
+ if (socket != null)
+ {
+ ((IDisposable)socket).Dispose();
+ }
+ }
+ }
+ _IsDisposed = true;
+ }
+#endregion
+ }
+}
+
+
+#endif
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Transport/TSocket.cs b/src/jaegertracing/thrift/lib/csharp/src/Transport/TSocket.cs
new file mode 100644
index 000000000..d8fa335ad
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Transport/TSocket.cs
@@ -0,0 +1,245 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+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()
+ {
+ this.client = TSocketVersionizer.CreateTcpClient();
+ this.client.ReceiveTimeout = client.SendTimeout = timeout;
+ this.client.Client.NoDelay = true;
+ }
+
+ public int Timeout
+ {
+ set
+ {
+ client.ReceiveTimeout = client.SendTimeout = timeout = value;
+ }
+ }
+
+ public TcpClient TcpClient
+ {
+ get
+ {
+ return client;
+ }
+ }
+
+ public string Host
+ {
+ get
+ {
+ return host;
+ }
+ }
+
+ public int Port
+ {
+ get
+ {
+ return port;
+ }
+ }
+
+ 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();
+ }
+
+ if (timeout == 0) // no timeout -> infinite
+ {
+ client.Connect(host, port);
+ }
+ else // we have a timeout -> use it
+ {
+ ConnectHelper hlp = new ConnectHelper(client);
+ IAsyncResult asyncres = client.BeginConnect(host, port, new AsyncCallback(ConnectCallback), hlp);
+ bool bConnected = asyncres.AsyncWaitHandle.WaitOne(timeout) && client.Connected;
+ if (!bConnected)
+ {
+ lock (hlp.Mutex)
+ {
+ if (hlp.CallbackDone)
+ {
+ asyncres.AsyncWaitHandle.Close();
+ client.Close();
+ }
+ else
+ {
+ hlp.DoCleanup = true;
+ client = null;
+ }
+ }
+ throw new TTransportException(TTransportException.ExceptionType.TimedOut, "Connect timed out");
+ }
+ }
+
+ inputStream = client.GetStream();
+ outputStream = client.GetStream();
+ }
+
+
+ static void ConnectCallback(IAsyncResult asyncres)
+ {
+ ConnectHelper hlp = asyncres.AsyncState as ConnectHelper;
+ lock (hlp.Mutex)
+ {
+ hlp.CallbackDone = true;
+
+ try
+ {
+ if (hlp.Client.Client != null)
+ hlp.Client.EndConnect(asyncres);
+ }
+ catch (Exception)
+ {
+ // catch that away
+ }
+
+ if (hlp.DoCleanup)
+ {
+ try
+ {
+ asyncres.AsyncWaitHandle.Close();
+ }
+ catch (Exception) { }
+
+ try
+ {
+ if (hlp.Client is IDisposable)
+ ((IDisposable)hlp.Client).Dispose();
+ }
+ catch (Exception) { }
+ hlp.Client = null;
+ }
+ }
+ }
+
+ private class ConnectHelper
+ {
+ public object Mutex = new object();
+ public bool DoCleanup = false;
+ public bool CallbackDone = false;
+ public TcpClient Client;
+ public ConnectHelper(TcpClient client)
+ {
+ Client = client;
+ }
+ }
+
+ public override void Close()
+ {
+ base.Close();
+ if (client != null)
+ {
+ client.Close();
+ client = null;
+ }
+ }
+
+ #region " IDisposable Support "
+ private bool _IsDisposed;
+
+ // IDisposable
+ protected override void Dispose(bool disposing)
+ {
+ if (!_IsDisposed)
+ {
+ if (disposing)
+ {
+ if (client != null)
+ ((IDisposable)client).Dispose();
+ base.Dispose(disposing);
+ }
+ }
+ _IsDisposed = true;
+ }
+ #endregion
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Transport/TSocketVersionizer.cs b/src/jaegertracing/thrift/lib/csharp/src/Transport/TSocketVersionizer.cs
new file mode 100644
index 000000000..8c2f8e995
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Transport/TSocketVersionizer.cs
@@ -0,0 +1,78 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Sockets;
+using System.Reflection;
+using System.Text;
+#if NET45
+using System.Threading.Tasks;
+#endif
+
+namespace Thrift.Transport
+{
+ /// <summary>
+ /// PropertyInfo for the DualMode property of the System.Net.Sockets.Socket class. Used to determine if the sockets are capable of
+ /// automatic IPv4 and IPv6 handling. If DualMode is present the sockets automatically handle IPv4 and IPv6 connections.
+ /// If the DualMode is not available the system configuration determines whether IPv4 or IPv6 is used.
+ /// </summary>
+ internal static class TSocketVersionizer
+ {
+ /// <summary>
+ /// Creates a TcpClient according to the capabilities of the used framework.
+ /// </summary>
+ internal static TcpClient CreateTcpClient()
+ {
+ TcpClient client = null;
+
+#if NET45
+ client = new TcpClient(AddressFamily.InterNetworkV6);
+ client.Client.DualMode = true;
+#else
+ client = new TcpClient(AddressFamily.InterNetwork);
+#endif
+
+ return client;
+ }
+
+ /// <summary>
+ /// Creates a TcpListener according to the capabilities of the used framework.
+ /// </summary>
+ internal static TcpListener CreateTcpListener(Int32 port)
+ {
+ TcpListener listener = null;
+
+#if NET45
+ listener = new TcpListener(System.Net.IPAddress.IPv6Any, port);
+ listener.Server.DualMode = true;
+#else
+
+ listener = new TcpListener(System.Net.IPAddress.Any, port);
+#endif
+
+ return listener;
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Transport/TStreamTransport.cs b/src/jaegertracing/thrift/lib/csharp/src/Transport/TStreamTransport.cs
new file mode 100644
index 000000000..304599faa
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Transport/TStreamTransport.cs
@@ -0,0 +1,128 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.IO;
+
+namespace Thrift.Transport
+{
+ public class TStreamTransport : TTransport
+ {
+ protected Stream inputStream;
+ protected Stream outputStream;
+
+ protected TStreamTransport()
+ {
+ }
+
+ public TStreamTransport(Stream inputStream, Stream outputStream)
+ {
+ this.inputStream = inputStream;
+ this.outputStream = outputStream;
+ }
+
+ public Stream OutputStream
+ {
+ get { return outputStream; }
+ }
+
+ public Stream InputStream
+ {
+ get { return inputStream; }
+ }
+
+ 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();
+ }
+
+
+ #region " IDisposable Support "
+ private bool _IsDisposed;
+
+ // IDisposable
+ protected override void Dispose(bool disposing)
+ {
+ if (!_IsDisposed)
+ {
+ if (disposing)
+ {
+ if (InputStream != null)
+ InputStream.Dispose();
+ if (OutputStream != null)
+ OutputStream.Dispose();
+ }
+ }
+ _IsDisposed = true;
+ }
+ #endregion
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Transport/TTLSServerSocket.cs b/src/jaegertracing/thrift/lib/csharp/src/Transport/TTLSServerSocket.cs
new file mode 100644
index 000000000..716a97ca8
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Transport/TTLSServerSocket.cs
@@ -0,0 +1,223 @@
+/**
+ * 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;
+using System.Net.Security;
+using System.Net.Sockets;
+using System.Security.Authentication;
+using System.Security.Cryptography.X509Certificates;
+
+namespace Thrift.Transport
+{
+ /// <summary>
+ /// SSL Server Socket Wrapper Class
+ /// </summary>
+ public class TTLSServerSocket : TServerTransport
+ {
+ /// <summary>
+ /// Underlying tcp server
+ /// </summary>
+ private TcpListener server = null;
+
+ /// <summary>
+ /// The port where the socket listen
+ /// </summary>
+ private int port = 0;
+
+ /// <summary>
+ /// Timeout for the created server socket
+ /// </summary>
+ private readonly int clientTimeout;
+
+ /// <summary>
+ /// Whether or not to wrap new TSocket connections in buffers
+ /// </summary>
+ private bool useBufferedSockets = false;
+
+ /// <summary>
+ /// The servercertificate with the private- and public-key
+ /// </summary>
+ private X509Certificate serverCertificate;
+
+ /// <summary>
+ /// The function to validate the client certificate.
+ /// </summary>
+ private RemoteCertificateValidationCallback clientCertValidator;
+
+ /// <summary>
+ /// The function to determine which certificate to use.
+ /// </summary>
+ private LocalCertificateSelectionCallback localCertificateSelectionCallback;
+
+ /// <summary>
+ /// The SslProtocols value that represents the protocol used for authentication.
+ /// </summary>
+ private readonly SslProtocols sslProtocols;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TTLSServerSocket" /> class.
+ /// </summary>
+ /// <param name="port">The port where the server runs.</param>
+ /// <param name="certificate">The certificate object.</param>
+ public TTLSServerSocket(int port, X509Certificate2 certificate)
+ : this(port, 0, certificate)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TTLSServerSocket" /> class.
+ /// </summary>
+ /// <param name="port">The port where the server runs.</param>
+ /// <param name="clientTimeout">Send/receive timeout.</param>
+ /// <param name="certificate">The certificate object.</param>
+ public TTLSServerSocket(int port, int clientTimeout, X509Certificate2 certificate)
+ : this(port, clientTimeout, false, certificate)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TTLSServerSocket" /> class.
+ /// </summary>
+ /// <param name="port">The port where the server runs.</param>
+ /// <param name="clientTimeout">Send/receive timeout.</param>
+ /// <param name="useBufferedSockets">If set to <c>true</c> [use buffered sockets].</param>
+ /// <param name="certificate">The certificate object.</param>
+ /// <param name="clientCertValidator">The certificate validator.</param>
+ /// <param name="localCertificateSelectionCallback">The callback to select which certificate to use.</param>
+ /// <param name="sslProtocols">The SslProtocols value that represents the protocol used for authentication.</param>
+ public TTLSServerSocket(
+ int port,
+ int clientTimeout,
+ bool useBufferedSockets,
+ X509Certificate2 certificate,
+ RemoteCertificateValidationCallback clientCertValidator = null,
+ LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
+ // TODO: Enable Tls11 and Tls12 (TLS 1.1 and 1.2) by default once we start using .NET 4.5+.
+ SslProtocols sslProtocols = SslProtocols.Tls)
+ {
+ if (!certificate.HasPrivateKey)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.Unknown, "Your server-certificate needs to have a private key");
+ }
+
+ this.port = port;
+ this.clientTimeout = clientTimeout;
+ this.serverCertificate = certificate;
+ this.useBufferedSockets = useBufferedSockets;
+ this.clientCertValidator = clientCertValidator;
+ this.localCertificateSelectionCallback = localCertificateSelectionCallback;
+ this.sslProtocols = sslProtocols;
+ try
+ {
+ // Create server socket
+ this.server = TSocketVersionizer.CreateTcpListener(this.port);
+ this.server.Server.NoDelay = true;
+ }
+ catch (Exception ex)
+ {
+ server = null;
+ throw new TTransportException("Could not create ServerSocket on port " + this.port + ".", ex);
+ }
+ }
+
+ /// <summary>
+ /// Starts the server.
+ /// </summary>
+ public override void Listen()
+ {
+ // Make sure accept is not blocking
+ if (this.server != null)
+ {
+ try
+ {
+ this.server.Start();
+ }
+ catch (SocketException sx)
+ {
+ throw new TTransportException("Could not accept on listening socket: " + sx.Message, sx);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Callback for Accept Implementation
+ /// </summary>
+ /// <returns>
+ /// TTransport-object.
+ /// </returns>
+ protected override TTransport AcceptImpl()
+ {
+ if (this.server == null)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen, "No underlying server socket.");
+ }
+
+ try
+ {
+ TcpClient client = this.server.AcceptTcpClient();
+ client.SendTimeout = client.ReceiveTimeout = this.clientTimeout;
+
+ //wrap the client in an SSL Socket passing in the SSL cert
+ TTLSSocket socket = new TTLSSocket(
+ client,
+ this.serverCertificate,
+ true,
+ this.clientCertValidator,
+ this.localCertificateSelectionCallback,
+ this.sslProtocols);
+
+ socket.setupTLS();
+
+ if (useBufferedSockets)
+ {
+ TBufferedTransport trans = new TBufferedTransport(socket);
+ return trans;
+ }
+ else
+ {
+ return socket;
+ }
+
+ }
+ catch (Exception ex)
+ {
+ throw new TTransportException(ex.ToString(), ex);
+ }
+ }
+
+ /// <summary>
+ /// Stops the Server
+ /// </summary>
+ public override void Close()
+ {
+ if (this.server != null)
+ {
+ try
+ {
+ this.server.Stop();
+ }
+ catch (Exception ex)
+ {
+ throw new TTransportException("WARNING: Could not close server socket: " + ex, ex);
+ }
+ this.server = null;
+ }
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Transport/TTLSSocket.cs b/src/jaegertracing/thrift/lib/csharp/src/Transport/TTLSSocket.cs
new file mode 100644
index 000000000..06286dc8b
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Transport/TTLSSocket.cs
@@ -0,0 +1,445 @@
+/**
+ * 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;
+using System.Net.Security;
+using System.Net.Sockets;
+using System.Security.Authentication;
+using System.Security.Cryptography.X509Certificates;
+
+namespace Thrift.Transport
+{
+ /// <summary>
+ /// SSL Socket Wrapper class
+ /// </summary>
+ public class TTLSSocket : TStreamTransport
+ {
+ /// <summary>
+ /// Internal TCP Client
+ /// </summary>
+ private TcpClient client;
+
+ /// <summary>
+ /// The host
+ /// </summary>
+ private string host;
+
+ /// <summary>
+ /// The port
+ /// </summary>
+ private int port;
+
+ /// <summary>
+ /// The timeout for the connection
+ /// </summary>
+ private int timeout;
+
+ /// <summary>
+ /// Internal SSL Stream for IO
+ /// </summary>
+ private SslStream secureStream;
+
+ /// <summary>
+ /// Defines wheter or not this socket is a server socket<br/>
+ /// This is used for the TLS-authentication
+ /// </summary>
+ private bool isServer;
+
+ /// <summary>
+ /// The certificate
+ /// </summary>
+ private X509Certificate certificate;
+
+ /// <summary>
+ /// User defined certificate validator.
+ /// </summary>
+ private RemoteCertificateValidationCallback certValidator;
+
+ /// <summary>
+ /// The function to determine which certificate to use.
+ /// </summary>
+ private LocalCertificateSelectionCallback localCertificateSelectionCallback;
+
+ /// <summary>
+ /// The SslProtocols value that represents the protocol used for authentication.SSL protocols to be used.
+ /// </summary>
+ private readonly SslProtocols sslProtocols;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TTLSSocket"/> class.
+ /// </summary>
+ /// <param name="client">An already created TCP-client</param>
+ /// <param name="certificate">The certificate.</param>
+ /// <param name="isServer">if set to <c>true</c> [is server].</param>
+ /// <param name="certValidator">User defined cert validator.</param>
+ /// <param name="localCertificateSelectionCallback">The callback to select which certificate to use.</param>
+ /// <param name="sslProtocols">The SslProtocols value that represents the protocol used for authentication.</param>
+ public TTLSSocket(
+ TcpClient client,
+ X509Certificate certificate,
+ bool isServer = false,
+ RemoteCertificateValidationCallback certValidator = null,
+ LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
+ // TODO: Enable Tls11 and Tls12 (TLS 1.1 and 1.2) by default once we start using .NET 4.5+.
+ SslProtocols sslProtocols = SslProtocols.Tls)
+ {
+ this.client = client;
+ this.certificate = certificate;
+ this.certValidator = certValidator;
+ this.localCertificateSelectionCallback = localCertificateSelectionCallback;
+ this.sslProtocols = sslProtocols;
+ this.isServer = isServer;
+ if (isServer && certificate == null)
+ {
+ throw new ArgumentException("TTLSSocket needs certificate to be used for server", "certificate");
+ }
+
+ if (IsOpen)
+ {
+ base.inputStream = client.GetStream();
+ base.outputStream = client.GetStream();
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TTLSSocket"/> class.
+ /// </summary>
+ /// <param name="host">The host, where the socket should connect to.</param>
+ /// <param name="port">The port.</param>
+ /// <param name="certificatePath">The certificate path.</param>
+ /// <param name="certValidator">User defined cert validator.</param>
+ /// <param name="localCertificateSelectionCallback">The callback to select which certificate to use.</param>
+ /// <param name="sslProtocols">The SslProtocols value that represents the protocol used for authentication.</param>
+ public TTLSSocket(
+ string host,
+ int port,
+ string certificatePath,
+ RemoteCertificateValidationCallback certValidator = null,
+ LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
+ SslProtocols sslProtocols = SslProtocols.Tls)
+ : this(host, port, 0, X509Certificate.CreateFromCertFile(certificatePath), certValidator, localCertificateSelectionCallback, sslProtocols)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TTLSSocket"/> class.
+ /// </summary>
+ /// <param name="host">The host, where the socket should connect to.</param>
+ /// <param name="port">The port.</param>
+ /// <param name="certificate">The certificate.</param>
+ /// <param name="certValidator">User defined cert validator.</param>
+ /// <param name="localCertificateSelectionCallback">The callback to select which certificate to use.</param>
+ /// <param name="sslProtocols">The SslProtocols value that represents the protocol used for authentication.</param>
+ public TTLSSocket(
+ string host,
+ int port,
+ X509Certificate certificate = null,
+ RemoteCertificateValidationCallback certValidator = null,
+ LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
+ SslProtocols sslProtocols = SslProtocols.Tls)
+ : this(host, port, 0, certificate, certValidator, localCertificateSelectionCallback, sslProtocols)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TTLSSocket"/> class.
+ /// </summary>
+ /// <param name="host">The host, where the socket should connect to.</param>
+ /// <param name="port">The port.</param>
+ /// <param name="timeout">The timeout.</param>
+ /// <param name="certificate">The certificate.</param>
+ /// <param name="certValidator">User defined cert validator.</param>
+ /// <param name="localCertificateSelectionCallback">The callback to select which certificate to use.</param>
+ /// <param name="sslProtocols">The SslProtocols value that represents the protocol used for authentication.</param>
+ public TTLSSocket(
+ string host,
+ int port,
+ int timeout,
+ X509Certificate certificate,
+ RemoteCertificateValidationCallback certValidator = null,
+ LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
+ SslProtocols sslProtocols = SslProtocols.Tls)
+ {
+ this.host = host;
+ this.port = port;
+ this.timeout = timeout;
+ this.certificate = certificate;
+ this.certValidator = certValidator;
+ this.localCertificateSelectionCallback = localCertificateSelectionCallback;
+ this.sslProtocols = sslProtocols;
+
+ InitSocket();
+ }
+
+ /// <summary>
+ /// Creates the TcpClient and sets the timeouts
+ /// </summary>
+ private void InitSocket()
+ {
+ client = TSocketVersionizer.CreateTcpClient();
+ client.ReceiveTimeout = client.SendTimeout = timeout;
+ client.Client.NoDelay = true;
+ }
+
+ /// <summary>
+ /// Sets Send / Recv Timeout for IO
+ /// </summary>
+ public int Timeout
+ {
+ set
+ {
+ this.client.ReceiveTimeout = this.client.SendTimeout = this.timeout = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets the TCP client.
+ /// </summary>
+ public TcpClient TcpClient
+ {
+ get
+ {
+ return client;
+ }
+ }
+
+ /// <summary>
+ /// Gets the host.
+ /// </summary>
+ public string Host
+ {
+ get
+ {
+ return host;
+ }
+ }
+
+ /// <summary>
+ /// Gets the port.
+ /// </summary>
+ public int Port
+ {
+ get
+ {
+ return port;
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether TCP Client is Cpen
+ /// </summary>
+ public override bool IsOpen
+ {
+ get
+ {
+ if (this.client == null)
+ {
+ return false;
+ }
+
+ return this.client.Connected;
+ }
+ }
+
+ /// <summary>
+ /// Validates the certificates!<br/>
+ /// </summary>
+ /// <param name="sender">The sender-object.</param>
+ /// <param name="certificate">The used certificate.</param>
+ /// <param name="chain">The certificate chain.</param>
+ /// <param name="sslValidationErrors">An enum, which lists all the errors from the .NET certificate check.</param>
+ /// <returns></returns>
+ private bool DefaultCertificateValidator(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslValidationErrors)
+ {
+ return (sslValidationErrors == SslPolicyErrors.None);
+ }
+
+ /// <summary>
+ /// Connects to the host and starts the routine, which sets up the TLS
+ /// </summary>
+ 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();
+ }
+
+ if (timeout == 0) // no timeout -> infinite
+ {
+ client.Connect(host, port);
+ }
+ else // we have a timeout -> use it
+ {
+ ConnectHelper hlp = new ConnectHelper(client);
+ IAsyncResult asyncres = client.BeginConnect(host, port, new AsyncCallback(ConnectCallback), hlp);
+ bool bConnected = asyncres.AsyncWaitHandle.WaitOne(timeout) && client.Connected;
+ if (!bConnected)
+ {
+ lock (hlp.Mutex)
+ {
+ if (hlp.CallbackDone)
+ {
+ asyncres.AsyncWaitHandle.Close();
+ client.Close();
+ }
+ else
+ {
+ hlp.DoCleanup = true;
+ client = null;
+ }
+ }
+ throw new TTransportException(TTransportException.ExceptionType.TimedOut, "Connect timed out");
+ }
+ }
+
+ setupTLS();
+ }
+
+ /// <summary>
+ /// Creates a TLS-stream and lays it over the existing socket
+ /// </summary>
+ public void setupTLS()
+ {
+ RemoteCertificateValidationCallback validator = this.certValidator ?? DefaultCertificateValidator;
+
+ if (this.localCertificateSelectionCallback != null)
+ {
+ this.secureStream = new SslStream(
+ this.client.GetStream(),
+ false,
+ validator,
+ this.localCertificateSelectionCallback
+ );
+ }
+ else
+ {
+ this.secureStream = new SslStream(
+ this.client.GetStream(),
+ false,
+ validator
+ );
+ }
+
+ try
+ {
+ if (isServer)
+ {
+ // Server authentication
+ this.secureStream.AuthenticateAsServer(this.certificate, this.certValidator != null, sslProtocols, true);
+ }
+ else
+ {
+ // Client authentication
+ X509CertificateCollection certs = certificate != null ? new X509CertificateCollection { certificate } : new X509CertificateCollection();
+ this.secureStream.AuthenticateAsClient(host, certs, sslProtocols, true);
+ }
+ }
+ catch (Exception)
+ {
+ this.Close();
+ throw;
+ }
+
+ inputStream = this.secureStream;
+ outputStream = this.secureStream;
+ }
+
+ static void ConnectCallback(IAsyncResult asyncres)
+ {
+ ConnectHelper hlp = asyncres.AsyncState as ConnectHelper;
+ lock (hlp.Mutex)
+ {
+ hlp.CallbackDone = true;
+
+ try
+ {
+ if (hlp.Client.Client != null)
+ hlp.Client.EndConnect(asyncres);
+ }
+ catch (Exception)
+ {
+ // catch that away
+ }
+
+ if (hlp.DoCleanup)
+ {
+ try
+ {
+ asyncres.AsyncWaitHandle.Close();
+ }
+ catch (Exception) { }
+
+ try
+ {
+ if (hlp.Client is IDisposable)
+ ((IDisposable)hlp.Client).Dispose();
+ }
+ catch (Exception) { }
+ hlp.Client = null;
+ }
+ }
+ }
+
+ private class ConnectHelper
+ {
+ public object Mutex = new object();
+ public bool DoCleanup = false;
+ public bool CallbackDone = false;
+ public TcpClient Client;
+ public ConnectHelper(TcpClient client)
+ {
+ Client = client;
+ }
+ }
+
+ /// <summary>
+ /// Closes the SSL Socket
+ /// </summary>
+ public override void Close()
+ {
+ base.Close();
+ if (this.client != null)
+ {
+ this.client.Close();
+ this.client = null;
+ }
+
+ if (this.secureStream != null)
+ {
+ this.secureStream.Close();
+ this.secureStream = null;
+ }
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Transport/TTransport.cs b/src/jaegertracing/thrift/lib/csharp/src/Transport/TTransport.cs
new file mode 100644
index 000000000..5e4ac22ea
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Transport/TTransport.cs
@@ -0,0 +1,146 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.IO;
+
+namespace Thrift.Transport
+{
+ public abstract class TTransport : IDisposable
+ {
+ public abstract bool IsOpen
+ {
+ get;
+ }
+
+ private byte[] _peekBuffer = new byte[1];
+ private bool _hasPeekByte;
+
+ public bool Peek()
+ {
+ //If we already have a byte read but not consumed, do nothing.
+ if (_hasPeekByte)
+ return true;
+
+ //If transport closed we can't peek.
+ if (!IsOpen)
+ return false;
+
+ //Try to read one byte. If succeeds we will need to store it for the next read.
+ try
+ {
+ int bytes = Read(_peekBuffer, 0, 1);
+ if (bytes == 0)
+ return false;
+ }
+ catch (IOException)
+ {
+ return false;
+ }
+
+ _hasPeekByte = true;
+ return true;
+ }
+
+ public abstract void Open();
+
+ public abstract void Close();
+
+ protected static void ValidateBufferArgs(byte[] buf, int off, int len)
+ {
+ if (buf == null)
+ throw new ArgumentNullException("buf");
+ if (off < 0)
+ throw new ArgumentOutOfRangeException("Buffer offset is smaller than zero.");
+ if (len < 0)
+ throw new ArgumentOutOfRangeException("Buffer length is smaller than zero.");
+ if (off + len > buf.Length)
+ throw new ArgumentOutOfRangeException("Not enough data.");
+ }
+
+ public abstract int Read(byte[] buf, int off, int len);
+
+ public int ReadAll(byte[] buf, int off, int len)
+ {
+ ValidateBufferArgs(buf, off, len);
+ int got = 0;
+
+ //If we previously peeked a byte, we need to use that first.
+ if (_hasPeekByte)
+ {
+ buf[off + got++] = _peekBuffer[0];
+ _hasPeekByte = false;
+ }
+
+ while (got < len)
+ {
+ int ret = Read(buf, off + got, len - got);
+ if (ret <= 0)
+ {
+ throw new TTransportException(
+ TTransportException.ExceptionType.EndOfFile,
+ "Cannot read, Remote side has closed");
+ }
+ got += ret;
+ }
+ return got;
+ }
+
+ public virtual void Write(byte[] buf)
+ {
+ Write(buf, 0, buf.Length);
+ }
+
+ public abstract void Write(byte[] buf, int off, int len);
+
+ public virtual void Flush()
+ {
+ }
+
+ public virtual IAsyncResult BeginFlush(AsyncCallback callback, object state)
+ {
+ throw new TTransportException(
+ TTransportException.ExceptionType.Unknown,
+ "Asynchronous operations are not supported by this transport.");
+ }
+
+ public virtual void EndFlush(IAsyncResult asyncResult)
+ {
+ throw new TTransportException(
+ TTransportException.ExceptionType.Unknown,
+ "Asynchronous operations are not supported by this transport.");
+ }
+
+ #region " IDisposable Support "
+ // IDisposable
+ protected abstract void Dispose(bool disposing);
+
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Transport/TTransportException.cs b/src/jaegertracing/thrift/lib/csharp/src/Transport/TTransportException.cs
new file mode 100644
index 000000000..7f6cc1889
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Transport/TTransportException.cs
@@ -0,0 +1,69 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+
+namespace Thrift.Transport
+{
+ public class TTransportException : TException
+ {
+ protected ExceptionType type;
+
+ public TTransportException()
+ : base()
+ {
+ }
+
+ public TTransportException(ExceptionType type)
+ : this()
+ {
+ this.type = type;
+ }
+
+ public TTransportException(ExceptionType type, string message, Exception inner = null)
+ : base(message, inner)
+ {
+ this.type = type;
+ }
+
+ public TTransportException(string message, Exception inner = null)
+ : base(message, inner)
+ {
+ }
+
+ public ExceptionType Type
+ {
+ get { return type; }
+ }
+
+ public enum ExceptionType
+ {
+ Unknown,
+ NotOpen,
+ AlreadyOpen,
+ TimedOut,
+ EndOfFile,
+ Interrupted
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/Transport/TTransportFactory.cs b/src/jaegertracing/thrift/lib/csharp/src/Transport/TTransportFactory.cs
new file mode 100644
index 000000000..47a0c6265
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/Transport/TTransportFactory.cs
@@ -0,0 +1,42 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+
+namespace Thrift.Transport
+{
+ /// <summary>
+ /// From Mark Slee &amp; 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 virtual TTransport GetTransport(TTransport trans)
+ {
+ return trans;
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/src/thrift.snk b/src/jaegertracing/thrift/lib/csharp/src/thrift.snk
new file mode 100644
index 000000000..97bc5812b
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/src/thrift.snk
Binary files differ
diff --git a/src/jaegertracing/thrift/lib/csharp/test/JSON/JSONTest.csproj b/src/jaegertracing/thrift/lib/csharp/test/JSON/JSONTest.csproj
new file mode 100644
index 000000000..f07d43eec
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/JSON/JSONTest.csproj
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{E37A0034-DCBF-4886-A0DA-25A03D12D975}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>JSONTest</RootNamespace>
+ <AssemblyName>JSONTest</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <TargetFrameworkProfile>
+ </TargetFrameworkProfile>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+ <PlatformTarget>x86</PlatformTarget>
+ <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|x86' ">
+ <PlatformTarget>x86</PlatformTarget>
+ <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" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="app.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\src\Thrift.csproj">
+ <Project>{499EB63C-D74C-47E8-AE48-A2FC94538E9D}</Project>
+ <Name>Thrift</Name>
+ </ProjectReference>
+ </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/src/jaegertracing/thrift/lib/csharp/test/JSON/Program.cs b/src/jaegertracing/thrift/lib/csharp/test/JSON/Program.cs
new file mode 100644
index 000000000..f61388ae7
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/JSON/Program.cs
@@ -0,0 +1,95 @@
+/**
+ * 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;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Thrift.Protocol;
+using Thrift.Transport;
+
+namespace JSONTest
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ TestThrift2365(); // JSON binary decodes too much data
+ TestThrift2336(); // hex encoding using \uXXXX where 0xXXXX > 0xFF
+ TestThrift3403(); // JSON escaped unicode surrogate pair support.
+ }
+
+
+ public static void TestThrift2365()
+ {
+ var rnd = new Random();
+ for (var len = 0; len < 10; ++len)
+ {
+ byte[] dataWritten = new byte[len];
+ rnd.NextBytes(dataWritten);
+
+ Stream stm = new MemoryStream();
+ TTransport trans = new TStreamTransport(null, stm);
+ TProtocol prot = new TJSONProtocol(trans);
+ prot.WriteBinary(dataWritten);
+
+ stm.Position = 0;
+ trans = new TStreamTransport(stm, null);
+ prot = new TJSONProtocol(trans);
+ byte[] dataRead = prot.ReadBinary();
+
+ Debug.Assert(dataRead.Length == dataWritten.Length);
+ for (var i = 0; i < dataRead.Length; ++i)
+ Debug.Assert(dataRead[i] == dataWritten[i]);
+ }
+ }
+
+
+ public static void TestThrift2336()
+ {
+ const string RUSSIAN_TEXT = "\u0420\u0443\u0441\u0441\u043a\u043e\u0435 \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435";
+ const string RUSSIAN_JSON = "\"\\u0420\\u0443\\u0441\\u0441\\u043a\\u043e\\u0435 \\u041d\\u0430\\u0437\\u0432\\u0430\\u043d\\u0438\\u0435\"";
+
+ // prepare buffer with JSON data
+ byte[] rawBytes = new byte[RUSSIAN_JSON.Length];
+ for (var i = 0; i < RUSSIAN_JSON.Length; ++i)
+ rawBytes[i] = (byte)(RUSSIAN_JSON[i] & (char)0xFF); // only low bytes
+
+ // parse and check
+ var stm = new MemoryStream(rawBytes);
+ var trans = new TStreamTransport(stm, null);
+ var prot = new TJSONProtocol(trans);
+ Debug.Assert(prot.ReadString() == RUSSIAN_TEXT, "reading JSON with hex-encoded chars > 8 bit");
+ }
+
+ public static void TestThrift3403()
+ {
+ string GCLEF_TEXT = "\ud834\udd1e";
+ const string GCLEF_JSON = "\"\\ud834\\udd1e\"";
+
+ // parse and check
+ var stm = new MemoryStream(Encoding.UTF8.GetBytes(GCLEF_JSON));
+ var trans = new TStreamTransport(stm, null);
+ var prot = new TJSONProtocol(trans);
+ Debug.Assert(prot.ReadString() == GCLEF_TEXT, "reading JSON with surrogate pair hex-encoded chars");
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/test/JSON/Properties/AssemblyInfo.cs b/src/jaegertracing/thrift/lib/csharp/test/JSON/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..fdff4a1a5
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/JSON/Properties/AssemblyInfo.cs
@@ -0,0 +1,55 @@
+/*
+ * 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen über eine Assembly werden über die folgenden
+// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
+// die mit einer Assembly verknüpft sind.
+[assembly: AssemblyTitle("JSONTest")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("Thrift")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
+// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
+// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
+[assembly: ComVisible(false)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
+[assembly: Guid("2b2e7d56-3e65-4368-92d7-e34d56b7105e")]
+
+// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
+//
+// Hauptversion
+// Nebenversion
+// Buildnummer
+// Revision
+//
+// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
+// übernehmen, indem Sie "*" eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/jaegertracing/thrift/lib/csharp/test/JSON/app.config b/src/jaegertracing/thrift/lib/csharp/test/JSON/app.config
new file mode 100644
index 000000000..9c1919d4f
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/JSON/app.config
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+-->
+<configuration>
+<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
diff --git a/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Client/Multiplex.Test.Client.cs b/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Client/Multiplex.Test.Client.cs
new file mode 100644
index 000000000..c810a0891
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Client/Multiplex.Test.Client.cs
@@ -0,0 +1,82 @@
+/*
+ * 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;
+using System.Collections.Generic;
+using Thrift.Collections;
+using Thrift.Transport;
+using Thrift.Protocol;
+using Thrift.Server;
+using Thrift;
+using Test.Multiplex;
+
+namespace Test.Multiplex.Client
+{
+ public class TestClient
+ {
+ static void Execute(int port)
+ {
+ try
+ {
+ TTransport trans;
+ trans = new TSocket("localhost", port);
+ trans = new TFramedTransport(trans);
+ trans.Open();
+
+ TProtocol Protocol = new TBinaryProtocol(trans, true, true);
+
+ TMultiplexedProtocol multiplex;
+
+ multiplex = new TMultiplexedProtocol(Protocol, Constants.NAME_BENCHMARKSERVICE);
+ BenchmarkService.Iface bench = new BenchmarkService.Client(multiplex);
+
+ multiplex = new TMultiplexedProtocol(Protocol, Constants.NAME_AGGR);
+ Aggr.Iface aggr = new Aggr.Client(multiplex);
+
+ for (sbyte i = 1; 10 >= i; ++i)
+ {
+ aggr.addValue(bench.fibonacci(i));
+ }
+
+ foreach (int k in aggr.getValues())
+ {
+ Console.Write(k.ToString() + " ");
+ Console.WriteLine("");
+ }
+ trans.Close();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.Message);
+ }
+ }
+
+ static void Main(string[] args)
+ {
+ int port = 9090;
+ if (args.Length > 0)
+ {
+ port = ushort.Parse(args[0]);
+ }
+ Execute(port);
+ Console.WriteLine("done.");
+ }
+ }
+}
+
diff --git a/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Client/MultiplexClient.csproj b/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Client/MultiplexClient.csproj
new file mode 100644
index 000000000..09d20f503
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Client/MultiplexClient.csproj
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<Project ToolsVersion="4.0" 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>{5E91DA17-E548-415F-8C9F-9E84EDF8EE06}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>MultiplexClient</RootNamespace>
+ <AssemblyName>MultiplexClient</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <IsWebBootstrapper>false</IsWebBootstrapper>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <UpgradeBackupLocation />
+ <PublishUrl>publish\</PublishUrl>
+ <Install>true</Install>
+ <InstallFrom>Disk</InstallFrom>
+ <UpdateEnabled>false</UpdateEnabled>
+ <UpdateMode>Foreground</UpdateMode>
+ <UpdateInterval>7</UpdateInterval>
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+ <UpdatePeriodically>false</UpdatePeriodically>
+ <UpdateRequired>false</UpdateRequired>
+ <MapFileExtensions>true</MapFileExtensions>
+ <ApplicationRevision>0</ApplicationRevision>
+ <ApplicationVersion>0.13.0.0</ApplicationVersion>
+ <UseApplicationTrust>false</UseApplicationTrust>
+ <BootstrapperEnabled>true</BootstrapperEnabled>
+ </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>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </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>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\Multiplex.Test.Common.cs">
+ <Link>Multiplex.Test.Common.cs</Link>
+ </Compile>
+ <Compile Include="..\gen-csharp\Aggr.cs" />
+ <Compile Include="..\gen-csharp\BenchmarkService.cs" />
+ <Compile Include="..\gen-csharp\Error.cs" />
+ <Compile Include="Multiplex.Test.Client.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+ <Visible>False</Visible>
+ <ProductName>Windows Installer 3.1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\src\Thrift.csproj">
+ <Project>{499EB63C-D74C-47E8-AE48-A2FC94538E9D}</Project>
+ <Name>Thrift</Name>
+ </ProjectReference>
+ </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>
+ -->
+ <PropertyGroup>
+ <PreBuildEvent>rmdir /s /q "$(ProjectDir)gen-csharp"
+del /f /q "$(ProjectDir)ThriftImpl.dll"
+SET OUTPUT_DIR=$(ProjectDir)
+
+SET THRIFT_FILE=$(ProjectDir)\..\..\..\..\..\contrib\async-test\aggr.thrift
+for %25%25I in ("%25OUTPUT_DIR%25") do set SHORT_DIR=%25%25~fsI
+for %25%25I in ("%25THRIFT_FILE%25") do set THRIFT_SHORT=%25%25~fsI
+"$(ProjectDir)\..\..\..\..\..\compiler\cpp\thrift.exe" --gen csharp -o %25SHORT_DIR%25 %25THRIFT_SHORT%25
+
+SET THRIFT_FILE=$(ProjectDir)\..\..\..\..\..\lib\rb\benchmark\Benchmark.thrift
+for %25%25I in ("%25OUTPUT_DIR%25") do set SHORT_DIR=%25%25~fsI
+for %25%25I in ("%25THRIFT_FILE%25") do set THRIFT_SHORT=%25%25~fsI
+"$(ProjectDir)\..\..\..\..\..\compiler\cpp\thrift.exe" --gen csharp -o %25SHORT_DIR%25 %25THRIFT_SHORT%25
+
+</PreBuildEvent>
+ </PropertyGroup>
+</Project>
diff --git a/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Client/Properties/AssemblyInfo.cs b/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Client/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..0b65c1e52
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Client/Properties/AssemblyInfo.cs
@@ -0,0 +1,55 @@
+/*
+ * 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.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("MultiplexClient")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("Thrift")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[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("66FC61E5-420B-4b56-8012-D6D6CE22537F")]
+
+// 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("0.13.0.0")]
+[assembly: AssemblyFileVersion("0.13.0.0")]
diff --git a/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Makefile.am b/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Makefile.am
new file mode 100644
index 000000000..9c1f1b8b7
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Makefile.am
@@ -0,0 +1,63 @@
+#
+# 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.
+#
+
+GENERATED = \
+ gen-csharp/Aggr.cs \
+ gen-csharp/BenchmarkService.cs \
+ gen-csharp/Error.cs
+
+BUILT_SOURCES = $(GENERATED)
+
+THRIFT = $(top_builddir)/compiler/cpp/thrift
+
+gen-csharp/Aggr.cs: $(top_srcdir)/contrib/async-test/aggr.thrift
+ $(THRIFT) --gen csharp $<
+
+gen-csharp/BenchmarkService.cs gen-csharp/Error.cs: $(top_srcdir)/lib/rb/benchmark/Benchmark.thrift
+ $(THRIFT) --gen csharp $<
+
+ThriftImpl.dll: Multiplex.Test.Common.cs $(GENERATED) ../../Thrift.dll
+ $(CSC) $(CSC_DEFINES) -t:library -out:./ThriftImpl.dll -reference:../../Thrift.dll $(GENERATED) $<
+
+MultiplexClient.exe: Client/Multiplex.Test.Client.cs ThriftImpl.dll
+ $(CSC) $(CSC_DEFINES) -out:$@ -reference:../../Thrift.dll -reference:ThriftImpl.dll $<
+
+MultiplexServer.exe: Server/Multiplex.Test.Server.cs ThriftImpl.dll
+ $(CSC) $(CSC_DEFINES) -out:$@ -reference:../../Thrift.dll -reference:ThriftImpl.dll $<
+
+CLEANFILES = \
+ MultiplexClient.exe \
+ MultiplexServer.exe \
+ ThriftImpl.dll
+
+DISTCLEANFILES = \
+ Makefile.in
+
+clean-local:
+ $(RM) -rf gen-csharp
+
+dist-hook:
+ $(RM) -r $(distdir)/gen-csharp/
+
+TESTPORT = 9501
+check-local: MultiplexServer.exe MultiplexClient.exe
+ echo $(TESTPORT)
+ MONO_PATH=../../ timeout 10 mono MultiplexServer.exe $(TESTPORT) &
+ sleep 1
+ MONO_PATH=../../ mono MultiplexClient.exe $(TESTPORT)
diff --git a/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Multiplex.Test.Common.cs b/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Multiplex.Test.Common.cs
new file mode 100644
index 000000000..a687852d9
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Multiplex.Test.Common.cs
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+// Distributed under the Thrift Software License
+//
+// See accompanying file LICENSE or visit the Thrift site at:
+// http://developers.facebook.com/thrift/
+using System;
+using System.Collections.Generic;
+using Thrift.Collections;
+using Thrift.Transport;
+using Thrift.Protocol;
+using Thrift.Server;
+
+namespace Test.Multiplex
+{
+ public class Constants
+ {
+ public const string NAME_BENCHMARKSERVICE = "BenchmarkService";
+ public const string NAME_AGGR = "Aggr";
+ }
+}
+
+
diff --git a/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Server/Multiplex.Test.Server.cs b/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Server/Multiplex.Test.Server.cs
new file mode 100644
index 000000000..9786189bb
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Server/Multiplex.Test.Server.cs
@@ -0,0 +1,107 @@
+/*
+ * 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;
+using System.Collections.Generic;
+using Thrift.Collections;
+using Thrift.Transport;
+using Thrift.Protocol;
+using Thrift.Server;
+using Thrift;
+using Test.Multiplex;
+
+namespace Test.Multiplex.Server
+{
+ public class TestServer
+ {
+ class BenchmarkServiceImpl : BenchmarkService.Iface
+ {
+ public int fibonacci(sbyte n)
+ {
+ int prev, next, result;
+ prev = 0;
+ result = 1;
+ while (n > 0)
+ {
+ next = result + prev;
+ prev = result;
+ result = next;
+ --n;
+ }
+ return result;
+ }
+ }
+
+ class AggrServiceImpl : Aggr.Iface
+ {
+ List<int> values = new List<int>();
+
+ public void addValue(int value)
+ {
+ values.Add(value);
+ }
+
+ public List<int> getValues()
+ {
+ return values;
+ }
+ }
+
+ static void Execute(int port)
+ {
+ try
+ {
+ // create protocol factory, default to BinaryProtocol
+ TProtocolFactory ProtocolFactory = new TBinaryProtocol.Factory(true,true);
+ TServerTransport servertrans = new TServerSocket(port, 0, false);
+ TTransportFactory TransportFactory = new TFramedTransport.Factory();
+
+ BenchmarkService.Iface benchHandler = new BenchmarkServiceImpl();
+ TProcessor benchProcessor = new BenchmarkService.Processor(benchHandler);
+
+ Aggr.Iface aggrHandler = new AggrServiceImpl();
+ TProcessor aggrProcessor = new Aggr.Processor(aggrHandler);
+
+ TMultiplexedProcessor multiplex = new TMultiplexedProcessor();
+ multiplex.RegisterProcessor(Constants.NAME_BENCHMARKSERVICE, benchProcessor);
+ multiplex.RegisterProcessor(Constants.NAME_AGGR, aggrProcessor);
+
+ TServer ServerEngine = new TSimpleServer(multiplex, servertrans, TransportFactory, ProtocolFactory);
+
+ Console.WriteLine("Starting the server ...");
+ ServerEngine.Serve();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.Message);
+ }
+ }
+
+ static void Main(string[] args)
+ {
+ int port = 9090;
+ if (args.Length > 0)
+ {
+ port = ushort.Parse(args[0]);
+ }
+ Execute(port);
+ }
+ }
+}
+
diff --git a/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Server/MultiplexServer.csproj b/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Server/MultiplexServer.csproj
new file mode 100644
index 000000000..23d325362
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Server/MultiplexServer.csproj
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<Project ToolsVersion="4.0" 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>{D592BDF3-0DCE-48FB-890F-E4AE1D9CE7CD}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>MultiplexServer</RootNamespace>
+ <AssemblyName>MultiplexServer</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <IsWebBootstrapper>false</IsWebBootstrapper>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <UpgradeBackupLocation />
+ <PublishUrl>publish\</PublishUrl>
+ <Install>true</Install>
+ <InstallFrom>Disk</InstallFrom>
+ <UpdateEnabled>false</UpdateEnabled>
+ <UpdateMode>Foreground</UpdateMode>
+ <UpdateInterval>7</UpdateInterval>
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+ <UpdatePeriodically>false</UpdatePeriodically>
+ <UpdateRequired>false</UpdateRequired>
+ <MapFileExtensions>true</MapFileExtensions>
+ <ApplicationRevision>0</ApplicationRevision>
+ <ApplicationVersion>0.13.0.0</ApplicationVersion>
+ <UseApplicationTrust>false</UseApplicationTrust>
+ <BootstrapperEnabled>true</BootstrapperEnabled>
+ </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>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </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>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\Multiplex.Test.Common.cs">
+ <Link>Multiplex.Test.Common.cs</Link>
+ </Compile>
+ <Compile Include="..\gen-csharp\Aggr.cs" />
+ <Compile Include="..\gen-csharp\BenchmarkService.cs" />
+ <Compile Include="..\gen-csharp\Error.cs" />
+ <Compile Include="Multiplex.Test.Server.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+ <Visible>False</Visible>
+ <ProductName>Windows Installer 3.1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\src\Thrift.csproj">
+ <Project>{499EB63C-D74C-47E8-AE48-A2FC94538E9D}</Project>
+ <Name>Thrift</Name>
+ </ProjectReference>
+ </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>
+ -->
+ <PropertyGroup>
+ <PreBuildEvent>rmdir /s /q "$(ProjectDir)gen-csharp"
+del /f /q "$(ProjectDir)ThriftImpl.dll"
+SET OUTPUT_DIR=$(ProjectDir)
+
+SET THRIFT_FILE=$(ProjectDir)\..\..\..\..\..\contrib\async-test\aggr.thrift
+for %25%25I in ("%25OUTPUT_DIR%25") do set SHORT_DIR=%25%25~fsI
+for %25%25I in ("%25THRIFT_FILE%25") do set THRIFT_SHORT=%25%25~fsI
+"$(ProjectDir)\..\..\..\..\..\compiler\cpp\thrift.exe" --gen csharp -o %25SHORT_DIR%25 %25THRIFT_SHORT%25
+
+SET THRIFT_FILE=$(ProjectDir)\..\..\..\..\..\lib\rb\benchmark\Benchmark.thrift
+for %25%25I in ("%25OUTPUT_DIR%25") do set SHORT_DIR=%25%25~fsI
+for %25%25I in ("%25THRIFT_FILE%25") do set THRIFT_SHORT=%25%25~fsI
+"$(ProjectDir)\..\..\..\..\..\compiler\cpp\thrift.exe" --gen csharp -o %25SHORT_DIR%25 %25THRIFT_SHORT%25
+
+</PreBuildEvent>
+ </PropertyGroup>
+</Project>
diff --git a/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Server/Properties/AssemblyInfo.cs b/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Server/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..2b8a6af23
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/Multiplex/Server/Properties/AssemblyInfo.cs
@@ -0,0 +1,55 @@
+/*
+ * 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.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("MultiplexServer")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("Thrift")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[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("F2F436C1-3D4F-411a-ADC3-B98848476A8E")]
+
+// 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("0.13.0.0")]
+[assembly: AssemblyFileVersion("0.13.0.0")]
diff --git a/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/App_Start/FilterConfig.cs b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/App_Start/FilterConfig.cs
new file mode 100644
index 000000000..855184fd2
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/App_Start/FilterConfig.cs
@@ -0,0 +1,31 @@
+/**
+ * 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.Web.Mvc;
+
+namespace ThriftMVCTest
+{
+ public static class FilterConfig
+ {
+ public static void RegisterGlobalFilters(GlobalFilterCollection filters)
+ {
+ filters.Add(new HandleErrorAttribute());
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/App_Start/RouteConfig.cs b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/App_Start/RouteConfig.cs
new file mode 100644
index 000000000..b4b6023d6
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/App_Start/RouteConfig.cs
@@ -0,0 +1,39 @@
+/**
+ * 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.Web.Mvc;
+using System.Web.Routing;
+
+namespace ThriftMVCTest
+{
+ public static class RouteConfig
+ {
+ public static void RegisterRoutes(RouteCollection routes)
+ {
+ routes.IgnoreRoute("{resource}.thrift");
+ routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
+
+ routes.MapRoute(
+ name: "Default",
+ url: "{controller}/{action}/{id}",
+ defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
+ );
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/AsyncHttpHandler.cs b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/AsyncHttpHandler.cs
new file mode 100644
index 000000000..7f26184fa
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/AsyncHttpHandler.cs
@@ -0,0 +1,32 @@
+/**
+ * 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 Thrift.Transport;
+
+namespace ThriftMVCTest
+{
+ public class AsyncHttpHandler : THttpTaskAsyncHandler
+ {
+ public AsyncHttpHandler()
+ : base(
+ new Thrift.Test.SecondService.AsyncProcessor(new SecondServiceImpl()))
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Controllers/HomeController.cs b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Controllers/HomeController.cs
new file mode 100644
index 000000000..c9a1ec43f
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Controllers/HomeController.cs
@@ -0,0 +1,70 @@
+/**
+ * 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;
+using System.Threading.Tasks;
+using System.Web.Mvc;
+using Thrift.Protocol;
+using Thrift.Test;
+using Thrift.Transport;
+
+namespace ThriftMVCTest.Controllers
+{
+ public class HomeController : Controller
+ {
+ public ActionResult Index()
+ {
+ return View();
+ }
+
+ public async Task<ActionResult> TestThriftAsync()
+ {
+ var baseUri = new Uri(string.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Authority,
+ Url.Content("~")));
+
+ SecondService.IAsync asyncService =
+ new SecondService.Client(new TBinaryProtocol(new THttpClient(new Uri(baseUri, "Async.thrift"))));
+
+ var result = await asyncService.secondtestStringAsync("TestString");
+ if (result != "testString(\"TestString\")")
+ {
+ throw new Exception("The wrong result was returned");
+ }
+
+ return RedirectToAction("Index");
+ }
+
+ public ActionResult TestThriftSync()
+ {
+ var baseUri = new Uri(string.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Authority,
+ Url.Content("~")));
+
+ SecondService.ISync service =
+ new SecondService.Client(new TBinaryProtocol(new THttpClient(new Uri(baseUri, "Sync.thrift"))));
+
+ var result = service.secondtestString("TestString");
+ if (result != "testString(\"TestString\")")
+ {
+ throw new Exception("The wrong result was returned");
+ }
+
+ return RedirectToAction("Index");
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Global.asax b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Global.asax
new file mode 100644
index 000000000..7bb688c7a
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Global.asax
@@ -0,0 +1,19 @@
+<%@ Application Codebehind="Global.asax.cs" Inherits="ThriftMVCTest.MvcApplication" Language="C#" %>
+<!--
+ 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.
+-->
diff --git a/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Global.asax.cs b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Global.asax.cs
new file mode 100644
index 000000000..59731efb3
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Global.asax.cs
@@ -0,0 +1,34 @@
+/**
+ * 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.Web.Mvc;
+using System.Web.Routing;
+
+namespace ThriftMVCTest
+{
+ public class MvcApplication : System.Web.HttpApplication
+ {
+ protected void Application_Start()
+ {
+ AreaRegistration.RegisterAllAreas();
+ FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
+ RouteConfig.RegisterRoutes(RouteTable.Routes);
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Properties/AssemblyInfo.cs b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..b812aaf1d
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Properties/AssemblyInfo.cs
@@ -0,0 +1,53 @@
+/**
+ * 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.Reflection;
+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("ThriftMVCTest")]
+[assembly: AssemblyDescription("A web project for testing the thrift ASP.NET features.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("Thrift")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[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("366f9bd0-3c0e-48aa-b2ca-61fd4a93e427")]
+
+// 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("0.13.0.0")]
+[assembly: AssemblyFileVersion("0.13.0.0")]
diff --git a/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/SecondServiceImpl.cs b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/SecondServiceImpl.cs
new file mode 100644
index 000000000..fad301a35
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/SecondServiceImpl.cs
@@ -0,0 +1,37 @@
+/**
+ * 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.Threading.Tasks;
+using Thrift.Test;
+
+namespace ThriftMVCTest
+{
+ public class SecondServiceImpl : SecondService.IAsync, SecondService.ISync
+ {
+ public Task<string> secondtestStringAsync(string thing)
+ {
+ return Task.FromResult(thing);
+ }
+
+ public string secondtestString(string thing)
+ {
+ return "testString(\"" + thing + "\")";
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/SyncHttpHandler.cs b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/SyncHttpHandler.cs
new file mode 100644
index 000000000..4fe26624a
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/SyncHttpHandler.cs
@@ -0,0 +1,32 @@
+/**
+ * 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 Thrift.Transport;
+
+namespace ThriftMVCTest
+{
+ public class SyncHttpHandler : THttpHandler
+ {
+ public SyncHttpHandler()
+ : base(
+ new Thrift.Test.SecondService.Processor(new SecondServiceImpl()))
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/ThriftMVCTest.csproj b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/ThriftMVCTest.csproj
new file mode 100644
index 000000000..0eb969a04
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/ThriftMVCTest.csproj
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>
+ </ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{891B4487-C7BA-427E-BBC8-4C596C229A10}</ProjectGuid>
+ <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>ThriftMVCTest</RootNamespace>
+ <AssemblyName>ThriftMVCTest</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <MvcBuildViews>false</MvcBuildViews>
+ <UseIISExpress>true</UseIISExpress>
+ <IISExpressSSLPort />
+ <IISExpressAnonymousAuthentication />
+ <IISExpressWindowsAuthentication />
+ <IISExpressUseClassicPipelineMode />
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\</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\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Web.DynamicData" />
+ <Reference Include="System.Web.Entity" />
+ <Reference Include="System.Web.ApplicationServices" />
+ <Reference Include="System.ComponentModel.DataAnnotations" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Web.Extensions" />
+ <Reference Include="System.Web.Abstractions" />
+ <Reference Include="System.Web.Routing" />
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Configuration" />
+ <Reference Include="System.Web.Services" />
+ <Reference Include="System.EnterpriseServices" />
+ <Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <Private>True</Private>
+ <HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Net.Http">
+ </Reference>
+ <Reference Include="System.Net.Http.WebRequest">
+ </Reference>
+ <Reference Include="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <Private>True</Private>
+ <HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <Private>True</Private>
+ <HintPath>..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <Private>True</Private>
+ <HintPath>..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <Private>True</Private>
+ <HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Web.WebPages.Deployment, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <Private>True</Private>
+ <HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <Private>True</Private>
+ <HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
+ </Reference>
+ <Reference Include="ThriftImpl">
+ <HintPath>.\ThriftImpl.dll</HintPath>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="App_Start\FilterConfig.cs" />
+ <Compile Include="App_Start\RouteConfig.cs" />
+ <Compile Include="SyncHttpHandler.cs" />
+ <Compile Include="AsyncHttpHandler.cs" />
+ <Compile Include="Controllers\HomeController.cs" />
+ <Compile Include="Global.asax.cs">
+ <DependentUpon>Global.asax</DependentUpon>
+ </Compile>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="SecondServiceImpl.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="favicon.ico" />
+ <Content Include="Global.asax" />
+ <Content Include="Web.config" />
+ <Content Include="Web.Debug.config">
+ <DependentUpon>Web.config</DependentUpon>
+ </Content>
+ <Content Include="Web.Release.config">
+ <DependentUpon>Web.config</DependentUpon>
+ </Content>
+ <Content Include="Views\Web.config" />
+ <Content Include="Views\_ViewStart.cshtml" />
+ <Content Include="Views\Shared\_Layout.cshtml" />
+ <Content Include="Views\Home\Index.cshtml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="App_Data\" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="packages.config">
+ <SubType>Designer</SubType>
+ </Content>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\src\Thrift.45.csproj">
+ <Project>{ebce35da-cf6a-42bc-a357-a9c09b534299}</Project>
+ <Name>Thrift.45</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <PropertyGroup>
+ <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ </PropertyGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
+ <Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
+ <AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
+ </Target>
+ <ProjectExtensions>
+ <VisualStudio>
+ <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
+ <WebProjectProperties>
+ <UseIIS>True</UseIIS>
+ <AutoAssignPort>True</AutoAssignPort>
+ <DevelopmentServerPort>57482</DevelopmentServerPort>
+ <DevelopmentServerVPath>/</DevelopmentServerVPath>
+ <IISUrl>http://localhost:57482/</IISUrl>
+ <NTLMAuthentication>False</NTLMAuthentication>
+ <UseCustomServer>False</UseCustomServer>
+ <CustomServerUrl>
+ </CustomServerUrl>
+ <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
+ </WebProjectProperties>
+ </FlavorProperties>
+ </VisualStudio>
+ </ProjectExtensions>
+ <PropertyGroup>
+ <PreBuildEvent>rmdir /s /q "$(ProjectDir)gen-csharp"
+del /f /q "$(ProjectDir)ThriftImpl.dll"
+SET OUTPUT_DIR=$(ProjectDir)
+SET THRIFT_FILE=$(ProjectDir)\..\..\..\..\test\ThriftTest.thrift
+for %25%25I in ("%25OUTPUT_DIR%25") do set SHORT_DIR=%25%25~fsI
+for %25%25I in ("%25THRIFT_FILE%25") do set THRIFT_SHORT=%25%25~fsI
+"$(ProjectDir)\..\..\..\..\compiler\cpp\Debug\thrift.exe" --gen csharp:async=true -o %25SHORT_DIR%25 %25THRIFT_SHORT%25
+"$(MSBuildToolsPath)\Csc.exe" /t:library /out:"$(ProjectDir)ThriftImpl.dll" /recurse:"$(ProjectDir)gen-csharp"\* /reference:"$(ProjectDir)..\..\src\bin\Debug\Thrift45.dll"</PreBuildEvent>
+ </PropertyGroup>
+ <!-- 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/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Views/Home/Index.cshtml b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Views/Home/Index.cshtml
new file mode 100644
index 000000000..f0ca7da20
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Views/Home/Index.cshtml
@@ -0,0 +1,25 @@
+@*
+ 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.
+*@
+
+@{
+ ViewBag.Title = "Home Page";
+}
+
+<p>@Html.ActionLink("Test Thrift Async Service", "TestThriftAsync")</p>
+<p>@Html.ActionLink("Test Thrift Sync Service", "TestThriftSync")</p>
diff --git a/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Views/Shared/_Layout.cshtml b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Views/Shared/_Layout.cshtml
new file mode 100644
index 000000000..b41c99a10
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Views/Shared/_Layout.cshtml
@@ -0,0 +1,30 @@
+@*
+ 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.
+*@
+
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Thrift ASP.NET Test</title>
+</head>
+<body>
+ @RenderBody()
+</body>
+</html>
diff --git a/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Views/Web.config b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Views/Web.config
new file mode 100644
index 000000000..3c211387a
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Views/Web.config
@@ -0,0 +1,60 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+-->
+<configuration>
+ <configSections>
+ <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+ <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
+ <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
+ </sectionGroup>
+ </configSections>
+
+ <system.web.webPages.razor>
+ <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
+ <pages pageBaseType="System.Web.Mvc.WebViewPage">
+ <namespaces>
+ <add namespace="System.Web.Mvc" />
+ <add namespace="System.Web.Mvc.Ajax" />
+ <add namespace="System.Web.Mvc.Html" />
+ <add namespace="System.Web.Optimization"/>
+ <add namespace="System.Web.Routing" />
+ <add namespace="ThriftMVCTest" />
+ </namespaces>
+ </pages>
+ </system.web.webPages.razor>
+
+ <appSettings>
+ <add key="webpages:Enabled" value="false" />
+ </appSettings>
+
+ <system.webServer>
+ <handlers>
+ <remove name="BlockViewHandler"/>
+ <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
+ </handlers>
+ </system.webServer>
+
+ <system.web>
+ <compilation>
+ <assemblies>
+ <add assembly="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
+ </assemblies>
+ </compilation>
+ </system.web>
+</configuration>
diff --git a/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Views/_ViewStart.cshtml b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Views/_ViewStart.cshtml
new file mode 100644
index 000000000..8cde2eeb9
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Views/_ViewStart.cshtml
@@ -0,0 +1,22 @@
+@*
+ 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.
+*@
+
+@{
+ Layout = "~/Views/Shared/_Layout.cshtml";
+}
diff --git a/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Web.Debug.config b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Web.Debug.config
new file mode 100644
index 000000000..45d56d809
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Web.Debug.config
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+-->
+<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
+ <!--
+ In the example below, the "SetAttributes" transform will change the value of
+ "connectionString" to use "ReleaseSQLServer" only when the "Match" locator
+ finds an attribute "name" that has a value of "MyDB".
+
+ <connectionStrings>
+ <add name="MyDB"
+ connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
+ xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
+ </connectionStrings>
+ -->
+ <system.web>
+ <!--
+ In the example below, the "Replace" transform will replace the entire
+ <customErrors> section of your Web.config file.
+ Note that because there is only one customErrors section under the
+ <system.web> node, there is no need to use the "xdt:Locator" attribute.
+
+ <customErrors defaultRedirect="GenericError.htm"
+ mode="RemoteOnly" xdt:Transform="Replace">
+ <error statusCode="500" redirect="InternalError.htm"/>
+ </customErrors>
+ -->
+ </system.web>
+</configuration>
diff --git a/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Web.Release.config b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Web.Release.config
new file mode 100644
index 000000000..157c340ca
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Web.Release.config
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+-->
+<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
+ <!--
+ In the example below, the "SetAttributes" transform will change the value of
+ "connectionString" to use "ReleaseSQLServer" only when the "Match" locator
+ finds an attribute "name" that has a value of "MyDB".
+
+ <connectionStrings>
+ <add name="MyDB"
+ connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
+ xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
+ </connectionStrings>
+ -->
+ <system.web>
+ <compilation xdt:Transform="RemoveAttributes(debug)" />
+ <!--
+ In the example below, the "Replace" transform will replace the entire
+ <customErrors> section of your Web.config file.
+ Note that because there is only one customErrors section under the
+ <system.web> node, there is no need to use the "xdt:Locator" attribute.
+
+ <customErrors defaultRedirect="GenericError.htm"
+ mode="RemoteOnly" xdt:Transform="Replace">
+ <error statusCode="500" redirect="InternalError.htm"/>
+ </customErrors>
+ -->
+ </system.web>
+</configuration>
diff --git a/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Web.config b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Web.config
new file mode 100644
index 000000000..9c57d117c
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/Web.config
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ 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.
+-->
+
+<!--
+ For more information on how to configure your ASP.NET application, please visit
+ http://go.microsoft.com/fwlink/?LinkId=301880
+ -->
+<configuration>
+ <appSettings>
+ <add key="webpages:Version" value="3.0.0.0" />
+ <add key="webpages:Enabled" value="false" />
+ <add key="ClientValidationEnabled" value="true" />
+ <add key="UnobtrusiveJavaScriptEnabled" value="true" />
+ <add key="owin:AutomaticAppStartup" value="false" />
+ </appSettings>
+ <system.web>
+ <authentication mode="None" />
+ <compilation debug="true" targetFramework="4.5" />
+ <httpRuntime targetFramework="4.5" />
+ </system.web>
+ <system.webServer>
+ <modules>
+ <remove name="FormsAuthentication" />
+ </modules>
+ <handlers>
+ <add name="AsyncHttpHandler" verb="*" path="Async.thrift" type="ThriftMVCTest.AsyncHttpHandler, ThriftMVCTest" />
+ <add name="SyncHttpHandler" verb="*" path="Sync.thrift" type="ThriftMVCTest.SyncHttpHandler, ThriftMVCTest" />
+ </handlers>
+ </system.webServer>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
+ <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+</configuration> \ No newline at end of file
diff --git a/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/favicon.ico b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/favicon.ico
new file mode 100644
index 000000000..a3a799985
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/favicon.ico
Binary files differ
diff --git a/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/packages.config b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/packages.config
new file mode 100644
index 000000000..98c8416f5
--- /dev/null
+++ b/src/jaegertracing/thrift/lib/csharp/test/ThriftMVCTest/packages.config
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<packages>
+ <package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net45" />
+ <package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net45" />
+ <package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net45" />
+ <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
+</packages> \ No newline at end of file