unrarsrc  6.1.7
About: unrar extracts, views and tests the contents of archives created with the RAR archiver.
  Fossies Dox: unrarsrc-6.1.7.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

unpack50frag.cpp
Go to the documentation of this file.
2{
3 memset(Mem,0,sizeof(Mem));
4 memset(MemSize,0,sizeof(MemSize));
5}
6
7
9{
10 Reset();
11}
12
13
15{
16 for (uint I=0;I<ASIZE(Mem);I++)
17 if (Mem[I]!=NULL)
18 {
19 free(Mem[I]);
20 Mem[I]=NULL;
21 }
22}
23
24
25void FragmentedWindow::Init(size_t WinSize)
26{
27 Reset();
28
29 uint BlockNum=0;
30 size_t TotalSize=0; // Already allocated.
31 while (TotalSize<WinSize && BlockNum<ASIZE(Mem))
32 {
33 size_t Size=WinSize-TotalSize; // Size needed to allocate.
34
35 // Minimum still acceptable block size. Next allocations cannot be larger
36 // than current, so we do not need blocks if they are smaller than
37 // "size left / attempts left". Also we do not waste time to blocks
38 // smaller than some arbitrary constant.
39 size_t MinSize=Max(Size/(ASIZE(Mem)-BlockNum), 0x400000);
40
41 byte *NewMem=NULL;
42 while (Size>=MinSize)
43 {
44 NewMem=(byte *)malloc(Size);
45 if (NewMem!=NULL)
46 break;
47 Size-=Size/32;
48 }
49 if (NewMem==NULL)
50 throw std::bad_alloc();
51
52 // Clean the window to generate the same output when unpacking corrupt
53 // RAR files, which may access to unused areas of sliding dictionary.
54 memset(NewMem,0,Size);
55
56 Mem[BlockNum]=NewMem;
57 TotalSize+=Size;
58 MemSize[BlockNum]=TotalSize;
59 BlockNum++;
60 }
61 if (TotalSize<WinSize) // Not found enough free blocks.
62 throw std::bad_alloc();
63}
64
65
67{
68 if (Item<MemSize[0])
69 return Mem[0][Item];
70 for (uint I=1;I<ASIZE(MemSize);I++)
71 if (Item<MemSize[I])
72 return Mem[I][Item-MemSize[I-1]];
73 return Mem[0][0]; // Must never happen;
74}
75
76
77void FragmentedWindow::CopyString(uint Length,uint Distance,size_t &UnpPtr,size_t MaxWinMask)
78{
79 size_t SrcPtr=UnpPtr-Distance;
80 while (Length-- > 0)
81 {
82 (*this)[UnpPtr]=(*this)[SrcPtr++ & MaxWinMask];
83 // We need to have masked UnpPtr after quit from loop, so it must not
84 // be replaced with '(*this)[UnpPtr++ & MaxWinMask]'
85 UnpPtr=(UnpPtr+1) & MaxWinMask;
86 }
87}
88
89
90void FragmentedWindow::CopyData(byte *Dest,size_t WinPos,size_t Size)
91{
92 for (size_t I=0;I<Size;I++)
93 Dest[I]=(*this)[WinPos+I];
94}
95
96
97size_t FragmentedWindow::GetBlockSize(size_t StartPos,size_t RequiredSize)
98{
99 for (uint I=0;I<ASIZE(MemSize);I++)
100 if (StartPos<MemSize[I])
101 return Min(MemSize[I]-StartPos,RequiredSize);
102 return 0; // Must never be here.
103}
byte * Mem[MAX_MEM_BLOCKS]
Definition: unpack.hpp:189
byte & operator[](size_t Item)
void CopyString(uint Length, uint Distance, size_t &UnpPtr, size_t MaxWinMask)
size_t GetBlockSize(size_t StartPos, size_t RequiredSize)
size_t MemSize[MAX_MEM_BLOCKS]
Definition: unpack.hpp:190
void Init(size_t WinSize)
void CopyData(byte *Dest, size_t WinPos, size_t Size)
#define Min(x, y)
Definition: rardefs.hpp:4
#define Max(x, y)
Definition: rardefs.hpp:5
#define ASIZE(x)
Definition: rardefs.hpp:10
unsigned int uint
Definition: rartypes.hpp:8