mirror of
https://github.com/FabInfra/capnproto-dotnetcore_Runtime.git
synced 2025-03-12 23:01:44 +01:00
refactored for .NET standard 2
This commit is contained in:
parent
caa5604e9f
commit
d0863fbdc4
@ -1,11 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
|
||||
<LangVersion>7.1</LangVersion>
|
||||
|
||||
<OutputType>Library</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
|
@ -111,7 +111,9 @@ namespace Capnp.Net.Runtime.Tests
|
||||
Assert.AreEqual(expectedCount - i, length);
|
||||
for (int j = 0; j < length; j++)
|
||||
{
|
||||
Assert.AreEqual((ulong)(length - j), frame.Segments[i].Span[j]);
|
||||
var expected = (ulong) (length - j);
|
||||
var actual = frame.Segments[i].Span[j];
|
||||
Assert.AreEqual(expected, actual);
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,7 +167,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
txPump.Send(PackFrame(4));
|
||||
txPump.Send(PackFrame(5));
|
||||
|
||||
Assert.IsTrue(SpinWait.SpinUntil(() => bc.Count == 8, 500));
|
||||
Assert.IsTrue(SpinWait.SpinUntil(() => bc.Count == 8, 50000));
|
||||
|
||||
UnpackAndVerifyFrame(bc.Take(), 1);
|
||||
UnpackAndVerifyFrame(bc.Take(), 8);
|
||||
|
@ -1,8 +1,8 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks.Dataflow;
|
||||
using Capnp.Rpc;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System.Threading.Tasks.Dataflow;
|
||||
|
||||
namespace Capnp.Net.Runtime.Tests
|
||||
{
|
||||
|
@ -1,11 +1,13 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Capnp.Rpc;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Diagnostics;
|
||||
using Exception = Capnp.Rpc.Exception;
|
||||
|
||||
namespace Capnp.Net.Runtime.Tests
|
||||
{
|
||||
@ -41,7 +43,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
|
||||
int MediumTimeout => Debugger.IsAttached ? Timeout.Infinite : 2000;
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void CreateAndDispose()
|
||||
{
|
||||
(var server, var client) = SetupClientServerPair();
|
||||
@ -52,21 +54,29 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void ConnectAndDispose()
|
||||
{
|
||||
(var server, var client) = SetupClientServerPair();
|
||||
|
||||
using (server)
|
||||
using (client)
|
||||
{
|
||||
try
|
||||
{
|
||||
Assert.IsTrue(client.WhenConnected.Wait(MediumTimeout));
|
||||
SpinWait.SpinUntil(() => server.ConnectionCount > 0, MediumTimeout);
|
||||
Assert.AreEqual(1, server.ConnectionCount);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void ConnectNoServer()
|
||||
{
|
||||
using (var client = new TcpRpcClient("localhost", TcpPort))
|
||||
@ -75,7 +85,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void ConnectAndBootstrap()
|
||||
{
|
||||
(var server, var client) = SetupClientServerPair();
|
||||
@ -94,7 +104,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void ConnectNoBootstrap()
|
||||
{
|
||||
(var server, var client) = SetupClientServerPair();
|
||||
@ -112,7 +122,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void CallReturn()
|
||||
{
|
||||
(var server, var client) = SetupClientServerPair();
|
||||
@ -153,7 +163,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void CallCancelOnServer()
|
||||
{
|
||||
(var server, var client) = SetupClientServerPair();
|
||||
@ -188,7 +198,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void CallCancelOnClient()
|
||||
{
|
||||
ExpectingLogOutput = false;
|
||||
@ -233,7 +243,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void CallReturnAfterClientSideCancel()
|
||||
{
|
||||
ExpectingLogOutput = false;
|
||||
@ -295,7 +305,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void CallServerSideException()
|
||||
{
|
||||
(var server, var client) = SetupClientServerPair();
|
||||
@ -332,7 +342,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void PipelineBeforeReturn()
|
||||
{
|
||||
(var server, var client) = SetupClientServerPair();
|
||||
@ -405,7 +415,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void PipelineAfterReturn()
|
||||
{
|
||||
(var server, var client) = SetupClientServerPair();
|
||||
@ -481,7 +491,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void PipelineMultiple()
|
||||
{
|
||||
(var server, var client) = SetupClientServerPair();
|
||||
@ -598,7 +608,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void PipelineCallAfterDisposal()
|
||||
{
|
||||
(var server, var client) = SetupClientServerPair();
|
||||
@ -635,7 +645,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void PipelineCallDuringDisposal()
|
||||
{
|
||||
(var server, var client) = SetupClientServerPair();
|
||||
|
@ -12,7 +12,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
[TestClass]
|
||||
public class TcpRpcAdvancedStuff: TestBase
|
||||
{
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void MultiConnect()
|
||||
{
|
||||
using (var server = SetupServer())
|
||||
@ -50,7 +50,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void TwoClients()
|
||||
{
|
||||
using (var server = SetupServer())
|
||||
|
@ -95,7 +95,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
Assert.AreEqual(expected, line.Result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void BasicClient()
|
||||
{
|
||||
LaunchCompatTestProcess("server:Interface", stdout =>
|
||||
@ -126,7 +126,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
});
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void BasicServer()
|
||||
{
|
||||
using (var server = SetupServer())
|
||||
@ -143,7 +143,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void PipelineClient()
|
||||
{
|
||||
LaunchCompatTestProcess("server:Pipeline", stdout =>
|
||||
@ -180,7 +180,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
});
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void PipelineServer()
|
||||
{
|
||||
using (var server = SetupServer())
|
||||
@ -198,7 +198,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void ReleaseClient()
|
||||
{
|
||||
LaunchCompatTestProcess("server:MoreStuff", stdout =>
|
||||
@ -231,7 +231,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
});
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void ReleaseServer()
|
||||
{
|
||||
using (var server = SetupServer())
|
||||
@ -259,7 +259,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void ReleaseOnCancelClient()
|
||||
{
|
||||
// Since we have a threaded model, there is no way to deterministically provoke the situation
|
||||
@ -337,7 +337,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
});
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void ReleaseOnCancelServer()
|
||||
{
|
||||
using (var server = SetupServer())
|
||||
@ -354,7 +354,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void TestTailCallClient()
|
||||
{
|
||||
LaunchCompatTestProcess("server:TailCaller", stdout =>
|
||||
@ -389,7 +389,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
});
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void TestTailCallServer()
|
||||
{
|
||||
using (var server = SetupServer())
|
||||
@ -408,7 +408,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void CancelationServer()
|
||||
{
|
||||
LaunchCompatTestProcess("server:MoreStuff", stdout =>
|
||||
@ -432,13 +432,13 @@ namespace Capnp.Net.Runtime.Tests
|
||||
cts.Cancel();
|
||||
|
||||
Assert.IsTrue(destroyed.Task.Wait(MediumNonDbgTimeout));
|
||||
Assert.IsFalse(cancelTask.IsCompletedSuccessfully);
|
||||
Assert.IsFalse(cancelTask.IsCompleted && !cancelTask.IsCanceled);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void CancelationClient()
|
||||
{
|
||||
using (var server = SetupServer())
|
||||
@ -455,7 +455,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void PromiseResolveServer()
|
||||
{
|
||||
LaunchCompatTestProcess("server:MoreStuff", stdout =>
|
||||
@ -497,7 +497,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
});
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void PromiseResolveClient()
|
||||
{
|
||||
using (var server = SetupServer())
|
||||
@ -516,7 +516,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void RetainAndReleaseServer()
|
||||
{
|
||||
var destructionPromise = new TaskCompletionSource<int>();
|
||||
@ -594,7 +594,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
});
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void RetainAndReleaseClient()
|
||||
{
|
||||
using (var server = SetupServer())
|
||||
@ -614,7 +614,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void CancelServer()
|
||||
{
|
||||
LaunchCompatTestProcess("server:MoreStuff", stdout =>
|
||||
@ -655,7 +655,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
});
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void CancelClient()
|
||||
{
|
||||
using (var server = SetupServer())
|
||||
@ -672,7 +672,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void SendTwiceServer()
|
||||
{
|
||||
LaunchCompatTestProcess("server:MoreStuff", stdout =>
|
||||
@ -716,7 +716,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
});
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void SendTwiceClient()
|
||||
{
|
||||
using (var server = SetupServer())
|
||||
@ -736,7 +736,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void EmbargoServer()
|
||||
{
|
||||
LaunchCompatTestProcess("server:MoreStuff", stdout =>
|
||||
@ -803,7 +803,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
});
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void EmbargoClient()
|
||||
{
|
||||
using (var server = SetupServer())
|
||||
@ -873,13 +873,13 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void EmbargoErrorServer()
|
||||
{
|
||||
LaunchCompatTestProcess("server:MoreStuff", EmbargoErrorImpl);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void RepeatedEmbargoError()
|
||||
{
|
||||
LaunchCompatTestProcess("server:MoreStuff", stdout =>
|
||||
@ -891,7 +891,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
});
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void EmbargoErrorClient()
|
||||
{
|
||||
using (var server = SetupServer())
|
||||
@ -907,7 +907,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void EmbargoNullServer()
|
||||
{
|
||||
LaunchCompatTestProcess("server:MoreStuff", stdout =>
|
||||
@ -956,7 +956,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
});
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void EmbargoNullClient()
|
||||
{
|
||||
using (var server = SetupServer())
|
||||
@ -972,7 +972,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void CallBrokenPromiseServer()
|
||||
{
|
||||
LaunchCompatTestProcess("server:MoreStuff", stdout =>
|
||||
@ -1009,7 +1009,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
});
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[TestMethod, Timeout(10000)]
|
||||
public void CallBrokenPromiseClient()
|
||||
{
|
||||
using (var server = SetupServer())
|
||||
|
@ -212,7 +212,7 @@ namespace Capnp.Net.Runtime.Tests
|
||||
cts.Cancel();
|
||||
|
||||
Assert.IsTrue(destroyed.Task.Wait(MediumNonDbgTimeout));
|
||||
Assert.IsFalse(cancelTask.IsCompletedSuccessfully);
|
||||
Assert.IsFalse(cancelTask.IsCompleted && !cancelTask.IsCanceled);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<RootNamespace>Capnp</RootNamespace>
|
||||
<LangVersion>7.2</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
@ -82,6 +82,8 @@ namespace Capnp
|
||||
throw new ArgumentException("Segment must not have zero length");
|
||||
}
|
||||
|
||||
|
||||
|
||||
lock (_writeLock)
|
||||
{
|
||||
_writer.Write(frame.Segments.Count - 1);
|
||||
@ -99,8 +101,7 @@ namespace Capnp
|
||||
|
||||
foreach (var segment in frame.Segments)
|
||||
{
|
||||
var bytes = MemoryMarshal.Cast<ulong, byte>(segment.Span);
|
||||
|
||||
var bytes = MemoryMarshal.Cast<ulong, byte>(segment.Span).ToArray();
|
||||
_writer.Write(bytes);
|
||||
}
|
||||
}
|
||||
@ -123,7 +124,7 @@ namespace Capnp
|
||||
/// to be part of normal operation. It does pass exceptions which arise due to I/O errors or invalid data.
|
||||
/// </summary>
|
||||
/// <exception cref="ArgumentException">The underlying stream does not support reading or is already closed.</exception>
|
||||
/// <exception cref="OverflowException">Received invalid data.</exception>
|
||||
/// <exception cref="InvalidDataException">Encountered Invalid Framing Data</exception>
|
||||
/// <exception cref="OutOfMemoryException">Received a message with too many or too big segments, probably dues to invalid data.</exception>
|
||||
/// <exception cref="IOException">An I/O error occurs.</exception>
|
||||
public void Run()
|
||||
@ -135,55 +136,19 @@ namespace Capnp
|
||||
while (true)
|
||||
{
|
||||
IsWaitingForData = true;
|
||||
|
||||
uint scountm = reader.ReadUInt32();
|
||||
int scount = checked((int)(scountm + 1));
|
||||
var buffers = new Memory<ulong>[scount];
|
||||
|
||||
for (uint i = 0; i < scount; i++)
|
||||
{
|
||||
int size = checked((int)reader.ReadUInt32());
|
||||
|
||||
// This implementation will never send empty segments.
|
||||
// Other implementations should not. An empty segment may also
|
||||
// indicate and end-of-stream (stream closed) condition.
|
||||
if (size == 0)
|
||||
{
|
||||
Logger.LogInformation("Received zero-sized segment, stopping interaction");
|
||||
return;
|
||||
}
|
||||
|
||||
buffers[i] = new Memory<ulong>(new ulong[size]);
|
||||
}
|
||||
|
||||
if ((scount & 1) == 0)
|
||||
{
|
||||
// Padding
|
||||
reader.ReadUInt32();
|
||||
}
|
||||
|
||||
for (uint i = 0; i < scount; i++)
|
||||
{
|
||||
var buffer = MemoryMarshal.Cast<ulong, byte>(buffers[i].Span);
|
||||
|
||||
int got = reader.Read(buffer);
|
||||
|
||||
if (got != buffer.Length)
|
||||
{
|
||||
Logger.LogWarning("Received incomplete frame");
|
||||
|
||||
throw new EndOfStreamException("Expected more bytes according to framing header");
|
||||
}
|
||||
}
|
||||
|
||||
var frame = reader.ReadWireFrame();
|
||||
IsWaitingForData = false;
|
||||
|
||||
FrameReceived?.Invoke(new WireFrame(new ArraySegment<Memory<ulong>>(buffers, 0, scount)));
|
||||
FrameReceived?.Invoke(frame);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (EndOfStreamException)
|
||||
{
|
||||
Logger.LogWarning("Encountered End of Stream");
|
||||
}
|
||||
catch (InvalidDataException e)
|
||||
{
|
||||
Logger.LogWarning(e.Message);
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
|
@ -21,19 +21,26 @@ namespace Capnp
|
||||
/// <exception cref="EndOfStreamException">The end of the stream is reached.</exception>
|
||||
/// <exception cref="ObjectDisposedException">The stream is closed.</exception>
|
||||
/// <exception cref="IOException">An I/O error occurs.</exception>
|
||||
/// <exception cref="OverflowException">Encountered invalid framing data.</exception>
|
||||
/// <exception cref="InvalidDataException">Encountered invalid framing data.</exception>
|
||||
/// <exception cref="OutOfMemoryException">Too many or too large segments, probably due to invalid framing data.</exception>
|
||||
public static WireFrame ReadSegments(Stream stream)
|
||||
{
|
||||
using (var reader = new BinaryReader(stream, Encoding.Default, true))
|
||||
{
|
||||
uint scountm = reader.ReadUInt32();
|
||||
uint scount = checked(scountm + 1);
|
||||
return reader.ReadWireFrame();
|
||||
}
|
||||
}
|
||||
|
||||
public static WireFrame ReadWireFrame(this BinaryReader reader)
|
||||
{
|
||||
uint scount = reader.ReadUInt32();
|
||||
if(scount++ == UInt32.MaxValue) throw new InvalidDataException("Encountered Invalid Framing Data");
|
||||
var buffers = new Memory<ulong>[scount];
|
||||
|
||||
for (uint i = 0; i < scount; i++)
|
||||
{
|
||||
uint size = reader.ReadUInt32();
|
||||
if(size==0) throw new EndOfStreamException("Stream Closed");
|
||||
buffers[i] = new Memory<ulong>(new ulong[size]);
|
||||
}
|
||||
|
||||
@ -43,18 +50,29 @@ namespace Capnp
|
||||
reader.ReadUInt32();
|
||||
}
|
||||
|
||||
for (uint i = 0; i < scount; i++)
|
||||
{
|
||||
var buffer = MemoryMarshal.Cast<ulong, byte>(buffers[i].Span);
|
||||
|
||||
if (reader.Read(buffer) != buffer.Length)
|
||||
{
|
||||
throw new EndOfStreamException("Expected more bytes according to framing header");
|
||||
}
|
||||
}
|
||||
FillBuffersFromFrames(buffers, scount, reader);
|
||||
|
||||
return new WireFrame(buffers);
|
||||
}
|
||||
|
||||
public static void FillBuffersFromFrames(Memory<ulong>[] buffers, uint segmentCount, BinaryReader reader)
|
||||
{
|
||||
for (uint i = 0; i < segmentCount; i++)
|
||||
{
|
||||
var buffer = MemoryMarshal.Cast<ulong, byte>(buffers[i].Span.ToArray());
|
||||
var tmpBuffer = reader.ReadBytes(buffer.Length);
|
||||
|
||||
if (tmpBuffer.Length != buffer.Length)
|
||||
{
|
||||
throw new InvalidDataException("Expected more bytes according to framing header");
|
||||
}
|
||||
|
||||
for (int j = 0; j < buffers[i].Length; j++)
|
||||
{
|
||||
var value = BitConverter.ToUInt64(tmpBuffer, j*8);
|
||||
buffers[i].Span[j] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ namespace Capnp
|
||||
var utf8Bytes = PrimitiveCast<byte>().Data;
|
||||
if (utf8Bytes.Length == 0) return string.Empty;
|
||||
var utf8GytesNoZterm = utf8Bytes.Slice(0, utf8Bytes.Length - 1);
|
||||
return Encoding.UTF8.GetString(utf8GytesNoZterm);
|
||||
return Encoding.UTF8.GetString(utf8GytesNoZterm.ToArray());
|
||||
}
|
||||
|
||||
IEnumerable<T> Enumerate()
|
||||
|
@ -24,10 +24,10 @@ namespace Capnp
|
||||
Coder<ulong>.Fn = (x, y) => x ^ y;
|
||||
Coder<float>.Fn = (x, y) =>
|
||||
{
|
||||
int xi = BitConverter.SingleToInt32Bits(x);
|
||||
int yi = BitConverter.SingleToInt32Bits(y);
|
||||
int xi = x.SingleToInt32();
|
||||
int yi = y.SingleToInt32();
|
||||
int zi = xi ^ yi;
|
||||
return BitConverter.Int32BitsToSingle(zi);
|
||||
return BitConverter.ToSingle(BitConverter.GetBytes(zi), 0);
|
||||
};
|
||||
Coder<double>.Fn = (x, y) =>
|
||||
{
|
||||
|
@ -52,7 +52,7 @@ namespace Capnp.Rpc
|
||||
|
||||
internal override void Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer)
|
||||
{
|
||||
if (WhenResolved.IsCompletedSuccessfully)
|
||||
if (WhenResolved.ReplacementTaskIsCompletedSuccessfully())
|
||||
{
|
||||
WhenResolved.Result.Export(endpoint, writer);
|
||||
}
|
||||
|
@ -77,7 +77,8 @@ namespace Capnp.Rpc
|
||||
{
|
||||
lock (_reentrancyBlocker)
|
||||
{
|
||||
if (_resolvedCap.Task.IsCompletedSuccessfully)
|
||||
|
||||
if (_resolvedCap.Task.ReplacementTaskIsCompletedSuccessfully())
|
||||
{
|
||||
_resolvedCap.Task.Result.Export(endpoint, writer);
|
||||
}
|
||||
|
@ -179,13 +179,9 @@ namespace Capnp.Rpc
|
||||
|
||||
uint RandId()
|
||||
{
|
||||
uint id = 0;
|
||||
var idSpan = MemoryMarshal.CreateSpan(ref id, 1);
|
||||
var idBytes = MemoryMarshal.Cast<uint, byte>(idSpan);
|
||||
|
||||
_random.NextBytes(idBytes);
|
||||
|
||||
return id;
|
||||
var holder = new byte[4];
|
||||
_random.NextBytes(holder);
|
||||
return BitConverter.ToUInt32(holder,0);
|
||||
}
|
||||
|
||||
uint AllocateExport(Skeleton providedCapability, out bool first)
|
||||
@ -237,7 +233,7 @@ namespace Capnp.Rpc
|
||||
|
||||
lock (_reentrancyBlocker)
|
||||
{
|
||||
while (!_questionTable.TryAdd(questionId, question))
|
||||
while (!_questionTable.ReplacementTryAdd(questionId, question))
|
||||
{
|
||||
questionId = RandId();
|
||||
var oldQuestion = question;
|
||||
@ -277,7 +273,7 @@ namespace Capnp.Rpc
|
||||
{
|
||||
uint id = RandId();
|
||||
|
||||
while (!_pendingDisembargos.TryAdd(id, tcs))
|
||||
while (!_pendingDisembargos.ReplacementTryAdd(id, tcs))
|
||||
{
|
||||
id = RandId();
|
||||
}
|
||||
@ -323,7 +319,7 @@ namespace Capnp.Rpc
|
||||
bool added;
|
||||
lock (_reentrancyBlocker)
|
||||
{
|
||||
added = _answerTable.TryAdd(req.QuestionId, pendingAnswer);
|
||||
added = _answerTable.ReplacementTryAdd(req.QuestionId, pendingAnswer);
|
||||
}
|
||||
|
||||
if (!added)
|
||||
@ -382,7 +378,7 @@ namespace Capnp.Rpc
|
||||
bool added;
|
||||
lock (_reentrancyBlocker)
|
||||
{
|
||||
added = _answerTable.TryAdd(req.QuestionId, pendingAnswer);
|
||||
added = _answerTable.ReplacementTryAdd(req.QuestionId, pendingAnswer);
|
||||
}
|
||||
|
||||
if (!added)
|
||||
@ -876,7 +872,7 @@ namespace Capnp.Rpc
|
||||
|
||||
lock (_reentrancyBlocker)
|
||||
{
|
||||
exists = _pendingDisembargos.Remove(disembargo.Context.ReceiverLoopback, out tcs);
|
||||
exists = _pendingDisembargos.ReplacementTryRemove(disembargo.Context.ReceiverLoopback, out tcs);
|
||||
}
|
||||
|
||||
if (exists)
|
||||
@ -950,7 +946,7 @@ namespace Capnp.Rpc
|
||||
|
||||
lock (_reentrancyBlocker)
|
||||
{
|
||||
exists = _answerTable.Remove(finish.QuestionId, out answer);
|
||||
exists = _answerTable.ReplacementTryRemove(finish.QuestionId, out answer);
|
||||
}
|
||||
|
||||
if (exists)
|
||||
@ -988,7 +984,7 @@ namespace Capnp.Rpc
|
||||
if (rc.RefCount == 0)
|
||||
{
|
||||
_exportTable.Remove(id);
|
||||
_revExportTable.Remove(rc.Cap, out uint _);
|
||||
_revExportTable.ReplacementTryRemove(rc.Cap, out uint _);
|
||||
}
|
||||
}
|
||||
catch (System.Exception)
|
||||
|
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@ -62,6 +63,10 @@ namespace Capnp.Rpc
|
||||
{
|
||||
throw new RpcException("TcpRpcClient is unable to connect", exception);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogError("UNHANDLED EXCEPTION");
|
||||
}
|
||||
|
||||
}
|
||||
async Task Connect(string host, int port)
|
||||
@ -103,6 +108,7 @@ namespace Capnp.Rpc
|
||||
{
|
||||
_rpcEngine = new RpcEngine();
|
||||
_client = new TcpClient();
|
||||
_client.ExclusiveAddressUse = false;
|
||||
|
||||
WhenConnected = Connect(host, port);
|
||||
}
|
||||
@ -119,7 +125,7 @@ namespace Capnp.Rpc
|
||||
throw new InvalidOperationException("Connection not yet established");
|
||||
}
|
||||
|
||||
if (!WhenConnected.IsCompletedSuccessfully)
|
||||
if (!WhenConnected.ReplacementTaskIsCompletedSuccessfully())
|
||||
{
|
||||
throw new InvalidOperationException("Connection not successfully established");
|
||||
}
|
||||
@ -143,8 +149,9 @@ namespace Capnp.Rpc
|
||||
Logger.LogError("Unable to join connection task within timeout");
|
||||
}
|
||||
}
|
||||
catch (System.Exception)
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Logger.LogError(e, "Failure disposing client");
|
||||
}
|
||||
|
||||
if (_pumpThread != null && !_pumpThread.Join(500))
|
||||
|
@ -188,12 +188,10 @@ namespace Capnp.Rpc
|
||||
{
|
||||
_rpcEngine = new RpcEngine();
|
||||
_listener = new TcpListener(localAddr, port);
|
||||
_listener.ExclusiveAddressUse = false;
|
||||
_listener.Start();
|
||||
|
||||
_acceptorThread = new Thread(() =>
|
||||
{
|
||||
AcceptClients();
|
||||
});
|
||||
_acceptorThread = new Thread(AcceptClients);
|
||||
|
||||
_acceptorThread.Start();
|
||||
}
|
||||
|
@ -2528,7 +2528,7 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
|
||||
public class Exception : ICapnpSerializable
|
||||
public class Exception : System.Exception, ICapnpSerializable
|
||||
{
|
||||
void ICapnpSerializable.Deserialize(DeserializerState arg_)
|
||||
{
|
||||
|
@ -285,9 +285,9 @@ namespace Capnp
|
||||
public static float ReadDataFloat<T>(this T d, ulong bitOffset, float defaultValue = 0)
|
||||
where T : IStructDeserializer
|
||||
{
|
||||
int defaultBits = BitConverter.SingleToInt32Bits(defaultValue);
|
||||
int defaultBits = defaultValue.SingleToInt32();
|
||||
int bits = (int)d.StructReadData(bitOffset, 32) ^ defaultBits;
|
||||
return BitConverter.Int32BitsToSingle(bits);
|
||||
return bits.Int32ToSingle();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -301,8 +301,8 @@ namespace Capnp
|
||||
public static void WriteData<T>(this T d, ulong bitOffset, float value, float defaultValue = 0.0f)
|
||||
where T : IStructSerializer
|
||||
{
|
||||
int bits = BitConverter.SingleToInt32Bits(value);
|
||||
int defaultBits = BitConverter.SingleToInt32Bits(defaultValue);
|
||||
int bits = value.SingleToInt32();
|
||||
int defaultBits = defaultValue.SingleToInt32();
|
||||
WriteData(d, bitOffset, bits, defaultBits);
|
||||
}
|
||||
|
||||
|
@ -1068,7 +1068,7 @@ namespace Capnp
|
||||
{
|
||||
var bytes = ListGetBytes();
|
||||
if (bytes.Length == 0) return string.Empty;
|
||||
return Encoding.UTF8.GetString(bytes.Slice(0, bytes.Length - 1));
|
||||
return Encoding.UTF8.GetString(bytes.Slice(0, bytes.Length - 1).ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1164,8 +1164,8 @@ namespace Capnp
|
||||
/// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is out of bounds.</exception>
|
||||
public void ListWriteValue(int index, float value, float defaultValue = 0)
|
||||
{
|
||||
int rcastValue = BitConverter.SingleToInt32Bits(value);
|
||||
int rcastDefaultValue = BitConverter.SingleToInt32Bits(defaultValue);
|
||||
int rcastValue = value.SingleToInt32();
|
||||
int rcastDefaultValue = defaultValue.SingleToInt32();
|
||||
ListWriteValue(index, rcastValue, rcastDefaultValue);
|
||||
}
|
||||
|
||||
|
67
Capnp.Net.Runtime/UtilityExtensions.cs
Normal file
67
Capnp.Net.Runtime/UtilityExtensions.cs
Normal file
@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Capnp
|
||||
{
|
||||
public static class UtilityExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// This method exists until NET Standard 2.1 is released
|
||||
/// </summary>
|
||||
/// <param name="thisDict"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <typeparam name="K"></typeparam>
|
||||
/// <typeparam name="V"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static bool ReplacementTryAdd<K, V>(this Dictionary<K, V> thisDict, K key, V value)
|
||||
{
|
||||
if (thisDict.ContainsKey(key))
|
||||
return false;
|
||||
thisDict.Add(key, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method exists until NET Standard 2.1 is released
|
||||
/// </summary>
|
||||
/// <param name="thisDict"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <typeparam name="K"></typeparam>
|
||||
/// <typeparam name="V"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static bool ReplacementTryRemove<K, V>(this Dictionary<K, V> thisDict, K key, out V value)
|
||||
{
|
||||
if (!thisDict.ContainsKey(key))
|
||||
{
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
value = thisDict[key];
|
||||
return thisDict.Remove(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method exists until NET Standard 2.1 is released
|
||||
/// </summary>
|
||||
/// <param name="task"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static bool ReplacementTaskIsCompletedSuccessfully(this Task task)
|
||||
{
|
||||
return task.IsCompleted && !task.IsCanceled && !task.IsFaulted;
|
||||
}
|
||||
|
||||
public static int SingleToInt32(this float value)
|
||||
{
|
||||
var valueBytes = BitConverter.GetBytes(value);
|
||||
return BitConverter.ToInt32(valueBytes,0);
|
||||
}
|
||||
|
||||
public static float Int32ToSingle(this int value) =>
|
||||
BitConverter.ToSingle(BitConverter.GetBytes(value),0);
|
||||
}
|
||||
}
|
@ -7,8 +7,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Capnp.Net.Runtime", "Capnp.
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "capnpc-csharp", "capnpc-csharp\capnpc-csharp.csproj", "{D19E5EA7-D35B-4A1F-99CB-ED136316B577}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "capnpc-binblob", "capnpc-binblob\capnpc-binblob.csproj", "{8C17F147-D784-4584-80FF-21BE03AC0D17}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Capnp.Net.Runtime.Tests", "Capnp.Net.Runtime.Tests\Capnp.Net.Runtime.Tests.csproj", "{9ED38750-F83F-4B10-B3A3-4FD6183F9E86}"
|
||||
EndProject
|
||||
Global
|
||||
|
Loading…
x
Reference in New Issue
Block a user