Files
2025-08-13 09:26:42 +08:00

202 lines
3.8 KiB
C#

using System.IO;
namespace MoleMole
{
public class SprotoPack
{
private MemoryStream buffer;
private byte[] tmp;
public SprotoPack()
{
tmp = new byte[8];
}
private void write_ff(byte[] src, int offset, long pos, int n)
{
int num = (n + 7) & -8;
long position = buffer.Position;
buffer.Seek(pos, SeekOrigin.Begin);
buffer.WriteByte(byte.MaxValue);
buffer.WriteByte((byte)(num / 8 - 1));
buffer.Write(src, offset, n);
for (int i = 0; i < num - n; i++)
{
buffer.WriteByte(0);
}
buffer.Seek(position, SeekOrigin.Begin);
}
private int pack_seg(byte[] src, long offset, int ff_n)
{
byte b = 0;
int num = 0;
long position = buffer.Position;
buffer.Seek(1L, SeekOrigin.Current);
for (int i = 0; i < 8; i++)
{
if (src[offset + i] != 0)
{
num++;
b |= (byte)(1 << i);
buffer.WriteByte(src[offset + i]);
}
}
if ((num == 7 || num == 6) && ff_n > 0)
{
num = 8;
}
if (num == 8)
{
if (ff_n > 0)
{
buffer.Seek(position, SeekOrigin.Begin);
return 8;
}
buffer.Seek(position, SeekOrigin.Begin);
return 10;
}
buffer.Seek(position, SeekOrigin.Begin);
buffer.WriteByte(b);
buffer.Seek(position, SeekOrigin.Begin);
return num + 1;
}
public int pack(byte[] data, int len, byte[] outBuffer, int outBufferOffset)
{
clear();
buffer = new MemoryStream(outBuffer);
buffer.Position = outBufferOffset;
byte[] array = null;
int num = 0;
long pos = 0L;
int num2 = 0;
byte[] array2 = data;
int num3 = 0;
int num5;
for (int i = 0; i < len; buffer.Seek(num5, SeekOrigin.Current), i += 8)
{
num3 = i;
int num4 = i + 8 - len;
if (num4 > 0)
{
for (int j = 0; j < 8 - num4; j++)
{
tmp[j] = array2[i + j];
}
for (int k = 0; k < num4; k++)
{
tmp[7 - k] = 0;
}
array2 = tmp;
num3 = 0;
}
num5 = pack_seg(array2, num3, num2);
switch (num5)
{
case 10:
array = array2;
num = num3;
pos = buffer.Position;
num2 = 1;
continue;
case 8:
if (num2 > 0)
{
num2++;
if (num2 == 256)
{
write_ff(array, num, pos, 2048);
num2 = 0;
}
continue;
}
break;
}
if (num2 > 0)
{
write_ff(array, num, pos, num2 * 8);
num2 = 0;
}
}
if (num2 == 1)
{
write_ff(array, num, pos, 8);
}
else if (num2 > 1)
{
int num6 = ((array != data) ? array.Length : len);
write_ff(array, num, pos, num6 - num);
}
long num7 = (len + 2047) / 2048 * 2 + len + 2;
if (num7 < buffer.Position)
{
}
int result = (int)(buffer.Position - outBufferOffset);
buffer.Dispose();
return result;
}
public int unpack(byte[] data, int len, byte[] outBuffer, int outBufferOffset)
{
clear();
buffer = new MemoryStream(outBuffer);
buffer.Position = outBufferOffset;
len = ((len != 0) ? len : data.Length);
int num = len;
while (num > 0)
{
byte b = data[len - num];
num--;
if (b == byte.MaxValue)
{
if (num < 0)
{
}
int num2 = (data[len - num] + 1) * 8;
if (num < num2 + 1)
{
}
buffer.Write(data, len - num + 1, num2);
num -= num2 + 1;
continue;
}
for (int i = 0; i < 8; i++)
{
int num3 = (b >> i) & 1;
if (num3 == 1)
{
if (num < 0)
{
}
buffer.WriteByte(data[len - num]);
num--;
}
else
{
buffer.WriteByte(0);
}
}
}
int result = (int)(buffer.Position - outBufferOffset);
buffer.Dispose();
return result;
}
private void clear()
{
for (int i = 0; i < tmp.Length; i++)
{
tmp[i] = 0;
}
}
public int RoundUpTo8(int x)
{
int num = x & 7;
return (num != 0) ? (x + 8 - num) : x;
}
}
}