Decode Huffman block and save decoded data to memory.
| 287 | |
| 288 | // Decode Huffman block and save decoded data to memory. |
| 289 | void Unpack::UnpackDecode(UnpackThreadData &D) |
| 290 | { |
| 291 | if (!D.TableRead) |
| 292 | { |
| 293 | D.TableRead=true; |
| 294 | if (!ReadTables(D.Inp,D.BlockHeader,D.BlockTables)) |
| 295 | { |
| 296 | D.DamagedData=true; |
| 297 | return; |
| 298 | } |
| 299 | } |
| 300 | |
| 301 | if (D.Inp.InAddr>D.BlockHeader.HeaderSize+D.BlockHeader.BlockSize) |
| 302 | { |
| 303 | D.DamagedData=true; |
| 304 | return; |
| 305 | } |
| 306 | |
| 307 | D.DecodedSize=0; |
| 308 | int BlockBorder=D.BlockHeader.BlockStart+D.BlockHeader.BlockSize-1; |
| 309 | |
| 310 | // Reserve enough space even for filter entry. |
| 311 | int DataBorder=D.DataSize-16; |
| 312 | int ReadBorder=Min(BlockBorder,DataBorder); |
| 313 | |
| 314 | while (true) |
| 315 | { |
| 316 | if (D.Inp.InAddr>=ReadBorder) |
| 317 | { |
| 318 | if (D.Inp.InAddr>BlockBorder || D.Inp.InAddr==BlockBorder && |
| 319 | D.Inp.InBit>=D.BlockHeader.BlockBitSize) |
| 320 | break; |
| 321 | |
| 322 | // If we do not have any more data in file to read, we must process |
| 323 | // what we have until last byte. Otherwise we can return and append |
| 324 | // more data to unprocessed few bytes. |
| 325 | if ((D.Inp.InAddr>=DataBorder) && !D.NoDataLeft || D.Inp.InAddr>=D.DataSize) |
| 326 | { |
| 327 | D.Incomplete=true; |
| 328 | break; |
| 329 | } |
| 330 | } |
| 331 | if (D.DecodedSize>D.DecodedAllocated-8) // Filter can use several slots. |
| 332 | { |
| 333 | D.DecodedAllocated=D.DecodedAllocated*2; |
| 334 | void *Decoded=realloc(D.Decoded,D.DecodedAllocated*sizeof(UnpackDecodedItem)); |
| 335 | if (Decoded==NULL) |
| 336 | ErrHandler.MemoryError(); // D.Decoded will be freed in the destructor. |
| 337 | D.Decoded=(UnpackDecodedItem *)Decoded; |
| 338 | } |
| 339 | |
| 340 | UnpackDecodedItem *CurItem=D.Decoded+D.DecodedSize++; |
| 341 | |
| 342 | uint MainSlot=DecodeNumber(D.Inp,&D.BlockTables.LD); |
| 343 | if (MainSlot<256) |
| 344 | { |
| 345 | if (D.DecodedSize>1) |
| 346 | { |
no test coverage detected