예제 #1
0
        public override BinaryReader MakeReader()
        {
            var compressed = new byte[SizeOnDisk];

            this.PackageStream.Seek(OffsetInFile, SeekOrigin.Begin);
            int readSize = this.PackageStream.Read(compressed, 0, (int)SizeOnDisk);

            if (readSize != SizeOnDisk)
            {
                var msg = String.Format("Failed to read {0} bytes from archive (only got {1})", SizeOnDisk, readSize);
                throw new InvalidDataException(msg);
            }

            if (Crc != 0)
            {
                var computedCrc = Crc32.Compute(compressed);
                if (computedCrc != Crc)
                {
                    var msg = String.Format(
                        "CRC check failed on file '{0}', archive is possibly corrupted. Expected {1,8:X}, got {2,8:X}",
                        Name, Crc, computedCrc
                        );
                    throw new InvalidDataException(msg);
                }
            }

            var uncompressed = BinUtils.Decompress(compressed, (int)Size(), (byte)Flags);
            var memStream    = new MemoryStream(uncompressed);
            var reader       = new BinaryReader(memStream);

            return(reader);
        }
예제 #2
0
        private byte[] Decompress(BinaryReader reader, uint compressedSize, uint uncompressedSize, Header header)
        {
            bool chunked = header.Version >= (ulong)FileVersion.VerChunkedCompress;

            byte[] compressed = reader.ReadBytes((int)compressedSize);
            return(BinUtils.Decompress(compressed, (int)uncompressedSize, header.CompressionFlags, chunked));
        }
예제 #3
0
        public override Stream MakeStream()
        {
            if (_uncompressedStream != null)
            {
                return(_uncompressedStream);
            }

            var compressed = new byte[SizeOnDisk];

            PackageStream.Seek(OffsetInFile, SeekOrigin.Begin);
            int readSize = PackageStream.Read(compressed, 0, (int)SizeOnDisk);

            if (readSize != SizeOnDisk)
            {
                string msg = $"Failed to read {SizeOnDisk} bytes from archive (only got {readSize})";
                throw new InvalidDataException(msg);
            }

            if (Crc != 0)
            {
                UInt32 computedCrc = Crc32.Compute(compressed, 0);
                if (computedCrc != Crc)
                {
                    string msg = $"CRC check failed on file '{Name}', archive is possibly corrupted. Expected {Crc,8:X}, got {computedCrc,8:X}";
                    throw new InvalidDataException(msg);
                }
            }

            byte[] uncompressed = BinUtils.Decompress(compressed, (int)Size(), (byte)Flags);
            _uncompressedStream = new MemoryStream(uncompressed);

            return(_uncompressedStream);
        }
예제 #4
0
        public override Stream MakeStream()
        {
            if (_uncompressedStream != null)
            {
                return(_uncompressedStream);
            }

            if ((CompressionMethod)(Flags & 0x0F) == CompressionMethod.None)
            {
                // Use direct stream read for non-compressed files
                _uncompressedStream = new UncompressedPackagedFileStream(PackageStream, this);
                return(_uncompressedStream);
            }

            if (SizeOnDisk > 0x7fffffff)
            {
                throw new InvalidDataException($"File '{Name}' is over 2GB ({SizeOnDisk} bytes), which is not supported yet!");
            }

            var compressed = new byte[SizeOnDisk];

            PackageStream.Seek((long)OffsetInFile, SeekOrigin.Begin);
            int readSize = PackageStream.Read(compressed, 0, (int)SizeOnDisk);

            if (readSize != (long)SizeOnDisk)
            {
                string msg = $"Failed to read {SizeOnDisk} bytes from archive (only got {readSize})";
                throw new InvalidDataException(msg);
            }

            if (Crc != 0)
            {
                UInt32 computedCrc = Crc32.Compute(compressed, 0);
                if (computedCrc != Crc)
                {
                    string msg = $"CRC check failed on file '{Name}', archive is possibly corrupted. Expected {Crc,8:X}, got {computedCrc,8:X}";
                    throw new InvalidDataException(msg);
                }
            }

            if (Solid)
            {
                SolidStream.Seek(SolidOffset, SeekOrigin.Begin);
                byte[] uncompressed = new byte[UncompressedSize];
                SolidStream.Read(uncompressed, 0, (int)UncompressedSize);
                _uncompressedStream = new MemoryStream(uncompressed);
            }
            else
            {
                byte[] uncompressed = BinUtils.Decompress(compressed, (int)Size(), (byte)Flags);
                _uncompressedStream = new MemoryStream(uncompressed);
            }

            return(_uncompressedStream);
        }
