From: Date: June 1 2007 5:28pm Subject: Connector/NET commit: r749 - in branches/5.0: . Driver/Source List-Archive: http://lists.mysql.com/commits/27937 X-Bug: 28204, 28204 Message-Id: <200706011528.l51FS3i4028295@bk-internal.mysql.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Modified: branches/5.0/CHANGES branches/5.0/Driver/Source/CompressedStream.cs Log: Bug #28204 Net Connector 5.0.6/5.1.0 compression problem Fixed a problem with compression over a network. We were letting the inflate stream read directly from the network stream. Under certain situations, two bytes were being left unread and this messed up our byte counts. Now we are using a WeakReference to an internal buffer that we read the compressed data into before inflating. (Bug #28204) Modified: branches/5.0/CHANGES =================================================================== --- branches/5.0/CHANGES 2007-05-30 18:44:55 UTC (rev 748) +++ branches/5.0/CHANGES 2007-06-01 15:28:02 UTC (rev 749) @@ -1,9 +1,10 @@ Version 5.0.8 - Bugs fixed - ---------- Bug #28706 Log messages are truncated + - Fixed a problem with compression over a network. We were letting the inflate stream read + directly from the network stream. Under certain situations, two bytes were being left unread + and this messed up our byte counts. Now we are using a WeakReference to an internal buffer + that we read the compressed data into before inflating. (Bug #28204) - Version 5.0.7 5/16/2007 Bugs fixed Modified: branches/5.0/Driver/Source/CompressedStream.cs =================================================================== --- branches/5.0/Driver/Source/CompressedStream.cs 2007-05-30 18:44:55 UTC (rev 748) +++ branches/5.0/Driver/Source/CompressedStream.cs 2007-06-01 15:28:02 UTC (rev 749) @@ -35,6 +35,8 @@ // reading fields private byte[] localByte; + private byte[] inBuffer; + private WeakReference inBufferRef; private int inPos; private int maxInPos; private ZInputStream zInStream; @@ -44,16 +46,11 @@ this.baseStream = baseStream; localByte = new byte[1]; cache = new MemoryStream(); - } + inBufferRef = new WeakReference(inBuffer, false); + } #region Properties - //TODO: remove comment -/* public Stream BaseStream - { - get { return baseStream; } - } -*/ public override bool CanRead { get { return baseStream.CanRead; } @@ -109,9 +106,8 @@ throw new ArgumentException(Resources.BufferNotLargeEnough, "buffer"); if (inPos == maxInPos) - { PrepareNextPacket(); - } + int countToRead = Math.Min(count, maxInPos-inPos); int countRead; if (zInStream != null) @@ -119,6 +115,15 @@ else countRead = baseStream.Read(buffer, offset, countToRead); inPos += countRead; + + // release the weak reference + if (inPos == maxInPos) + { + zInStream = null; + inBufferRef.Target = inBuffer; + inBuffer = null; + } + return countRead; } @@ -141,7 +146,9 @@ } else { - zInStream = new ZInputStream(baseStream); + ReadNextPacket(compressedLength); + MemoryStream ms = new MemoryStream(inBuffer); + zInStream = new ZInputStream(ms); zInStream.maxInput = compressedLength; } @@ -149,6 +156,21 @@ maxInPos = unCompressedLength; } + private void ReadNextPacket(int len) + { + inBuffer = (byte[])inBufferRef.Target; + if (inBuffer == null || inBuffer.Length < len) + inBuffer = new byte[len]; + int numRead = 0; + int numToRead = len; + while (numToRead > 0) + { + int read = baseStream.Read(inBuffer, numRead, numToRead); + numRead += read; + numToRead -= read; + } + } + private MemoryStream CompressCache() { // small arrays almost never yeild a benefit from compressing