RunLengthEncoder
Simple run length encoder (RLE) that works on spans.
using System.Runtime.CompilerServices;
namespace System.IO.Compression
{
internal static class RunLengthEncoder
{
public static int GetEncodedLength([System.Runtime.CompilerServices.ParamCollection] [ScopedRef] ReadOnlySpan<byte> data)
{
SpanReader<byte> spanReader = new SpanReader<byte>(data);
int num = 0;
byte value;
while (spanReader.TryRead(out value)) {
for (int num2 = spanReader.AdvancePast(value) + 1; num2 > 0; num2 -= 255) {
num += 2;
}
}
return num;
}
public static int GetDecodedLength([System.Runtime.CompilerServices.ParamCollection] [ScopedRef] ReadOnlySpan<byte> encoded)
{
int num = 0;
for (int i = 0; i < encoded.Length; i += 2) {
num += encoded[i];
}
return num;
}
public static bool TryEncode(ReadOnlySpan<byte> data, Span<byte> encoded, out int written)
{
SpanReader<byte> spanReader = new SpanReader<byte>(data);
SpanWriter<byte> spanWriter = new SpanWriter<byte>(encoded);
byte value;
while (spanReader.TryRead(out value)) {
for (int num = spanReader.AdvancePast(value) + 1; num > 0; num -= 255) {
if (!spanWriter.TryWrite((byte)Math.Min(num, 255)) || !spanWriter.TryWrite(value)) {
written = spanWriter.Position;
return false;
}
}
}
written = spanWriter.Position;
return true;
}
public static bool TryDecode(ReadOnlySpan<byte> encoded, Span<byte> data, out int written)
{
SpanReader<byte> spanReader = new SpanReader<byte>(encoded);
SpanWriter<byte> spanWriter = new SpanWriter<byte>(data);
byte value;
while (spanReader.TryRead(out value)) {
if (!spanReader.TryRead(out byte value2) || !spanWriter.TryWriteCount(value, value2)) {
written = spanWriter.Position;
return false;
}
}
written = spanWriter.Position;
return true;
}
}
}