Closed
Description
Background and motivation
BinaryPrimitives today exposes a ReverseEndianness method for byte, ushort, uint, ulong, sbyte, short, int, and long, and #72107 proposes adding overloads for nuint, UInt128, nint, and Int128 as well. However, we lack versions of this API for processing multiple elements at a time. A developer can write this in their own loop, e.g.
- https://github.com/dorssel/usbipd-win/blob/2f7cbb732889ed00617e85f2f0b22239e8533960/Usbipd/Interop/UsbIp.cs#L165-L171
- https://github.com/HaveIBeenPwned/PwnedPasswordsAzureFunction/blob/0f81f2258f8f1f8f8486adf0820b141a43be396e/Shared/HaveIBeenPwned.PwnedPasswords.Shared/MD4.cs#L51-L55
- https://github.com/ratbuddy/ratbuddyssey/blob/65166ec837abc2ad78e2b2f239e8b1eb26aaaeef/Ratbuddyssey/AudysseyMultEQAvrTcpClientWithTimeout.cs#L51-L55
- https://github.com/saucecontrol/PhotoSauce/blob/d2555900c980c38a521e6381fc9b7a52dea66e3c/src/MagicScaler/Metadata/ExifReader.cs#L72-L73
- https://github.com/mono/mono/blob/b40e9939a7d07b30a75625692874f02bcc9be18f/mcs/class/referencesource/mscorlib/system/io/binaryreader.cs#L249-L250
- https://github.com/couchbase/couchbase-net-client/blob/4a755f449d2c4b37a4a44ba7107f2ba7a8594d80/src/Couchbase/Core/IO/Operations/Hello.cs#L59-L63
- https://github.com/Nenkai/PDTools/blob/2a9a5963f3754a029dfe0287aaddf8cbd804c763/PDTools.Files/Textures/TextureSet3.cs#L67-L68
- https://github.com/Nenkai/GTToolsSharp/blob/c33dbdb53e905be5b4b31a6575595749d5533a73/GTToolsSharp/Encryption/GT5POldCrypto.cs#L51-L52
- [API Proposal] Expose missing BinaryPrimitives APIs #72107 (comment)
runtime/src/libraries/System.Net.Primitives/src/System/Net/IPAddress.cs
Lines 294 to 306 in 8ceb8f8
but it'd be nice if a) they didn't have to, and b) it could be vectorized (for at least some data types).
API Proposal
namespace System.Buffers.Binary;
public static class BinaryPrimitives
{
+ public static void ReverseEndianness(ReadOnlySpan<ushort> source, Span<ushort> destination);
+ public static void ReverseEndianness(ReadOnlySpan<short> source, Span<short> destination);
+ public static void ReverseEndianness(ReadOnlySpan<uint> source, Span<uint> destination);
+ public static void ReverseEndianness(ReadOnlySpan<int> source, Span<int> destination);
+ public static void ReverseEndianness(ReadOnlySpan<ulong> source, Span<ulong> destination);
+ public static void ReverseEndianness(ReadOnlySpan<long> source, Span<long> destination);
+ public static void ReverseEndianness(ReadOnlySpan<nuint> source, Span<nuint> destination);
+ public static void ReverseEndianness(ReadOnlySpan<nint> source, Span<nint> destination);
+ public static void ReverseEndianness(ReadOnlySpan<UInt128> source, Span<UInt128> destination);
+ public static void ReverseEndianness(ReadOnlySpan<Int128> source, Span<Int128> destination);
}
source
and destination
may be the same.
I did not include overloads for byte/sbyte as they're useless (the current byte/sbyte overloads are useless, too).
API Usage
Span<uint> values = ...;
BinaryPrimitives.ReverseEndianness(values);
Alternative Designs
- Instead of taking a source and a destination span, each overload could instead just take a
Span<T>
that's reversed in-place, and if you need the results in a different location, you first copy and then reverse in-place in the destination.
Risks
No response