"Fossies" - the Fresh Open Source Software Archive 
Member "unrar/unpackinline.cpp" (4 May 2022, 3789 Bytes) of package /linux/misc/unrarsrc-6.1.7.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "unpackinline.cpp" see the
Fossies "Dox" file reference documentation.
1 _forceinline void Unpack::InsertOldDist(uint Distance)
2 {
3 OldDist[3]=OldDist[2];
4 OldDist[2]=OldDist[1];
5 OldDist[1]=OldDist[0];
6 OldDist[0]=Distance;
7 }
8
9 #ifdef _MSC_VER
10 #define FAST_MEMCPY
11 #endif
12
13 _forceinline void Unpack::CopyString(uint Length,uint Distance)
14 {
15 size_t SrcPtr=UnpPtr-Distance;
16 if (SrcPtr<MaxWinSize-MAX_INC_LZ_MATCH && UnpPtr<MaxWinSize-MAX_INC_LZ_MATCH)
17 {
18 // If we are not close to end of window, we do not need to waste time
19 // to "& MaxWinMask" pointer protection.
20
21 byte *Src=Window+SrcPtr;
22 byte *Dest=Window+UnpPtr;
23 UnpPtr+=Length;
24
25 #ifdef FAST_MEMCPY
26 if (Distance<Length) // Overlapping strings
27 #endif
28 while (Length>=8)
29 {
30 Dest[0]=Src[0];
31 Dest[1]=Src[1];
32 Dest[2]=Src[2];
33 Dest[3]=Src[3];
34 Dest[4]=Src[4];
35 Dest[5]=Src[5];
36 Dest[6]=Src[6];
37 Dest[7]=Src[7];
38
39 Src+=8;
40 Dest+=8;
41 Length-=8;
42 }
43 #ifdef FAST_MEMCPY
44 else
45 while (Length>=8)
46 {
47 // In theory we still could overlap here.
48 // Supposing Distance == MaxWinSize - 1 we have memcpy(Src, Src + 1, 8).
49 // But for real RAR archives Distance <= MaxWinSize - MAX_INC_LZ_MATCH
50 // always, so overlap here is impossible.
51
52 // This memcpy expanded inline by MSVC. We could also use uint64
53 // assignment, which seems to provide about the same speed.
54 memcpy(Dest,Src,8);
55
56 Src+=8;
57 Dest+=8;
58 Length-=8;
59 }
60 #endif
61
62 // Unroll the loop for 0 - 7 bytes left. Note that we use nested "if"s.
63 if (Length>0) { Dest[0]=Src[0];
64 if (Length>1) { Dest[1]=Src[1];
65 if (Length>2) { Dest[2]=Src[2];
66 if (Length>3) { Dest[3]=Src[3];
67 if (Length>4) { Dest[4]=Src[4];
68 if (Length>5) { Dest[5]=Src[5];
69 if (Length>6) { Dest[6]=Src[6]; } } } } } } } // Close all nested "if"s.
70 }
71 else
72 while (Length-- > 0) // Slow copying with all possible precautions.
73 {
74 Window[UnpPtr]=Window[SrcPtr++ & MaxWinMask];
75 // We need to have masked UnpPtr after quit from loop, so it must not
76 // be replaced with 'Window[UnpPtr++ & MaxWinMask]'
77 UnpPtr=(UnpPtr+1) & MaxWinMask;
78 }
79 }
80
81
82 _forceinline uint Unpack::DecodeNumber(BitInput &Inp,DecodeTable *Dec)
83 {
84 // Left aligned 15 bit length raw bit field.
85 uint BitField=Inp.getbits() & 0xfffe;
86
87 if (BitField<Dec->DecodeLen[Dec->QuickBits])
88 {
89 uint Code=BitField>>(16-Dec->QuickBits);
90 Inp.addbits(Dec->QuickLen[Code]);
91 return Dec->QuickNum[Code];
92 }
93
94 // Detect the real bit length for current code.
95 uint Bits=15;
96 for (uint I=Dec->QuickBits+1;I<15;I++)
97 if (BitField<Dec->DecodeLen[I])
98 {
99 Bits=I;
100 break;
101 }
102
103 Inp.addbits(Bits);
104
105 // Calculate the distance from the start code for current bit length.
106 uint Dist=BitField-Dec->DecodeLen[Bits-1];
107
108 // Start codes are left aligned, but we need the normal right aligned
109 // number. So we shift the distance to the right.
110 Dist>>=(16-Bits);
111
112 // Now we can calculate the position in the code list. It is the sum
113 // of first position for current bit length and right aligned distance
114 // between our bit field and start code for current bit length.
115 uint Pos=Dec->DecodePos[Bits]+Dist;
116
117 // Out of bounds safety check required for damaged archives.
118 if (Pos>=Dec->MaxNum)
119 Pos=0;
120
121 // Convert the position in the code list to position in alphabet
122 // and return it.
123 return Dec->DecodeNum[Pos];
124 }
125
126
127 _forceinline uint Unpack::SlotToLength(BitInput &Inp,uint Slot)
128 {
129 uint LBits,Length=2;
130 if (Slot<8)
131 {
132 LBits=0;
133 Length+=Slot;
134 }
135 else
136 {
137 LBits=Slot/4-1;
138 Length+=(4 | (Slot & 3)) << LBits;
139 }
140
141 if (LBits>0)
142 {
143 Length+=Inp.getbits()>>(16-LBits);
144 Inp.addbits(LBits);
145 }
146 return Length;
147 }