|
1 | 1 | using System;
|
2 | 2 | using System.Buffers.Binary;
|
3 | 3 | using System.Linq;
|
| 4 | +using System.Runtime.CompilerServices; |
4 | 5 | using System.Runtime.InteropServices;
|
5 | 6 |
|
6 | 7 | namespace RabbitMQ.Util
|
7 | 8 | {
|
8 | 9 | internal static class NetworkOrderDeserializer
|
9 | 10 | {
|
10 |
| - internal static double ReadDouble(Memory<byte> memory, int offset = 0) |
| 11 | + internal static double ReadDouble(ReadOnlyMemory<byte> memory) => ReadDouble(memory.Span); |
| 12 | + |
| 13 | + internal static double ReadDouble(ReadOnlySpan<byte> span) |
11 | 14 | {
|
12 |
| - if (memory.Length - offset < 8) |
| 15 | + if (span.Length < 8) |
13 | 16 | {
|
14 |
| - throw new ArgumentOutOfRangeException(nameof(memory), "Insufficient length to decode Double from memory."); |
| 17 | + throw new ArgumentOutOfRangeException(nameof(span), "Insufficient length to decode Double from memory."); |
15 | 18 | }
|
16 | 19 |
|
17 |
| - long val = BinaryPrimitives.ReadInt64BigEndian((offset > 0 ? memory.Slice(offset) : memory).Span); |
18 |
| - return BitConverter.Int64BitsToDouble(val); |
| 20 | + long val = BinaryPrimitives.ReadInt64BigEndian(span); |
| 21 | + return Unsafe.As<long, double>(ref val); |
19 | 22 | }
|
20 | 23 |
|
21 |
| - internal static short ReadInt16(Memory<byte> memory, int offset = 0) |
| 24 | + internal static short ReadInt16(ReadOnlyMemory<byte> memory) => ReadInt16(memory.Span); |
| 25 | + |
| 26 | + internal static short ReadInt16(ReadOnlySpan<byte> span) |
22 | 27 | {
|
23 |
| - if (memory.Length - offset < 2) |
| 28 | + if (span.Length < 2) |
24 | 29 | {
|
25 |
| - throw new ArgumentOutOfRangeException(nameof(memory), "Insufficient length to decode Int16 from memory."); |
| 30 | + throw new ArgumentOutOfRangeException(nameof(span), "Insufficient length to decode Int16 from memory."); |
26 | 31 | }
|
27 | 32 |
|
28 |
| - return BinaryPrimitives.ReadInt16BigEndian((offset > 0 ? memory.Slice(offset) : memory).Span); |
| 33 | + return BinaryPrimitives.ReadInt16BigEndian(span); |
29 | 34 | }
|
30 | 35 |
|
31 |
| - internal static int ReadInt32(Memory<byte> memory, int offset = 0) |
| 36 | + internal static int ReadInt32(ReadOnlyMemory<byte> memory) => ReadInt32(memory.Span); |
| 37 | + |
| 38 | + internal static int ReadInt32(ReadOnlySpan<byte> span) |
32 | 39 | {
|
33 |
| - if (memory.Length - offset < 4) |
| 40 | + if (span.Length < 4) |
34 | 41 | {
|
35 |
| - throw new ArgumentOutOfRangeException(nameof(memory), "Insufficient length to decode Int32 from memory."); |
| 42 | + throw new ArgumentOutOfRangeException(nameof(span), "Insufficient length to decode Int32 from memory."); |
36 | 43 | }
|
37 | 44 |
|
38 |
| - return BinaryPrimitives.ReadInt32BigEndian((offset > 0 ? memory.Slice(offset) : memory).Span); |
| 45 | + return BinaryPrimitives.ReadInt32BigEndian(span); |
39 | 46 | }
|
40 | 47 |
|
41 |
| - internal static long ReadInt64(Memory<byte> memory, int offset = 0) |
| 48 | + internal static long ReadInt64(ReadOnlyMemory<byte> memory) => ReadInt64(memory.Span); |
| 49 | + |
| 50 | + internal static long ReadInt64(ReadOnlySpan<byte> span) |
42 | 51 | {
|
43 |
| - if (memory.Length - offset < 8) |
| 52 | + if (span.Length < 8) |
44 | 53 | {
|
45 |
| - throw new ArgumentOutOfRangeException(nameof(memory), "Insufficient length to decode Int64 from memory."); |
| 54 | + throw new ArgumentOutOfRangeException(nameof(span), "Insufficient length to decode Int64 from memory."); |
46 | 55 | }
|
47 | 56 |
|
48 |
| - return BinaryPrimitives.ReadInt64BigEndian((offset > 0 ? memory.Slice(offset) : memory).Span); |
| 57 | + return BinaryPrimitives.ReadInt64BigEndian(span); |
49 | 58 | }
|
50 | 59 |
|
51 |
| - internal static float ReadSingle(Memory<byte> memory, int offset = 0) |
52 |
| - { |
53 |
| - if (memory.Length - offset < 4) |
54 |
| - { |
55 |
| - throw new ArgumentOutOfRangeException(nameof(memory), "Insufficient length to decode Single from memory."); |
56 |
| - } |
57 |
| - |
58 |
| - Memory<byte> bytes = memory.Slice(offset, 4); |
59 |
| - if (BitConverter.IsLittleEndian) |
60 |
| - { |
61 |
| - bytes.Span.Reverse(); |
62 |
| - } |
| 60 | + internal static float ReadSingle(ReadOnlyMemory<byte> memory) => ReadSingle(memory.Span); |
63 | 61 |
|
64 |
| - if (MemoryMarshal.TryGetArray(bytes, out ArraySegment<byte> segment)) |
| 62 | + internal static float ReadSingle(ReadOnlySpan<byte> span) |
| 63 | + { |
| 64 | + if (span.Length < 4) |
65 | 65 | {
|
66 |
| - return BitConverter.ToSingle(segment.Array, segment.Offset); |
| 66 | + throw new ArgumentOutOfRangeException(nameof(span), "Insufficient length to decode Single from memory."); |
67 | 67 | }
|
68 | 68 |
|
69 |
| - throw new InvalidOperationException("Unable to get ArraySegment from memory."); |
| 69 | + int num = BinaryPrimitives.ReadInt32BigEndian(span); |
| 70 | + return Unsafe.As<int, float>(ref num); |
70 | 71 | }
|
71 | 72 |
|
72 |
| - internal static ushort ReadUInt16(Memory<byte> memory, int offset = 0) |
| 73 | + internal static ushort ReadUInt16(Memory<byte> memory) => ReadUInt16(memory.Span); |
| 74 | + |
| 75 | + internal static ushort ReadUInt16(ReadOnlySpan<byte> span) |
73 | 76 | {
|
74 |
| - if (memory.Length - offset < 2) |
| 77 | + if (span.Length < 2) |
75 | 78 | {
|
76 |
| - throw new ArgumentOutOfRangeException(nameof(memory), "Insufficient length to decode UInt16 from memory."); |
| 79 | + throw new ArgumentOutOfRangeException(nameof(span), "Insufficient length to decode UInt16 from memory."); |
77 | 80 | }
|
78 | 81 |
|
79 |
| - return BinaryPrimitives.ReadUInt16BigEndian((offset > 0 ? memory.Slice(offset) : memory).Span); |
| 82 | + return BinaryPrimitives.ReadUInt16BigEndian(span); |
80 | 83 | }
|
81 | 84 |
|
82 |
| - internal static uint ReadUInt32(Memory<byte> memory, int offset = 0) |
| 85 | + internal static uint ReadUInt32(Memory<byte> memory) => ReadUInt32(memory.Span); |
| 86 | + |
| 87 | + internal static uint ReadUInt32(ReadOnlySpan<byte> span) |
83 | 88 | {
|
84 |
| - if (memory.Length - offset < 4) |
| 89 | + if (span.Length < 4) |
85 | 90 | {
|
86 |
| - throw new ArgumentOutOfRangeException(nameof(memory), "Insufficient length to decode UInt32 from memory."); |
| 91 | + throw new ArgumentOutOfRangeException(nameof(span), "Insufficient length to decode UInt32 from memory."); |
87 | 92 | }
|
88 | 93 |
|
89 |
| - return BinaryPrimitives.ReadUInt32BigEndian((offset > 0 ? memory.Slice(offset) : memory).Span); |
| 94 | + return BinaryPrimitives.ReadUInt32BigEndian(span); |
90 | 95 | }
|
91 | 96 |
|
92 |
| - internal static ulong ReadUInt64(Memory<byte> memory, int offset = 0) |
| 97 | + internal static ulong ReadUInt64(Memory<byte> memory) => ReadUInt64(memory.Span); |
| 98 | + |
| 99 | + internal static ulong ReadUInt64(ReadOnlySpan<byte> span) |
93 | 100 | {
|
94 |
| - if (memory.Length - offset < 8) |
| 101 | + if (span.Length < 8) |
95 | 102 | {
|
96 |
| - throw new ArgumentOutOfRangeException(nameof(memory), "Insufficient length to decode UInt64 from memory."); |
| 103 | + throw new ArgumentOutOfRangeException(nameof(span), "Insufficient length to decode UInt64 from memory."); |
97 | 104 | }
|
98 | 105 |
|
99 |
| - return BinaryPrimitives.ReadUInt64BigEndian((offset > 0 ? memory.Slice(offset) : memory).Span); |
| 106 | + return BinaryPrimitives.ReadUInt64BigEndian(span); |
100 | 107 | }
|
101 | 108 | }
|
102 | 109 | }
|
0 commit comments