Esempio n. 1
0
        public void Deserialize(Stream input)
        {
            var magic = input.ReadValueU32(Endian.Little);
            if (magic != 0x53464152 && // SFAR
                magic.Swap() != 0x53464152)
            {
                throw new FormatException();
            }
            var endian = magic == 0x53464152 ? Endian.Little : Endian.Big;

            var version = input.ReadValueU32(endian);
            if (version != 0x00010000)
            {
                throw new FormatException();
            }

            var dataOffset = input.ReadValueU32(endian);
            var fileTableOffset = input.ReadValueU32(endian);
            var fileTableCount = input.ReadValueU32(endian);
            var blockSizeTableOffset = input.ReadValueU32(endian);
            this.MaximumBlockSize = input.ReadValueU32(endian);
            this.CompressionScheme = input
                .ReadValueEnum<SFXArchive.CompressionScheme>(endian);

            if (fileTableOffset != 0x20)
            {
                throw new FormatException();
            }

            if (this.MaximumBlockSize != 0x010000)
            {
                throw new FormatException();
            }

            /*
            if (this.CompressionScheme != SFXArchive.CompressionScheme.None &&
                this.CompressionScheme != SFXArchive.CompressionScheme.LZMA &&
                this.CompressionScheme != SFXArchive.CompressionScheme.LZX)
            {
                throw new FormatException();
            }
            */

            input.Seek(blockSizeTableOffset, SeekOrigin.Begin);

            var blockSizeTableSize = dataOffset - fileTableOffset;
            var blockSizeTableCount = blockSizeTableSize / 2;
            this.BlockSizes.Clear();
            for (uint i = 0; i < blockSizeTableCount; i++)
            {
                this.BlockSizes.Add(input.ReadValueU16(endian));
            }

            input.Seek(fileTableOffset, SeekOrigin.Begin);
            for (uint i = 0; i < fileTableCount; i++)
            {
// ReSharper disable UseObjectOrCollectionInitializer
                var entry = new SFXArchive.Entry();
// ReSharper restore UseObjectOrCollectionInitializer
                entry.NameHash = input.ReadFileNameHash();
                entry.BlockSizeIndex = input.ReadValueS32(endian);
                entry.UncompressedSize = input.ReadValueU32(endian);
                entry.UncompressedSize |= ((long)input.ReadValueU8()) << 32;
                entry.Offset = input.ReadValueU32(endian);
                entry.Offset |= ((long)input.ReadValueU8()) << 32;
                this.Entries.Add(entry);
            }
        }
