diff --git a/src/libraries/Common/src/Polyfills/BitConverterPolyfills.cs b/src/libraries/Common/src/Polyfills/BitConverterPolyfills.cs
index dd418d32f94406..92fed514916fa7 100644
--- a/src/libraries/Common/src/Polyfills/BitConverterPolyfills.cs
+++ b/src/libraries/Common/src/Polyfills/BitConverterPolyfills.cs
@@ -1,6 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Runtime.InteropServices;
+
namespace System;
/// Provides downlevel polyfills for static methods on .
@@ -23,5 +25,16 @@ public static ulong DoubleToUInt64Bits(double value)
return *(ulong*)&value;
}
}
+
+ // ---- ReadOnlySpan read overloads (host-endian, semantics match BCL net5+) ----
+
+ public static short ToInt16(ReadOnlySpan value) => MemoryMarshal.Read(value);
+ public static ushort ToUInt16(ReadOnlySpan value) => MemoryMarshal.Read(value);
+ public static int ToInt32(ReadOnlySpan value) => MemoryMarshal.Read(value);
+ public static uint ToUInt32(ReadOnlySpan value) => MemoryMarshal.Read(value);
+ public static long ToInt64(ReadOnlySpan value) => MemoryMarshal.Read(value);
+ public static ulong ToUInt64(ReadOnlySpan value) => MemoryMarshal.Read(value);
+ public static float ToSingle(ReadOnlySpan value) => MemoryMarshal.Read(value);
+ public static double ToDouble(ReadOnlySpan value) => MemoryMarshal.Read(value);
}
}
diff --git a/src/libraries/Common/src/Polyfills/HashCodePolyfills.cs b/src/libraries/Common/src/Polyfills/HashCodePolyfills.cs
index 7b2bc309c24bfd..95aa9ad2ce5ea4 100644
--- a/src/libraries/Common/src/Polyfills/HashCodePolyfills.cs
+++ b/src/libraries/Common/src/Polyfills/HashCodePolyfills.cs
@@ -12,7 +12,7 @@ public static void AddBytes(this ref HashCode hashCode, ReadOnlySpan value
{
while (value.Length >= sizeof(int))
{
- hashCode.Add(MemoryMarshal.Read(value));
+ hashCode.Add(BitConverter.ToInt32(value));
value = value.Slice(sizeof(int));
}
diff --git a/src/libraries/Microsoft.Win32.Registry/src/Microsoft/Win32/RegistryKey.cs b/src/libraries/Microsoft.Win32.Registry/src/Microsoft/Win32/RegistryKey.cs
index 0aa1b22d5f316d..5da1144cd2e94a 100644
--- a/src/libraries/Microsoft.Win32.Registry/src/Microsoft/Win32/RegistryKey.cs
+++ b/src/libraries/Microsoft.Win32.Registry/src/Microsoft/Win32/RegistryKey.cs
@@ -1087,8 +1087,8 @@ public unsafe string[] GetValueNames()
case Interop.Advapi32.RegistryValues.REG_QWORD:
return dataLength switch
{
- 4 => MemoryMarshal.Read(span),
- 8 => MemoryMarshal.Read(span),
+ 4 => BitConverter.ToInt32(span),
+ 8 => BitConverter.ToInt64(span),
_ => span.Slice(0, dataLength).ToArray(), // This shouldn't happen, but the previous implementation included it defensively.
};
diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj b/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj
index 1a6cc53679e5f8..cf181a3cf2e763 100644
--- a/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj
+++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj
@@ -137,6 +137,10 @@ System.Diagnostics.PerformanceCounter
Link="Common\DisableRuntimeMarshalling.cs" />
+
+
+
+
diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceCounterLib.cs b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceCounterLib.cs
index a9f4d8121f5033..34f317c812be5f 100644
--- a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceCounterLib.cs
+++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/PerformanceCounterLib.cs
@@ -1713,11 +1713,11 @@ private long ReadValue(ReadOnlySpan data)
{
if (_size == 4)
{
- return (long)MemoryMarshal.Read(data.Slice(_offset));
+ return (long)BitConverter.ToUInt32(data.Slice(_offset));
}
else if (_size == 8)
{
- return MemoryMarshal.Read(data.Slice(_offset));
+ return BitConverter.ToInt64(data.Slice(_offset));
}
return -1;
diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessManager.Windows.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessManager.Windows.cs
index 7c2bb7b35764b3..87fbf233f882c6 100644
--- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessManager.Windows.cs
+++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/ProcessManager.Windows.cs
@@ -761,9 +761,9 @@ private static ValueId GetValueId(string counterName)
private static long ReadCounterValue(int counterType, ReadOnlySpan data)
{
if ((counterType & PerfCounterOptions.NtPerfCounterSizeLarge) != 0)
- return MemoryMarshal.Read(data);
+ return BitConverter.ToInt64(data);
else
- return MemoryMarshal.Read(data);
+ return BitConverter.ToInt32(data);
}
private enum ValueId
diff --git a/src/libraries/System.Formats.Cbor/src/System.Formats.Cbor.csproj b/src/libraries/System.Formats.Cbor/src/System.Formats.Cbor.csproj
index 04dfc7a44cf491..1c9501fdfd0c17 100644
--- a/src/libraries/System.Formats.Cbor/src/System.Formats.Cbor.csproj
+++ b/src/libraries/System.Formats.Cbor/src/System.Formats.Cbor.csproj
@@ -51,6 +51,7 @@ System.Formats.Cbor.CborWriter
+
diff --git a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/CborHelpers.netstandard.cs b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/CborHelpers.netstandard.cs
index adb2eb362c0308..d62cd99e4cdbcb 100644
--- a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/CborHelpers.netstandard.cs
+++ b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/CborHelpers.netstandard.cs
@@ -91,71 +91,27 @@ public static string BuildStringFromIndefiniteLengthTextString(int lengt
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ushort ReadHalfBigEndian(ReadOnlySpan source)
- {
- ushort value = BitConverter.IsLittleEndian ?
- BinaryPrimitives.ReverseEndianness(MemoryMarshal.Read(source)) :
- MemoryMarshal.Read(source);
-
- return value;
- }
+ => BinaryPrimitives.ReadUInt16BigEndian(source);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WriteHalfBigEndian(Span destination, ushort value)
- {
- if (BitConverter.IsLittleEndian)
- {
- ushort tmp = BinaryPrimitives.ReverseEndianness(value);
- MemoryMarshal.Write(destination, ref tmp);
- }
- else
- {
- MemoryMarshal.Write(destination, ref value);
- }
- }
+ => BinaryPrimitives.WriteUInt16BigEndian(destination, value);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float ReadSingleBigEndian(ReadOnlySpan source)
- {
- return BitConverter.IsLittleEndian ?
- Int32BitsToSingle(BinaryPrimitives.ReverseEndianness(MemoryMarshal.Read(source))) :
- MemoryMarshal.Read(source);
- }
+ => Int32BitsToSingle(BinaryPrimitives.ReadInt32BigEndian(source));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WriteSingleBigEndian(Span destination, float value)
- {
- if (BitConverter.IsLittleEndian)
- {
- int tmp = BinaryPrimitives.ReverseEndianness(SingleToInt32Bits(value));
- MemoryMarshal.Write(destination, ref tmp);
- }
- else
- {
- MemoryMarshal.Write(destination, ref value);
- }
- }
+ => BinaryPrimitives.WriteInt32BigEndian(destination, SingleToInt32Bits(value));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double ReadDoubleBigEndian(ReadOnlySpan source)
- {
- return BitConverter.IsLittleEndian ?
- BitConverter.Int64BitsToDouble(BinaryPrimitives.ReverseEndianness(MemoryMarshal.Read(source))) :
- MemoryMarshal.Read(source);
- }
+ => BitConverter.Int64BitsToDouble(BinaryPrimitives.ReadInt64BigEndian(source));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WriteDoubleBigEndian(Span destination, double value)
- {
- if (BitConverter.IsLittleEndian)
- {
- long tmp = BinaryPrimitives.ReverseEndianness(BitConverter.DoubleToInt64Bits(value));
- MemoryMarshal.Write(destination, ref tmp);
- }
- else
- {
- MemoryMarshal.Write(destination, ref value);
- }
- }
+ => BinaryPrimitives.WriteInt64BigEndian(destination, BitConverter.DoubleToInt64Bits(value));
internal static uint SingleToUInt32Bits(float value)
=> (uint)SingleToInt32Bits(value);
diff --git a/src/libraries/System.Net.Primitives/src/System/Net/IPAddress.cs b/src/libraries/System.Net.Primitives/src/System/Net/IPAddress.cs
index b53353cdf18edc..e093852350f318 100644
--- a/src/libraries/System.Net.Primitives/src/System/Net/IPAddress.cs
+++ b/src/libraries/System.Net.Primitives/src/System/Net/IPAddress.cs
@@ -183,7 +183,7 @@ public IPAddress(ReadOnlySpan address)
{
if (address.Length == IPAddressParserStatics.IPv4AddressBytes)
{
- PrivateAddress = MemoryMarshal.Read(address);
+ PrivateAddress = BitConverter.ToUInt32(address);
}
else if (address.Length == IPAddressParserStatics.IPv6AddressBytes)
{
@@ -721,10 +721,10 @@ public override int GetHashCode()
{
ReadOnlySpan numbers = MemoryMarshal.AsBytes(_numbers).Slice(0, 16);
_hashCode = HashCode.Combine(
- MemoryMarshal.Read(numbers),
- MemoryMarshal.Read(numbers.Slice(4)),
- MemoryMarshal.Read(numbers.Slice(8)),
- MemoryMarshal.Read(numbers.Slice(12)),
+ BitConverter.ToUInt32(numbers),
+ BitConverter.ToUInt32(numbers.Slice(4)),
+ BitConverter.ToUInt32(numbers.Slice(8)),
+ BitConverter.ToUInt32(numbers.Slice(12)),
_addressOrScopeId);
}
else
diff --git a/src/libraries/System.Private.CoreLib/src/Internal/Win32/RegistryKey.cs b/src/libraries/System.Private.CoreLib/src/Internal/Win32/RegistryKey.cs
index fd590c9e2ba7f1..a0557322279ecb 100644
--- a/src/libraries/System.Private.CoreLib/src/Internal/Win32/RegistryKey.cs
+++ b/src/libraries/System.Private.CoreLib/src/Internal/Win32/RegistryKey.cs
@@ -287,8 +287,8 @@ public string[] GetValueNames()
case Interop.Advapi32.RegistryValues.REG_QWORD:
return dataLength switch
{
- 4 => MemoryMarshal.Read(span),
- 8 => MemoryMarshal.Read(span),
+ 4 => BitConverter.ToInt32(span),
+ 8 => BitConverter.ToInt64(span),
_ => span.Slice(0, dataLength).ToArray(), // This shouldn't happen, but the previous implementation included it defensively.
};
diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipePayloadDecoder.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipePayloadDecoder.cs
index 661910025d8b1b..9def1dadecacfa 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipePayloadDecoder.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipePayloadDecoder.cs
@@ -55,12 +55,12 @@ internal static object[] DecodePayload(ref EventSource.EventMetadata metadata, R
}
else if (parameterType == typeof(byte) || enumType == typeof(byte))
{
- decodedFields[i] = MemoryMarshal.Read(payload);
+ decodedFields[i] = payload[0];
payload = payload.Slice(sizeof(byte));
}
else if (parameterType == typeof(sbyte) || enumType == typeof(sbyte))
{
- decodedFields[i] = MemoryMarshal.Read(payload);
+ decodedFields[i] = (sbyte)payload[0];
payload = payload.Slice(sizeof(sbyte));
}
else if (parameterType == typeof(short) || enumType == typeof(short))
diff --git a/src/libraries/System.Security.Cryptography.Cose/src/System.Security.Cryptography.Cose.csproj b/src/libraries/System.Security.Cryptography.Cose/src/System.Security.Cryptography.Cose.csproj
index b2b23ba884f621..b9951dd48a67b5 100644
--- a/src/libraries/System.Security.Cryptography.Cose/src/System.Security.Cryptography.Cose.csproj
+++ b/src/libraries/System.Security.Cryptography.Cose/src/System.Security.Cryptography.Cose.csproj
@@ -57,6 +57,7 @@
+
diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/HelpersWindows.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/HelpersWindows.cs
index a7127751bc5c11..109c39635f6c28 100644
--- a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/HelpersWindows.cs
+++ b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/HelpersWindows.cs
@@ -385,7 +385,7 @@ public static CspParameters GetProvParameters(this SafeProvOrNCryptKeyHandle han
throw new CryptographicException();
}
- int provType = MemoryMarshal.Read(stackSpan.Slice(0, size));
+ int provType = BitConverter.ToInt32(stackSpan.Slice(0, size));
size = stackSpan.Length;
if (!Interop.Advapi32.CryptGetProvParam(handle, CryptProvParam.PP_KEYSET_TYPE, stackSpan, ref size))
@@ -399,7 +399,7 @@ public static CspParameters GetProvParameters(this SafeProvOrNCryptKeyHandle han
throw new CryptographicException();
}
- int keysetType = MemoryMarshal.Read(stackSpan.Slice(0, size));
+ int keysetType = BitConverter.ToInt32(stackSpan.Slice(0, size));
// Only CRYPT_MACHINE_KEYSET is described as coming back, but be defensive.
CspProviderFlags provFlags =
diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System.Security.Cryptography.Pkcs.csproj b/src/libraries/System.Security.Cryptography.Pkcs/src/System.Security.Cryptography.Pkcs.csproj
index 19cc655555f692..a6d789e4ff0fc3 100644
--- a/src/libraries/System.Security.Cryptography.Pkcs/src/System.Security.Cryptography.Pkcs.csproj
+++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System.Security.Cryptography.Pkcs.csproj
@@ -712,6 +712,10 @@ System.Security.Cryptography.Pkcs.EnvelopedCms
+
+
+
+
diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCrlCache.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCrlCache.cs
index 1e69749ed681eb..d112569f31b54a 100644
--- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCrlCache.cs
+++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslCrlCache.cs
@@ -387,7 +387,7 @@ private static string GetCrlFileName(SafeX509Handle cert, string crlUrl)
throw new CryptographicException();
}
- uint urlHash = MemoryMarshal.Read(hash);
+ uint urlHash = BitConverter.ToUInt32(hash);
// OpenSSL's hashed filename algorithm is the 8-character hex version of the 32-bit value
// of X509_issuer_name_hash (or X509_subject_name_hash, depending on the context).
diff --git a/src/libraries/System.Text.Json/src/System.Text.Json.csproj b/src/libraries/System.Text.Json/src/System.Text.Json.csproj
index 687d263b4a3197..2f1a903683e201 100644
--- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj
+++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj
@@ -369,6 +369,7 @@ The System.Text.Json library is built-in as part of the shared framework in .NET
+
diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/PropertyRef.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/PropertyRef.cs
index aabcfdd2ee5f9f..1888c84cd3b218 100644
--- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/PropertyRef.cs
+++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/PropertyRef.cs
@@ -58,13 +58,13 @@ public static ulong GetKey(ReadOnlySpan name)
{
0 => 0,
1 => name[0],
- 2 => MemoryMarshal.Read(name),
- 3 => MemoryMarshal.Read(name) | ((ulong)name[2] << 16),
- 4 => MemoryMarshal.Read(name),
- 5 => MemoryMarshal.Read(name) | ((ulong)name[4] << 32),
- 6 => MemoryMarshal.Read(name) | ((ulong)MemoryMarshal.Read(name.Slice(4, 2)) << 32),
- 7 => MemoryMarshal.Read(name) | ((ulong)MemoryMarshal.Read(name.Slice(4, 2)) << 32) | ((ulong)name[6] << 48),
- _ => MemoryMarshal.Read(name) & 0x00ffffffffffffffUL
+ 2 => BitConverter.ToUInt16(name),
+ 3 => BitConverter.ToUInt16(name) | ((ulong)name[2] << 16),
+ 4 => BitConverter.ToUInt32(name),
+ 5 => BitConverter.ToUInt32(name) | ((ulong)name[4] << 32),
+ 6 => BitConverter.ToUInt32(name) | ((ulong)BitConverter.ToUInt16(name.Slice(4, 2)) << 32),
+ 7 => BitConverter.ToUInt32(name) | ((ulong)BitConverter.ToUInt16(name.Slice(4, 2)) << 32) | ((ulong)name[6] << 48),
+ _ => BitConverter.ToUInt64(name) & 0x00ffffffffffffffUL
};
#if DEBUG
// Verify key contains the embedded bytes as expected.