예제 #5
0
        public Resource Read()
        {
            using (var reader = new BinaryReader(Stream))
            {
                var hdr = BinUtils.ReadStruct <Header>(reader);
                if (hdr.Magic != BitConverter.ToUInt32(Header.Signature, 0))
                {
                    var msg = String.Format(
                        "Invalid LSF signature; expected {0,8:X}, got {1,8:X}",
                        BitConverter.ToUInt32(Header.Signature, 0), hdr.Magic
                        );
                    throw new InvalidDataException(msg);
                }

                if (hdr.Version < (ulong)FileVersion.VerInitial || hdr.Version > (ulong)FileVersion.CurrentVersion)
                {
                    var msg = String.Format("LSF version {0} is not supported", hdr.Version);
                    throw new InvalidDataException(msg);
                }

                bool isCompressed = BinUtils.CompressionFlagsToMethod(hdr.CompressionFlags) != CompressionMethod.None;
                if (hdr.StringsSizeOnDisk > 0 || hdr.StringsUncompressedSize > 0)
                {
                    uint   onDiskSize = isCompressed ? hdr.StringsSizeOnDisk : hdr.StringsUncompressedSize;
                    byte[] compressed = reader.ReadBytes((int)onDiskSize);
                    byte[] uncompressed;
                    if (isCompressed)
                    {
                        uncompressed = BinUtils.Decompress(compressed, (int)hdr.StringsUncompressedSize, hdr.CompressionFlags);
                    }
                    else
                    {
                        uncompressed = compressed;
                    }

#if DUMP_LSF_SERIALIZATION
                    using (var nodesFile = new FileStream("names.bin", FileMode.Create, FileAccess.Write))
                    {
                        nodesFile.Write(uncompressed, 0, uncompressed.Length);
                    }
#endif

                    using (var namesStream = new MemoryStream(uncompressed))
                    {
                        ReadNames(namesStream);
                    }
                }

                if (hdr.NodesSizeOnDisk > 0 || hdr.NodesUncompressedSize > 0)
                {
                    uint onDiskSize   = isCompressed ? hdr.NodesSizeOnDisk : hdr.NodesUncompressedSize;
                    var  uncompressed = Decompress(reader, onDiskSize, hdr.NodesUncompressedSize, hdr);

#if DUMP_LSF_SERIALIZATION
                    using (var nodesFile = new FileStream("nodes.bin", FileMode.Create, FileAccess.Write))
                    {
                        nodesFile.Write(uncompressed, 0, uncompressed.Length);
                    }
#endif

                    using (var nodesStream = new MemoryStream(uncompressed))
                    {
                        var longNodes = hdr.Version >= (ulong)FileVersion.VerExtendedNodes &&
                                        hdr.Extended == 1;
                        ReadNodes(nodesStream, longNodes);
                    }
                }

                if (hdr.AttributesSizeOnDisk > 0 || hdr.AttributesUncompressedSize > 0)
                {
                    uint onDiskSize   = isCompressed ? hdr.AttributesSizeOnDisk : hdr.AttributesUncompressedSize;
                    var  uncompressed = Decompress(reader, onDiskSize, hdr.AttributesUncompressedSize, hdr);

#if DUMP_LSF_SERIALIZATION
                    using (var attributesFile = new FileStream("attributes.bin", FileMode.Create, FileAccess.Write))
                    {
                        attributesFile.Write(uncompressed, 0, uncompressed.Length);
                    }
#endif

                    using (var attributesStream = new MemoryStream(uncompressed))
                    {
                        var longAttributes = hdr.Version >= (ulong)FileVersion.VerExtendedNodes &&
                                             hdr.Extended == 1;
                        if (longAttributes)
                        {
                            ReadAttributesV3(attributesStream);
                        }
                        else
                        {
                            ReadAttributesV2(attributesStream);
                        }
                    }
                }

                if (hdr.ValuesSizeOnDisk > 0 || hdr.ValuesUncompressedSize > 0)
                {
                    uint onDiskSize   = isCompressed ? hdr.ValuesSizeOnDisk : hdr.ValuesUncompressedSize;
                    var  uncompressed = Decompress(reader, onDiskSize, hdr.ValuesUncompressedSize, hdr);
                    var  valueStream  = new MemoryStream(uncompressed);
                    this.Values = valueStream;

#if DUMP_LSF_SERIALIZATION
                    using (var valuesFile = new FileStream("values.bin", FileMode.Create, FileAccess.Write))
                    {
                        valuesFile.Write(uncompressed, 0, uncompressed.Length);
                    }
#endif
                }
                else
                {
                    this.Values = new MemoryStream();
                }

                Resource resource = new Resource();
                ReadRegions(resource);

                resource.Metadata.majorVersion = (hdr.EngineVersion & 0xff000000) >> 24;
                resource.Metadata.minorVersion = (hdr.EngineVersion & 0xff0000) >> 16;
                resource.Metadata.revision     = (hdr.EngineVersion & 0xff00) >> 8;
                resource.Metadata.buildNumber  = (hdr.EngineVersion & 0xff);

                return(resource);
            }
        }