Esempio n. 2
0
        public void Deserialize(Stream input)
        {
            var magic = input.ReadValueU32(Endian.Little);

            if (magic != 0x53464152 && // SFAR
                magic.Swap() != 0x53464152)
            {
                throw new FormatException();
            }
            var endian = magic == 0x53464152 ? Endian.Little : Endian.Big;

            var version = input.ReadValueU32(endian);

            if (version != 0x00010000)
            {
                throw new FormatException();
            }

            var  dataOffset      = input.ReadValueU32(endian);
            bool firstDataOffset = true;
            uint minDataOffset   = dataOffset;
            //Console.WriteLine("Data Offset: {0:X8}",dataOffset);
            var fileTableOffset = input.ReadValueU32(endian);
            //Console.WriteLine("File Table Offset: {0:X8}",fileTableOffset);
            var fileTableCount = input.ReadValueU32(endian);
            //Console.WriteLine("File Table Count: {0:X8}",fileTableCount);
            var blockSizeTableOffset = input.ReadValueU32(endian);

            //Console.WriteLine("Block Size Table Offset: {0:X8}",blockSizeTableOffset);
            this.MaximumBlockSize  = input.ReadValueU32(endian);
            this.CompressionScheme = input
                                     .ReadValueEnum <SFXArchive.CompressionScheme>(endian);

            if (fileTableOffset != 0x20)
            {
                throw new FormatException();
            }

            if (this.MaximumBlockSize != 0x010000)
            {
                throw new FormatException();
            }

            /*
             * if (this.CompressionScheme != SFXArchive.CompressionScheme.None &&
             *  this.CompressionScheme != SFXArchive.CompressionScheme.LZMA &&
             *  this.CompressionScheme != SFXArchive.CompressionScheme.LZX)
             * {
             *  throw new FormatException();
             * }
             */
            input.Seek(fileTableOffset, SeekOrigin.Begin);
            for (uint i = 0; i < fileTableCount; i++)
            {
// ReSharper disable UseObjectOrCollectionInitializer
                var entry = new SFXArchive.Entry();
                entry.entryOffset = input.Position;
// ReSharper restore UseObjectOrCollectionInitializer
                entry.nameHash = input.ReadFileNameHash();
                //Console.WriteLine("FileNameHash: {0}",entry.NameHash.ToString());
                entry.blockSizeIndex = input.ReadValueS32(endian);
                //Console.WriteLine("Begin position: {0:X8}",input.Position);
                entry.uncompressedSize  = input.ReadValueU32(endian);
                entry.uncompressedSize |= ((long)input.ReadValueU8()) << 32;
                //Console.WriteLine("  End position: {0:X8}",input.Position);
                entry.dataOffset  = input.ReadValueU32(endian);
                entry.dataOffset |= ((long)input.ReadValueU8()) << 32;
                if (firstDataOffset)
                {
                    minDataOffset   = (uint)entry.dataOffset;
                    firstDataOffset = false;
                }
                else
                {
                    if (minDataOffset > entry.dataOffset)
                    {
                        minDataOffset = (uint)entry.dataOffset;
                    }
                }
                //if(entry.NameHash.Equals (fileNameListNameHash))Console.WriteLine("Offset: {0:X10}, UncSize {1:X10}",entry.Offset,entry.UncompressedSize);
                this.Entries.Add(entry);
            }
            if (minDataOffset > dataOffset)
            {
                dataOffset = minDataOffset;
            }

            input.Seek(blockSizeTableOffset, SeekOrigin.Begin);

            var blockSizeTableSize  = dataOffset - blockSizeTableOffset;
            var blockSizeTableCount = blockSizeTableSize / 2;

            //ushort aux;
            //Console.WriteLine("dataOffset: {0:X8}\nfileTableOffset: {1:X8}\nBlockSizeTableSize: {2:X8}\nblockSizeTableOffset: {3:X8}", dataOffset,fileTableOffset,blockSizeTableSize,blockSizeTableOffset);
            this.BlockSizes.Clear();
            //Console.WriteLine("initial position: {0:X8}",input.Position);
            //Console.WriteLine("blockSizeTableCount: {0}",blockSizeTableCount);
            for (uint i = 0; i < blockSizeTableCount; i++)
            {
                this.BlockSizes.Add(input.ReadValueU16(endian));
            }
            //Console.WriteLine("final position: {0:X8}",input.Position);
            //Console.WriteLine("number of repetitions: {0}",blockSizeTableCount);
            //var fileNameListNameHash = new FileNameHash(
            //        new byte[] { 0xB5, 0x50, 0x19, 0xCB, 0xF9, 0xD3, 0xDA, 0x65, 0xD5, 0x5B, 0x32, 0x1C, 0x00, 0x19, 0x69, 0x7C, });
        }
