Fixed documentation bugs + minor testsuite warnings

This commit is contained in:
Christian Köllner 2019-07-12 21:48:01 +02:00
parent 26ae8762d4
commit 71c2b32c69
29 changed files with 722 additions and 96 deletions

View File

@ -13,8 +13,6 @@ namespace Capnp.Net.Runtime.Tests
[TestClass] [TestClass]
public class TcpRpcStress: TestBase public class TcpRpcStress: TestBase
{ {
ILogger Logger { get; set; }
void Repeat(int count, Action action) void Repeat(int count, Action action)
{ {
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
@ -24,15 +22,6 @@ namespace Capnp.Net.Runtime.Tests
} }
} }
[TestInitialize]
public void InitConsoleLogging()
{
Logging.LoggerFactory = new LoggerFactory().AddConsole((msg, level) => true);
Logger = Logging.CreateLogger<TcpRpcStress>();
if (Thread.CurrentThread.Name == null)
Thread.CurrentThread.Name = $"Test Thread {Thread.CurrentThread.ManagedThreadId}";
}
[TestMethod] [TestMethod]
public void ResolveMain() public void ResolveMain()
{ {

View File

@ -62,6 +62,16 @@
This exception gets thrown when a Cap'n Proto object could not be deserialized correctly. This exception gets thrown when a Cap'n Proto object could not be deserialized correctly.
</summary> </summary>
</member> </member>
<member name="M:Capnp.DeserializationException.#ctor(System.String)">
<summary>
Constructs an instance
</summary>
</member>
<member name="M:Capnp.DeserializationException.#ctor(System.String,System.Exception)">
<summary>
Constructs an instance with message and inner exception
</summary>
</member>
<member name="T:Capnp.DeserializerState"> <member name="T:Capnp.DeserializerState">
<summary> <summary>
Implements the heart of deserialization. This stateful helper struct exposes all functionality to traverse serialized data. Implements the heart of deserialization. This stateful helper struct exposes all functionality to traverse serialized data.
@ -279,6 +289,9 @@
</summary> </summary>
<typeparam name="T">Capability interface</typeparam> <typeparam name="T">Capability interface</typeparam>
<param name="index">index within this struct's pointer table</param> <param name="index">index within this struct's pointer table</param>
<param name="memberName">debugging aid</param>
<param name="sourceFilePath">debugging aid</param>
<param name="sourceLineNumber">debugging aid</param>
<returns>capability instance or null if pointer was null</returns> <returns>capability instance or null if pointer was null</returns>
<exception cref="T:System.IndexOutOfRangeException">negative index</exception> <exception cref="T:System.IndexOutOfRangeException">negative index</exception>
<exception cref="T:Capnp.DeserializationException">state does not represent a struct, invalid pointer, <exception cref="T:Capnp.DeserializationException">state does not represent a struct, invalid pointer,
@ -331,8 +344,36 @@
</summary> </summary>
<param name="state">The deserializer state to convert</param> <param name="state">The deserializer state to convert</param>
</member> </member>
<!-- Badly formed XML comment ignored for member "M:Capnp.DynamicSerializerState.Link(System.Int32,Capnp.SerializerState,System.Boolean)" --> <member name="M:Capnp.DynamicSerializerState.Link(System.Int32,Capnp.SerializerState,System.Boolean)">
<!-- Badly formed XML comment ignored for member "M:Capnp.DynamicSerializerState.LinkToCapability(System.Int32,System.UInt32)" --> <summary>
Links a sub-item (struct field or list element) of this state to another state. Usually, this operation is not necessary, since objects are constructed top-down.
However, there might be some advanced scenarios where you want to reference the same object twice (also interesting for designing amplification attacks).
The Cap'n Proto serialization intrinsically supports this, since messages are object graphs, not trees.
</summary>
<param name="slot">If this state describes a struct: Index into this struct's pointer table.
If this state describes a list of pointers: List element index.</param>
<param name="target">state to be linked</param>
<param name="allowCopy">Whether to deep copy the target state if it belongs to a different message builder than this state.</param>
<exception cref="T:System.ArgumentNullException"><paramref name="target"/> is null</exception>
<exception cref="T:System.ArgumentOutOfRangeException"><paramref name="slot"/> out of range</exception>
<exception cref="T:System.InvalidOperationException"><list type="bullet">
<item><description>This state does neither describe a struct, nor a list of pointers</description></item>
<item><description>Another state is already linked to the specified position (sorry, no overwrite allowed)</description></item>
<item><description>This state and <paramref name="target"/> belong to different message builder, and<paramref name="allowCopy"/> is false</description></item></list>
</exception>
</member>
<member name="M:Capnp.DynamicSerializerState.LinkToCapability(System.Int32,System.UInt32)">
<summary>
Links a sub-item (struct field or list element) of this state to a capability.
</summary>
<param name="slot">If this state describes a struct: Index into this struct's pointer table.
If this state describes a list of pointers: List element index.</param>
<param name="capabilityIndex">capability index inside the capability table</param>
<exception cref="T:System.InvalidOperationException"><list type="bullet">
<item><description>This state does neither describe a struct, nor a list of pointers</description></item>
<item><description>Another state is already linked to the specified position (sorry, no overwrite allowed)</description></item></list>
</exception>
</member>
<member name="M:Capnp.DynamicSerializerState.SetStruct(System.UInt16,System.UInt16)"> <member name="M:Capnp.DynamicSerializerState.SetStruct(System.UInt16,System.UInt16)">
<summary> <summary>
Determines the underlying object to be a struct. Determines the underlying object to be a struct.
@ -369,7 +410,37 @@
<exception cref="T:System.InvalidOperationException">The object type was already set to something different</exception> <exception cref="T:System.InvalidOperationException">The object type was already set to something different</exception>
<exception cref="T:System.ArgumentOutOfRangeException"><paramref name="totalCount"/> negative, or total word count would exceed 2^29-1</exception> <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="totalCount"/> negative, or total word count would exceed 2^29-1</exception>
</member> </member>
<!-- Badly formed XML comment ignored for member "M:Capnp.DynamicSerializerState.SetObject(System.Object)" --> <member name="M:Capnp.DynamicSerializerState.SetObject(System.Object)">
<summary>
Constructs the underlying object from the given representation.
</summary>
<param name="obj">Object representation. Must be one of the following:
<list type="bullet">
<item><description>An instance implementing <see cref="T:Capnp.ICapnpSerializable"/></description></item>
<item><description>null</description></item>
<item><description>A <see cref="T:System.String"/></description></item>
<item><description>A <code><![CDATA[IReadOnlyList<byte>]]></code></description></item>
<item><description>A <code><![CDATA[IReadOnlyList<sbyte>]]></code></description></item>
<item><description>A <code><![CDATA[IReadOnlyList<ushort>]]></code></description></item>
<item><description>A <code><![CDATA[IReadOnlyList<short>]]></code></description></item>
<item><description>A <code><![CDATA[IReadOnlyList<int>]]></code></description></item>
<item><description>A <code><![CDATA[IReadOnlyList<uint>]]></code></description></item>
<item><description>A <code><![CDATA[IReadOnlyList<long>]]></code></description></item>
<item><description>A <code><![CDATA[IReadOnlyList<ulong>]]></code></description></item>
<item><description>A <code><![CDATA[IReadOnlyList<float>]]></code></description></item>
<item><description>A <code><![CDATA[IReadOnlyList<double>]]></code></description></item>
<item><description>A <code><![CDATA[IReadOnlyList<bool>]]></code></description></item>
<item><description>A <code><![CDATA[IReadOnlyList<string>]]></code></description></item>
<item><description>Another <see cref="T:Capnp.DeserializerState"/></description></item>
<item><description>Another <see cref="T:Capnp.SerializerState"/></description></item>
<item><description>Low-level capability object (<see cref="T:Capnp.Rpc.ConsumedCapability"/>)</description></item>
<item><description>Proxy object (<see cref="T:Capnp.Rpc.Proxy"/>)</description></item>
<item><description>Skeleton object (<see cref="T:Capnp.Rpc.Skeleton"/>)</description></item>
<item><description>Capability interface implementation</description></item>
<item><description>A <code><![CDATA[IReadOnlyList<object>]]></code> whereby each list item is one of the things listed here.</description></item>
</list>
</param>
</member>
<member name="T:Capnp.EmptyList`1"> <member name="T:Capnp.EmptyList`1">
<summary> <summary>
Implements an empty <see cref="T:System.Collections.Generic.IReadOnlyList`1"/>. Implements an empty <see cref="T:System.Collections.Generic.IReadOnlyList`1"/>.
@ -411,43 +482,47 @@
</member> </member>
<member name="M:Capnp.EmptyListDeserializer.CastBool"> <member name="M:Capnp.EmptyListDeserializer.CastBool">
<summary> <summary>
Returns an empty <see cref="T:System.Collections.Generic.IReadOnlyList`1"/>. Returns an empty <code><![CDATA[IReadOnlyList<bool>]]></code>/>.
</summary> </summary>
</member> </member>
<member name="M:Capnp.EmptyListDeserializer.CastByte"> <member name="M:Capnp.EmptyListDeserializer.CastByte">
<summary> <summary>
Returns an empty <see cref="T:System.Collections.Generic.IReadOnlyList`1"/>. Returns an empty <code><![CDATA[IReadOnlyList<byte>]]></code>/>.
</summary> </summary>
</member> </member>
<member name="M:Capnp.EmptyListDeserializer.CastDouble"> <member name="M:Capnp.EmptyListDeserializer.CastDouble">
<summary> <summary>
Returns an empty <see cref="T:System.Collections.Generic.IReadOnlyList`1"/>. Returns an empty <code><![CDATA[IReadOnlyList<double>]]></code>/>.
</summary>
</member>
<member name="M:Capnp.EmptyListDeserializer.CastFloat">
<summary>
Returns an empty <code><![CDATA[IReadOnlyList<float>]]></code>.
</summary> </summary>
</member> </member>
<!-- Badly formed XML comment ignored for member "M:Capnp.EmptyListDeserializer.CastFloat" -->
<member name="M:Capnp.EmptyListDeserializer.CastInt"> <member name="M:Capnp.EmptyListDeserializer.CastInt">
<summary> <summary>
Returns an empty <see cref="T:System.Collections.Generic.IReadOnlyList`1"/>. Returns an empty <code><![CDATA[IReadOnlyList<int>]]></code>.
</summary> </summary>
</member> </member>
<member name="M:Capnp.EmptyListDeserializer.CastList"> <member name="M:Capnp.EmptyListDeserializer.CastList">
<summary> <summary>
Returns an empty <see cref="T:System.Collections.Generic.IReadOnlyList`1"/>. Returns an empty <code><![CDATA[IReadOnlyList<ListDeserializer>]]></code>.
</summary> </summary>
</member> </member>
<member name="M:Capnp.EmptyListDeserializer.CastLong"> <member name="M:Capnp.EmptyListDeserializer.CastLong">
<summary> <summary>
Returns an empty <see cref="T:System.Collections.Generic.IReadOnlyList`1"/>. Returns an empty <code><![CDATA[IReadOnlyList<long>]]></code>/>.
</summary> </summary>
</member> </member>
<member name="M:Capnp.EmptyListDeserializer.CastSByte"> <member name="M:Capnp.EmptyListDeserializer.CastSByte">
<summary> <summary>
Returns an empty <see cref="T:System.Collections.Generic.IReadOnlyList`1"/>. Returns an empty <code><![CDATA[IReadOnlyList<sbyte>]]></code>.
</summary> </summary>
</member> </member>
<member name="M:Capnp.EmptyListDeserializer.CastShort"> <member name="M:Capnp.EmptyListDeserializer.CastShort">
<summary> <summary>
Returns an empty <see cref="T:System.Collections.Generic.IReadOnlyList`1"/>. Returns an empty <code><![CDATA[IReadOnlyList<short>]]></code>.
</summary> </summary>
</member> </member>
<member name="M:Capnp.EmptyListDeserializer.CastText"> <member name="M:Capnp.EmptyListDeserializer.CastText">
@ -457,17 +532,17 @@
</member> </member>
<member name="M:Capnp.EmptyListDeserializer.CastUInt"> <member name="M:Capnp.EmptyListDeserializer.CastUInt">
<summary> <summary>
Returns an empty <see cref="T:System.Collections.Generic.IReadOnlyList`1"/>. Returns an empty <code><![CDATA[IReadOnlyList<uint>]]></code>.
</summary> </summary>
</member> </member>
<member name="M:Capnp.EmptyListDeserializer.CastULong"> <member name="M:Capnp.EmptyListDeserializer.CastULong">
<summary> <summary>
Returns an empty <see cref="T:System.Collections.Generic.IReadOnlyList`1"/>. Returns an empty <code><![CDATA[IReadOnlyList<ulong>]]></code>.
</summary> </summary>
</member> </member>
<member name="M:Capnp.EmptyListDeserializer.CastUShort"> <member name="M:Capnp.EmptyListDeserializer.CastUShort">
<summary> <summary>
Returns an empty <see cref="T:System.Collections.Generic.IReadOnlyList`1"/>. Returns an empty <code><![CDATA[IReadOnlyList<ushort>]]></code>.
</summary> </summary>
</member> </member>
<member name="T:Capnp.FramePump"> <member name="T:Capnp.FramePump">
@ -543,6 +618,13 @@
<exception cref="T:System.IO.InvalidDataException">Encountered invalid framing data, too many or too large segments</exception> <exception cref="T:System.IO.InvalidDataException">Encountered invalid framing data, too many or too large segments</exception>
<exception cref="T:System.OutOfMemoryException">Too many or too large segments, probably due to invalid framing data.</exception> <exception cref="T:System.OutOfMemoryException">Too many or too large segments, probably due to invalid framing data.</exception>
</member> </member>
<member name="M:Capnp.Framing.ReadWireFrame(System.IO.BinaryReader)">
<summary>
Deserializes the next Cap'n Proto message from given stream.
</summary>
<param name="reader">The stream to read from</param>
<returns>The message</returns>
</member>
<member name="T:Capnp.ICapnpSerializable"> <member name="T:Capnp.ICapnpSerializable">
<summary> <summary>
This interface is intended to be implemented by schema-generated domain classes which support deserialization from This interface is intended to be implemented by schema-generated domain classes which support deserialization from
@ -876,6 +958,13 @@
<returns>The desired representation</returns> <returns>The desired representation</returns>
<exception cref="T:System.NotSupportedException">If this list cannot be represented in the desired manner.</exception> <exception cref="T:System.NotSupportedException">If this list cannot be represented in the desired manner.</exception>
</member> </member>
<member name="M:Capnp.ListDeserializer.CastLong">
<summary>
Represents this list as List(Int64).
</summary>
<returns>The desired representation</returns>
<exception cref="T:System.NotSupportedException">If this list cannot be represented in the desired manner.</exception>
</member>
<member name="M:Capnp.ListDeserializer.CastULong"> <member name="M:Capnp.ListDeserializer.CastULong">
<summary> <summary>
Represents this list as List(UInt64). Represents this list as List(UInt64).
@ -962,7 +1051,7 @@
</member> </member>
<member name="M:Capnp.ListOfBitsDeserializer.GetEnumerator"> <member name="M:Capnp.ListOfBitsDeserializer.GetEnumerator">
<summary> <summary>
Implements <see cref="!:IEnumerable&lt;bool&gt;"/> Implements <see cref="T:System.Collections.Generic.IEnumerable`1"/>
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
@ -1039,7 +1128,12 @@
Always throws <see cref="T:System.NotSupportedException"/>, since it is not intended to convert a capability list to anything else. Always throws <see cref="T:System.NotSupportedException"/>, since it is not intended to convert a capability list to anything else.
</summary> </summary>
</member> </member>
<!-- Badly formed XML comment ignored for member "M:Capnp.ListOfCapsDeserializer`1.GetEnumerator" --> <member name="M:Capnp.ListOfCapsDeserializer`1.GetEnumerator">
<summary>
Implements <see cref="T:System.Collections.Generic.IEnumerable`1"/>.
</summary>
<returns></returns>
</member>
<member name="T:Capnp.ListOfCapsSerializer`1"> <member name="T:Capnp.ListOfCapsSerializer`1">
<summary> <summary>
SerializerState specialization for a list of capabilities. SerializerState specialization for a list of capabilities.
@ -1084,7 +1178,12 @@
This list's element count. This list's element count.
</summary> </summary>
</member> </member>
<!-- Badly formed XML comment ignored for member "M:Capnp.ListOfCapsSerializer`1.GetEnumerator" --> <member name="M:Capnp.ListOfCapsSerializer`1.GetEnumerator">
<summary>
Implements <see cref="T:System.Collections.Generic.IEnumerable`1"/>.
</summary>
<returns></returns>
</member>
<member name="T:Capnp.ListOfEmptyDeserializer"> <member name="T:Capnp.ListOfEmptyDeserializer">
<summary> <summary>
ListDeserializer specialization for List(Void). ListDeserializer specialization for List(Void).
@ -1403,7 +1502,11 @@
<param name="cons">The selector function</param> <param name="cons">The selector function</param>
<returns>The new list representation</returns> <returns>The new list representation</returns>
</member> </member>
<!-- Badly formed XML comment ignored for member "M:Capnp.ListOfStructsDeserializer.GetEnumerator" --> <member name="M:Capnp.ListOfStructsDeserializer.GetEnumerator">
<summary>
Implements <see cref="T:System.Collections.Generic.IEnumerable`1"/>.
</summary>
</member>
<member name="T:Capnp.ListOfStructsSerializer`1"> <member name="T:Capnp.ListOfStructsSerializer`1">
<summary> <summary>
SerializerState specialization for List(T) when T is a known struct (i.e. a list of fixed-width composites). SerializerState specialization for List(T) when T is a known struct (i.e. a list of fixed-width composites).
@ -1625,7 +1728,18 @@
Provides extension methods for <see cref="T:System.Collections.Generic.IReadOnlyList`1"/> Provides extension methods for <see cref="T:System.Collections.Generic.IReadOnlyList`1"/>
</summary> </summary>
</member> </member>
<!-- Badly formed XML comment ignored for member "M:Capnp.ReadOnlyListExtensions.LazyListSelect``2(System.Collections.Generic.IReadOnlyList{``0},System.Func{``0,``1})" --> <member name="M:Capnp.ReadOnlyListExtensions.LazyListSelect``2(System.Collections.Generic.IReadOnlyList{``0},System.Func{``0,``1})">
<summary>
LINQ-like "Select" operator for <see cref="T:System.Collections.Generic.IReadOnlyList`1"/>, with the addition that the resulting elements are accessible by index.
The operator implements lazy semantics, which means that the selector function results are not cached./>
</summary>
<typeparam name="From">Source element type</typeparam>
<typeparam name="To">Target element type</typeparam>
<param name="source">Source list</param>
<param name="selector">Selector function</param>
<returns>A read-only list in which each element corresponds to the source element after applying the selector function</returns>
<exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
</member>
<member name="M:Capnp.ReadOnlyListExtensions.ToReadOnlyList``2(System.Collections.Generic.IReadOnlyList{``0},System.Func{``0,``1})"> <member name="M:Capnp.ReadOnlyListExtensions.ToReadOnlyList``2(System.Collections.Generic.IReadOnlyList{``0},System.Func{``0,``1})">
<summary> <summary>
Applies a selector function to each list element and stores the result in a new list. Applies a selector function to each list element and stores the result in a new list.
@ -1662,6 +1776,28 @@
Helper struct to support tail calls Helper struct to support tail calls
</summary> </summary>
</member> </member>
<member name="M:Capnp.Rpc.AnswerOrCounterquestion.op_Implicit(Capnp.SerializerState)~Capnp.Rpc.AnswerOrCounterquestion">
<summary>
Wraps a SerializerState
</summary>
<param name="answer">object to wrap</param>
</member>
<member name="M:Capnp.Rpc.AnswerOrCounterquestion.op_Implicit(Capnp.Rpc.PendingQuestion)~Capnp.Rpc.AnswerOrCounterquestion">
<summary>
Wraps a PendingQuestion
</summary>
<param name="counterquestion">object to wrap</param>
</member>
<member name="P:Capnp.Rpc.AnswerOrCounterquestion.Answer">
<summary>
SerializerState, if applicable
</summary>
</member>
<member name="P:Capnp.Rpc.AnswerOrCounterquestion.Counterquestion">
<summary>
PendingQuestion, if applicable
</summary>
</member>
<member name="T:Capnp.Rpc.BareProxy"> <member name="T:Capnp.Rpc.BareProxy">
<summary> <summary>
Generic Proxy implementation which exposes the (usually protected) Call method. Generic Proxy implementation which exposes the (usually protected) Call method.
@ -1673,13 +1809,13 @@
</summary> </summary>
<param name="impl">Capability implementation</param> <param name="impl">Capability implementation</param>
<returns>Proxy</returns> <returns>Proxy</returns>
<exception cref="!:ArgumentNullException"><paramref name="impl"/> is null.</exception> <exception cref="T:System.ArgumentNullException"><paramref name="impl"/> is null.</exception>
<exception cref="T:Capnp.Rpc.InvalidCapabilityInterfaceException">No <see cref="T:Capnp.Rpc.SkeletonAttribute"/> found on implemented interface(s).</exception> <exception cref="T:Capnp.Rpc.InvalidCapabilityInterfaceException">No <see cref="T:Capnp.Rpc.SkeletonAttribute"/> found on implemented interface(s).</exception>
<exception cref="!:InvalidOperationException">Mismatch between generic type arguments (if capability interface is generic).</exception> <exception cref="T:System.InvalidOperationException">Mismatch between generic type arguments (if capability interface is generic).</exception>
<exception cref="!:ArgumentException">Mismatch between generic type arguments (if capability interface is generic).</exception> <exception cref="T:System.ArgumentException">Mismatch between generic type arguments (if capability interface is generic).</exception>
<exception cref="T:System.Reflection.TargetInvocationException">Problem with instatiating the Skeleton (constructor threw exception).</exception> <exception cref="T:System.Reflection.TargetInvocationException">Problem with instatiating the Skeleton (constructor threw exception).</exception>
<exception cref="!:MemberAccessException">Caller does not have permission to invoke the Skeleton constructor.</exception> <exception cref="T:System.MemberAccessException">Caller does not have permission to invoke the Skeleton constructor.</exception>
<exception cref="!:TypeLoadException">Problem with building the Skeleton type, or problem with loading some dependent class.</exception> <exception cref="T:System.TypeLoadException">Problem with building the Skeleton type, or problem with loading some dependent class.</exception>
</member> </member>
<member name="M:Capnp.Rpc.BareProxy.#ctor"> <member name="M:Capnp.Rpc.BareProxy.#ctor">
<summary> <summary>
@ -1746,6 +1882,9 @@
</summary> </summary>
<typeparam name="TInterface">Capability interface. Must be annotated with <see cref="T:Capnp.Rpc.ProxyAttribute"/>.</typeparam> <typeparam name="TInterface">Capability interface. Must be annotated with <see cref="T:Capnp.Rpc.ProxyAttribute"/>.</typeparam>
<param name="cap">low-level capability</param> <param name="cap">low-level capability</param>
<param name="memberName">debugging aid</param>
<param name="sourceFilePath">debugging aid</param>
<param name="sourceLineNumber">debugging aid</param>
<returns>The Proxy instance which implements <typeparamref name="TInterface"/>.</returns> <returns>The Proxy instance which implements <typeparamref name="TInterface"/>.</returns>
<exception cref="T:System.ArgumentNullException"><paramref name="cap"/> is null.</exception> <exception cref="T:System.ArgumentNullException"><paramref name="cap"/> is null.</exception>
<exception cref="T:Capnp.Rpc.InvalidCapabilityInterfaceException"><typeparamref name="TInterface"/> did not qualify as capability interface.</exception> <exception cref="T:Capnp.Rpc.InvalidCapabilityInterfaceException"><typeparamref name="TInterface"/> did not qualify as capability interface.</exception>
@ -1824,11 +1963,53 @@
</summary> </summary>
<typeparam name="TInterface">Capability interface type</typeparam> <typeparam name="TInterface">Capability interface type</typeparam>
<param name="task">The task</param> <param name="task">The task</param>
<param name="memberName">debugging aid</param>
<param name="sourceFilePath">debugging aid</param>
<param name="sourceLineNumber">debugging aid</param>
<returns>A proxy for the given task.</returns> <returns>A proxy for the given task.</returns>
<exception cref="T:System.ArgumentNullException"><paramref name="task"/> is null.</exception> <exception cref="T:System.ArgumentNullException"><paramref name="task"/> is null.</exception>
<exception cref="T:Capnp.Rpc.InvalidCapabilityInterfaceException"><typeparamref name="TInterface"/> did not <exception cref="T:Capnp.Rpc.InvalidCapabilityInterfaceException"><typeparamref name="TInterface"/> did not
quality as capability interface.</exception> quality as capability interface.</exception>
</member> </member>
<member name="M:Capnp.Rpc.Impatient.MaybeTailCall``1(System.Threading.Tasks.Task{``0},System.Func{``0,Capnp.SerializerState})">
<summary>
Checks whether a given task belongs to a pending RPC and requests a tail call if applicable.
</summary>
<typeparam name="T">Task result type</typeparam>
<param name="task">Task to request</param>
<param name="func">Converts the task's result to a SerializerState</param>
<returns>Tail-call aware task</returns>
</member>
<member name="M:Capnp.Rpc.Impatient.MaybeTailCall``2(System.Threading.Tasks.Task{System.ValueTuple{``0,``1}},System.Func{``0,``1,Capnp.SerializerState})">
<summary>
Overload for tuple-typed tasks
</summary>
</member>
<member name="M:Capnp.Rpc.Impatient.MaybeTailCall``3(System.Threading.Tasks.Task{System.ValueTuple{``0,``1,``2}},System.Func{``0,``1,``2,Capnp.SerializerState})">
<summary>
Overload for tuple-typed tasks
</summary>
</member>
<member name="M:Capnp.Rpc.Impatient.MaybeTailCall``4(System.Threading.Tasks.Task{System.ValueTuple{``0,``1,``2,``3}},System.Func{``0,``1,``2,``3,Capnp.SerializerState})">
<summary>
Overload for tuple-typed tasks
</summary>
</member>
<member name="M:Capnp.Rpc.Impatient.MaybeTailCall``5(System.Threading.Tasks.Task{System.ValueTuple{``0,``1,``2,``3,``4}},System.Func{``0,``1,``2,``3,``4,Capnp.SerializerState})">
<summary>
Overload for tuple-typed tasks
</summary>
</member>
<member name="M:Capnp.Rpc.Impatient.MaybeTailCall``6(System.Threading.Tasks.Task{System.ValueTuple{``0,``1,``2,``3,``4,``5}},System.Func{``0,``1,``2,``3,``4,``5,Capnp.SerializerState})">
<summary>
Overload for tuple-typed tasks
</summary>
</member>
<member name="M:Capnp.Rpc.Impatient.MaybeTailCall``7(System.Threading.Tasks.Task{System.ValueTuple{``0,``1,``2,``3,``4,``5,``6}},System.Func{``0,``1,``2,``3,``4,``5,``6,Capnp.SerializerState})">
<summary>
Overload for tuple-typed tasks
</summary>
</member>
<member name="T:Capnp.Rpc.ImportedCapability"> <member name="T:Capnp.Rpc.ImportedCapability">
<summary> <summary>
Low-level capability which as imported from a remote peer. Low-level capability which as imported from a remote peer.
@ -1841,6 +2022,16 @@
See descriptions of these attributes for further details. See descriptions of these attributes for further details.
</summary> </summary>
</member> </member>
<member name="M:Capnp.Rpc.InvalidCapabilityInterfaceException.#ctor(System.String)">
<summary>
Constructs an instance.
</summary>
</member>
<member name="M:Capnp.Rpc.InvalidCapabilityInterfaceException.#ctor(System.String,System.Exception)">
<summary>
Constructs an instance with message an inner exception.
</summary>
</member>
<member name="T:Capnp.Rpc.IPromisedAnswer"> <member name="T:Capnp.Rpc.IPromisedAnswer">
<summary> <summary>
A promised answer due to RPC. A promised answer due to RPC.
@ -1892,6 +2083,18 @@
A path from an outer Cap'n Proto struct to an inner (probably deeply nested) struct member. A path from an outer Cap'n Proto struct to an inner (probably deeply nested) struct member.
</summary> </summary>
</member> </member>
<member name="F:Capnp.Rpc.MemberAccessPath.BootstrapAccess">
<summary>
Path to the bootstrap capability (which is an empty path)
</summary>
</member>
<member name="M:Capnp.Rpc.MemberAccessPath.Deserialize(Capnp.Rpc.PromisedAnswer.READER)">
<summary>
Deserializes a MemberAccessPath from Cap'n Proto representation.
</summary>
<param name="promisedAnswer">Cap'n Proto representation</param>
<returns>The MemberAccessPath</returns>
</member>
<member name="M:Capnp.Rpc.MemberAccessPath.#ctor(System.Collections.Generic.IReadOnlyList{Capnp.Rpc.MemberAccessPath.MemberAccess})"> <member name="M:Capnp.Rpc.MemberAccessPath.#ctor(System.Collections.Generic.IReadOnlyList{Capnp.Rpc.MemberAccessPath.MemberAccess})">
<summary> <summary>
Constructs a path from <see cref="T:Capnp.Rpc.MemberAccessPath.MemberAccess"/> qualifiers. Constructs a path from <see cref="T:Capnp.Rpc.MemberAccessPath.MemberAccess"/> qualifiers.
@ -1914,6 +2117,13 @@
Now we already have a suitable design pattern, mainly to show the abstract concept behind a member access path. Now we already have a suitable design pattern, mainly to show the abstract concept behind a member access path.
</remarks> </remarks>
</member> </member>
<member name="M:Capnp.Rpc.MemberAccessPath.MemberAccess.Deserialize(Capnp.Rpc.PromisedAnswer.Op.READER)">
<summary>
Deserializes a MemberAccess instance from Cap'n Proto representation.
</summary>
<param name="op">Cap'n Proto representation</param>
<returns>Deserialized instance</returns>
</member>
<member name="M:Capnp.Rpc.MemberAccessPath.MemberAccess.Serialize(Capnp.Rpc.PromisedAnswer.Op.WRITER)"> <member name="M:Capnp.Rpc.MemberAccessPath.MemberAccess.Serialize(Capnp.Rpc.PromisedAnswer.Op.WRITER)">
<summary> <summary>
Serializes this instance to a <see cref="T:Capnp.Rpc.PromisedAnswer.Op"/>. Serializes this instance to a <see cref="T:Capnp.Rpc.PromisedAnswer.Op"/>.
@ -1984,6 +2194,72 @@
the ongoing call. the ongoing call.
</remarks> </remarks>
</member> </member>
<member name="T:Capnp.Rpc.PendingQuestion.State">
<summary>
Question lifetime management state
</summary>
</member>
<member name="F:Capnp.Rpc.PendingQuestion.State.None">
<summary>
The question has not yet been sent.
</summary>
</member>
<member name="F:Capnp.Rpc.PendingQuestion.State.TailCall">
<summary>
Tail call flag
</summary>
</member>
<member name="F:Capnp.Rpc.PendingQuestion.State.Sent">
<summary>
The question has been sent.
</summary>
</member>
<member name="F:Capnp.Rpc.PendingQuestion.State.Returned">
<summary>
The question has been answered.
</summary>
</member>
<member name="F:Capnp.Rpc.PendingQuestion.State.FinishRequested">
<summary>
A 'finish' request was sent to the peer, indicating that no further requests will refer
to this question.
</summary>
</member>
<member name="F:Capnp.Rpc.PendingQuestion.State.Disposed">
<summary>
Question object was disposed.
</summary>
</member>
<member name="F:Capnp.Rpc.PendingQuestion.State.Finalized">
<summary>
Question object was finalized by GC.
This flag should only be observable when debugging the finalizer itself.
</summary>
</member>
<member name="P:Capnp.Rpc.PendingQuestion.WhenReturned">
<summary>
Eventually returns the server answer
</summary>
</member>
<member name="M:Capnp.Rpc.PendingQuestion.Access(Capnp.Rpc.MemberAccessPath)">
<summary>
Refer to a (possibly nested) member of this question's (possibly future) result and return
it as a capability.
</summary>
<param name="access">Access path</param>
<returns>Low-level capability</returns>
<exception cref="T:Capnp.DeserializationException">The referenced member does not exist or does not resolve to a capability pointer.</exception>
</member>
<member name="M:Capnp.Rpc.PendingQuestion.Finalize">
<summary>
Finalizer
</summary>
</member>
<member name="M:Capnp.Rpc.PendingQuestion.Dispose">
<summary>
Implements <see cref="T:System.IDisposable"/>.
</summary>
</member>
<member name="T:Capnp.Rpc.PolySkeleton"> <member name="T:Capnp.Rpc.PolySkeleton">
<summary> <summary>
Combines multiple skeletons to represent objects which implement multiple interfaces. Combines multiple skeletons to represent objects which implement multiple interfaces.
@ -2024,6 +2300,11 @@
Will eventually give the resolved capability, if this is a promised capability. Will eventually give the resolved capability, if this is a promised capability.
</summary> </summary>
</member> </member>
<member name="P:Capnp.Rpc.Proxy.ConsumedCap">
<summary>
Underlying low-level capability
</summary>
</member>
<member name="P:Capnp.Rpc.Proxy.IsNull"> <member name="P:Capnp.Rpc.Proxy.IsNull">
<summary> <summary>
Whether is this a broken capability. Whether is this a broken capability.
@ -2041,13 +2322,23 @@
<returns>An answer promise</returns> <returns>An answer promise</returns>
<exception cref="T:System.ObjectDisposedException">This instance was disposed, or transport-layer stream was disposed.</exception> <exception cref="T:System.ObjectDisposedException">This instance was disposed, or transport-layer stream was disposed.</exception>
<exception cref="T:System.InvalidOperationException">Capability is broken.</exception> <exception cref="T:System.InvalidOperationException">Capability is broken.</exception>
<exception cref="!:IOException">An I/O error occurs.</exception> <exception cref="T:System.IO.IOException">An I/O error occurs.</exception>
</member>
<member name="M:Capnp.Rpc.Proxy.#ctor">
<summary>
Constructs a null instance.
</summary>
</member> </member>
<member name="M:Capnp.Rpc.Proxy.Dispose(System.Boolean)"> <member name="M:Capnp.Rpc.Proxy.Dispose(System.Boolean)">
<summary> <summary>
Dispose pattern implementation Dispose pattern implementation
</summary> </summary>
</member> </member>
<member name="M:Capnp.Rpc.Proxy.Finalize">
<summary>
Finalizer
</summary>
</member>
<member name="M:Capnp.Rpc.Proxy.Dispose"> <member name="M:Capnp.Rpc.Proxy.Dispose">
<summary> <summary>
Dispose pattern implementation Dispose pattern implementation
@ -2106,6 +2397,16 @@
Thrown when an RPC-related error condition occurs. Thrown when an RPC-related error condition occurs.
</summary> </summary>
</member> </member>
<member name="M:Capnp.Rpc.RpcException.#ctor(System.String)">
<summary>
Constructs an instance.
</summary>
</member>
<member name="M:Capnp.Rpc.RpcException.#ctor(System.String,System.Exception)">
<summary>
Constructs an instance with message and inner exception.
</summary>
</member>
<member name="T:Capnp.Rpc.Skeleton"> <member name="T:Capnp.Rpc.Skeleton">
<summary> <summary>
A skeleton is a wrapper around a capability interface implementation which adapts it in the way it is A skeleton is a wrapper around a capability interface implementation which adapts it in the way it is
@ -2135,6 +2436,11 @@
Dispose pattern implementation Dispose pattern implementation
</summary> </summary>
</member> </member>
<member name="M:Capnp.Rpc.Skeleton.Finalize">
<summary>
Finalizer
</summary>
</member>
<member name="T:Capnp.Rpc.Skeleton`1"> <member name="T:Capnp.Rpc.Skeleton`1">
<summary> <summary>
Skeleton for a specific capability interface. Skeleton for a specific capability interface.
@ -2262,6 +2568,36 @@
Cap'n Proto RPC TCP server. Cap'n Proto RPC TCP server.
</summary> </summary>
</member> </member>
<member name="T:Capnp.Rpc.TcpRpcServer.IConnection">
<summary>
Models an incoming connection.
</summary>
</member>
<member name="P:Capnp.Rpc.TcpRpcServer.IConnection.LocalPort">
<summary>
Server-side port
</summary>
</member>
<member name="P:Capnp.Rpc.TcpRpcServer.IConnection.RecvCount">
<summary>
Receive message counter
</summary>
</member>
<member name="P:Capnp.Rpc.TcpRpcServer.IConnection.SendCount">
<summary>
Sent message counter
</summary>
</member>
<member name="P:Capnp.Rpc.TcpRpcServer.IConnection.IsComputing">
<summary>
Whether the RPC engine is currently computing.
</summary>
</member>
<member name="P:Capnp.Rpc.TcpRpcServer.IConnection.IsWaitingForData">
<summary>
Whether the connection is idle, waiting for data to receive.
</summary>
</member>
<member name="P:Capnp.Rpc.TcpRpcServer.ConnectionCount"> <member name="P:Capnp.Rpc.TcpRpcServer.ConnectionCount">
<summary> <summary>
Gets the number of currently active inbound TCP connections. Gets the number of currently active inbound TCP connections.
@ -2352,6 +2688,16 @@
Helper struct to represent the tuple (segment index, offset) Helper struct to represent the tuple (segment index, offset)
</summary> </summary>
</member> </member>
<member name="F:Capnp.SegmentSlice.SegmentIndex">
<summary>
Segment index
</summary>
</member>
<member name="F:Capnp.SegmentSlice.Offset">
<summary>
Word offset within segment
</summary>
</member>
<member name="T:Capnp.SerializerExtensions"> <member name="T:Capnp.SerializerExtensions">
<summary> <summary>
Provides extensions to the <see cref="T:Capnp.IStructDeserializer"/> and <see cref="T:Capnp.IStructSerializer"/> interfaces for type-safe reading and writing. Provides extensions to the <see cref="T:Capnp.IStructDeserializer"/> and <see cref="T:Capnp.IStructSerializer"/> interfaces for type-safe reading and writing.
@ -2646,8 +2992,37 @@
anymore (e.g. changing from struct to list, or modifying the struct's section sizes). anymore (e.g. changing from struct to list, or modifying the struct's section sizes).
</summary> </summary>
</member> </member>
<!-- Badly formed XML comment ignored for member "M:Capnp.SerializerState.Link(System.Int32,Capnp.SerializerState,System.Boolean)" --> <member name="M:Capnp.SerializerState.Link(System.Int32,Capnp.SerializerState,System.Boolean)">
<!-- Badly formed XML comment ignored for member "M:Capnp.SerializerState.LinkToCapability(System.Int32,System.UInt32)" --> <summary>
Links a sub-item (struct field or list element) of this state to another state. Usually, this operation is not necessary, since objects are constructed top-down.
However, there might be some advanced scenarios where you want to reference the same object twice (also interesting for designing amplification attacks).
The Cap'n Proto serialization intrinsically supports this, since messages are object graphs, not trees.
</summary>
<param name="slot">If this state describes a struct: Index into this struct's pointer table.
If this state describes a list of pointers: List element index.</param>
<param name="target">state to be linked</param>
<param name="allowCopy">Whether to deep copy the target state if it belongs to a different message builder than this state.</param>
<exception cref="T:System.ArgumentNullException"><paramref name="target"/> is null</exception>
<exception cref="T:System.ArgumentOutOfRangeException"><paramref name="slot"/> out of range</exception>
<exception cref="T:System.InvalidOperationException"><list type="bullet">
<item><description>This state does neither describe a struct, nor a list of pointers</description></item>
<item><description>Another state is already linked to the specified position (sorry, no overwrite allowed)</description></item>
<item><description>This state and <paramref name="target"/> belong to different message builder, and<paramref name="allowCopy"/> is false</description></item>
</list>
</exception>
</member>
<member name="M:Capnp.SerializerState.LinkToCapability(System.Int32,System.UInt32)">
<summary>
Links a sub-item (struct field or list element) of this state to a capability.
</summary>
<param name="slot">If this state describes a struct: Index into this struct's pointer table.
If this state describes a list of pointers: List element index.</param>
<param name="capabilityIndex">capability index inside the capability table</param>
<exception cref="T:System.InvalidOperationException"><list type="bullet">
<item><description>This state does neither describe a struct, nor a list of pointers</description></item>
<item><description>Another state is already linked to the specified position (sorry, no overwrite allowed)</description></item></list>
</exception>
</member>
<member name="M:Capnp.SerializerState.SetStruct(System.UInt16,System.UInt16)"> <member name="M:Capnp.SerializerState.SetStruct(System.UInt16,System.UInt16)">
<summary> <summary>
Determines the underlying object to be a struct. Determines the underlying object to be a struct.
@ -2715,8 +3090,8 @@
<param name="count">Number of bits to read</param> <param name="count">Number of bits to read</param>
<returns>Data bits which were read</returns> <returns>Data bits which were read</returns>
<exception cref="T:System.InvalidOperationException">The object was not determined to be a struct</exception> <exception cref="T:System.InvalidOperationException">The object was not determined to be a struct</exception>
<exception cref="T:System.ArgumentOutOfRangeException">The data slice specified by <paramref name="bitOffset"/> and <paramref name="bitCount"/> <exception cref="T:System.ArgumentOutOfRangeException">The data slice specified by <paramref name="bitOffset"/> and <paramref name="count"/>
is not completely within the struct's data section, misaligned, exceeds one word, or <paramref name="bitCount"/> is negative</exception> is not completely within the struct's data section, misaligned, exceeds one word, or <paramref name="count"/> is negative</exception>
</member> </member>
<member name="M:Capnp.SerializerState.BuildPointer``1(System.Int32)"> <member name="M:Capnp.SerializerState.BuildPointer``1(System.Int32)">
<summary> <summary>
@ -2772,6 +3147,15 @@
</list></exception> </list></exception>
<exception cref="T:System.IndexOutOfRangeException"><paramref name="index"/> is out of bounds.</exception> <exception cref="T:System.IndexOutOfRangeException"><paramref name="index"/> is out of bounds.</exception>
</member> </member>
<member name="M:Capnp.SerializerState.ReadText(System.Int32,System.String)">
<summary>
Reads text from a struct field or list element.
</summary>
<param name="index">If the underlying object is a struct: index into the struct's pointer section.
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>
</member>
<member name="M:Capnp.SerializerState.WriteText(System.Int32,System.String)"> <member name="M:Capnp.SerializerState.WriteText(System.Int32,System.String)">
<summary> <summary>
Encodes text into a struct field or list element. Encodes text into a struct field or list element.
@ -2975,7 +3359,7 @@
<summary> <summary>
Adds an entry to the capability table if the provided capability does not yet exist. Adds an entry to the capability table if the provided capability does not yet exist.
</summary> </summary>
<param name="capability">The capability, in one of the following forms:<list type="bullet"> <param name="obj">The capability, in one of the following forms:<list type="bullet">
<item><description>Low-level capability object (<code>Rpc.ConsumedCapability</code>)</description></item> <item><description>Low-level capability object (<code>Rpc.ConsumedCapability</code>)</description></item>
<item><description>Proxy object (<code>Rpc.Proxy</code>)</description></item> <item><description>Proxy object (<code>Rpc.Proxy</code>)</description></item>
<item><description>Skeleton object (<code>Rpc.Skeleton</code>)</description></item> <item><description>Skeleton object (<code>Rpc.Skeleton</code>)</description></item>
@ -2984,8 +3368,41 @@
<returns>Index of the given capability in the capability table</returns> <returns>Index of the given capability in the capability table</returns>
<exception cref="T:System.InvalidOperationException">The underlying message builder was not configured for capability table support.</exception> <exception cref="T:System.InvalidOperationException">The underlying message builder was not configured for capability table support.</exception>
</member> </member>
<!-- Badly formed XML comment ignored for member "M:Capnp.SerializerState.LinkObject``1(System.Int32,``0)" --> <member name="M:Capnp.SerializerState.LinkObject``1(System.Int32,``0)">
<!-- Badly formed XML comment ignored for member "M:Capnp.SerializerState.ReadCap``1(System.Int32)" --> <summary>
Links a sub-item (struct field or list element) of this state to another object.
In contrast to <see cref="M:Capnp.SerializerState.Link(System.Int32,Capnp.SerializerState,System.Boolean)"/>, this method also accepts deserializer states, domain objects, capabilites, and lists thereof.
If necessary, it will perform a deep copy.
</summary>
<param name="slot">If this state describes a struct: Index into this struct's pointer table.
If this state describes a list of pointers: List element index.</param>
<param name="obj">Object to be linked. Must be one of the following:<list type="bullet">
<item><description>Another <see cref="T:Capnp.SerializerState"/></description></item>
<item><description>A <see cref="T:Capnp.DeserializerState"/> (will always deep copy)</description></item>
<item><description>An object implementing <see cref="T:Capnp.ICapnpSerializable"/></description></item>
<item><description>A low-level capability object (<see cref="T:Capnp.Rpc.ConsumedCapability"/>)</description></item>
<item><description>A proxy object (<see cref="T:Capnp.Rpc.Proxy"/>)</description></item>
<item><description>A skeleton object (<see cref="T:Capnp.Rpc.Skeleton"/>)</description></item>
<item><description>A capability interface implementation</description></item>
<item><description>A <see cref="T:System.Collections.Generic.IReadOnlyList`1"/> of one of the things listed here.</description></item>
</list></param>
<exception cref="T:System.ArgumentOutOfRangeException"><paramref name="slot"/> is out of range.</exception>
<exception cref="T:System.InvalidOperationException"><list type="bullet">
<item><description>This state does neither describe a struct, nor a list of pointers</description></item>
<item><description>Another state is already linked to the specified position (sorry, no overwrite allowed)</description></item></list>
</exception>
</member>
<member name="M:Capnp.SerializerState.ReadCap``1(System.Int32)">
<summary>
Reads a struct field as capability and returns a proxy to that capability.
</summary>
<typeparam name="T">Desired capability interface</typeparam>
<param name="slot">Index into this struct's pointer table.</param>
<returns>The proxy instance</returns>
<exception cref="T:System.ArgumentOutOfRangeException"><paramref name="slot"/> is out of range.</exception>
<exception cref="T:System.ArgumentException">The desired interface does not qualify as capability interface (<see cref="T:Capnp.Rpc.ProxyAttribute"/>)</exception>
<exception cref="T:System.InvalidOperationException">This state does not represent a struct.</exception>
</member>
<member name="M:Capnp.SerializerState.ReadCap(System.Int32)"> <member name="M:Capnp.SerializerState.ReadCap(System.Int32)">
<summary> <summary>
Reads a struct field as capability and returns a bare (generic) proxy to that capability. Reads a struct field as capability and returns a bare (generic) proxy to that capability.
@ -3022,7 +3439,6 @@
This method exists until NET Standard 2.1 is released This method exists until NET Standard 2.1 is released
</summary> </summary>
<param name="task"></param> <param name="task"></param>
<typeparam name="T"></typeparam>
<returns></returns> <returns></returns>
</member> </member>
<member name="T:Capnp.WireFrame"> <member name="T:Capnp.WireFrame">
@ -3042,7 +3458,27 @@
</member> </member>
<member name="T:Capnp.PointerKind"> <member name="T:Capnp.PointerKind">
<summary> <summary>
Pointer tag, <see cref="!:https://capnproto.org/encoding.html"/> Pointer tag, see https://capnproto.org/encoding.html/>
</summary>
</member>
<member name="F:Capnp.PointerKind.Struct">
<summary>
Struct pointer
</summary>
</member>
<member name="F:Capnp.PointerKind.List">
<summary>
List pointer
</summary>
</member>
<member name="F:Capnp.PointerKind.Far">
<summary>
Far pointer
</summary>
</member>
<member name="F:Capnp.PointerKind.Other">
<summary>
Other (capability) pointer
</summary> </summary>
</member> </member>
<member name="T:Capnp.WirePointer"> <member name="T:Capnp.WirePointer">

View File

@ -7,10 +7,16 @@ namespace Capnp
/// </summary> /// </summary>
public class DeserializationException : Exception public class DeserializationException : Exception
{ {
/// <summary>
/// Constructs an instance
/// </summary>
public DeserializationException(string message) : base(message) public DeserializationException(string message) : base(message)
{ {
} }
/// <summary>
/// Constructs an instance with message and inner exception
/// </summary>
public DeserializationException(string message, Exception innerException): public DeserializationException(string message, Exception innerException):
base(message, innerException) base(message, innerException)
{ {

View File

@ -637,6 +637,9 @@ namespace Capnp
/// </summary> /// </summary>
/// <typeparam name="T">Capability interface</typeparam> /// <typeparam name="T">Capability interface</typeparam>
/// <param name="index">index within this struct's pointer table</param> /// <param name="index">index within this struct's pointer table</param>
/// <param name="memberName">debugging aid</param>
/// <param name="sourceFilePath">debugging aid</param>
/// <param name="sourceLineNumber">debugging aid</param>
/// <returns>capability instance or null if pointer was null</returns> /// <returns>capability instance or null if pointer was null</returns>
/// <exception cref="IndexOutOfRangeException">negative index</exception> /// <exception cref="IndexOutOfRangeException">negative index</exception>
/// <exception cref="DeserializationException">state does not represent a struct, invalid pointer, /// <exception cref="DeserializationException">state does not represent a struct, invalid pointer,

View File

@ -61,8 +61,8 @@ namespace Capnp
/// <exception cref="ArgumentNullException"><paramref name="target"/> is null</exception> /// <exception cref="ArgumentNullException"><paramref name="target"/> is null</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="slot"/> out of range</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="slot"/> out of range</exception>
/// <exception cref="InvalidOperationException"><list type="bullet"> /// <exception cref="InvalidOperationException"><list type="bullet">
/// <item><description>This state does neither describe a struct, nor a list of pointers</description></item></list> /// <item><description>This state does neither describe a struct, nor a list of pointers</description></item>
/// <item><description>Another state is already linked to the specified position (sorry, no overwrite allowed)</description></item></list> /// <item><description>Another state is already linked to the specified position (sorry, no overwrite allowed)</description></item>
/// <item><description>This state and <paramref name="target"/> belong to different message builder, and<paramref name="allowCopy"/> is false</description></item></list> /// <item><description>This state and <paramref name="target"/> belong to different message builder, and<paramref name="allowCopy"/> is false</description></item></list>
/// </exception> /// </exception>
public new void Link(int slot, SerializerState target, bool allowCopy = true) => base.Link(slot, target, allowCopy); public new void Link(int slot, SerializerState target, bool allowCopy = true) => base.Link(slot, target, allowCopy);
@ -74,7 +74,7 @@ namespace Capnp
/// If this state describes a list of pointers: List element index.</param> /// If this state describes a list of pointers: List element index.</param>
/// <param name="capabilityIndex">capability index inside the capability table</param> /// <param name="capabilityIndex">capability index inside the capability table</param>
/// <exception cref="InvalidOperationException"><list type="bullet"> /// <exception cref="InvalidOperationException"><list type="bullet">
/// <item><description>This state does neither describe a struct, nor a list of pointers</description></item></list> /// <item><description>This state does neither describe a struct, nor a list of pointers</description></item>
/// <item><description>Another state is already linked to the specified position (sorry, no overwrite allowed)</description></item></list> /// <item><description>Another state is already linked to the specified position (sorry, no overwrite allowed)</description></item></list>
/// </exception> /// </exception>
public new void LinkToCapability(int slot, uint capabilityIndex) => base.LinkToCapability(slot, capabilityIndex); public new void LinkToCapability(int slot, uint capabilityIndex) => base.LinkToCapability(slot, capabilityIndex);
@ -123,24 +123,25 @@ namespace Capnp
/// <item><description>An instance implementing <see cref="ICapnpSerializable"/></description></item> /// <item><description>An instance implementing <see cref="ICapnpSerializable"/></description></item>
/// <item><description>null</description></item> /// <item><description>null</description></item>
/// <item><description>A <see cref="String"/></description></item> /// <item><description>A <see cref="String"/></description></item>
/// <item><description>A <see cref="IReadOnlyList{Byte}"/></description></item> /// <item><description>A <code><![CDATA[IReadOnlyList<byte>]]></code></description></item>
/// <item><description>A <see cref="IReadOnlyList{SByte}"/></description></item> /// <item><description>A <code><![CDATA[IReadOnlyList<sbyte>]]></code></description></item>
/// <item><description>A <see cref="IReadOnlyList{UInt16}"/></description></item> /// <item><description>A <code><![CDATA[IReadOnlyList<ushort>]]></code></description></item>
/// <item><description>A <see cref="IReadOnlyList{Int16}"/></description></item> /// <item><description>A <code><![CDATA[IReadOnlyList<short>]]></code></description></item>
/// <item><description>A <see cref="IReadOnlyList{UInt32}"/></description></item> /// <item><description>A <code><![CDATA[IReadOnlyList<int>]]></code></description></item>
/// <item><description>A <see cref="IReadOnlyList{Int64}"/></description></item> /// <item><description>A <code><![CDATA[IReadOnlyList<uint>]]></code></description></item>
/// <item><description>A <see cref="IReadOnlyList{UInt64}"/></description></item> /// <item><description>A <code><![CDATA[IReadOnlyList<long>]]></code></description></item>
/// <item><description>A <see cref="IReadOnlyList{Single}"/></description></item> /// <item><description>A <code><![CDATA[IReadOnlyList<ulong>]]></code></description></item>
/// <item><description>A <see cref="IReadOnlyList{Double}"/></description></item> /// <item><description>A <code><![CDATA[IReadOnlyList<float>]]></code></description></item>
/// <item><description>A <see cref="IReadOnlyList{Boolean}/></description></item> /// <item><description>A <code><![CDATA[IReadOnlyList<double>]]></code></description></item>
/// <item><description>A <see cref="IReadOnlyList{String}"/></description></item> /// <item><description>A <code><![CDATA[IReadOnlyList<bool>]]></code></description></item>
/// <item><description>A <code><![CDATA[IReadOnlyList<string>]]></code></description></item>
/// <item><description>Another <see cref="DeserializerState"/></description></item> /// <item><description>Another <see cref="DeserializerState"/></description></item>
/// <item><description>Another <see cref="SerializerState"/></description></item> /// <item><description>Another <see cref="SerializerState"/></description></item>
/// <item><description>Low-level capability object (<see cref="Rpc.ConsumedCapability"/>)</description></item> /// <item><description>Low-level capability object (<see cref="Rpc.ConsumedCapability"/>)</description></item>
/// <item><description>Proxy object (<see cref="Rpc.Proxy"/>)</description></item> /// <item><description>Proxy object (<see cref="Rpc.Proxy"/>)</description></item>
/// <item><description>Skeleton object (<see cref="Rpc.Skeleton"/>)</description></item> /// <item><description>Skeleton object (<see cref="Rpc.Skeleton"/>)</description></item>
/// <item><description>Capability interface implementation</description></item> /// <item><description>Capability interface implementation</description></item>
/// <item><description>A <see cref="IReadOnlyList{Object}"/> whereby each list item is one of the things listed here.</description></item> /// <item><description>A <code><![CDATA[IReadOnlyList<object>]]></code> whereby each list item is one of the things listed here.</description></item>
/// </list> /// </list>
/// </param> /// </param>
public void SetObject(object obj) public void SetObject(object obj)

View File

@ -21,47 +21,47 @@ namespace Capnp
public override IReadOnlyList<T> Cast<T>(Func<DeserializerState, T> cons) => new EmptyList<T>(); public override IReadOnlyList<T> Cast<T>(Func<DeserializerState, T> cons) => new EmptyList<T>();
/// <summary> /// <summary>
/// Returns an empty <see cref="IReadOnlyList{Boolean}"/>. /// Returns an empty <code><![CDATA[IReadOnlyList<bool>]]></code>/>.
/// </summary> /// </summary>
public override IReadOnlyList<bool> CastBool() => new EmptyList<bool>(); public override IReadOnlyList<bool> CastBool() => new EmptyList<bool>();
/// <summary> /// <summary>
/// Returns an empty <see cref="IReadOnlyList{Byte}"/>. /// Returns an empty <code><![CDATA[IReadOnlyList<byte>]]></code>/>.
/// </summary> /// </summary>
public override IReadOnlyList<byte> CastByte() => new EmptyList<byte>(); public override IReadOnlyList<byte> CastByte() => new EmptyList<byte>();
/// <summary> /// <summary>
/// Returns an empty <see cref="IReadOnlyList{Double}"/>. /// Returns an empty <code><![CDATA[IReadOnlyList<double>]]></code>/>.
/// </summary> /// </summary>
public override IReadOnlyList<double> CastDouble() => new EmptyList<double>(); public override IReadOnlyList<double> CastDouble() => new EmptyList<double>();
/// <summary> /// <summary>
/// Returns an empty <see cref="IReadOnlyList{Single}"./> /// Returns an empty <code><![CDATA[IReadOnlyList<float>]]></code>.
/// </summary> /// </summary>
public override IReadOnlyList<float> CastFloat() => new EmptyList<float>(); public override IReadOnlyList<float> CastFloat() => new EmptyList<float>();
/// <summary> /// <summary>
/// Returns an empty <see cref="IReadOnlyList{Int32}"/>. /// Returns an empty <code><![CDATA[IReadOnlyList<int>]]></code>.
/// </summary> /// </summary>
public override IReadOnlyList<int> CastInt() => new EmptyList<int>(); public override IReadOnlyList<int> CastInt() => new EmptyList<int>();
/// <summary> /// <summary>
/// Returns an empty <see cref="IReadOnlyList{ListDeserializer}"/>. /// Returns an empty <code><![CDATA[IReadOnlyList<ListDeserializer>]]></code>.
/// </summary> /// </summary>
public override IReadOnlyList<ListDeserializer> CastList() => new EmptyList<ListDeserializer>(); public override IReadOnlyList<ListDeserializer> CastList() => new EmptyList<ListDeserializer>();
/// <summary> /// <summary>
/// Returns an empty <see cref="IReadOnlyList{Int64}"/>. /// Returns an empty <code><![CDATA[IReadOnlyList<long>]]></code>/>.
/// </summary> /// </summary>
public override IReadOnlyList<long> CastLong() => new EmptyList<long>(); public override IReadOnlyList<long> CastLong() => new EmptyList<long>();
/// <summary> /// <summary>
/// Returns an empty <see cref="IReadOnlyList{SByte}"/>. /// Returns an empty <code><![CDATA[IReadOnlyList<sbyte>]]></code>.
/// </summary> /// </summary>
public override IReadOnlyList<sbyte> CastSByte() => new EmptyList<sbyte>(); public override IReadOnlyList<sbyte> CastSByte() => new EmptyList<sbyte>();
/// <summary> /// <summary>
/// Returns an empty <see cref="IReadOnlyList{Int16}"/>. /// Returns an empty <code><![CDATA[IReadOnlyList<short>]]></code>.
/// </summary> /// </summary>
public override IReadOnlyList<short> CastShort() => new EmptyList<short>(); public override IReadOnlyList<short> CastShort() => new EmptyList<short>();
@ -71,17 +71,17 @@ namespace Capnp
public override string CastText() => string.Empty; public override string CastText() => string.Empty;
/// <summary> /// <summary>
/// Returns an empty <see cref="IReadOnlyList{UInt32}"/>. /// Returns an empty <code><![CDATA[IReadOnlyList<uint>]]></code>.
/// </summary> /// </summary>
public override IReadOnlyList<uint> CastUInt() => new EmptyList<uint>(); public override IReadOnlyList<uint> CastUInt() => new EmptyList<uint>();
/// <summary> /// <summary>
/// Returns an empty <see cref="IReadOnlyList{UInt64}"/>. /// Returns an empty <code><![CDATA[IReadOnlyList<ulong>]]></code>.
/// </summary> /// </summary>
public override IReadOnlyList<ulong> CastULong() => new EmptyList<ulong>(); public override IReadOnlyList<ulong> CastULong() => new EmptyList<ulong>();
/// <summary> /// <summary>
/// Returns an empty <see cref="IReadOnlyList{UInt16}"/>. /// Returns an empty <code><![CDATA[IReadOnlyList<ushort>]]></code>.
/// </summary> /// </summary>
public override IReadOnlyList<ushort> CastUShort() => new EmptyList<ushort>(); public override IReadOnlyList<ushort> CastUShort() => new EmptyList<ushort>();
} }

View File

@ -31,6 +31,11 @@ namespace Capnp
} }
} }
/// <summary>
/// Deserializes the next Cap'n Proto message from given stream.
/// </summary>
/// <param name="reader">The stream to read from</param>
/// <returns>The message</returns>
public static WireFrame ReadWireFrame(this BinaryReader reader) public static WireFrame ReadWireFrame(this BinaryReader reader)
{ {
uint scount = reader.ReadUInt32(); uint scount = reader.ReadUInt32();

View File

@ -360,12 +360,12 @@ namespace Capnp
return Cast(sd => sd.ReadDataUInt(0)); return Cast(sd => sd.ReadDataUInt(0));
} }
public virtual IReadOnlyList<long> CastLong()
/// <summary> /// <summary>
/// Represents this list as List(Int64). /// Represents this list as List(Int64).
/// </summary> /// </summary>
/// <returns>The desired representation</returns> /// <returns>The desired representation</returns>
/// <exception cref="NotSupportedException">If this list cannot be represented in the desired manner.</exception> /// <exception cref="NotSupportedException">If this list cannot be represented in the desired manner.</exception>
public virtual IReadOnlyList<long> CastLong()
{ {
return Cast(sd => sd.ReadDataLong(0)); return Cast(sd => sd.ReadDataLong(0));
} }

