Skip to content

Commit 5095bf0

Browse files
committed
fix: simplify xnb decompress stream
1 parent d39e43b commit 5095bf0

1 file changed

Lines changed: 14 additions & 30 deletions

File tree

Core/XNB/XnbDecompressStream.cs

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,18 @@ internal class XnbDecompressStream : Stream
88
{
99
private readonly Stream _source;
1010
private readonly bool _copyOriginalSource;
11+
private readonly MemoryStream _decompressionBuffer;
1112
private readonly LzxDecoder? _decoder;
1213
private readonly long _sourceEndPosition;
1314
private readonly int _decompressedSize;
14-
private readonly byte[] _decompressedHeaderBytes;
15-
private readonly MemoryStream? _decompressionBuffer;
1615
private long _readPosition;
1716
private long _sourcePosition;
1817
private bool _finished;
1918

2019
public override bool CanRead => true;
2120
public override bool CanSeek => false;
2221
public override bool CanWrite => false;
23-
public override long Length => _copyOriginalSource ? _source.Length : _decompressedHeaderBytes.Length + _decompressedSize;
22+
public override long Length => _copyOriginalSource ? _source.Length : _decompressedSize;
2423
public override long Position
2524
{
2625
get => _copyOriginalSource ? _source.Position : _readPosition;
@@ -30,8 +29,9 @@ public override long Position
3029
public XnbDecompressStream(Stream source)
3130
{
3231
_source = source;
32+
_decompressionBuffer = new MemoryStream();
3333

34-
if (!TryProcessHeader(out _decompressedHeaderBytes, out var compressedSize, out var decompressedSize))
34+
if (!TryProcessHeader(out var compressedSize, out var decompressedSize))
3535
{
3636
_copyOriginalSource = true;
3737
return;
@@ -41,15 +41,13 @@ public XnbDecompressStream(Stream source)
4141
_sourcePosition = source.Position;
4242
_sourceEndPosition = _sourcePosition + compressedSize;
4343
_decompressedSize = decompressedSize;
44-
_decompressionBuffer = new MemoryStream();
4544
}
4645

47-
private bool TryProcessHeader(out byte[] decompressedHeaderBytes, out int compressedSize, out int decompressedSize)
46+
private bool TryProcessHeader(out int compressedSize, out int decompressedSize)
4847
{
4948
var sourcePositionPreHeaderRead = _source.Position;
5049
if (!XnbHeader.TryRead(_source, out var header) || (header.Flags & XnbHeader.XnbFlags.Compressed) == 0)
5150
{
52-
decompressedHeaderBytes = Array.Empty<byte>();
5351
compressedSize = 0;
5452
decompressedSize = 0;
5553
_source.Position = sourcePositionPreHeaderRead;
@@ -58,13 +56,11 @@ private bool TryProcessHeader(out byte[] decompressedHeaderBytes, out int compre
5856

5957
using var reader = new BinaryReader(_source, Encoding.UTF8, true);
6058
compressedSize = reader.ReadInt32();
61-
decompressedSize = reader.ReadInt32();
59+
decompressedSize = reader.ReadInt32() + XnbHeader.Size;
6260

6361
header.Flags &= ~XnbHeader.XnbFlags.Compressed;
64-
using var headerBufferStream = new MemoryStream();
65-
header.Write(headerBufferStream);
66-
new BinaryWriter(headerBufferStream).Write(decompressedSize + XnbHeader.Size);
67-
decompressedHeaderBytes = headerBufferStream.ToArray();
62+
header.Write(_decompressionBuffer);
63+
new BinaryWriter(_decompressionBuffer).Write(decompressedSize);
6864

6965
return true;
7066
}
@@ -78,27 +74,15 @@ public override int Read(byte[] buffer, int offset, int count)
7874

7975
int bytesRead = 0;
8076

81-
if (_readPosition < _decompressedHeaderBytes.Length)
82-
{
83-
var headerBytesToReadCount = (int)Math.Min(_decompressedHeaderBytes.Length - _readPosition, count);
84-
Array.Copy(_decompressedHeaderBytes, (int)_readPosition, buffer, offset, headerBytesToReadCount);
85-
_readPosition += headerBytesToReadCount;
86-
offset += headerBytesToReadCount;
87-
count -= headerBytesToReadCount;
88-
bytesRead += headerBytesToReadCount;
89-
}
90-
91-
long decompressionReadPosition = _readPosition - _decompressedHeaderBytes.Length;
92-
93-
while (_decompressionBuffer!.Length - decompressionReadPosition < count && !_finished)
77+
while (_decompressionBuffer.Length - _readPosition < count && !_finished)
9478
{
9579
DecompressNextBlock();
9680
}
9781

98-
int decompressedBytesToReadCount = (int)Math.Min(count, _decompressionBuffer.Length - decompressionReadPosition);
82+
int decompressedBytesToReadCount = (int)Math.Min(count, _decompressionBuffer.Length - _readPosition);
9983
if (decompressedBytesToReadCount > 0)
10084
{
101-
_decompressionBuffer.Position = decompressionReadPosition;
85+
_decompressionBuffer.Position = _readPosition;
10286
int read = _decompressionBuffer.Read(buffer, offset, decompressedBytesToReadCount);
10387
_readPosition += read;
10488
bytesRead += read;
@@ -139,15 +123,15 @@ private void DecompressNextBlock()
139123
return;
140124
}
141125

142-
_decompressionBuffer!.Position = _decompressionBuffer.Length;
126+
_decompressionBuffer.Position = _decompressionBuffer.Length;
143127
_decoder!.Decompress(_source, blockSize, _decompressionBuffer, frameSize);
144128
_sourcePosition += blockSize;
145129
}
146130

147131
private void MarkFinished()
148132
{
149133
_finished = true;
150-
var finalSize = _decompressionBuffer!.Length;
134+
var finalSize = _decompressionBuffer.Length;
151135
if (finalSize != _decompressedSize)
152136
{
153137
throw new XnbSerializationException(
@@ -160,7 +144,7 @@ protected override void Dispose(bool disposing)
160144
{
161145
if (disposing)
162146
{
163-
_decompressionBuffer?.Dispose();
147+
_decompressionBuffer.Dispose();
164148
}
165149

166150
base.Dispose(disposing);

0 commit comments

Comments
 (0)