Esempio n. 3
0
        private void getStructure(Stream input)
        {
            var magic = input.ReadValueU32(Endian.Little);

            if (magic != sfarHeader && // SFAR
                magic.Swap() != sfarHeader)
            {
                throw new FormatException("Not a valid sfar file.");
            }
            var endian = magic == sfarHeader ? Endian.Little : Endian.Big;

            var version = input.ReadValueU32(endian);

            if (version != 0x00010000)
            {
                throw new FormatException("Not supported version.");
            }

            dataOffset = input.ReadValueU32(endian);
            uint minDataOffset = dataOffset;

            entryOffset = input.ReadValueU32(endian);
            var fileTableCount = numOfFiles = input.ReadValueU32(endian);

            blockTableOffset       = input.ReadValueU32(endian);
            MaximumBlockSize       = input.ReadValueU32(endian);
            this.CompressionScheme = input.ReadValueEnum <CompressionScheme>(endian);

            if (entryOffset != 0x20)
            {
                throw new FormatException();
            }

            if (MaximumBlockSize != 0x010000)
            {
                throw new FormatException();
            }

            if (this.CompressionScheme != CompressionScheme.None &&
                this.CompressionScheme != CompressionScheme.Lzma &&
                this.CompressionScheme != CompressionScheme.Lzx)
            {
                throw new FormatException();
            }

            input.Seek(entryOffset, SeekOrigin.Begin);
            for (uint i = 0; i < fileTableCount; i++)
            {
                sfarFile entry = new sfarFile();
                entry.entryOffset       = input.Position;
                entry.nameHash          = input.ReadFileNameHash();
                entry.blockSizeIndex    = input.ReadValueS32(endian);
                entry.uncompressedSize  = input.ReadValueU32(endian);
                entry.uncompressedSize |= ((long)input.ReadValueU8()) << 32;
                totalUncSize           += entry.uncompressedSize;

                if (entry.blockSizeIndex == -1)
                {
                    entry.dataOffset     = new long[1];
                    entry.dataOffset[0]  = input.ReadValueU32(endian);
                    entry.dataOffset[0] |= ((long)input.ReadValueU8()) << 32;
                    totalComprSize      += entry.uncompressedSize;
                }
                else
                {
                    int numBlocks = (int)Math.Ceiling(entry.uncompressedSize / (double)MaximumBlockSize);
                    entry.dataOffset     = new long[numBlocks];
                    entry.blockSizeArray = new ushort[numBlocks];
                    entry.dataOffset[0]  = input.ReadValueU32(endian);
                    entry.dataOffset[0] |= ((long)input.ReadValueU8()) << 32;

                    long lastPosition = input.Position;
                    input.Seek(getBlockOffset(entry.blockSizeIndex, entryOffset, fileTableCount), 0);
                    entry.blockSizeArray[0] = input.ReadValueU16();

                    for (int j = 1; j < numBlocks; j++)
                    {
                        entry.blockSizeArray[j] = input.ReadValueU16();
                        entry.dataOffset[j]     = entry.dataOffset[j - 1] + entry.blockSizeArray[j];
                        totalComprSize         += entry.blockSizeArray[j];
                    }
                    input.Seek(lastPosition, 0);
                }
                fileList.Add(entry);
            }// end of foreach
        }
