internal int Read(MPQStream stream, byte[] buffer, int offset, int count) { if (offset + count > buffer.Length) throw new ArgumentException(); var f = (FileHandle)stream.Handle; int totalRead = 0; while (count > 0 && f.Pos < f.Entry.FSize) { var blockIndex = f.Pos / BlockSize; var blockPos = f.Pos % BlockSize; if (blockIndex != f.BlockIndex) { var pos = f.Entry.FilePos + f.BlockOffsets[blockIndex]; uint size = f.BlockOffsets[blockIndex + 1] - f.BlockOffsets[blockIndex]; f.Stream.Seek(pos, SeekOrigin.Begin); var len = f.Stream.Read(f.TempBuffer, 0, (int)size); if (len != (int)size) throw new Exception("read error"); if ((f.Entry.Flags & FileEncrypted) != 0) Decrypt(f.TempBuffer, 0, (int)size, f.DecryptionKey + blockIndex, f.CryptBuffer); if (f.Entry.CSize < f.Entry.FSize) { if ((f.Entry.Flags & FileImplode) != 0) { var unzip = new PkUnzipper(); f.BlockSize = unzip.Decompress(f.TempBuffer, 0, (int)size, f.BlockBuffer); } else { throw new Exception("corrupt file"); } } else { Buffer.BlockCopy(f.TempBuffer, 0, f.BlockBuffer, 0, (int)size); f.BlockSize = size; } } int toRead = count; if (blockPos + toRead > f.BlockSize) toRead = (int)(f.BlockSize - blockPos); if (f.Pos + toRead > f.Entry.FSize) toRead = (int)(f.Entry.FSize - f.Pos); Buffer.BlockCopy(f.BlockBuffer, (int)blockPos, buffer, offset, toRead); count -= toRead; offset += toRead; totalRead += toRead; f.Pos += (uint)toRead; } return totalRead; }
internal int Read(MPQStream stream, byte[] buffer, int offset, int count) { if (offset + count > buffer.Length) { throw new ArgumentException(); } var f = (FileHandle)stream.Handle; int totalRead = 0; while (count > 0 && f.Pos < f.Entry.FSize) { var blockIndex = f.Pos / BlockSize; var blockPos = f.Pos % BlockSize; if (blockIndex != f.BlockIndex) { var pos = f.Entry.FilePos + f.BlockOffsets[blockIndex]; uint size = f.BlockOffsets[blockIndex + 1] - f.BlockOffsets[blockIndex]; f.Stream.Seek(pos, SeekOrigin.Begin); var len = f.Stream.Read(f.TempBuffer, 0, (int)size); if (len != (int)size) { throw new Exception("read error"); } if ((f.Entry.Flags & FileEncrypted) != 0) { Decrypt(f.TempBuffer, 0, (int)size, f.DecryptionKey + blockIndex, f.CryptBuffer); } if (f.Entry.CSize < f.Entry.FSize) { if ((f.Entry.Flags & FileImplode) != 0) { var unzip = new PkUnzipper(); f.BlockSize = unzip.Decompress(f.TempBuffer, 0, (int)size, f.BlockBuffer); } else { throw new Exception("corrupt file"); } } else { Buffer.BlockCopy(f.TempBuffer, 0, f.BlockBuffer, 0, (int)size); f.BlockSize = size; } } int toRead = count; if (blockPos + toRead > f.BlockSize) { toRead = (int)(f.BlockSize - blockPos); } if (f.Pos + toRead > f.Entry.FSize) { toRead = (int)(f.Entry.FSize - f.Pos); } Buffer.BlockCopy(f.BlockBuffer, (int)blockPos, buffer, offset, toRead); count -= toRead; offset += toRead; totalRead += toRead; f.Pos += (uint)toRead; } return(totalRead); }