Skip to content

Commit 33ba407

Browse files
committed
Remove obsolete TODO comment.
Add a few more explanatory comments.
1 parent 9c58ff9 commit 33ba407

File tree

1 file changed

+17
-4
lines changed

1 file changed

+17
-4
lines changed

src/MySqlConnector/Protocol/Serialization/CompressedPayloadHandler.cs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public ValueTask<ArraySegment<byte>> ReadPayloadAsync(ProtocolErrorBehavior prot
3333

3434
public ValueTask<int> WritePayloadAsync(ArraySegment<byte> payload, IOBehavior ioBehavior)
3535
{
36+
// break the payload up into (possibly more than one) uncompressed packets
3637
return ProtocolUtility.WritePayloadAsync(m_uncompressedStreamByteHandler, GetNextUncompressedSequenceNumber, payload, ioBehavior).ContinueWith(_ =>
3738
{
3839
if (m_uncompressedStream.Length == 0)
@@ -45,6 +46,7 @@ public ValueTask<int> WritePayloadAsync(ArraySegment<byte> payload, IOBehavior i
4546
return CompressAndWrite(uncompressedData, ioBehavior)
4647
.ContinueWith(__ =>
4748
{
49+
// reset the uncompressed stream to accept more data
4850
m_uncompressedStream.SetLength(0);
4951
return default(ValueTask<int>);
5052
});
@@ -53,6 +55,7 @@ public ValueTask<int> WritePayloadAsync(ArraySegment<byte> payload, IOBehavior i
5355

5456
private ValueTask<ArraySegment<byte>> ReadBytesAsync(int count, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior)
5557
{
58+
// satisfy the read from cache if possible
5659
if (m_remainingData.Count > 0)
5760
{
5861
int bytesToRead = Math.Min(m_remainingData.Count, count);
@@ -61,6 +64,7 @@ private ValueTask<ArraySegment<byte>> ReadBytesAsync(int count, ProtocolErrorBeh
6164
return new ValueTask<ArraySegment<byte>>(result);
6265
}
6366

67+
// read the compressed header (seven bytes)
6468
return m_bufferedByteReader.ReadBytesAsync(m_byteHandler, 7, ioBehavior)
6569
.ContinueWith(headerReadBytes =>
6670
{
@@ -75,6 +79,7 @@ private ValueTask<ArraySegment<byte>> ReadBytesAsync(int count, ProtocolErrorBeh
7579
int packetSequenceNumber = headerReadBytes.Array[headerReadBytes.Offset + 3];
7680
var uncompressedLength = (int) SerializationUtility.ReadUInt32(headerReadBytes.Array, headerReadBytes.Offset + 4, 3);
7781

82+
// verify the compressed packet sequence number
7883
var expectedSequenceNumber = GetNextCompressedSequenceNumber() % 256;
7984
if (packetSequenceNumber != expectedSequenceNumber)
8085
{
@@ -85,11 +90,14 @@ private ValueTask<ArraySegment<byte>> ReadBytesAsync(int count, ProtocolErrorBeh
8590
return ValueTaskExtensions.FromException<ArraySegment<byte>>(exception);
8691
}
8792

88-
// MySQL protocol hack: reset the uncompressed sequence number back to the sequence number of this compressed packet
93+
// MySQL protocol resets the uncompressed sequence number back to the sequence number of this compressed packet.
94+
// This isn't in the documentation, but the code explicitly notes that uncompressed packets are modified by compression:
95+
// - https://github.com/mysql/mysql-server/blob/c28e258157f39f25e044bb72e8bae1ff00989a3d/sql/net_serv.cc#L276
96+
// - https://github.com/mysql/mysql-server/blob/c28e258157f39f25e044bb72e8bae1ff00989a3d/sql/net_serv.cc#L225-L227
8997
if (!m_isContinuationPacket)
9098
m_uncompressedSequenceNumber = packetSequenceNumber;
9199

92-
// except when uncompressed packets need to be broken up across multiple compressed packets
100+
// except this doesn't happen when uncompressed packets need to be broken up across multiple compressed packets
93101
m_isContinuationPacket = payloadLength == ProtocolUtility.MaxPacketSize || uncompressedLength == ProtocolUtility.MaxPacketSize;
94102

95103
return m_bufferedByteReader.ReadBytesAsync(m_byteHandler, payloadLength, ioBehavior)
@@ -104,7 +112,7 @@ private ValueTask<ArraySegment<byte>> ReadBytesAsync(int count, ProtocolErrorBeh
104112

105113
if (uncompressedLength == 0)
106114
{
107-
// uncompressed
115+
// data is uncompressed
108116
m_remainingData = payloadReadBytes;
109117
}
110118
else
@@ -122,8 +130,12 @@ private ValueTask<ArraySegment<byte>> ReadBytesAsync(int count, ProtocolErrorBeh
122130
ValueTaskExtensions.FromException<ArraySegment<byte>>(new NotSupportedException("Unsupported zlib header: {0:X2}{1:X2}".FormatInvariant(cmf, flg)));
123131
}
124132

133+
// zlib format (https://www.ietf.org/rfc/rfc1950.txt) is: [two header bytes] [deflate-compressed data] [four-byte checksum]
134+
// .NET implements the middle part with DeflateStream; need to handle header and checksum explicitly
135+
const int headerSize = 2;
136+
const int checksumSize = 4;
125137
var uncompressedData = new byte[uncompressedLength];
126-
using (var compressedStream = new MemoryStream(payloadReadBytes.Array, payloadReadBytes.Offset + 2, payloadReadBytes.Count - 6)) // TODO: handle zlib format correctly
138+
using (var compressedStream = new MemoryStream(payloadReadBytes.Array, payloadReadBytes.Offset + headerSize, payloadReadBytes.Count - headerSize - checksumSize))
127139
using (var decompressingStream = new DeflateStream(compressedStream, CompressionMode.Decompress))
128140
{
129141
var bytesRead = decompressingStream.Read(uncompressedData, 0, uncompressedLength);
@@ -219,6 +231,7 @@ private ValueTask<int> CompressAndWrite(ArraySegment<byte> remainingUncompressed
219231
CompressAndWrite(remainingUncompressedData, ioBehavior));
220232
}
221233

234+
// CompressedByteHandler implements IByteHandler and delegates reading bytes back to the CompressedPayloadHandler class.
222235
private class CompressedByteHandler : IByteHandler
223236
{
224237
public CompressedByteHandler(CompressedPayloadHandler compressedPayloadHandler, ProtocolErrorBehavior protocolErrorBehavior)

0 commit comments

Comments
 (0)