예제 #1
0
        internal long Seek(MPQStream stream, long offset, SeekOrigin origin)
        {
            var  f = (FileHandle)stream.Handle;
            long pos;

            switch (origin)
            {
            case SeekOrigin.Begin:
                pos = offset;
                break;

            case SeekOrigin.End:
                pos = f.Entry.FSize + offset;
                break;

            default: // SeekOrigin.Current
                pos = f.Pos + offset;
                break;
            }
            if (pos < 0)
            {
                pos = 0;
            }
            if (pos > f.Entry.FSize)
            {
                pos = f.Entry.FSize;
            }
            f.Pos = (uint)pos;
            return(pos);
        }
예제 #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;
        }
예제 #3
0
 internal long Seek(MPQStream stream, long offset, SeekOrigin origin)
 {
     var f = (FileHandle)stream.Handle;
     long pos;
     switch (origin) {
     case SeekOrigin.Begin:
         pos = offset;
         break;
     case SeekOrigin.End:
         pos = f.Entry.FSize + offset;
         break;
     default: // SeekOrigin.Current
         pos = f.Pos + offset;
         break;
     }
     if (pos < 0)
         pos = 0;
     if (pos > f.Entry.FSize)
         pos = f.Entry.FSize;
     f.Pos = (uint)pos;
     return pos;
 }
예제 #4
0
 internal long Position(MPQStream stream)
 {
     var f = (FileHandle)stream.Handle;
     return f.Pos;
 }
예제 #5
0
 internal long Length(MPQStream stream)
 {
     var f = (FileHandle)stream.Handle;
     return f.Entry.FSize;
 }
예제 #6
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);
        }
예제 #7
0
        internal long Position(MPQStream stream)
        {
            var f = (FileHandle)stream.Handle;

            return(f.Pos);
        }
예제 #8
0
        internal long Length(MPQStream stream)
        {
            var f = (FileHandle)stream.Handle;

            return(f.Entry.FSize);
        }