Files
SuperVPN/output/Libraries/BouncyCastle.Crypto/Org/BouncyCastle/Apache/Bzip2/CBZip2OutputStream.cs
2025-10-09 09:57:24 +09:00

1603 lines
27 KiB
C#

using System.IO;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Apache.Bzip2;
public class CBZip2OutputStream : Stream
{
internal class StackElem
{
internal int ll;
internal int hh;
internal int dd;
}
protected const int SETMASK = 2097152;
protected const int CLEARMASK = -2097153;
protected const int GREATER_ICOST = 15;
protected const int LESSER_ICOST = 0;
protected const int SMALL_THRESH = 20;
protected const int DEPTH_THRESH = 10;
protected const int QSORT_STACK_SIZE = 1000;
private bool finished;
private int last;
private int origPtr;
private int blockSize100k;
private bool blockRandomised;
private int bytesOut;
private int bsBuff;
private int bsLive;
private CRC mCrc = new CRC();
private bool[] inUse = new bool[256];
private int nInUse;
private char[] seqToUnseq = new char[256];
private char[] unseqToSeq = new char[256];
private char[] selector = new char[18002];
private char[] selectorMtf = new char[18002];
private char[] block;
private int[] quadrant;
private int[] zptr;
private short[] szptr;
private int[] ftab;
private int nMTF;
private int[] mtfFreq = new int[258];
private int workFactor;
private int workDone;
private int workLimit;
private bool firstAttempt;
private int nBlocksRandomised;
private int currentChar = -1;
private int runLength = 0;
private bool closed = false;
private int blockCRC;
private int combinedCRC;
private int allowableBlockSize;
private Stream bsStream;
private int[] incs = new int[14]
{
1, 4, 13, 40, 121, 364, 1093, 3280, 9841, 29524,
88573, 265720, 797161, 2391484
};
public override bool CanRead => false;
public override bool CanSeek => false;
public override bool CanWrite => true;
public override long Length => 0L;
public override long Position
{
get
{
return 0L;
}
set
{
}
}
private static void Panic()
{
}
private void MakeMaps()
{
nInUse = 0;
for (int i = 0; i < 256; i++)
{
if (inUse[i])
{
seqToUnseq[nInUse] = (char)i;
unseqToSeq[i] = (char)nInUse;
nInUse++;
}
}
}
protected static void HbMakeCodeLengths(char[] len, int[] freq, int alphaSize, int maxLen)
{
int[] array = new int[260];
int[] array2 = new int[516];
int[] array3 = new int[516];
for (int i = 0; i < alphaSize; i++)
{
array2[i + 1] = ((freq[i] == 0) ? 1 : freq[i]) << 8;
}
while (true)
{
int num = alphaSize;
int num2 = 0;
array[0] = 0;
array2[0] = 0;
array3[0] = -2;
for (int i = 1; i <= alphaSize; i++)
{
array3[i] = -1;
num2++;
array[num2] = i;
int num3 = num2;
int num4 = array[num3];
while (array2[num4] < array2[array[num3 >> 1]])
{
array[num3] = array[num3 >> 1];
num3 >>= 1;
}
array[num3] = num4;
}
if (num2 >= 260)
{
Panic();
}
while (num2 > 1)
{
int num5 = array[1];
array[1] = array[num2];
num2--;
int num6 = 0;
int num7 = 0;
int num8 = 0;
num6 = 1;
num8 = array[num6];
while (true)
{
num7 = num6 << 1;
if (num7 > num2)
{
break;
}
if (num7 < num2 && array2[array[num7 + 1]] < array2[array[num7]])
{
num7++;
}
if (array2[num8] < array2[array[num7]])
{
break;
}
array[num6] = array[num7];
num6 = num7;
}
array[num6] = num8;
int num9 = array[1];
array[1] = array[num2];
num2--;
int num10 = 0;
int num11 = 0;
int num12 = 0;
num10 = 1;
num12 = array[num10];
while (true)
{
num11 = num10 << 1;
if (num11 > num2)
{
break;
}
if (num11 < num2 && array2[array[num11 + 1]] < array2[array[num11]])
{
num11++;
}
if (array2[num12] < array2[array[num11]])
{
break;
}
array[num10] = array[num11];
num10 = num11;
}
array[num10] = num12;
num++;
array3[num5] = (array3[num9] = num);
array2[num] = (int)((array2[num5] & 0xFFFFFF00u) + (array2[num9] & 0xFFFFFF00u)) | (1 + (((array2[num5] & 0xFF) > (array2[num9] & 0xFF)) ? (array2[num5] & 0xFF) : (array2[num9] & 0xFF)));
array3[num] = -1;
num2++;
array[num2] = num;
int num13 = 0;
int num14 = 0;
num13 = num2;
num14 = array[num13];
while (array2[num14] < array2[array[num13 >> 1]])
{
array[num13] = array[num13 >> 1];
num13 >>= 1;
}
array[num13] = num14;
}
if (num >= 516)
{
Panic();
}
bool flag = false;
for (int i = 1; i <= alphaSize; i++)
{
int num15 = 0;
int num16 = i;
while (array3[num16] >= 0)
{
num16 = array3[num16];
num15++;
}
len[i - 1] = (char)num15;
if (num15 > maxLen)
{
flag = true;
}
}
if (!flag)
{
break;
}
for (int i = 1; i < alphaSize; i++)
{
int num15 = array2[i] >> 8;
num15 = 1 + num15 / 2;
array2[i] = num15 << 8;
}
}
}
public CBZip2OutputStream(Stream inStream)
: this(inStream, 9)
{
}
public CBZip2OutputStream(Stream inStream, int inBlockSize)
{
block = null;
quadrant = null;
zptr = null;
ftab = null;
inStream.WriteByte(66);
inStream.WriteByte(90);
BsSetStream(inStream);
workFactor = 50;
if (inBlockSize > 9)
{
inBlockSize = 9;
}
if (inBlockSize < 1)
{
inBlockSize = 1;
}
blockSize100k = inBlockSize;
AllocateCompressStructures();
Initialize();
InitBlock();
}
public override void WriteByte(byte bv)
{
int num = (256 + bv) % 256;
if (currentChar != -1)
{
if (currentChar == num)
{
runLength++;
if (runLength > 254)
{
WriteRun();
currentChar = -1;
runLength = 0;
}
}
else
{
WriteRun();
runLength = 1;
currentChar = num;
}
}
else
{
currentChar = num;
runLength++;
}
}
private void WriteRun()
{
if (last < allowableBlockSize)
{
inUse[currentChar] = true;
for (int i = 0; i < runLength; i++)
{
mCrc.UpdateCRC((ushort)currentChar);
}
switch (runLength)
{
case 1:
last++;
block[last + 1] = (char)currentChar;
break;
case 2:
last++;
block[last + 1] = (char)currentChar;
last++;
block[last + 1] = (char)currentChar;
break;
case 3:
last++;
block[last + 1] = (char)currentChar;
last++;
block[last + 1] = (char)currentChar;
last++;
block[last + 1] = (char)currentChar;
break;
default:
inUse[runLength - 4] = true;
last++;
block[last + 1] = (char)currentChar;
last++;
block[last + 1] = (char)currentChar;
last++;
block[last + 1] = (char)currentChar;
last++;
block[last + 1] = (char)currentChar;
last++;
block[last + 1] = (char)(runLength - 4);
break;
}
}
else
{
EndBlock();
InitBlock();
WriteRun();
}
}
public override void Close()
{
if (!closed)
{
Finish();
closed = true;
Platform.Dispose(bsStream);
base.Close();
}
}
public void Finish()
{
if (!finished)
{
if (runLength > 0)
{
WriteRun();
}
currentChar = -1;
EndBlock();
EndCompression();
finished = true;
Flush();
}
}
public override void Flush()
{
bsStream.Flush();
}
private void Initialize()
{
bytesOut = 0;
nBlocksRandomised = 0;
BsPutUChar(104);
BsPutUChar(48 + blockSize100k);
combinedCRC = 0;
}
private void InitBlock()
{
mCrc.InitialiseCRC();
last = -1;
for (int i = 0; i < 256; i++)
{
inUse[i] = false;
}
allowableBlockSize = 100000 * blockSize100k - 20;
}
private void EndBlock()
{
blockCRC = mCrc.GetFinalCRC();
combinedCRC = (combinedCRC << 1) | (combinedCRC >>> 31);
combinedCRC ^= blockCRC;
DoReversibleTransformation();
BsPutUChar(49);
BsPutUChar(65);
BsPutUChar(89);
BsPutUChar(38);
BsPutUChar(83);
BsPutUChar(89);
BsPutint(blockCRC);
if (blockRandomised)
{
BsW(1, 1);
nBlocksRandomised++;
}
else
{
BsW(1, 0);
}
MoveToFrontCodeAndSend();
}
private void EndCompression()
{
BsPutUChar(23);
BsPutUChar(114);
BsPutUChar(69);
BsPutUChar(56);
BsPutUChar(80);
BsPutUChar(144);
BsPutint(combinedCRC);
BsFinishedWithStream();
}
private void HbAssignCodes(int[] code, char[] length, int minLen, int maxLen, int alphaSize)
{
int num = 0;
for (int i = minLen; i <= maxLen; i++)
{
for (int j = 0; j < alphaSize; j++)
{
if (length[j] == i)
{
code[j] = num;
num++;
}
}
num <<= 1;
}
}
private void BsSetStream(Stream f)
{
bsStream = f;
bsLive = 0;
bsBuff = 0;
bytesOut = 0;
}
private void BsFinishedWithStream()
{
while (bsLive > 0)
{
int num = bsBuff >> 24;
try
{
bsStream.WriteByte((byte)num);
}
catch (IOException ex)
{
throw ex;
}
bsBuff <<= 8;
bsLive -= 8;
bytesOut++;
}
}
private void BsW(int n, int v)
{
while (bsLive >= 8)
{
int num = bsBuff >> 24;
try
{
bsStream.WriteByte((byte)num);
}
catch (IOException ex)
{
throw ex;
}
bsBuff <<= 8;
bsLive -= 8;
bytesOut++;
}
bsBuff |= v << 32 - bsLive - n;
bsLive += n;
}
private void BsPutUChar(int c)
{
BsW(8, c);
}
private void BsPutint(int u)
{
BsW(8, (u >> 24) & 0xFF);
BsW(8, (u >> 16) & 0xFF);
BsW(8, (u >> 8) & 0xFF);
BsW(8, u & 0xFF);
}
private void BsPutIntVS(int numBits, int c)
{
BsW(numBits, c);
}
private void SendMTFValues()
{
char[][] array = CBZip2InputStream.InitCharArray(6, 258);
int num = 0;
int num2 = nInUse + 2;
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < num2; j++)
{
array[i][j] = '\u000f';
}
}
if (nMTF <= 0)
{
Panic();
}
int num3 = ((nMTF < 200) ? 2 : ((nMTF < 600) ? 3 : ((nMTF < 1200) ? 4 : ((nMTF >= 2400) ? 6 : 5))));
int num4 = num3;
int num5 = nMTF;
int num6 = 0;
while (num4 > 0)
{
int num7 = num5 / num4;
int num8 = num6 - 1;
int k;
for (k = 0; k < num7; k += mtfFreq[num8])
{
if (num8 >= num2 - 1)
{
break;
}
num8++;
}
if (num8 > num6 && num4 != num3 && num4 != 1 && (num3 - num4) % 2 == 1)
{
k -= mtfFreq[num8];
num8--;
}
for (int j = 0; j < num2; j++)
{
if (j >= num6 && j <= num8)
{
array[num4 - 1][j] = '\0';
}
else
{
array[num4 - 1][j] = '\u000f';
}
}
num4--;
num6 = num8 + 1;
num5 -= k;
}
int[][] array2 = CBZip2InputStream.InitIntArray(6, 258);
int[] array3 = new int[6];
short[] array4 = new short[6];
for (int l = 0; l < 4; l++)
{
for (int i = 0; i < num3; i++)
{
array3[i] = 0;
}
for (int i = 0; i < num3; i++)
{
for (int j = 0; j < num2; j++)
{
array2[i][j] = 0;
}
}
num = 0;
int num9 = 0;
num6 = 0;
while (num6 < nMTF)
{
int num8 = num6 + 50 - 1;
if (num8 >= nMTF)
{
num8 = nMTF - 1;
}
for (int i = 0; i < num3; i++)
{
array4[i] = 0;
}
nint num19;
if (num3 == 6)
{
short num11;
short num12;
short num13;
short num14;
short num15;
short num10 = (num11 = (num12 = (num13 = (num14 = (num15 = 0)))));
for (int m = num6; m <= num8; m++)
{
short num16 = szptr[m];
num10 += (short)array[0][num16];
num11 += (short)array[1][num16];
num12 += (short)array[2][num16];
num13 += (short)array[3][num16];
num14 += (short)array[4][num16];
num15 += (short)array[5][num16];
}
array4[0] = num10;
array4[1] = num11;
array4[2] = num12;
array4[3] = num13;
array4[4] = num14;
array4[5] = num15;
}
else
{
for (int m = num6; m <= num8; m++)
{
short num17 = szptr[m];
for (int i = 0; i < num3; i++)
{
short[] array6;
short[] array5 = (array6 = array4);
int num18 = i;
num19 = num18;
array5[num18] = (short)(array6[num19] + (short)array[i][num17]);
}
}
}
int num20 = 999999999;
int num21 = -1;
for (int i = 0; i < num3; i++)
{
if (array4[i] < num20)
{
num20 = array4[i];
num21 = i;
}
}
num9 += num20;
int[] array8;
int[] array7 = (array8 = array3);
int num22 = num21;
num19 = num22;
array7[num22] = array8[num19] + 1;
selector[num] = (char)num21;
num++;
for (int m = num6; m <= num8; m++)
{
int[] array9 = (array8 = array2[num21]);
short num23 = szptr[m];
num19 = num23;
array9[num23] = array8[num19] + 1;
}
num6 = num8 + 1;
}
for (int i = 0; i < num3; i++)
{
HbMakeCodeLengths(array[i], array2[i], num2, 20);
}
}
array2 = null;
array3 = null;
array4 = null;
if (num3 >= 8)
{
Panic();
}
if (num >= 32768 || num > 18002)
{
Panic();
}
char[] array10 = new char[6];
for (int m = 0; m < num3; m++)
{
array10[m] = (char)m;
}
for (int m = 0; m < num; m++)
{
char c = selector[m];
int num24 = 0;
char c2 = array10[num24];
while (c != c2)
{
num24++;
char c3 = c2;
c2 = array10[num24];
array10[num24] = c3;
}
array10[0] = c2;
selectorMtf[m] = (char)num24;
}
int[][] array11 = CBZip2InputStream.InitIntArray(6, 258);
for (int i = 0; i < num3; i++)
{
int num25 = 32;
int num26 = 0;
for (int m = 0; m < num2; m++)
{
if (array[i][m] > num26)
{
num26 = array[i][m];
}
if (array[i][m] < num25)
{
num25 = array[i][m];
}
}
if (num26 > 20)
{
Panic();
}
if (num25 < 1)
{
Panic();
}
HbAssignCodes(array11[i], array[i], num25, num26, num2);
}
bool[] array12 = new bool[16];
for (int m = 0; m < 16; m++)
{
array12[m] = false;
for (int num24 = 0; num24 < 16; num24++)
{
if (inUse[m * 16 + num24])
{
array12[m] = true;
}
}
}
for (int m = 0; m < 16; m++)
{
if (array12[m])
{
BsW(1, 1);
}
else
{
BsW(1, 0);
}
}
for (int m = 0; m < 16; m++)
{
if (!array12[m])
{
continue;
}
for (int num24 = 0; num24 < 16; num24++)
{
if (inUse[m * 16 + num24])
{
BsW(1, 1);
}
else
{
BsW(1, 0);
}
}
}
BsW(3, num3);
BsW(15, num);
for (int m = 0; m < num; m++)
{
for (int num24 = 0; num24 < selectorMtf[m]; num24++)
{
BsW(1, 1);
}
BsW(1, 0);
}
for (int i = 0; i < num3; i++)
{
int n = array[i][0];
BsW(5, n);
for (int m = 0; m < num2; m++)
{
for (; n < array[i][m]; n++)
{
BsW(2, 2);
}
while (n > array[i][m])
{
BsW(2, 3);
n--;
}
BsW(1, 0);
}
}
int num27 = 0;
num6 = 0;
while (num6 < nMTF)
{
int num8 = num6 + 50 - 1;
if (num8 >= nMTF)
{
num8 = nMTF - 1;
}
for (int m = num6; m <= num8; m++)
{
BsW(array[(uint)selector[num27]][szptr[m]], array11[(uint)selector[num27]][szptr[m]]);
}
num6 = num8 + 1;
num27++;
}
if (num27 != num)
{
Panic();
}
}
private void MoveToFrontCodeAndSend()
{
BsPutIntVS(24, origPtr);
GenerateMTFValues();
SendMTFValues();
}
private void SimpleSort(int lo, int hi, int d)
{
int num = hi - lo + 1;
if (num < 2)
{
return;
}
int i;
for (i = 0; incs[i] < num; i++)
{
}
for (i--; i >= 0; i--)
{
int num2 = incs[i];
int num3 = lo + num2;
while (num3 <= hi)
{
int num4 = zptr[num3];
int num5 = num3;
while (FullGtU(zptr[num5 - num2] + d, num4 + d))
{
zptr[num5] = zptr[num5 - num2];
num5 -= num2;
if (num5 <= lo + num2 - 1)
{
break;
}
}
zptr[num5] = num4;
num3++;
if (num3 > hi)
{
break;
}
num4 = zptr[num3];
num5 = num3;
while (FullGtU(zptr[num5 - num2] + d, num4 + d))
{
zptr[num5] = zptr[num5 - num2];
num5 -= num2;
if (num5 <= lo + num2 - 1)
{
break;
}
}
zptr[num5] = num4;
num3++;
if (num3 > hi)
{
break;
}
num4 = zptr[num3];
num5 = num3;
while (FullGtU(zptr[num5 - num2] + d, num4 + d))
{
zptr[num5] = zptr[num5 - num2];
num5 -= num2;
if (num5 <= lo + num2 - 1)
{
break;
}
}
zptr[num5] = num4;
num3++;
if (workDone > workLimit && firstAttempt)
{
return;
}
}
}
}
private void Vswap(int p1, int p2, int n)
{
int num = 0;
while (n > 0)
{
num = zptr[p1];
zptr[p1] = zptr[p2];
zptr[p2] = num;
p1++;
p2++;
n--;
}
}
private char Med3(char a, char b, char c)
{
if (a > b)
{
char c2 = a;
a = b;
b = c2;
}
if (b > c)
{
char c2 = b;
b = c;
c = c2;
}
if (a > b)
{
b = a;
}
return b;
}
private void QSort3(int loSt, int hiSt, int dSt)
{
StackElem[] array = new StackElem[1000];
for (int i = 0; i < 1000; i++)
{
array[i] = new StackElem();
}
int num = 0;
array[num].ll = loSt;
array[num].hh = hiSt;
array[num].dd = dSt;
num++;
while (num > 0)
{
if (num >= 1000)
{
Panic();
}
num--;
int ll = array[num].ll;
int hh = array[num].hh;
int dd = array[num].dd;
if (hh - ll < 20 || dd > 10)
{
SimpleSort(ll, hh, dd);
if (workDone > workLimit && firstAttempt)
{
break;
}
continue;
}
int num2 = Med3(block[zptr[ll] + dd + 1], block[zptr[hh] + dd + 1], block[zptr[ll + hh >> 1] + dd + 1]);
int num4;
int num3 = (num4 = ll);
int num6;
int num5 = (num6 = hh);
int num7;
while (true)
{
if (num3 <= num5)
{
num7 = block[zptr[num3] + dd + 1] - num2;
if (num7 == 0)
{
int num8 = 0;
num8 = zptr[num3];
zptr[num3] = zptr[num4];
zptr[num4] = num8;
num4++;
num3++;
continue;
}
if (num7 <= 0)
{
num3++;
continue;
}
}
while (num3 <= num5)
{
num7 = block[zptr[num5] + dd + 1] - num2;
if (num7 == 0)
{
int num9 = 0;
num9 = zptr[num5];
zptr[num5] = zptr[num6];
zptr[num6] = num9;
num6--;
num5--;
}
else
{
if (num7 < 0)
{
break;
}
num5--;
}
}
if (num3 > num5)
{
break;
}
int num10 = zptr[num3];
zptr[num3] = zptr[num5];
zptr[num5] = num10;
num3++;
num5--;
}
if (num6 < num4)
{
array[num].ll = ll;
array[num].hh = hh;
array[num].dd = dd + 1;
num++;
continue;
}
num7 = ((num4 - ll < num3 - num4) ? (num4 - ll) : (num3 - num4));
Vswap(ll, num3 - num7, num7);
int num11 = ((hh - num6 < num6 - num5) ? (hh - num6) : (num6 - num5));
Vswap(num3, hh - num11 + 1, num11);
num7 = ll + num3 - num4 - 1;
num11 = hh - (num6 - num5) + 1;
array[num].ll = ll;
array[num].hh = num7;
array[num].dd = dd;
num++;
array[num].ll = num7 + 1;
array[num].hh = num11 - 1;
array[num].dd = dd + 1;
num++;
array[num].ll = num11;
array[num].hh = hh;
array[num].dd = dd;
num++;
}
}
private void MainSort()
{
int[] array = new int[256];
int[] array2 = new int[256];
bool[] array3 = new bool[256];
for (int i = 0; i < 20; i++)
{
block[last + i + 2] = block[i % (last + 1) + 1];
}
for (int i = 0; i <= last + 20; i++)
{
quadrant[i] = 0;
}
block[0] = block[last + 1];
if (last < 4000)
{
for (int i = 0; i <= last; i++)
{
zptr[i] = i;
}
firstAttempt = false;
workDone = (workLimit = 0);
SimpleSort(0, last, 0);
return;
}
int num = 0;
for (int i = 0; i <= 255; i++)
{
array3[i] = false;
}
for (int i = 0; i <= 65536; i++)
{
ftab[i] = 0;
}
int num2 = block[0];
int[] array5;
nint num5;
for (int i = 0; i <= last; i++)
{
int num3 = block[i + 1];
int[] array4 = (array5 = ftab);
int num4 = (num2 << 8) + num3;
num5 = num4;
array4[num4] = array5[num5] + 1;
num2 = num3;
}
for (int i = 1; i <= 65536; i++)
{
int[] array6 = (array5 = ftab);
int num6 = i;
num5 = num6;
array6[num6] = array5[num5] + ftab[i - 1];
}
num2 = block[1];
int num7;
for (int i = 0; i < last; i++)
{
int num3 = block[i + 2];
num7 = (num2 << 8) + num3;
num2 = num3;
int[] array7 = (array5 = ftab);
int num8 = num7;
num5 = num8;
array7[num8] = array5[num5] - 1;
zptr[ftab[num7]] = i;
}
num7 = (int)(((uint)block[last + 1] << 8) + block[1]);
int[] array8 = (array5 = ftab);
int num9 = num7;
num5 = num9;
array8[num9] = array5[num5] - 1;
zptr[ftab[num7]] = last;
for (int i = 0; i <= 255; i++)
{
array[i] = i;
}
int num10 = 1;
do
{
num10 = 3 * num10 + 1;
}
while (num10 <= 256);
do
{
num10 /= 3;
for (int i = num10; i <= 255; i++)
{
int num11 = array[i];
num7 = i;
while (ftab[array[num7 - num10] + 1 << 8] - ftab[array[num7 - num10] << 8] > ftab[num11 + 1 << 8] - ftab[num11 << 8])
{
array[num7] = array[num7 - num10];
num7 -= num10;
if (num7 <= num10 - 1)
{
break;
}
}
array[num7] = num11;
}
}
while (num10 != 1);
for (int i = 0; i <= 255; i++)
{
int num12 = array[i];
for (num7 = 0; num7 <= 255; num7++)
{
int num13 = (num12 << 8) + num7;
if ((ftab[num13] & 0x200000) == 2097152)
{
continue;
}
int num14 = ftab[num13] & -2097153;
int num15 = (ftab[num13 + 1] & -2097153) - 1;
if (num15 > num14)
{
QSort3(num14, num15, 2);
num += num15 - num14 + 1;
if (workDone > workLimit && firstAttempt)
{
return;
}
}
int[] array9 = (array5 = ftab);
num5 = num13;
array9[num13] = array5[num5] | 0x200000;
}
array3[num12] = true;
if (i < 255)
{
int num16 = ftab[num12 << 8] & -2097153;
int num17 = (ftab[num12 + 1 << 8] & -2097153) - num16;
int j;
for (j = 0; num17 >> j > 65534; j++)
{
}
for (num7 = 0; num7 < num17; num7++)
{
int num18 = zptr[num16 + num7];
int num19 = num7 >> j;
quadrant[num18] = num19;
if (num18 < 20)
{
quadrant[num18 + last + 1] = num19;
}
}
if (num17 - 1 >> j > 65535)
{
Panic();
}
}
for (num7 = 0; num7 <= 255; num7++)
{
array2[num7] = ftab[(num7 << 8) + num12] & -2097153;
}
for (num7 = ftab[num12 << 8] & -2097153; num7 < (ftab[num12 + 1 << 8] & -2097153); num7++)
{
num2 = block[zptr[num7]];
if (!array3[num2])
{
zptr[array2[num2]] = ((zptr[num7] == 0) ? last : (zptr[num7] - 1));
int[] array10 = (array5 = array2);
int num20 = num2;
num5 = num20;
array10[num20] = array5[num5] + 1;
}
}
for (num7 = 0; num7 <= 255; num7++)
{
int[] array11 = (array5 = ftab);
int num21 = (num7 << 8) + num12;
num5 = num21;
array11[num21] = array5[num5] | 0x200000;
}
}
}
private void RandomiseBlock()
{
int num = 0;
int num2 = 0;
for (int i = 0; i < 256; i++)
{
inUse[i] = false;
}
for (int i = 0; i <= last; i++)
{
if (num == 0)
{
num = (ushort)BZip2Constants.rNums[num2];
num2++;
if (num2 == 512)
{
num2 = 0;
}
}
num--;
char[] array2;
char[] array = (array2 = block);
int num3 = i + 1;
nint num4 = num3;
array[num3] = (char)((uint)array2[num4] ^ ((num == 1) ? 1u : 0u));
char[] array3 = (array2 = block);
int num5 = i + 1;
num4 = num5;
array3[num5] = (char)(array2[num4] & 0xFF);
inUse[(uint)block[i + 1]] = true;
}
}
private void DoReversibleTransformation()
{
workLimit = workFactor * last;
workDone = 0;
blockRandomised = false;
firstAttempt = true;
MainSort();
if (workDone > workLimit && firstAttempt)
{
RandomiseBlock();
workLimit = (workDone = 0);
blockRandomised = true;
firstAttempt = false;
MainSort();
}
origPtr = -1;
for (int i = 0; i <= last; i++)
{
if (zptr[i] == 0)
{
origPtr = i;
break;
}
}
if (origPtr == -1)
{
Panic();
}
}
private bool FullGtU(int i1, int i2)
{
char c = block[i1 + 1];
char c2 = block[i2 + 1];
if (c != c2)
{
return c > c2;
}
i1++;
i2++;
c = block[i1 + 1];
c2 = block[i2 + 1];
if (c != c2)
{
return c > c2;
}
i1++;
i2++;
c = block[i1 + 1];
c2 = block[i2 + 1];
if (c != c2)
{
return c > c2;
}
i1++;
i2++;
c = block[i1 + 1];
c2 = block[i2 + 1];
if (c != c2)
{
return c > c2;
}
i1++;
i2++;
c = block[i1 + 1];
c2 = block[i2 + 1];
if (c != c2)
{
return c > c2;
}
i1++;
i2++;
c = block[i1 + 1];
c2 = block[i2 + 1];
if (c != c2)
{
return c > c2;
}
i1++;
i2++;
int num = last + 1;
do
{
c = block[i1 + 1];
c2 = block[i2 + 1];
if (c != c2)
{
return c > c2;
}
int num2 = quadrant[i1];
int num3 = quadrant[i2];
if (num2 != num3)
{
return num2 > num3;
}
i1++;
i2++;
c = block[i1 + 1];
c2 = block[i2 + 1];
if (c != c2)
{
return c > c2;
}
num2 = quadrant[i1];
num3 = quadrant[i2];
if (num2 != num3)
{
return num2 > num3;
}
i1++;
i2++;
c = block[i1 + 1];
c2 = block[i2 + 1];
if (c != c2)
{
return c > c2;
}
num2 = quadrant[i1];
num3 = quadrant[i2];
if (num2 != num3)
{
return num2 > num3;
}
i1++;
i2++;
c = block[i1 + 1];
c2 = block[i2 + 1];
if (c != c2)
{
return c > c2;
}
num2 = quadrant[i1];
num3 = quadrant[i2];
if (num2 != num3)
{
return num2 > num3;
}
i1++;
i2++;
if (i1 > last)
{
i1 -= last;
i1--;
}
if (i2 > last)
{
i2 -= last;
i2--;
}
num -= 4;
workDone++;
}
while (num >= 0);
return false;
}
private void AllocateCompressStructures()
{
int num = 100000 * blockSize100k;
block = new char[num + 1 + 20];
quadrant = new int[num + 20];
zptr = new int[num];
ftab = new int[65537];
if (block != null && quadrant != null && zptr != null)
{
_ = ftab;
}
szptr = new short[2 * num];
}
private void GenerateMTFValues()
{
char[] array = new char[256];
MakeMaps();
int num = nInUse + 1;
for (int i = 0; i <= num; i++)
{
mtfFreq[i] = 0;
}
int num2 = 0;
int num3 = 0;
for (int i = 0; i < nInUse; i++)
{
array[i] = (char)i;
}
int[] array2;
nint num6;
for (int i = 0; i <= last; i++)
{
char c = unseqToSeq[(uint)block[zptr[i]]];
int num4 = 0;
char c2 = array[num4];
while (c != c2)
{
num4++;
char c3 = c2;
c2 = array[num4];
array[num4] = c3;
}
array[0] = c2;
if (num4 == 0)
{
num3++;
continue;
}
if (num3 > 0)
{
num3--;
while (true)
{
switch (num3 % 2)
{
case 0:
szptr[num2] = 0;
num2++;
(array2 = mtfFreq)[0] = array2[0] + 1;
break;
case 1:
szptr[num2] = 1;
num2++;
(array2 = mtfFreq)[1] = array2[1] + 1;
break;
}
if (num3 < 2)
{
break;
}
num3 = (num3 - 2) / 2;
}
num3 = 0;
}
szptr[num2] = (short)(num4 + 1);
num2++;
int[] array3 = (array2 = mtfFreq);
int num5 = num4 + 1;
num6 = num5;
array3[num5] = array2[num6] + 1;
}
if (num3 > 0)
{
num3--;
while (true)
{
switch (num3 % 2)
{
case 0:
szptr[num2] = 0;
num2++;
(array2 = mtfFreq)[0] = array2[0] + 1;
break;
case 1:
szptr[num2] = 1;
num2++;
(array2 = mtfFreq)[1] = array2[1] + 1;
break;
}
if (num3 < 2)
{
break;
}
num3 = (num3 - 2) / 2;
}
}
szptr[num2] = (short)num;
num2++;
int[] array4 = (array2 = mtfFreq);
num6 = num;
array4[num] = array2[num6] + 1;
nMTF = num2;
}
public override int Read(byte[] buffer, int offset, int count)
{
return 0;
}
public override long Seek(long offset, SeekOrigin origin)
{
return 0L;
}
public override void SetLength(long value)
{
}
public override void Write(byte[] buffer, int offset, int count)
{
for (int i = 0; i < count; i++)
{
WriteByte(buffer[i + offset]);
}
}
}