Fill RawRead object from buffer.
| 233 | |
| 234 | // Fill RawRead object from buffer. |
| 235 | bool QuickOpen::ReadRaw(RawRead &Raw) |
| 236 | { |
| 237 | if (MaxBufSize-ReadBufPos<0x100) // We are close to end of buffer. |
| 238 | { |
| 239 | // Ensure that we have enough data to read CRC and header size. |
| 240 | size_t DataLeft=ReadBufSize-ReadBufPos; |
| 241 | memcpy(Buf,Buf+ReadBufPos,DataLeft); |
| 242 | ReadBufPos=0; |
| 243 | ReadBufSize=DataLeft; |
| 244 | ReadBuffer(); |
| 245 | } |
| 246 | const size_t FirstReadSize=7; |
| 247 | if (ReadBufPos+FirstReadSize>ReadBufSize) |
| 248 | return false; |
| 249 | Raw.Read(Buf+ReadBufPos,FirstReadSize); |
| 250 | ReadBufPos+=FirstReadSize; |
| 251 | |
| 252 | uint SavedCRC=Raw.Get4(); |
| 253 | uint SizeBytes=Raw.GetVSize(4); |
| 254 | uint64 BlockSize=Raw.GetV(); |
| 255 | int SizeToRead=int(BlockSize); |
| 256 | SizeToRead-=FirstReadSize-SizeBytes-4; // Adjust overread size bytes if any. |
| 257 | if (SizeToRead<0 || SizeBytes==0 || BlockSize==0) |
| 258 | { |
| 259 | Loaded=false; // Invalid data. |
| 260 | return false; |
| 261 | } |
| 262 | |
| 263 | // If rest of block data crosses Buf boundary, read it in loop. |
| 264 | while (SizeToRead>0) |
| 265 | { |
| 266 | size_t DataLeft=ReadBufSize-ReadBufPos; |
| 267 | size_t CurSizeToRead=Min(DataLeft,(size_t)SizeToRead); |
| 268 | Raw.Read(Buf+ReadBufPos,CurSizeToRead); |
| 269 | ReadBufPos+=CurSizeToRead; |
| 270 | SizeToRead-=int(CurSizeToRead); |
| 271 | if (SizeToRead>0) // We read the entire buffer and still need more data. |
| 272 | { |
| 273 | ReadBufPos=0; |
| 274 | ReadBufSize=0; |
| 275 | if (ReadBuffer()==0) |
| 276 | return false; |
| 277 | } |
| 278 | } |
| 279 | |
| 280 | return SavedCRC==Raw.GetCRC50(); |
| 281 | } |
| 282 | |
| 283 | |
| 284 | // Read next cached header. |