private void Parse(MD5Hash md5)
{
int size = (int)_reader.BaseStream.Length;
if (size < 8)
throw new BLTEDecoderException("not enough data: {0}", 8);
int magic = _reader.ReadInt32();
if (magic != BLTE_MAGIC)
throw new BLTEDecoderException("frame header mismatch (bad BLTE file)");
int headerSize = _reader.ReadInt32BE();
if (CASCConfig.ValidateData)
{
long oldPos = _reader.BaseStream.Position;
_reader.BaseStream.Position = 0;
byte[] newHash = _md5.ComputeHash(_reader.ReadBytes(headerSize > 0 ? headerSize : size));
if (!md5.EqualsTo(newHash))
throw new BLTEDecoderException("data corrupted");
_reader.BaseStream.Position = oldPos;
}
int numBlocks = 1;
if (headerSize > 0)
{
if (size < 12)
throw new BLTEDecoderException("not enough data: {0}", 12);
byte[] fcbytes = _reader.ReadBytes(4);
numBlocks = fcbytes[1] << 16 | fcbytes[2] << 8 | fcbytes[3] << 0;
if (fcbytes[0] != 0x0F || numBlocks == 0)
throw new BLTEDecoderException("bad table format 0x{0:x2}, numBlocks {1}", fcbytes[0], numBlocks);
int frameHeaderSize = 24 * numBlocks + 12;
if (headerSize != frameHeaderSize)
throw new BLTEDecoderException("header size mismatch");
if (size < frameHeaderSize)
throw new BLTEDecoderException("not enough data: {0}", frameHeaderSize);
}
_dataBlocks = new DataBlock[numBlocks];
for (int i = 0; i < numBlocks; i++)
{
DataBlock block = new DataBlock();
if (headerSize != 0)
{
block.CompSize = _reader.ReadInt32BE();
block.DecompSize = _reader.ReadInt32BE();
block.Hash = _reader.Read<MD5Hash>();
}
else
{
block.CompSize = size - 8;
block.DecompSize = size - 8 - 1;
block.Hash = default(MD5Hash);
}
_dataBlocks[i] = block;
}
_memStream = new MemoryStream(_dataBlocks.Sum(b => b.DecompSize));
ProcessNextBlock();
_length = headerSize == 0 ? _memStream.Length : _memStream.Capacity;
//for (int i = 0; i < _dataBlocks.Length; i++)
//{
// ProcessNextBlock();
//}
}