forked from icsharpcode/SharpZipLib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ByteOrderUtils.cs
130 lines (103 loc) · 6.26 KB
/
ByteOrderUtils.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using CT = System.Threading.CancellationToken;
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable InconsistentNaming
namespace ICSharpCode.SharpZipLib.Core
{
internal static class ByteOrderStreamExtensions
{
internal static byte[] SwappedBytes(ushort value) => new[] {(byte)value, (byte)(value >> 8)};
internal static byte[] SwappedBytes(short value) => new[] {(byte)value, (byte)(value >> 8)};
internal static byte[] SwappedBytes(uint value) => new[] {(byte)value, (byte)(value >> 8), (byte)(value >> 16), (byte)(value >> 24)};
internal static byte[] SwappedBytes(int value) => new[] {(byte)value, (byte)(value >> 8), (byte)(value >> 16), (byte)(value >> 24)};
internal static byte[] SwappedBytes(long value) => new[] {
(byte)value, (byte)(value >> 8), (byte)(value >> 16), (byte)(value >> 24),
(byte)(value >> 32), (byte)(value >> 40), (byte)(value >> 48), (byte)(value >> 56)
};
internal static byte[] SwappedBytes(ulong value) => new[] {
(byte)value, (byte)(value >> 8), (byte)(value >> 16), (byte)(value >> 24),
(byte)(value >> 32), (byte)(value >> 40), (byte)(value >> 48), (byte)(value >> 56)
};
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static long SwappedS64(byte[] bytes) => (
(long)bytes[0] << 0 | (long)bytes[1] << 8 | (long)bytes[2] << 16 | (long)bytes[3] << 24 |
(long)bytes[4] << 32 | (long)bytes[5] << 40 | (long)bytes[6] << 48 | (long)bytes[7] << 56);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static ulong SwappedU64(byte[] bytes) => (
(ulong)bytes[0] << 0 | (ulong)bytes[1] << 8 | (ulong)bytes[2] << 16 | (ulong)bytes[3] << 24 |
(ulong)bytes[4] << 32 | (ulong)bytes[5] << 40 | (ulong)bytes[6] << 48 | (ulong)bytes[7] << 56);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static int SwappedS32(byte[] bytes) => bytes[0] | bytes[1] << 8 | bytes[2] << 16 | bytes[3] << 24;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static uint SwappedU32(byte[] bytes) => (uint) SwappedS32(bytes);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static short SwappedS16(byte[] bytes) => (short)(bytes[0] | bytes[1] << 8);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static ushort SwappedU16(byte[] bytes) => (ushort) SwappedS16(bytes);
internal static byte[] ReadBytes(this Stream stream, int count)
{
var bytes = new byte[count];
var remaining = count;
while (remaining > 0)
{
var bytesRead = stream.Read(bytes, count - remaining, remaining);
if (bytesRead < 1) throw new EndOfStreamException();
remaining -= bytesRead;
}
return bytes;
}
/// <summary> Read an unsigned short in little endian byte order. </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int ReadLEShort(this Stream stream) => SwappedS16(ReadBytes(stream, 2));
/// <summary> Read an int in little endian byte order. </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int ReadLEInt(this Stream stream) => SwappedS32(ReadBytes(stream, 4));
/// <summary> Read a long in little endian byte order. </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static long ReadLELong(this Stream stream) => SwappedS64(ReadBytes(stream, 8));
/// <summary> Write an unsigned short in little endian byte order. </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WriteLEShort(this Stream stream, int value) => stream.Write(SwappedBytes(value), 0, 2);
/// <inheritdoc cref="WriteLEShort"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static async Task WriteLEShortAsync(this Stream stream, int value, CT ct)
=> await stream.WriteAsync(SwappedBytes(value), 0, 2, ct).ConfigureAwait(false);
/// <summary> Write a ushort in little endian byte order. </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WriteLEUshort(this Stream stream, ushort value) => stream.Write(SwappedBytes(value), 0, 2);
/// <inheritdoc cref="WriteLEUshort"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static async Task WriteLEUshortAsync(this Stream stream, ushort value, CT ct)
=> await stream.WriteAsync(SwappedBytes(value), 0, 2, ct).ConfigureAwait(false);
/// <summary> Write an int in little endian byte order. </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WriteLEInt(this Stream stream, int value) => stream.Write(SwappedBytes(value), 0, 4);
/// <inheritdoc cref="WriteLEInt"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static async Task WriteLEIntAsync(this Stream stream, int value, CT ct)
=> await stream.WriteAsync(SwappedBytes(value), 0, 4, ct).ConfigureAwait(false);
/// <summary> Write a uint in little endian byte order. </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WriteLEUint(this Stream stream, uint value) => stream.Write(SwappedBytes(value), 0, 4);
/// <inheritdoc cref="WriteLEUint"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static async Task WriteLEUintAsync(this Stream stream, uint value, CT ct)
=> await stream.WriteAsync(SwappedBytes(value), 0, 4, ct).ConfigureAwait(false);
/// <summary> Write a long in little endian byte order. </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WriteLELong(this Stream stream, long value) => stream.Write(SwappedBytes(value), 0, 8);
/// <inheritdoc cref="WriteLELong"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static async Task WriteLELongAsync(this Stream stream, long value, CT ct)
=> await stream.WriteAsync(SwappedBytes(value), 0, 8, ct).ConfigureAwait(false);
/// <summary> Write a ulong in little endian byte order. </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WriteLEUlong(this Stream stream, ulong value) => stream.Write(SwappedBytes(value), 0, 8);
/// <inheritdoc cref="WriteLEUlong"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static async Task WriteLEUlongAsync(this Stream stream, ulong value, CT ct)
=> await stream.WriteAsync(SwappedBytes(value), 0, 8, ct).ConfigureAwait(false);
}
}