Skip to content

[NRBF] change StartsWithPayloadHeader to accept a Span rather than array #103636

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 28, 2024
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public static partial class NrbfDecoder
public static System.Formats.Nrbf.SerializationRecord Decode(System.IO.Stream payload, out System.Collections.Generic.IReadOnlyDictionary<System.Formats.Nrbf.SerializationRecordId, System.Formats.Nrbf.SerializationRecord> recordMap, System.Formats.Nrbf.PayloadOptions options=null, bool leaveOpen=false) { throw null; }
public static System.Formats.Nrbf.SerializationRecord Decode(System.IO.Stream payload, System.Formats.Nrbf.PayloadOptions? options=null, bool leaveOpen=false) { throw null; }
public static System.Formats.Nrbf.ClassRecord DecodeClassRecord(System.IO.Stream payload, System.Formats.Nrbf.PayloadOptions? options=null, bool leaveOpen=false) { throw null; }
public static bool StartsWithPayloadHeader(byte[] bytes) { throw null; }
public static bool StartsWithPayloadHeader(System.ReadOnlySpan<byte> bytes) { throw null; }
public static bool StartsWithPayloadHeader(System.IO.Stream stream) { throw null; }
}
public sealed partial class PayloadOptions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Formats.Nrbf.Utils;
using System.Text;
using System.Runtime.Serialization;
using System.Runtime.InteropServices;

namespace System.Formats.Nrbf;

Expand All @@ -18,33 +19,24 @@ public static class NrbfDecoder
{
private static UTF8Encoding ThrowOnInvalidUtf8Encoding { get; } = new(false, throwOnInvalidBytes: true);

// The header consists of:
// - a byte that describes the record type (SerializationRecordType.SerializedStreamHeader)
// - four 32 bit integers:
// - root Id (every value is valid)
// - header Id (value is ignored)
// - major version, it has to be equal 1.
// - minor version, it has to be equal 0.
private static ReadOnlySpan<byte> HeaderSuffix => [1, 0, 0, 0, 0, 0, 0, 0];

/// <summary>
/// Checks if given buffer starts with <see href="https://learn.microsoft.com/openspecs/windows_protocols/ms-nrbf/a7e578d3-400a-4249-9424-7529d10d1b3c">NRBF payload header</see>.
/// </summary>
/// <param name="bytes">The buffer to inspect.</param>
/// <returns><see langword="true" /> if it starts with NRBF payload header; otherwise, <see langword="false" />.</returns>
public static bool StartsWithPayloadHeader(byte[] bytes)
{
#if NET
ArgumentNullException.ThrowIfNull(bytes);
#else
if (bytes is null)
{
throw new ArgumentNullException(nameof(bytes));
}
#endif

return bytes.Length >= SerializedStreamHeaderRecord.Size
&& bytes[0] == (byte)SerializationRecordType.SerializedStreamHeader
#if NET
&& BinaryPrimitives.ReadInt32LittleEndian(bytes.AsSpan(9)) == SerializedStreamHeaderRecord.MajorVersion
&& BinaryPrimitives.ReadInt32LittleEndian(bytes.AsSpan(13)) == SerializedStreamHeaderRecord.MinorVersion;
#else
&& BitConverter.ToInt32(bytes, 9) == SerializedStreamHeaderRecord.MajorVersion
&& BitConverter.ToInt32(bytes, 13) == SerializedStreamHeaderRecord.MinorVersion;
#endif
}

public static bool StartsWithPayloadHeader(ReadOnlySpan<byte> bytes)
=> bytes.Length >= SerializedStreamHeaderRecord.Size
&& bytes[0] == (byte)SerializationRecordType.SerializedStreamHeader
&& bytes.Slice(SerializedStreamHeaderRecord.Size - HeaderSuffix.Length, HeaderSuffix.Length).SequenceEqual(HeaderSuffix);

/// <summary>
/// Checks if given stream starts with <see href="https://learn.microsoft.com/openspecs/windows_protocols/ms-nrbf/a7e578d3-400a-4249-9424-7529d10d1b3c">NRBF payload header</see>.
Expand Down Expand Up @@ -76,13 +68,13 @@ public static bool StartsWithPayloadHeader(Stream stream)
return false;
}

byte[] buffer = new byte[SerializedStreamHeaderRecord.Size];

try
{
#if NET
stream.ReadExactly(buffer, 0, buffer.Length);
Span<byte> buffer = stackalloc byte[SerializedStreamHeaderRecord.Size];
stream.ReadExactly(buffer);
#else
byte[] buffer = new byte[SerializedStreamHeaderRecord.Size];
int offset = 0;
while (offset < buffer.Length)
{
Expand Down
Loading