THRIFT-4434: .NET Core cleanup and the beginnings of compiler unit tests
Client: netcore
This closes #1449
diff --git a/lib/netcore/Makefile.am b/lib/netcore/Makefile.am
index facee11..992558b 100644
--- a/lib/netcore/Makefile.am
+++ b/lib/netcore/Makefile.am
@@ -19,86 +19,25 @@
SUBDIRS = .
-THRIFT = $(top_builddir)/compiler/cpp/thrift
-
-TESTDIR = Tests/Thrift.PublicInterfaces.Compile.Tests
-GENDIR = $(TESTDIR)/gen-netcore
-
THRIFTCODE = \
- Thrift/Thrift.csproj \
- Thrift/ITAsyncProcessor.cs \
- Thrift/ITProcessorFactory.cs \
- Thrift/SingletonTProcessorFactory.cs \
- Thrift/TApplicationException.cs \
- Thrift/TBaseClient.cs \
- Thrift/TException.cs \
- Thrift/TMultiplexedProcessor.cs \
- Thrift/Collections/TCollections.cs \
- Thrift/Collections/THashSet.cs \
- Thrift/Properties/AssemblyInfo.cs \
- Thrift/Protocols/ITProtocolFactory.cs \
- Thrift/Protocols/TAbstractBase.cs \
- Thrift/Protocols/TBase.cs \
- Thrift/Protocols/TBinaryProtocol.cs \
- Thrift/Protocols/TCompactProtocol.cs \
- Thrift/Protocols/TJSONProtocol.cs \
- Thrift/Protocols/TMultiplexedProtocol.cs \
- Thrift/Protocols/TProtocol.cs \
- Thrift/Protocols/TProtocolDecorator.cs \
- Thrift/Protocols/TProtocolException.cs \
- Thrift/Protocols/Entities/TField.cs \
- Thrift/Protocols/Entities/TList.cs \
- Thrift/Protocols/Entities/TMap.cs \
- Thrift/Protocols/Entities/TMessage.cs \
- Thrift/Protocols/Entities/TMessageType.cs \
- Thrift/Protocols/Entities/TSet.cs \
- Thrift/Protocols/Entities/TStruct.cs \
- Thrift/Protocols/Entities/TType.cs \
- Thrift/Protocols/Utilities/TBase64Utils.cs \
- Thrift/Protocols/Utilities/TProtocolUtil.cs \
- Thrift/Server/AsyncBaseServer.cs \
- Thrift/Server/TBaseServer.cs \
- Thrift/Server/TServerEventHandler.cs \
- Thrift/Transports/TClientTransport.cs \
- Thrift/Transports/TServerTransport.cs \
- Thrift/Transports/TTransportException.cs \
- Thrift/Transports/TTransportFactory.cs \
- Thrift/Transports/Client/TBufferedClientTransport.cs \
- Thrift/Transports/Client/TFramedClientTransport.cs \
- Thrift/Transports/Client/THttpClientTransport.cs \
- Thrift/Transports/Client/TMemoryBufferClientTransport.cs \
- Thrift/Transports/Client/TNamedPipeClientTransport.cs \
- Thrift/Transports/Client/TSocketClientTransport.cs \
- Thrift/Transports/Client/TStreamClientTransport.cs \
- Thrift/Transports/Client/TTlsSocketClientTransport.cs \
- Thrift/Transports/Server/THttpServerTransport.cs \
- Thrift/Transports/Server/TNamedPipeServerTransport.cs \
- Thrift/Transports/Server/TServerFramedTransport.cs \
- Thrift/Transports/Server/TServerSocketTransport.cs \
- Thrift/Transports/Server/TTlsServerSocketTransport.cs
+ Thrift/Thrift.csproj
all-local: \
Thrift.dll
Thrift.dll: $(THRIFTCODE)
- $(MKDIR_P) $(GENDIR)
- $(THRIFT) -gen netcore:wcf -r -out $(GENDIR) $(TESTDIR)/CassandraTest.thrift
- $(THRIFT) -gen netcore:wcf -r -out $(GENDIR) $(top_srcdir)/test/ThriftTest.thrift
- $(THRIFT) -gen netcore:wcf -r -out $(GENDIR) $(top_srcdir)/contrib/fb303/if/fb303.thrift
- $(DOTNETCORE) --info
- $(DOTNETCORE) restore
+# $(MKDIR_P) $(GENDIR)
+# $(THRIFT) -gen netcore:wcf -r -out $(GENDIR) $(TESTDIR)/CassandraTest.thrift
+# $(THRIFT) -gen netcore:wcf -r -out $(GENDIR) $(top_srcdir)/test/ThriftTest.thrift
+# $(THRIFT) -gen netcore:wcf -r -out $(GENDIR) $(top_srcdir)/contrib/fb303/if/fb303.thrift
$(DOTNETCORE) build
clean-local:
- $(RM) Thrift.dll
- $(RM) -r $(GENDIR)
$(RM) -r Thrift/bin
$(RM) -r Thrift/obj
- $(RM) -r Tests/Thrift.PublicInterfaces.Compile.Tests/bin
- $(RM) -r Tests/Thrift.PublicInterfaces.Compile.Tests/obj
EXTRA_DIST = \
- $(THRIFTCODE) \
+ Thrift \
Thrift.sln \
Tests \
README.md
diff --git a/lib/netcore/README.md b/lib/netcore/README.md
index 39492f3..94b047f 100644
--- a/lib/netcore/README.md
+++ b/lib/netcore/README.md
@@ -10,7 +10,10 @@
- .NET Standard 1.6 (SDK 2.0.0)
# How to build on Windows
+- Get Thrift IDL compiler executable, add to some folder and add path to this folder into PATH variable
- Open the Thrift.sln project with Visual Studio and build.
+or
+- Build with scripts
# How to build on Unix
- Ensure you have .NET Core 2.0.0 SDK installed or use the Ubuntu Xenial docker image
diff --git a/lib/netcore/Tests/Thrift.IntegrationTests/.gitignore b/lib/netcore/Tests/Thrift.IntegrationTests/.gitignore
new file mode 100644
index 0000000..7254c31
--- /dev/null
+++ b/lib/netcore/Tests/Thrift.IntegrationTests/.gitignore
@@ -0,0 +1,2 @@
+# ignore for autogenerated files
+/Apache
diff --git a/lib/netcore/Tests/Thrift.IntegrationTests/Protocols/ProtocolsOperationsTests.cs b/lib/netcore/Tests/Thrift.IntegrationTests/Protocols/ProtocolsOperationsTests.cs
new file mode 100644
index 0000000..bc4afa1
--- /dev/null
+++ b/lib/netcore/Tests/Thrift.IntegrationTests/Protocols/ProtocolsOperationsTests.cs
@@ -0,0 +1,502 @@
+// 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.Threading.Tasks;
+using KellermanSoftware.CompareNetObjects;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Thrift.Protocols;
+using Thrift.Protocols.Entities;
+using Thrift.Transports.Client;
+
+namespace Thrift.IntegrationTests.Protocols
+{
+ [TestClass]
+ public class ProtocolsOperationsTests
+ {
+ private readonly CompareLogic _compareLogic = new CompareLogic();
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol), TMessageType.Call)]
+ [DataRow(typeof(TBinaryProtocol), TMessageType.Exception)]
+ [DataRow(typeof(TBinaryProtocol), TMessageType.Oneway)]
+ [DataRow(typeof(TBinaryProtocol), TMessageType.Reply)]
+ [DataRow(typeof(TCompactProtocol), TMessageType.Call)]
+ [DataRow(typeof(TCompactProtocol), TMessageType.Exception)]
+ [DataRow(typeof(TCompactProtocol), TMessageType.Oneway)]
+ [DataRow(typeof(TCompactProtocol), TMessageType.Reply)]
+ [DataRow(typeof(TJsonProtocol), TMessageType.Call)]
+ [DataRow(typeof(TJsonProtocol), TMessageType.Exception)]
+ [DataRow(typeof(TJsonProtocol), TMessageType.Oneway)]
+ [DataRow(typeof(TJsonProtocol), TMessageType.Reply)]
+ public async Task WriteReadMessage_Test(Type protocolType, TMessageType messageType)
+ {
+ var expected = new TMessage(nameof(TMessage), messageType, 1);
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteMessageBeginAsync(expected);
+ await protocol.WriteMessageEndAsync();
+
+ stream.Seek(0, SeekOrigin.Begin);
+
+ var actualMessage = await protocol.ReadMessageBeginAsync();
+ await protocol.ReadMessageEndAsync();
+
+ var result = _compareLogic.Compare(expected, actualMessage);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ [ExpectedException(typeof(Exception))]
+ public async Task WriteReadStruct_Test(Type protocolType)
+ {
+ var expected = new TStruct(nameof(TStruct));
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteStructBeginAsync(expected);
+ await protocol.WriteStructEndAsync();
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadStructBeginAsync();
+ await protocol.ReadStructEndAsync();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ [ExpectedException(typeof(Exception))]
+ public async Task WriteReadField_Test(Type protocolType)
+ {
+ var expected = new TField(nameof(TField), TType.String, 1);
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteFieldBeginAsync(expected);
+ await protocol.WriteFieldEndAsync();
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadFieldBeginAsync();
+ await protocol.ReadFieldEndAsync();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ public async Task WriteReadMap_Test(Type protocolType)
+ {
+ var expected = new TMap(TType.String, TType.String, 1);
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteMapBeginAsync(expected);
+ await protocol.WriteMapEndAsync();
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadMapBeginAsync();
+ await protocol.ReadMapEndAsync();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ public async Task WriteReadList_Test(Type protocolType)
+ {
+ var expected = new TList(TType.String, 1);
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteListBeginAsync(expected);
+ await protocol.WriteListEndAsync();
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadListBeginAsync();
+ await protocol.ReadListEndAsync();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ public async Task WriteReadSet_Test(Type protocolType)
+ {
+ var expected = new TSet(TType.String, 1);
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteSetBeginAsync(expected);
+ await protocol.WriteSetEndAsync();
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadSetBeginAsync();
+ await protocol.ReadSetEndAsync();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ public async Task WriteReadBool_Test(Type protocolType)
+ {
+ var expected = true;
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteBoolAsync(expected);
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadBoolAsync();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ public async Task WriteReadByte_Test(Type protocolType)
+ {
+ var expected = sbyte.MaxValue;
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteByteAsync(expected);
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadByteAsync();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ public async Task WriteReadI16_Test(Type protocolType)
+ {
+ var expected = short.MaxValue;
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteI16Async(expected);
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadI16Async();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ public async Task WriteReadI32_Test(Type protocolType)
+ {
+ var expected = int.MaxValue;
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteI32Async(expected);
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadI32Async();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ public async Task WriteReadI64_Test(Type protocolType)
+ {
+ var expected = long.MaxValue;
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteI64Async(expected);
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadI64Async();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ public async Task WriteReadDouble_Test(Type protocolType)
+ {
+ var expected = double.MaxValue;
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteDoubleAsync(expected);
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadDoubleAsync();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ public async Task WriteReadString_Test(Type protocolType)
+ {
+ var expected = nameof(String);
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteStringAsync(expected);
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadStringAsync();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ public async Task WriteReadBinary_Test(Type protocolType)
+ {
+ var expected = Encoding.UTF8.GetBytes(nameof(String));
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteBinaryAsync(expected);
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadBinaryAsync();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ private static Tuple<Stream, TProtocol> GetProtocolInstance(Type protocolType)
+ {
+ var memoryStream = new MemoryStream();
+ var streamClientTransport = new TStreamClientTransport(memoryStream, memoryStream);
+ var protocol = (TProtocol) Activator.CreateInstance(protocolType, streamClientTransport);
+ return new Tuple<Stream, TProtocol>(memoryStream, protocol);
+ }
+ }
+}
diff --git a/lib/netcore/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj b/lib/netcore/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj
new file mode 100644
index 0000000..f25dac5
--- /dev/null
+++ b/lib/netcore/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj
@@ -0,0 +1,29 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <TargetFramework>netcoreapp2.0</TargetFramework>
+ <AssemblyName>Thrift.IntegrationTests</AssemblyName>
+ <PackageId>Thrift.IntegrationTests</PackageId>
+ <OutputType>Exe</OutputType>
+ <GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
+ <GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
+ <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+ <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+ <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+ <GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="CompareNETObjects" Version="4.3.0" />
+ <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
+ <PackageReference Include="MSTest.TestAdapter" Version="1.2.0" />
+ <PackageReference Include="MSTest.TestFramework" Version="1.2.0" />
+ <PackageReference Include="System.ServiceModel.Primitives" Version="4.4.0" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\Thrift\Thrift.csproj" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
+ </ItemGroup>
+
+</Project>
\ No newline at end of file
diff --git a/lib/netcore/Tests/Thrift.PublicInterfaces.Compile.Tests/.gitignore b/lib/netcore/Tests/Thrift.PublicInterfaces.Compile.Tests/.gitignore
new file mode 100644
index 0000000..ae929a3
--- /dev/null
+++ b/lib/netcore/Tests/Thrift.PublicInterfaces.Compile.Tests/.gitignore
@@ -0,0 +1,4 @@
+# ignore for autogenerated files
+/ThriftTest
+/Apache
+/Facebook
diff --git a/lib/netcore/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj b/lib/netcore/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj
index f551116..c4a84a3 100644
--- a/lib/netcore/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj
+++ b/lib/netcore/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj
@@ -18,4 +18,19 @@
<PackageReference Include="System.ServiceModel.Primitives" Version="[4.1.0,)" />
</ItemGroup>
+ <Target Name="PreBuild" BeforeTargets="_GenerateRestoreProjectSpec;Restore;Compile">
+ <Exec Condition="'$(OS)' == 'Windows_NT'" Command="where thrift" ConsoleToMSBuild="true">
+ <Output TaskParameter="ConsoleOutput" PropertyName="PathToThrift" />
+ </Exec>
+ <Exec Condition="Exists('$(PathToThrift)')" Command="$(PathToThrift) -out $(ProjectDir) -gen netcore:wcf,union,serial,hashcode -r ./CassandraTest.thrift" />
+ <Exec Condition="Exists('thrift')" Command="thrift -out $(ProjectDir) -gen netcore:wcf,union,serial,hashcode -r ./CassandraTest.thrift" />
+ <Exec Condition="Exists('$(ProjectDir)/../../../compiler/cpp/thrift')" Command="$(ProjectDir)/../../../compiler/cpp/thrift -out $(ProjectDir) -gen netcore:wcf,union,serial,hashcode -r ./CassandraTest.thrift" />
+ <Exec Condition="Exists('$(PathToThrift)')" Command="$(PathToThrift) -out $(ProjectDir) -gen netcore:wcf,union,serial,hashcode -r ./../../../../test/ThriftTest.thrift" />
+ <Exec Condition="Exists('thrift')" Command="thrift -out $(ProjectDir) -gen netcore:wcf,union,serial,hashcode -r ./../../../../test/ThriftTest.thrift" />
+ <Exec Condition="Exists('$(ProjectDir)/../../../compiler/cpp/thrift')" Command="$(ProjectDir)/../../../compiler/cpp/thrift -out $(ProjectDir) -gen netcore:wcf,union,serial,hashcode -r ./../../../../test/ThriftTest.thrift" />
+ <Exec Condition="Exists('$(PathToThrift)')" Command="$(PathToThrift) -out $(ProjectDir) -gen netcore:wcf,union,serial,hashcode -r ./../../../../contrib/fb303/if/fb303.thrift" />
+ <Exec Condition="Exists('thrift')" Command="thrift -out $(ProjectDir) -gen netcore:wcf,union,serial,hashcode -r ./../../../../contrib/fb303/if/fb303.thrift" />
+ <Exec Condition="Exists('$(ProjectDir)/../../../compiler/cpp/thrift')" Command="$(ProjectDir)/../../../compiler/cpp/thrift -out $(ProjectDir) -gen netcore:wcf,union,serial,hashcode -r ./../../../../contrib/fb303/if/fb303.thrift" />
+ </Target>
+
</Project>
diff --git a/lib/netcore/Tests/Thrift.Tests/Collections/TCollectionsTests.cs b/lib/netcore/Tests/Thrift.Tests/Collections/TCollectionsTests.cs
new file mode 100644
index 0000000..1be99b4
--- /dev/null
+++ b/lib/netcore/Tests/Thrift.Tests/Collections/TCollectionsTests.cs
@@ -0,0 +1,83 @@
+// 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.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Thrift.Collections;
+
+namespace Thrift.Tests.Collections
+{
+ // ReSharper disable once InconsistentNaming
+ [TestClass]
+ public class TCollectionsTests
+ {
+ //TODO: Add tests for IEnumerable with objects and primitive values inside
+
+ [TestMethod]
+ public void TCollection_Equals_Primitive_Test()
+ {
+ var collection1 = new List<int> {1,2,3};
+ var collection2 = new List<int> {1,2,3};
+
+ var result = TCollections.Equals(collection1, collection2);
+
+ Assert.IsTrue(result);
+ }
+
+ [TestMethod]
+ public void TCollection_Equals_Primitive_Different_Test()
+ {
+ var collection1 = new List<int> { 1, 2, 3 };
+ var collection2 = new List<int> { 1, 2 };
+
+ var result = TCollections.Equals(collection1, collection2);
+
+ Assert.IsFalse(result);
+ }
+
+ [TestMethod]
+ public void TCollection_Equals_Objects_Test()
+ {
+ var collection1 = new List<ExampleClass> { new ExampleClass { X = 1 }, new ExampleClass { X = 2 } };
+ var collection2 = new List<ExampleClass> { new ExampleClass { X = 1 }, new ExampleClass { X = 2 } };
+
+ var result = TCollections.Equals(collection1, collection2);
+
+ // references to different collections
+ Assert.IsFalse(result);
+ }
+
+ [TestMethod]
+ public void TCollection_Equals_OneAndTheSameObject_Test()
+ {
+ var collection1 = new List<ExampleClass> { new ExampleClass { X = 1 }, new ExampleClass { X = 2 } };
+ var collection2 = collection1;
+
+ var result = TCollections.Equals(collection1, collection2);
+
+ // references to one and the same collection
+ Assert.IsTrue(result);
+ }
+
+ private class ExampleClass
+ {
+ public int X { get; set; }
+ }
+ }
+}
diff --git a/lib/netcore/Tests/Thrift.Tests/Collections/THashSetTests.cs b/lib/netcore/Tests/Thrift.Tests/Collections/THashSetTests.cs
new file mode 100644
index 0000000..8de573e
--- /dev/null
+++ b/lib/netcore/Tests/Thrift.Tests/Collections/THashSetTests.cs
@@ -0,0 +1,71 @@
+// 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 Microsoft.VisualStudio.TestTools.UnitTesting;
+using Thrift.Collections;
+
+namespace Thrift.Tests.Collections
+{
+ // ReSharper disable once InconsistentNaming
+ [TestClass]
+ public class THashSetTests
+ {
+ [TestMethod]
+ public void THashSet_Equals_Primitive_Test()
+ {
+ const int value = 1;
+
+ var hashSet = new THashSet<int> {value};
+
+ Assert.IsTrue(hashSet.Contains(value));
+
+ hashSet.Remove(value);
+
+ Assert.IsTrue(hashSet.Count == 0);
+
+ hashSet.Add(value);
+
+ Assert.IsTrue(hashSet.Contains(value));
+
+ hashSet.Clear();
+
+ Assert.IsTrue(hashSet.Count == 0);
+
+ var newArr = new int[1];
+ hashSet.Add(value);
+ hashSet.CopyTo(newArr, 0);
+
+ Assert.IsTrue(newArr.Contains(value));
+
+ var en = hashSet.GetEnumerator();
+ en.MoveNext();
+
+ Assert.IsTrue((int)en.Current == value);
+
+ using (var ien = ((IEnumerable<int>)hashSet).GetEnumerator())
+ {
+ ien.MoveNext();
+
+ Assert.IsTrue(ien.Current == value);
+ }
+ }
+ }
+}
diff --git a/lib/netcore/Tests/Thrift.Tests/Protocols/TJsonProtocolHelperTests.cs b/lib/netcore/Tests/Thrift.Tests/Protocols/TJsonProtocolHelperTests.cs
new file mode 100644
index 0000000..cdc8317
--- /dev/null
+++ b/lib/netcore/Tests/Thrift.Tests/Protocols/TJsonProtocolHelperTests.cs
@@ -0,0 +1,172 @@
+// 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 Microsoft.VisualStudio.TestTools.UnitTesting;
+using Thrift.Protocols;
+using Thrift.Protocols.Entities;
+using Thrift.Protocols.Utilities;
+
+namespace Thrift.Tests.Protocols
+{
+ [TestClass]
+ public class TJSONProtocolHelperTests
+ {
+ [TestMethod]
+ public void GetTypeNameForTypeId_Test()
+ {
+ // input/output
+ var sets = new List<Tuple<TType, byte[]>>
+ {
+ new Tuple<TType, byte[]>(TType.Bool, TJSONProtocolConstants.TypeNames.NameBool),
+ new Tuple<TType, byte[]>(TType.Byte, TJSONProtocolConstants.TypeNames.NameByte),
+ new Tuple<TType, byte[]>(TType.I16, TJSONProtocolConstants.TypeNames.NameI16),
+ new Tuple<TType, byte[]>(TType.I32, TJSONProtocolConstants.TypeNames.NameI32),
+ new Tuple<TType, byte[]>(TType.I64, TJSONProtocolConstants.TypeNames.NameI64),
+ new Tuple<TType, byte[]>(TType.Double, TJSONProtocolConstants.TypeNames.NameDouble),
+ new Tuple<TType, byte[]>(TType.String, TJSONProtocolConstants.TypeNames.NameString),
+ new Tuple<TType, byte[]>(TType.Struct, TJSONProtocolConstants.TypeNames.NameStruct),
+ new Tuple<TType, byte[]>(TType.Map, TJSONProtocolConstants.TypeNames.NameMap),
+ new Tuple<TType, byte[]>(TType.Set, TJSONProtocolConstants.TypeNames.NameSet),
+ new Tuple<TType, byte[]>(TType.List, TJSONProtocolConstants.TypeNames.NameList),
+ };
+
+ foreach (var t in sets)
+ {
+ Assert.IsTrue(TJSONProtocolHelper.GetTypeNameForTypeId(t.Item1) == t.Item2, $"Wrong mapping of TypeName {t.Item2} to TType: {t.Item1}");
+ }
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(TProtocolException))]
+ public void GetTypeNameForTypeId_TStop_Test()
+ {
+ TJSONProtocolHelper.GetTypeNameForTypeId(TType.Stop);
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(TProtocolException))]
+ public void GetTypeNameForTypeId_NonExistingTType_Test()
+ {
+ TJSONProtocolHelper.GetTypeNameForTypeId((TType)100);
+ }
+
+ [TestMethod]
+ public void GetTypeIdForTypeName_Test()
+ {
+ // input/output
+ var sets = new List<Tuple<TType, byte[]>>
+ {
+ new Tuple<TType, byte[]>(TType.Bool, TJSONProtocolConstants.TypeNames.NameBool),
+ new Tuple<TType, byte[]>(TType.Byte, TJSONProtocolConstants.TypeNames.NameByte),
+ new Tuple<TType, byte[]>(TType.I16, TJSONProtocolConstants.TypeNames.NameI16),
+ new Tuple<TType, byte[]>(TType.I32, TJSONProtocolConstants.TypeNames.NameI32),
+ new Tuple<TType, byte[]>(TType.I64, TJSONProtocolConstants.TypeNames.NameI64),
+ new Tuple<TType, byte[]>(TType.Double, TJSONProtocolConstants.TypeNames.NameDouble),
+ new Tuple<TType, byte[]>(TType.String, TJSONProtocolConstants.TypeNames.NameString),
+ new Tuple<TType, byte[]>(TType.Struct, TJSONProtocolConstants.TypeNames.NameStruct),
+ new Tuple<TType, byte[]>(TType.Map, TJSONProtocolConstants.TypeNames.NameMap),
+ new Tuple<TType, byte[]>(TType.Set, TJSONProtocolConstants.TypeNames.NameSet),
+ new Tuple<TType, byte[]>(TType.List, TJSONProtocolConstants.TypeNames.NameList),
+ };
+
+ foreach (var t in sets)
+ {
+ Assert.IsTrue(TJSONProtocolHelper.GetTypeIdForTypeName(t.Item2) == t.Item1, $"Wrong mapping of TypeName {t.Item2} to TType: {t.Item1}");
+ }
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(TProtocolException))]
+ public void GetTypeIdForTypeName_TStopTypeName_Test()
+ {
+ TJSONProtocolHelper.GetTypeIdForTypeName(new []{(byte)TType.Stop, (byte)TType.Stop});
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(TProtocolException))]
+ public void GetTypeIdForTypeName_NonExistingTypeName_Test()
+ {
+ TJSONProtocolHelper.GetTypeIdForTypeName(new byte[]{100});
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(TProtocolException))]
+ public void GetTypeIdForTypeName_EmptyName_Test()
+ {
+ TJSONProtocolHelper.GetTypeIdForTypeName(new byte[] {});
+ }
+
+ [TestMethod]
+ public void IsJsonNumeric_Test()
+ {
+ // input/output
+ var correctJsonNumeric = "+-.0123456789Ee";
+ var incorrectJsonNumeric = "AaBcDd/*\\";
+
+ var sets = correctJsonNumeric.Select(ch => new Tuple<byte, bool>((byte) ch, true)).ToList();
+ sets.AddRange(incorrectJsonNumeric.Select(ch => new Tuple<byte, bool>((byte) ch, false)));
+
+ foreach (var t in sets)
+ {
+ Assert.IsTrue(TJSONProtocolHelper.IsJsonNumeric(t.Item1) == t.Item2, $"Wrong mapping of Char {t.Item1} to bool: {t.Item2}");
+ }
+ }
+
+ [TestMethod]
+ public void ToHexVal_Test()
+ {
+ // input/output
+ var chars = "0123456789abcdef";
+ var expectedHexValues = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+
+ var sets = chars.Select((ch, i) => new Tuple<char, byte>(ch, expectedHexValues[i])).ToList();
+
+ foreach (var t in sets)
+ {
+ var actualResult = TJSONProtocolHelper.ToHexVal((byte)t.Item1);
+ Assert.IsTrue(actualResult == t.Item2, $"Wrong mapping of char byte {t.Item1} to it expected hex value: {t.Item2}. Actual hex value: {actualResult}");
+ }
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(TProtocolException))]
+ public void ToHexVal_WrongInputChar_Test()
+ {
+ TJSONProtocolHelper.ToHexVal((byte)'s');
+ }
+
+ [TestMethod]
+ public void ToHexChar_Test()
+ {
+ // input/output
+ var hexValues = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+ var expectedChars = "0123456789abcdef";
+
+
+ var sets = hexValues.Select((hv, i) => new Tuple<byte, char>(hv, expectedChars[i])).ToList();
+
+ foreach (var t in sets)
+ {
+ var actualResult = TJSONProtocolHelper.ToHexChar(t.Item1);
+ Assert.IsTrue(actualResult == t.Item2, $"Wrong mapping of hex value {t.Item1} to it expected char: {t.Item2}. Actual hex value: {actualResult}");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netcore/Tests/Thrift.Tests/Protocols/TJsonProtocolTests.cs b/lib/netcore/Tests/Thrift.Tests/Protocols/TJsonProtocolTests.cs
new file mode 100644
index 0000000..5237360
--- /dev/null
+++ b/lib/netcore/Tests/Thrift.Tests/Protocols/TJsonProtocolTests.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.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using NSubstitute;
+using Thrift.Protocols;
+using Thrift.Protocols.Entities;
+using Thrift.Transports;
+using Thrift.Transports.Client;
+
+namespace Thrift.Tests.Protocols
+{
+ // ReSharper disable once InconsistentNaming
+ [TestClass]
+ public class TJSONProtocolTests
+ {
+ [TestMethod]
+ public void TJSONProtocol_Can_Create_Instance_Test()
+ {
+ var httpClientTransport = Substitute.For<THttpClientTransport>(new Uri("http://localhost"), null);
+
+ var result = new TJSONProtocolWrapper(httpClientTransport);
+
+ Assert.IsNotNull(result);
+ Assert.IsNotNull(result.WrappedContext);
+ Assert.IsNotNull(result.WrappedReader);
+ Assert.IsNotNull(result.Transport);
+ Assert.IsTrue(result.WrappedRecursionDepth == 0);
+ Assert.IsTrue(result.WrappedRecursionLimit == TProtocol.DefaultRecursionDepth);
+
+ Assert.IsTrue(result.Transport.Equals(httpClientTransport));
+ Assert.IsTrue(result.WrappedContext.GetType().Name.Equals("JSONBaseContext", StringComparison.OrdinalIgnoreCase));
+ Assert.IsTrue(result.WrappedReader.GetType().Name.Equals("LookaheadReader", StringComparison.OrdinalIgnoreCase));
+ }
+
+ private class TJSONProtocolWrapper : TJsonProtocol
+ {
+ public TJSONProtocolWrapper(TClientTransport trans) : base(trans)
+ {
+ }
+
+ public object WrappedContext => Context;
+ public object WrappedReader => Reader;
+ public int WrappedRecursionDepth => RecursionDepth;
+ public int WrappedRecursionLimit => RecursionLimit;
+ }
+ }
+}
diff --git a/lib/netcore/Tests/Thrift.Tests/Thrift.Tests.csproj b/lib/netcore/Tests/Thrift.Tests/Thrift.Tests.csproj
new file mode 100644
index 0000000..e46f165
--- /dev/null
+++ b/lib/netcore/Tests/Thrift.Tests/Thrift.Tests.csproj
@@ -0,0 +1,18 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <TargetFramework>netcoreapp2.0</TargetFramework>
+ </PropertyGroup>
+ <ItemGroup>
+ <PackageReference Include="CompareNETObjects" Version="4.3.0" />
+ <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
+ <PackageReference Include="MSTest.TestAdapter" Version="1.2.0" />
+ <PackageReference Include="MSTest.TestFramework" Version="1.2.0" />
+ <PackageReference Include="NSubstitute" Version="3.1.0" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\Thrift\Thrift.csproj" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
+ </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/lib/netcore/Thrift.sln b/lib/netcore/Thrift.sln
index a730269..fe30aa5 100644
--- a/lib/netcore/Thrift.sln
+++ b/lib/netcore/Thrift.sln
@@ -4,10 +4,14 @@
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{F51FC4DA-CAC0-48B1-A069-B1712BCAA5BE}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.PublicInterfaces.Compile.Tests", "Tests\Thrift.PublicInterfaces.Compile.Tests\Thrift.PublicInterfaces.Compile.Tests.csproj", "{0676962B-98C2-49EC-B4C4-7A0451D0640B}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift", "Thrift\Thrift.csproj", "{D85F572F-7D80-40A4-9A9B-2731ED187C24}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.IntegrationTests", "Tests\Thrift.IntegrationTests\Thrift.IntegrationTests.csproj", "{9F9A11BF-3C95-4E80-AFBF-768541996844}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.Tests", "Tests\Thrift.Tests\Thrift.Tests.csproj", "{75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.PublicInterfaces.Compile.Tests", "Tests\Thrift.PublicInterfaces.Compile.Tests\Thrift.PublicInterfaces.Compile.Tests.csproj", "{A429F05B-F511-45EF-AE7B-04E1AE9C9367}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -18,18 +22,6 @@
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Debug|x64.ActiveCfg = Debug|Any CPU
- {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Debug|x64.Build.0 = Debug|Any CPU
- {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Debug|x86.ActiveCfg = Debug|Any CPU
- {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Debug|x86.Build.0 = Debug|Any CPU
- {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Release|Any CPU.Build.0 = Release|Any CPU
- {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Release|x64.ActiveCfg = Release|Any CPU
- {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Release|x64.Build.0 = Release|Any CPU
- {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Release|x86.ActiveCfg = Release|Any CPU
- {0676962B-98C2-49EC-B4C4-7A0451D0640B}.Release|x86.Build.0 = Release|Any CPU
{D85F572F-7D80-40A4-9A9B-2731ED187C24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D85F572F-7D80-40A4-9A9B-2731ED187C24}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D85F572F-7D80-40A4-9A9B-2731ED187C24}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -42,12 +34,50 @@
{D85F572F-7D80-40A4-9A9B-2731ED187C24}.Release|x64.Build.0 = Release|Any CPU
{D85F572F-7D80-40A4-9A9B-2731ED187C24}.Release|x86.ActiveCfg = Release|Any CPU
{D85F572F-7D80-40A4-9A9B-2731ED187C24}.Release|x86.Build.0 = Release|Any CPU
+ {9F9A11BF-3C95-4E80-AFBF-768541996844}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9F9A11BF-3C95-4E80-AFBF-768541996844}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9F9A11BF-3C95-4E80-AFBF-768541996844}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {9F9A11BF-3C95-4E80-AFBF-768541996844}.Debug|x64.Build.0 = Debug|Any CPU
+ {9F9A11BF-3C95-4E80-AFBF-768541996844}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9F9A11BF-3C95-4E80-AFBF-768541996844}.Debug|x86.Build.0 = Debug|Any CPU
+ {9F9A11BF-3C95-4E80-AFBF-768541996844}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9F9A11BF-3C95-4E80-AFBF-768541996844}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9F9A11BF-3C95-4E80-AFBF-768541996844}.Release|x64.ActiveCfg = Release|Any CPU
+ {9F9A11BF-3C95-4E80-AFBF-768541996844}.Release|x64.Build.0 = Release|Any CPU
+ {9F9A11BF-3C95-4E80-AFBF-768541996844}.Release|x86.ActiveCfg = Release|Any CPU
+ {9F9A11BF-3C95-4E80-AFBF-768541996844}.Release|x86.Build.0 = Release|Any CPU
+ {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Debug|x64.Build.0 = Debug|Any CPU
+ {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Debug|x86.Build.0 = Debug|Any CPU
+ {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Release|x64.ActiveCfg = Release|Any CPU
+ {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Release|x64.Build.0 = Release|Any CPU
+ {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Release|x86.ActiveCfg = Release|Any CPU
+ {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1}.Release|x86.Build.0 = Release|Any CPU
+ {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Debug|x64.Build.0 = Debug|Any CPU
+ {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Debug|x86.Build.0 = Debug|Any CPU
+ {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Release|x64.ActiveCfg = Release|Any CPU
+ {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Release|x64.Build.0 = Release|Any CPU
+ {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Release|x86.ActiveCfg = Release|Any CPU
+ {A429F05B-F511-45EF-AE7B-04E1AE9C9367}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
- {0676962B-98C2-49EC-B4C4-7A0451D0640B} = {F51FC4DA-CAC0-48B1-A069-B1712BCAA5BE}
+ {9F9A11BF-3C95-4E80-AFBF-768541996844} = {F51FC4DA-CAC0-48B1-A069-B1712BCAA5BE}
+ {75C2F9DC-3546-4D0A-A2DF-31C93516B6C1} = {F51FC4DA-CAC0-48B1-A069-B1712BCAA5BE}
+ {A429F05B-F511-45EF-AE7B-04E1AE9C9367} = {F51FC4DA-CAC0-48B1-A069-B1712BCAA5BE}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FD20BC4A-0109-41D8-8C0C-893E784D7EF9}
diff --git a/lib/netcore/Thrift/Protocols/TAbstractBase.cs b/lib/netcore/Thrift/Protocols/TAbstractBase.cs
index eddb85e..4e18681 100644
--- a/lib/netcore/Thrift/Protocols/TAbstractBase.cs
+++ b/lib/netcore/Thrift/Protocols/TAbstractBase.cs
@@ -1,4 +1,4 @@
-// Licensed to the Apache Software Foundation(ASF) under one
+// 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
diff --git a/lib/netcore/Thrift/Protocols/TBase.cs b/lib/netcore/Thrift/Protocols/TBase.cs
index cd11099..014e1ae 100644
--- a/lib/netcore/Thrift/Protocols/TBase.cs
+++ b/lib/netcore/Thrift/Protocols/TBase.cs
@@ -1,4 +1,4 @@
-// Licensed to the Apache Software Foundation(ASF) under one
+// 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
diff --git a/lib/netcore/Thrift/Protocols/TBinaryProtocol.cs b/lib/netcore/Thrift/Protocols/TBinaryProtocol.cs
index fa0c5fc..deec85c 100644
--- a/lib/netcore/Thrift/Protocols/TBinaryProtocol.cs
+++ b/lib/netcore/Thrift/Protocols/TBinaryProtocol.cs
@@ -1,4 +1,4 @@
-// Licensed to the Apache Software Foundation(ASF) under one
+// 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
@@ -79,7 +79,7 @@
}
}
- public override async Task WriteStructBeginAsync(TStruct struc, CancellationToken cancellationToken)
+ public override async Task WriteStructBeginAsync(TStruct @struct, CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -293,15 +293,15 @@
await WriteI64Async(BitConverter.DoubleToInt64Bits(d), cancellationToken);
}
- public override async Task WriteBinaryAsync(byte[] b, CancellationToken cancellationToken)
+ public override async Task WriteBinaryAsync(byte[] bytes, CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
{
return;
}
- await WriteI32Async(b.Length, cancellationToken);
- await Trans.WriteAsync(b, 0, b.Length, cancellationToken);
+ await WriteI32Async(bytes.Length, cancellationToken);
+ await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
}
public override async Task<TMessage> ReadMessageBeginAsync(CancellationToken cancellationToken)
@@ -511,8 +511,13 @@
var i32In = new byte[4];
await Trans.ReadAllAsync(i32In, 0, 4, cancellationToken);
- var result = ((i32In[0] & 0xff) << 24) | ((i32In[1] & 0xff) << 16) | ((i32In[2] & 0xff) << 8) |
- i32In[3] & 0xff;
+
+ var result =
+ ((i32In[0] & 0xff) << 24) |
+ ((i32In[1] & 0xff) << 16) |
+ ((i32In[2] & 0xff) << 8) |
+ i32In[3] & 0xff;
+
return result;
}
diff --git a/lib/netcore/Thrift/Protocols/TCompactProtocol.cs b/lib/netcore/Thrift/Protocols/TCompactProtocol.cs
index 6d5e0bf..cecdf03 100644
--- a/lib/netcore/Thrift/Protocols/TCompactProtocol.cs
+++ b/lib/netcore/Thrift/Protocols/TCompactProtocol.cs
@@ -1,4 +1,4 @@
-// Licensed to the Apache Software Foundation(ASF) under one
+// 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
@@ -114,7 +114,7 @@
/// 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 async Task WriteStructBeginAsync(TStruct struc, CancellationToken cancellationToken)
+ public override async Task WriteStructBeginAsync(TStruct @struct, CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -383,16 +383,16 @@
await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
}
- public override async Task WriteBinaryAsync(byte[] b, CancellationToken cancellationToken)
+ public override async Task WriteBinaryAsync(byte[] bytes, CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
{
return;
}
- var bufferTuple = CreateWriteVarInt32((uint) b.Length);
+ var bufferTuple = CreateWriteVarInt32((uint) bytes.Length);
await Trans.WriteAsync(bufferTuple.Item1, 0, bufferTuple.Item2, cancellationToken);
- await Trans.WriteAsync(b, 0, b.Length, cancellationToken);
+ await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
}
public override async Task WriteMapBeginAsync(TMap map, CancellationToken cancellationToken)
diff --git a/lib/netcore/Thrift/Protocols/TJSONProtocol.cs b/lib/netcore/Thrift/Protocols/TJSONProtocol.cs
index 17aa5f7..6d33f02 100644
--- a/lib/netcore/Thrift/Protocols/TJSONProtocol.cs
+++ b/lib/netcore/Thrift/Protocols/TJSONProtocol.cs
@@ -19,6 +19,7 @@
using System.Collections.Generic;
using System.Globalization;
using System.IO;
+using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -28,8 +29,6 @@
namespace Thrift.Protocols
{
- //TODO: implementation of TProtocol
-
/// <summary>
/// JSON protocol implementation for thrift.
/// This is a full-featured protocol supporting Write and Read.
@@ -42,53 +41,14 @@
{
private const long Version = 1;
- private const int DefStringSize = 16;
-
- private static readonly byte[] Comma = {(byte) ','};
- private static readonly byte[] Colon = {(byte) ':'};
- private static readonly byte[] Lbrace = {(byte) '{'};
- private static readonly byte[] Rbrace = {(byte) '}'};
- private static readonly byte[] Lbracket = {(byte) '['};
- private static readonly byte[] Rbracket = {(byte) ']'};
- private static readonly byte[] Quote = {(byte) '"'};
- private static readonly byte[] Backslash = {(byte) '\\'};
-
- private static readonly byte[] NameBool = {(byte) 't', (byte) 'f'};
- private static readonly byte[] NameByte = {(byte) 'i', (byte) '8'};
- private static readonly byte[] NameI16 = {(byte) 'i', (byte) '1', (byte) '6'};
- private static readonly byte[] NameI32 = {(byte) 'i', (byte) '3', (byte) '2'};
- private static readonly byte[] NameI64 = {(byte) 'i', (byte) '6', (byte) '4'};
- private static readonly byte[] NameDouble = {(byte) 'd', (byte) 'b', (byte) 'l'};
- private static readonly byte[] NameStruct = {(byte) 'r', (byte) 'e', (byte) 'c'};
- private static readonly byte[] NameString = {(byte) 's', (byte) 't', (byte) 'r'};
- private static readonly byte[] NameMap = {(byte) 'm', (byte) 'a', (byte) 'p'};
- private static readonly byte[] NameList = {(byte) 'l', (byte) 's', (byte) 't'};
- private static readonly byte[] NameSet = {(byte) 's', (byte) 'e', (byte) 't'};
-
- private readonly char[] _escapeChars = "\"\\/bfnrt".ToCharArray();
-
- private readonly byte[] _escapeCharVals =
- {
- (byte) '"', (byte) '\\', (byte) '/', (byte) '\b', (byte) '\f', (byte) '\n', (byte) '\r', (byte) '\t'
- };
-
- private readonly byte[] _escseq = {(byte) '\\', (byte) 'u', (byte) '0', (byte) '0'};
-
- private readonly byte[] _jsonCharTable =
- {
- 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
- };
-
// Temporary buffer used by several methods
private readonly byte[] _tempBuffer = new byte[4];
// Current context that we are in
- protected JsonBaseContext Context;
+ protected JSONBaseContext Context;
// Stack of nested contexts that we may be in
- protected Stack<JsonBaseContext> ContextStack = new Stack<JsonBaseContext>();
+ protected Stack<JSONBaseContext> ContextStack = new Stack<JSONBaseContext>();
// Reader that manages a 1-byte buffer
protected LookaheadReader Reader;
@@ -102,105 +62,14 @@
public TJsonProtocol(TClientTransport trans)
: base(trans)
{
- //throw new NotImplementedException("TJsonProtocol is not fully ready for usage");
-
- Context = new JsonBaseContext(this);
+ Context = new JSONBaseContext(this);
Reader = new LookaheadReader(this);
}
- private static byte[] GetTypeNameForTypeId(TType typeId)
- {
- switch (typeId)
- {
- case TType.Bool:
- return NameBool;
- case TType.Byte:
- return NameByte;
- case TType.I16:
- return NameI16;
- case TType.I32:
- return NameI32;
- case TType.I64:
- return NameI64;
- case TType.Double:
- return NameDouble;
- case TType.String:
- return NameString;
- case TType.Struct:
- return NameStruct;
- case TType.Map:
- return NameMap;
- case TType.Set:
- return NameSet;
- case TType.List:
- return NameList;
- default:
- throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "Unrecognized exType");
- }
- }
-
- private static TType GetTypeIdForTypeName(byte[] name)
- {
- var 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 exType");
- }
- return result;
- }
-
/// <summary>
/// Push a new JSON context onto the stack.
/// </summary>
- protected void PushContext(JsonBaseContext c)
+ protected void PushContext(JSONBaseContext c)
{
ContextStack.Push(Context);
Context = c;
@@ -219,94 +88,60 @@
/// Marked protected to avoid synthetic accessor in JSONListContext.Read
/// and JSONPairContext.Read
/// </summary>
- protected async Task ReadJsonSyntaxCharAsync(byte[] b, CancellationToken cancellationToken)
+ protected async Task ReadJsonSyntaxCharAsync(byte[] bytes, CancellationToken cancellationToken)
{
var ch = await Reader.ReadAsync(cancellationToken);
- if (ch != b[0])
+ if (ch != bytes[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');
- }
-
- if ((ch >= 'a') && (ch <= 'f'))
- {
- ch += 10;
- return (byte) ((char) ch - 'a');
- }
-
- 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');
- }
- val -= 10;
- return (byte) ((char) val + 'a');
- }
-
- /// <summary>
/// Write the bytes in array buf as a JSON characters, escaping as needed
/// </summary>
- private async Task WriteJsonStringAsync(byte[] b, CancellationToken cancellationToken)
+ private async Task WriteJsonStringAsync(byte[] bytes, CancellationToken cancellationToken)
{
await Context.WriteAsync(cancellationToken);
- await Trans.WriteAsync(Quote, cancellationToken);
+ await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken);
- var len = b.Length;
+ var len = bytes.Length;
for (var i = 0; i < len; i++)
{
- if ((b[i] & 0x00FF) >= 0x30)
+ if ((bytes[i] & 0x00FF) >= 0x30)
{
- if (b[i] == Backslash[0])
+ if (bytes[i] == TJSONProtocolConstants.Backslash[0])
{
- await Trans.WriteAsync(Backslash, cancellationToken);
- await Trans.WriteAsync(Backslash, cancellationToken);
+ await Trans.WriteAsync(TJSONProtocolConstants.Backslash, cancellationToken);
+ await Trans.WriteAsync(TJSONProtocolConstants.Backslash, cancellationToken);
}
else
{
- await Trans.WriteAsync(b, i, 1, cancellationToken);
+ await Trans.WriteAsync(bytes.ToArray(), i, 1, cancellationToken);
}
}
else
{
- _tempBuffer[0] = _jsonCharTable[b[i]];
+ _tempBuffer[0] = TJSONProtocolConstants.JsonCharTable[bytes[i]];
if (_tempBuffer[0] == 1)
{
- await Trans.WriteAsync(b, i, 1, cancellationToken);
+ await Trans.WriteAsync(bytes, i, 1, cancellationToken);
}
else if (_tempBuffer[0] > 1)
{
- await Trans.WriteAsync(Backslash, cancellationToken);
+ await Trans.WriteAsync(TJSONProtocolConstants.Backslash, cancellationToken);
await Trans.WriteAsync(_tempBuffer, 0, 1, cancellationToken);
}
else
{
- await Trans.WriteAsync(_escseq, cancellationToken);
- _tempBuffer[0] = HexChar((byte) (b[i] >> 4));
- _tempBuffer[1] = HexChar(b[i]);
+ await Trans.WriteAsync(TJSONProtocolConstants.EscSequences, cancellationToken);
+ _tempBuffer[0] = TJSONProtocolHelper.ToHexChar((byte) (bytes[i] >> 4));
+ _tempBuffer[1] = TJSONProtocolHelper.ToHexChar(bytes[i]);
await Trans.WriteAsync(_tempBuffer, 0, 2, cancellationToken);
}
}
}
- await Trans.WriteAsync(Quote, cancellationToken);
+ await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken);
}
/// <summary>
@@ -321,14 +156,15 @@
var escapeNum = Context.EscapeNumbers();
if (escapeNum)
{
- await Trans.WriteAsync(Quote, cancellationToken);
+ await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken);
}
- await Trans.WriteAsync(Utf8Encoding.GetBytes(str), cancellationToken);
+ var bytes = Utf8Encoding.GetBytes(str);
+ await Trans.WriteAsync(bytes, cancellationToken);
if (escapeNum)
{
- await Trans.WriteAsync(Quote, cancellationToken);
+ await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken);
}
}
@@ -361,14 +197,14 @@
if (escapeNum)
{
- await Trans.WriteAsync(Quote, cancellationToken);
+ await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken);
}
await Trans.WriteAsync(Utf8Encoding.GetBytes(str), cancellationToken);
if (escapeNum)
{
- await Trans.WriteAsync(Quote, cancellationToken);
+ await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken);
}
}
@@ -376,18 +212,18 @@
/// Write out contents of byte array b as a JSON string with base-64 encoded
/// data
/// </summary>
- private async Task WriteJsonBase64Async(byte[] b, CancellationToken cancellationToken)
+ private async Task WriteJsonBase64Async(byte[] bytes, CancellationToken cancellationToken)
{
await Context.WriteAsync(cancellationToken);
- await Trans.WriteAsync(Quote, cancellationToken);
+ await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken);
- var len = b.Length;
+ var len = bytes.Length;
var off = 0;
while (len >= 3)
{
// Encode 3 bytes at a time
- TBase64Utils.Encode(b, off, 3, _tempBuffer, 0);
+ TBase64Helper.Encode(bytes, off, 3, _tempBuffer, 0);
await Trans.WriteAsync(_tempBuffer, 0, 4, cancellationToken);
off += 3;
len -= 3;
@@ -396,37 +232,37 @@
if (len > 0)
{
// Encode remainder
- TBase64Utils.Encode(b, off, len, _tempBuffer, 0);
+ TBase64Helper.Encode(bytes, off, len, _tempBuffer, 0);
await Trans.WriteAsync(_tempBuffer, 0, len + 1, cancellationToken);
}
- await Trans.WriteAsync(Quote, cancellationToken);
+ await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken);
}
private async Task WriteJsonObjectStartAsync(CancellationToken cancellationToken)
{
await Context.WriteAsync(cancellationToken);
- await Trans.WriteAsync(Lbrace, cancellationToken);
- PushContext(new JsonPairContext(this));
+ await Trans.WriteAsync(TJSONProtocolConstants.LeftBrace, cancellationToken);
+ PushContext(new JSONPairContext(this));
}
private async Task WriteJsonObjectEndAsync(CancellationToken cancellationToken)
{
PopContext();
- await Trans.WriteAsync(Rbrace, cancellationToken);
+ await Trans.WriteAsync(TJSONProtocolConstants.RightBrace, cancellationToken);
}
private async Task WriteJsonArrayStartAsync(CancellationToken cancellationToken)
{
await Context.WriteAsync(cancellationToken);
- await Trans.WriteAsync(Lbracket, cancellationToken);
- PushContext(new JsonListContext(this));
+ await Trans.WriteAsync(TJSONProtocolConstants.LeftBracket, cancellationToken);
+ PushContext(new JSONListContext(this));
}
private async Task WriteJsonArrayEndAsync(CancellationToken cancellationToken)
{
PopContext();
- await Trans.WriteAsync(Rbracket, cancellationToken);
+ await Trans.WriteAsync(TJSONProtocolConstants.RightBracket, cancellationToken);
}
public override async Task WriteMessageBeginAsync(TMessage message, CancellationToken cancellationToken)
@@ -446,7 +282,7 @@
await WriteJsonArrayEndAsync(cancellationToken);
}
- public override async Task WriteStructBeginAsync(TStruct struc, CancellationToken cancellationToken)
+ public override async Task WriteStructBeginAsync(TStruct @struct, CancellationToken cancellationToken)
{
await WriteJsonObjectStartAsync(cancellationToken);
}
@@ -460,7 +296,7 @@
{
await WriteJsonIntegerAsync(field.ID, cancellationToken);
await WriteJsonObjectStartAsync(cancellationToken);
- await WriteJsonStringAsync(GetTypeNameForTypeId(field.Type), cancellationToken);
+ await WriteJsonStringAsync(TJSONProtocolHelper.GetTypeNameForTypeId(field.Type), cancellationToken);
}
public override async Task WriteFieldEndAsync(CancellationToken cancellationToken)
@@ -479,8 +315,8 @@
public override async Task WriteMapBeginAsync(TMap map, CancellationToken cancellationToken)
{
await WriteJsonArrayStartAsync(cancellationToken);
- await WriteJsonStringAsync(GetTypeNameForTypeId(map.KeyType), cancellationToken);
- await WriteJsonStringAsync(GetTypeNameForTypeId(map.ValueType), cancellationToken);
+ await WriteJsonStringAsync(TJSONProtocolHelper.GetTypeNameForTypeId(map.KeyType), cancellationToken);
+ await WriteJsonStringAsync(TJSONProtocolHelper.GetTypeNameForTypeId(map.ValueType), cancellationToken);
await WriteJsonIntegerAsync(map.Count, cancellationToken);
await WriteJsonObjectStartAsync(cancellationToken);
}
@@ -494,7 +330,7 @@
public override async Task WriteListBeginAsync(TList list, CancellationToken cancellationToken)
{
await WriteJsonArrayStartAsync(cancellationToken);
- await WriteJsonStringAsync(GetTypeNameForTypeId(list.ElementType), cancellationToken);
+ await WriteJsonStringAsync(TJSONProtocolHelper.GetTypeNameForTypeId(list.ElementType), cancellationToken);
await WriteJsonIntegerAsync(list.Count, cancellationToken);
}
@@ -506,7 +342,7 @@
public override async Task WriteSetBeginAsync(TSet set, CancellationToken cancellationToken)
{
await WriteJsonArrayStartAsync(cancellationToken);
- await WriteJsonStringAsync(GetTypeNameForTypeId(set.ElementType), cancellationToken);
+ await WriteJsonStringAsync(TJSONProtocolHelper.GetTypeNameForTypeId(set.ElementType), cancellationToken);
await WriteJsonIntegerAsync(set.Count, cancellationToken);
}
@@ -551,9 +387,9 @@
await WriteJsonStringAsync(b, cancellationToken);
}
- public override async Task WriteBinaryAsync(byte[] b, CancellationToken cancellationToken)
+ public override async Task WriteBinaryAsync(byte[] bytes, CancellationToken cancellationToken)
{
- await WriteJsonBase64Async(b, cancellationToken);
+ await WriteJsonBase64Async(bytes, cancellationToken);
}
/// <summary>
@@ -572,18 +408,18 @@
await Context.ReadAsync(cancellationToken);
}
- await ReadJsonSyntaxCharAsync(Quote, cancellationToken);
+ await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.Quote, cancellationToken);
while (true)
{
var ch = await Reader.ReadAsync(cancellationToken);
- if (ch == Quote[0])
+ if (ch == TJSONProtocolConstants.Quote[0])
{
break;
}
// escaped?
- if (ch != _escseq[0])
+ if (ch != TJSONProtocolConstants.EscSequences[0])
{
await buffer.WriteAsync(new[] {ch}, 0, 1, cancellationToken);
continue;
@@ -591,26 +427,25 @@
// distinguish between \uXXXX and \?
ch = await Reader.ReadAsync(cancellationToken);
- if (ch != _escseq[1]) // control chars like \n
+ if (ch != TJSONProtocolConstants.EscSequences[1]) // control chars like \n
{
- var off = Array.IndexOf(_escapeChars, (char) ch);
+ var off = Array.IndexOf(TJSONProtocolConstants.EscapeChars, (char) ch);
if (off == -1)
{
throw new TProtocolException(TProtocolException.INVALID_DATA, "Expected control char");
}
- ch = _escapeCharVals[off];
+ ch = TJSONProtocolConstants.EscapeCharValues[off];
await buffer.WriteAsync(new[] {ch}, 0, 1, cancellationToken);
continue;
}
-
// it's \uXXXX
await Trans.ReadAllAsync(_tempBuffer, 0, 4, cancellationToken);
- var wch = (short) ((HexVal(_tempBuffer[0]) << 12) +
- (HexVal(_tempBuffer[1]) << 8) +
- (HexVal(_tempBuffer[2]) << 4) +
- HexVal(_tempBuffer[3]));
+ var wch = (short) ((TJSONProtocolHelper.ToHexVal(_tempBuffer[0]) << 12) +
+ (TJSONProtocolHelper.ToHexVal(_tempBuffer[1]) << 8) +
+ (TJSONProtocolHelper.ToHexVal(_tempBuffer[2]) << 4) +
+ TJSONProtocolHelper.ToHexVal(_tempBuffer[3]));
if (char.IsHighSurrogate((char) wch))
{
@@ -649,34 +484,6 @@
}
/// <summary>
- /// Return true if the given byte could be a valid part of a JSON number.
- /// </summary>
- private static 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>
@@ -685,12 +492,21 @@
var strbld = new StringBuilder();
while (true)
{
- var ch = await Reader.PeekAsync(cancellationToken);
- if (!IsJsonNumeric(ch))
+ //TODO: workaround for primitive types with TJsonProtocol, think - how to rewrite into more easy form without exceptions
+ try
+ {
+ var ch = await Reader.PeekAsync(cancellationToken);
+ if (!TJSONProtocolHelper.IsJsonNumeric(ch))
+ {
+ break;
+ }
+ var c = (char)await Reader.ReadAsync(cancellationToken);
+ strbld.Append(c);
+ }
+ catch (TTransportException)
{
break;
}
- strbld.Append((char) await Reader.ReadAsync(cancellationToken));
}
return strbld.ToString();
}
@@ -703,13 +519,13 @@
await Context.ReadAsync(cancellationToken);
if (Context.EscapeNumbers())
{
- await ReadJsonSyntaxCharAsync(Quote, cancellationToken);
+ await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.Quote, cancellationToken);
}
var str = await ReadJsonNumericCharsAsync(cancellationToken);
if (Context.EscapeNumbers())
{
- await ReadJsonSyntaxCharAsync(Quote, cancellationToken);
+ await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.Quote, cancellationToken);
}
try
@@ -729,7 +545,7 @@
private async Task<double> ReadJsonDoubleAsync(CancellationToken cancellationToken)
{
await Context.ReadAsync(cancellationToken);
- if (await Reader.PeekAsync(cancellationToken) == Quote[0])
+ if (await Reader.PeekAsync(cancellationToken) == TJSONProtocolConstants.Quote[0])
{
var arr = await ReadJsonStringAsync(true, cancellationToken);
var dub = double.Parse(Utf8Encoding.GetString(arr, 0, arr.Length), CultureInfo.InvariantCulture);
@@ -746,7 +562,7 @@
if (Context.EscapeNumbers())
{
// This will throw - we should have had a quote if escapeNum == true
- await ReadJsonSyntaxCharAsync(Quote, cancellationToken);
+ await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.Quote, cancellationToken);
}
try
@@ -779,7 +595,7 @@
while (len > 4)
{
// Decode 4 bytes at a time
- TBase64Utils.Decode(b, off, 4, b, size); // NB: decoded in place
+ TBase64Helper.Decode(b, off, 4, b, size); // NB: decoded in place
off += 4;
len -= 4;
size += 3;
@@ -790,7 +606,7 @@
if (len > 1)
{
// Decode remainder
- TBase64Utils.Decode(b, off, len, b, size); // NB: decoded in place
+ TBase64Helper.Decode(b, off, len, b, size); // NB: decoded in place
size += len - 1;
}
@@ -803,26 +619,26 @@
private async Task ReadJsonObjectStartAsync(CancellationToken cancellationToken)
{
await Context.ReadAsync(cancellationToken);
- await ReadJsonSyntaxCharAsync(Lbrace, cancellationToken);
- PushContext(new JsonPairContext(this));
+ await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.LeftBrace, cancellationToken);
+ PushContext(new JSONPairContext(this));
}
private async Task ReadJsonObjectEndAsync(CancellationToken cancellationToken)
{
- await ReadJsonSyntaxCharAsync(Rbrace, cancellationToken);
+ await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.RightBrace, cancellationToken);
PopContext();
}
private async Task ReadJsonArrayStartAsync(CancellationToken cancellationToken)
{
await Context.ReadAsync(cancellationToken);
- await ReadJsonSyntaxCharAsync(Lbracket, cancellationToken);
- PushContext(new JsonListContext(this));
+ await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.LeftBracket, cancellationToken);
+ PushContext(new JSONListContext(this));
}
private async Task ReadJsonArrayEndAsync(CancellationToken cancellationToken)
{
- await ReadJsonSyntaxCharAsync(Rbracket, cancellationToken);
+ await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.RightBracket, cancellationToken);
PopContext();
}
@@ -862,7 +678,7 @@
{
var field = new TField();
var ch = await Reader.PeekAsync(cancellationToken);
- if (ch == Rbrace[0])
+ if (ch == TJSONProtocolConstants.RightBrace[0])
{
field.Type = TType.Stop;
}
@@ -870,7 +686,7 @@
{
field.ID = (short) await ReadJsonIntegerAsync(cancellationToken);
await ReadJsonObjectStartAsync(cancellationToken);
- field.Type = GetTypeIdForTypeName(await ReadJsonStringAsync(false, cancellationToken));
+ field.Type = TJSONProtocolHelper.GetTypeIdForTypeName(await ReadJsonStringAsync(false, cancellationToken));
}
return field;
}
@@ -884,8 +700,8 @@
{
var map = new TMap();
await ReadJsonArrayStartAsync(cancellationToken);
- map.KeyType = GetTypeIdForTypeName(await ReadJsonStringAsync(false, cancellationToken));
- map.ValueType = GetTypeIdForTypeName(await ReadJsonStringAsync(false, cancellationToken));
+ map.KeyType = TJSONProtocolHelper.GetTypeIdForTypeName(await ReadJsonStringAsync(false, cancellationToken));
+ map.ValueType = TJSONProtocolHelper.GetTypeIdForTypeName(await ReadJsonStringAsync(false, cancellationToken));
map.Count = (int) await ReadJsonIntegerAsync(cancellationToken);
await ReadJsonObjectStartAsync(cancellationToken);
return map;
@@ -901,7 +717,7 @@
{
var list = new TList();
await ReadJsonArrayStartAsync(cancellationToken);
- list.ElementType = GetTypeIdForTypeName(await ReadJsonStringAsync(false, cancellationToken));
+ list.ElementType = TJSONProtocolHelper.GetTypeIdForTypeName(await ReadJsonStringAsync(false, cancellationToken));
list.Count = (int) await ReadJsonIntegerAsync(cancellationToken);
return list;
}
@@ -915,7 +731,7 @@
{
var set = new TSet();
await ReadJsonArrayStartAsync(cancellationToken);
- set.ElementType = GetTypeIdForTypeName(await ReadJsonStringAsync(false, cancellationToken));
+ set.ElementType = TJSONProtocolHelper.GetTypeIdForTypeName(await ReadJsonStringAsync(false, cancellationToken));
set.Count = (int) await ReadJsonIntegerAsync(cancellationToken);
return set;
}
@@ -982,11 +798,11 @@
/// inserting/Reading additional JSON syntax characters
/// This base context does nothing.
/// </summary>
- protected class JsonBaseContext
+ protected class JSONBaseContext
{
protected TJsonProtocol Proto;
- public JsonBaseContext(TJsonProtocol proto)
+ public JSONBaseContext(TJsonProtocol proto)
{
Proto = proto;
}
@@ -1017,11 +833,11 @@
/// Context for JSON lists. Will insert/Read commas before each item except
/// for the first one
/// </summary>
- protected class JsonListContext : JsonBaseContext
+ protected class JSONListContext : JSONBaseContext
{
private bool _first = true;
- public JsonListContext(TJsonProtocol protocol)
+ public JSONListContext(TJsonProtocol protocol)
: base(protocol)
{
}
@@ -1034,7 +850,7 @@
}
else
{
- await Proto.Trans.WriteAsync(Comma, cancellationToken);
+ await Proto.Trans.WriteAsync(TJSONProtocolConstants.Comma, cancellationToken);
}
}
@@ -1046,7 +862,7 @@
}
else
{
- await Proto.ReadJsonSyntaxCharAsync(Comma, cancellationToken);
+ await Proto.ReadJsonSyntaxCharAsync(TJSONProtocolConstants.Comma, cancellationToken);
}
}
}
@@ -1057,13 +873,14 @@
/// 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
+ // ReSharper disable once InconsistentNaming
+ protected class JSONPairContext : JSONBaseContext
{
private bool _colon = true;
private bool _first = true;
- public JsonPairContext(TJsonProtocol proto)
+ public JSONPairContext(TJsonProtocol proto)
: base(proto)
{
}
@@ -1077,7 +894,7 @@
}
else
{
- await Proto.Trans.WriteAsync(_colon ? Colon : Comma, cancellationToken);
+ await Proto.Trans.WriteAsync(_colon ? TJSONProtocolConstants.Colon : TJSONProtocolConstants.Comma, cancellationToken);
_colon = !_colon;
}
}
@@ -1091,7 +908,7 @@
}
else
{
- await Proto.ReadJsonSyntaxCharAsync(_colon ? Colon : Comma, cancellationToken);
+ await Proto.ReadJsonSyntaxCharAsync(_colon ? TJSONProtocolConstants.Colon : TJSONProtocolConstants.Comma, cancellationToken);
_colon = !_colon;
}
}
@@ -1134,6 +951,7 @@
}
else
{
+ // find more easy way to avoid exception on reading primitive types
await Proto.Trans.ReadAllAsync(_data, 0, 1, cancellationToken);
}
return _data[0];
@@ -1152,6 +970,7 @@
if (!_hasData)
{
+ // find more easy way to avoid exception on reading primitive types
await Proto.Trans.ReadAllAsync(_data, 0, 1, cancellationToken);
}
_hasData = true;
diff --git a/lib/netcore/Thrift/Protocols/TMultiplexedProtocol.cs b/lib/netcore/Thrift/Protocols/TMultiplexedProtocol.cs
index 5b2202e..367e4e6 100644
--- a/lib/netcore/Thrift/Protocols/TMultiplexedProtocol.cs
+++ b/lib/netcore/Thrift/Protocols/TMultiplexedProtocol.cs
@@ -74,22 +74,13 @@
_serviceName = serviceName;
}
- /**
- * Prepends the service name to the function name, separated by TMultiplexedProtocol.SEPARATOR.
- * Args:
- * tMessage The original message.
- */
-
public override async Task WriteMessageBeginAsync(TMessage message, CancellationToken cancellationToken)
{
switch (message.Type)
{
case TMessageType.Call:
case TMessageType.Oneway:
- await
- base.WriteMessageBeginAsync(
- new TMessage($"{_serviceName}{Separator}{message.Name}", message.Type, message.SeqID),
- cancellationToken);
+ await base.WriteMessageBeginAsync(new TMessage($"{_serviceName}{Separator}{message.Name}", message.Type, message.SeqID), cancellationToken);
break;
default:
await base.WriteMessageBeginAsync(message, cancellationToken);
@@ -97,4 +88,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/lib/netcore/Thrift/Protocols/TProtocol.cs b/lib/netcore/Thrift/Protocols/TProtocol.cs
index 8fef861..91e009d 100644
--- a/lib/netcore/Thrift/Protocols/TProtocol.cs
+++ b/lib/netcore/Thrift/Protocols/TProtocol.cs
@@ -1,4 +1,4 @@
-// Licensed to the Apache Software Foundation(ASF) under one
+// 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
@@ -27,7 +27,7 @@
// ReSharper disable once InconsistentNaming
public abstract class TProtocol : IDisposable
{
- private const int DefaultRecursionDepth = 64;
+ public const int DefaultRecursionDepth = 64;
private bool _isDisposed;
protected int RecursionDepth;
@@ -42,7 +42,6 @@
public TClientTransport Transport => Trans;
- //TODO: check for protected
protected int RecursionLimit { get; set; }
public void Dispose()
@@ -93,12 +92,12 @@
public abstract Task WriteMessageEndAsync(CancellationToken cancellationToken);
- public virtual async Task WriteStructBeginAsync(TStruct struc)
+ public virtual async Task WriteStructBeginAsync(TStruct @struct)
{
- await WriteStructBeginAsync(struc, CancellationToken.None);
+ await WriteStructBeginAsync(@struct, CancellationToken.None);
}
- public abstract Task WriteStructBeginAsync(TStruct struc, CancellationToken cancellationToken);
+ public abstract Task WriteStructBeginAsync(TStruct @struct, CancellationToken cancellationToken);
public virtual async Task WriteStructEndAsync()
{
@@ -223,12 +222,12 @@
await WriteBinaryAsync(bytes, cancellationToken);
}
- public virtual async Task WriteBinaryAsync(byte[] b)
+ public virtual async Task WriteBinaryAsync(byte[] bytes)
{
- await WriteBinaryAsync(b, CancellationToken.None);
+ await WriteBinaryAsync(bytes, CancellationToken.None);
}
- public abstract Task WriteBinaryAsync(byte[] b, CancellationToken cancellationToken);
+ public abstract Task WriteBinaryAsync(byte[] bytes, CancellationToken cancellationToken);
public virtual async Task<TMessage> ReadMessageBeginAsync()
{
diff --git a/lib/netcore/Thrift/Protocols/TProtocolDecorator.cs b/lib/netcore/Thrift/Protocols/TProtocolDecorator.cs
index 458b117..3222754 100644
--- a/lib/netcore/Thrift/Protocols/TProtocolDecorator.cs
+++ b/lib/netcore/Thrift/Protocols/TProtocolDecorator.cs
@@ -1,4 +1,4 @@
-// Licensed to the Apache Software Foundation(ASF) under one
+// 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
@@ -36,12 +36,7 @@
protected TProtocolDecorator(TProtocol protocol)
: base(protocol.Transport)
{
- if (protocol == null)
- {
- throw new ArgumentNullException(nameof(protocol));
- }
-
- _wrappedProtocol = protocol;
+ _wrappedProtocol = protocol ?? throw new ArgumentNullException(nameof(protocol));
}
public override async Task WriteMessageBeginAsync(TMessage message, CancellationToken cancellationToken)
@@ -54,9 +49,9 @@
await _wrappedProtocol.WriteMessageEndAsync(cancellationToken);
}
- public override async Task WriteStructBeginAsync(TStruct struc, CancellationToken cancellationToken)
+ public override async Task WriteStructBeginAsync(TStruct @struct, CancellationToken cancellationToken)
{
- await _wrappedProtocol.WriteStructBeginAsync(struc, cancellationToken);
+ await _wrappedProtocol.WriteStructBeginAsync(@struct, cancellationToken);
}
public override async Task WriteStructEndAsync(CancellationToken cancellationToken)
@@ -144,9 +139,9 @@
await _wrappedProtocol.WriteStringAsync(s, cancellationToken);
}
- public override async Task WriteBinaryAsync(byte[] b, CancellationToken cancellationToken)
+ public override async Task WriteBinaryAsync(byte[] bytes, CancellationToken cancellationToken)
{
- await _wrappedProtocol.WriteBinaryAsync(b, cancellationToken);
+ await _wrappedProtocol.WriteBinaryAsync(bytes, cancellationToken);
}
public override async Task<TMessage> ReadMessageBeginAsync(CancellationToken cancellationToken)
diff --git a/lib/netcore/Thrift/Protocols/TProtocolException.cs b/lib/netcore/Thrift/Protocols/TProtocolException.cs
index 02d0d3f..8c67c3b 100644
--- a/lib/netcore/Thrift/Protocols/TProtocolException.cs
+++ b/lib/netcore/Thrift/Protocols/TProtocolException.cs
@@ -1,4 +1,4 @@
-// Licensed to the Apache Software Foundation(ASF) under one
+// 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
@@ -15,11 +15,12 @@
// specific language governing permissions and limitations
// under the License.
+// ReSharper disable InconsistentNaming
namespace Thrift.Protocols
{
public class TProtocolException : TException
{
- // do not rename public contants - they used in generated files
+ // do not rename public constants - they used in generated files
public const int UNKNOWN = 0;
public const int INVALID_DATA = 1;
public const int NEGATIVE_SIZE = 2;
diff --git a/lib/netcore/Thrift/Protocols/Utilities/TBase64Helper.cs b/lib/netcore/Thrift/Protocols/Utilities/TBase64Helper.cs
new file mode 100644
index 0000000..7eff5e1
--- /dev/null
+++ b/lib/netcore/Thrift/Protocols/Utilities/TBase64Helper.cs
@@ -0,0 +1,101 @@
+// 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.Protocols.Utilities
+{
+ // ReSharper disable once InconsistentNaming
+ internal static class TBase64Helper
+ {
+ //TODO: Constants
+ //TODO: Check for args
+ //TODO: Unitests
+
+ internal const string EncodeTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+ private static readonly int[] DecodeTable =
+ {
+ -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 Encode(byte[] src, int srcOff, int len, byte[] dst, int dstOff)
+ {
+ if (src == null)
+ {
+ throw new ArgumentNullException(nameof(src));
+ }
+
+ dst[dstOff] = (byte) EncodeTable[(src[srcOff] >> 2) & 0x3F];
+
+ if (len == 3)
+ {
+ dst[dstOff + 1] = (byte) EncodeTable[((src[srcOff] << 4) & 0x30) | ((src[srcOff + 1] >> 4) & 0x0F)];
+ dst[dstOff + 2] = (byte) EncodeTable[((src[srcOff + 1] << 2) & 0x3C) | ((src[srcOff + 2] >> 6) & 0x03)];
+ dst[dstOff + 3] = (byte) EncodeTable[src[srcOff + 2] & 0x3F];
+ }
+ else if (len == 2)
+ {
+ dst[dstOff + 1] = (byte) EncodeTable[((src[srcOff] << 4) & 0x30) | ((src[srcOff + 1] >> 4) & 0x0F)];
+ dst[dstOff + 2] = (byte) EncodeTable[(src[srcOff + 1] << 2) & 0x3C];
+ }
+ else
+ {
+ // len == 1
+ dst[dstOff + 1] = (byte) EncodeTable[(src[srcOff] << 4) & 0x30];
+ }
+ }
+
+ internal static void Decode(byte[] src, int srcOff, int len, byte[] dst, int dstOff)
+ {
+ if (src == null)
+ {
+ throw new ArgumentNullException(nameof(src));
+ }
+
+ dst[dstOff] = (byte) ((DecodeTable[src[srcOff] & 0x0FF] << 2) | (DecodeTable[src[srcOff + 1] & 0x0FF] >> 4));
+
+ if (len > 2)
+ {
+ dst[dstOff + 1] =
+ (byte)
+ (((DecodeTable[src[srcOff + 1] & 0x0FF] << 4) & 0xF0) | (DecodeTable[src[srcOff + 2] & 0x0FF] >> 2));
+ if (len > 3)
+ {
+ dst[dstOff + 2] =
+ (byte)
+ (((DecodeTable[src[srcOff + 2] & 0x0FF] << 6) & 0xC0) | DecodeTable[src[srcOff + 3] & 0x0FF]);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netcore/Thrift/Protocols/Utilities/TJsonProtocolConstants.cs b/lib/netcore/Thrift/Protocols/Utilities/TJsonProtocolConstants.cs
new file mode 100644
index 0000000..93eff78
--- /dev/null
+++ b/lib/netcore/Thrift/Protocols/Utilities/TJsonProtocolConstants.cs
@@ -0,0 +1,61 @@
+// 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.Protocols.Utilities
+{
+ // ReSharper disable once InconsistentNaming
+ public static class TJSONProtocolConstants
+ {
+ //TODO Check for performance for reusing ImmutableArray from System.Collections.Immutable (https://blogs.msdn.microsoft.com/dotnet/2013/06/24/please-welcome-immutablearrayt/)
+ // can be possible to get better performance and also better GC
+
+ public static readonly byte[] Comma = {(byte) ','};
+ public static readonly byte[] Colon = {(byte) ':'};
+ public static readonly byte[] LeftBrace = {(byte) '{'};
+ public static readonly byte[] RightBrace = {(byte) '}'};
+ public static readonly byte[] LeftBracket = {(byte) '['};
+ public static readonly byte[] RightBracket = {(byte) ']'};
+ public static readonly byte[] Quote = {(byte) '"'};
+ public static readonly byte[] Backslash = {(byte) '\\'};
+
+ public static readonly byte[] JsonCharTable =
+ {
+ 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
+ };
+
+ public static readonly char[] EscapeChars = "\"\\/bfnrt".ToCharArray();
+ public static readonly byte[] EscapeCharValues = {(byte) '"', (byte) '\\', (byte) '/', (byte) '\b', (byte) '\f', (byte) '\n', (byte) '\r', (byte) '\t'};
+ public static readonly byte[] EscSequences = {(byte) '\\', (byte) 'u', (byte) '0', (byte) '0'};
+
+ public static class TypeNames
+ {
+ public static readonly byte[] NameBool = { (byte)'t', (byte)'f' };
+ public static readonly byte[] NameByte = { (byte)'i', (byte)'8' };
+ public static readonly byte[] NameI16 = { (byte)'i', (byte)'1', (byte)'6' };
+ public static readonly byte[] NameI32 = { (byte)'i', (byte)'3', (byte)'2' };
+ public static readonly byte[] NameI64 = { (byte)'i', (byte)'6', (byte)'4' };
+ public static readonly byte[] NameDouble = { (byte)'d', (byte)'b', (byte)'l' };
+ public static readonly byte[] NameStruct = { (byte)'r', (byte)'e', (byte)'c' };
+ public static readonly byte[] NameString = { (byte)'s', (byte)'t', (byte)'r' };
+ public static readonly byte[] NameMap = { (byte)'m', (byte)'a', (byte)'p' };
+ public static readonly byte[] NameList = { (byte)'l', (byte)'s', (byte)'t' };
+ public static readonly byte[] NameSet = { (byte)'s', (byte)'e', (byte)'t' };
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netcore/Thrift/Protocols/Utilities/TJsonProtocolHelper.cs b/lib/netcore/Thrift/Protocols/Utilities/TJsonProtocolHelper.cs
new file mode 100644
index 0000000..adc26a9
--- /dev/null
+++ b/lib/netcore/Thrift/Protocols/Utilities/TJsonProtocolHelper.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.
+
+using Thrift.Protocols.Entities;
+
+namespace Thrift.Protocols.Utilities
+{
+ // ReSharper disable once InconsistentNaming
+ public static class TJSONProtocolHelper
+ {
+ public static byte[] GetTypeNameForTypeId(TType typeId)
+ {
+ switch (typeId)
+ {
+ case TType.Bool:
+ return TJSONProtocolConstants.TypeNames.NameBool;
+ case TType.Byte:
+ return TJSONProtocolConstants.TypeNames.NameByte;
+ case TType.I16:
+ return TJSONProtocolConstants.TypeNames.NameI16;
+ case TType.I32:
+ return TJSONProtocolConstants.TypeNames.NameI32;
+ case TType.I64:
+ return TJSONProtocolConstants.TypeNames.NameI64;
+ case TType.Double:
+ return TJSONProtocolConstants.TypeNames.NameDouble;
+ case TType.String:
+ return TJSONProtocolConstants.TypeNames.NameString;
+ case TType.Struct:
+ return TJSONProtocolConstants.TypeNames.NameStruct;
+ case TType.Map:
+ return TJSONProtocolConstants.TypeNames.NameMap;
+ case TType.Set:
+ return TJSONProtocolConstants.TypeNames.NameSet;
+ case TType.List:
+ return TJSONProtocolConstants.TypeNames.NameList;
+ default:
+ throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "Unrecognized exType");
+ }
+ }
+
+ public static TType GetTypeIdForTypeName(byte[] name)
+ {
+ var 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 exType");
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Return true if the given byte could be a valid part of a JSON number.
+ /// </summary>
+ public static 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;
+ default:
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Convert a byte containing a hex char ('0'-'9' or 'a'-'f') into its
+ /// corresponding hex value
+ /// </summary>
+ public static byte ToHexVal(byte ch)
+ {
+ if (ch >= '0' && ch <= '9')
+ {
+ return (byte)((char)ch - '0');
+ }
+
+ if (ch >= 'a' && ch <= 'f')
+ {
+ ch += 10;
+ return (byte)((char)ch - 'a');
+ }
+
+ throw new TProtocolException(TProtocolException.INVALID_DATA, "Expected hex character");
+ }
+
+ /// <summary>
+ /// Convert a byte containing a hex value to its corresponding hex character
+ /// </summary>
+ public static byte ToHexChar(byte val)
+ {
+ val &= 0x0F;
+ if (val < 10)
+ {
+ return (byte)((char)val + '0');
+ }
+ val -= 10;
+ return (byte)((char)val + 'a');
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netcore/Thrift/Protocols/Utilities/TProtocolUtil.cs b/lib/netcore/Thrift/Protocols/Utilities/TProtocolUtil.cs
index 038edb9..50b0385 100644
--- a/lib/netcore/Thrift/Protocols/Utilities/TProtocolUtil.cs
+++ b/lib/netcore/Thrift/Protocols/Utilities/TProtocolUtil.cs
@@ -19,83 +19,83 @@
using System.Threading.Tasks;
using Thrift.Protocols.Entities;
-namespace Thrift.Protocols
+namespace Thrift.Protocols.Utilities
{
// ReSharper disable once InconsistentNaming
public static class TProtocolUtil
{
- public static async Task SkipAsync(TProtocol prot, TType type, CancellationToken cancellationToken)
+ public static async Task SkipAsync(TProtocol protocol, TType type, CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
{
await Task.FromCanceled(cancellationToken);
}
- prot.IncrementRecursionDepth();
+ protocol.IncrementRecursionDepth();
try
{
switch (type)
{
case TType.Bool:
- await prot.ReadBoolAsync(cancellationToken);
+ await protocol.ReadBoolAsync(cancellationToken);
break;
case TType.Byte:
- await prot.ReadByteAsync(cancellationToken);
+ await protocol.ReadByteAsync(cancellationToken);
break;
case TType.I16:
- await prot.ReadI16Async(cancellationToken);
+ await protocol.ReadI16Async(cancellationToken);
break;
case TType.I32:
- await prot.ReadI32Async(cancellationToken);
+ await protocol.ReadI32Async(cancellationToken);
break;
case TType.I64:
- await prot.ReadI64Async(cancellationToken);
+ await protocol.ReadI64Async(cancellationToken);
break;
case TType.Double:
- await prot.ReadDoubleAsync(cancellationToken);
+ await protocol.ReadDoubleAsync(cancellationToken);
break;
case TType.String:
// Don't try to decode the string, just skip it.
- await prot.ReadBinaryAsync(cancellationToken);
+ await protocol.ReadBinaryAsync(cancellationToken);
break;
case TType.Struct:
- await prot.ReadStructBeginAsync(cancellationToken);
+ await protocol.ReadStructBeginAsync(cancellationToken);
while (true)
{
- var field = await prot.ReadFieldBeginAsync(cancellationToken);
+ var field = await protocol.ReadFieldBeginAsync(cancellationToken);
if (field.Type == TType.Stop)
{
break;
}
- await SkipAsync(prot, field.Type, cancellationToken);
- await prot.ReadFieldEndAsync(cancellationToken);
+ await SkipAsync(protocol, field.Type, cancellationToken);
+ await protocol.ReadFieldEndAsync(cancellationToken);
}
- await prot.ReadStructEndAsync(cancellationToken);
+ await protocol.ReadStructEndAsync(cancellationToken);
break;
case TType.Map:
- var map = await prot.ReadMapBeginAsync(cancellationToken);
+ var map = await protocol.ReadMapBeginAsync(cancellationToken);
for (var i = 0; i < map.Count; i++)
{
- await SkipAsync(prot, map.KeyType, cancellationToken);
- await SkipAsync(prot, map.ValueType, cancellationToken);
+ await SkipAsync(protocol, map.KeyType, cancellationToken);
+ await SkipAsync(protocol, map.ValueType, cancellationToken);
}
- await prot.ReadMapEndAsync(cancellationToken);
+ await protocol.ReadMapEndAsync(cancellationToken);
break;
case TType.Set:
- var set = await prot.ReadSetBeginAsync(cancellationToken);
+ var set = await protocol.ReadSetBeginAsync(cancellationToken);
for (var i = 0; i < set.Count; i++)
{
- await SkipAsync(prot, set.ElementType, cancellationToken);
+ await SkipAsync(protocol, set.ElementType, cancellationToken);
}
- await prot.ReadSetEndAsync(cancellationToken);
+ await protocol.ReadSetEndAsync(cancellationToken);
break;
case TType.List:
- var list = await prot.ReadListBeginAsync(cancellationToken);
+ var list = await protocol.ReadListBeginAsync(cancellationToken);
for (var i = 0; i < list.Count; i++)
{
- await SkipAsync(prot, list.ElementType, cancellationToken);
+ await SkipAsync(protocol, list.ElementType, cancellationToken);
}
- await prot.ReadListEndAsync(cancellationToken);
+ await protocol.ReadListEndAsync(cancellationToken);
break;
default:
throw new TProtocolException(TProtocolException.INVALID_DATA, "Unknown data type " + type.ToString("d"));
@@ -103,8 +103,8 @@
}
finally
{
- prot.DecrementRecursionDepth();
+ protocol.DecrementRecursionDepth();
}
}
}
-}
\ No newline at end of file
+}
diff --git a/lib/netcore/Thrift/Server/AsyncBaseServer.cs b/lib/netcore/Thrift/Server/AsyncBaseServer.cs
index 5ff7a32..0032ca3 100644
--- a/lib/netcore/Thrift/Server/AsyncBaseServer.cs
+++ b/lib/netcore/Thrift/Server/AsyncBaseServer.cs
@@ -57,8 +57,7 @@
try
{
// cancelation token
- _serverTask = Task.Factory.StartNew(() => StartListening(cancellationToken),
- TaskCreationOptions.LongRunning);
+ _serverTask = Task.Factory.StartNew(() => StartListening(cancellationToken), TaskCreationOptions.LongRunning);
await _serverTask;
}
catch (Exception ex)
@@ -87,7 +86,7 @@
try
{
var client = await ServerTransport.AcceptAsync(cancellationToken);
- await Task.Factory.StartNew(() => Execute(client, cancellationToken));
+ await Task.Factory.StartNew(() => Execute(client, cancellationToken), cancellationToken);
}
catch (TTransportException ttx)
{
@@ -136,8 +135,7 @@
if (ServerEventHandler != null)
{
- connectionContext =
- await ServerEventHandler.CreateContextAsync(inputProtocol, outputProtocol, cancellationToken);
+ connectionContext = await ServerEventHandler.CreateContextAsync(inputProtocol, outputProtocol, cancellationToken);
}
while (!cancellationToken.IsCancellationRequested)
@@ -149,8 +147,7 @@
if (ServerEventHandler != null)
{
- await
- ServerEventHandler.ProcessContextAsync(connectionContext, inputTransport, cancellationToken);
+ await ServerEventHandler.ProcessContextAsync(connectionContext, inputTransport, cancellationToken);
}
if (!await processor.ProcessAsync(inputProtocol, outputProtocol, cancellationToken))
@@ -170,9 +167,7 @@
if (ServerEventHandler != null)
{
- await
- ServerEventHandler.DeleteContextAsync(connectionContext, inputProtocol, outputProtocol,
- cancellationToken);
+ await ServerEventHandler.DeleteContextAsync(connectionContext, inputProtocol, outputProtocol, cancellationToken);
}
inputTransport?.Close();
@@ -181,4 +176,4 @@
Logger.LogTrace("Completed client request processing");
}
}
-}
\ No newline at end of file
+}
diff --git a/lib/netcore/Thrift/Server/TBaseServer.cs b/lib/netcore/Thrift/Server/TBaseServer.cs
index 97cc7ff..741dd5c 100644
--- a/lib/netcore/Thrift/Server/TBaseServer.cs
+++ b/lib/netcore/Thrift/Server/TBaseServer.cs
@@ -42,20 +42,13 @@
ITProtocolFactory inputProtocolFactory, ITProtocolFactory outputProtocolFactory,
ILogger logger)
{
- if (itProcessorFactory == null) throw new ArgumentNullException(nameof(itProcessorFactory));
- if (inputTransportFactory == null) throw new ArgumentNullException(nameof(inputTransportFactory));
- if (outputTransportFactory == null) throw new ArgumentNullException(nameof(outputTransportFactory));
- if (inputProtocolFactory == null) throw new ArgumentNullException(nameof(inputProtocolFactory));
- if (outputProtocolFactory == null) throw new ArgumentNullException(nameof(outputProtocolFactory));
- if (logger == null) throw new ArgumentNullException(nameof(logger));
-
- ItProcessorFactory = itProcessorFactory;
+ ItProcessorFactory = itProcessorFactory ?? throw new ArgumentNullException(nameof(itProcessorFactory));
ServerTransport = serverTransport;
- InputTransportFactory = inputTransportFactory;
- OutputTransportFactory = outputTransportFactory;
- InputProtocolFactory = inputProtocolFactory;
- OutputProtocolFactory = outputProtocolFactory;
- Logger = logger;
+ InputTransportFactory = inputTransportFactory ?? throw new ArgumentNullException(nameof(inputTransportFactory));
+ OutputTransportFactory = outputTransportFactory ?? throw new ArgumentNullException(nameof(outputTransportFactory));
+ InputProtocolFactory = inputProtocolFactory ?? throw new ArgumentNullException(nameof(inputProtocolFactory));
+ OutputProtocolFactory = outputProtocolFactory ?? throw new ArgumentNullException(nameof(outputProtocolFactory));
+ Logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public void SetEventHandler(TServerEventHandler seh)
diff --git a/lib/netcore/Thrift/TApplicationException.cs b/lib/netcore/Thrift/TApplicationException.cs
index f1ea252..9ec145a 100644
--- a/lib/netcore/Thrift/TApplicationException.cs
+++ b/lib/netcore/Thrift/TApplicationException.cs
@@ -1,4 +1,4 @@
-// Licensed to the Apache Software Foundation(ASF) under one
+// 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
@@ -19,6 +19,7 @@
using System.Threading.Tasks;
using Thrift.Protocols;
using Thrift.Protocols.Entities;
+using Thrift.Protocols.Utilities;
namespace Thrift
{
@@ -60,15 +61,15 @@
Type = type;
}
- public static async Task<TApplicationException> ReadAsync(TProtocol iprot, CancellationToken cancellationToken)
+ public static async Task<TApplicationException> ReadAsync(TProtocol inputProtocol, CancellationToken cancellationToken)
{
string message = null;
var type = ExceptionType.Unknown;
- await iprot.ReadStructBeginAsync(cancellationToken);
+ await inputProtocol.ReadStructBeginAsync(cancellationToken);
while (true)
{
- var field = await iprot.ReadFieldBeginAsync(cancellationToken);
+ var field = await inputProtocol.ReadFieldBeginAsync(cancellationToken);
if (field.Type == TType.Stop)
{
break;
@@ -79,37 +80,37 @@
case MessageTypeFieldId:
if (field.Type == TType.String)
{
- message = await iprot.ReadStringAsync(cancellationToken);
+ message = await inputProtocol.ReadStringAsync(cancellationToken);
}
else
{
- await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
+ await TProtocolUtil.SkipAsync(inputProtocol, field.Type, cancellationToken);
}
break;
case ExTypeFieldId:
if (field.Type == TType.I32)
{
- type = (ExceptionType) await iprot.ReadI32Async(cancellationToken);
+ type = (ExceptionType) await inputProtocol.ReadI32Async(cancellationToken);
}
else
{
- await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
+ await TProtocolUtil.SkipAsync(inputProtocol, field.Type, cancellationToken);
}
break;
default:
- await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
+ await TProtocolUtil.SkipAsync(inputProtocol, field.Type, cancellationToken);
break;
}
- await iprot.ReadFieldEndAsync(cancellationToken);
+ await inputProtocol.ReadFieldEndAsync(cancellationToken);
}
- await iprot.ReadStructEndAsync(cancellationToken);
+ await inputProtocol.ReadStructEndAsync(cancellationToken);
return new TApplicationException(type, message);
}
- public async Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken)
+ public async Task WriteAsync(TProtocol outputProtocol, CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
{
@@ -123,27 +124,27 @@
var struc = new TStruct(structApplicationExceptionName);
var field = new TField();
- await oprot.WriteStructBeginAsync(struc, cancellationToken);
+ await outputProtocol.WriteStructBeginAsync(struc, cancellationToken);
if (!string.IsNullOrEmpty(Message))
{
field.Name = messageTypeFieldName;
field.Type = TType.String;
field.ID = MessageTypeFieldId;
- await oprot.WriteFieldBeginAsync(field, cancellationToken);
- await oprot.WriteStringAsync(Message, cancellationToken);
- await oprot.WriteFieldEndAsync(cancellationToken);
+ await outputProtocol.WriteFieldBeginAsync(field, cancellationToken);
+ await outputProtocol.WriteStringAsync(Message, cancellationToken);
+ await outputProtocol.WriteFieldEndAsync(cancellationToken);
}
field.Name = exTypeFieldName;
field.Type = TType.I32;
field.ID = ExTypeFieldId;
- await oprot.WriteFieldBeginAsync(field, cancellationToken);
- await oprot.WriteI32Async((int) Type, cancellationToken);
- await oprot.WriteFieldEndAsync(cancellationToken);
- await oprot.WriteFieldStopAsync(cancellationToken);
- await oprot.WriteStructEndAsync(cancellationToken);
+ await outputProtocol.WriteFieldBeginAsync(field, cancellationToken);
+ await outputProtocol.WriteI32Async((int) Type, cancellationToken);
+ await outputProtocol.WriteFieldEndAsync(cancellationToken);
+ await outputProtocol.WriteFieldStopAsync(cancellationToken);
+ await outputProtocol.WriteStructEndAsync(cancellationToken);
}
}
}
\ No newline at end of file
diff --git a/lib/netcore/Thrift/TBaseClient.cs b/lib/netcore/Thrift/TBaseClient.cs
index ca403e5..e019251 100644
--- a/lib/netcore/Thrift/TBaseClient.cs
+++ b/lib/netcore/Thrift/TBaseClient.cs
@@ -1,4 +1,4 @@
-// Licensed to the Apache Software Foundation(ASF) under one
+// 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
@@ -16,14 +16,13 @@
// under the License.
using System;
-using System.Collections.Generic;
-using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Thrift.Protocols;
namespace Thrift
{
+ // ReSharper disable once InconsistentNaming
/// <summary>
/// TBaseClient.
/// Base client for generated clients.
@@ -39,18 +38,8 @@
protected TBaseClient(TProtocol inputProtocol, TProtocol outputProtocol)
{
- if (inputProtocol == null)
- {
- throw new ArgumentNullException(nameof(inputProtocol));
- }
-
- if (outputProtocol == null)
- {
- throw new ArgumentNullException(nameof(outputProtocol));
- }
-
- _inputProtocol = inputProtocol;
- _outputProtocol = outputProtocol;
+ _inputProtocol = inputProtocol ?? throw new ArgumentNullException(nameof(inputProtocol));
+ _outputProtocol = outputProtocol ?? throw new ArgumentNullException(nameof(outputProtocol));
}
public TProtocol InputProtocol => _inputProtocol;
diff --git a/lib/netcore/Thrift/Transports/Client/TBufferedClientTransport.cs b/lib/netcore/Thrift/Transports/Client/TBufferedClientTransport.cs
index 86eb735..761f1ac 100644
--- a/lib/netcore/Thrift/Transports/Client/TBufferedClientTransport.cs
+++ b/lib/netcore/Thrift/Transports/Client/TBufferedClientTransport.cs
@@ -1,4 +1,4 @@
-// Licensed to the Apache Software Foundation(ASF) under one
+// 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
@@ -34,17 +34,12 @@
//TODO: should support only specified input transport?
public TBufferedClientTransport(TClientTransport transport, int bufSize = 1024)
{
- if (transport == null)
- {
- throw new ArgumentNullException(nameof(transport));
- }
-
if (bufSize <= 0)
{
throw new ArgumentOutOfRangeException(nameof(bufSize), "Buffer size must be a positive number.");
}
- _transport = transport;
+ _transport = transport ?? throw new ArgumentNullException(nameof(transport));
_bufSize = bufSize;
}
@@ -200,8 +195,9 @@
{
if (disposing)
{
- _inputBuffer.Dispose();
- _outputBuffer.Dispose();
+ _inputBuffer?.Dispose();
+ _outputBuffer?.Dispose();
+ _transport?.Dispose();
}
}
_isDisposed = true;
diff --git a/lib/netcore/Thrift/Transports/Client/TFramedClientTransport.cs b/lib/netcore/Thrift/Transports/Client/TFramedClientTransport.cs
index f54a42a..d11bb95 100644
--- a/lib/netcore/Thrift/Transports/Client/TFramedClientTransport.cs
+++ b/lib/netcore/Thrift/Transports/Client/TFramedClientTransport.cs
@@ -1,4 +1,4 @@
-// Licensed to the Apache Software Foundation(ASF) under one
+// 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
@@ -37,12 +37,7 @@
public TFramedClientTransport(TClientTransport transport)
{
- if (transport == null)
- {
- throw new ArgumentNullException(nameof(transport));
- }
-
- _transport = transport;
+ _transport = transport ?? throw new ArgumentNullException(nameof(transport));
InitWriteBuffer();
}
@@ -195,8 +190,9 @@
{
if (disposing)
{
- _readBuffer.Dispose();
- _writeBuffer.Dispose();
+ _readBuffer?.Dispose();
+ _writeBuffer?.Dispose();
+ _transport?.Dispose();
}
}
_isDisposed = true;
diff --git a/lib/netcore/Thrift/Transports/Client/THttpClientTransport.cs b/lib/netcore/Thrift/Transports/Client/THttpClientTransport.cs
index bc36bb3..16754b2 100644
--- a/lib/netcore/Thrift/Transports/Client/THttpClientTransport.cs
+++ b/lib/netcore/Thrift/Transports/Client/THttpClientTransport.cs
@@ -16,11 +16,9 @@
// under the License.
using System;
-using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography.X509Certificates;
@@ -198,7 +196,7 @@
{
throw new TTransportException(TTransportException.ExceptionType.Unknown, iox.ToString());
}
- catch (WebException wx)
+ catch (HttpRequestException wx)
{
throw new TTransportException(TTransportException.ExceptionType.Unknown,
"Couldn't connect to server: " + wx);
diff --git a/lib/netcore/Thrift/Transports/Client/TSocketClientTransport.cs b/lib/netcore/Thrift/Transports/Client/TSocketClientTransport.cs
index a44efe6..e769d14 100644
--- a/lib/netcore/Thrift/Transports/Client/TSocketClientTransport.cs
+++ b/lib/netcore/Thrift/Transports/Client/TSocketClientTransport.cs
@@ -30,12 +30,7 @@
public TSocketClientTransport(TcpClient client)
{
- if (client == null)
- {
- throw new ArgumentNullException(nameof(client));
- }
-
- TcpClient = client;
+ TcpClient = client ?? throw new ArgumentNullException(nameof(client));
if (IsOpen)
{
diff --git a/lib/netcore/Thrift/Transports/Client/TTlsSocketClientTransport.cs b/lib/netcore/Thrift/Transports/Client/TTlsSocketClientTransport.cs
index a21977b..c8be4ed 100644
--- a/lib/netcore/Thrift/Transports/Client/TTlsSocketClientTransport.cs
+++ b/lib/netcore/Thrift/Transports/Client/TTlsSocketClientTransport.cs
@@ -1,4 +1,4 @@
-// Licensed to the Apache Software Foundation(ASF) under one
+// 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
@@ -57,7 +57,7 @@
if (isServer && certificate == null)
{
throw new ArgumentException("TTlsSocketClientTransport needs certificate to be used for server",
- "certificate");
+ nameof(certificate));
}
if (IsOpen)
@@ -204,7 +204,8 @@
? new X509CertificateCollection {_certificate}
: new X509CertificateCollection();
- await _secureStream.AuthenticateAsClientAsync(_host.ToString(), certs, _sslProtocols, true);
+ var targetHost = _host.ToString();
+ await _secureStream.AuthenticateAsClientAsync(targetHost, certs, _sslProtocols, true);
}
}
catch (Exception)
diff --git a/lib/netcore/Thrift/Transports/Server/THttpServerTransport.cs b/lib/netcore/Thrift/Transports/Server/THttpServerTransport.cs
index 6073741..032063a 100644
--- a/lib/netcore/Thrift/Transports/Server/THttpServerTransport.cs
+++ b/lib/netcore/Thrift/Transports/Server/THttpServerTransport.cs
@@ -53,29 +53,14 @@
public THttpServerTransport(ITAsyncProcessor processor, ITProtocolFactory inputProtocolFactory,
ITProtocolFactory outputProtocolFactory, RequestDelegate next, ILoggerFactory loggerFactory)
{
- if (processor == null)
- {
- throw new ArgumentNullException(nameof(processor));
- }
-
- if (inputProtocolFactory == null)
- {
- throw new ArgumentNullException(nameof(inputProtocolFactory));
- }
-
- if (outputProtocolFactory == null)
- {
- throw new ArgumentNullException(nameof(outputProtocolFactory));
- }
-
if (loggerFactory == null)
{
throw new ArgumentNullException(nameof(loggerFactory));
}
- Processor = processor;
- InputProtocolFactory = inputProtocolFactory;
- OutputProtocolFactory = outputProtocolFactory;
+ Processor = processor ?? throw new ArgumentNullException(nameof(processor));
+ InputProtocolFactory = inputProtocolFactory ?? throw new ArgumentNullException(nameof(inputProtocolFactory));
+ OutputProtocolFactory = outputProtocolFactory ?? throw new ArgumentNullException(nameof(outputProtocolFactory));
_next = next;
_logger = loggerFactory.CreateLogger<THttpServerTransport>();
diff --git a/lib/netcore/Thrift/Transports/Server/TNamedPipeServerTransport.cs b/lib/netcore/Thrift/Transports/Server/TNamedPipeServerTransport.cs
index 01195d4..186786e 100644
--- a/lib/netcore/Thrift/Transports/Server/TNamedPipeServerTransport.cs
+++ b/lib/netcore/Thrift/Transports/Server/TNamedPipeServerTransport.cs
@@ -1,4 +1,4 @@
-// Licensed to the Apache Software Foundation(ASF) under one
+// 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
diff --git a/lib/netcore/Thrift/Transports/Server/TServerSocketTransport.cs b/lib/netcore/Thrift/Transports/Server/TServerSocketTransport.cs
index af154ef..3a9d8a1 100644
--- a/lib/netcore/Thrift/Transports/Server/TServerSocketTransport.cs
+++ b/lib/netcore/Thrift/Transports/Server/TServerSocketTransport.cs
@@ -30,6 +30,7 @@
private readonly int _clientTimeout;
private readonly int _port;
private readonly bool _useBufferedSockets;
+ private readonly bool _useFramedTransport;
private TcpListener _server;
public TServerSocketTransport(TcpListener listener)
@@ -53,11 +54,17 @@
{
}
- public TServerSocketTransport(int port, int clientTimeout, bool useBufferedSockets)
+ public TServerSocketTransport(int port, int clientTimeout, bool useBufferedSockets):
+ this(port, clientTimeout, useBufferedSockets, false)
+ {
+ }
+
+ public TServerSocketTransport(int port, int clientTimeout, bool useBufferedSockets, bool useFramedTransport)
{
_port = port;
_clientTimeout = clientTimeout;
_useBufferedSockets = useBufferedSockets;
+ _useFramedTransport = useFramedTransport;
try
{
// Make server socket
@@ -106,7 +113,7 @@
try
{
- TSocketClientTransport tSocketTransport = null;
+ TClientTransport tSocketTransport = null;
var tcpClient = await _server.AcceptTcpClientAsync();
try
@@ -118,7 +125,12 @@
if (_useBufferedSockets)
{
- return new TBufferedClientTransport(tSocketTransport);
+ tSocketTransport = new TBufferedClientTransport(tSocketTransport);
+ }
+
+ if (_useFramedTransport)
+ {
+ tSocketTransport = new TFramedClientTransport(tSocketTransport);
}
return tSocketTransport;
diff --git a/lib/netcore/Thrift/Transports/Server/TTlsServerSocketTransport.cs b/lib/netcore/Thrift/Transports/Server/TTlsServerSocketTransport.cs
index 49abdac..759feed 100644
--- a/lib/netcore/Thrift/Transports/Server/TTlsServerSocketTransport.cs
+++ b/lib/netcore/Thrift/Transports/Server/TTlsServerSocketTransport.cs
@@ -37,6 +37,7 @@
private readonly X509Certificate2 _serverCertificate;
private readonly SslProtocols _sslProtocols;
private readonly bool _useBufferedSockets;
+ private readonly bool _useFramedTransport;
private TcpListener _server;
public TTlsServerSocketTransport(int port, X509Certificate2 certificate)
@@ -50,6 +51,19 @@
X509Certificate2 certificate,
RemoteCertificateValidationCallback clientCertValidator = null,
LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
+ SslProtocols sslProtocols = SslProtocols.Tls12)
+ : this(port, useBufferedSockets, false, certificate,
+ clientCertValidator, localCertificateSelectionCallback, sslProtocols)
+ {
+ }
+
+ public TTlsServerSocketTransport(
+ int port,
+ bool useBufferedSockets,
+ bool useFramedTransport,
+ X509Certificate2 certificate,
+ RemoteCertificateValidationCallback clientCertValidator = null,
+ LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
SslProtocols sslProtocols = SslProtocols.Tls12)
{
if (!certificate.HasPrivateKey)
@@ -61,6 +75,7 @@
_port = port;
_serverCertificate = certificate;
_useBufferedSockets = useBufferedSockets;
+ _useFramedTransport = useFramedTransport;
_clientCertValidator = clientCertValidator;
_localCertificateSelectionCallback = localCertificateSelectionCallback;
_sslProtocols = sslProtocols;
@@ -122,13 +137,19 @@
await tTlsSocket.SetupTlsAsync();
+ TClientTransport trans = tTlsSocket;
+
if (_useBufferedSockets)
{
- var trans = new TBufferedClientTransport(tTlsSocket);
- return trans;
+ trans = new TBufferedClientTransport(trans);
}
- return tTlsSocket;
+ if (_useFramedTransport)
+ {
+ trans = new TFramedClientTransport(trans);
+ }
+
+ return trans;
}
catch (Exception ex)
{
diff --git a/lib/netcore/Thrift/Transports/TClientTransport.cs b/lib/netcore/Thrift/Transports/TClientTransport.cs
index cee0a00..0dd96cb 100644
--- a/lib/netcore/Thrift/Transports/TClientTransport.cs
+++ b/lib/netcore/Thrift/Transports/TClientTransport.cs
@@ -1,4 +1,4 @@
-// Licensed to the Apache Software Foundation(ASF) under one
+// 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
@@ -26,6 +26,7 @@
// ReSharper disable once InconsistentNaming
public abstract class TClientTransport : IDisposable
{
+ //TODO: think how to avoid peek byte
private readonly byte[] _peekBuffer = new byte[1];
private bool _hasPeekByte;
public abstract bool IsOpen { get; }
diff --git a/lib/netcore/Thrift/Transports/TServerTransport.cs b/lib/netcore/Thrift/Transports/TServerTransport.cs
index d49feb6..0d45a55 100644
--- a/lib/netcore/Thrift/Transports/TServerTransport.cs
+++ b/lib/netcore/Thrift/Transports/TServerTransport.cs
@@ -45,7 +45,7 @@
if (transport == null)
{
- throw new TTransportException("AcceptAsync() should not return null");
+ throw new TTransportException($"{nameof(AcceptImplementationAsync)} should not return null");
}
return transport;
diff --git a/lib/netcore/build.cmd b/lib/netcore/build.cmd
new file mode 100644
index 0000000..863c4b4
--- /dev/null
+++ b/lib/netcore/build.cmd
@@ -0,0 +1,27 @@
+@echo off
+rem /*
+rem * Licensed to the Apache Software Foundation (ASF) under one
+rem * or more contributor license agreements. See the NOTICE file
+rem * distributed with this work for additional information
+rem * regarding copyright ownership. The ASF licenses this file
+rem * to you under the Apache License, Version 2.0 (the
+rem * "License"); you may not use this file except in compliance
+rem * with the License. You may obtain a copy of the License at
+rem *
+rem * http://www.apache.org/licenses/LICENSE-2.0
+rem *
+rem * Unless required by applicable law or agreed to in writing,
+rem * software distributed under the License is distributed on an
+rem * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+rem * KIND, either express or implied. See the License for the
+rem * specific language governing permissions and limitations
+rem * under the License.
+rem */
+
+setlocal
+
+thrift -version
+dotnet --info
+dotnet build
+
+:eof
diff --git a/lib/netcore/build.sh b/lib/netcore/build.sh
new file mode 100644
index 0000000..ae18bce
--- /dev/null
+++ b/lib/netcore/build.sh
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+
+#
+# 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.
+#
+
+#exit if any command fails
+#set -e
+
+thrift --version
+dotnet --info
+dotnet build
+
+#revision=${TRAVIS_JOB_ID:=1}
+#revision=$(printf "%04d" $revision)
+
+#dotnet pack ./src/PROJECT_NAME -c Release -o ./artifacts --version-suffix=$revision
diff --git a/lib/netcore/runtests.cmd b/lib/netcore/runtests.cmd
new file mode 100644
index 0000000..5114bc5
--- /dev/null
+++ b/lib/netcore/runtests.cmd
@@ -0,0 +1,28 @@
+@echo off
+rem /*
+rem * Licensed to the Apache Software Foundation (ASF) under one
+rem * or more contributor license agreements. See the NOTICE file
+rem * distributed with this work for additional information
+rem * regarding copyright ownership. The ASF licenses this file
+rem * to you under the Apache License, Version 2.0 (the
+rem * "License"); you may not use this file except in compliance
+rem * with the License. You may obtain a copy of the License at
+rem *
+rem * http://www.apache.org/licenses/LICENSE-2.0
+rem *
+rem * Unless required by applicable law or agreed to in writing,
+rem * software distributed under the License is distributed on an
+rem * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+rem * KIND, either express or implied. See the License for the
+rem * specific language governing permissions and limitations
+rem * under the License.
+rem */
+setlocal
+
+thrift -version
+dotnet --info
+
+dotnet test Tests\Thrift.IntegrationTests\Thrift.IntegrationTests.csproj
+dotnet test Tests\Thrift.Tests\Thrift.Tests.csproj
+
+:eof
diff --git a/lib/netcore/runtests.sh b/lib/netcore/runtests.sh
new file mode 100644
index 0000000..a26cc36
--- /dev/null
+++ b/lib/netcore/runtests.sh
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+
+#
+# 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.
+#
+
+thrift -version
+dotnet --info
+
+dotnet test Tests\Thrift.IntegrationTests\Thrift.IntegrationTests.csproj
+dotnet test Tests\Thrift.Tests\Thrift.Tests.csproj
\ No newline at end of file