using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace Capnp { /// <summary> /// SerializerState specialization for a List(Bool). /// </summary> public class ListOfBitsSerializer: SerializerState, IReadOnlyList<bool> { /// <summary> /// Gets or sets the element at given index. /// </summary> /// <param name="index">Element index</param> /// <returns>Element value</returns> /// <exception cref="InvalidOperationException">List was not initialized, or attempting to overwrite a non-null element.</exception> /// <exception cref="IndexOutOfRangeException"><paramref name="index"/> is out of range.</exception> public bool this[int index] { get { if (index < 0 || index >= Count) throw new IndexOutOfRangeException(); int wi = index / 64; int bi = index % 64; return ((RawData[wi] >> bi) & 1) != 0; } set { 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); } } /// <summary> /// This list's element count. /// </summary> public int Count => ListElementCount; /// <summary> /// Initializes this list with a specific size. The list can be initialized only once. /// </summary> /// <param name="count">List element count</param> /// <exception cref="InvalidOperationException">The list was already initialized</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="count"/> is negative or greater than 2^29-1</exception> public void Init(int count) { if (IsAllocated) throw new InvalidOperationException("Already initialized"); if (count < 0) throw new ArgumentOutOfRangeException(nameof(count)); SetListOfValues(1, count); } /// <summary> /// Initializes the list with given content. /// </summary> /// <param name="items">List content. Can be null in which case the list is simply not initialized.</param> /// <exception cref="InvalidOperationException">The list was already initialized</exception> /// <exception cref="ArgumentOutOfRangeException">More than 2^29-1 items.</exception> public void Init(IReadOnlyList<bool> items) { if (items == null) { return; } Init(items.Count); for (int i = 0; i < items.Count; i++) { this[i] = items[i]; } } /// <summary> /// Implements <see cref="IEnumerable{Boolean}"/> /// </summary> public IEnumerator<bool> GetEnumerator() => (IEnumerator<bool>)this.ToArray().GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => this.ToArray().GetEnumerator(); } }