rar5: refactor unpack classes

This commit is contained in:
coderb
2017-12-17 11:33:31 -05:00
parent d268cc7685
commit 1445b0a48b
11 changed files with 752 additions and 56 deletions

View File

@@ -3,7 +3,7 @@ namespace SharpCompress.Compressors.Rar.Decode
internal class BitDecode : Decode
{
internal BitDecode()
: base(new int[Compress.BC])
: base(new int[PackDef.BC])
{
}
}

View File

@@ -3,7 +3,7 @@ namespace SharpCompress.Compressors.Rar.Decode
internal class DistDecode : Decode
{
internal DistDecode()
: base(new int[Compress.DC])
: base(new int[PackDef.DC])
{
}
}

View File

@@ -3,7 +3,7 @@ namespace SharpCompress.Compressors.Rar.Decode
internal class LitDecode : Decode
{
internal LitDecode()
: base(new int[Compress.NC])
: base(new int[PackDef.NC])
{
}
}

View File

@@ -3,7 +3,7 @@ namespace SharpCompress.Compressors.Rar.Decode
internal class LowDistDecode : Decode
{
internal LowDistDecode()
: base(new int[Compress.LDC])
: base(new int[PackDef.LDC])
{
}
}

View File

@@ -3,7 +3,7 @@ namespace SharpCompress.Compressors.Rar.Decode
internal class MultDecode : Decode
{
internal MultDecode()
: base(new int[Compress.MC20])
: base(new int[PackDef.MC20])
{
}
}

View File

