コード例 #1
0
ファイル: MPQArchive.cs プロジェクト: robinei/primevil
        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;
        }
コード例 #2
0
        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);
        }