using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; namespace Capnp { /// /// SerializerState specialization for a List(Bool). /// public class ListOfBitsSerializer: SerializerState, IReadOnlyList { /// /// Gets or sets the element at given index. /// /// Element index /// Element value /// List was not initialized, or attempting to overwrite a non-null element. /// is out of range. public bool this[int index] { get { ListSerializerHelper.EnsureAllocated(this); if (index < 0 || index >= Count) throw new IndexOutOfRangeException(); int wi = index / 64; int bi = index % 64; return ((RawData[wi] >> bi) & 1) != 0; } set { ListSerializerHelper.EnsureAllocated(this); if (index < 0 || index >= Count) throw new IndexOutOfRangeException(); int wi = index / 64; int bi = index % 64; if (value) RawData[wi] |= (1ul << bi); else RawData[wi] &= ~(1ul << bi); } } /// /// This list's element count. /// public int Count => ListElementCount; /// /// 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) { if (IsAllocated) throw new InvalidOperationException("Already initialized"); if (count < 0) throw new ArgumentOutOfRangeException(nameof(count)); SetListOfValues(1, 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? items) { if (items == null) { return; } Init(items.Count); for (int i = 0; i < items.Count; i++) { this[i] = items[i]; } } IEnumerable Enumerate() { for (int i = 0; i < Count; i++) yield return this[i]; } /// /// Implements /// public IEnumerator GetEnumerator() => Enumerate().GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } }