"Fossies" - the Fresh Open Source Software Archive 
Member "unrar/rawread.cpp" (4 May 2022, 3943 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 "rawread.cpp" see the
Fossies "Dox" file reference documentation.
1 #include "rar.hpp"
2
3 RawRead::RawRead()
4 {
5 RawRead::SrcFile=NULL;
6 Reset();
7 }
8
9
10 RawRead::RawRead(File *SrcFile)
11 {
12 RawRead::SrcFile=SrcFile;
13 Reset();
14 }
15
16
17 void RawRead::Reset()
18 {
19 Data.SoftReset();
20 ReadPos=0;
21 DataSize=0;
22 Crypt=NULL;
23 }
24
25
26 size_t RawRead::Read(size_t Size)
27 {
28 size_t ReadSize=0;
29 #if !defined(RAR_NOCRYPT)
30 if (Crypt!=NULL)
31 {
32 // Full size of buffer with already read data including data read
33 // for encryption block alignment.
34 size_t FullSize=Data.Size();
35
36 // Data read for alignment and not processed yet.
37 size_t DataLeft=FullSize-DataSize;
38
39 if (Size>DataLeft) // Need to read more than we already have.
40 {
41 size_t SizeToRead=Size-DataLeft;
42 size_t AlignedReadSize=SizeToRead+((~SizeToRead+1) & CRYPT_BLOCK_MASK);
43 Data.Add(AlignedReadSize);
44 ReadSize=SrcFile->Read(&Data[FullSize],AlignedReadSize);
45 Crypt->DecryptBlock(&Data[FullSize],AlignedReadSize);
46 DataSize+=ReadSize==0 ? 0:Size;
47 }
48 else // Use buffered data, no real read.
49 {
50 ReadSize=Size;
51 DataSize+=Size;
52 }
53 }
54 else
55 #endif
56 if (Size!=0)
57 {
58 Data.Add(Size);
59 ReadSize=SrcFile->Read(&Data[DataSize],Size);
60 DataSize+=ReadSize;
61 }
62 return ReadSize;
63 }
64
65
66 void RawRead::Read(byte *SrcData,size_t Size)
67 {
68 if (Size!=0)
69 {
70 Data.Add(Size);
71 memcpy(&Data[DataSize],SrcData,Size);
72 DataSize+=Size;
73 }
74 }
75
76
77 byte RawRead::Get1()
78 {
79 return ReadPos<DataSize ? Data[ReadPos++]:0;
80 }
81
82
83 ushort RawRead::Get2()
84 {
85 if (ReadPos+1<DataSize)
86 {
87 ushort Result=Data[ReadPos]+(Data[ReadPos+1]<<8);
88 ReadPos+=2;
89 return Result;
90 }
91 return 0;
92 }
93
94
95 uint RawRead::Get4()
96 {
97 if (ReadPos+3<DataSize)
98 {
99 uint Result=Data[ReadPos]+(Data[ReadPos+1]<<8)+(Data[ReadPos+2]<<16)+
100 (Data[ReadPos+3]<<24);
101 ReadPos+=4;
102 return Result;
103 }
104 return 0;
105 }
106
107
108 uint64 RawRead::Get8()
109 {
110 uint Low=Get4(),High=Get4();
111 return INT32TO64(High,Low);
112 }
113
114
115 uint64 RawRead::GetV()
116 {
117 uint64 Result=0;
118 // Need to check Shift<64, because for shift greater than or equal to
119 // the width of the promoted left operand, the behavior is undefined.
120 for (uint Shift=0;ReadPos<DataSize && Shift<64;Shift+=7)
121 {
122 byte CurByte=Data[ReadPos++];
123 Result+=uint64(CurByte & 0x7f)<<Shift;
124 if ((CurByte & 0x80)==0)
125 return Result; // Decoded successfully.
126 }
127 return 0; // Out of buffer border.
128 }
129
130
131 // Return a number of bytes in current variable length integer.
132 uint RawRead::GetVSize(size_t Pos)
133 {
134 for (size_t CurPos=Pos;CurPos<DataSize;CurPos++)
135 if ((Data[CurPos] & 0x80)==0)
136 return int(CurPos-Pos+1);
137 return 0; // Buffer overflow.
138 }
139
140
141 size_t RawRead::GetB(void *Field,size_t Size)
142 {
143 byte *F=(byte *)Field;
144 size_t CopySize=Min(DataSize-ReadPos,Size);
145 if (CopySize>0)
146 memcpy(F,&Data[ReadPos],CopySize);
147 if (Size>CopySize)
148 memset(F+CopySize,0,Size-CopySize);
149 ReadPos+=CopySize;
150 return CopySize;
151 }
152
153
154 void RawRead::GetW(wchar *Field,size_t Size)
155 {
156 if (ReadPos+2*Size-1<DataSize)
157 {
158 RawToWide(&Data[ReadPos],Field,Size);
159 ReadPos+=sizeof(wchar)*Size;
160 }
161 else
162 memset(Field,0,sizeof(wchar)*Size);
163 }
164
165
166 uint RawRead::GetCRC15(bool ProcessedOnly) // RAR 1.5 block CRC.
167 {
168 if (DataSize<=2)
169 return 0;
170 uint HeaderCRC=CRC32(0xffffffff,&Data[2],(ProcessedOnly ? ReadPos:DataSize)-2);
171 return ~HeaderCRC & 0xffff;
172 }
173
174
175 uint RawRead::GetCRC50() // RAR 5.0 block CRC.
176 {
177 if (DataSize<=4)
178 return 0xffffffff;
179 return CRC32(0xffffffff,&Data[4],DataSize-4) ^ 0xffffffff;
180 }
181
182
183 // Read vint from arbitrary byte array.
184 uint64 RawGetV(const byte *Data,uint &ReadPos,uint DataSize,bool &Overflow)
185 {
186 Overflow=false;
187 uint64 Result=0;
188 for (uint Shift=0;ReadPos<DataSize;Shift+=7)
189 {
190 byte CurByte=Data[ReadPos++];
191 Result+=uint64(CurByte & 0x7f)<<Shift;
192 if ((CurByte & 0x80)==0)
193 return Result; // Decoded successfully.
194 }
195 Overflow=true;
196 return 0; // Out of buffer border.
197 }