Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/libraries/System.Memory/ref/System.Memory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ public partial struct Enumerator
}
public static partial class SequenceReaderExtensions
{
public static bool TryPeekBigEndian(this ref System.Buffers.SequenceReader<byte> reader, out short value) { throw null; }
public static bool TryPeekBigEndian(this ref System.Buffers.SequenceReader<byte> reader, out int value) { throw null; }
public static bool TryPeekBigEndian(this ref System.Buffers.SequenceReader<byte> reader, out long value) { throw null; }
public static bool TryPeekLittleEndian(this ref System.Buffers.SequenceReader<byte> reader, out short value) { throw null; }
public static bool TryPeekLittleEndian(this ref System.Buffers.SequenceReader<byte> reader, out int value) { throw null; }
public static bool TryPeekLittleEndian(this ref System.Buffers.SequenceReader<byte> reader, out long value) { throw null; }
public static bool TryReadBigEndian(this ref System.Buffers.SequenceReader<byte> reader, out short value) { throw null; }
public static bool TryReadBigEndian(this ref System.Buffers.SequenceReader<byte> reader, out int value) { throw null; }
public static bool TryReadBigEndian(this ref System.Buffers.SequenceReader<byte> reader, out long value) { throw null; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,5 +169,137 @@ private static bool TryReadReverseEndianness(ref SequenceReader<byte> reader, ou

return false;
}

/// <summary>
/// Tries to peek at an <see cref="short"/> as little endian without advancing the reader.
/// </summary>
/// <param name="reader">The byte sequence reader instance from which the value is to be peeked.</param>
/// <param name="value">When the method returns, the value peeked out of the byte sequence reader, as little endian.</param>
/// <returns>
/// <see langword="true" /> if the peek operation is successful; <see langword="false" /> if there isn't enough data for an <see cref="short"/>.
/// </returns>
public static bool TryPeekLittleEndian(ref this SequenceReader<byte> reader, out short value)
{
if (!BinaryPrimitives.TryReadInt16LittleEndian(reader.UnreadSpan, out value))
{
Span<byte> tmpSpan = [0, 0];
if (!reader.TryCopyTo(tmpSpan))
{
return false;
}
value = BinaryPrimitives.ReadInt16LittleEndian(tmpSpan);
}
return true;
}

/// <summary>
/// Tries to peek at an <see cref="short"/> as big endian without advancing the reader.
/// </summary>
/// <param name="reader">The byte sequence reader instance from which the value is to be peeked.</param>
/// <param name="value">When the method returns, the value peeked out of the byte sequence reader, as big endian.</param>
/// <returns>
/// <see langword="true" /> if the peek operation is successful; <see langword="false" /> if there isn't enough data for an <see cref="short"/>.
/// </returns>
public static bool TryPeekBigEndian(ref this SequenceReader<byte> reader, out short value)
{
if (!BinaryPrimitives.TryReadInt16BigEndian(reader.UnreadSpan, out value))
{
Span<byte> tmpSpan = [0, 0];
if (!reader.TryCopyTo(tmpSpan))
{
return false;
}
value = BinaryPrimitives.ReadInt16BigEndian(tmpSpan);
}
return true;
}

/// <summary>
/// Tries to peek at an <see cref="int"/> as little endian without advancing the reader.
/// </summary>
/// <param name="reader">The byte sequence reader instance from which the value is to be peeked.</param>
/// <param name="value">When the method returns, the value peeked out of the byte sequence reader, as little endian.</param>
/// <returns>
/// <see langword="true" /> if the peek operation is successful; <see langword="false" /> if there isn't enough data for an <see cref="int"/>.
/// </returns>
public static bool TryPeekLittleEndian(ref this SequenceReader<byte> reader, out int value)
{
if (!BinaryPrimitives.TryReadInt32LittleEndian(reader.UnreadSpan, out value))
{
Span<byte> tmpSpan = [0, 0, 0, 0];
if (!reader.TryCopyTo(tmpSpan))
{
return false;
}
value = BinaryPrimitives.ReadInt32LittleEndian(tmpSpan);
}
return true;
}

/// <summary>
/// Tries to peek at an <see cref="int"/> as big endian without advancing the reader.
/// </summary>
/// <param name="reader">The byte sequence reader instance from which the value is to be peeked.</param>
/// <param name="value">When the method returns, the value peeked out of the byte sequence reader, as big endian.</param>
/// <returns>
/// <see langword="true" /> if the peek operation is successful; <see langword="false" /> if there isn't enough data for an <see cref="int"/>.
/// </returns>
public static bool TryPeekBigEndian(ref this SequenceReader<byte> reader, out int value)
{
if (!BinaryPrimitives.TryReadInt32BigEndian(reader.UnreadSpan, out value))
{
Span<byte> tmpSpan = [0, 0, 0, 0];
if (!reader.TryCopyTo(tmpSpan))
{
return false;
}
value = BinaryPrimitives.ReadInt32BigEndian(tmpSpan);
}
return true;
}

/// <summary>
/// Tries to peek at an <see cref="long"/> as little endian without advancing the reader.
/// </summary>
/// <param name="reader">The byte sequence reader instance from which the value is to be peeked.</param>
/// <param name="value">When the method returns, the value peeked out of the byte sequence reader, as little endian.</param>
/// <returns>
/// <see langword="true" /> if the peek operation is successful; <see langword="false" /> if there isn't enough data for an <see cref="long"/>.
/// </returns>
public static bool TryPeekLittleEndian(ref this SequenceReader<byte> reader, out long value)
{
if (!BinaryPrimitives.TryReadInt64LittleEndian(reader.UnreadSpan, out value))
{
Span<byte> tmpSpan = [0, 0, 0, 0, 0, 0, 0, 0];
if (!reader.TryCopyTo(tmpSpan))
{
return false;
}
value = BinaryPrimitives.ReadInt64LittleEndian(tmpSpan);
}
return true;
}

/// <summary>
/// Tries to peek at an <see cref="long"/> as big endian without advancing the reader.
/// </summary>
/// <param name="reader">The byte sequence reader instance from which the value is to be peeked.</param>
/// <param name="value">When the method returns, the value peeked out of the byte sequence reader, as big endian.</param>
/// <returns>
/// <see langword="true" /> if the peek operation is successful; <see langword="false" /> if there isn't enough data for an <see cref="long"/>.
/// </returns>
public static bool TryPeekBigEndian(ref this SequenceReader<byte> reader, out long value)
{
if (!BinaryPrimitives.TryReadInt64BigEndian(reader.UnreadSpan, out value))
{
Span<byte> tmpSpan = [0, 0, 0, 0, 0, 0, 0, 0];
if (!reader.TryCopyTo(tmpSpan))
{
return false;
}
value = BinaryPrimitives.ReadInt64BigEndian(tmpSpan);
}
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ public void MultiSegmentBytesReaderNumbers()
new byte[] { 8, 0 },
new byte[] { 1, },
new byte[] { 0, 2, },
new byte[] { 6, 7, 8, 9 },
new byte[] { 1, 2, 3, 4 },
new byte[] { 5, 6 },
new byte[] { 7, 8, 9, },
new byte[] { 0, 1, 2, 3 },
new byte[] { 4, 5 },
new byte[] { 6, 7, 8, 9 },
new byte[] { 0, 1, 2, 3 },
new byte[] { 4 },
new byte[] { 4, 6 },
});

SequenceReader<byte> reader = new SequenceReader<byte>(bytes);
Expand All @@ -36,34 +37,120 @@ public void MultiSegmentBytesReaderNumbers()
Span<byte> span = bytesValue.ToArray();
Assert.Equal(0, span[0]);
Assert.Equal(1, span[1]);
Assert.Equal(2, span.Length);
Assert.Equal(3, reader.Consumed);

Assert.True(reader.TryReadTo(out bytesValue, 5));
span = bytesValue.ToArray();
Assert.Equal(3, span[0]);
Assert.Equal(4, span[1]);
Assert.Equal(2, span.Length);
Assert.Equal(6, reader.Consumed);

Assert.True(reader.TryReadTo(out bytesValue, new byte[] { 8, 8 }));
span = bytesValue.ToArray();
Assert.Equal(6, span[0]);
Assert.Equal(7, span[1]);
Assert.Equal(2, span.Length);
Assert.Equal(10, reader.Consumed);

Assert.True(SequenceMarshal.TryRead(ref reader, out int intValue));
Assert.Equal(BitConverter.ToInt32(new byte[] { 0, 1, 0, 2 }), intValue);
Assert.Equal(14, reader.Consumed);

Assert.True(reader.TryPeekLittleEndian(out intValue));
Assert.Equal(0x09080706, intValue);
Assert.Equal(14, reader.Consumed);

Assert.True(reader.TryReadLittleEndian(out intValue));
Assert.Equal(0x09080706, intValue);
Assert.Equal(18, reader.Consumed);

Assert.True(reader.TryPeekBigEndian(out intValue));
Assert.Equal(0x01020304, intValue);
Assert.Equal(18, reader.Consumed);

Assert.True(reader.TryReadBigEndian(out intValue));
Assert.Equal(0x01020304, intValue);
Assert.Equal(22, reader.Consumed);

Assert.True(reader.TryPeekLittleEndian(out long longValue));
Assert.Equal(0x0201000908070605L, longValue);
Assert.Equal(22, reader.Consumed);

Assert.True(reader.TryReadLittleEndian(out long longValue));
Assert.True(reader.TryReadLittleEndian(out longValue));
Assert.Equal(0x0201000908070605L, longValue);
Assert.Equal(30, reader.Consumed);

Assert.True(reader.TryPeekBigEndian(out longValue));
Assert.Equal(0x0304050607080900L, longValue);
Assert.Equal(30, reader.Consumed);

Assert.True(reader.TryReadBigEndian(out longValue));
Assert.Equal(0x0304050607080900L, longValue);
Assert.Equal(38, reader.Consumed);

Assert.True(reader.TryPeekLittleEndian(out short shortValue));
Assert.Equal(0x0201, shortValue);
Assert.Equal(38, reader.Consumed);

Assert.True(reader.TryReadLittleEndian(out short shortValue));
Assert.True(reader.TryReadLittleEndian(out shortValue));
Assert.Equal(0x0201, shortValue);
Assert.Equal(40, reader.Consumed);

Assert.True(reader.TryPeekBigEndian(out shortValue));
Assert.Equal(0x0304, shortValue);
Assert.Equal(40, reader.Consumed);

Assert.True(reader.TryReadBigEndian(out shortValue));
Assert.Equal(0x0304, shortValue);
Assert.Equal(42, reader.Consumed);

// There is only one byte left, all Try* methods should return false

Assert.False(SequenceMarshal.TryRead(ref reader, out intValue));
Assert.Equal(0, intValue);
Assert.Equal(42, reader.Consumed);

Assert.False(reader.TryPeekBigEndian(out intValue));
Assert.Equal(0, intValue);
Assert.Equal(42, reader.Consumed);

Assert.False(reader.TryReadBigEndian(out intValue));
Assert.Equal(0, intValue);
Assert.Equal(42, reader.Consumed);

Assert.False(reader.TryPeekLittleEndian(out longValue));
Assert.Equal(0, longValue);
Assert.Equal(42, reader.Consumed);

Assert.False(reader.TryReadLittleEndian(out longValue));
Assert.Equal(0, longValue);
Assert.Equal(42, reader.Consumed);

Assert.False(reader.TryPeekBigEndian(out longValue));
Assert.Equal(0, longValue);
Assert.Equal(42, reader.Consumed);

Assert.False(reader.TryReadBigEndian(out longValue));
Assert.Equal(0, longValue);
Assert.Equal(42, reader.Consumed);

Assert.False(reader.TryPeekLittleEndian(out shortValue));
Assert.Equal(0, shortValue);
Assert.Equal(42, reader.Consumed);

Assert.False(reader.TryReadLittleEndian(out shortValue));
Assert.Equal(0, shortValue);
Assert.Equal(42, reader.Consumed);

Assert.False(reader.TryPeekBigEndian(out shortValue));
Assert.Equal(0, shortValue);
Assert.Equal(42, reader.Consumed);

Assert.False(reader.TryReadBigEndian(out shortValue));
Assert.Equal(0, shortValue);
Assert.Equal(42, reader.Consumed);
}
}
}
Loading