Skip to content

Commit ce91731

Browse files
committed
Implement GetChars.
Standardise argument validation between it and GetBytes. Tests are in the ADO.NET conformance test suite.
1 parent 610dbdb commit ce91731

File tree

1 file changed

+34
-5
lines changed

1 file changed

+34
-5
lines changed

src/MySqlConnector/Core/Row.cs

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,17 +104,30 @@ public long GetBytes(int ordinal, long dataOffset, byte[] buffer, int bufferOffs
104104
return m_dataLengths[ordinal];
105105
}
106106

107-
if (bufferOffset + length > buffer.Length)
108-
throw new ArgumentException("bufferOffset + length cannot exceed buffer.Length", nameof(length));
107+
CheckBufferArguments(dataOffset, buffer, bufferOffset, length);
109108

110-
int lengthToCopy = Math.Min(m_dataLengths[ordinal] - (int) dataOffset, length);
111-
Buffer.BlockCopy(m_payload.Array, checked((int) (m_dataOffsets[ordinal] + dataOffset)), buffer, bufferOffset, lengthToCopy);
109+
var offset = (int) dataOffset;
110+
var lengthToCopy = Math.Max(0, Math.Min(m_dataLengths[ordinal] - offset, length));
111+
Buffer.BlockCopy(m_payload.Array, m_dataOffsets[ordinal] + offset, buffer, bufferOffset, lengthToCopy);
112112
return lengthToCopy;
113113
}
114114

115115
public char GetChar(int ordinal) => (char) GetValue(ordinal);
116116

117-
public long GetChars(int ordinal, long dataOffset, char[] buffer, int bufferOffset, int length) => throw new NotImplementedException();
117+
public long GetChars(int ordinal, long dataOffset, char[] buffer, int bufferOffset, int length)
118+
{
119+
var value = GetString(ordinal);
120+
if (buffer == null)
121+
return value.Length;
122+
123+
CheckBufferArguments(dataOffset, buffer, bufferOffset, length);
124+
125+
var offset = (int) dataOffset;
126+
var lengthToCopy = Math.Max(0, Math.Min(value.Length - offset, length));
127+
if (lengthToCopy > 0)
128+
value.CopyTo(offset, buffer, bufferOffset, lengthToCopy);
129+
return lengthToCopy;
130+
}
118131

119132
public Guid GetGuid(int ordinal)
120133
{
@@ -325,6 +338,22 @@ public object GetValue(int ordinal)
325338
}
326339
}
327340

341+
private static void CheckBufferArguments<T>(long dataOffset, T[] buffer, int bufferOffset, int length)
342+
{
343+
if (dataOffset < 0)
344+
throw new ArgumentOutOfRangeException(nameof(dataOffset), dataOffset, "dataOffset must be non-negative");
345+
if (dataOffset > int.MaxValue)
346+
throw new ArgumentOutOfRangeException(nameof(dataOffset), dataOffset, "dataOffset must be a 32-bit integer");
347+
if (length < 0)
348+
throw new ArgumentOutOfRangeException(nameof(length), length, "length must be non-negative");
349+
if (bufferOffset < 0)
350+
throw new ArgumentOutOfRangeException(nameof(bufferOffset), bufferOffset, "bufferOffset must be non-negative");
351+
if (bufferOffset > buffer.Length)
352+
throw new ArgumentOutOfRangeException(nameof(bufferOffset), bufferOffset, "bufferOffset must be within the buffer");
353+
if (checked(bufferOffset + length) > buffer.Length)
354+
throw new ArgumentException("bufferOffset + length cannot exceed buffer.Length", nameof(length));
355+
}
356+
328357
private DateTime ParseDateTime(ArraySegment<byte> value)
329358
{
330359
var parts = Encoding.UTF8.GetString(value).Split('-', ' ', ':', '.');

0 commit comments

Comments
 (0)