|
1 | | -using System.Diagnostics; |
| 1 | + |
2 | 2 | using System.Runtime.CompilerServices; |
3 | | -using System.Runtime.InteropServices; |
4 | 3 |
|
5 | 4 | namespace PngDecoder.Extension; |
6 | 5 | internal static class GenericHelper |
7 | 6 | { |
8 | | - [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)] |
9 | | - private static extern int memcmp(IntPtr a1, IntPtr a2, uint count); |
| 7 | + [MethodImpl(MethodImplOptions.AggressiveInlining)] |
| 8 | + internal static bool Equal(ReadOnlySpan<byte> data1, ReadOnlySpan<byte> data2) => |
| 9 | + data1.SequenceEqual(data2); |
10 | 10 |
|
11 | | - internal static unsafe bool Equal(byte[] data1, byte[] data2) |
12 | | - { |
13 | | - if (data1 is null || data2 is null || data1.Length != data2.Length) |
14 | | - return false; |
15 | | - |
16 | | - fixed (byte* p1 = data1, p2 = data2) |
17 | | - return memcmp((IntPtr)p1, (IntPtr)p2, (uint)data1.Length * sizeof(byte)) == 0; |
18 | | - } |
19 | | - |
20 | | - |
21 | | - internal static unsafe bool Equal(ReadOnlySpan<byte> data1, ReadOnlySpan<byte> data2) |
22 | | - { |
23 | | - if (data1.Length != data2.Length) |
24 | | - return false; |
25 | | - |
26 | | - fixed (byte* p1 = data1, p2 = data2) |
27 | | - return memcmp((IntPtr)p1, (IntPtr)p2, (uint)data1.Length * sizeof(byte)) == 0; |
28 | | - } |
29 | | - |
30 | | - |
31 | | - |
32 | | - internal static byte[] Tobytes(this ValueType @struct) |
33 | | - { |
34 | | - var result = new byte[Marshal.SizeOf(@struct)]; |
35 | | - Unsafe.As<byte, ValueType>(ref result[0]) = @struct; |
36 | | - return result; |
37 | | - } |
38 | | - |
39 | | - internal static T ToStruct<T>(this byte[] @bytes) where T : struct => |
40 | | - Unsafe.As<byte, T>(ref @bytes[0]); |
41 | 11 | internal static T ToStruct<T>(this Span<byte> @bytes) where T : struct => |
42 | 12 | Unsafe.As<byte, T>(ref @bytes[0]); |
43 | | - |
44 | | - internal static T FromStream<T>(this Stream stream, |
45 | | - long skip = 0, |
46 | | - SeekOrigin origin = SeekOrigin.Current) where T : struct |
47 | | - { |
48 | | - var size = Marshal.SizeOf(typeof(T)); |
49 | | - Span<byte> resultAsByte = stackalloc byte[size]; |
50 | | - stream.Seek(skip, origin); |
51 | | - |
52 | | - var read = stream.Read(resultAsByte); |
53 | | - Debug.Assert(read == size); |
54 | | - |
55 | | - return resultAsByte.ToStruct<T>(); |
56 | | - } |
57 | | - |
58 | | - internal static byte ReadByteNotMove(this Stream stream, long index) |
59 | | - { |
60 | | - var current = stream.Position; |
61 | | - |
62 | | - Span<byte> result = stackalloc byte[1]; |
63 | | - stream.Seek(index, SeekOrigin.Current); |
64 | | - stream.Read(result); |
65 | | - stream.Seek(current, SeekOrigin.Begin); |
66 | | - return result[0]; |
67 | | - } |
68 | 13 | } |
0 commit comments