128 lines
2.3 KiB
C#
128 lines
2.3 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace Gma.QrCodeNet.Encoding;
|
|
|
|
internal sealed class BitList : IEnumerable<bool>
|
|
{
|
|
internal BitList()
|
|
{
|
|
Count = 0;
|
|
List = new List<byte>(32);
|
|
}
|
|
|
|
internal BitList(IEnumerable<byte> byteArray)
|
|
{
|
|
Count = byteArray.Count();
|
|
List = byteArray.ToList();
|
|
}
|
|
|
|
internal List<byte> List { get; }
|
|
|
|
internal int Count { get; private set; }
|
|
|
|
internal bool this[int index]
|
|
{
|
|
get
|
|
{
|
|
if (index < 0 || index >= Count)
|
|
{
|
|
throw new ArgumentOutOfRangeException(nameof(index), "Index out of range");
|
|
}
|
|
|
|
int value_Renamed = List[index >> 3] & 0xff;
|
|
return ((value_Renamed >> (7 - (index & 0x7))) & 1) == 1;
|
|
}
|
|
}
|
|
|
|
public IEnumerator<bool> GetEnumerator()
|
|
{
|
|
int numBytes = Count >> 3;
|
|
int remainder = Count & 0x7;
|
|
byte value;
|
|
for (int index = 0; index < numBytes; index++)
|
|
{
|
|
value = List[index];
|
|
for (int shiftNum = 7; shiftNum >= 0; shiftNum--)
|
|
{
|
|
yield return ((value >> shiftNum) & 1) == 1;
|
|
}
|
|
}
|
|
if (remainder > 0)
|
|
{
|
|
value = List[numBytes];
|
|
for (int index = 0; index < remainder; index++)
|
|
{
|
|
yield return ((value >> (7 - index)) & 1) == 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
return GetEnumerator();
|
|
}
|
|
|
|
private int ToBit(bool item)
|
|
{
|
|
return item ? 1 : 0;
|
|
}
|
|
|
|
internal void Add(bool item)
|
|
{
|
|
int numBitsinLastByte = Count & 0x7;
|
|
|
|
// Add one more byte to List when we have no bits in the last byte.
|
|
if (numBitsinLastByte == 0)
|
|
{
|
|
List.Add(0);
|
|
}
|
|
|
|
List[Count >> 3] |= (byte)(ToBit(item) << (7 - numBitsinLastByte));
|
|
Count++;
|
|
}
|
|
|
|
internal void Add(IEnumerable<bool> items)
|
|
{
|
|
foreach (bool item in items)
|
|
{
|
|
Add(item);
|
|
}
|
|
}
|
|
|
|
internal void Add(int value, int bitCount)
|
|
{
|
|
if (bitCount is < 0 or > 32)
|
|
{
|
|
throw new ArgumentOutOfRangeException(nameof(bitCount), $"{nameof(bitCount)} must be greater than or equal to 0");
|
|
}
|
|
|
|
int numBitsLeft = bitCount;
|
|
|
|
while (numBitsLeft > 0)
|
|
{
|
|
if ((Count & 0x7) == 0 && numBitsLeft >= 8)
|
|
{
|
|
// Add one more byte to List.
|
|
byte newByte = (byte)((value >> (numBitsLeft - 8)) & 0xFF);
|
|
AppendByte(newByte);
|
|
numBitsLeft -= 8;
|
|
}
|
|
else
|
|
{
|
|
bool bit = ((value >> (numBitsLeft - 1)) & 1) == 1;
|
|
Add(bit);
|
|
numBitsLeft--;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void AppendByte(byte item)
|
|
{
|
|
List.Add(item);
|
|
Count += 8;
|
|
}
|
|
}
|