Files
UltimateFishing/Assets/Scripts/Assembly-CSharp/Unity/IO/Compression/FastEncoder.cs
2026-02-21 16:45:37 +08:00

173 lines
4.1 KiB
C#

using System;
namespace Unity.IO.Compression
{
internal class FastEncoder
{
private FastEncoderWindow inputWindow;
private Match currentMatch;
private double lastCompressionRatio;
internal int BytesInHistory
{
get
{
return inputWindow.BytesAvailable;
}
}
internal DeflateInput UnprocessedInput
{
get
{
return inputWindow.UnprocessedInput;
}
}
internal double LastCompressionRatio
{
get
{
return lastCompressionRatio;
}
}
public FastEncoder()
{
inputWindow = new FastEncoderWindow();
currentMatch = new Match();
}
internal void FlushInput()
{
inputWindow.FlushWindow();
}
internal void GetBlock(DeflateInput input, OutputBuffer output, int maxBytesToCopy)
{
WriteDeflatePreamble(output);
GetCompressedOutput(input, output, maxBytesToCopy);
WriteEndOfBlock(output);
}
internal void GetCompressedData(DeflateInput input, OutputBuffer output)
{
GetCompressedOutput(input, output, -1);
}
internal void GetBlockHeader(OutputBuffer output)
{
WriteDeflatePreamble(output);
}
internal void GetBlockFooter(OutputBuffer output)
{
WriteEndOfBlock(output);
}
private void GetCompressedOutput(DeflateInput input, OutputBuffer output, int maxBytesToCopy)
{
int bytesWritten = output.BytesWritten;
int num = 0;
int num2 = BytesInHistory + input.Count;
do
{
int num3 = ((input.Count >= inputWindow.FreeWindowSpace) ? inputWindow.FreeWindowSpace : input.Count);
if (maxBytesToCopy >= 1)
{
num3 = Math.Min(num3, maxBytesToCopy - num);
}
if (num3 > 0)
{
inputWindow.CopyBytes(input.Buffer, input.StartIndex, num3);
input.ConsumeBytes(num3);
num += num3;
}
GetCompressedOutput(output);
}
while (SafeToWriteTo(output) && InputAvailable(input) && (maxBytesToCopy < 1 || num < maxBytesToCopy));
int bytesWritten2 = output.BytesWritten;
int num4 = bytesWritten2 - bytesWritten;
int num5 = BytesInHistory + input.Count;
int num6 = num2 - num5;
if (num4 != 0)
{
lastCompressionRatio = (double)num4 / (double)num6;
}
}
private void GetCompressedOutput(OutputBuffer output)
{
while (inputWindow.BytesAvailable > 0 && SafeToWriteTo(output))
{
inputWindow.GetNextSymbolOrMatch(currentMatch);
if (currentMatch.State == MatchState.HasSymbol)
{
WriteChar(currentMatch.Symbol, output);
continue;
}
if (currentMatch.State == MatchState.HasMatch)
{
WriteMatch(currentMatch.Length, currentMatch.Position, output);
continue;
}
WriteChar(currentMatch.Symbol, output);
WriteMatch(currentMatch.Length, currentMatch.Position, output);
}
}
private bool InputAvailable(DeflateInput input)
{
return input.Count > 0 || BytesInHistory > 0;
}
private bool SafeToWriteTo(OutputBuffer output)
{
return output.FreeBytes > 16;
}
private void WriteEndOfBlock(OutputBuffer output)
{
uint num = FastEncoderStatics.FastEncoderLiteralCodeInfo[256];
int n = (int)(num & 0x1F);
output.WriteBits(n, num >> 5);
}
internal static void WriteMatch(int matchLen, int matchPos, OutputBuffer output)
{
uint num = FastEncoderStatics.FastEncoderLiteralCodeInfo[254 + matchLen];
int num2 = (int)(num & 0x1F);
if (num2 <= 16)
{
output.WriteBits(num2, num >> 5);
}
else
{
output.WriteBits(16, (num >> 5) & 0xFFFF);
output.WriteBits(num2 - 16, num >> 21);
}
num = FastEncoderStatics.FastEncoderDistanceCodeInfo[FastEncoderStatics.GetSlot(matchPos)];
output.WriteBits((int)(num & 0xF), num >> 8);
int num3 = (int)((num >> 4) & 0xF);
if (num3 != 0)
{
output.WriteBits(num3, (uint)matchPos & FastEncoderStatics.BitMask[num3]);
}
}
internal static void WriteChar(byte b, OutputBuffer output)
{
uint num = FastEncoderStatics.FastEncoderLiteralCodeInfo[b];
output.WriteBits((int)(num & 0x1F), num >> 5);
}
internal static void WriteDeflatePreamble(OutputBuffer output)
{
output.WriteBytes(FastEncoderStatics.FastEncoderTreeStructureData, 0, FastEncoderStatics.FastEncoderTreeStructureData.Length);
output.WriteBits(9, 34u);
}
}
}