mirror of
https://github.com/FabInfra/capnproto-dotnetcore_Runtime.git
synced 2025-03-12 14:51:41 +01:00
nullable first step
This commit is contained in:
parent
abe9921ec5
commit
3c9c98bc2b
@ -1,4 +1,5 @@
|
||||
namespace Capnp
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
/// Generic <see cref="ICapnpSerializable"/> implementation, based on a wrapper around <see cref="DeserializerState"/>.
|
||||
@ -29,3 +30,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,9 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;netcoreapp2.1</TargetFrameworks>
|
||||
<TargetFrameworks>netstandard2.0;netcoreapp2.1;netcoreapp3.0</TargetFrameworks>
|
||||
<RootNamespace>Capnp</RootNamespace>
|
||||
<LangVersion>7.2</LangVersion>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<AssemblyName>Capnp.Net.Runtime</AssemblyName>
|
||||
<PackageId>Capnp.Net.Runtime</PackageId>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -10,15 +11,15 @@ namespace Capnp
|
||||
/// </summary>
|
||||
public static class CapnpSerializable
|
||||
{
|
||||
interface IConstructibleFromDeserializerState<out T>
|
||||
interface IConstructibleFromDeserializerState
|
||||
{
|
||||
T Create(DeserializerState state);
|
||||
object? Create(DeserializerState state);
|
||||
}
|
||||
|
||||
class FromStruct<T>: IConstructibleFromDeserializerState<T>
|
||||
class FromStruct<T>: IConstructibleFromDeserializerState
|
||||
where T : ICapnpSerializable, new()
|
||||
{
|
||||
public T Create(DeserializerState state)
|
||||
public object Create(DeserializerState state)
|
||||
{
|
||||
var result = new T();
|
||||
if (state.Kind != ObjectKind.Nil)
|
||||
@ -29,7 +30,7 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
|
||||
class FromList<T>: IConstructibleFromDeserializerState<IReadOnlyList<T>>
|
||||
class FromList<T>: IConstructibleFromDeserializerState
|
||||
where T: class
|
||||
{
|
||||
readonly Func<DeserializerState, T> _elementSerializer;
|
||||
@ -39,23 +40,23 @@ namespace Capnp
|
||||
_elementSerializer = (Func<DeserializerState, T>)GetSerializer(typeof(T));
|
||||
|
||||
}
|
||||
public IReadOnlyList<T> Create(DeserializerState state)
|
||||
public object Create(DeserializerState state)
|
||||
{
|
||||
return state.RequireList().Cast(_elementSerializer);
|
||||
}
|
||||
}
|
||||
|
||||
class FromCapability<T>: IConstructibleFromDeserializerState<T>
|
||||
class FromCapability<T>: IConstructibleFromDeserializerState
|
||||
where T: class
|
||||
{
|
||||
public T Create(DeserializerState state)
|
||||
public object? Create(DeserializerState state)
|
||||
{
|
||||
return state.RequireCap<T>();
|
||||
}
|
||||
}
|
||||
|
||||
static readonly ConditionalWeakTable<Type, Func<DeserializerState, object>> _typeMap =
|
||||
new ConditionalWeakTable<Type, Func<DeserializerState, object>>();
|
||||
static readonly ConditionalWeakTable<Type, Func<DeserializerState, object?>> _typeMap =
|
||||
new ConditionalWeakTable<Type, Func<DeserializerState, object?>>();
|
||||
|
||||
static CapnpSerializable()
|
||||
{
|
||||
@ -73,14 +74,14 @@ namespace Capnp
|
||||
_typeMap.Add(typeof(IReadOnlyList<double>), d => d.RequireList().CastDouble());
|
||||
}
|
||||
|
||||
static Func<DeserializerState, object> CreateSerializer(Type type)
|
||||
static Func<DeserializerState, object?> CreateSerializer(Type type)
|
||||
{
|
||||
if (typeof(ICapnpSerializable).IsAssignableFrom(type))
|
||||
{
|
||||
try
|
||||
{
|
||||
return ((IConstructibleFromDeserializerState<object>)
|
||||
Activator.CreateInstance(typeof(FromStruct<>).MakeGenericType(type))).Create;
|
||||
return ((IConstructibleFromDeserializerState)
|
||||
Activator.CreateInstance(typeof(FromStruct<>).MakeGenericType(type))!).Create;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -94,12 +95,12 @@ namespace Capnp
|
||||
try
|
||||
{
|
||||
var elementType = type.GetGenericArguments()[0];
|
||||
return ((IConstructibleFromDeserializerState<object>)
|
||||
Activator.CreateInstance(typeof(FromList<>).MakeGenericType(elementType))).Create;
|
||||
return ((IConstructibleFromDeserializerState)
|
||||
Activator.CreateInstance(typeof(FromList<>).MakeGenericType(elementType))!).Create;
|
||||
}
|
||||
catch (TargetInvocationException ex)
|
||||
{
|
||||
throw ex.InnerException;
|
||||
throw ex.InnerException!;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -123,8 +124,8 @@ namespace Capnp
|
||||
|
||||
try
|
||||
{
|
||||
return ((IConstructibleFromDeserializerState<object>)
|
||||
Activator.CreateInstance(typeof(FromCapability<>).MakeGenericType(type))).Create;
|
||||
return ((IConstructibleFromDeserializerState)
|
||||
Activator.CreateInstance(typeof(FromCapability<>).MakeGenericType(type))!).Create;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -135,7 +136,7 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
|
||||
static Func<DeserializerState, object> GetSerializer(Type type)
|
||||
static Func<DeserializerState, object?> GetSerializer(Type type)
|
||||
{
|
||||
return _typeMap.GetValue(type, CreateSerializer);
|
||||
}
|
||||
@ -164,10 +165,11 @@ namespace Capnp
|
||||
/// </typeparam>
|
||||
/// <param name="state"></param>
|
||||
/// <returns></returns>
|
||||
public static T Create<T>(DeserializerState state)
|
||||
public static T? Create<T>(DeserializerState state)
|
||||
where T: class
|
||||
{
|
||||
return (T)GetSerializer(typeof(T))(state);
|
||||
return (T?)GetSerializer(typeof(T))(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -23,3 +24,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -47,7 +49,7 @@ namespace Capnp
|
||||
/// <summary>
|
||||
/// The capabilities imported from the capability table. Only valid in RPC context.
|
||||
/// </summary>
|
||||
public IList<Rpc.ConsumedCapability> Caps { get; set; }
|
||||
public IList<Rpc.ConsumedCapability?>? Caps { get; set; }
|
||||
/// <summary>
|
||||
/// Current segment (essentially Segments[CurrentSegmentIndex]
|
||||
/// </summary>
|
||||
@ -83,10 +85,15 @@ namespace Capnp
|
||||
/// The conversion is cheap, since it does not involve copying any payload.
|
||||
/// </summary>
|
||||
/// <param name="state">The serializer state to be converted</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="state"/> is null</exception>
|
||||
/// <exception cref="InvalidOperationException"><paramref name="state"/> is not bound to a MessageBuilder</exception>
|
||||
public static implicit operator DeserializerState(SerializerState state)
|
||||
{
|
||||
if (state == null)
|
||||
throw new ArgumentNullException(nameof(state));
|
||||
|
||||
if (state.MsgBuilder == null)
|
||||
throw new InvalidOperationException("state is not bound to a MessageBuilder");
|
||||
|
||||
switch (state.Kind)
|
||||
{
|
||||
@ -100,7 +107,7 @@ namespace Capnp
|
||||
case ObjectKind.ListOfStructs:
|
||||
case ObjectKind.Nil:
|
||||
case ObjectKind.Struct:
|
||||
return new DeserializerState(state.Allocator.Segments)
|
||||
return new DeserializerState(state.Allocator!.Segments)
|
||||
{
|
||||
CurrentSegmentIndex = state.SegmentIndex,
|
||||
Offset = state.Offset,
|
||||
@ -112,7 +119,7 @@ namespace Capnp
|
||||
};
|
||||
|
||||
case ObjectKind.Capability:
|
||||
return new DeserializerState(state.Allocator.Segments)
|
||||
return new DeserializerState(state.Allocator!.Segments)
|
||||
{
|
||||
Kind = ObjectKind.Capability,
|
||||
Caps = state.Caps,
|
||||
@ -376,11 +383,11 @@ namespace Capnp
|
||||
/// the capability table. Does not mutate this state.
|
||||
/// </summary>
|
||||
/// <param name="offset">Offset relative to this.Offset within current segment</param>
|
||||
/// <returns>the low-level capability object</returns>
|
||||
/// <returns>the low-level capability object, or null if it is a null pointer</returns>
|
||||
/// <exception cref="IndexOutOfRangeException">offset negative or out of range</exception>
|
||||
/// <exception cref="InvalidOperationException">capability table not set</exception>
|
||||
/// <exception cref="Rpc.RpcException">not a capability pointer or invalid capability index</exception>
|
||||
internal Rpc.ConsumedCapability DecodeCapPointer(int offset)
|
||||
internal Rpc.ConsumedCapability? DecodeCapPointer(int offset)
|
||||
{
|
||||
if (offset < 0)
|
||||
{
|
||||
@ -490,7 +497,7 @@ namespace Capnp
|
||||
return state;
|
||||
}
|
||||
|
||||
internal Rpc.ConsumedCapability StructReadRawCap(int index)
|
||||
internal Rpc.ConsumedCapability? StructReadRawCap(int index)
|
||||
{
|
||||
if (Kind != ObjectKind.Struct && Kind != ObjectKind.Nil)
|
||||
throw new InvalidOperationException("Allowed on structs only");
|
||||
@ -567,7 +574,7 @@ namespace Capnp
|
||||
/// <exception cref="IndexOutOfRangeException">negative index</exception>
|
||||
/// <exception cref="DeserializationException">state does not represent a struct, invalid pointer,
|
||||
/// non-list-of-bytes pointer, traversal limit exceeded</exception>
|
||||
public string ReadText(int index, string defaultText = null)
|
||||
public string? ReadText(int index, string? defaultText = null)
|
||||
{
|
||||
return StructReadPointer(index).RequireList().CastText() ?? defaultText;
|
||||
}
|
||||
@ -646,7 +653,7 @@ namespace Capnp
|
||||
/// <exception cref="IndexOutOfRangeException">negative index</exception>
|
||||
/// <exception cref="DeserializationException">state does not represent a struct, invalid pointer,
|
||||
/// non-capability pointer, traversal limit exceeded</exception>
|
||||
public T ReadCap<T>(int index,
|
||||
public T? ReadCap<T>(int index,
|
||||
[System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
|
||||
[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
|
||||
[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0) where T: class
|
||||
@ -677,7 +684,7 @@ namespace Capnp
|
||||
/// <returns>capability instance or null if pointer was null</returns>
|
||||
/// <exception cref="IndexOutOfRangeException">negative index</exception>
|
||||
/// <exception cref="DeserializationException">state does not represent a capability</exception>
|
||||
public T RequireCap<T>() where T: class
|
||||
public T? RequireCap<T>() where T: class
|
||||
{
|
||||
if (Kind == ObjectKind.Nil)
|
||||
return null;
|
||||
@ -685,7 +692,11 @@ namespace Capnp
|
||||
if (Kind != ObjectKind.Capability)
|
||||
throw new DeserializationException("Expected a capability");
|
||||
|
||||
if (Caps == null)
|
||||
throw new InvalidOperationException("Capability table not set. This is a bug.");
|
||||
|
||||
return Rpc.CapabilityReflection.CreateProxy<T>(Caps[(int)CapabilityIndex]) as T;
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -226,3 +227,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -3,6 +3,7 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -36,3 +37,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -86,3 +87,4 @@ namespace Capnp
|
||||
public override IReadOnlyList<ushort> CastUShort() => new EmptyList<ushort>();
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -9,6 +9,7 @@ using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -22,7 +23,7 @@ namespace Capnp
|
||||
|
||||
int _disposing;
|
||||
readonly Stream _stream;
|
||||
readonly BinaryWriter _writer;
|
||||
readonly BinaryWriter? _writer;
|
||||
readonly object _writeLock = new object();
|
||||
readonly List<IFrameTracer> _tracers = new List<IFrameTracer>();
|
||||
|
||||
@ -62,7 +63,7 @@ namespace Capnp
|
||||
/// <summary>
|
||||
/// Event handler for frame reception.
|
||||
/// </summary>
|
||||
public event Action<WireFrame> FrameReceived;
|
||||
public event Action<WireFrame>? FrameReceived;
|
||||
|
||||
/// <summary>
|
||||
/// Sends a message over the stream.
|
||||
@ -196,3 +197,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.FrameTracing
|
||||
{
|
||||
/// <summary>
|
||||
@ -31,3 +32,4 @@ namespace Capnp.FrameTracing
|
||||
void TraceFrame(FrameDirection direction, WireFrame frame);
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -6,6 +6,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.FrameTracing
|
||||
{
|
||||
/// <summary>
|
||||
@ -245,3 +246,4 @@ namespace Capnp.FrameTracing
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -3,6 +3,7 @@ using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -107,3 +108,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,4 +1,5 @@
|
||||
namespace Capnp
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
/// This interface is intended to be implemented by schema-generated domain classes which support deserialization from
|
||||
@ -19,3 +20,4 @@
|
||||
void Deserialize(DeserializerState state);
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -27,3 +28,4 @@ namespace Capnp
|
||||
bool Allocate(uint nwords, uint preferredSegment, out SegmentSlice slice, bool forcePreferredSegment);
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -20,3 +21,4 @@ namespace Capnp
|
||||
ulong StructReadData(ulong bitOffset, int bitCount);
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -25,3 +26,4 @@ namespace Capnp
|
||||
Span<ulong> StructDataSection { get; }
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -10,7 +11,7 @@ namespace Capnp
|
||||
{
|
||||
static class GenericCasts<T>
|
||||
{
|
||||
public static Func<ListDeserializer, T> CastFunc;
|
||||
public static Func<ListDeserializer, T>? CastFunc;
|
||||
}
|
||||
|
||||
static ListDeserializer()
|
||||
@ -401,3 +402,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,4 +1,5 @@
|
||||
namespace Capnp
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumerates the list element categories which are defined by Cap'n Proto.
|
||||
@ -46,3 +47,4 @@
|
||||
ListOfStructs = 7
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -2,6 +2,7 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -77,3 +78,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -3,6 +3,7 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -96,3 +97,4 @@ namespace Capnp
|
||||
IEnumerator IEnumerable.GetEnumerator() => this.ToArray().GetEnumerator();
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -3,6 +3,7 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -29,7 +30,7 @@ namespace Capnp
|
||||
if (index < 0 || index >= Count)
|
||||
throw new IndexOutOfRangeException();
|
||||
|
||||
return Rpc.CapabilityReflection.CreateProxy<T>(State.DecodeCapPointer(index)) as T;
|
||||
return (Rpc.CapabilityReflection.CreateProxy<T>(State.DecodeCapPointer(index)) as T)!;
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,3 +71,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -34,7 +34,7 @@ namespace Capnp
|
||||
/// <exception cref="IndexOutOfRangeException"><paramref name="index"/> is out of range.</exception>
|
||||
public T this[int index]
|
||||
{
|
||||
get => Rpc.CapabilityReflection.CreateProxy<T>(DecodeCapPointer(index)) as T;
|
||||
get => (Rpc.CapabilityReflection.CreateProxy<T>(DecodeCapPointer(index)) as T)!;
|
||||
set
|
||||
{
|
||||
if (!IsAllocated)
|
||||
@ -109,3 +109,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -3,6 +3,7 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -64,3 +65,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -31,3 +32,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -2,6 +2,7 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -89,3 +90,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -12,7 +13,7 @@ namespace Capnp
|
||||
/// <typeparam name="TS">SerializerState which represents the element type</typeparam>
|
||||
public class ListOfPointersSerializer<TS>:
|
||||
SerializerState,
|
||||
IReadOnlyList<TS>
|
||||
IReadOnlyList<TS?>
|
||||
where TS: SerializerState, new()
|
||||
{
|
||||
/// <summary>
|
||||
@ -51,7 +52,7 @@ namespace Capnp
|
||||
/// </summary>
|
||||
public int Count => ListElementCount;
|
||||
|
||||
IEnumerable<TS> Enumerate()
|
||||
IEnumerable<TS?> Enumerate()
|
||||
{
|
||||
int count = Count;
|
||||
|
||||
@ -64,7 +65,7 @@ namespace Capnp
|
||||
/// <summary>
|
||||
/// Implements <see cref="IEnumerable{TS}"/>.
|
||||
/// </summary>
|
||||
public IEnumerator<TS> GetEnumerator()
|
||||
public IEnumerator<TS?> GetEnumerator()
|
||||
{
|
||||
return Enumerate().GetEnumerator();
|
||||
}
|
||||
@ -115,4 +116,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#nullable enable
|
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -232,3 +233,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -94,3 +95,4 @@ namespace Capnp
|
||||
IEnumerator IEnumerable.GetEnumerator() => Data.ToArray().GetEnumerator();
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -3,6 +3,7 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -79,3 +80,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -3,6 +3,7 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -93,3 +94,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -2,6 +2,7 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -9,7 +10,7 @@ namespace Capnp
|
||||
/// </summary>
|
||||
public class ListOfTextSerializer :
|
||||
SerializerState,
|
||||
IReadOnlyList<string>
|
||||
IReadOnlyList<string?>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the text at given index. Once an element is set, it cannot be overwritten.
|
||||
@ -18,7 +19,7 @@ namespace Capnp
|
||||
/// <exception cref="InvalidOperationException">List is not initialized</exception>
|
||||
/// <exception cref="IndexOutOfRangeException"><paramref name="index"/> is out of range.</exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">UTF-8 encoding exceeds 2^29-2 bytes</exception>
|
||||
public string this[int index]
|
||||
public string? this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -47,7 +48,7 @@ namespace Capnp
|
||||
/// </summary>
|
||||
public int Count => ListElementCount;
|
||||
|
||||
IEnumerable<string> Enumerate()
|
||||
IEnumerable<string?> Enumerate()
|
||||
{
|
||||
int count = Count;
|
||||
|
||||
@ -60,7 +61,7 @@ namespace Capnp
|
||||
/// <summary>
|
||||
/// Implementation of <see cref="IEnumerable{String}"/>/>
|
||||
/// </summary>
|
||||
public IEnumerator<string> GetEnumerator()
|
||||
public IEnumerator<string?> GetEnumerator()
|
||||
{
|
||||
return Enumerate().GetEnumerator();
|
||||
}
|
||||
@ -110,3 +111,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
|
||||
#nullable restore
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -21,3 +22,4 @@ namespace Capnp
|
||||
public static ILogger CreateLogger<T>() => LoggerFactory.CreateLogger<T>();
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -12,7 +13,7 @@ namespace Capnp
|
||||
{
|
||||
readonly ISegmentAllocator _allocator;
|
||||
readonly DynamicSerializerState _rootPtrBuilder;
|
||||
List<Rpc.ConsumedCapability> _capTable;
|
||||
List<Rpc.ConsumedCapability?>? _capTable;
|
||||
|
||||
MessageBuilder(ISegmentAllocator allocator)
|
||||
{
|
||||
@ -56,10 +57,11 @@ namespace Capnp
|
||||
/// Gets or sets the root object. The root object must be set exactly once per message.
|
||||
/// Setting it manually is only required (and allowed) when it was created with <see cref="CreateObject{TS}"/>.
|
||||
/// </summary>
|
||||
public SerializerState Root
|
||||
/// <exception cref="ArgumentNullException">Attempt to set null reference</exception>
|
||||
public SerializerState? Root
|
||||
{
|
||||
get => _rootPtrBuilder.TryGetPointer(0);
|
||||
set => _rootPtrBuilder.Link(0, value);
|
||||
set => _rootPtrBuilder.Link(0, value ?? throw new ArgumentNullException(nameof(value)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -90,13 +92,14 @@ namespace Capnp
|
||||
if (_capTable != null)
|
||||
throw new InvalidOperationException("Capability table was already initialized");
|
||||
|
||||
_capTable = new List<Rpc.ConsumedCapability>();
|
||||
_capTable = new List<Rpc.ConsumedCapability?>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns this message builder's segment allocator.
|
||||
/// </summary>
|
||||
public ISegmentAllocator Allocator => _allocator;
|
||||
internal List<Rpc.ConsumedCapability> Caps => _capTable;
|
||||
internal List<Rpc.ConsumedCapability?>? Caps => _capTable;
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -71,3 +72,4 @@ namespace Capnp
|
||||
Value = 16
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -2,13 +2,14 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
class PrimitiveCoder
|
||||
{
|
||||
class Coder<T>
|
||||
{
|
||||
public static Func<T, T, T> Fn { get; set; }
|
||||
public static Func<T, T, T>? Fn { get; set; }
|
||||
}
|
||||
|
||||
static PrimitiveCoder()
|
||||
@ -45,3 +46,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -71,3 +72,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -103,3 +104,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,4 +1,5 @@
|
||||
namespace Capnp.Rpc
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper struct to support tail calls
|
||||
@ -33,11 +34,12 @@
|
||||
/// <summary>
|
||||
/// SerializerState, if applicable
|
||||
/// </summary>
|
||||
public SerializerState Answer => _obj as SerializerState;
|
||||
public SerializerState? Answer => _obj as SerializerState;
|
||||
|
||||
/// <summary>
|
||||
/// PendingQuestion, if applicable
|
||||
/// </summary>
|
||||
public PendingQuestion Counterquestion => _obj as PendingQuestion;
|
||||
public PendingQuestion? Counterquestion => _obj as PendingQuestion;
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,4 +1,5 @@
|
||||
namespace Capnp.Rpc
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
/// Generic Proxy implementation which exposes the (usually protected) Call method.
|
||||
@ -33,7 +34,7 @@
|
||||
/// Constructs an instance and binds it to the given low-level capability.
|
||||
/// </summary>
|
||||
/// <param name="cap">low-level capability</param>
|
||||
public BareProxy(ConsumedCapability cap): base(cap)
|
||||
public BareProxy(ConsumedCapability? cap): base(cap)
|
||||
{
|
||||
}
|
||||
|
||||
@ -50,3 +51,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -3,6 +3,7 @@ using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
@ -110,7 +111,7 @@ namespace Capnp.Rpc
|
||||
|
||||
return (SkeletonFactory)Activator.CreateInstance(
|
||||
typeof(SkeletonFactory<>)
|
||||
.MakeGenericType(skeletonClass));
|
||||
.MakeGenericType(skeletonClass))!;
|
||||
}
|
||||
|
||||
static SkeletonFactory GetSkeletonFactory(Type type)
|
||||
@ -190,7 +191,7 @@ namespace Capnp.Rpc
|
||||
|
||||
return (ProxyFactory)Activator.CreateInstance(
|
||||
typeof(ProxyFactory<>)
|
||||
.MakeGenericType(proxyClass));
|
||||
.MakeGenericType(proxyClass))!;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -263,7 +264,7 @@ namespace Capnp.Rpc
|
||||
/// <exception cref="System.Reflection.TargetInvocationException">Problem with instatiating the Proxy (constructor threw exception).</exception>
|
||||
/// <exception cref="MemberAccessException">Caller does not have permission to invoke the Proxy constructor.</exception>
|
||||
/// <exception cref="TypeLoadException">Problem with building the Proxy type, or problem with loading some dependent class.</exception>
|
||||
public static Proxy CreateProxy<TInterface>(ConsumedCapability cap,
|
||||
public static Proxy CreateProxy<TInterface>(ConsumedCapability? cap,
|
||||
[System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
|
||||
[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
|
||||
[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
|
||||
@ -286,3 +287,4 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,4 +1,5 @@
|
||||
namespace Capnp.Rpc
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
/// State of an RPC connection
|
||||
@ -22,3 +23,4 @@
|
||||
Down
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -2,6 +2,7 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
@ -18,7 +19,7 @@ namespace Capnp.Rpc
|
||||
/// </summary>
|
||||
protected abstract void ReleaseRemotely();
|
||||
internal abstract void Export(IRpcEndpoint endpoint, CapDescriptor.WRITER writer);
|
||||
internal abstract void Freeze(out IRpcEndpoint boundEndpoint);
|
||||
internal abstract void Freeze(out IRpcEndpoint? boundEndpoint);
|
||||
internal abstract void Unfreeze();
|
||||
|
||||
internal abstract void AddRef();
|
||||
@ -31,3 +32,4 @@ namespace Capnp.Rpc
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,6 +1,7 @@
|
||||
using Capnp.FrameTracing;
|
||||
using System;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
@ -58,3 +59,4 @@ namespace Capnp.Rpc
|
||||
void Close();
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,4 +1,5 @@
|
||||
namespace Capnp.Rpc
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
/// A uni-directional endpoint, used in conjunction with the <see cref="RpcEngine"/>.
|
||||
@ -16,3 +17,4 @@
|
||||
void Dismiss();
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,4 +1,5 @@
|
||||
namespace Capnp.Rpc
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
/// A mono skeleton (as opposed to <see cref="PolySkeleton"/>) is a skeleton which implements one particular RPC interface.
|
||||
@ -11,3 +12,4 @@
|
||||
ulong InterfaceId { get; }
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
@ -22,6 +23,7 @@ namespace Capnp.Rpc
|
||||
/// </summary>
|
||||
/// <param name="access">Path to the desired capability inside the result struct.</param>
|
||||
/// <returns>Pipelined low-level capability</returns>
|
||||
ConsumedCapability Access(MemberAccessPath access);
|
||||
ConsumedCapability? Access(MemberAccessPath access);
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -2,6 +2,7 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
|
||||
@ -22,3 +23,4 @@ namespace Capnp.Rpc
|
||||
DeserializerState args, CancellationToken cancellationToken = default);
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,5 +1,6 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
@ -13,3 +14,4 @@ namespace Capnp.Rpc
|
||||
Task<Proxy> WhenResolved { get; }
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
internal interface IRpcEndpoint
|
||||
@ -19,3 +20,4 @@ namespace Capnp.Rpc
|
||||
void DeleteQuestion(PendingQuestion question);
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -3,6 +3,7 @@ using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
@ -11,7 +12,7 @@ namespace Capnp.Rpc
|
||||
public static class Impatient
|
||||
{
|
||||
static readonly ConditionalWeakTable<Task, IPromisedAnswer> _taskTable = new ConditionalWeakTable<Task, IPromisedAnswer>();
|
||||
static readonly ThreadLocal<IRpcEndpoint> _askingEndpoint = new ThreadLocal<IRpcEndpoint>();
|
||||
static readonly ThreadLocal<IRpcEndpoint?> _askingEndpoint = new ThreadLocal<IRpcEndpoint?>();
|
||||
|
||||
/// <summary>
|
||||
/// Attaches a continuation to the given promise and registers the resulting task for pipelining.
|
||||
@ -51,7 +52,7 @@ namespace Capnp.Rpc
|
||||
}
|
||||
else if (rtask.IsFaulted)
|
||||
{
|
||||
rtask = Task.FromException<T>(rtask.Exception.InnerException);
|
||||
rtask = Task.FromException<T>(rtask.Exception!.InnerException!);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -86,7 +87,7 @@ namespace Capnp.Rpc
|
||||
return answer;
|
||||
}
|
||||
|
||||
internal static IPromisedAnswer TryGetAnswer(Task task)
|
||||
internal static IPromisedAnswer? TryGetAnswer(Task task)
|
||||
{
|
||||
_taskTable.TryGetValue(task, out var answer);
|
||||
return answer;
|
||||
@ -102,10 +103,10 @@ namespace Capnp.Rpc
|
||||
return proxy;
|
||||
|
||||
case null:
|
||||
return null;
|
||||
return CapabilityReflection.CreateProxy<T>(null);
|
||||
}
|
||||
|
||||
var skel = Skeleton.GetOrCreateSkeleton(item, false);
|
||||
var skel = Skeleton.GetOrCreateSkeleton(item!, false);
|
||||
var localCap = LocalCapability.Create(skel);
|
||||
return CapabilityReflection.CreateProxy<T>(localCap);
|
||||
}
|
||||
@ -131,7 +132,7 @@ namespace Capnp.Rpc
|
||||
where TInterface : class
|
||||
{
|
||||
var lazyCap = new LazyCapability(AwaitProxy(task));
|
||||
return CapabilityReflection.CreateProxy<TInterface>(lazyCap, memberName, sourceFilePath, sourceLineNumber) as TInterface;
|
||||
return (CapabilityReflection.CreateProxy<TInterface>(lazyCap, memberName, sourceFilePath, sourceLineNumber) as TInterface)!;
|
||||
}
|
||||
|
||||
static readonly MemberAccessPath Path_OneAndOnly = new MemberAccessPath(0U);
|
||||
@ -168,15 +169,15 @@ namespace Capnp.Rpc
|
||||
}
|
||||
|
||||
var lazyCap = new LazyCapability(AwaitProxy(task));
|
||||
return CapabilityReflection.CreateProxy<TInterface>(lazyCap) as TInterface;
|
||||
return (CapabilityReflection.CreateProxy<TInterface>(lazyCap) as TInterface)!;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CapabilityReflection.CreateProxy<TInterface>(answer.Access(Path_OneAndOnly)) as TInterface;
|
||||
return (CapabilityReflection.CreateProxy<TInterface>(answer.Access(Path_OneAndOnly)) as TInterface)!;
|
||||
}
|
||||
}
|
||||
|
||||
internal static IRpcEndpoint AskingEndpoint
|
||||
internal static IRpcEndpoint? AskingEndpoint
|
||||
{
|
||||
get => _askingEndpoint.Value;
|
||||
set { _askingEndpoint.Value = value; }
|
||||
@ -252,3 +253,4 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,5 +1,6 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
@ -52,3 +53,4 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -5,6 +5,7 @@ using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc.Interception
|
||||
{
|
||||
|
||||
@ -34,7 +35,7 @@ namespace Capnp.Rpc.Interception
|
||||
return new Proxy(Access(access));
|
||||
}
|
||||
|
||||
public ConsumedCapability Access(MemberAccessPath access)
|
||||
public ConsumedCapability? Access(MemberAccessPath access)
|
||||
{
|
||||
if (_futureResult.Task.IsCompleted)
|
||||
{
|
||||
@ -44,7 +45,7 @@ namespace Capnp.Rpc.Interception
|
||||
}
|
||||
catch (AggregateException exception)
|
||||
{
|
||||
throw exception.InnerException;
|
||||
throw exception.InnerException!;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -107,7 +108,7 @@ namespace Capnp.Rpc.Interception
|
||||
/// <summary>
|
||||
/// Input arguments
|
||||
/// </summary>
|
||||
public SerializerState InArgs { get; set; }
|
||||
public SerializerState? InArgs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Output arguments ("return value")
|
||||
@ -117,7 +118,7 @@ namespace Capnp.Rpc.Interception
|
||||
/// <summary>
|
||||
/// Exception text, or null if there is no exception
|
||||
/// </summary>
|
||||
public string Exception { get; set; }
|
||||
public string? Exception { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the call should return in canceled state to Alice (the original caller).
|
||||
@ -156,7 +157,7 @@ namespace Capnp.Rpc.Interception
|
||||
/// <item><description>null</description></item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public object Bob
|
||||
public object? Bob
|
||||
{
|
||||
get => _bob;
|
||||
set
|
||||
@ -196,11 +197,11 @@ namespace Capnp.Rpc.Interception
|
||||
}
|
||||
}
|
||||
|
||||
internal Proxy BobProxy { get; private set; }
|
||||
internal Proxy? BobProxy { get; private set; }
|
||||
|
||||
readonly CensorCapability _censorCapability;
|
||||
PromisedAnswer _promisedAnswer;
|
||||
object _bob;
|
||||
object? _bob;
|
||||
|
||||
internal IPromisedAnswer Answer => _promisedAnswer;
|
||||
|
||||
@ -224,8 +225,13 @@ namespace Capnp.Rpc.Interception
|
||||
{
|
||||
for (int i = 0; i < state.Caps.Count; i++)
|
||||
{
|
||||
state.Caps[i] = policy.Attach(state.Caps[i]);
|
||||
state.Caps[i].AddRef();
|
||||
var cap = state.Caps[i];
|
||||
if (cap != null)
|
||||
{
|
||||
cap = policy.Attach(cap);
|
||||
state.Caps[i] = cap;
|
||||
cap.AddRef();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -236,8 +242,13 @@ namespace Capnp.Rpc.Interception
|
||||
{
|
||||
for (int i = 0; i < state.Caps.Count; i++)
|
||||
{
|
||||
state.Caps[i] = policy.Detach(state.Caps[i]);
|
||||
state.Caps[i].AddRef();
|
||||
var cap = state.Caps[i];
|
||||
if (cap != null)
|
||||
{
|
||||
cap = policy.Detach(cap);
|
||||
state.Caps[i] = cap;
|
||||
cap.AddRef();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -246,8 +257,12 @@ namespace Capnp.Rpc.Interception
|
||||
/// Intercepts all capabilies inside the input arguments
|
||||
/// </summary>
|
||||
/// <param name="policyOverride">Policy to use, or null to further use present policy</param>
|
||||
public void InterceptInCaps(IInterceptionPolicy policyOverride = null)
|
||||
/// <exception cref="InvalidOperationException">InArgs not set</exception>
|
||||
public void InterceptInCaps(IInterceptionPolicy? policyOverride = null)
|
||||
{
|
||||
if (InArgs == null)
|
||||
throw new InvalidOperationException("InArgs not set");
|
||||
|
||||
InterceptCaps(InArgs, policyOverride ?? _censorCapability.Policy);
|
||||
}
|
||||
|
||||
@ -255,7 +270,7 @@ namespace Capnp.Rpc.Interception
|
||||
/// Intercepts all capabilies inside the output arguments
|
||||
/// </summary>
|
||||
/// <param name="policyOverride">Policy to use, or null to further use present policy</param>
|
||||
public void InterceptOutCaps(IInterceptionPolicy policyOverride = null)
|
||||
public void InterceptOutCaps(IInterceptionPolicy? policyOverride = null)
|
||||
{
|
||||
InterceptCaps(OutArgs, policyOverride ?? _censorCapability.Policy);
|
||||
}
|
||||
@ -264,8 +279,12 @@ namespace Capnp.Rpc.Interception
|
||||
/// Unintercepts all capabilies inside the input arguments
|
||||
/// </summary>
|
||||
/// <param name="policyOverride">Policy to remove, or null to remove present policy</param>
|
||||
public void UninterceptInCaps(IInterceptionPolicy policyOverride = null)
|
||||
/// <exception cref="InvalidOperationException">InArgs not set</exception>
|
||||
public void UninterceptInCaps(IInterceptionPolicy? policyOverride = null)
|
||||
{
|
||||
if (InArgs == null)
|
||||
throw new InvalidOperationException("InArgs not set");
|
||||
|
||||
UninterceptCaps(InArgs, policyOverride ?? _censorCapability.Policy);
|
||||
}
|
||||
|
||||
@ -273,7 +292,7 @@ namespace Capnp.Rpc.Interception
|
||||
/// Unintercepts all capabilies inside the output arguments
|
||||
/// </summary>
|
||||
/// <param name="policyOverride">Policy to remove, or null to remove present policy</param>
|
||||
public void UninterceptOutCaps(IInterceptionPolicy policyOverride = null)
|
||||
public void UninterceptOutCaps(IInterceptionPolicy? policyOverride = null)
|
||||
{
|
||||
UninterceptCaps(OutArgs, policyOverride ?? _censorCapability.Policy);
|
||||
}
|
||||
@ -281,14 +300,16 @@ namespace Capnp.Rpc.Interception
|
||||
/// <summary>
|
||||
/// Forwards this intercepted call to the target capability ("Bob").
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">Bob/InArgs not set</exception>
|
||||
public void ForwardToBob()
|
||||
{
|
||||
if (Bob == null)
|
||||
{
|
||||
throw new InvalidOperationException("Bob is null");
|
||||
}
|
||||
|
||||
var answer = BobProxy.Call(InterfaceId, MethodId, InArgs.Rewrap<DynamicSerializerState>(), default, CancelToBob);
|
||||
|
||||
if (InArgs == null)
|
||||
throw new InvalidOperationException("InArgs not set");
|
||||
|
||||
var answer = BobProxy!.Call(InterfaceId, MethodId, InArgs.Rewrap<DynamicSerializerState>(), default, CancelToBob);
|
||||
|
||||
State = InterceptionState.ForwardedToBob;
|
||||
|
||||
@ -336,3 +357,4 @@ namespace Capnp.Rpc.Interception
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,4 +1,5 @@
|
||||
namespace Capnp.Rpc.Interception
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc.Interception
|
||||
{
|
||||
class CensorCapability : RefCountingCapability
|
||||
{
|
||||
@ -32,7 +33,7 @@
|
||||
writer.SenderHosted = endpoint.AllocateExport(MyVine, out bool _);
|
||||
}
|
||||
|
||||
internal override void Freeze(out IRpcEndpoint boundEndpoint)
|
||||
internal override void Freeze(out IRpcEndpoint? boundEndpoint)
|
||||
{
|
||||
boundEndpoint = null;
|
||||
}
|
||||
@ -42,3 +43,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc.Interception
|
||||
{
|
||||
/// <summary>
|
||||
@ -21,3 +22,4 @@ namespace Capnp.Rpc.Interception
|
||||
void OnReturnFromBob(CallContext callContext);
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,4 +1,5 @@
|
||||
namespace Capnp.Rpc.Interception
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc.Interception
|
||||
{
|
||||
/// <summary>
|
||||
/// The state of an intercepted call from Alice to Bob.
|
||||
@ -26,3 +27,4 @@
|
||||
ReturnedToAlice
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc.Interception
|
||||
{
|
||||
/// <summary>
|
||||
@ -45,16 +46,16 @@ namespace Capnp.Rpc.Interception
|
||||
switch (cap)
|
||||
{
|
||||
case Proxy proxy:
|
||||
return CapabilityReflection.CreateProxy<TCap>(Attach(policy, proxy.ConsumedCap)) as TCap;
|
||||
return (CapabilityReflection.CreateProxy<TCap>(Attach(policy, proxy.ConsumedCap!)) as TCap)!;
|
||||
|
||||
case ConsumedCapability ccap:
|
||||
return new CensorCapability(ccap, policy) as TCap;
|
||||
return (new CensorCapability(ccap, policy) as TCap)!;
|
||||
|
||||
default:
|
||||
return Attach(policy,
|
||||
CapabilityReflection.CreateProxy<TCap>(
|
||||
return (Attach(policy,
|
||||
(CapabilityReflection.CreateProxy<TCap>(
|
||||
LocalCapability.Create(
|
||||
Skeleton.GetOrCreateSkeleton(cap, false))) as TCap);
|
||||
Skeleton.GetOrCreateSkeleton(cap, false))) as TCap)!));
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,11 +80,11 @@ namespace Capnp.Rpc.Interception
|
||||
switch (cap)
|
||||
{
|
||||
case Proxy proxy:
|
||||
return CapabilityReflection.CreateProxy<TCap>(Detach(policy, proxy.ConsumedCap)) as TCap;
|
||||
return (CapabilityReflection.CreateProxy<TCap>(Detach(policy, proxy.ConsumedCap!)) as TCap)!;
|
||||
|
||||
case CensorCapability ccap:
|
||||
{
|
||||
var cur = ccap;
|
||||
CensorCapability? cur = ccap;
|
||||
var stk = new Stack<IInterceptionPolicy>();
|
||||
|
||||
do
|
||||
@ -96,7 +97,7 @@ namespace Capnp.Rpc.Interception
|
||||
{
|
||||
cur2 = p.Attach(cur2);
|
||||
}
|
||||
return cur2 as TCap;
|
||||
return (cur2 as TCap)!;
|
||||
}
|
||||
|
||||
stk.Push(cur.Policy);
|
||||
@ -104,7 +105,7 @@ namespace Capnp.Rpc.Interception
|
||||
}
|
||||
while (cur != null);
|
||||
|
||||
return ccap as TCap;
|
||||
return (ccap as TCap)!;
|
||||
}
|
||||
|
||||
default:
|
||||
@ -113,3 +114,4 @@ namespace Capnp.Rpc.Interception
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,4 +1,5 @@
|
||||
namespace Capnp.Rpc
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
/// Will be thrown if a type did not qualify as capability interface.
|
||||
@ -22,3 +23,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -2,6 +2,7 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
class LazyCapability : RefCountingCapability, IResolvingCapability
|
||||
@ -27,7 +28,7 @@ namespace Capnp.Rpc
|
||||
WhenResolved = capabilityTask;
|
||||
}
|
||||
|
||||
internal override void Freeze(out IRpcEndpoint boundEndpoint)
|
||||
internal override void Freeze(out IRpcEndpoint? boundEndpoint)
|
||||
{
|
||||
if (WhenResolved.IsCompleted)
|
||||
{
|
||||
@ -37,7 +38,7 @@ namespace Capnp.Rpc
|
||||
}
|
||||
catch (AggregateException exception)
|
||||
{
|
||||
throw exception.InnerException;
|
||||
throw exception.InnerException!;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -106,3 +107,4 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -2,6 +2,7 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
class LocalAnswer : IPromisedAnswer
|
||||
@ -50,3 +51,4 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -2,6 +2,7 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
class LocalAnswerCapability : RefCountingCapability, IResolvingCapability
|
||||
@ -15,7 +16,7 @@ namespace Capnp.Rpc
|
||||
_access = access;
|
||||
}
|
||||
|
||||
internal override void Freeze(out IRpcEndpoint boundEndpoint)
|
||||
internal override void Freeze(out IRpcEndpoint? boundEndpoint)
|
||||
{
|
||||
boundEndpoint = null;
|
||||
}
|
||||
@ -43,7 +44,7 @@ namespace Capnp.Rpc
|
||||
}
|
||||
catch (AggregateException exception)
|
||||
{
|
||||
throw exception.InnerException;
|
||||
throw exception.InnerException!;
|
||||
}
|
||||
|
||||
using (var proxy = new Proxy(_access.Eval(result)))
|
||||
@ -87,3 +88,4 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -4,6 +4,7 @@ using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
class LocalCapability : ConsumedCapability
|
||||
@ -14,7 +15,7 @@ namespace Capnp.Rpc
|
||||
public static ConsumedCapability Create(Skeleton skeleton)
|
||||
{
|
||||
if (skeleton is Vine vine)
|
||||
return vine.Proxy.ConsumedCap;
|
||||
return vine.Proxy.ConsumedCap!;
|
||||
else
|
||||
return _localCaps.GetValue(skeleton, _ => new LocalCapability(_));
|
||||
}
|
||||
@ -22,7 +23,7 @@ namespace Capnp.Rpc
|
||||
static async Task<DeserializerState> AwaitAnswer(Task<AnswerOrCounterquestion> call)
|
||||
{
|
||||
var aorcq = await call;
|
||||
return aorcq.Answer ?? await aorcq.Counterquestion.WhenReturned;
|
||||
return aorcq.Answer ?? await aorcq.Counterquestion!.WhenReturned;
|
||||
}
|
||||
|
||||
public Skeleton ProvidedCap { get; }
|
||||
@ -55,7 +56,7 @@ namespace Capnp.Rpc
|
||||
capDesc.SenderHosted = endpoint.AllocateExport(ProvidedCap, out bool _);
|
||||
}
|
||||
|
||||
internal override void Freeze(out IRpcEndpoint boundEndpoint)
|
||||
internal override void Freeze(out IRpcEndpoint? boundEndpoint)
|
||||
{
|
||||
boundEndpoint = null;
|
||||
}
|
||||
@ -69,3 +70,4 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
@ -169,7 +170,7 @@ namespace Capnp.Rpc
|
||||
/// <param name="rpcState">The object (usually "params struct") on which to evaluate this path.</param>
|
||||
/// <returns>Resulting low-level capability</returns>
|
||||
/// <exception cref="DeserializationException">Evaluation of this path did not give a capability</exception>
|
||||
public ConsumedCapability Eval(DeserializerState rpcState)
|
||||
public ConsumedCapability? Eval(DeserializerState rpcState)
|
||||
{
|
||||
var cur = rpcState;
|
||||
|
||||
@ -184,7 +185,7 @@ namespace Capnp.Rpc
|
||||
return null;
|
||||
|
||||
case ObjectKind.Capability:
|
||||
return rpcState.Caps[(int)cur.CapabilityIndex];
|
||||
return rpcState.Caps![(int)cur.CapabilityIndex];
|
||||
|
||||
default:
|
||||
throw new DeserializationException("Access path did not result in a capability");
|
||||
@ -192,3 +193,4 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -3,19 +3,20 @@ using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
class PendingAnswer: IDisposable
|
||||
{
|
||||
readonly object _reentrancyBlocker = new object();
|
||||
readonly CancellationTokenSource _cts;
|
||||
readonly CancellationTokenSource? _cts;
|
||||
readonly TaskCompletionSource<int> _whenCanceled;
|
||||
Task<AnswerOrCounterquestion> _callTask;
|
||||
Task _initialTask;
|
||||
Task _chainedTask;
|
||||
Task? _initialTask;
|
||||
Task? _chainedTask;
|
||||
bool _disposed;
|
||||
|
||||
public PendingAnswer(Task<AnswerOrCounterquestion> callTask, CancellationTokenSource cts)
|
||||
public PendingAnswer(Task<AnswerOrCounterquestion> callTask, CancellationTokenSource? cts)
|
||||
{
|
||||
_cts = cts;
|
||||
_callTask = callTask ?? throw new ArgumentNullException(nameof(callTask));
|
||||
@ -138,7 +139,7 @@ namespace Capnp.Rpc
|
||||
case ObjectKind.Capability:
|
||||
try
|
||||
{
|
||||
var cap = aorcq.Answer.Caps[(int)cur.CapabilityIndex];
|
||||
var cap = aorcq.Answer.Caps![(int)cur.CapabilityIndex];
|
||||
proxy = new Proxy(cap ?? LazyCapability.Null);
|
||||
}
|
||||
catch (ArgumentOutOfRangeException)
|
||||
@ -154,7 +155,7 @@ namespace Capnp.Rpc
|
||||
else
|
||||
{
|
||||
var path = MemberAccessPath.Deserialize(rd);
|
||||
var cap = new RemoteAnswerCapability(aorcq.Counterquestion, path);
|
||||
var cap = new RemoteAnswerCapability(aorcq.Counterquestion!, path);
|
||||
return new Proxy(cap);
|
||||
}
|
||||
}
|
||||
@ -169,7 +170,7 @@ namespace Capnp.Rpc
|
||||
{
|
||||
if (_cts != null)
|
||||
{
|
||||
Task chainedTask;
|
||||
Task? chainedTask;
|
||||
|
||||
lock (_reentrancyBlocker)
|
||||
{
|
||||
@ -199,3 +200,4 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -4,6 +4,7 @@ using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
@ -61,11 +62,11 @@ namespace Capnp.Rpc
|
||||
|
||||
readonly TaskCompletionSource<DeserializerState> _tcs = new TaskCompletionSource<DeserializerState>();
|
||||
readonly uint _questionId;
|
||||
ConsumedCapability _target;
|
||||
SerializerState _inParams;
|
||||
ConsumedCapability? _target;
|
||||
SerializerState? _inParams;
|
||||
int _inhibitFinishCounter;
|
||||
|
||||
internal PendingQuestion(IRpcEndpoint ep, uint id, ConsumedCapability target, SerializerState inParams)
|
||||
internal PendingQuestion(IRpcEndpoint ep, uint id, ConsumedCapability? target, SerializerState? inParams)
|
||||
{
|
||||
RpcEndpoint = ep ?? throw new ArgumentNullException(nameof(ep));
|
||||
_questionId = id;
|
||||
@ -75,7 +76,7 @@ namespace Capnp.Rpc
|
||||
|
||||
if (inParams != null)
|
||||
{
|
||||
foreach (var cap in inParams.Caps)
|
||||
foreach (var cap in inParams.Caps!)
|
||||
{
|
||||
cap?.AddRef();
|
||||
}
|
||||
@ -236,7 +237,7 @@ namespace Capnp.Rpc
|
||||
/// <param name="access">Access path</param>
|
||||
/// <returns>Low-level capability</returns>
|
||||
/// <exception cref="DeserializationException">The referenced member does not exist or does not resolve to a capability pointer.</exception>
|
||||
public ConsumedCapability Access(MemberAccessPath access)
|
||||
public ConsumedCapability? Access(MemberAccessPath access)
|
||||
{
|
||||
lock (ReentrancyBlocker)
|
||||
{
|
||||
@ -249,7 +250,7 @@ namespace Capnp.Rpc
|
||||
}
|
||||
catch (AggregateException exception)
|
||||
{
|
||||
throw exception.InnerException;
|
||||
throw exception.InnerException!;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -259,11 +260,11 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
|
||||
static void ReleaseCaps(ConsumedCapability target, SerializerState inParams)
|
||||
static void ReleaseCaps(ConsumedCapability? target, SerializerState? inParams)
|
||||
{
|
||||
if (inParams != null)
|
||||
{
|
||||
foreach (var cap in inParams.Caps)
|
||||
foreach (var cap in inParams.Caps!)
|
||||
{
|
||||
cap?.Release();
|
||||
}
|
||||
@ -277,7 +278,7 @@ namespace Capnp.Rpc
|
||||
|
||||
static void ReleaseOutCaps(DeserializerState outParams)
|
||||
{
|
||||
foreach (var cap in outParams.Caps)
|
||||
foreach (var cap in outParams.Caps!)
|
||||
{
|
||||
cap?.Release();
|
||||
}
|
||||
@ -285,12 +286,13 @@ namespace Capnp.Rpc
|
||||
|
||||
internal void Send()
|
||||
{
|
||||
SerializerState inParams;
|
||||
ConsumedCapability target;
|
||||
SerializerState? inParams;
|
||||
ConsumedCapability? target;
|
||||
|
||||
lock (ReentrancyBlocker)
|
||||
{
|
||||
Debug.Assert(!StateFlags.HasFlag(State.Sent));
|
||||
if (StateFlags.HasFlag(State.Sent))
|
||||
throw new InvalidOperationException("Already sent");
|
||||
|
||||
inParams = _inParams;
|
||||
_inParams = null;
|
||||
@ -299,7 +301,7 @@ namespace Capnp.Rpc
|
||||
StateFlags |= State.Sent;
|
||||
}
|
||||
|
||||
var msg = (Message.WRITER)inParams.MsgBuilder.Root;
|
||||
var msg = (Message.WRITER)inParams!.MsgBuilder!.Root!;
|
||||
Debug.Assert(msg.Call.Target.which != MessageTarget.WHICH.undefined);
|
||||
var call = msg.Call;
|
||||
call.QuestionId = QuestionId;
|
||||
@ -316,15 +318,15 @@ namespace Capnp.Rpc
|
||||
OnException(exception);
|
||||
}
|
||||
|
||||
ReleaseCaps(target, inParams);
|
||||
ReleaseCaps(target!, inParams);
|
||||
}
|
||||
|
||||
#region IDisposable Support
|
||||
|
||||
void Dispose(bool disposing)
|
||||
{
|
||||
SerializerState inParams;
|
||||
ConsumedCapability target;
|
||||
SerializerState? inParams;
|
||||
ConsumedCapability? target;
|
||||
bool justDisposed = false;
|
||||
|
||||
lock (ReentrancyBlocker)
|
||||
@ -377,3 +379,4 @@ namespace Capnp.Rpc
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
@ -71,3 +72,4 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -3,6 +3,7 @@ using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
class PromisedCapability : RemoteResolvingCapability
|
||||
@ -19,7 +20,7 @@ namespace Capnp.Rpc
|
||||
|
||||
public override Task<Proxy> WhenResolved => _resolvedCap.Task;
|
||||
|
||||
internal override void Freeze(out IRpcEndpoint boundEndpoint)
|
||||
internal override void Freeze(out IRpcEndpoint? boundEndpoint)
|
||||
{
|
||||
lock (_reentrancyBlocker)
|
||||
{
|
||||
@ -31,7 +32,7 @@ namespace Capnp.Rpc
|
||||
}
|
||||
catch (AggregateException exception)
|
||||
{
|
||||
throw exception.InnerException;
|
||||
throw exception.InnerException!;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -148,7 +149,7 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
|
||||
protected override Proxy ResolvedCap
|
||||
protected override Proxy? ResolvedCap
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -158,7 +159,7 @@ namespace Capnp.Rpc
|
||||
}
|
||||
catch (AggregateException exception)
|
||||
{
|
||||
throw exception.InnerException;
|
||||
throw exception.InnerException!;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -258,3 +259,4 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -3,6 +3,7 @@ using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
@ -38,7 +39,7 @@ namespace Capnp.Rpc
|
||||
/// <summary>
|
||||
/// Underlying low-level capability
|
||||
/// </summary>
|
||||
protected internal ConsumedCapability ConsumedCap { get; private set; }
|
||||
protected internal ConsumedCapability? ConsumedCap { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether is this a broken capability.
|
||||
@ -99,12 +100,12 @@ namespace Capnp.Rpc
|
||||
{
|
||||
}
|
||||
|
||||
internal Proxy(ConsumedCapability cap)
|
||||
internal Proxy(ConsumedCapability? cap)
|
||||
{
|
||||
Bind(cap);
|
||||
}
|
||||
|
||||
internal void Bind(ConsumedCapability cap)
|
||||
internal void Bind(ConsumedCapability? cap)
|
||||
{
|
||||
if (ConsumedCap != null)
|
||||
throw new InvalidOperationException("Proxy was already bound");
|
||||
@ -116,7 +117,7 @@ namespace Capnp.Rpc
|
||||
cap.AddRef();
|
||||
}
|
||||
|
||||
internal IProvidedCapability GetProvider()
|
||||
internal IProvidedCapability? GetProvider()
|
||||
{
|
||||
switch (ConsumedCap)
|
||||
{
|
||||
@ -200,7 +201,7 @@ namespace Capnp.Rpc
|
||||
|
||||
using (disposeThis ? this : null)
|
||||
{
|
||||
return CapabilityReflection.CreateProxy<T>(ConsumedCap) as T;
|
||||
return (CapabilityReflection.CreateProxy<T>(ConsumedCap) as T)!;
|
||||
}
|
||||
}
|
||||
|
||||
@ -215,7 +216,7 @@ namespace Capnp.Rpc
|
||||
ConsumedCap.Export(endpoint, writer);
|
||||
}
|
||||
|
||||
internal void Freeze(out IRpcEndpoint boundEndpoint)
|
||||
internal void Freeze(out IRpcEndpoint? boundEndpoint)
|
||||
{
|
||||
if (_disposedValue)
|
||||
throw new ObjectDisposedException(nameof(Proxy));
|
||||
@ -239,3 +240,4 @@ namespace Capnp.Rpc
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
@ -28,3 +29,4 @@ namespace Capnp.Rpc
|
||||
public Type ProxyClass { get; }
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -2,6 +2,7 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
abstract class RefCountingCapability: ConsumedCapability
|
||||
@ -112,3 +113,4 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -3,6 +3,7 @@ using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
class RemoteAnswerCapability : RemoteResolvingCapability
|
||||
@ -18,7 +19,7 @@ namespace Capnp.Rpc
|
||||
|
||||
readonly PendingQuestion _question;
|
||||
readonly MemberAccessPath _access;
|
||||
Proxy _resolvedCap;
|
||||
Proxy? _resolvedCap;
|
||||
|
||||
public RemoteAnswerCapability(PendingQuestion question, MemberAccessPath access): base(question.RpcEndpoint)
|
||||
{
|
||||
@ -59,7 +60,7 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
|
||||
protected override Proxy ResolvedCap
|
||||
protected override Proxy? ResolvedCap
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -74,7 +75,7 @@ namespace Capnp.Rpc
|
||||
}
|
||||
catch (AggregateException exception)
|
||||
{
|
||||
throw exception.InnerException;
|
||||
throw exception.InnerException!;
|
||||
}
|
||||
|
||||
_resolvedCap = new Proxy(_access.Eval(result));
|
||||
@ -87,7 +88,11 @@ namespace Capnp.Rpc
|
||||
async Task<Proxy> AwaitWhenResolved()
|
||||
{
|
||||
await _question.WhenReturned;
|
||||
return ResolvedCap;
|
||||
|
||||
if (_question.IsTailCall)
|
||||
throw new InvalidOperationException("Question is a tail call, so won't resolve back.");
|
||||
|
||||
return ResolvedCap!;
|
||||
}
|
||||
|
||||
public override Task<Proxy> WhenResolved => AwaitWhenResolved();
|
||||
@ -168,7 +173,7 @@ namespace Capnp.Rpc
|
||||
return call;
|
||||
}
|
||||
|
||||
internal override void Freeze(out IRpcEndpoint boundEndpoint)
|
||||
internal override void Freeze(out IRpcEndpoint? boundEndpoint)
|
||||
{
|
||||
lock (_question.ReentrancyBlocker)
|
||||
{
|
||||
@ -216,7 +221,7 @@ namespace Capnp.Rpc
|
||||
|
||||
if (_question.StateFlags.HasFlag(PendingQuestion.State.Returned))
|
||||
{
|
||||
ResolvedCap.Export(endpoint, writer);
|
||||
ResolvedCap?.Export(endpoint, writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -255,3 +260,4 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -3,6 +3,7 @@ using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
|
||||
@ -24,6 +25,9 @@ namespace Capnp.Rpc
|
||||
|
||||
protected virtual Call.WRITER SetupMessage(DynamicSerializerState args, ulong interfaceId, ushort methodId)
|
||||
{
|
||||
if (args.MsgBuilder == null)
|
||||
throw new ArgumentException("Unbound serializer state", nameof(args));
|
||||
|
||||
var callMsg = args.MsgBuilder.BuildRoot<Message.WRITER>();
|
||||
|
||||
callMsg.which = Message.WHICH.Call;
|
||||
@ -38,3 +42,4 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -3,6 +3,7 @@ using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
abstract class RemoteResolvingCapability : RemoteCapability, IResolvingCapability
|
||||
@ -23,14 +24,17 @@ namespace Capnp.Rpc
|
||||
}
|
||||
|
||||
protected int _pendingCallsOnPromise;
|
||||
Task _disembargo;
|
||||
Task? _disembargo;
|
||||
|
||||
protected abstract Proxy ResolvedCap { get; }
|
||||
protected abstract Proxy? ResolvedCap { get; }
|
||||
|
||||
protected abstract void GetMessageTarget(MessageTarget.WRITER wr);
|
||||
|
||||
protected IPromisedAnswer CallOnResolution(ulong interfaceId, ushort methodId, DynamicSerializerState args)
|
||||
{
|
||||
if (ResolvedCap == null)
|
||||
throw new InvalidOperationException("Capability not yet resolved, calling on resolution not possible");
|
||||
|
||||
try
|
||||
{
|
||||
ResolvedCap.Freeze(out var resolvedCapEndpoint);
|
||||
@ -124,3 +128,4 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,4 +1,5 @@
|
||||
namespace Capnp.Rpc
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
static class ResolvingCapabilityExtensions
|
||||
{
|
||||
@ -19,7 +20,7 @@
|
||||
{
|
||||
var resolvedCap = await cap.WhenResolved;
|
||||
|
||||
endpoint.Resolve(preliminaryId, vine, () => resolvedCap.ConsumedCap);
|
||||
endpoint.Resolve(preliminaryId, vine, () => resolvedCap.ConsumedCap!);
|
||||
}
|
||||
catch (System.Exception exception)
|
||||
{
|
||||
@ -42,3 +43,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -10,6 +10,7 @@ using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
@ -65,8 +66,8 @@ namespace Capnp.Rpc
|
||||
|
||||
internal class RpcEndpoint : IEndpoint, IRpcEndpoint
|
||||
{
|
||||
static readonly ThreadLocal<Action> _exportCapTablePostActions = new ThreadLocal<Action>();
|
||||
static readonly ThreadLocal<PendingQuestion> _tailCall = new ThreadLocal<PendingQuestion>();
|
||||
static readonly ThreadLocal<Action?> _exportCapTablePostActions = new ThreadLocal<Action?>();
|
||||
static readonly ThreadLocal<PendingQuestion?> _tailCall = new ThreadLocal<PendingQuestion?>();
|
||||
static readonly ThreadLocal<bool> _canDeferCalls = new ThreadLocal<bool>();
|
||||
|
||||
ILogger Logger { get; } = Logging.CreateLogger<RpcEndpoint>();
|
||||
@ -145,8 +146,7 @@ namespace Capnp.Rpc
|
||||
Tx(mb.Frame);
|
||||
}
|
||||
|
||||
void IRpcEndpoint.Resolve(uint preliminaryId, Skeleton preliminaryCap,
|
||||
Func<ConsumedCapability> resolvedCapGetter)
|
||||
void IRpcEndpoint.Resolve(uint preliminaryId, Skeleton preliminaryCap, Func<ConsumedCapability> resolvedCapGetter)
|
||||
{
|
||||
lock (_reentrancyBlocker)
|
||||
{
|
||||
@ -232,7 +232,7 @@ namespace Capnp.Rpc
|
||||
return AllocateExport(providedCapability, out first);
|
||||
}
|
||||
|
||||
PendingQuestion AllocateQuestion(ConsumedCapability target, SerializerState inParams)
|
||||
PendingQuestion AllocateQuestion(ConsumedCapability? target, SerializerState? inParams)
|
||||
{
|
||||
lock (_reentrancyBlocker)
|
||||
{
|
||||
@ -293,7 +293,7 @@ namespace Capnp.Rpc
|
||||
uint q = req.QuestionId;
|
||||
|
||||
var bootstrap = DynamicSerializerState.CreateForRpc();
|
||||
var ans = bootstrap.MsgBuilder.BuildRoot<Message.WRITER>();
|
||||
var ans = bootstrap.MsgBuilder!.BuildRoot<Message.WRITER>();
|
||||
|
||||
ans.which = Message.WHICH.Return;
|
||||
var ret = ans.Return;
|
||||
@ -305,7 +305,7 @@ namespace Capnp.Rpc
|
||||
if (bootstrapCap != null)
|
||||
{
|
||||
ret.which = Return.WHICH.Results;
|
||||
bootstrap.SetCapability(bootstrap.ProvideCapability(LocalCapability.Create(_host.BootstrapCap)));
|
||||
bootstrap.SetCapability(bootstrap.ProvideCapability(LocalCapability.Create(bootstrapCap)));
|
||||
ret.Results.Content = bootstrap;
|
||||
|
||||
bootstrapTask = Task.FromResult<AnswerOrCounterquestion>(bootstrap);
|
||||
@ -371,12 +371,12 @@ namespace Capnp.Rpc
|
||||
}
|
||||
catch (RpcException exception)
|
||||
{
|
||||
Logger.LogWarning($"Unable to return call: {exception.InnerException.Message}");
|
||||
Logger.LogWarning($"Unable to return call: {exception.InnerException?.Message ?? exception.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
IProvidedCapability cap;
|
||||
PendingAnswer pendingAnswer = null;
|
||||
IProvidedCapability? cap;
|
||||
PendingAnswer? pendingAnswer = null;
|
||||
bool releaseParamCaps = false;
|
||||
|
||||
void AwaitAnswerAndReply()
|
||||
@ -414,8 +414,8 @@ namespace Capnp.Rpc
|
||||
}
|
||||
else if (aorcq.Answer != null || aorcq.Counterquestion != _tailCall.Value)
|
||||
{
|
||||
var results = aorcq.Answer ?? (DynamicSerializerState)(await aorcq.Counterquestion.WhenReturned);
|
||||
var ret = SetupReturn(results.MsgBuilder);
|
||||
var results = aorcq.Answer ?? (DynamicSerializerState)(await aorcq.Counterquestion!.WhenReturned);
|
||||
var ret = SetupReturn(results.MsgBuilder!);
|
||||
|
||||
switch (req.SendResultsTo.which)
|
||||
{
|
||||
@ -569,7 +569,7 @@ namespace Capnp.Rpc
|
||||
case MessageTarget.WHICH.PromisedAnswer:
|
||||
{
|
||||
bool exists;
|
||||
PendingAnswer previousAnswer;
|
||||
PendingAnswer? previousAnswer;
|
||||
|
||||
lock (_reentrancyBlocker)
|
||||
{
|
||||
@ -578,7 +578,7 @@ namespace Capnp.Rpc
|
||||
|
||||
if (exists)
|
||||
{
|
||||
previousAnswer.Chain(
|
||||
previousAnswer!.Chain(
|
||||
false,
|
||||
req.Target.PromisedAnswer,
|
||||
async t =>
|
||||
@ -633,7 +633,7 @@ namespace Capnp.Rpc
|
||||
|
||||
void ProcessReturn(Return.READER req)
|
||||
{
|
||||
PendingQuestion question;
|
||||
PendingQuestion? question;
|
||||
|
||||
lock (_reentrancyBlocker)
|
||||
{
|
||||
@ -674,7 +674,7 @@ namespace Capnp.Rpc
|
||||
case Return.WHICH.TakeFromOtherQuestion:
|
||||
{
|
||||
bool exists;
|
||||
PendingAnswer pendingAnswer;
|
||||
PendingAnswer? pendingAnswer;
|
||||
|
||||
lock (_reentrancyBlocker)
|
||||
{
|
||||
@ -683,7 +683,7 @@ namespace Capnp.Rpc
|
||||
|
||||
if (exists)
|
||||
{
|
||||
pendingAnswer.Chain(false, async t =>
|
||||
pendingAnswer!.Chain(false, async t =>
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -747,6 +747,8 @@ namespace Capnp.Rpc
|
||||
lock (_reentrancyBlocker)
|
||||
{
|
||||
var resolvedCap = ImportCap(resolve.Cap);
|
||||
if (resolvedCap == null)
|
||||
resolvedCap = LazyCapability.CreateBrokenCap("Failed to resolve this capability");
|
||||
resolvableCap.ResolveTo(resolvedCap);
|
||||
}
|
||||
break;
|
||||
@ -935,7 +937,7 @@ namespace Capnp.Rpc
|
||||
{
|
||||
foreach (var cap in results.Caps)
|
||||
{
|
||||
cap.Release();
|
||||
cap?.Release();
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -984,8 +986,8 @@ namespace Capnp.Rpc
|
||||
try
|
||||
{
|
||||
int icount = checked((int)count);
|
||||
rc.Release(icount);
|
||||
rc.Cap.Relinquish(icount);
|
||||
rc!.Release(icount);
|
||||
rc!.Cap.Relinquish(icount);
|
||||
|
||||
if (rc.RefCount == 0)
|
||||
{
|
||||
@ -1171,7 +1173,7 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
|
||||
ConsumedCapability ImportCap(CapDescriptor.READER capDesc)
|
||||
ConsumedCapability? ImportCap(CapDescriptor.READER capDesc)
|
||||
{
|
||||
lock (_reentrancyBlocker)
|
||||
{
|
||||
@ -1192,8 +1194,7 @@ namespace Capnp.Rpc
|
||||
rcw.Cap.SetTarget(impCap);
|
||||
}
|
||||
|
||||
Debug.Assert(impCap != null);
|
||||
return impCap;
|
||||
return impCap!;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1236,7 +1237,6 @@ namespace Capnp.Rpc
|
||||
case CapDescriptor.WHICH.ReceiverHosted:
|
||||
if (_exportTable.TryGetValue(capDesc.ReceiverHosted, out var rc))
|
||||
{
|
||||
Debug.Assert(rc.Cap != null);
|
||||
return LocalCapability.Create(rc.Cap);
|
||||
}
|
||||
else
|
||||
@ -1311,9 +1311,9 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
|
||||
public IList<ConsumedCapability> ImportCapTable(Payload.READER payload)
|
||||
public IList<ConsumedCapability?> ImportCapTable(Payload.READER payload)
|
||||
{
|
||||
var list = new List<ConsumedCapability>();
|
||||
var list = new List<ConsumedCapability?>();
|
||||
|
||||
if (payload.CapTable != null)
|
||||
{
|
||||
@ -1341,7 +1341,7 @@ namespace Capnp.Rpc
|
||||
Debug.Assert(_exportCapTablePostActions.Value == null);
|
||||
_exportCapTablePostActions.Value = null;
|
||||
|
||||
payload.CapTable.Init(state.MsgBuilder.Caps.Count);
|
||||
payload.CapTable.Init(state.MsgBuilder!.Caps!.Count);
|
||||
|
||||
int i = 0;
|
||||
foreach (var cap in state.MsgBuilder.Caps)
|
||||
@ -1454,7 +1454,7 @@ namespace Capnp.Rpc
|
||||
}
|
||||
catch (RpcException exception)
|
||||
{
|
||||
Logger.LogWarning($"Unable to release import: {exception.InnerException.Message}");
|
||||
Logger.LogWarning($"Unable to release import: {exception.InnerException?.Message ?? exception.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1492,12 +1492,12 @@ namespace Capnp.Rpc
|
||||
return inboundEndpoint;
|
||||
}
|
||||
|
||||
Skeleton _bootstrapCap;
|
||||
Skeleton? _bootstrapCap;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the bootstrap capability.
|
||||
/// </summary>
|
||||
public Skeleton BootstrapCap
|
||||
public Skeleton? BootstrapCap
|
||||
{
|
||||
get => _bootstrapCap;
|
||||
set
|
||||
@ -1509,3 +1509,4 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,4 +1,5 @@
|
||||
namespace Capnp.Rpc
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
/// Thrown when an RPC-related error condition occurs.
|
||||
@ -20,3 +21,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,6 +1,8 @@
|
||||
namespace Capnp.Rpc
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
class RpcUnimplementedException : System.Exception
|
||||
{
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -6,6 +6,7 @@ using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
@ -179,8 +180,8 @@ namespace Capnp.Rpc
|
||||
ILogger Logger { get; } = Logging.CreateLogger<Skeleton<T>>();
|
||||
#endif
|
||||
|
||||
Func<DeserializerState, CancellationToken, Task<AnswerOrCounterquestion>>[] _methods;
|
||||
CancellationTokenSource _disposed = new CancellationTokenSource();
|
||||
Func<DeserializerState, CancellationToken, Task<AnswerOrCounterquestion>>[] _methods = null!;
|
||||
CancellationTokenSource? _disposed = new CancellationTokenSource();
|
||||
readonly object _reentrancyBlocker = new object();
|
||||
int _pendingCalls;
|
||||
|
||||
@ -204,7 +205,7 @@ namespace Capnp.Rpc
|
||||
/// <summary>
|
||||
/// Gets the underlying capability implementation.
|
||||
/// </summary>
|
||||
protected T Impl { get; private set; }
|
||||
protected T Impl { get; private set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the implemented interface.
|
||||
@ -299,3 +300,4 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
@ -32,3 +33,4 @@ namespace Capnp.Rpc
|
||||
public Type SkeletonClass { get; }
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -10,6 +10,7 @@ using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
@ -44,17 +45,17 @@ namespace Capnp.Rpc
|
||||
|
||||
readonly RpcEngine _rpcEngine;
|
||||
readonly TcpClient _client;
|
||||
RpcEngine.RpcEndpoint _inboundEndpoint;
|
||||
OutboundTcpEndpoint _outboundEndpoint;
|
||||
FramePump _pump;
|
||||
Thread _pumpThread;
|
||||
Action _attachTracerAction;
|
||||
RpcEngine.RpcEndpoint? _inboundEndpoint;
|
||||
OutboundTcpEndpoint? _outboundEndpoint;
|
||||
FramePump? _pump;
|
||||
Thread? _pumpThread;
|
||||
Action? _attachTracerAction;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a Task which completes when TCP is connected. Will be
|
||||
/// null until connection is actually requested (either by calling Connect or using appropriate constructor).
|
||||
/// </summary>
|
||||
public Task WhenConnected { get; private set; }
|
||||
public Task? WhenConnected { get; private set; }
|
||||
|
||||
async Task ConnectAsync(string host, int port)
|
||||
{
|
||||
@ -152,8 +153,14 @@ namespace Capnp.Rpc
|
||||
/// </summary>
|
||||
/// <typeparam name="TProxy">Bootstrap capability interface</typeparam>
|
||||
/// <returns>A proxy for the bootstrap capability</returns>
|
||||
/// <exception cref="InvalidOperationException">Not connected</exception>
|
||||
public TProxy GetMain<TProxy>() where TProxy: class
|
||||
{
|
||||
if (WhenConnected == null)
|
||||
{
|
||||
throw new InvalidOperationException("Not connecting");
|
||||
}
|
||||
|
||||
if (!WhenConnected.IsCompleted)
|
||||
{
|
||||
throw new InvalidOperationException("Connection not yet established");
|
||||
@ -164,9 +171,7 @@ namespace Capnp.Rpc
|
||||
throw new InvalidOperationException("Connection not successfully established");
|
||||
}
|
||||
|
||||
Debug.Assert(_inboundEndpoint != null);
|
||||
|
||||
return CapabilityReflection.CreateProxy<TProxy>(_inboundEndpoint.QueryMain()) as TProxy;
|
||||
return (CapabilityReflection.CreateProxy<TProxy>(_inboundEndpoint!.QueryMain()) as TProxy)!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -178,7 +183,7 @@ namespace Capnp.Rpc
|
||||
|
||||
try
|
||||
{
|
||||
if (!WhenConnected.Wait(500))
|
||||
if (WhenConnected != null && !WhenConnected.Wait(500))
|
||||
{
|
||||
Logger.LogError("Unable to join connection task within timeout");
|
||||
}
|
||||
@ -214,7 +219,7 @@ namespace Capnp.Rpc
|
||||
|
||||
_attachTracerAction += () =>
|
||||
{
|
||||
_pump.AttachTracer(tracer);
|
||||
_pump?.AttachTracer(tracer);
|
||||
};
|
||||
}
|
||||
|
||||
@ -234,33 +239,34 @@ namespace Capnp.Rpc
|
||||
/// <summary>
|
||||
/// Gets the number of RPC protocol messages sent by this client so far.
|
||||
/// </summary>
|
||||
public long SendCount => _inboundEndpoint.SendCount;
|
||||
public long SendCount => _inboundEndpoint?.SendCount ?? 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of RPC protocol messages received by this client so far.
|
||||
/// </summary>
|
||||
public long RecvCount => _inboundEndpoint.RecvCount;
|
||||
public long RecvCount => _inboundEndpoint?.RecvCount ?? 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the remote port number which this client is connected to,
|
||||
/// or null if the connection is not yet established.
|
||||
/// </summary>
|
||||
public int? RemotePort => ((IPEndPoint)_client.Client?.RemoteEndPoint)?.Port;
|
||||
public int? RemotePort => ((IPEndPoint)_client.Client.RemoteEndPoint)?.Port;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the local port number which this client using,
|
||||
/// or null if the connection is not yet established.
|
||||
/// </summary>
|
||||
public int? LocalPort => ((IPEndPoint)_client.Client?.LocalEndPoint)?.Port;
|
||||
public int? LocalPort => ((IPEndPoint)_client.Client.LocalEndPoint)?.Port;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the I/O thread is currently running
|
||||
/// </summary>
|
||||
public bool IsComputing => _pumpThread.ThreadState == System.Threading.ThreadState.Running;
|
||||
public bool IsComputing => _pumpThread?.ThreadState == System.Threading.ThreadState.Running;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the I/O thread is waiting for data to receive
|
||||
/// </summary>
|
||||
public bool IsWaitingForData => _pump.IsWaitingForData;
|
||||
public bool IsWaitingForData => _pump?.IsWaitingForData ?? false;
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -6,6 +6,7 @@ using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
@ -103,12 +104,12 @@ namespace Capnp.Rpc
|
||||
public FramePump Pump { get; private set; }
|
||||
public OutboundTcpEndpoint OutboundEp { get; private set; }
|
||||
public RpcEngine.RpcEndpoint InboundEp { get; private set; }
|
||||
public Thread PumpRunner { get; private set; }
|
||||
public Thread? PumpRunner { get; private set; }
|
||||
public int? LocalPort => ((IPEndPoint)Client.Client.LocalEndPoint)?.Port;
|
||||
public int? RemotePort => ((IPEndPoint)Client.Client.RemoteEndPoint)?.Port;
|
||||
public long RecvCount => InboundEp.RecvCount;
|
||||
public long SendCount => InboundEp.SendCount;
|
||||
public bool IsComputing => PumpRunner.ThreadState == ThreadState.Running;
|
||||
public bool IsComputing => PumpRunner?.ThreadState == ThreadState.Running;
|
||||
public bool IsWaitingForData => Pump.IsWaitingForData;
|
||||
|
||||
public void AttachTracer(IFrameTracer tracer)
|
||||
@ -165,7 +166,7 @@ namespace Capnp.Rpc
|
||||
connection.Start();
|
||||
}
|
||||
|
||||
connection.PumpRunner.Start();
|
||||
connection.PumpRunner!.Start();
|
||||
}
|
||||
}
|
||||
catch (SocketException)
|
||||
@ -180,8 +181,13 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
|
||||
void SafeJoin(Thread thread)
|
||||
void SafeJoin(Thread? thread)
|
||||
{
|
||||
if (thread == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int retry = 0; retry < 5; ++retry)
|
||||
{
|
||||
try
|
||||
@ -313,6 +319,7 @@ namespace Capnp.Rpc
|
||||
/// <summary>
|
||||
/// Fires when a new incoming connection was accepted, or when an active connection is closed.
|
||||
/// </summary>
|
||||
public event Action<object, ConnectionEventArgs> OnConnectionChanged;
|
||||
public event Action<object, ConnectionEventArgs>? OnConnectionChanged;
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -4,6 +4,7 @@ using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp.Rpc
|
||||
{
|
||||
class Vine : Skeleton
|
||||
@ -70,3 +71,4 @@ namespace Capnp.Rpc
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,4 +1,5 @@
|
||||
namespace Capnp
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides the security bounds for defeating amplification and stack overflow DoS attacks.
|
||||
@ -16,3 +17,4 @@
|
||||
public static int RecursionLimit { get; set; } = 64;
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -145,3 +146,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -18,3 +19,4 @@ namespace Capnp
|
||||
public int Offset;
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -339,3 +340,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -29,10 +30,10 @@ namespace Capnp
|
||||
return s;
|
||||
}
|
||||
|
||||
internal MessageBuilder MsgBuilder { get; set; }
|
||||
internal ISegmentAllocator Allocator => MsgBuilder?.Allocator;
|
||||
internal List<Rpc.ConsumedCapability> Caps => MsgBuilder?.Caps;
|
||||
internal SerializerState Owner { get; set; }
|
||||
internal MessageBuilder? MsgBuilder { get; set; }
|
||||
internal ISegmentAllocator? Allocator => MsgBuilder?.Allocator;
|
||||
internal List<Rpc.ConsumedCapability?>? Caps => MsgBuilder?.Caps;
|
||||
internal SerializerState? Owner { get; set; }
|
||||
internal int OwnerSlot { get; set; }
|
||||
internal uint SegmentIndex { get; set; }
|
||||
internal int Offset { get; set; }
|
||||
@ -43,7 +44,7 @@ namespace Capnp
|
||||
internal ObjectKind Kind { get; set; }
|
||||
internal uint CapabilityIndex { get; set; }
|
||||
|
||||
SerializerState[] _linkedStates;
|
||||
SerializerState[]? _linkedStates;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs an unbound serializer state.
|
||||
@ -129,7 +130,7 @@ namespace Capnp
|
||||
if (Owner != null)
|
||||
ts.Bind(Owner, OwnerSlot);
|
||||
else
|
||||
ts.Bind(MsgBuilder);
|
||||
ts.Bind(MsgBuilder ?? throw Unbound());
|
||||
|
||||
return ts;
|
||||
}
|
||||
@ -152,8 +153,8 @@ namespace Capnp
|
||||
/// </summary>
|
||||
public bool IsAllocated => Offset >= 0;
|
||||
|
||||
Span<ulong> SegmentSpan => IsAllocated ? Allocator.Segments[(int)SegmentIndex].Span : Span<ulong>.Empty;
|
||||
Span<ulong> FarSpan(uint index) => Allocator.Segments[(int)index].Span;
|
||||
Span<ulong> SegmentSpan => IsAllocated && Allocator != null ? Allocator.Segments[(int)SegmentIndex].Span : Span<ulong>.Empty;
|
||||
Span<ulong> FarSpan(uint index) => Allocator!.Segments[(int)index].Span;
|
||||
|
||||
/// <summary>
|
||||
/// Given this state describes a struct and is allocated, returns the struct's data section.
|
||||
@ -181,6 +182,9 @@ namespace Capnp
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Allocator == null)
|
||||
throw Unbound();
|
||||
|
||||
SegmentIndex = Owner?.SegmentIndex ?? SegmentIndex;
|
||||
Allocator.Allocate(count, SegmentIndex, out var slice, false);
|
||||
SegmentIndex = slice.SegmentIndex;
|
||||
@ -191,7 +195,7 @@ namespace Capnp
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allocates storage for the underlying object. Does nothing if it is already allocated. From the point the object is allocated, its type cannot by changed
|
||||
/// Allocates storage for the underlying object. Does nothing if it is already allocated. From the point the object is allocated, its type cannot be changed
|
||||
/// anymore (e.g. changing from struct to list, or modifying the struct's section sizes).
|
||||
/// </summary>
|
||||
public void Allocate()
|
||||
@ -250,6 +254,9 @@ namespace Capnp
|
||||
if (!target.IsAllocated)
|
||||
throw new InvalidOperationException("Target must be allocated before a pointer can be built");
|
||||
|
||||
if (MsgBuilder == null)
|
||||
throw Unbound();
|
||||
|
||||
try
|
||||
{
|
||||
if (SegmentSpan[offset] != 0)
|
||||
@ -345,7 +352,7 @@ namespace Capnp
|
||||
{
|
||||
WirePointer farPtr = default;
|
||||
|
||||
if (Allocator.Allocate(1, target.SegmentIndex, out var landingPadSlice, true))
|
||||
if (Allocator!.Allocate(1, target.SegmentIndex, out var landingPadSlice, true))
|
||||
{
|
||||
farPtr.SetFarPointer(target.SegmentIndex, landingPadSlice.Offset, false);
|
||||
SegmentSpan[offset] = farPtr;
|
||||
@ -372,7 +379,7 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
|
||||
internal Rpc.ConsumedCapability DecodeCapPointer(int offset)
|
||||
internal Rpc.ConsumedCapability? DecodeCapPointer(int offset)
|
||||
{
|
||||
if (offset < 0)
|
||||
throw new IndexOutOfRangeException(nameof(offset));
|
||||
@ -455,7 +462,7 @@ namespace Capnp
|
||||
throw new InvalidOperationException("This object cannot own pointers to sub-objects");
|
||||
}
|
||||
|
||||
_linkedStates[slot] = target;
|
||||
_linkedStates![slot] = target;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -476,6 +483,7 @@ namespace Capnp
|
||||
}
|
||||
|
||||
static InvalidOperationException AlreadySet() => new InvalidOperationException("The object type was already set");
|
||||
static InvalidOperationException Unbound() => new InvalidOperationException("This state is not bound to a MessageBuilder");
|
||||
|
||||
void VerifyNotYetAllocated()
|
||||
{
|
||||
@ -654,14 +662,21 @@ namespace Capnp
|
||||
/// <exception cref="EncoderFallbackException">Trying to obtain the UTF-8 encoding might throw this exception.</exception>
|
||||
/// <exception cref="InvalidOperationException">The object type was already set to something different</exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">UTF-8 encoding exceeds 2^29-2 bytes</exception>
|
||||
protected void WriteText(string text)
|
||||
protected void WriteText(string? text)
|
||||
{
|
||||
byte[] srcBytes = Encoding.UTF8.GetBytes(text);
|
||||
SetListOfValues(8, srcBytes.Length + 1);
|
||||
var srcSpan = new ReadOnlySpan<byte>(srcBytes);
|
||||
var dstSpan = ListGetBytes();
|
||||
dstSpan = dstSpan.Slice(0, dstSpan.Length - 1);
|
||||
srcSpan.CopyTo(dstSpan);
|
||||
if (text == null)
|
||||
{
|
||||
VerifyNotYetAllocated();
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] srcBytes = Encoding.UTF8.GetBytes(text);
|
||||
SetListOfValues(8, srcBytes.Length + 1);
|
||||
var srcSpan = new ReadOnlySpan<byte>(srcBytes);
|
||||
var dstSpan = ListGetBytes();
|
||||
dstSpan = dstSpan.Slice(0, dstSpan.Length - 1);
|
||||
srcSpan.CopyTo(dstSpan);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -761,7 +776,7 @@ namespace Capnp
|
||||
if (Kind != ObjectKind.Struct && Kind != ObjectKind.ListOfPointers)
|
||||
throw new InvalidOperationException("This is not a struct or list of pointers");
|
||||
|
||||
ref var state = ref _linkedStates[index];
|
||||
ref var state = ref _linkedStates![index];
|
||||
|
||||
if (state == null)
|
||||
{
|
||||
@ -784,12 +799,12 @@ namespace Capnp
|
||||
/// <item><description>Object at given position is not compatible with the desired target serializer type.</description></item>
|
||||
/// </list></exception>
|
||||
/// <exception cref="IndexOutOfRangeException"><paramref name="index"/> is out of bounds.</exception>
|
||||
public TS TryGetPointer<TS>(int index) where TS : SerializerState, new()
|
||||
public TS? TryGetPointer<TS>(int index) where TS : SerializerState, new()
|
||||
{
|
||||
if (Kind != ObjectKind.Struct && Kind != ObjectKind.ListOfPointers)
|
||||
throw new InvalidOperationException("This is not a struct or list of pointers");
|
||||
|
||||
var state = _linkedStates[index];
|
||||
var state = _linkedStates![index];
|
||||
|
||||
if (state == null) return null;
|
||||
|
||||
@ -820,7 +835,7 @@ namespace Capnp
|
||||
/// <item><description>Object at given position is not compatible with the desired target serializer type.</description></item>
|
||||
/// </list></exception>
|
||||
/// <exception cref="IndexOutOfRangeException"><paramref name="index"/> is out of bounds.</exception>
|
||||
public SerializerState TryGetPointer(int index) => TryGetPointer<SerializerState>(index);
|
||||
public SerializerState? TryGetPointer(int index) => TryGetPointer<SerializerState>(index);
|
||||
|
||||
/// <summary>
|
||||
/// Reads text from a struct field or list element.
|
||||
@ -829,7 +844,7 @@ namespace Capnp
|
||||
/// If the underlying object is a list of pointers: Element index</param>
|
||||
/// <param name="defaultText">String to return in case of null</param>
|
||||
/// <returns>The decoded text</returns>
|
||||
public string ReadText(int index, string defaultText = null)
|
||||
public string? ReadText(int index, string? defaultText = null)
|
||||
{
|
||||
var b = BuildPointer(index);
|
||||
|
||||
@ -851,7 +866,7 @@ namespace Capnp
|
||||
/// <item><description>Object at given position was already set.</description></item>
|
||||
/// </list></exception>
|
||||
/// <exception cref="IndexOutOfRangeException"><paramref name="index"/> is out of bounds.</exception>
|
||||
public void WriteText(int index, string text)
|
||||
public void WriteText(int index, string? text)
|
||||
{
|
||||
BuildPointer(index).WriteText(text);
|
||||
}
|
||||
@ -886,11 +901,11 @@ namespace Capnp
|
||||
if (Kind != ObjectKind.ListOfStructs)
|
||||
throw new InvalidOperationException("This is not a list of structs");
|
||||
|
||||
ref var state = ref _linkedStates[index];
|
||||
ref var state = ref _linkedStates![index];
|
||||
|
||||
if (state == null)
|
||||
{
|
||||
state = new SerializerState(MsgBuilder);
|
||||
state = new SerializerState(MsgBuilder!);
|
||||
state.SetStruct(StructDataCount, StructPtrCount);
|
||||
state.SegmentIndex = SegmentIndex;
|
||||
state.Offset = Offset + 1 + index * (StructDataCount + StructPtrCount);
|
||||
@ -913,12 +928,12 @@ namespace Capnp
|
||||
if (Kind != ObjectKind.ListOfStructs)
|
||||
throw new InvalidOperationException("This is not a list of structs");
|
||||
|
||||
ref var state = ref _linkedStates[index];
|
||||
ref var state = ref _linkedStates![index];
|
||||
|
||||
if (state == null)
|
||||
{
|
||||
state = new TS();
|
||||
state.Bind(MsgBuilder);
|
||||
state.Bind(MsgBuilder!);
|
||||
state.SetStruct(StructDataCount, StructPtrCount);
|
||||
state.SegmentIndex = SegmentIndex;
|
||||
int stride = StructDataCount + StructPtrCount;
|
||||
@ -942,19 +957,19 @@ namespace Capnp
|
||||
|
||||
for (int offset = minOffset; offset < maxOffset; offset++)
|
||||
{
|
||||
ref var state = ref _linkedStates[offset - minOffset];
|
||||
ref var state = ref _linkedStates![offset - minOffset];
|
||||
|
||||
if (state == null)
|
||||
{
|
||||
state = new TS();
|
||||
state.Bind(MsgBuilder);
|
||||
state.Bind(MsgBuilder!);
|
||||
state.SetStruct(StructDataCount, StructPtrCount);
|
||||
state.SegmentIndex = SegmentIndex;
|
||||
state.Offset = offset;
|
||||
}
|
||||
}
|
||||
|
||||
return _linkedStates.LazyListSelect(ts => (TS)ts);
|
||||
return _linkedStates!.LazyListSelect(ts => (TS)ts);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1240,7 +1255,7 @@ namespace Capnp
|
||||
/// <param name="capability">The low-level capability object to provide.</param>
|
||||
/// <returns>Index of the given capability in the capability table</returns>
|
||||
/// <exception cref="InvalidOperationException">The underlying message builder was not configured for capability table support.</exception>
|
||||
public uint ProvideCapability(Rpc.ConsumedCapability capability)
|
||||
public uint ProvideCapability(Rpc.ConsumedCapability? capability)
|
||||
{
|
||||
if (Caps == null)
|
||||
throw new InvalidOperationException("Underlying MessageBuilder was not enabled to support capabilities");
|
||||
@ -1279,7 +1294,7 @@ namespace Capnp
|
||||
/// </list></param>
|
||||
/// <returns>Index of the given capability in the capability table</returns>
|
||||
/// <exception cref="InvalidOperationException">The underlying message builder was not configured for capability table support.</exception>
|
||||
public uint ProvideCapability(object obj)
|
||||
public uint ProvideCapability(object? obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return ProvideCapability(default(Rpc.ConsumedCapability));
|
||||
@ -1352,7 +1367,7 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
|
||||
internal Rpc.ConsumedCapability StructReadRawCap(int index)
|
||||
internal Rpc.ConsumedCapability? StructReadRawCap(int index)
|
||||
{
|
||||
if (Kind != ObjectKind.Struct && Kind != ObjectKind.Nil)
|
||||
throw new InvalidOperationException("Allowed on structs only");
|
||||
@ -1372,7 +1387,7 @@ namespace Capnp
|
||||
/// <exception cref="ArgumentOutOfRangeException"><paramref name="slot"/> is out of range.</exception>
|
||||
/// <exception cref="ArgumentException">The desired interface does not qualify as capability interface (<see cref="Rpc.ProxyAttribute"/>)</exception>
|
||||
/// <exception cref="InvalidOperationException">This state does not represent a struct.</exception>
|
||||
public T ReadCap<T>(int slot) where T : class
|
||||
public T? ReadCap<T>(int slot) where T : class
|
||||
{
|
||||
var cap = StructReadRawCap(slot);
|
||||
return Rpc.CapabilityReflection.CreateProxy<T>(cap) as T;
|
||||
@ -1392,3 +1407,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -25,3 +26,4 @@ namespace Capnp
|
||||
public ulong Id { get; }
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -4,8 +4,9 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Capnp
|
||||
{
|
||||
internal static class UtilityExtensions
|
||||
{
|
||||
#nullable enable
|
||||
internal static class UtilityExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// This method exists until NET Standard 2.1 is released
|
||||
/// </summary>
|
||||
@ -23,7 +24,7 @@ namespace Capnp
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
public static bool ReplacementTryAdd<K, V>(this Dictionary<K, V> thisDict, K key, V value) => thisDict.TryAdd(key, value);
|
||||
public static bool ReplacementTryAdd<K, V>(this Dictionary<K, V> thisDict, K key, V value) where K: struct => thisDict.TryAdd(key, value);
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
@ -40,14 +41,16 @@ namespace Capnp
|
||||
{
|
||||
if (!thisDict.ContainsKey(key))
|
||||
{
|
||||
value = default;
|
||||
value = default!; // OK here since .NET Standard 2.0 does not support (non-)nullability anyway.
|
||||
return false;
|
||||
}
|
||||
value = thisDict[key];
|
||||
return thisDict.Remove(key);
|
||||
}
|
||||
#else
|
||||
#pragma warning disable CS8714
|
||||
public static bool ReplacementTryRemove<K, V>(this Dictionary<K, V> thisDict, K key, out V value) => thisDict.Remove(key, out value);
|
||||
#pragma warning restore CS8714
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
@ -76,4 +79,5 @@ namespace Capnp
|
||||
public static float ReplacementInt32ToSingleBits(this int value) => BitConverter.Int32BitsToSingle(value);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -22,3 +23,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
#nullable enable
|
||||
namespace Capnp
|
||||
{
|
||||
/// <summary>
|
||||
@ -228,3 +229,4 @@ namespace Capnp
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
Loading…
x
Reference in New Issue
Block a user