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);
}
}