Esempio n. 4
0
        public void Deserialize(Stream input)
        {
            var magic = input.ReadValueU32(Endian.Little);
            if (magic != 0x53464152 && // SFAR
                magic.Swap() != 0x53464152)
            {
                throw new FormatException();
            }
            var endian = magic == 0x53464152 ? Endian.Little : Endian.Big;

            var version = input.ReadValueU32(endian);
            if (version != 0x00010000)
            {
                throw new FormatException();
            }

            var dataOffset = input.ReadValueU32(endian);
            bool firstDataOffset = true;
            uint minDataOffset = dataOffset;
            //Console.WriteLine("Data Offset: {0:X8}",dataOffset);
            var fileTableOffset = input.ReadValueU32(endian);
            //Console.WriteLine("File Table Offset: {0:X8}",fileTableOffset);
            var fileTableCount = input.ReadValueU32(endian);
            //Console.WriteLine("File Table Count: {0:X8}",fileTableCount);
            var blockSizeTableOffset = input.ReadValueU32(endian);
            //Console.WriteLine("Block Size Table Offset: {0:X8}",blockSizeTableOffset);
            this.MaximumBlockSize = input.ReadValueU32(endian);
            this.CompressionScheme = input
                .ReadValueEnum<SFXArchive.CompressionScheme>(endian);

            if (fileTableOffset != 0x20)
            {
                throw new FormatException();
            }

            if (this.MaximumBlockSize != 0x010000)
            {
                throw new FormatException();
            }

            /*
            if (this.CompressionScheme != SFXArchive.CompressionScheme.None &&
                this.CompressionScheme != SFXArchive.CompressionScheme.LZMA &&
                this.CompressionScheme != SFXArchive.CompressionScheme.LZX)
            {
                throw new FormatException();
            }
            */
            input.Seek(fileTableOffset, SeekOrigin.Begin);
            for (uint i = 0; i < fileTableCount; i++)
            {
            // ReSharper disable UseObjectOrCollectionInitializer
                var entry = new SFXArchive.Entry();
                entry.entryOffset = input.Position;
            // ReSharper restore UseObjectOrCollectionInitializer
                entry.nameHash = input.ReadFileNameHash();
                //Console.WriteLine("FileNameHash: {0}",entry.NameHash.ToString());
                entry.blockSizeIndex = input.ReadValueS32(endian);
                //Console.WriteLine("Begin position: {0:X8}",input.Position);
                entry.uncompressedSize = input.ReadValueU32(endian);
                entry.uncompressedSize |= ((long)input.ReadValueU8()) << 32;
                //Console.WriteLine("  End position: {0:X8}",input.Position);
                entry.dataOffset = input.ReadValueU32(endian);
                entry.dataOffset |= ((long)input.ReadValueU8()) << 32;
                if(firstDataOffset)
                {
                    minDataOffset = (uint)entry.dataOffset;
                    firstDataOffset = false;
                }
                else
                {
                    if(minDataOffset > entry.dataOffset)
                        minDataOffset = (uint)entry.dataOffset;
                }
                //if(entry.NameHash.Equals (fileNameListNameHash))Console.WriteLine("Offset: {0:X10}, UncSize {1:X10}",entry.Offset,entry.UncompressedSize);
                this.Entries.Add(entry);
            }
            if(minDataOffset > dataOffset)
                dataOffset = minDataOffset;

            input.Seek(blockSizeTableOffset, SeekOrigin.Begin);

            var blockSizeTableSize = dataOffset - blockSizeTableOffset;
            var blockSizeTableCount = blockSizeTableSize / 2;
            //ushort aux;
            //Console.WriteLine("dataOffset: {0:X8}\nfileTableOffset: {1:X8}\nBlockSizeTableSize: {2:X8}\nblockSizeTableOffset: {3:X8}", dataOffset,fileTableOffset,blockSizeTableSize,blockSizeTableOffset);
            this.BlockSizes.Clear();
            //Console.WriteLine("initial position: {0:X8}",input.Position);
            //Console.WriteLine("blockSizeTableCount: {0}",blockSizeTableCount);
            for (uint i = 0; i < blockSizeTableCount; i++)
            {
                this.BlockSizes.Add(input.ReadValueU16(endian));
            }
            //Console.WriteLine("final position: {0:X8}",input.Position);
            //Console.WriteLine("number of repetitions: {0}",blockSizeTableCount);
            //var fileNameListNameHash = new FileNameHash(
            //        new byte[] { 0xB5, 0x50, 0x19, 0xCB, 0xF9, 0xD3, 0xDA, 0x65, 0xD5, 0x5B, 0x32, 0x1C, 0x00, 0x19, 0x69, 0x7C, });
        }
        public void Deserialize(Stream input)
        {
            var magic = input.ReadValueU32(Endian.Little);

            if (magic != 0x53464152 && // SFAR
                magic.Swap() != 0x53464152)
            {
                throw new FormatException();
            }
            var endian = magic == 0x53464152 ? Endian.Little : Endian.Big;

            var version = input.ReadValueU32(endian);

            if (version != 0x00010000)
            {
                throw new FormatException();
            }

            var dataOffset           = input.ReadValueU32(endian);
            var fileTableOffset      = input.ReadValueU32(endian);
            var fileTableCount       = input.ReadValueU32(endian);
            var blockSizeTableOffset = input.ReadValueU32(endian);

            this.MaximumBlockSize  = input.ReadValueU32(endian);
            this.CompressionScheme = input
                                     .ReadValueEnum <SFXArchive.CompressionScheme>(endian);

            if (fileTableOffset != 0x20)
            {
                throw new FormatException();
            }

            if (this.MaximumBlockSize != 0x010000)
            {
                throw new FormatException();
            }

            /*
             * if (this.CompressionScheme != SFXArchive.CompressionScheme.None &&
             *  this.CompressionScheme != SFXArchive.CompressionScheme.LZMA &&
             *  this.CompressionScheme != SFXArchive.CompressionScheme.LZX)
             * {
             *  throw new FormatException();
             * }
             */

            input.Seek(blockSizeTableOffset, SeekOrigin.Begin);

            var blockSizeTableSize  = dataOffset - fileTableOffset;
            var blockSizeTableCount = blockSizeTableSize / 2;

            this.BlockSizes.Clear();
            for (uint i = 0; i < blockSizeTableCount; i++)
            {
                this.BlockSizes.Add(input.ReadValueU16(endian));
            }

            input.Seek(fileTableOffset, SeekOrigin.Begin);
            for (uint i = 0; i < fileTableCount; i++)
            {
// ReSharper disable UseObjectOrCollectionInitializer
                var entry = new SFXArchive.Entry();
// ReSharper restore UseObjectOrCollectionInitializer
                entry.NameHash          = input.ReadFileNameHash();
                entry.BlockSizeIndex    = input.ReadValueS32(endian);
                entry.UncompressedSize  = input.ReadValueU32(endian);
                entry.UncompressedSize |= ((long)input.ReadValueU8()) << 32;
                entry.Offset            = input.ReadValueU32(endian);
                entry.Offset           |= ((long)input.ReadValueU8()) << 32;
                this.Entries.Add(entry);
            }
        }