View File

@ -50,7 +50,7 @@ namespace Capnp
} }
/// <summary> /// <summary>
/// Implements <see cref="IEnumerable{bool}"/> /// Implements <see cref="IEnumerable{T}"/>
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public IEnumerator<bool> GetEnumerator() public IEnumerator<bool> GetEnumerator()

View File

@ -56,7 +56,7 @@ namespace Capnp
} }
/// <summary> /// <summary>
/// Implements <see cref="IEnumerable{T}"./> /// Implements <see cref="IEnumerable{T}"/>.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public IEnumerator<T> GetEnumerator() public IEnumerator<T> GetEnumerator()

View File

@ -95,7 +95,7 @@ namespace Capnp
} }
/// <summary> /// <summary>
/// Implements <see cref="IEnumerable{T}"./> /// Implements <see cref="IEnumerable{T}"/>.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public IEnumerator<T> GetEnumerator() public IEnumerator<T> GetEnumerator()

View File

@ -66,7 +66,7 @@ namespace Capnp
} }
/// <summary> /// <summary>
/// Implements <see cref="IEnumerable{DeserializerState}"./> /// Implements <see cref="IEnumerable{DeserializerState}"/>.
/// </summary> /// </summary>
public IEnumerator<DeserializerState> GetEnumerator() public IEnumerator<DeserializerState> GetEnumerator()
{ {

View File

@ -38,7 +38,7 @@ namespace Capnp
} }
/// <summary> /// <summary>
/// LINQ-like "Select" operator for <see cref="IReadOnlyList{T}", with the addition that the resulting elements are accessible by index. /// LINQ-like "Select" operator for <see cref="IReadOnlyList{T}"/>, with the addition that the resulting elements are accessible by index.
/// The operator implements lazy semantics, which means that the selector function results are not cached./> /// The operator implements lazy semantics, which means that the selector function results are not cached./>
/// </summary> /// </summary>
/// <typeparam name="From">Source element type</typeparam> /// <typeparam name="From">Source element type</typeparam>

