| 215 | |
| 216 | |
| 217 | bool Unpack::UnpReadBuf() |
| 218 | { |
| 219 | int DataSize=ReadTop-Inp.InAddr; // Data left to process. |
| 220 | if (DataSize<0) |
| 221 | return false; |
| 222 | BlockHeader.BlockSize-=Inp.InAddr-BlockHeader.BlockStart; |
| 223 | if (Inp.InAddr>BitInput::MAX_SIZE/2) |
| 224 | { |
| 225 | // If we already processed more than half of buffer, let's move |
| 226 | // remaining data into beginning to free more space for new data |
| 227 | // and ensure that calling function does not cross the buffer border |
| 228 | // even if we did not read anything here. Also it ensures that read size |
| 229 | // is not less than CRYPT_BLOCK_SIZE, so we can align it without risk |
| 230 | // to make it zero. |
| 231 | if (DataSize>0) |
| 232 | memmove(Inp.InBuf,Inp.InBuf+Inp.InAddr,DataSize); |
| 233 | Inp.InAddr=0; |
| 234 | ReadTop=DataSize; |
| 235 | } |
| 236 | else |
| 237 | DataSize=ReadTop; |
| 238 | int ReadCode=0; |
| 239 | if (BitInput::MAX_SIZE!=DataSize) |
| 240 | ReadCode=UnpIO->UnpRead(Inp.InBuf+DataSize,BitInput::MAX_SIZE-DataSize); |
| 241 | if (ReadCode>0) // Can be also -1. |
| 242 | ReadTop+=ReadCode; |
| 243 | ReadBorder=ReadTop-30; |
| 244 | BlockHeader.BlockStart=Inp.InAddr; |
| 245 | if (BlockHeader.BlockSize!=-1) // '-1' means not defined yet. |
| 246 | { |
| 247 | // We may need to quit from main extraction loop and read new block header |
| 248 | // and trees earlier than data in input buffer ends. |
| 249 | ReadBorder=Min(ReadBorder,BlockHeader.BlockStart+BlockHeader.BlockSize-1); |
| 250 | } |
| 251 | return ReadCode!=-1; |
| 252 | } |
| 253 | |
| 254 | |
| 255 | void Unpack::UnpWriteBuf() |