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 0a0b502728f9c4..cba3c974bf0abd 100644
--- a/src/libraries/System.Formats.Cbor/src/System.Formats.Cbor.csproj
+++ b/src/libraries/System.Formats.Cbor/src/System.Formats.Cbor.csproj
@@ -36,17 +36,16 @@ 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.cs
similarity index 55%
rename from src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/CborHelpers.netstandard.cs
rename to src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/CborHelpers.cs
index adb2eb362c0308..bcfdd1e76526c7 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.cs
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Buffers;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Diagnostics;
@@ -11,12 +12,20 @@
namespace System.Formats.Cbor
{
- internal static partial class CborHelpers
+ internal static class CborHelpers
{
+#if NET
+ public static readonly DateTimeOffset UnixEpoch = DateTimeOffset.UnixEpoch;
+#else
private const long UnixEpochTicks = 719162L /*Number of days from 1/1/0001 to 12/31/1969*/ * 10000 * 1000 * 60 * 60 * 24; /* Ticks per day.*/
public static readonly DateTimeOffset UnixEpoch = new DateTimeOffset(UnixEpochTicks, TimeSpan.Zero);
+#endif
+#if NET
+ public static BigInteger CreateBigIntegerFromUnsignedBigEndianBytes(byte[] bytes)
+ => new BigInteger(bytes, isUnsigned: true, isBigEndian: true);
+#else
public static BigInteger CreateBigIntegerFromUnsignedBigEndianBytes(byte[] bigEndianBytes)
{
if (bigEndianBytes.Length == 0)
@@ -44,7 +53,12 @@ public static BigInteger CreateBigIntegerFromUnsignedBigEndianBytes(byte[] bigEn
return new BigInteger(temp);
}
+#endif
+#if NET
+ public static byte[] CreateUnsignedBigEndianBytesFromBigInteger(BigInteger value)
+ => value.ToByteArray(isUnsigned: true, isBigEndian: true);
+#else
public static byte[] CreateUnsignedBigEndianBytesFromBigInteger(BigInteger value)
{
byte[] littleEndianBytes = value.ToByteArray();
@@ -74,12 +88,22 @@ public static byte[] CreateUnsignedBigEndianBytesFromBigInteger(BigInteger value
return start == 0 ? littleEndianBytes : bytesAsSpan.Slice(start).ToArray();
}
+#endif
+#if NET
+ public static void GetBitsFromDecimal(decimal d, Span destination)
+ => decimal.GetBits(d, destination);
+#else
public static void GetBitsFromDecimal(decimal d, Span destination)
{
decimal.GetBits(d).CopyTo(destination);
}
+#endif
+#if NET
+ public static string BuildStringFromIndefiniteLengthTextString(int length, TState state, SpanAction action)
+ => string.Create(length, state, action);
+#else
public delegate void SpanAction(Span span, TArg arg);
public static string BuildStringFromIndefiniteLengthTextString(int length, TState state, SpanAction action)
@@ -88,87 +112,71 @@ public static string BuildStringFromIndefiniteLengthTextString(int lengt
action(arr, state);
return new string(arr);
}
+#endif
+#if NET
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Half ReadHalfBigEndian(ReadOnlySpan source)
+ => BinaryPrimitives.ReadHalfBigEndian(source);
+#else
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ushort ReadHalfBigEndian(ReadOnlySpan source)
{
- ushort value = BitConverter.IsLittleEndian ?
- BinaryPrimitives.ReverseEndianness(MemoryMarshal.Read(source)) :
- MemoryMarshal.Read(source);
-
- return value;
+ return BinaryPrimitives.ReadUInt16BigEndian(source);
}
+#endif
+ }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void WriteHalfBigEndian(Span destination, ushort value)
+#if !NET
+ internal static class BinaryPrimitivesPolyfills
+ {
+ extension(BinaryPrimitives)
{
- if (BitConverter.IsLittleEndian)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static double ReadDoubleBigEndian(ReadOnlySpan source)
{
- ushort tmp = BinaryPrimitives.ReverseEndianness(value);
- MemoryMarshal.Write(destination, ref tmp);
+ return BitConverter.Int64BitsToDouble(BinaryPrimitives.ReadInt64BigEndian(source));
}
- else
- {
- MemoryMarshal.Write(destination, ref value);
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float ReadSingleBigEndian(ReadOnlySpan source)
- {
- return BitConverter.IsLittleEndian ?
- Int32BitsToSingle(BinaryPrimitives.ReverseEndianness(MemoryMarshal.Read(source))) :
- MemoryMarshal.Read(source);
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void WriteSingleBigEndian(Span destination, float value)
- {
- if (BitConverter.IsLittleEndian)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void WriteDoubleBigEndian(Span destination, double value)
{
- int tmp = BinaryPrimitives.ReverseEndianness(SingleToInt32Bits(value));
- MemoryMarshal.Write(destination, ref tmp);
+ BinaryPrimitives.WriteInt64BigEndian(destination, BitConverter.DoubleToInt64Bits(value));
}
- else
- {
- MemoryMarshal.Write(destination, ref value);
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double ReadDoubleBigEndian(ReadOnlySpan source)
- {
- return BitConverter.IsLittleEndian ?
- BitConverter.Int64BitsToDouble(BinaryPrimitives.ReverseEndianness(MemoryMarshal.Read(source))) :
- MemoryMarshal.Read(source);
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void WriteDoubleBigEndian(Span destination, double value)
- {
- if (BitConverter.IsLittleEndian)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static unsafe float ReadSingleBigEndian(ReadOnlySpan source)
{
- long tmp = BinaryPrimitives.ReverseEndianness(BitConverter.DoubleToInt64Bits(value));
- MemoryMarshal.Write(destination, ref tmp);
+ int intValue = BinaryPrimitives.ReadInt32BigEndian(source);
+ return *((float*)&intValue);
}
- else
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static unsafe void WriteSingleBigEndian(Span destination, float value)
{
- MemoryMarshal.Write(destination, ref value);
+ BinaryPrimitives.WriteInt32BigEndian(destination, *((int*)&value));
}
}
+ }
- internal static uint SingleToUInt32Bits(float value)
- => (uint)SingleToInt32Bits(value);
+ internal static class BitConverterPolyfills
+ {
+ extension(BitConverter)
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static unsafe int SingleToInt32Bits(float value) => *((int*)&value);
- internal static unsafe int SingleToInt32Bits(float value)
- => *((int*)&value);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static unsafe float Int32BitsToSingle(int value) => *((float*)&value);
- internal static float UInt32BitsToSingle(uint value)
- => Int32BitsToSingle((int)value);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static uint SingleToUInt32Bits(float value) => unchecked((uint)BitConverter.SingleToInt32Bits(value));
- internal static unsafe float Int32BitsToSingle(int value)
- => *((float*)&value);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float UInt32BitsToSingle(uint value) => BitConverter.Int32BitsToSingle((int)value);
+ }
}
+#endif
internal static class StackExtensions
{
diff --git a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/CborHelpers.netcoreapp.cs b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/CborHelpers.netcoreapp.cs
deleted file mode 100644
index 95dc9bde882ba4..00000000000000
--- a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/CborHelpers.netcoreapp.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Buffers;
-using System.Buffers.Binary;
-using System.Numerics;
-using System.Runtime.CompilerServices;
-
-namespace System.Formats.Cbor
-{
- internal static partial class CborHelpers
- {
- public static readonly DateTimeOffset UnixEpoch = DateTimeOffset.UnixEpoch;
-
- public static BigInteger CreateBigIntegerFromUnsignedBigEndianBytes(byte[] bytes)
- => new BigInteger(bytes, isUnsigned: true, isBigEndian: true);
-
- public static byte[] CreateUnsignedBigEndianBytesFromBigInteger(BigInteger value)
- => value.ToByteArray(isUnsigned: true, isBigEndian: true);
-
- public static void GetBitsFromDecimal(decimal d, Span destination)
- => decimal.GetBits(d, destination);
-
- public static string BuildStringFromIndefiniteLengthTextString(int length, TState state, SpanAction action)
- => string.Create(length, state, action);
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Half ReadHalfBigEndian(ReadOnlySpan source)
- => BinaryPrimitives.ReadHalfBigEndian(source);
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static unsafe float ReadSingleBigEndian(ReadOnlySpan source)
- => BinaryPrimitives.ReadSingleBigEndian(source);
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double ReadDoubleBigEndian(ReadOnlySpan source)
- => BinaryPrimitives.ReadDoubleBigEndian(source);
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static unsafe void WriteSingleBigEndian(Span destination, float value)
- => BinaryPrimitives.WriteSingleBigEndian(destination, value);
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static unsafe void WriteDoubleBigEndian(Span destination, double value)
- => BinaryPrimitives.WriteDoubleBigEndian(destination, value);
- }
-}
diff --git a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/HalfHelpers.netstandard.cs b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/HalfHelpers.netstandard.cs
index c4d191be9ad54c..890fa148e9fd79 100644
--- a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/HalfHelpers.netstandard.cs
+++ b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/HalfHelpers.netstandard.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// 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.CompilerServices;
@@ -53,7 +53,7 @@ public static float HalfToFloat(ushort value)
{
if (sig == 0)
{
- return CborHelpers.UInt32BitsToSingle(sign ? FloatSignMask : 0); // Positive / Negative zero
+ return BitConverter.UInt32BitsToSingle(sign ? FloatSignMask : 0); // Positive / Negative zero
}
(exp, sig) = NormSubnormalF16Sig(sig);
exp -= 1;
@@ -62,7 +62,7 @@ public static float HalfToFloat(ushort value)
return CreateSingle(sign, (byte)(exp + 0x70), sig << 13);
static float CreateSingle(bool sign, byte exp, uint sig)
- => CborHelpers.Int32BitsToSingle((int)(((sign ? 1U : 0U) << FloatSignShift) + ((uint)exp << FloatExponentShift) + sig));
+ => BitConverter.Int32BitsToSingle((int)(((sign ? 1U : 0U) << FloatSignShift) + ((uint)exp << FloatExponentShift) + sig));
}
public static bool HalfIsNaN(ushort value)
@@ -119,7 +119,7 @@ private static float CreateSingleNaN(bool sign, ulong significand)
uint signInt = (sign ? 1U : 0U) << FloatSignShift;
uint sigInt = (uint)(significand >> 41);
- return CborHelpers.UInt32BitsToSingle(signInt | NaNBits | sigInt);
+ return BitConverter.UInt32BitsToSingle(signInt | NaNBits | sigInt);
}
#endregion
@@ -128,7 +128,7 @@ public static ushort FloatToHalf(float value)
{
const int SingleMaxExponent = 0xFF;
- uint floatInt = CborHelpers.SingleToUInt32Bits(value);
+ uint floatInt = BitConverter.SingleToUInt32Bits(value);
bool sign = (floatInt & FloatSignMask) >> FloatSignShift != 0;
int exp = (int)(floatInt & FloatExponentMask) >> FloatExponentShift;
uint sig = floatInt & FloatSignificandMask;
diff --git a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Reader/CborReader.Simple.cs b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Reader/CborReader.Simple.cs
index 228ae0bb78d9d4..ec115bc980b555 100644
--- a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Reader/CborReader.Simple.cs
+++ b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Reader/CborReader.Simple.cs
@@ -36,7 +36,7 @@ public float ReadSingle()
case CborAdditionalInfo.Additional32BitData:
EnsureReadCapacity(buffer, 1 + sizeof(float));
- result = CborHelpers.ReadSingleBigEndian(buffer.Slice(1));
+ result = BinaryPrimitives.ReadSingleBigEndian(buffer.Slice(1));
AdvanceBuffer(1 + sizeof(float));
AdvanceDataItemCounters();
return result;
@@ -77,14 +77,14 @@ public double ReadDouble()
case CborAdditionalInfo.Additional32BitData:
EnsureReadCapacity(buffer, 1 + sizeof(float));
- result = CborHelpers.ReadSingleBigEndian(buffer.Slice(1));
+ result = BinaryPrimitives.ReadSingleBigEndian(buffer.Slice(1));
AdvanceBuffer(1 + sizeof(float));
AdvanceDataItemCounters();
return result;
case CborAdditionalInfo.Additional64BitData:
EnsureReadCapacity(buffer, 1 + sizeof(double));
- result = CborHelpers.ReadDoubleBigEndian(buffer.Slice(1));
+ result = BinaryPrimitives.ReadDoubleBigEndian(buffer.Slice(1));
AdvanceBuffer(1 + sizeof(double));
AdvanceDataItemCounters();
return result;
diff --git a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Writer/CborWriter.Simple.cs b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Writer/CborWriter.Simple.cs
index 1b7e8dd00074be..72345928dc2d0f 100644
--- a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Writer/CborWriter.Simple.cs
+++ b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Writer/CborWriter.Simple.cs
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Buffers.Binary;
using System.Runtime.CompilerServices;
namespace System.Formats.Cbor
@@ -63,7 +64,7 @@ private void WriteSingleCore(float value)
{
EnsureWriteCapacity(1 + sizeof(float));
WriteInitialByte(new CborInitialByte(CborMajorType.Simple, CborAdditionalInfo.Additional32BitData));
- CborHelpers.WriteSingleBigEndian(_buffer.AsSpan(_offset), value);
+ BinaryPrimitives.WriteSingleBigEndian(_buffer.AsSpan(_offset), value);
_offset += sizeof(float);
AdvanceDataItemCounters();
}
@@ -72,7 +73,7 @@ private void WriteDoubleCore(double value)
{
EnsureWriteCapacity(1 + sizeof(double));
WriteInitialByte(new CborInitialByte(CborMajorType.Simple, CborAdditionalInfo.Additional64BitData));
- CborHelpers.WriteDoubleBigEndian(_buffer.AsSpan(_offset), value);
+ BinaryPrimitives.WriteDoubleBigEndian(_buffer.AsSpan(_offset), value);
_offset += sizeof(double);
AdvanceDataItemCounters();
}
diff --git a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Writer/CborWriter.Simple.netstandard.cs b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Writer/CborWriter.Simple.netstandard.cs
index f257ce1f4b4e02..86ccde95d03984 100644
--- a/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Writer/CborWriter.Simple.netstandard.cs
+++ b/src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Writer/CborWriter.Simple.netstandard.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Buffers.Binary;
@@ -27,7 +27,7 @@ private void WriteHalf(ushort value)
}
else
{
- CborHelpers.WriteHalfBigEndian(_buffer.AsSpan(_offset), value);
+ BinaryPrimitives.WriteUInt16BigEndian(_buffer.AsSpan(_offset), value);
}
_offset += sizeof(ushort);
AdvanceDataItemCounters();
@@ -37,7 +37,7 @@ private void WriteHalf(ushort value)
internal static bool TryConvertSingleToHalf(float value, out ushort result)
{
result = HalfHelpers.FloatToHalf(value);
- return float.IsNaN(value) || CborHelpers.SingleToInt32Bits(HalfHelpers.HalfToFloat(result)) == CborHelpers.SingleToInt32Bits(value);
+ return float.IsNaN(value) || BitConverter.SingleToInt32Bits(HalfHelpers.HalfToFloat(result)) == BitConverter.SingleToInt32Bits(value);
}
}
}
diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BlobUtilities.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BlobUtilities.cs
index 56d5dacd85d352..212c42c17ef952 100644
--- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BlobUtilities.cs
+++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BlobUtilities.cs
@@ -21,19 +21,16 @@ public static void WriteBytes(this byte[] buffer, int start, byte value, int byt
public static void WriteDouble(this byte[] buffer, int start, double value)
{
#if NET
- WriteUInt64(buffer, start, BitConverter.DoubleToUInt64Bits(value));
+ BinaryPrimitives.WriteDoubleLittleEndian(buffer.AsSpan(start), value);
#else
- unsafe
- {
- WriteUInt64(buffer, start, *(ulong*)&value);
- }
+ WriteUInt64(buffer, start, unchecked((ulong)BitConverter.DoubleToInt64Bits(value)));
#endif
}
public static void WriteSingle(this byte[] buffer, int start, float value)
{
#if NET
- WriteUInt32(buffer, start, BitConverter.SingleToUInt32Bits(value));
+ BinaryPrimitives.WriteSingleLittleEndian(buffer.AsSpan(start), value);
#else
unsafe
{
@@ -49,19 +46,19 @@ public static void WriteByte(this byte[] buffer, int start, byte value)
}
public static void WriteUInt16(this byte[] buffer, int start, ushort value) =>
- Unsafe.WriteUnaligned(ref buffer[start], !BitConverter.IsLittleEndian ? BinaryPrimitives.ReverseEndianness(value) : value);
+ BinaryPrimitives.WriteUInt16LittleEndian(buffer.AsSpan(start), value);
public static void WriteUInt16BE(this byte[] buffer, int start, ushort value) =>
- Unsafe.WriteUnaligned(ref buffer[start], BitConverter.IsLittleEndian ? BinaryPrimitives.ReverseEndianness(value) : value);
+ BinaryPrimitives.WriteUInt16BigEndian(buffer.AsSpan(start), value);
public static void WriteUInt32BE(this byte[] buffer, int start, uint value) =>
- Unsafe.WriteUnaligned(ref buffer[start], BitConverter.IsLittleEndian ? BinaryPrimitives.ReverseEndianness(value) : value);
+ BinaryPrimitives.WriteUInt32BigEndian(buffer.AsSpan(start), value);
public static void WriteUInt32(this byte[] buffer, int start, uint value) =>
- Unsafe.WriteUnaligned(ref buffer[start], !BitConverter.IsLittleEndian ? BinaryPrimitives.ReverseEndianness(value) : value);
+ BinaryPrimitives.WriteUInt32LittleEndian(buffer.AsSpan(start), value);
public static void WriteUInt64(this byte[] buffer, int start, ulong value) =>
- Unsafe.WriteUnaligned(ref buffer[start], !BitConverter.IsLittleEndian ? BinaryPrimitives.ReverseEndianness(value) : value);
+ BinaryPrimitives.WriteUInt64LittleEndian(buffer.AsSpan(start), value);
public const int SizeOfSerializedDecimal = sizeof(byte) + 3 * sizeof(uint);