123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 |
- #include "rar.hpp"
- #include "coder.cpp"
- #include "suballoc.cpp"
- #include "model.cpp"
- #include "unpackinline.cpp"
- #ifdef RAR_SMP
- #include "unpack50mt.cpp"
- #endif
- #ifndef SFX_MODULE
- #include "unpack15.cpp"
- #include "unpack20.cpp"
- #endif
- #include "unpack30.cpp"
- #include "unpack50.cpp"
- #include "unpack50frag.cpp"
- Unpack::Unpack(ComprDataIO *DataIO)
- :Inp(true),VMCodeInp(true)
- {
- UnpIO=DataIO;
- Window=NULL;
- Fragmented=false;
- Suspended=false;
- UnpAllBuf=false;
- UnpSomeRead=false;
- #ifdef RAR_SMP
- MaxUserThreads=1;
- UnpThreadPool=NULL;
- ReadBufMT=NULL;
- UnpThreadData=NULL;
- #endif
- MaxWinSize=0;
- MaxWinMask=0;
-
-
-
- UnpInitData(false);
- #ifndef SFX_MODULE
-
- UnpInitData15(false);
- InitHuff();
- #endif
- }
- Unpack::~Unpack()
- {
- InitFilters30(false);
- if (Window!=NULL)
- free(Window);
- #ifdef RAR_SMP
- delete UnpThreadPool;
- delete[] ReadBufMT;
- delete[] UnpThreadData;
- #endif
- }
- #ifdef RAR_SMP
- void Unpack::SetThreads(uint Threads)
- {
-
-
- MaxUserThreads=Min(Threads,8);
- UnpThreadPool=new ThreadPool(MaxUserThreads);
- }
- #endif
- void Unpack::Init(size_t WinSize,bool Solid)
- {
-
-
- if (WinSize==0)
- ErrHandler.MemoryError();
-
-
-
-
-
- const size_t MinAllocSize=0x40000;
- if (WinSize<MinAllocSize)
- WinSize=MinAllocSize;
- if (WinSize<=MaxWinSize)
- return;
- if ((WinSize>>16)>0x10000)
- return;
-
-
-
-
-
- bool Grow=Solid && (Window!=NULL || Fragmented);
-
- if (Grow && Fragmented)
- throw std::bad_alloc();
- byte *NewWindow=Fragmented ? NULL : (byte *)malloc(WinSize);
- if (NewWindow==NULL)
- if (Grow || WinSize<0x1000000)
- {
-
-
- throw std::bad_alloc();
- }
- else
- {
- if (Window!=NULL)
- {
- free(Window);
- Window=NULL;
- }
- FragWindow.Init(WinSize);
- Fragmented=true;
- }
- if (!Fragmented)
- {
-
-
- memset(NewWindow,0,WinSize);
-
-
-
-
- if (Grow)
- for (size_t I=1;I<=MaxWinSize;I++)
- NewWindow[(UnpPtr-I)&(WinSize-1)]=Window[(UnpPtr-I)&(MaxWinSize-1)];
- if (Window!=NULL)
- free(Window);
- Window=NewWindow;
- }
- MaxWinSize=WinSize;
- MaxWinMask=MaxWinSize-1;
- }
- void Unpack::DoUnpack(uint Method,bool Solid)
- {
-
-
-
- switch(Method)
- {
- #ifndef SFX_MODULE
- case 15:
- if (!Fragmented)
- Unpack15(Solid);
- break;
- case 20:
- case 26:
- if (!Fragmented)
- Unpack20(Solid);
- break;
- #endif
- case 29:
- if (!Fragmented)
- Unpack29(Solid);
- break;
- case 50:
- #ifdef RAR_SMP
- if (MaxUserThreads>1)
- {
- if (!Fragmented)
- {
- Unpack5MT(Solid);
- break;
- }
- }
- #endif
- Unpack5(Solid);
- break;
- }
- }
- void Unpack::UnpInitData(bool Solid)
- {
- if (!Solid)
- {
- memset(OldDist,0,sizeof(OldDist));
- OldDistPtr=0;
- LastDist=LastLength=0;
- memset(&BlockTables,0,sizeof(BlockTables));
- UnpPtr=WrPtr=0;
- WriteBorder=Min(MaxWinSize,UNPACK_MAX_WRITE)&MaxWinMask;
- }
-
-
- InitFilters();
- Inp.InitBitInput();
- WrittenFileSize=0;
- ReadTop=0;
- ReadBorder=0;
- memset(&BlockHeader,0,sizeof(BlockHeader));
- BlockHeader.BlockSize=-1;
- #ifndef SFX_MODULE
- UnpInitData20(Solid);
- #endif
- UnpInitData30(Solid);
- UnpInitData50(Solid);
- }
- void Unpack::MakeDecodeTables(byte *LengthTable,DecodeTable *Dec,uint Size)
- {
-
- Dec->MaxNum=Size;
-
- uint LengthCount[16];
- memset(LengthCount,0,sizeof(LengthCount));
- for (size_t I=0;I<Size;I++)
- LengthCount[LengthTable[I] & 0xf]++;
-
- LengthCount[0]=0;
-
- memset(Dec->DecodeNum,0,Size*sizeof(*Dec->DecodeNum));
-
- Dec->DecodePos[0]=0;
-
- Dec->DecodeLen[0]=0;
-
- uint UpperLimit=0;
- for (size_t I=1;I<16;I++)
- {
-
- UpperLimit+=LengthCount[I];
-
- uint LeftAligned=UpperLimit<<(16-I);
-
- UpperLimit*=2;
-
- Dec->DecodeLen[I]=(uint)LeftAligned;
-
-
- Dec->DecodePos[I]=Dec->DecodePos[I-1]+LengthCount[I-1];
- }
-
-
- uint CopyDecodePos[ASIZE(Dec->DecodePos)];
- memcpy(CopyDecodePos,Dec->DecodePos,sizeof(CopyDecodePos));
-
-
- for (uint I=0;I<Size;I++)
- {
-
- byte CurBitLength=LengthTable[I] & 0xf;
- if (CurBitLength!=0)
- {
-
- uint LastPos=CopyDecodePos[CurBitLength];
-
-
- Dec->DecodeNum[LastPos]=(ushort)I;
-
-
-
- CopyDecodePos[CurBitLength]++;
- }
- }
-
-
-
-
- switch (Size)
- {
- case NC:
- case NC20:
- case NC30:
- Dec->QuickBits=MAX_QUICK_DECODE_BITS;
- break;
- default:
- Dec->QuickBits=MAX_QUICK_DECODE_BITS-3;
- break;
- }
-
- uint QuickDataSize=1<<Dec->QuickBits;
-
-
-
- uint CurBitLength=1;
-
- for (uint Code=0;Code<QuickDataSize;Code++)
- {
-
- uint BitField=Code<<(16-Dec->QuickBits);
-
-
-
-
- while (CurBitLength<ASIZE(Dec->DecodeLen) && BitField>=Dec->DecodeLen[CurBitLength])
- CurBitLength++;
-
- Dec->QuickLen[Code]=CurBitLength;
-
-
-
- uint Dist=BitField-Dec->DecodeLen[CurBitLength-1];
-
- Dist>>=(16-CurBitLength);
-
-
-
- uint Pos;
- if (CurBitLength<ASIZE(Dec->DecodePos) &&
- (Pos=Dec->DecodePos[CurBitLength]+Dist)<Size)
- {
-
- Dec->QuickNum[Code]=Dec->DecodeNum[Pos];
- }
- else
- {
-
- Dec->QuickNum[Code]=0;
- }
- }
- }
|