Skip to content

Commit

Permalink
Resize decompression buffer as needed (DNET-944, DNET-948). (#104)
Browse files Browse the repository at this point in the history
  • Loading branch information
cincuranet committed Aug 19, 2020
1 parent bab2829 commit c1d674c
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 20 deletions.
Expand Up @@ -30,7 +30,6 @@ class FirebirdNetworkStream : Stream, ITracksIOFailure
public const string EncryptionName = "Arc4";

const int PreferredBufferSize = 32 * 1024;
const int CompressionBufferSize = 1 * 1024 * 1024;

readonly NetworkStream _networkStream;

Expand Down Expand Up @@ -160,7 +159,7 @@ public override void Flush()

public void StartCompression(Ionic.Zlib.ZlibCodec compressor, Ionic.Zlib.ZlibCodec decompressor)
{
_compressionBuffer = new byte[CompressionBufferSize];
_compressionBuffer = new byte[PreferredBufferSize];
_compressor = compressor;
_decompressor = decompressor;
}
Expand Down Expand Up @@ -197,36 +196,69 @@ void WriteToInputBuffer(byte[] data, int count)

int HandleDecompression(byte[] buffer, int count)
{
_decompressor.OutputBuffer = _compressionBuffer;
_decompressor.AvailableBytesOut = _compressionBuffer.Length;
_decompressor.NextOut = 0;
_decompressor.InputBuffer = buffer;
_decompressor.AvailableBytesIn = count;
_decompressor.NextOut = 0;
_decompressor.NextIn = 0;
var rc = _decompressor.Inflate(Ionic.Zlib.FlushType.None);
if (rc != Ionic.Zlib.ZlibConstants.Z_OK)
throw new IOException($"Error '{rc}' while decompressing the data.");
if (_decompressor.AvailableBytesIn != 0)
throw new IOException("Decompression buffer too small.");
_decompressor.AvailableBytesIn = count;
while (true)
{
_decompressor.OutputBuffer = _compressionBuffer;
_decompressor.AvailableBytesOut = _compressionBuffer.Length - _decompressor.NextOut;
var rc = _decompressor.Inflate(Ionic.Zlib.FlushType.None);
if (rc != Ionic.Zlib.ZlibConstants.Z_OK)
throw new IOException($"Error '{rc}' while decompressing the data.");
if (_decompressor.AvailableBytesIn > 0 || _decompressor.AvailableBytesOut == 0)
{
ResizeBuffer(ref _compressionBuffer);
continue;
}
break;
}
return _decompressor.NextOut;
}

int HandleCompression(byte[] buffer, int count)
{
_compressor.OutputBuffer = _compressionBuffer;
_compressor.AvailableBytesOut = _compressionBuffer.Length;
_compressor.NextOut = 0;
_compressor.InputBuffer = buffer;
_compressor.AvailableBytesIn = count;
_compressor.NextOut = 0;
_compressor.NextIn = 0;
var rc = _compressor.Deflate(Ionic.Zlib.FlushType.Sync);
if (rc != Ionic.Zlib.ZlibConstants.Z_OK)
throw new IOException($"Error '{rc}' while compressing the data.");
if (_compressor.AvailableBytesIn != 0)
throw new IOException("Compression buffer too small.");
_compressor.AvailableBytesIn = count;
while (true)
{
_compressor.OutputBuffer = _compressionBuffer;
_compressor.AvailableBytesOut = _compressionBuffer.Length - _compressor.NextOut;
var rc = _compressor.Deflate(Ionic.Zlib.FlushType.None);
if (rc != Ionic.Zlib.ZlibConstants.Z_OK)
throw new IOException($"Error '{rc}' while compressing the data.");
if (_compressor.AvailableBytesIn > 0 || _compressor.AvailableBytesOut == 0)
{
ResizeBuffer(ref _compressionBuffer);
continue;
}
break;
}
while (true)
{
_compressor.OutputBuffer = _compressionBuffer;
_compressor.AvailableBytesOut = _compressionBuffer.Length - _compressor.NextOut;
var rc = _compressor.Deflate(Ionic.Zlib.FlushType.Sync);
if (rc != Ionic.Zlib.ZlibConstants.Z_OK)
throw new IOException($"Error '{rc}' while compressing the data.");
if (_compressor.AvailableBytesIn > 0 || _compressor.AvailableBytesOut == 0)
{
ResizeBuffer(ref _compressionBuffer);
continue;
}
break;
}
return _compressor.NextOut;
}

static void ResizeBuffer(ref byte[] buffer)
{
Array.Resize(ref buffer, buffer.Length * 2);
}

public override bool CanRead => throw new NotSupportedException();
public override bool CanSeek => throw new NotSupportedException();
public override bool CanWrite => throw new NotSupportedException();
Expand Down
4 changes: 4 additions & 0 deletions Provider/src/NETProvider.sln
Expand Up @@ -41,6 +41,10 @@ Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
FirebirdSql.Data.TestsBase\FirebirdSql.Data.TestsBase.projitems*{2f67ff6e-a6fc-44f4-9687-9e5ca05c73a3}*SharedItemsImports = 13
FirebirdSql.Data.External\FirebirdSql.Data.External.projitems*{884ee120-b22e-4940-8c1c-626f13028376}*SharedItemsImports = 13
FirebirdSql.Data.External\FirebirdSql.Data.External.projitems*{adc34658-2605-4588-a056-5288ede4f5de}*SharedItemsImports = 5
FirebirdSql.Data.TestsBase\FirebirdSql.Data.TestsBase.projitems*{c954bc7e-8c16-472f-ba78-93afb11c69a4}*SharedItemsImports = 5
FirebirdSql.Data.TestsBase\FirebirdSql.Data.TestsBase.projitems*{e6849ff6-d309-433a-b3ee-0554f07e3b21}*SharedItemsImports = 5
FirebirdSql.Data.TestsBase\FirebirdSql.Data.TestsBase.projitems*{e9e13e28-1e4a-4b99-b594-07a696b19bc8}*SharedItemsImports = 5
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down

0 comments on commit c1d674c

Please sign in to comment.