Alexandria.Engines.DarkSouls.ArchiveRecord.Open C# (CSharp) Method

Open() public method

Open the record, decompressing it as necessary.
public Open ( ) : Stream
return Stream
        public override Stream Open()
        {
            var archive = Archive;
            var reader = archive.DataReader;
            reader.BaseStream.Position = Offset;

            if (fixedUncompressedSize != Size && fixedUncompressedSize != 0) {
                if (Size == fixedUncompressedSize)
                    return new MemoryStream(reader.ReadBytes(checked((int)fixedUncompressedSize)), false);
                else {
                    byte[] data = new byte[fixedUncompressedSize];

                    var deflate = new ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream(reader.BaseStream);
                    var read = deflate.Read(data, 0, data.Length);
                    if (read != fixedUncompressedSize)
                        throw new InvalidDataException();
                    return new MemoryStream(data, false);
                }
            }

            var magic = reader.ReadString(4, Encoding.ASCII);

            if (magic == "DCX\0") {
                reader.Require(0x100);
                reader.RequireBE(0x18);
                reader.RequireBE(0x24);
                reader.RequireBE(0x24);
                int totalHeaderLength = reader.ReadInt32BE();
                reader.RequireMagic("DCS\0");
                int uncompressedSize = reader.ReadInt32BE();
                int compressedSize = reader.ReadInt32BE();
                reader.RequireMagic("DCP\0");

                string compressionMethod = reader.ReadStringz(4, Encoding.ASCII);

                reader.RequireBE(0x20);
                reader.Require(9);
                reader.Require(archive.IsDarkSoulsII ? 0x100 : 0);
                reader.RequireZeroes(8);
                reader.Require(archive.IsDarkSoulsII ? 0x11000 : 0x10100);
                reader.RequireMagic("DCA\0");
                int compressionHeaderLength = reader.ReadInt32BE();

                byte[] data = new byte[uncompressedSize];
                switch (compressionMethod) {
                    case "DFLT":
                        if (true) {
                            var deflate = new ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream(reader.BaseStream);

                            var read = deflate.Read(data, 0, data.Length);
                            if (read != uncompressedSize)
                                throw new Exception();
                            return new MemoryStream(data, false);
                        }

                    case "EDGE":
                        if (true) {
                            reader.RequireMagic("EgdT");
                            reader.RequireBE(0x10100);
                            reader.RequireBE(0x24); // sectionHeaderStart
                            int alignment = reader.ReadInt32BE();
                            if (alignment != 0x10)
                                throw new InvalidDataException();
                            int normalBlockSize = reader.ReadInt32BE();
                            int lastBlockSize = reader.ReadInt32BE();
                            int headerLength = reader.ReadInt32BE();
                            int sectionCount = reader.ReadInt32BE();
                            int sectionEntrySize = reader.ReadInt16BE();
                            if (headerLength != 36 + sectionCount * sectionEntrySize)
                                throw new InvalidDataException();
                            reader.RequireZeroes(2);
                            long blockHeaderStart = reader.BaseStream.Position;
                            long blockDataStart = blockHeaderStart + sectionCount * sectionEntrySize;
                            int offset = 0;

                            for (int index = 0; index < sectionCount; index++) {
                                reader.BaseStream.Position = blockHeaderStart + index * sectionEntrySize;
                                long blockOffset = reader.ReadInt64BE();
                                int blockSize = reader.ReadInt32BE();
                                int blockMode = reader.ReadInt32BE();
                                int uncompressedBlockSize = index < sectionCount - 1 ? normalBlockSize : lastBlockSize;

                                reader.BaseStream.Position = blockDataStart + blockOffset;

                                switch (blockMode) {
                                    case 0:
                                        if (blockSize < uncompressedBlockSize)
                                            throw new InvalidDataException();
                                        reader.Read(data, offset, uncompressedBlockSize);
                                        break;

                                    case 1:
                                        var deflate = new ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream(reader.BaseStream, new ICSharpCode.SharpZipLib.Zip.Compression.Inflater(true));
                                        int deflateRead = deflate.Read(data, offset, uncompressedBlockSize);
                                        if (deflateRead != uncompressedBlockSize)
                                            throw new InvalidDataException();
                                        break;

                                    default:
                                        throw new NotSupportedException("Unsupported block mode " + blockMode);
                                }

                                offset += uncompressedBlockSize;
                            }

                            if (offset != data.Length)
                                throw new InvalidDataException();
                            return new MemoryStream(data, false);
                        }

                    default:
                        throw new NotImplementedException(compressionMethod + " compression is not implemented.");
                }
            } else {
                reader.BaseStream.Seek(-4, SeekOrigin.Current);
                byte[] data = reader.ReadBytes(checked((int)Size));
                return new MemoryStream(data, false);
            }
        }