Skip to content
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
28 changes: 27 additions & 1 deletion BInaryKit-Test/EndianTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Iks.BinaryToolkit;
using System.Buffers.Binary;
using Iks.BinaryToolkit;
using Xunit.Abstractions;

namespace BinaryKit_Test;
Expand Down Expand Up @@ -34,5 +35,30 @@ public unsafe void Read_Struct()
output.WriteLine("actual: " + actual);
Assert.Equal(expected, actual);
}

#region Multiple-Test

[Fact]
public void ReverseManyTest()
{
Span<int> old = [10,20,30,40,50,60,70,80];
Span<int> expected = stackalloc int[old.Length];
for (var index = 0; index < old.Length; index++)
{
var item = old[index];
expected[index] = BinaryPrimitives.ReverseEndianness(item);
}

EndianToolkit.ReverseMany(old);
for (int i = 0; i < old.Length; i++)
{
if (old[i] != expected[i])
{
Assert.Fail();
}
}
}


#endregion
}
52 changes: 26 additions & 26 deletions BinaryToolKit/EndianToolkit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ namespace Iks.BinaryToolkit;
/// </summary>
public static class EndianToolkit
{
#region Single

/// <summary>
/// reverses the endianness of an unmanaged type(value).
/// </summary>
Expand Down Expand Up @@ -91,6 +93,7 @@ allows ref struct
/// converts the endianness of an unmanaged type(value) from one to another.
/// it cannot to make sure struct members are all in the same endian.it just reverses byte-endianness of the whole struct.
/// </summary>
/// <param name="value">target value</param>
/// <param name="from">source endian,can use local</param>
/// <param name="to">target endian,can use local</param>
public static void Convert<T>(scoped ref T value, Endianness from, Endianness to) where T : unmanaged
Expand All @@ -109,7 +112,9 @@ allows ref struct
Reverse(ref value);
}


#endregion


#region Multiple

/// <summary>
Expand Down Expand Up @@ -138,60 +143,55 @@ allows ref struct
{
throw new ArgumentException(ErrorMessage.Not_Supported_Type_With_Pointer, nameof(T));
}

//do not reverse
if(sizeof(T) ==1)return;
while (lenght-- > 0)
{
ReverseNoCheck(target);
target++;
}
}

/// <summary>
/// converts the endianness of multiple unmanaged type(value) from one to another.
/// </summary>
/// <param name="target">target position to reverse endianness</param>
/// <param name="from">source endian,can use local</param>
/// <param name="to">target endian,can use local</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe void ConvertMany<T>(Span<T> target, Endianness from, Endianness to) where T : unmanaged
{
fixed (T* ptr = &MemoryMarshal.GetReference(target))
{
ConvertMany(ptr, target.Length, from, to);
}
}

/// <summary>
/// converts the endianness of multiple unmanaged type(value) from one to another.
/// </summary>
/// <param name="target">target position to reverse endianness</param>
/// <param name="lenght">the number of ptr field</param>
/// <param name="from">source endian,can use local</param>
/// <param name="to">target endian,can use local</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe void ConvertMany<T>(T* target, int lenght, Endianness from, Endianness to) where T : unmanaged
#if NET9_0_OR_GREATER
,
// dotnet 8 not support by ref
allows ref struct
#endif
{
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
{
throw new ArgumentException(ErrorMessage.Not_Supported_Type_With_Pointer, nameof(T));
}

//process local
if (from is Endianness.Local) from = BitConverter.IsLittleEndian ? Endianness.Little : Endianness.Big;
if (to is Endianness.Local) to = BitConverter.IsLittleEndian ? Endianness.Little : Endianness.Big;
// same,do nothing
if (from == to) return;
// differ, reverse
while (lenght-- > 0)
{
ReverseNoCheck(target);
target++;
}
ReverseMany(target, lenght);
}

/// <summary>
/// converts the endianness of multiple unmanaged type(value) from one to another.
/// </summary>
/// <param name="target">target position to reverse endianness</param>
/// <param name="from">source endian,can use local</param>
/// <param name="to">target endian,can use local</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe void ConvertMany<T>(Span<T> target, Endianness from, Endianness to) where T : unmanaged
{
fixed (T* ptr = &MemoryMarshal.GetReference(target))
{
ConvertMany(ptr, target.Length, from, to);
}
}


#endregion
}
Expand Down