< Summary

Information
Class: ZeroC.Slice.BitSequenceWriter
Assembly: ZeroC.Slice
File(s): /home/runner/work/icerpc-csharp/icerpc-csharp/src/ZeroC.Slice/BitSequence.cs
Tag: 275_13775359185
Line coverage
100%
Covered lines: 27
Uncovered lines: 0
Coverable lines: 27
Total lines: 106
Line coverage: 100%
Branch coverage
100%
Covered branches: 6
Total branches: 6
Branch coverage: 100%
Method coverage
100%
Covered methods: 2
Total methods: 2
Method coverage: 100%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Write(...)100%66100%
.ctor(...)100%11100%

File(s)

/home/runner/work/icerpc-csharp/icerpc-csharp/src/ZeroC.Slice/BitSequence.cs

#LineLine coverage
 1// Copyright (c) ZeroC, Inc.
 2
 3using System.Buffers;
 4using ZeroC.Slice.Internal;
 5
 6namespace ZeroC.Slice;
 7
 8/// <summary>Provides a method for reading a bit sequence.</summary>
 9/// <remarks>This struct is typically returned by <see cref="SliceDecoder.GetBitSequenceReader(int)" />
 10/// to read the bit sequence associated with a Slice type.</remarks>
 11/// <seealso href="https://docs.icerpc.dev/slice2/encoding/encoding-only-constructs#bit-sequence"/>
 12public ref struct BitSequenceReader
 13{
 14    private byte _currentByte;
 15    private int _index; // between 0 and 7
 16    private SequenceReader<byte> _sequenceReader;
 17
 18    /// <summary>Constructs a bit sequence reader over a <see cref="ReadOnlySequence{T}" />.</summary>
 19    /// <param name="bitSequence">The read-only sequence.</param>
 20    public BitSequenceReader(ReadOnlySequence<byte> bitSequence)
 21    {
 22        _sequenceReader = new SequenceReader<byte>(bitSequence);
 23        _index = 0;
 24        if (!_sequenceReader.TryRead(out _currentByte))
 25        {
 26            throw new ArgumentException(
 27                "Cannot create a bit sequence reader over an empty byte sequence.",
 28                nameof(bitSequence));
 29        }
 30    }
 31
 32    /// <summary>Reads the next bit.</summary>
 33    /// <returns><see langword="true" /> when the next bit is set; otherwise, <see langword="false" />.</returns>
 34    public bool Read()
 35    {
 36        if (_index == 8)
 37        {
 38            _index = 0;
 39            if (!_sequenceReader.TryRead(out _currentByte))
 40            {
 41                throw new InvalidOperationException("Attempting to read past the end of the bit sequence.");
 42            }
 43        }
 44        return (_currentByte & (1 << _index++)) != 0;
 45    }
 46}
 47
 48/// <summary>Provides a method for writing a bit sequence.</summary>
 49/// <remarks>This struct is returned by <seealso cref="SliceEncoder.GetBitSequenceWriter(int)" />
 50/// to write the bit sequence associated with a Slice type.</remarks>
 51/// <seealso href="https://docs.icerpc.dev/slice2/encoding/encoding-only-constructs#bit-sequence"/>
 52public ref struct BitSequenceWriter
 53{
 54    private int _index; // the bit index in _spanEnumerator.Current
 55
 56    private SpanEnumerator _spanEnumerator;
 57
 58    /// <summary>Writes the bit at the current position in the underlying bit sequence and moves to the next
 59    /// position.</summary>
 60    /// <param name="value"><see langword="true" /> to set the bit and <see langword="false" /> to unset it.</param>
 61    public void Write(bool value)
 1356462    {
 1356463        int byteIndex = _index >> 3; // right-shift by 3 positions, equivalent to divide by 8
 1356464        Span<byte> span = _spanEnumerator.Current;
 65
 1356466        if (byteIndex >= span.Length)
 11867        {
 11868            if (_spanEnumerator.MoveNext())
 11469            {
 11470                span = _spanEnumerator.Current;
 11471                span.Clear();
 72
 11473                _index = 0;
 11474                byteIndex = 0;
 11475            }
 76            else
 477            {
 478                throw new InvalidOperationException("Cannot write past the end of the bit sequence.");
 79            }
 11480        }
 81
 1356082        if (value)
 643983        {
 84            // set bit
 643985            span[byteIndex] = (byte)(span[byteIndex] | (1 << (_index & 0x7)));
 643986        }
 87        // else keep it unset
 88
 1356089        _index++;
 1356090    }
 91
 92    /// <summary>Constructs a bit sequence writer over a bit sequence represented by a <see cref="SpanEnumerator" />.
 93    /// </summary>
 94    internal BitSequenceWriter(
 95        Span<byte> firstSpan,
 96        Span<byte> secondSpan = default,
 97        IList<Memory<byte>>? additionalMemory = null)
 113898    {
 113899        _index = 0;
 1138100        _spanEnumerator = new SpanEnumerator(firstSpan, secondSpan, additionalMemory);
 1138101        _spanEnumerator.MoveNext();
 102
 103        // We fill the span with 0s, this way we only need to set bits, never unset them.
 1138104        _spanEnumerator.Current.Clear();
 1138105    }
 106}