Tree @a6d80bbc-ed64-4b90-a9af-a4ea211328ac/main (Download .tar.gz)
- debian
- acknow.txt
- arccmt.cpp
- archive.cpp
- archive.hpp
- arcread.cpp
- array.hpp
- blake2s.cpp
- blake2s.hpp
- blake2s_sse.cpp
- blake2sp.cpp
- cmddata.cpp
- cmddata.hpp
- cmdfilter.cpp
- cmdmix.cpp
- coder.cpp
- coder.hpp
- compress.hpp
- consio.cpp
- consio.hpp
- crc.cpp
- crc.hpp
- crypt.cpp
- crypt.hpp
- crypt1.cpp
- crypt2.cpp
- crypt3.cpp
- crypt5.cpp
- dll.cpp
- dll.def
- dll.hpp
- dll.rc
- dll_nocrypt.def
- encname.cpp
- encname.hpp
- errhnd.cpp
- errhnd.hpp
- extinfo.cpp
- extinfo.hpp
- extract.cpp
- extract.hpp
- filcreat.cpp
- filcreat.hpp
- file.cpp
- file.hpp
- filefn.cpp
- filefn.hpp
- filestr.cpp
- filestr.hpp
- find.cpp
- find.hpp
- getbits.cpp
- getbits.hpp
- global.cpp
- global.hpp
- hardlinks.cpp
- hash.cpp
- hash.hpp
- headers.cpp
- headers.hpp
- headers5.hpp
- isnt.cpp
- isnt.hpp
- license.txt
- list.cpp
- list.hpp
- loclang.hpp
- log.cpp
- log.hpp
- makefile
- match.cpp
- match.hpp
- model.cpp
- model.hpp
- options.cpp
- options.hpp
- os.hpp
- pathfn.cpp
- pathfn.hpp
- qopen.cpp
- qopen.hpp
- rar.cpp
- rar.hpp
- rardefs.hpp
- rarlang.hpp
- raros.hpp
- rarpch.cpp
- rartypes.hpp
- rarvm.cpp
- rarvm.hpp
- rawint.hpp
- rawread.cpp
- rawread.hpp
- rdwrfn.cpp
- rdwrfn.hpp
- readme.txt
- recvol.cpp
- recvol.hpp
- recvol3.cpp
- recvol5.cpp
- resource.cpp
- resource.hpp
- rijndael.cpp
- rijndael.hpp
- rs.cpp
- rs.hpp
- rs16.cpp
- rs16.hpp
- scantree.cpp
- scantree.hpp
- secpassword.cpp
- secpassword.hpp
- sha1.cpp
- sha1.hpp
- sha256.cpp
- sha256.hpp
- smallfn.cpp
- smallfn.hpp
- strfn.cpp
- strfn.hpp
- strlist.cpp
- strlist.hpp
- suballoc.cpp
- suballoc.hpp
- system.cpp
- system.hpp
- threadmisc.cpp
- threadpool.cpp
- threadpool.hpp
- timefn.cpp
- timefn.hpp
- ui.cpp
- ui.hpp
- uicommon.cpp
- uiconsole.cpp
- uisilent.cpp
- ulinks.cpp
- unicode.cpp
- unicode.hpp
- unpack.cpp
- unpack.hpp
- unpack15.cpp
- unpack20.cpp
- unpack30.cpp
- unpack50.cpp
- unpack50frag.cpp
- unpack50mt.cpp
- unpackinline.cpp
- UnRAR.vcxproj
- UnRARDll.vcxproj
- uowners.cpp
- version.hpp
- volume.cpp
- volume.hpp
- win32acl.cpp
- win32lnk.cpp
- win32stm.cpp
unpack50frag.cpp @a6d80bbc-ed64-4b90-a9af-a4ea211328ac/main — raw · history · blame
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | FragmentedWindow::FragmentedWindow() { memset(Mem,0,sizeof(Mem)); memset(MemSize,0,sizeof(MemSize)); } FragmentedWindow::~FragmentedWindow() { Reset(); } void FragmentedWindow::Reset() { for (uint I=0;I<ASIZE(Mem);I++) if (Mem[I]!=NULL) { free(Mem[I]); Mem[I]=NULL; } } void FragmentedWindow::Init(size_t WinSize) { Reset(); uint BlockNum=0; size_t TotalSize=0; // Already allocated. while (TotalSize<WinSize && BlockNum<ASIZE(Mem)) { size_t Size=WinSize-TotalSize; // Size needed to allocate. // Minimum still acceptable block size. Next allocations cannot be larger // than current, so we do not need blocks if they are smaller than // "size left / attempts left". Also we do not waste time to blocks // smaller than some arbitrary constant. size_t MinSize=Max(Size/(ASIZE(Mem)-BlockNum), 0x400000); byte *NewMem=NULL; while (Size>=MinSize) { NewMem=(byte *)malloc(Size); if (NewMem!=NULL) break; Size-=Size/32; } if (NewMem==NULL) throw std::bad_alloc(); // Clean the window to generate the same output when unpacking corrupt // RAR files, which may access to unused areas of sliding dictionary. memset(NewMem,0,Size); Mem[BlockNum]=NewMem; TotalSize+=Size; MemSize[BlockNum]=TotalSize; BlockNum++; } if (TotalSize<WinSize) // Not found enough free blocks. throw std::bad_alloc(); } byte& FragmentedWindow::operator [](size_t Item) { if (Item<MemSize[0]) return Mem[0][Item]; for (uint I=1;I<ASIZE(MemSize);I++) if (Item<MemSize[I]) return Mem[I][Item-MemSize[I-1]]; return Mem[0][0]; // Must never happen; } void FragmentedWindow::CopyString(uint Length,uint Distance,size_t &UnpPtr,size_t MaxWinMask) { size_t SrcPtr=UnpPtr-Distance; while (Length-- > 0) { (*this)[UnpPtr]=(*this)[SrcPtr++ & MaxWinMask]; // We need to have masked UnpPtr after quit from loop, so it must not // be replaced with '(*this)[UnpPtr++ & MaxWinMask]' UnpPtr=(UnpPtr+1) & MaxWinMask; } } void FragmentedWindow::CopyData(byte *Dest,size_t WinPos,size_t Size) { for (size_t I=0;I<Size;I++) Dest[I]=(*this)[WinPos+I]; } size_t FragmentedWindow::GetBlockSize(size_t StartPos,size_t RequiredSize) { for (uint I=0;I<ASIZE(MemSize);I++) if (StartPos<MemSize[I]) return Min(MemSize[I]-StartPos,RequiredSize); return 0; // Must never be here. } |