View File

@ -12,17 +12,32 @@
_obj = obj; _obj = obj;
} }
/// <summary>
/// Wraps a SerializerState
/// </summary>
/// <param name="answer">object to wrap</param>
public static implicit operator AnswerOrCounterquestion (SerializerState answer) public static implicit operator AnswerOrCounterquestion (SerializerState answer)
{ {
return new AnswerOrCounterquestion(answer); return new AnswerOrCounterquestion(answer);
} }
/// <summary>
/// Wraps a PendingQuestion
/// </summary>
/// <param name="counterquestion">object to wrap</param>
public static implicit operator AnswerOrCounterquestion (PendingQuestion counterquestion) public static implicit operator AnswerOrCounterquestion (PendingQuestion counterquestion)
{ {
return new AnswerOrCounterquestion(counterquestion); return new AnswerOrCounterquestion(counterquestion);
} }
/// <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;
} }
} }

View File

@ -10,13 +10,13 @@
/// </summary> /// </summary>
/// <param name="impl">Capability implementation</param> /// <param name="impl">Capability implementation</param>
/// <returns>Proxy</returns> /// <returns>Proxy</returns>
/// <exception cref="ArgumentNullException"><paramref name="impl"/> is null.</exception> /// <exception cref="System.ArgumentNullException"><paramref name="impl"/> is null.</exception>
/// <exception cref="InvalidCapabilityInterfaceException">No <see cref="SkeletonAttribute"/> found on implemented interface(s).</exception> /// <exception cref="InvalidCapabilityInterfaceException">No <see cref="SkeletonAttribute"/> found on implemented interface(s).</exception>
/// <exception cref="InvalidOperationException">Mismatch between generic type arguments (if capability interface is generic).</exception> /// <exception cref="System.InvalidOperationException">Mismatch between generic type arguments (if capability interface is generic).</exception>
/// <exception cref="ArgumentException">Mismatch between generic type arguments (if capability interface is generic).</exception> /// <exception cref="System.ArgumentException">Mismatch between generic type arguments (if capability interface is generic).</exception>
/// <exception cref="System.Reflection.TargetInvocationException">Problem with instatiating the Skeleton (constructor threw exception).</exception> /// <exception cref="System.Reflection.TargetInvocationException">Problem with instatiating the Skeleton (constructor threw exception).</exception>
/// <exception cref="MemberAccessException">Caller does not have permission to invoke the Skeleton constructor.</exception> /// <exception cref="System.MemberAccessException">Caller does not have permission to invoke the Skeleton constructor.</exception>
/// <exception cref="TypeLoadException">Problem with building the Skeleton type, or problem with loading some dependent class.</exception> /// <exception cref="System.TypeLoadException">Problem with building the Skeleton type, or problem with loading some dependent class.</exception>
public static BareProxy FromImpl(object impl) public static BareProxy FromImpl(object impl)
{ {
return new BareProxy(LocalCapability.Create(CapabilityReflection.CreateSkeleton(impl))); return new BareProxy(LocalCapability.Create(CapabilityReflection.CreateSkeleton(impl)));

View File

@ -252,6 +252,9 @@ namespace Capnp.Rpc
/// </summary> /// </summary>
/// <typeparam name="TInterface">Capability interface. Must be annotated with <see cref="ProxyAttribute"/>.</typeparam> /// <typeparam name="TInterface">Capability interface. Must be annotated with <see cref="ProxyAttribute"/>.</typeparam>
/// <param name="cap">low-level capability</param> /// <param name="cap">low-level capability</param>
/// <param name="memberName">debugging aid</param>
/// <param name="sourceFilePath">debugging aid</param>
/// <param name="sourceLineNumber">debugging aid</param>
/// <returns>The Proxy instance which implements <typeparamref name="TInterface"/>.</returns> /// <returns>The Proxy instance which implements <typeparamref name="TInterface"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="cap"/> is null.</exception> /// <exception cref="ArgumentNullException"><paramref name="cap"/> is null.</exception>
/// <exception cref="InvalidCapabilityInterfaceException"><typeparamref name="TInterface"/> did not qualify as capability interface.</exception> /// <exception cref="InvalidCapabilityInterfaceException"><typeparamref name="TInterface"/> did not qualify as capability interface.</exception>

View File

@ -81,6 +81,9 @@ namespace Capnp.Rpc
/// </summary> /// </summary>
/// <typeparam name="TInterface">Capability interface type</typeparam> /// <typeparam name="TInterface">Capability interface type</typeparam>
/// <param name="task">The task</param> /// <param name="task">The task</param>
/// <param name="memberName">debugging aid</param>
/// <param name="sourceFilePath">debugging aid</param>
/// <param name="sourceLineNumber">debugging aid</param>
/// <returns>A proxy for the given task.</returns> /// <returns>A proxy for the given task.</returns>
/// <exception cref="ArgumentNullException"><paramref name="task"/> is null.</exception> /// <exception cref="ArgumentNullException"><paramref name="task"/> is null.</exception>
/// <exception cref="InvalidCapabilityInterfaceException"><typeparamref name="TInterface"/> did not /// <exception cref="InvalidCapabilityInterfaceException"><typeparamref name="TInterface"/> did not
@ -101,6 +104,13 @@ namespace Capnp.Rpc
set { _askingEndpoint.Value = value; } set { _askingEndpoint.Value = value; }
} }
/// <summary>
/// Checks whether a given task belongs to a pending RPC and requests a tail call if applicable.
/// </summary>
/// <typeparam name="T">Task result type</typeparam>
/// <param name="task">Task to request</param>
/// <param name="func">Converts the task's result to a SerializerState</param>
/// <returns>Tail-call aware task</returns>
public static async Task<AnswerOrCounterquestion> MaybeTailCall<T>(Task<T> task, Func<T, SerializerState> func) public static async Task<AnswerOrCounterquestion> MaybeTailCall<T>(Task<T> task, Func<T, SerializerState> func)
{ {
if (TryGetAnswer(task) is PendingQuestion pendingQuestion && if (TryGetAnswer(task) is PendingQuestion pendingQuestion &&
@ -115,31 +125,49 @@ namespace Capnp.Rpc
} }
} }
/// <summary>
/// Overload for tuple-typed tasks
/// </summary>
public static Task<AnswerOrCounterquestion> MaybeTailCall<T1, T2>(Task<(T1, T2)> task, Func<T1, T2, SerializerState> func) public static Task<AnswerOrCounterquestion> MaybeTailCall<T1, T2>(Task<(T1, T2)> task, Func<T1, T2, SerializerState> func)
{ {
return MaybeTailCall(task, (ValueTuple<T1, T2> t) => func(t.Item1, t.Item2)); return MaybeTailCall(task, (ValueTuple<T1, T2> t) => func(t.Item1, t.Item2));
} }
/// <summary>
/// Overload for tuple-typed tasks
/// </summary>
public static Task<AnswerOrCounterquestion> MaybeTailCall<T1, T2, T3>(Task<(T1, T2, T3)> task, Func<T1, T2, T3, SerializerState> func) public static Task<AnswerOrCounterquestion> MaybeTailCall<T1, T2, T3>(Task<(T1, T2, T3)> task, Func<T1, T2, T3, SerializerState> func)
{ {
return MaybeTailCall(task, (ValueTuple<T1, T2, T3> t) => func(t.Item1, t.Item2, t.Item3)); return MaybeTailCall(task, (ValueTuple<T1, T2, T3> t) => func(t.Item1, t.Item2, t.Item3));
} }
/// <summary>
/// Overload for tuple-typed tasks
/// </summary>
public static Task<AnswerOrCounterquestion> MaybeTailCall<T1, T2, T3, T4>(Task<(T1, T2, T3, T4)> task, Func<T1, T2, T3, T4, SerializerState> func) public static Task<AnswerOrCounterquestion> MaybeTailCall<T1, T2, T3, T4>(Task<(T1, T2, T3, T4)> task, Func<T1, T2, T3, T4, SerializerState> func)
{ {
return MaybeTailCall(task, (ValueTuple<T1, T2, T3, T4> t) => func(t.Item1, t.Item2, t.Item3, t.Item4)); return MaybeTailCall(task, (ValueTuple<T1, T2, T3, T4> t) => func(t.Item1, t.Item2, t.Item3, t.Item4));
} }
/// <summary>
/// Overload for tuple-typed tasks
/// </summary>
public static Task<AnswerOrCounterquestion> MaybeTailCall<T1, T2, T3, T4, T5>(Task<(T1, T2, T3, T4, T5)> task, Func<T1, T2, T3, T4, T5, SerializerState> func) public static Task<AnswerOrCounterquestion> MaybeTailCall<T1, T2, T3, T4, T5>(Task<(T1, T2, T3, T4, T5)> task, Func<T1, T2, T3, T4, T5, SerializerState> func)
{ {
return MaybeTailCall(task, (ValueTuple<T1, T2, T3, T4, T5> t) => func(t.Item1, t.Item2, t.Item3, t.Item4, t.Item5)); return MaybeTailCall(task, (ValueTuple<T1, T2, T3, T4, T5> t) => func(t.Item1, t.Item2, t.Item3, t.Item4, t.Item5));
} }
/// <summary>
/// Overload for tuple-typed tasks
/// </summary>
public static Task<AnswerOrCounterquestion> MaybeTailCall<T1, T2, T3, T4, T5, T6>(Task<(T1, T2, T3, T4, T5, T6)> task, Func<T1, T2, T3, T4, T5, T6, SerializerState> func) public static Task<AnswerOrCounterquestion> MaybeTailCall<T1, T2, T3, T4, T5, T6>(Task<(T1, T2, T3, T4, T5, T6)> task, Func<T1, T2, T3, T4, T5, T6, SerializerState> func)
{ {
return MaybeTailCall(task, (ValueTuple<T1, T2, T3, T4, T5, T6> t) => func(t.Item1, t.Item2, t.Item3, t.Item4, t.Item5, t.Item6)); return MaybeTailCall(task, (ValueTuple<T1, T2, T3, T4, T5, T6> t) => func(t.Item1, t.Item2, t.Item3, t.Item4, t.Item5, t.Item6));
} }
/// <summary>
/// Overload for tuple-typed tasks
/// </summary>
public static Task<AnswerOrCounterquestion> MaybeTailCall<T1, T2, T3, T4, T5, T6, T7>(Task<(T1, T2, T3, T4, T5, T6, T7)> task, Func<T1, T2, T3, T4, T5, T6, T7, SerializerState> func) public static Task<AnswerOrCounterquestion> MaybeTailCall<T1, T2, T3, T4, T5, T6, T7>(Task<(T1, T2, T3, T4, T5, T6, T7)> task, Func<T1, T2, T3, T4, T5, T6, T7, SerializerState> func)
{ {
return MaybeTailCall(task, (ValueTuple<T1, T2, T3, T4, T5, T6, T7> t) => func(t.Item1, t.Item2, t.Item3, t.Item4, t.Item5, t.Item6, t.Item7)); return MaybeTailCall(task, (ValueTuple<T1, T2, T3, T4, T5, T6, T7> t) => func(t.Item1, t.Item2, t.Item3, t.Item4, t.Item5, t.Item6, t.Item7));

View File

@ -7,10 +7,16 @@
/// </summary> /// </summary>
public class InvalidCapabilityInterfaceException : System.Exception public class InvalidCapabilityInterfaceException : System.Exception
{ {
/// <summary>
/// Constructs an instance.
/// </summary>
public InvalidCapabilityInterfaceException(string message) : base(message) public InvalidCapabilityInterfaceException(string message) : base(message)
{ {
} }
/// <summary>
/// Constructs an instance with message an inner exception.
/// </summary>
public InvalidCapabilityInterfaceException(string message, System.Exception innerException) : base(message, innerException) public InvalidCapabilityInterfaceException(string message, System.Exception innerException) : base(message, innerException)
{ {
} }

View File

@ -9,8 +9,16 @@ namespace Capnp.Rpc
/// </summary> /// </summary>
public class MemberAccessPath public class MemberAccessPath
{ {
/// <summary>
/// Path to the bootstrap capability (which is an empty path)
/// </summary>
public static readonly MemberAccessPath BootstrapAccess = new MemberAccessPath(new List<MemberAccess>()); public static readonly MemberAccessPath BootstrapAccess = new MemberAccessPath(new List<MemberAccess>());
/// <summary>
/// Deserializes a MemberAccessPath from Cap'n Proto representation.
/// </summary>
/// <param name="promisedAnswer">Cap'n Proto representation</param>
/// <returns>The MemberAccessPath</returns>
public static MemberAccessPath Deserialize(PromisedAnswer.READER promisedAnswer) public static MemberAccessPath Deserialize(PromisedAnswer.READER promisedAnswer)
{ {
var ops = new MemberAccess[promisedAnswer.Transform.Count]; var ops = new MemberAccess[promisedAnswer.Transform.Count];
@ -55,6 +63,11 @@ namespace Capnp.Rpc
/// </remarks> /// </remarks>
public abstract class MemberAccess public abstract class MemberAccess
{ {
/// <summary>
/// Deserializes a MemberAccess instance from Cap'n Proto representation.
/// </summary>
/// <param name="op">Cap'n Proto representation</param>
/// <returns>Deserialized instance</returns>
public static MemberAccess Deserialize(PromisedAnswer.Op.READER op) public static MemberAccess Deserialize(PromisedAnswer.Op.READER op)
{ {
switch (op.which) switch (op.which)

View File

@ -15,15 +15,47 @@ namespace Capnp.Rpc
/// </remarks> /// </remarks>
public sealed class PendingQuestion: IPromisedAnswer public sealed class PendingQuestion: IPromisedAnswer
{ {
/// <summary>
/// Question lifetime management state
/// </summary>
[Flags] [Flags]
public enum State public enum State
{ {
/// <summary>
/// The question has not yet been sent.
/// </summary>
None = 0, None = 0,
/// <summary>
/// Tail call flag
/// </summary>
TailCall = 1, TailCall = 1,
/// <summary>
/// The question has been sent.
/// </summary>
Sent = 2, Sent = 2,
/// <summary>
/// The question has been answered.
/// </summary>
Returned = 4, Returned = 4,
/// <summary>
/// A 'finish' request was sent to the peer, indicating that no further requests will refer
/// to this question.
/// </summary>
FinishRequested = 8, FinishRequested = 8,
/// <summary>
/// Question object was disposed.
/// </summary>
Disposed = 16, Disposed = 16,
/// <summary>
/// Question object was finalized by GC.
/// This flag should only be observable when debugging the finalizer itself.
/// </summary>
Finalized = 32 Finalized = 32
} }
@ -59,7 +91,12 @@ namespace Capnp.Rpc
internal object ReentrancyBlocker { get; } = new object(); internal object ReentrancyBlocker { get; } = new object();
internal uint QuestionId => _questionId; internal uint QuestionId => _questionId;
internal State StateFlags { get; private set; } internal State StateFlags { get; private set; }
/// <summary>
/// Eventually returns the server answer
/// </summary>
public Task<DeserializerState> WhenReturned => _tcs.Task; public Task<DeserializerState> WhenReturned => _tcs.Task;
internal bool IsTailCall internal bool IsTailCall
{ {
get => StateFlags.HasFlag(State.TailCall); get => StateFlags.HasFlag(State.TailCall);
@ -189,6 +226,13 @@ namespace Capnp.Rpc
DeleteMyQuestion(); DeleteMyQuestion();
} }
/// <summary>
/// Refer to a (possibly nested) member of this question's (possibly future) result and return
/// it as a capability.
/// </summary>
/// <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) lock (ReentrancyBlocker)
@ -296,11 +340,17 @@ namespace Capnp.Rpc
ReleaseCaps(target, inParams); ReleaseCaps(target, inParams);
} }
/// <summary>
/// Finalizer
/// </summary>
~PendingQuestion() ~PendingQuestion()
{ {
Dispose(false); Dispose(false);
} }
/// <summary>
/// Implements <see cref="IDisposable"/>.
/// </summary>
public void Dispose() public void Dispose()
{ {
Dispose(true); Dispose(true);

View File

@ -35,6 +35,9 @@ namespace Capnp.Rpc
} }
} }
/// <summary>
/// Underlying low-level capability
/// </summary>
protected internal ConsumedCapability ConsumedCap { get; private set; } protected internal ConsumedCapability ConsumedCap { get; private set; }
/// <summary> /// <summary>
@ -68,7 +71,7 @@ namespace Capnp.Rpc
/// <returns>An answer promise</returns> /// <returns>An answer promise</returns>
/// <exception cref="ObjectDisposedException">This instance was disposed, or transport-layer stream was disposed.</exception> /// <exception cref="ObjectDisposedException">This instance was disposed, or transport-layer stream was disposed.</exception>
/// <exception cref="InvalidOperationException">Capability is broken.</exception> /// <exception cref="InvalidOperationException">Capability is broken.</exception>
/// <exception cref="IOException">An I/O error occurs.</exception> /// <exception cref="System.IO.IOException">An I/O error occurs.</exception>
protected internal IPromisedAnswer Call(ulong interfaceId, ushort methodId, DynamicSerializerState args, bool tailCall, CancellationToken cancellationToken = default) protected internal IPromisedAnswer Call(ulong interfaceId, ushort methodId, DynamicSerializerState args, bool tailCall, CancellationToken cancellationToken = default)
{ {
if (_disposedValue) if (_disposedValue)
@ -87,6 +90,9 @@ namespace Capnp.Rpc
return answer; return answer;
} }
/// <summary>
/// Constructs a null instance.
/// </summary>
public Proxy() public Proxy()
{ {
} }
@ -135,6 +141,9 @@ namespace Capnp.Rpc
} }
} }
/// <summary>
/// Finalizer
/// </summary>
~Proxy() ~Proxy()
{ {
#if DebugFinalizers #if DebugFinalizers

View File

@ -5,10 +5,16 @@
/// </summary> /// </summary>
public class RpcException : System.Exception public class RpcException : System.Exception
{ {
/// <summary>
/// Constructs an instance.
/// </summary>
public RpcException(string message) : base(message) public RpcException(string message) : base(message)
{ {
} }
/// <summary>
/// Constructs an instance with message and inner exception.
/// </summary>
public RpcException(string message, System.Exception innerException) : base(message, innerException) public RpcException(string message, System.Exception innerException) : base(message, innerException)
{ {
} }

View File

@ -101,6 +101,9 @@ namespace Capnp.Rpc
{ {
} }
/// <summary>
/// Finalizer
/// </summary>
~Skeleton() ~Skeleton()
{ {
Dispose(false); Dispose(false);

View File

@ -14,12 +14,34 @@ namespace Capnp.Rpc
/// </summary> /// </summary>
public class TcpRpcServer: IDisposable public class TcpRpcServer: IDisposable
{ {
/// <summary>
/// Models an incoming connection.
/// </summary>
public interface IConnection public interface IConnection
{ {
/// <summary>
/// Server-side port
/// </summary>
int LocalPort { get; } int LocalPort { get; }
/// <summary>
/// Receive message counter
/// </summary>
long RecvCount { get; } long RecvCount { get; }
/// <summary>
/// Sent message counter
/// </summary>
long SendCount { get; } long SendCount { get; }
/// <summary>
/// Whether the RPC engine is currently computing.
/// </summary>
bool IsComputing { get; } bool IsComputing { get; }
/// <summary>
/// Whether the connection is idle, waiting for data to receive.
/// </summary>
bool IsWaitingForData { get; } bool IsWaitingForData { get; }
} }

View File

@ -1,3 +1,5 @@
#pragma warning disable CS1591
using Capnp; using Capnp;
using Capnp.Rpc; using Capnp.Rpc;
using System; using System;

View File

@ -7,7 +7,14 @@ namespace Capnp
/// </summary> /// </summary>
public struct SegmentSlice public struct SegmentSlice
{ {
/// <summary>
/// Segment index
/// </summary>
public uint SegmentIndex; public uint SegmentIndex;
/// <summary>
/// Word offset within segment
/// </summary>
public int Offset; public int Offset;
} }
} }

View File

@ -406,9 +406,10 @@ namespace Capnp
/// <exception cref="ArgumentNullException"><paramref name="target"/> is null</exception> /// <exception cref="ArgumentNullException"><paramref name="target"/> is null</exception>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="slot"/> out of range</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="slot"/> out of range</exception>
/// <exception cref="InvalidOperationException"><list type="bullet"> /// <exception cref="InvalidOperationException"><list type="bullet">
/// <item><description>This state does neither describe a struct, nor a list of pointers</description></item></list> /// <item><description>This state does neither describe a struct, nor a list of pointers</description></item>
/// <item><description>Another state is already linked to the specified position (sorry, no overwrite allowed)</description></item></list> /// <item><description>Another state is already linked to the specified position (sorry, no overwrite allowed)</description></item>
/// <item><description>This state and <paramref name="target"/> belong to different message builder, and<paramref name="allowCopy"/> is false</description></item></list> /// <item><description>This state and <paramref name="target"/> belong to different message builder, and<paramref name="allowCopy"/> is false</description></item>
/// </list>
/// </exception> /// </exception>
protected void Link(int slot, SerializerState target, bool allowCopy = true) protected void Link(int slot, SerializerState target, bool allowCopy = true)
{ {
@ -461,7 +462,7 @@ namespace Capnp
/// If this state describes a list of pointers: List element index.</param> /// If this state describes a list of pointers: List element index.</param>
/// <param name="capabilityIndex">capability index inside the capability table</param> /// <param name="capabilityIndex">capability index inside the capability table</param>
/// <exception cref="InvalidOperationException"><list type="bullet"> /// <exception cref="InvalidOperationException"><list type="bullet">
/// <item><description>This state does neither describe a struct, nor a list of pointers</description></item></list> /// <item><description>This state does neither describe a struct, nor a list of pointers</description></item>
/// <item><description>Another state is already linked to the specified position (sorry, no overwrite allowed)</description></item></list> /// <item><description>Another state is already linked to the specified position (sorry, no overwrite allowed)</description></item></list>
/// </exception> /// </exception>
protected void LinkToCapability(int slot, uint capabilityIndex) protected void LinkToCapability(int slot, uint capabilityIndex)
@ -706,8 +707,8 @@ namespace Capnp
/// <param name="count">Number of bits to read</param> /// <param name="count">Number of bits to read</param>
/// <returns>Data bits which were read</returns> /// <returns>Data bits which were read</returns>
/// <exception cref="InvalidOperationException">The object was not determined to be a struct</exception> /// <exception cref="InvalidOperationException">The object was not determined to be a struct</exception>
/// <exception cref="ArgumentOutOfRangeException">The data slice specified by <paramref name="bitOffset"/> and <paramref name="bitCount"/> /// <exception cref="ArgumentOutOfRangeException">The data slice specified by <paramref name="bitOffset"/> and <paramref name="count"/>
/// is not completely within the struct's data section, misaligned, exceeds one word, or <paramref name="bitCount"/> is negative</exception> /// is not completely within the struct's data section, misaligned, exceeds one word, or <paramref name="count"/> is negative</exception>
public ulong StructReadData(ulong bitOffset, int count) public ulong StructReadData(ulong bitOffset, int count)
{ {
if (Kind != ObjectKind.Struct) if (Kind != ObjectKind.Struct)
@ -818,6 +819,13 @@ namespace Capnp
/// <exception cref="IndexOutOfRangeException"><paramref name="index"/> is out of bounds.</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.
/// </summary>
/// <param name="index">If the underlying object is a struct: index into the struct's pointer section.
/// 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); var b = BuildPointer(index);
@ -1260,7 +1268,7 @@ namespace Capnp
/// <summary> /// <summary>
/// Adds an entry to the capability table if the provided capability does not yet exist. /// Adds an entry to the capability table if the provided capability does not yet exist.
/// </summary> /// </summary>
/// <param name="capability">The capability, in one of the following forms:<list type="bullet"> /// <param name="obj">The capability, in one of the following forms:<list type="bullet">
/// <item><description>Low-level capability object (<code>Rpc.ConsumedCapability</code>)</description></item> /// <item><description>Low-level capability object (<code>Rpc.ConsumedCapability</code>)</description></item>
/// <item><description>Proxy object (<code>Rpc.Proxy</code>)</description></item> /// <item><description>Proxy object (<code>Rpc.Proxy</code>)</description></item>
/// <item><description>Skeleton object (<code>Rpc.Skeleton</code>)</description></item> /// <item><description>Skeleton object (<code>Rpc.Skeleton</code>)</description></item>
@ -1301,7 +1309,7 @@ namespace Capnp
/// </list></param> /// </list></param>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="slot"/> is out of range.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="slot"/> is out of range.</exception>
/// <exception cref="InvalidOperationException"><list type="bullet"> /// <exception cref="InvalidOperationException"><list type="bullet">
/// <item><description>This state does neither describe a struct, nor a list of pointers</description></item></list> /// <item><description>This state does neither describe a struct, nor a list of pointers</description></item>
/// <item><description>Another state is already linked to the specified position (sorry, no overwrite allowed)</description></item></list> /// <item><description>Another state is already linked to the specified position (sorry, no overwrite allowed)</description></item></list>
/// </exception> /// </exception>
public void LinkObject<T>(int slot, T obj) public void LinkObject<T>(int slot, T obj)
@ -1359,7 +1367,7 @@ namespace Capnp
/// <param name="slot">Index into this struct's pointer table.</param> /// <param name="slot">Index into this struct's pointer table.</param>
/// <returns>The proxy instance</returns> /// <returns>The proxy instance</returns>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="slot"/> is out of range.</exception> /// <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="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> /// <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
{ {

View File

@ -55,7 +55,6 @@ namespace Capnp
/// This method exists until NET Standard 2.1 is released /// This method exists until NET Standard 2.1 is released
/// </summary> /// </summary>
/// <param name="task"></param> /// <param name="task"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns> /// <returns></returns>
#if NETSTANDARD2_0 #if NETSTANDARD2_0
public static bool ReplacementTaskIsCompletedSuccessfully(this Task task) public static bool ReplacementTaskIsCompletedSuccessfully(this Task task)

View File

@ -5,13 +5,28 @@ using System.Text;
namespace Capnp namespace Capnp
{ {
/// <summary> /// <summary>
/// Pointer tag, <see cref="https://capnproto.org/encoding.html"/> /// Pointer tag, see https://capnproto.org/encoding.html/>
/// </summary> /// </summary>
public enum PointerKind : byte public enum PointerKind : byte
{ {
/// <summary>
/// Struct pointer
/// </summary>
Struct = 0, Struct = 0,
/// <summary>
/// List pointer
/// </summary>
List = 1, List = 1,
/// <summary>
/// Far pointer
/// </summary>
Far = 2, Far = 2,
/// <summary>
/// Other (capability) pointer
/// </summary>
Other = 3 Other = 3
} }