1
Fork 0
mirror of https://bitbucket.org/Ioncannon/project-meteor-server.git synced 2025-04-21 20:27:47 +00:00
project-meteor-server/Common Class Lib/Bitstream.cs

205 lines
5.4 KiB
C#
Raw Normal View History

2022-02-16 15:32:54 -05:00
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Meteor.Common
{
public class Bitstream
{
private byte[] Data;
2022-02-16 15:32:54 -05:00
public Bitstream(uint numBits, bool setAllTrue = false)
{
Debug.Assert(numBits % 8 == 0);
Debug.Assert(numBits % 4 == 0);
Data = new byte[numBits / 8];
if (setAllTrue)
SetAll(true);
}
public Bitstream(bool[] boolArray)
{
Data = Utils.ConvertBoolArrayToBinaryStream(boolArray);
}
private Bitstream(byte[] byteArray)
{
Data = byteArray;
}
public void SetAll(bool to)
{
for (int i = 0; i < Data.Length; i += 4)
{
Data[i] = Data[i + 1] = Data[i + 2] = Data[i + 3] = (byte)(to ? 0xFF : 0x00);
}
}
public void SetTo(Bitstream result)
{
Debug.Assert(Data.Length == result.Data.Length);
for (int i = 0; i < result.Data.Length; i += 4)
{
Data[i] = result.Data[i];
Data[i + 1] = result.Data[i + 1];
Data[i + 2] = result.Data[i + 2];
Data[i + 3] = result.Data[i + 3];
}
}
public void SetTo(bool[] result)
{
Debug.Assert(Data.Length == result.Length / 8);
Data = Utils.ConvertBoolArrayToBinaryStream(result);
}
2022-02-16 15:32:54 -05:00
public bool Get(uint at)
{
return Get((int)at);
}
public bool Get(int at)
{
int bytePos = at / 8;
int bitPos = at % 8;
2022-02-16 15:32:54 -05:00
return (Data[bytePos] & (1 << bitPos)) != 0;
}
public void Set(uint at)
{
Set((int)at);
}
public void Set(int at)
{
int bytePos = at / 8;
int bitPos = at % 8;
Data[bytePos] |= (byte)(1 << bitPos);
}
public void Clear(uint at)
{
Clear((int)at);
}
public void Clear(int at)
{
int bytePos = at / 8;
int bitPos = at % 8;
Data[bytePos] &= (byte)~(1 << bitPos);
}
public void NOT()
{
for (int i = 0; i < Data.Length; i += 4)
{
Data[i] = (byte)~Data[i];
Data[i + 1] = (byte)~Data[i + 1];
Data[i + 2] = (byte)~Data[i + 2];
Data[i + 3] = (byte)~Data[i + 3];
}
}
public void OR(Bitstream other)
{
Debug.Assert(Data.Length == other.Data.Length);
for (int i = 0; i < Data.Length; i += 4)
{
Data[i] |= other.Data[i];
Data[i + 1] |= other.Data[i + 1];
Data[i + 2] |= other.Data[i + 2];
Data[i + 3] |= other.Data[i + 3];
}
}
public void AND(Bitstream other)
{
Debug.Assert(Data.Length == other.Data.Length);
for (int i = 0; i < Data.Length; i += 4)
{
Data[i] &= other.Data[i];
Data[i + 1] &= other.Data[i + 1];
Data[i + 2] &= other.Data[i + 2];
Data[i + 3] &= other.Data[i + 3];
}
}
public void XOR(Bitstream other)
{
Debug.Assert(Data.Length == other.Data.Length);
for (int i = 0; i < Data.Length; i += 4)
{
Data[i] ^= other.Data[i];
Data[i + 1] ^= other.Data[i + 1];
Data[i + 2] ^= other.Data[i + 2];
Data[i + 3] ^= other.Data[i + 3];
}
}
public Bitstream Copy()
{
byte[] copy = new byte[Data.Length];
Array.Copy(Data, copy, Data.Length);
return new Bitstream(copy);
}
public byte[] GetBytes()
{
return Data;
}
public byte[] GetSlice(ushort from, ushort to)
{
int remainder = ((to - from) % 8 != 0) ? 1 : 0;
byte[] toReturn = new byte[((to - from) / 8) + remainder + 1];
toReturn[toReturn.Length - 1] = 0x3;
byte curByte = 0;
int destByteIndx = 0;
int destShiftIndx = 0;
int srcByteIndx = from / 8;
int srcShiftIndx = from % 8;
for (int i = from; i <= to; i++)
{
// Skip Zeros
if (Data[srcByteIndx] == 0)
{
srcByteIndx++;
srcShiftIndx = 0;
destByteIndx++;
i += 8;
2022-02-20 12:06:48 -05:00
continue;
}
2022-02-20 12:06:48 -05:00
bool val = (Data[srcByteIndx] & (1 << srcShiftIndx++)) != 0;
curByte |= (byte)((val ? 1 : 0) << destShiftIndx++);
2022-02-20 12:06:48 -05:00
if (srcShiftIndx == 8)
{
srcShiftIndx = 0;
srcByteIndx++;
}
if (destShiftIndx == 8)
{
toReturn[destByteIndx++] = curByte;
destShiftIndx = 0;
curByte = 0;
}
}
if (destByteIndx == toReturn.Length - 2)
toReturn[destByteIndx] = curByte;
return toReturn;
}
2022-02-16 15:32:54 -05:00
}
}