using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; namespace Capnp { /// /// SerializerState specialization for a list of capabilities. /// /// Capability interface public class ListOfCapsSerializer : SerializerState, IReadOnlyList where T : class { /// /// Constructs an instance. /// /// does not quality as capability interface. /// The implementation might attempt to throw this exception earlier in the static constructor (during type load). Currently it doesn't /// because there is a significant risk of messing something up and ending with a hard-to-debug . public ListOfCapsSerializer() { Rpc.CapabilityReflection.ValidateCapabilityInterface(typeof(T)); } /// /// Gets or sets the capability at given element index. /// /// Element index /// Proxy object of capability at given element index /// List was not initialized, or attempting to overwrite an already set element. /// is out of range. [AllowNull] public T this[int index] { get { ListSerializerHelper.EnsureAllocated(this); try { return (Rpc.CapabilityReflection.CreateProxy(DecodeCapPointer(index)) as T)!; } catch (ArgumentOutOfRangeException) { throw new IndexOutOfRangeException(); } } set { ListSerializerHelper.EnsureAllocated(this); if (index < 0 || index >= RawData.Length) throw new IndexOutOfRangeException("index out of range"); var p = default(WirePointer); p.SetCapability(ProvideCapability(value)); RawData[index] = p; } } /// /// Initializes this list with a specific size. The list can be initialized only once. /// /// List element count /// The list was already initialized /// is negative or greater than 2^29-1 public void Init(int count) { SetListOfPointers(count); } /// /// Initializes the list with given content. /// /// List content. Can be null in which case the list is simply not initialized. /// The list was already initialized /// More than 2^29-1 items. public void Init(IReadOnlyList? caps) { if (caps == null) { return; } Init(caps.Count); for (int i = 0; i < caps.Count; i++) { this[i] = caps[i]; } } /// /// This list's element count. /// public int Count => ListElementCount; IEnumerable Enumerate() { int count = Count; for (int i = 0; i < count; i++) yield return this[i]; } /// /// Implements . /// /// public IEnumerator GetEnumerator() { return Enumerate().GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } }