Skip to content

Commit

Permalink
add PRS BigEndian compression
Browse files Browse the repository at this point in the history
  • Loading branch information
Venomalia committed Jun 13, 2023
1 parent f19c6d3 commit 1935f70
Show file tree
Hide file tree
Showing 4 changed files with 247 additions and 132 deletions.
67 changes: 67 additions & 0 deletions lib/AuroraLip/Compression/FlagReader.cs
@@ -0,0 +1,67 @@
using AuroraLib.Common;

namespace AuroraLip.Compression
{
/// <summary>
/// Reads individual bits from a stream and provides methods for interpreting the flag values.
/// </summary>
public class FlagReader
{
private byte CurrentFlag;
public byte BitsLeft { get; private set; }
public readonly Stream Base;
public readonly Endian Order;

public FlagReader(Stream source, Endian order)
{
Base = source;
Order = order;
}

/// <summary>
/// Reads a single bit from the stream.
/// </summary>
/// <returns>The value of the read bit.</returns>
public bool Readbit()
{
if (BitsLeft == 0)
{
CurrentFlag = Base.ReadUInt8();
BitsLeft = 8;
}

bool flag;
if (Order == Endian.Little)
{
flag = (CurrentFlag & 1) == 1;
CurrentFlag >>= 1;
}
else
{
flag = (CurrentFlag & 128) == 128;
CurrentFlag <<= 1;
}
BitsLeft--;
return flag;
}

/// <summary>
/// Reads an integer value with the specified number of bits from the stream.
/// </summary>
/// <param name="bits">The number of bits to read.</param>
/// <returns>The integer value read from the stream.</returns>
public int ReadInt(int bits = 1)
{
int vaule = 0;
for (int i = 0; i < bits; i++)
{
vaule <<= 1;
if (Readbit())
{
vaule |= 1;
}
}
return vaule;
}
}
}
84 changes: 84 additions & 0 deletions lib/AuroraLip/Compression/FlagWriter.cs
@@ -0,0 +1,84 @@
using AuroraLib.Common;

namespace AuroraLib.Compression
{
/// <summary>
/// Represents a flag writer used for compressing data. It provides methods to write individual bits.
/// </summary>
public class FlagWriter
{
private byte CurrentFlag;
public byte BitsLeft { get; private set; }
public readonly Stream Base;
public readonly MemoryStream Buffer;
public readonly Endian Order;

public FlagWriter(Stream destination, MemoryStream buffer, Endian order)
{
Base = destination;
Order = order;
Buffer = buffer;
}

/// <summary>
/// Writes a single bit as a flag. The bits are accumulated in a byte and flushed to the destination stream when necessary.
/// </summary>
/// <param name="bit">The bit value to write (true for 1, false for 0).</param>
public void WriteBit(bool bit)
{
if (BitsLeft == 0)
{
CurrentFlag = 0;
BitsLeft = 8;
}

if (bit)
{
if (Order == Endian.Little)
CurrentFlag |= (byte)(1 << (8 - BitsLeft));
else
CurrentFlag |= (byte)(1 << (BitsLeft - 1));
}

BitsLeft--;

if (BitsLeft == 0)
{
Base.WriteByte(CurrentFlag);
Buffer.WriteTo(Base);
Buffer.SetLength(0);
}
}

/// <summary>
/// Writes an integer value as a sequence of bits with the specified number of bits. The bits are written from the most significant bit to the least significant bit.
/// </summary>
/// <param name="value">The integer value to write.</param>
/// <param name="bits">The number of bits to write (default is 1).</param>
public void WriteInt(int value, int bits = 1)
{
for (int i = bits - 1; i >= 0; i--)
{
int bit = (value >> i) & 1;
WriteBit(bit == 1);
}
}

/// <summary>
/// Flushes any remaining bits in the buffer to the underlying stream.
/// </summary>
public void Flush()
{
if (BitsLeft != 0)
{
Base.WriteByte(CurrentFlag);
BitsLeft = 0;
}
if (Buffer.Length != 0)
{
Buffer.WriteTo(Base);
Buffer.SetLength(0);
}
}
}
}

0 comments on commit 1935f70

Please sign in to comment.