Skip to content

Commit 7eb4556

Browse files
committed
Add ReadByteArraySegment.
This allows part of the response to be read without allocating a temporary byte array.
1 parent 77bfe26 commit 7eb4556

File tree

5 files changed

+29
-13
lines changed

5 files changed

+29
-13
lines changed

src/MySqlConnector/Core/ServerSession.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -924,10 +924,10 @@ private async Task GetRealServerDetailsAsync(IOBehavior ioBehavior, Cancellation
924924
var reader = new ByteArrayReader(payload.ArraySegment);
925925
var length = reader.ReadLengthEncodedIntegerOrNull();
926926
if (length != -1)
927-
connectionId = int.Parse(Encoding.UTF8.GetString(reader.ReadByteArray(length)), CultureInfo.InvariantCulture);
927+
connectionId = int.Parse(Encoding.UTF8.GetString(reader.ReadByteArraySegment(length)), CultureInfo.InvariantCulture);
928928
length = reader.ReadLengthEncodedIntegerOrNull();
929929
if (length != -1)
930-
serverVersion = Encoding.UTF8.GetString(reader.ReadByteArray(length));
930+
serverVersion = Encoding.UTF8.GetString(reader.ReadByteArraySegment(length));
931931

932932
// OK/EOF payload
933933
payload = await ReceiveReplyAsync(ioBehavior, CancellationToken.None).ConfigureAwait(false);

src/MySqlConnector/Protocol/Payloads/ErrorPayload.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Text;
22
using MySql.Data.MySqlClient;
33
using MySqlConnector.Protocol.Serialization;
4+
using MySqlConnector.Utilities;
45

56
namespace MySqlConnector.Protocol.Payloads
67
{
@@ -19,17 +20,17 @@ public static ErrorPayload Create(PayloadData payload)
1920
reader.ReadByte(Signature);
2021

2122
var errorCode = reader.ReadUInt16();
22-
var stateMarker = Encoding.ASCII.GetString(reader.ReadByteArray(1));
23+
var stateMarker = Encoding.ASCII.GetString(reader.ReadByteArraySegment(1));
2324
string state, message;
2425
if (stateMarker == "#")
2526
{
26-
state = Encoding.ASCII.GetString(reader.ReadByteArray(5));
27-
message = Encoding.UTF8.GetString(reader.ReadByteArray(payload.ArraySegment.Count - 9));
27+
state = Encoding.ASCII.GetString(reader.ReadByteArraySegment(5));
28+
message = Encoding.UTF8.GetString(reader.ReadByteArraySegment(payload.ArraySegment.Count - 9));
2829
}
2930
else
3031
{
3132
state = "HY000";
32-
message = stateMarker + Encoding.UTF8.GetString(reader.ReadByteArray(payload.ArraySegment.Count - 4));
33+
message = stateMarker + Encoding.UTF8.GetString(reader.ReadByteArraySegment(payload.ArraySegment.Count - 4));
3334
}
3435
return new ErrorPayload(errorCode, state, message);
3536
}

src/MySqlConnector/Protocol/Payloads/InitialHandshakePayload.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ public static InitialHandshakePayload Create(PayloadData payload)
1818
reader.ReadByte(c_protocolVersion);
1919
var serverVersion = reader.ReadNullTerminatedByteString();
2020
var connectionId = reader.ReadInt32();
21-
var authPluginData = reader.ReadByteArray(8);
21+
byte[] authPluginData = null;
22+
var authPluginData1 = reader.ReadByteArraySegment(8);
2223
string authPluginName = null;
2324
reader.ReadByte(0);
2425
var protocolCapabilities = (ProtocolCapabilities) reader.ReadUInt16();
@@ -29,18 +30,23 @@ public static InitialHandshakePayload Create(PayloadData payload)
2930
var capabilityFlagsHigh = reader.ReadUInt16();
3031
protocolCapabilities |= (ProtocolCapabilities) (capabilityFlagsHigh << 16);
3132
var authPluginDataLength = reader.ReadByte();
32-
var unused = reader.ReadByteArray(10);
33+
var unused = reader.ReadByteArraySegment(10);
3334
if ((protocolCapabilities & ProtocolCapabilities.SecureConnection) != 0)
3435
{
35-
var authPluginData2 = reader.ReadByteArray(Math.Max(13, authPluginDataLength - 8));
36-
var concatenated = new byte[authPluginData.Length + authPluginData2.Length];
37-
Buffer.BlockCopy(authPluginData, 0, concatenated, 0, authPluginData.Length);
38-
Buffer.BlockCopy(authPluginData2, 0, concatenated,authPluginData.Length, authPluginData2.Length);
36+
var authPluginData2 = reader.ReadByteArraySegment(Math.Max(13, authPluginDataLength - 8));
37+
var concatenated = new byte[authPluginData1.Count + authPluginData2.Count];
38+
Buffer.BlockCopy(authPluginData1.Array, authPluginData1.Offset, concatenated, 0, authPluginData1.Count);
39+
Buffer.BlockCopy(authPluginData2.Array, authPluginData2.Offset, concatenated, authPluginData1.Count, authPluginData2.Count);
3940
authPluginData = concatenated;
4041
}
4142
if ((protocolCapabilities & ProtocolCapabilities.PluginAuth) != 0)
4243
authPluginName = Encoding.UTF8.GetString(reader.ReadNullOrEofTerminatedByteString());
4344
}
45+
if (authPluginData == null)
46+
{
47+
authPluginData = new byte[authPluginData1.Count];
48+
Buffer.BlockCopy(authPluginData1.Array, authPluginData1.Offset, authPluginData, 0, authPluginData1.Count);
49+
}
4450

4551
if (reader.BytesRemaining != 0)
4652
throw new FormatException("Extra bytes at end of payload.");

src/MySqlConnector/Protocol/Payloads/LocalInfilePayload.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Text;
22
using MySqlConnector.Protocol.Serialization;
3+
using MySqlConnector.Utilities;
34

45
namespace MySqlConnector.Protocol.Payloads
56
{
@@ -14,7 +15,7 @@ public static LocalInfilePayload Create(PayloadData payload)
1415
{
1516
var reader = new ByteArrayReader(payload.ArraySegment);
1617
reader.ReadByte(Signature);
17-
var fileName = Encoding.UTF8.GetString(reader.ReadByteArray(reader.BytesRemaining));
18+
var fileName = Encoding.UTF8.GetString(reader.ReadByteArraySegment(reader.BytesRemaining));
1819
return new LocalInfilePayload(fileName);
1920
}
2021

src/MySqlConnector/Protocol/Serialization/ByteArrayReader.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,14 @@ public byte[] ReadByteArray(int length)
127127
return result;
128128
}
129129

130+
public ArraySegment<byte> ReadByteArraySegment(int length)
131+
{
132+
VerifyRead(length);
133+
var result = new ArraySegment<byte>(m_buffer, m_offset, length);
134+
m_offset += length;
135+
return result;
136+
}
137+
130138
public ulong ReadLengthEncodedInteger()
131139
{
132140
byte encodedLength = m_buffer[m_offset++];

0 commit comments

Comments
 (0)