@@ -1,6 +1,6 @@
namespace SharpCompress.Compressors.Rar.Decode
{
internal class Compress
internal class PackDef
{
public const int CODEBUFSIZE = 0x4000;
public const int MAXWINSIZE = 0x400000;

View File

@@ -3,7 +3,7 @@ namespace SharpCompress.Compressors.Rar.Decode
internal class RepDecode : Decode
{
internal RepDecode()
: base(new int[Compress.RC])
: base(new int[PackDef.RC])
{
}
}

View File

@@ -82,7 +82,7 @@ namespace SharpCompress.Compressors.Rar
//UPGRADE_NOTE: The initialization of 'unpOldTable' was moved to method 'InitBlock'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1005'"
private readonly byte[] unpOldTable = new byte[Compress.HUFF_TABLE_SIZE];
private readonly byte[] unpOldTable = new byte[PackDef.HUFF_TABLE_SIZE];
private BlockTypes unpBlockType;
@@ -114,7 +114,7 @@ namespace SharpCompress.Compressors.Rar
{
if (window == null)
{
this.window = new byte[Compress.MAXWINSIZE];
this.window = new byte[PackDef.MAXWINSIZE];
}
else
{
@@ -198,8 +198,8 @@ namespace SharpCompress.Compressors.Rar
private void unpack29(bool solid)
{
int[] DDecode = new int[Compress.DC];
byte[] DBits = new byte[Compress.DC];
int[] DDecode = new int[PackDef.DC];
byte[] DBits = new byte[PackDef.DC];
int Bits;
@@ -239,7 +239,7 @@ namespace SharpCompress.Compressors.Rar
while (true)
{
unpPtr &= Compress.MAXWINMASK;
unpPtr &= PackDef.MAXWINMASK;
if (inAddr > readBorder)
{
@@ -251,7 +251,7 @@ namespace SharpCompress.Compressors.Rar
// System.out.println(((wrPtr - unpPtr) &
// Compress.MAXWINMASK)+":"+wrPtr+":"+unpPtr);
if (((wrPtr - unpPtr) & Compress.MAXWINMASK) < 260 && wrPtr != unpPtr)
if (((wrPtr - unpPtr) & PackDef.MAXWINMASK) < 260 && wrPtr != unpPtr)
{
UnpWriteBuf();
if (destUnpSize <= 0)
@@ -378,7 +378,7 @@ namespace SharpCompress.Compressors.Rar
int LowDist = this.decodeNumber(LDD);
if (LowDist == 16)
{
lowDistRepCount = Compress.LOW_DIST_REP_COUNT - 1;
lowDistRepCount = PackDef.LOW_DIST_REP_COUNT - 1;
Distance += prevLowDist;
}
else
@@ -474,7 +474,7 @@ namespace SharpCompress.Compressors.Rar
private void UnpWriteBuf()
{
int WrittenBorder = wrPtr;
int WriteSize = (unpPtr - WrittenBorder) & Compress.MAXWINMASK;
int WriteSize = (unpPtr - WrittenBorder) & PackDef.MAXWINMASK;
for (int I = 0; I < prgStack.Count; I++)
{
UnpackFilter flt = prgStack[I];
@@ -489,17 +489,17 @@ namespace SharpCompress.Compressors.Rar
}
int BlockStart = flt.BlockStart; // ->BlockStart;
int BlockLength = flt.BlockLength; // ->BlockLength;
if (((BlockStart - WrittenBorder) & Compress.MAXWINMASK) < WriteSize)
if (((BlockStart - WrittenBorder) & PackDef.MAXWINMASK) < WriteSize)
{
if (WrittenBorder != BlockStart)
{
UnpWriteArea(WrittenBorder, BlockStart);
WrittenBorder = BlockStart;
WriteSize = (unpPtr - WrittenBorder) & Compress.MAXWINMASK;
WriteSize = (unpPtr - WrittenBorder) & PackDef.MAXWINMASK;
}
if (BlockLength <= WriteSize)
{
int BlockEnd = (BlockStart + BlockLength) & Compress.MAXWINMASK;
int BlockEnd = (BlockStart + BlockLength) & PackDef.MAXWINMASK;
if (BlockStart < BlockEnd || BlockEnd == 0)
{
// VM.SetMemory(0,Window+BlockStart,BlockLength);
@@ -507,7 +507,7 @@ namespace SharpCompress.Compressors.Rar
}
else
{
int FirstPartLength = Compress.MAXWINSIZE - BlockStart;
int FirstPartLength = PackDef.MAXWINSIZE - BlockStart;
// VM.SetMemory(0,Window+BlockStart,FirstPartLength);
rarVM.setMemory(0, window, BlockStart, FirstPartLength);
@@ -641,7 +641,7 @@ namespace SharpCompress.Compressors.Rar
writtenFileSize += FilteredDataSize;
destUnpSize -= FilteredDataSize;
WrittenBorder = BlockEnd;
WriteSize = (unpPtr - WrittenBorder) & Compress.MAXWINMASK;
WriteSize = (unpPtr - WrittenBorder) & PackDef.MAXWINMASK;
}
else
{
@@ -671,7 +671,7 @@ namespace SharpCompress.Compressors.Rar
}
if (endPtr < startPtr)
{
UnpWriteData(window, startPtr, -startPtr & Compress.MAXWINMASK);
UnpWriteData(window, startPtr, -startPtr & PackDef.MAXWINMASK);
UnpWriteData(window, 0, endPtr);
unpAllBuf = true;
}
@@ -719,7 +719,7 @@ namespace SharpCompress.Compressors.Rar
int destPtr = unpPtr - distance;
// System.out.println(unpPtr+":"+distance);
if (destPtr >= 0 && destPtr < Compress.MAXWINSIZE - 260 && unpPtr < Compress.MAXWINSIZE - 260)
if (destPtr >= 0 && destPtr < PackDef.MAXWINSIZE - 260 && unpPtr < PackDef.MAXWINSIZE - 260)
{
window[unpPtr++] = window[destPtr++];
@@ -732,8 +732,8 @@ namespace SharpCompress.Compressors.Rar
{
while (length-- != 0)
{
window[unpPtr] = window[destPtr++ & Compress.MAXWINMASK];
unpPtr = (unpPtr + 1) & Compress.MAXWINMASK;
window[unpPtr] = window[destPtr++ & PackDef.MAXWINMASK];
unpPtr = (unpPtr + 1) & PackDef.MAXWINMASK;
}
}
}
@@ -796,9 +796,9 @@ namespace SharpCompress.Compressors.Rar
private bool readTables()
{
byte[] bitLength = new byte[Compress.BC];
byte[] bitLength = new byte[PackDef.BC];
byte[] table = new byte[Compress.HUFF_TABLE_SIZE];
byte[] table = new byte[PackDef.HUFF_TABLE_SIZE];
if (inAddr > readTop - 25)
{
if (!unpReadBuf())
@@ -824,7 +824,7 @@ namespace SharpCompress.Compressors.Rar
}
AddBits(2);
for (int i = 0; i < Compress.BC; i++)
for (int i = 0; i < PackDef.BC; i++)
{
int length = (Utility.URShift(GetBits(), 12)) & 0xFF;
AddBits(4);
@@ -852,9 +852,9 @@ namespace SharpCompress.Compressors.Rar
}
}
UnpackUtility.makeDecodeTables(bitLength, 0, BD, Compress.BC);
UnpackUtility.makeDecodeTables(bitLength, 0, BD, PackDef.BC);
int TableSize = Compress.HUFF_TABLE_SIZE;
int TableSize = PackDef.HUFF_TABLE_SIZE;
for (int i = 0; i < TableSize;)
{
@@ -914,10 +914,10 @@ namespace SharpCompress.Compressors.Rar
{
return (false);
}
UnpackUtility.makeDecodeTables(table, 0, LD, Compress.NC);
UnpackUtility.makeDecodeTables(table, Compress.NC, DD, Compress.DC);
UnpackUtility.makeDecodeTables(table, Compress.NC + Compress.DC, LDD, Compress.LDC);
UnpackUtility.makeDecodeTables(table, Compress.NC + Compress.DC + Compress.LDC, RD, Compress.RC);
UnpackUtility.makeDecodeTables(table, 0, LD, PackDef.NC);
UnpackUtility.makeDecodeTables(table, PackDef.NC, DD, PackDef.DC);
UnpackUtility.makeDecodeTables(table, PackDef.NC + PackDef.DC, LDD, PackDef.LDC);
UnpackUtility.makeDecodeTables(table, PackDef.NC + PackDef.DC + PackDef.LDC, RD, PackDef.RC);
// memcpy(unpOldTable,table,sizeof(unpOldTable));
@@ -1077,7 +1077,7 @@ namespace SharpCompress.Compressors.Rar
{
BlockStart += 258;
}
StackFilter.BlockStart = ((BlockStart + unpPtr) & Compress.MAXWINMASK);
StackFilter.BlockStart = ((BlockStart + unpPtr) & PackDef.MAXWINMASK);
if ((firstByte & 0x20) != 0)
{
StackFilter.BlockLength = RarVM.ReadData(Inp);
@@ -1086,7 +1086,7 @@ namespace SharpCompress.Compressors.Rar
{
StackFilter.BlockLength = FiltPos < oldFilterLengths.Count ? oldFilterLengths[FiltPos] : 0;
}
StackFilter.NextWindow = (wrPtr != unpPtr) && ((wrPtr - unpPtr) & Compress.MAXWINMASK) <= BlockStart;
StackFilter.NextWindow = (wrPtr != unpPtr) && ((wrPtr - unpPtr) & PackDef.MAXWINMASK) <= BlockStart;
// DebugLog("\nNextWindow: UnpPtr=%08x WrPtr=%08x
// BlockStart=%08x",UnpPtr,WrPtr,BlockStart);

View File

@@ -174,13 +174,13 @@ namespace SharpCompress.Compressors.Rar
while (destUnpSize >= 0)
{
unpPtr &= Compress.MAXWINMASK;
unpPtr &= PackDef.MAXWINMASK;
if (inAddr > readTop - 30 && !unpReadBuf())
{
break;
}
if (((wrPtr - unpPtr) & Compress.MAXWINMASK) < 270 && wrPtr != unpPtr)
if (((wrPtr - unpPtr) & PackDef.MAXWINMASK) < 270 && wrPtr != unpPtr)
{
oldUnpWriteBuf();
if (suspended)
@@ -702,8 +702,8 @@ namespace SharpCompress.Compressors.Rar
destUnpSize -= Length;
while ((Length--) != 0)
{
window[unpPtr] = window[(unpPtr - Distance) & Compress.MAXWINMASK];
unpPtr = (unpPtr + 1) & Compress.MAXWINMASK;
window[unpPtr] = window[(unpPtr - Distance) & PackDef.MAXWINMASK];
unpPtr = (unpPtr + 1) & PackDef.MAXWINMASK;
}
}
@@ -726,7 +726,7 @@ namespace SharpCompress.Compressors.Rar
}
if (unpPtr < wrPtr)
{
writeStream.Write(window, wrPtr, -wrPtr & Compress.MAXWINMASK);
writeStream.Write(window, wrPtr, -wrPtr & PackDef.MAXWINMASK);
writeStream.Write(window, 0, unpPtr);
unpAllBuf = true;
}

View File

@@ -37,7 +37,7 @@ namespace SharpCompress.Compressors.Rar
private void InitBlock()
{
UnpOldTable20 = new byte[Compress.MC20 * 4];
UnpOldTable20 = new byte[PackDef.MC20 * 4];
}
protected internal MultDecode[] MD = new MultDecode[4];
@@ -124,7 +124,7 @@ namespace SharpCompress.Compressors.Rar
while (destUnpSize >= 0)
{
unpPtr &= Compress.MAXWINMASK;
unpPtr &= PackDef.MAXWINMASK;
if (inAddr > readTop - 30)
{
@@ -133,7 +133,7 @@ namespace SharpCompress.Compressors.Rar
break;
}
}
if (((wrPtr - unpPtr) & Compress.MAXWINMASK) < 270 && wrPtr != unpPtr)
if (((wrPtr - unpPtr) & PackDef.MAXWINMASK) < 270 && wrPtr != unpPtr)
{
oldUnpWriteBuf();
if (suspended)
@@ -258,7 +258,7 @@ namespace SharpCompress.Compressors.Rar
destUnpSize -= Length;
int DestPtr = unpPtr - Distance;
if (DestPtr < Compress.MAXWINSIZE - 300 && unpPtr < Compress.MAXWINSIZE - 300)
if (DestPtr < PackDef.MAXWINSIZE - 300 && unpPtr < PackDef.MAXWINSIZE - 300)
{
window[unpPtr++] = window[DestPtr++];
window[unpPtr++] = window[DestPtr++];
@@ -272,16 +272,16 @@ namespace SharpCompress.Compressors.Rar
{
while ((Length--) != 0)
{
window[unpPtr] = window[DestPtr++ & Compress.MAXWINMASK];
unpPtr = (unpPtr + 1) & Compress.MAXWINMASK;
window[unpPtr] = window[DestPtr++ & PackDef.MAXWINMASK];
unpPtr = (unpPtr + 1) & PackDef.MAXWINMASK;
}
}
}
private bool ReadTables20()
{
byte[] BitLength = new byte[Compress.BC20];
byte[] Table = new byte[Compress.MC20 * 4];
byte[] BitLength = new byte[PackDef.BC20];
byte[] Table = new byte[PackDef.MC20 * 4];
int TableSize, N, I;
if (inAddr > readTop - 25)
{
@@ -308,18 +308,18 @@ namespace SharpCompress.Compressors.Rar
UnpCurChannel = 0;
}
AddBits(2);
TableSize = Compress.MC20 * UnpChannels;
TableSize = PackDef.MC20 * UnpChannels;
}
else
{
TableSize = Compress.NC20 + Compress.DC20 + Compress.RC20;
TableSize = PackDef.NC20 + PackDef.DC20 + PackDef.RC20;
}
for (I = 0; I < Compress.BC20; I++)
for (I = 0; I < PackDef.BC20; I++)
{
BitLength[I] = (byte)(Utility.URShift(GetBits(), 12));
AddBits(4);
}
UnpackUtility.makeDecodeTables(BitLength, 0, BD, Compress.BC20);
UnpackUtility.makeDecodeTables(BitLength, 0, BD, PackDef.BC20);
I = 0;
while (I < TableSize)
{
@@ -372,14 +372,14 @@ namespace SharpCompress.Compressors.Rar
{
for (I = 0; I < UnpChannels; I++)
{
UnpackUtility.makeDecodeTables(Table, I * Compress.MC20, MD[I], Compress.MC20);
UnpackUtility.makeDecodeTables(Table, I * PackDef.MC20, MD[I], PackDef.MC20);
}
}
else
{
UnpackUtility.makeDecodeTables(Table, 0, LD, Compress.NC20);
UnpackUtility.makeDecodeTables(Table, Compress.NC20, DD, Compress.DC20);
UnpackUtility.makeDecodeTables(Table, Compress.NC20 + Compress.DC20, RD, Compress.RC20);
UnpackUtility.makeDecodeTables(Table, 0, LD, PackDef.NC20);
UnpackUtility.makeDecodeTables(Table, PackDef.NC20, DD, PackDef.DC20);
UnpackUtility.makeDecodeTables(Table, PackDef.NC20 + PackDef.DC20, RD, PackDef.RC20);
}
// memcpy(UnpOldTable20,Table,sizeof(UnpOldTable20));

View File

@@ -0,0 +1,696 @@
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Threading.Tasks;
//
//namespace SharpCompress.Compressors.Rar
//{
// internal sealed class Unpack50
// {
//
// public void Unpack5(bool Solid) {
// FileExtracted=true;
//
// if (!Suspended)
// {
// UnpInitData(Solid);
// if (!UnpReadBuf())
// return;
//
// // Check TablesRead5 to be sure that we read tables at least once
// // regardless of current block header TablePresent flag.
// // So we can safefly use these tables below.
// if (!ReadBlockHeader(Inp,BlockHeader) ||
// !ReadTables(Inp,BlockHeader,BlockTables) || !TablesRead5)
// return;
// }
//
// while (true)
// {
// UnpPtr&=MaxWinMask;
//
// if (Inp.InAddr>=ReadBorder)
// {
// bool FileDone=false;
//
// // We use 'while', because for empty block containing only Huffman table,
// // we'll be on the block border once again just after reading the table.
// while (Inp.InAddr>BlockHeader.BlockStart+BlockHeader.BlockSize-1 ||
// Inp.InAddr==BlockHeader.BlockStart+BlockHeader.BlockSize-1 &&
// Inp.InBit>=BlockHeader.BlockBitSize)
// {
// if (BlockHeader.LastBlockInFile)
// {
// FileDone=true;
// break;
// }
// if (!ReadBlockHeader(Inp,BlockHeader) || !ReadTables(Inp,BlockHeader,BlockTables))
// return;
// }
// if (FileDone || !UnpReadBuf())
// break;
// }
//
// if (((WriteBorder-UnpPtr) & MaxWinMask)<MAX_LZ_MATCH+3 && WriteBorder!=UnpPtr)
// {
// UnpWriteBuf();
// if (WrittenFileSize>DestUnpSize)
// return;
// if (Suspended)
// {
// FileExtracted=false;
// return;
// }
// }
//
// uint MainSlot=DecodeNumber(Inp,&BlockTables.LD);
// if (MainSlot<256)
// {
// if (Fragmented)
// FragWindow[UnpPtr++]=(byte)MainSlot;
// else
// Window[UnpPtr++]=(byte)MainSlot;
// continue;
// }
// if (MainSlot>=262)
// {
// uint Length=SlotToLength(Inp,MainSlot-262);
//
// uint DBits,Distance=1,DistSlot=DecodeNumber(Inp,&BlockTables.DD);
// if (DistSlot<4)
// {
// DBits=0;
// Distance+=DistSlot;
// }
// else
// {
// DBits=DistSlot/2 - 1;
// Distance+=(2 | (DistSlot & 1)) << DBits;
// }
//
// if (DBits>0)
// {
// if (DBits>=4)
// {
// if (DBits>4)
// {
// Distance+=((Inp.getbits32()>>(36-DBits))<<4);
// Inp.addbits(DBits-4);
// }
// uint LowDist=DecodeNumber(Inp,&BlockTables.LDD);
// Distance+=LowDist;
// }
// else
// {
// Distance+=Inp.getbits32()>>(32-DBits);
// Inp.addbits(DBits);
// }
// }
//
// if (Distance>0x100)
// {
// Length++;
// if (Distance>0x2000)
// {
// Length++;
// if (Distance>0x40000)
// Length++;
// }
// }
//
// InsertOldDist(Distance);
// LastLength=Length;
// if (Fragmented)
// FragWindow.CopyString(Length,Distance,UnpPtr,MaxWinMask);
// else
// CopyString(Length,Distance);
// continue;
// }
// if (MainSlot==256)
// {
// UnpackFilter Filter;
// if (!ReadFilter(Inp,Filter) || !AddFilter(Filter))
// break;
// continue;
// }
// if (MainSlot==257)
// {
// if (LastLength!=0)
// if (Fragmented)
// FragWindow.CopyString(LastLength,OldDist[0],UnpPtr,MaxWinMask);
// else
// CopyString(LastLength,OldDist[0]);
// continue;
// }
// if (MainSlot<262)
// {
// uint DistNum=MainSlot-258;
// uint Distance=OldDist[DistNum];
// for (uint I=DistNum;I>0;I--)
// OldDist[I]=OldDist[I-1];
// OldDist[0]=Distance;
//
// uint LengthSlot=DecodeNumber(Inp,&BlockTables.RD);
// uint Length=SlotToLength(Inp,LengthSlot);
// LastLength=Length;
// if (Fragmented)
// FragWindow.CopyString(Length,Distance,UnpPtr,MaxWinMask);
// else
// CopyString(Length,Distance);
// continue;
// }
// }
// UnpWriteBuf();
//}
//
//
//uint ReadFilterData(BitInput &Inp)
//{
// uint ByteCount=(Inp.fgetbits()>>14)+1;
// Inp.addbits(2);
//
// uint Data=0;
// for (uint I=0;I<ByteCount;I++)
// {
// Data+=(Inp.fgetbits()>>8)<<(I*8);
// Inp.addbits(8);
// }
// return Data;
//}
//
//
//bool ReadFilter(BitInput &Inp,UnpackFilter &Filter)
//{
// if (!Inp.ExternalBuffer && Inp.InAddr>ReadTop-16)
// if (!UnpReadBuf())
// return false;
//
// Filter.BlockStart=ReadFilterData(Inp);
// Filter.BlockLength=ReadFilterData(Inp);
// if (Filter.BlockLength>MAX_FILTER_BLOCK_SIZE)
// Filter.BlockLength=0;
//
// Filter.Type=Inp.fgetbits()>>13;
// Inp.faddbits(3);
//
// if (Filter.Type==FILTER_DELTA)
// {
// Filter.Channels=(Inp.fgetbits()>>11)+1;
// Inp.faddbits(5);
// }
//
// return true;
//}
//
//
//bool AddFilter(UnpackFilter &Filter)
//{
// if (Filters.Size()>=MAX_UNPACK_FILTERS)
// {
// UnpWriteBuf(); // Write data, apply and flush filters.
// if (Filters.Size()>=MAX_UNPACK_FILTERS)
// InitFilters(); // Still too many filters, prevent excessive memory use.
// }
//
// // If distance to filter start is that large that due to circular dictionary
// // mode now it points to old not written yet data, then we set 'NextWindow'
// // flag and process this filter only after processing that older data.
// Filter.NextWindow=WrPtr!=UnpPtr && ((WrPtr-UnpPtr)&MaxWinMask)<=Filter.BlockStart;
//
// Filter.BlockStart=uint((Filter.BlockStart+UnpPtr)&MaxWinMask);
// Filters.Push(Filter);
// return true;
//}
//
//
//bool UnpReadBuf()
//{
// int DataSize=ReadTop-Inp.InAddr; // Data left to process.
// if (DataSize<0)
// return false;
// BlockHeader.BlockSize-=Inp.InAddr-BlockHeader.BlockStart;
// if (Inp.InAddr>BitInput::MAX_SIZE/2)
// {
// // If we already processed more than half of buffer, let's move
// // remaining data into beginning to free more space for new data
// // and ensure that calling function does not cross the buffer border
// // even if we did not read anything here. Also it ensures that read size
// // is not less than CRYPT_BLOCK_SIZE, so we can align it without risk
// // to make it zero.
// if (DataSize>0)
// memmove(Inp.InBuf,Inp.InBuf+Inp.InAddr,DataSize);
// Inp.InAddr=0;
// ReadTop=DataSize;
// }
// else
// DataSize=ReadTop;
// int ReadCode=0;
// if (BitInput::MAX_SIZE!=DataSize)
// ReadCode=UnpIO->UnpRead(Inp.InBuf+DataSize,BitInput::MAX_SIZE-DataSize);
// if (ReadCode>0) // Can be also -1.
// ReadTop+=ReadCode;
// ReadBorder=ReadTop-30;
// BlockHeader.BlockStart=Inp.InAddr;
// if (BlockHeader.BlockSize!=-1) // '-1' means not defined yet.
// {
// // We may need to quit from main extraction loop and read new block header
// // and trees earlier than data in input buffer ends.
// ReadBorder=Min(ReadBorder,BlockHeader.BlockStart+BlockHeader.BlockSize-1);
// }
// return ReadCode!=-1;
//}
//
//
//void UnpWriteBuf()
//{
// size_t WrittenBorder=WrPtr;
// size_t FullWriteSize=(UnpPtr-WrittenBorder)&MaxWinMask;
// size_t WriteSizeLeft=FullWriteSize;
// bool NotAllFiltersProcessed=false;
// for (size_t I=0;I<Filters.Size();I++)
// {
// // Here we apply filters to data which we need to write.
// // We always copy data to another memory block before processing.
// // We cannot process them just in place in Window buffer, because
// // these data can be used for future string matches, so we must
// // preserve them in original form.
//
// UnpackFilter *flt=&Filters[I];
// if (flt->Type==FILTER_NONE)
// continue;
// if (flt->NextWindow)
// {
// // Here we skip filters which have block start in current data range
// // due to address wrap around in circular dictionary, but actually
// // belong to next dictionary block. If such filter start position
// // is included to current write range, then we reset 'NextWindow' flag.
// // In fact we can reset it even without such check, because current
// // implementation seems to guarantee 'NextWindow' flag reset after
// // buffer writing for all existing filters. But let's keep this check
// // just in case. Compressor guarantees that distance between
// // filter block start and filter storing position cannot exceed
// // the dictionary size. So if we covered the filter block start with
// // our write here, we can safely assume that filter is applicable
// // to next block on no further wrap arounds is possible.
// if (((flt->BlockStart-WrPtr)&MaxWinMask)<=FullWriteSize)
// flt->NextWindow=false;
// continue;
// }
// uint BlockStart=flt->BlockStart;
// uint BlockLength=flt->BlockLength;
// if (((BlockStart-WrittenBorder)&MaxWinMask)<WriteSizeLeft)
// {
// if (WrittenBorder!=BlockStart)
// {
// UnpWriteArea(WrittenBorder,BlockStart);
// WrittenBorder=BlockStart;
// WriteSizeLeft=(UnpPtr-WrittenBorder)&MaxWinMask;
// }
// if (BlockLength<=WriteSizeLeft)
// {
// if (BlockLength>0) // We set it to 0 also for invalid filters.
// {
// uint BlockEnd=(BlockStart+BlockLength)&MaxWinMask;
//
// FilterSrcMemory.Alloc(BlockLength);
// byte *Mem=&FilterSrcMemory[0];
// if (BlockStart<BlockEnd || BlockEnd==0)
// {
// if (Fragmented)
// FragWindow.CopyData(Mem,BlockStart,BlockLength);
// else
// memcpy(Mem,Window+BlockStart,BlockLength);
// }
// else
// {
// size_t FirstPartLength=size_t(MaxWinSize-BlockStart);
// if (Fragmented)
// {
// FragWindow.CopyData(Mem,BlockStart,FirstPartLength);
// FragWindow.CopyData(Mem+FirstPartLength,0,BlockEnd);
// }
// else
// {
// memcpy(Mem,Window+BlockStart,FirstPartLength);
// memcpy(Mem+FirstPartLength,Window,BlockEnd);
// }
// }
//
// byte *OutMem=ApplyFilter(Mem,BlockLength,flt);
//
// Filters[I].Type=FILTER_NONE;
//
// if (OutMem!=NULL)
// UnpIO->UnpWrite(OutMem,BlockLength);
//
// UnpSomeRead=true;
// WrittenFileSize+=BlockLength;
// WrittenBorder=BlockEnd;
// WriteSizeLeft=(UnpPtr-WrittenBorder)&MaxWinMask;
// }
// }
// else
// {
// // Current filter intersects the window write border, so we adjust
// // the window border to process this filter next time, not now.
// WrPtr=WrittenBorder;
//
// // Since Filter start position can only increase, we quit processing
// // all following filters for this data block and reset 'NextWindow'
// // flag for them.
// for (size_t J=I;J<Filters.Size();J++)
// {
// UnpackFilter *flt=&Filters[J];
// if (flt->Type!=FILTER_NONE)
// flt->NextWindow=false;
// }
//
// // Do not write data left after current filter now.
// NotAllFiltersProcessed=true;
// break;
// }
// }
// }
//
// // Remove processed filters from queue.
// size_t EmptyCount=0;
// for (size_t I=0;I<Filters.Size();I++)
// {
// if (EmptyCount>0)
// Filters[I-EmptyCount]=Filters[I];
// if (Filters[I].Type==FILTER_NONE)
// EmptyCount++;
// }
// if (EmptyCount>0)
// Filters.Alloc(Filters.Size()-EmptyCount);
//
// if (!NotAllFiltersProcessed) // Only if all filters are processed.
// {
// // Write data left after last filter.
// UnpWriteArea(WrittenBorder,UnpPtr);
// WrPtr=UnpPtr;
// }
//
// // We prefer to write data in blocks not exceeding UNPACK_MAX_WRITE
// // instead of potentially huge MaxWinSize blocks. It also allows us
// // to keep the size of Filters array reasonable.
// WriteBorder=(UnpPtr+Min(MaxWinSize,UNPACK_MAX_WRITE))&MaxWinMask;
//
// // Choose the nearest among WriteBorder and WrPtr actual written border.
// // If border is equal to UnpPtr, it means that we have MaxWinSize data ahead.
// if (WriteBorder==UnpPtr ||
// WrPtr!=UnpPtr && ((WrPtr-UnpPtr)&MaxWinMask)<((WriteBorder-UnpPtr)&MaxWinMask))
// WriteBorder=WrPtr;
//}
//
//
//byte* ApplyFilter(byte *Data,uint DataSize,UnpackFilter *Flt)
//{
// byte *SrcData=Data;
// switch(Flt->Type)
// {
// case FILTER_E8:
// case FILTER_E8E9:
// {
// uint FileOffset=(uint)WrittenFileSize;
//
// const uint FileSize=0x1000000;
// byte CmpByte2=Flt->Type==FILTER_E8E9 ? 0xe9:0xe8;
// // DataSize is unsigned, so we use "CurPos+4" and not "DataSize-4"
// // to avoid overflow for DataSize<4.
// for (uint CurPos=0;CurPos+4<DataSize;)
// {
// byte CurByte=*(Data++);
// CurPos++;
// if (CurByte==0xe8 || CurByte==CmpByte2)
// {
// uint Offset=(CurPos+FileOffset)%FileSize;
// uint Addr=RawGet4(Data);
//
// // We check 0x80000000 bit instead of '< 0' comparison
// // not assuming int32 presence or uint size and endianness.
// if ((Addr & 0x80000000)!=0) // Addr<0
// {
// if (((Addr+Offset) & 0x80000000)==0) // Addr+Offset>=0
// RawPut4(Addr+FileSize,Data);
// }
// else
// if (((Addr-FileSize) & 0x80000000)!=0) // Addr<FileSize
// RawPut4(Addr-Offset,Data);
//
// Data+=4;
// CurPos+=4;
// }
// }
// }
// return SrcData;
// case FILTER_ARM:
// {
// uint FileOffset=(uint)WrittenFileSize;
// // DataSize is unsigned, so we use "CurPos+3" and not "DataSize-3"
// // to avoid overflow for DataSize<3.
// for (uint CurPos=0;CurPos+3<DataSize;CurPos+=4)
// {
// byte *D=Data+CurPos;
// if (D[3]==0xeb) // BL command with '1110' (Always) condition.
// {
// uint Offset=D[0]+uint(D[1])*0x100+uint(D[2])*0x10000;
// Offset-=(FileOffset+CurPos)/4;
// D[0]=(byte)Offset;
// D[1]=(byte)(Offset>>8);
// D[2]=(byte)(Offset>>16);
// }
// }
// }
// return SrcData;
// case FILTER_DELTA:
// {
// // Unlike RAR3, we do not need to reject excessive channel
// // values here, since RAR5 uses only 5 bits to store channel.
// uint Channels=Flt->Channels,SrcPos=0;
//
// FilterDstMemory.Alloc(DataSize);
// byte *DstData=&FilterDstMemory[0];
//
// // Bytes from same channels are grouped to continual data blocks,
// // so we need to place them back to their interleaving positions.
// for (uint CurChannel=0;CurChannel<Channels;CurChannel++)
// {
// byte PrevByte=0;
// for (uint DestPos=CurChannel;DestPos<DataSize;DestPos+=Channels)
// DstData[DestPos]=(PrevByte-=Data[SrcPos++]);
// }
// return DstData;
// }
//
// }
// return NULL;
//}
//
//
//void UnpWriteArea(size_t StartPtr,size_t EndPtr)
//{
// if (EndPtr!=StartPtr)
// UnpSomeRead=true;
// if (EndPtr<StartPtr)
// UnpAllBuf=true;
//
// if (Fragmented)
// {
// size_t SizeToWrite=(EndPtr-StartPtr) & MaxWinMask;
// while (SizeToWrite>0)
// {
// size_t BlockSize=FragWindow.GetBlockSize(StartPtr,SizeToWrite);
// UnpWriteData(&FragWindow[StartPtr],BlockSize);
// SizeToWrite-=BlockSize;
// StartPtr=(StartPtr+BlockSize) & MaxWinMask;
// }
// }
// else
// if (EndPtr<StartPtr)
// {
// UnpWriteData(Window+StartPtr,MaxWinSize-StartPtr);
// UnpWriteData(Window,EndPtr);
// }
// else
// UnpWriteData(Window+StartPtr,EndPtr-StartPtr);
//}
//
//
//void UnpWriteData(byte *Data,size_t Size)
//{
// if (WrittenFileSize>=DestUnpSize)
// return;
// size_t WriteSize=Size;
// int64 LeftToWrite=DestUnpSize-WrittenFileSize;
// if ((int64)WriteSize>LeftToWrite)
// WriteSize=(size_t)LeftToWrite;
// UnpIO->UnpWrite(Data,WriteSize);
// WrittenFileSize+=Size;
//}
//
//
//void UnpInitData50(bool Solid)
//{
// if (!Solid)
// TablesRead5=false;
//}
//
//
//bool ReadBlockHeader(BitInput &Inp,UnpackBlockHeader &Header)
//{
// Header.HeaderSize=0;
//
// if (!Inp.ExternalBuffer && Inp.InAddr>ReadTop-7)
// if (!UnpReadBuf())
// return false;
// Inp.faddbits((8-Inp.InBit)&7);
//
// byte BlockFlags=Inp.fgetbits()>>8;
// Inp.faddbits(8);
// uint ByteCount=((BlockFlags>>3)&3)+1; // Block size byte count.
//
// if (ByteCount==4)
// return false;
//
// Header.HeaderSize=2+ByteCount;
//
// Header.BlockBitSize=(BlockFlags&7)+1;
//
// byte SavedCheckSum=Inp.fgetbits()>>8;
// Inp.faddbits(8);
//
// int BlockSize=0;
// for (uint I=0;I<ByteCount;I++)
// {
// BlockSize+=(Inp.fgetbits()>>8)<<(I*8);
// Inp.addbits(8);
// }
//
// Header.BlockSize=BlockSize;
// byte CheckSum=byte(0x5a^BlockFlags^BlockSize^(BlockSize>>8)^(BlockSize>>16));
// if (CheckSum!=SavedCheckSum)
// return false;
//
// Header.BlockStart=Inp.InAddr;
// ReadBorder=Min(ReadBorder,Header.BlockStart+Header.BlockSize-1);
//
// Header.LastBlockInFile=(BlockFlags & 0x40)!=0;
// Header.TablePresent=(BlockFlags & 0x80)!=0;
// return true;
//}
//
//
//bool ReadTables(BitInput &Inp,UnpackBlockHeader &Header,UnpackBlockTables &Tables)
//{
// if (!Header.TablePresent)
// return true;
//
// if (!Inp.ExternalBuffer && Inp.InAddr>ReadTop-25)
// if (!UnpReadBuf())
// return false;
//
// byte BitLength[BC];
// for (uint I=0;I<BC;I++)
// {
// uint Length=(byte)(Inp.fgetbits() >> 12);
// Inp.faddbits(4);
// if (Length==15)
// {
// uint ZeroCount=(byte)(Inp.fgetbits() >> 12);
// Inp.faddbits(4);
// if (ZeroCount==0)
// BitLength[I]=15;
// else
// {
// ZeroCount+=2;
// while (ZeroCount-- > 0 && I<ASIZE(BitLength))
// BitLength[I++]=0;
// I--;
// }
// }
// else
// BitLength[I]=Length;
// }
//
// MakeDecodeTables(BitLength,&Tables.BD,BC);
//
// byte Table[HUFF_TABLE_SIZE];
// const uint TableSize=HUFF_TABLE_SIZE;
// for (uint I=0;I<TableSize;)
// {
// if (!Inp.ExternalBuffer && Inp.InAddr>ReadTop-5)
// if (!UnpReadBuf())
// return false;
// uint Number=DecodeNumber(Inp,&Tables.BD);
// if (Number<16)
// {
// Table[I]=Number;
// I++;
// }
// else
// if (Number<18)
// {
// uint N;
// if (Number==16)
// {
// N=(Inp.fgetbits() >> 13)+3;
// Inp.faddbits(3);
// }
// else
// {
// N=(Inp.fgetbits() >> 9)+11;
// Inp.faddbits(7);
// }
// if (I==0)
// {
// // We cannot have "repeat previous" code at the first position.
// // Multiple such codes would shift Inp position without changing I,
// // which can lead to reading beyond of Inp boundary in mutithreading
// // mode, where Inp.ExternalBuffer disables bounds check and we just
// // reserve a lot of buffer space to not need such check normally.
// return false;
// }
// else
// while (N-- > 0 && I<TableSize)
// {
// Table[I]=Table[I-1];
// I++;
// }
// }
// else
// {
// uint N;
// if (Number==18)
// {
// N=(Inp.fgetbits() >> 13)+3;
// Inp.faddbits(3);
// }
// else
// {
// N=(Inp.fgetbits() >> 9)+11;
// Inp.faddbits(7);
// }
// while (N-- > 0 && I<TableSize)
// Table[I++]=0;
// }
// }
// TablesRead5=true;
// if (!Inp.ExternalBuffer && Inp.InAddr>ReadTop)
// return false;
// MakeDecodeTables(&Table[0],&Tables.LD,NC);
// MakeDecodeTables(&Table[NC],&Tables.DD,DC);
// MakeDecodeTables(&Table[NC+DC],&Tables.LDD,LDC);
// MakeDecodeTables(&Table[NC+DC+LDC],&Tables.RD,RC);
// return true;
//}
//
//
//void InitFilters()
//{
// Filters.SoftReset();
//}
//
// }
//}