Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c0f7e53

Browse files
committed
Added BigEndianBitConverter and LittleEndianBitConverter.
1 parent 8f6bd41 commit c0f7e53

File tree

8 files changed

+420
-0
lines changed

8 files changed

+420
-0
lines changed

‎ReClass.NET/ReClass.NET.csproj‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,9 @@
394394
<Compile Include="Util\BitString.cs" />
395395
<Compile Include="Util\CircularBuffer.cs" />
396396
<Compile Include="Util\CommandLineArgs.cs" />
397+
<Compile Include="Util\Conversion\BigEndianBitConverter.cs" />
398+
<Compile Include="Util\Conversion\EndianBitConverter.cs" />
399+
<Compile Include="Util\Conversion\LittleEndianBitConverter.cs" />
397400
<Compile Include="Util\CustomDataMap.cs" />
398401
<Compile Include="Extensions\BinaryReaderWriterExtensions.cs" />
399402
<Compile Include="Extensions\ColorExtensions.cs" />
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
3+
namespace ReClassNET.Util.Conversion
4+
{
5+
public sealed class BigEndianBitConverter : EndianBitConverter
6+
{
7+
protected override long FromBytes(byte[] buffer, int index, int bytesToConvert)
8+
{
9+
if (buffer == null)
10+
{
11+
throw new ArgumentNullException(nameof(buffer));
12+
}
13+
if (index + bytesToConvert > buffer.Length)
14+
{
15+
throw new ArgumentOutOfRangeException(nameof(index));
16+
}
17+
18+
long ret = 0;
19+
for (var i = 0; i < bytesToConvert; i++)
20+
{
21+
ret = unchecked((ret << 8) | buffer[index + i]);
22+
}
23+
return ret;
24+
}
25+
26+
protected override byte[] ToBytes(long value, int bytes)
27+
{
28+
var endOffset = bytes - 1;
29+
30+
var buffer = new byte[bytes];
31+
for (var i = 0; i < bytes; i++)
32+
{
33+
buffer[endOffset - i] = unchecked((byte)(value & 0xFF));
34+
value >>= 8;
35+
}
36+
return buffer;
37+
}
38+
}
39+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
4+
namespace ReClassNET.Util.Conversion
5+
{
6+
public abstract class EndianBitConverter
7+
{
8+
public static LittleEndianBitConverter Little { get; } = new LittleEndianBitConverter();
9+
10+
public static BigEndianBitConverter Big { get; } = new BigEndianBitConverter();
11+
12+
public static EndianBitConverter System { get; } = BitConverter.IsLittleEndian ? (EndianBitConverter)Little : Big;
13+
14+
15+
public bool ToBoolean(byte[] value, int startIndex) => BitConverter.ToBoolean(value, startIndex);
16+
17+
public char ToChar(byte[] value, int startIndex) => unchecked((char)FromBytes(value, startIndex, 2));
18+
19+
public double ToDouble(byte[] value, int startIndex) => BitConverter.Int64BitsToDouble(ToInt64(value, startIndex));
20+
21+
public float ToSingle(byte[] value, int startIndex) => new Int32FloatUnion(ToInt32(value, startIndex)).FloatValue;
22+
23+
public short ToInt16(byte[] value, int startIndex) => unchecked((short)FromBytes(value, startIndex, 2));
24+
25+
public int ToInt32(byte[] value, int startIndex) => unchecked((int)FromBytes(value, startIndex, 4));
26+
27+
public long ToInt64(byte[] value, int startIndex) => FromBytes(value, startIndex, 8);
28+
29+
public ushort ToUInt16(byte[] value, int startIndex) => unchecked((ushort)FromBytes(value, startIndex, 2));
30+
31+
public uint ToUInt32(byte[] value, int startIndex) => unchecked((uint)FromBytes(value, startIndex, 4));
32+
33+
public ulong ToUInt64(byte[] value, int startIndex) => unchecked((ulong)FromBytes(value, startIndex, 8));
34+
35+
protected abstract long FromBytes(byte[] value, int index, int bytesToConvert);
36+
37+
38+
public byte[] GetBytes(bool value) => BitConverter.GetBytes(value);
39+
40+
public byte[] GetBytes(char value) => ToBytes(value, 2);
41+
42+
public byte[] GetBytes(double value) => ToBytes(BitConverter.DoubleToInt64Bits(value), 8);
43+
44+
public byte[] GetBytes(short value) => ToBytes(value, 2);
45+
46+
public byte[] GetBytes(int value) => ToBytes(value, 4);
47+
48+
public byte[] GetBytes(long value) => ToBytes(value, 8);
49+
50+
public byte[] GetBytes(float value) => ToBytes(new Int32FloatUnion(value).IntValue, 4);
51+
52+
public byte[] GetBytes(ushort value) => ToBytes(value, 2);
53+
54+
public byte[] GetBytes(uint value) => ToBytes(value, 4);
55+
56+
public byte[] GetBytes(ulong value) => ToBytes(unchecked((long)value), 8);
57+
58+
protected abstract byte[] ToBytes(long value, int bytes);
59+
60+
61+
[StructLayout(LayoutKind.Explicit)]
62+
private readonly struct Int32FloatUnion
63+
{
64+
[FieldOffset(0)]
65+
public readonly int IntValue;
66+
67+
[FieldOffset(0)]
68+
public readonly float FloatValue;
69+
70+
internal Int32FloatUnion(int value)
71+
{
72+
FloatValue = 0.0f;
73+
IntValue = value;
74+
}
75+
76+
internal Int32FloatUnion(float value)
77+
{
78+
IntValue = 0;
79+
FloatValue = value;
80+
}
81+
}
82+
}
83+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
3+
namespace ReClassNET.Util.Conversion
4+
{
5+
public sealed class LittleEndianBitConverter : EndianBitConverter
6+
{
7+
protected override long FromBytes(byte[] buffer, int index, int bytesToConvert)
8+
{
9+
if (buffer == null)
10+
{
11+
throw new ArgumentNullException(nameof(buffer));
12+
}
13+
if (index + bytesToConvert > buffer.Length)
14+
{
15+
throw new ArgumentOutOfRangeException(nameof(index));
16+
}
17+
18+
var ret = 0L;
19+
for (var i = 0; i < bytesToConvert; i++)
20+
{
21+
ret = unchecked((ret << 8) | buffer[index + bytesToConvert - 1 - i]);
22+
}
23+
return ret;
24+
}
25+
26+
protected override byte[] ToBytes(long value, int bytes)
27+
{
28+
var buffer = new byte[bytes];
29+
30+
for (var i = 0; i < bytes; i++)
31+
{
32+
buffer[i] = unchecked((byte)(value & 0xFF));
33+
value >>= 8;
34+
}
35+
36+
return buffer;
37+
}
38+
}
39+
}

‎ReClass.NET_Tests/ReClass.NET_Tests.csproj‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@
9191
<Compile Include="Util\BitStringTest.cs" />
9292
<Compile Include="Util\CircularBufferTest.cs" />
9393
<Compile Include="Util\CommandLineArgsTest.cs" />
94+
<Compile Include="Util\Conversion\BigEndianBitConverterTest.cs" />
95+
<Compile Include="Util\Conversion\EndianBitConverterTest.cs" />
96+
<Compile Include="Util\Conversion\LittleEndianBitConverterTest.cs" />
9497
<Compile Include="Util\CustomDataMapTest.cs" />
9598
<Compile Include="Util\DirectedGraphTest.cs" />
9699
<Compile Include="Util\GrowingListTest.cs" />
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
using System;
2+
using NFluent;
3+
using ReClassNET.Util.Conversion;
4+
using Xunit;
5+
6+
namespace ReClass.NET_Tests.Util.Conversion
7+
{
8+
public class BigEndianBitConverterTest
9+
{
10+
[Fact]
11+
public void ToXXX_ThrowsOnNull()
12+
{
13+
var sut = new BigEndianBitConverter();
14+
15+
Check.ThatCode(() => sut.ToInt32(null, 0)).Throws<ArgumentNullException>();
16+
}
17+
18+
[Fact]
19+
public void ToXXX_ThrowsOnInvalidIndexOrSize()
20+
{
21+
var sut = new BigEndianBitConverter();
22+
23+
var data = new byte[3];
24+
Check.ThatCode(() => sut.ToInt32(data, 0)).Throws<ArgumentOutOfRangeException>();
25+
26+
data = new byte[4];
27+
Check.ThatCode(() => sut.ToInt32(data, 1)).Throws<ArgumentOutOfRangeException>();
28+
}
29+
30+
[Fact]
31+
public void GetBytes()
32+
{
33+
var sut = new BigEndianBitConverter();
34+
35+
Check.That(new byte[] { 0 }).ContainsExactly(sut.GetBytes(false));
36+
Check.That(new byte[] { 1 }).ContainsExactly(sut.GetBytes(true));
37+
38+
Check.That(new byte[] { 0, 0 }).ContainsExactly(sut.GetBytes((short)0));
39+
Check.That(new byte[] { 0, 1 }).ContainsExactly(sut.GetBytes((short)1));
40+
Check.That(new byte[] { 1, 0 }).ContainsExactly(sut.GetBytes((short)256));
41+
Check.That(new byte[] { 255, 255 }).ContainsExactly(sut.GetBytes((short)-1));
42+
43+
Check.That(new byte[] { 0, 0 }).ContainsExactly(sut.GetBytes((ushort)0));
44+
Check.That(new byte[] { 0, 1 }).ContainsExactly(sut.GetBytes((ushort)1));
45+
Check.That(new byte[] { 1, 0 }).ContainsExactly(sut.GetBytes((ushort)256));
46+
Check.That(new byte[] { 255, 255 }).ContainsExactly(sut.GetBytes(ushort.MaxValue));
47+
48+
Check.That(new byte[] { 0, 0, 0, 0 }).ContainsExactly(sut.GetBytes(0));
49+
Check.That(new byte[] { 0, 0, 0, 1 }).ContainsExactly(sut.GetBytes(1));
50+
Check.That(new byte[] { 0, 0, 1, 0 }).ContainsExactly(sut.GetBytes(256));
51+
Check.That(new byte[] { 0, 1, 0, 0 }).ContainsExactly(sut.GetBytes(65536));
52+
Check.That(new byte[] { 1, 0, 0, 0 }).ContainsExactly(sut.GetBytes(16777216));
53+
Check.That(new byte[] { 255, 255, 255, 255 }).ContainsExactly(sut.GetBytes(-1));
54+
55+
Check.That(new byte[] { 0, 0, 0, 0 }).ContainsExactly(sut.GetBytes(0u));
56+
Check.That(new byte[] { 0, 0, 0, 1 }).ContainsExactly(sut.GetBytes(1u));
57+
Check.That(new byte[] { 0, 0, 1, 0 }).ContainsExactly(sut.GetBytes(256u));
58+
Check.That(new byte[] { 0, 1, 0, 0 }).ContainsExactly(sut.GetBytes(65536u));
59+
Check.That(new byte[] { 1, 0, 0, 0 }).ContainsExactly(sut.GetBytes(16777216u));
60+
Check.That(new byte[] { 255, 255, 255, 255 }).ContainsExactly(sut.GetBytes(uint.MaxValue));
61+
62+
Check.That(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }).ContainsExactly(sut.GetBytes(0L));
63+
Check.That(new byte[] { 0, 0, 0, 0, 0, 0, 0, 1 }).ContainsExactly(sut.GetBytes(1L));
64+
Check.That(new byte[] { 0, 0, 0, 0, 0, 0, 1, 0 }).ContainsExactly(sut.GetBytes(256L));
65+
Check.That(new byte[] { 0, 0, 0, 0, 0, 1, 0, 0 }).ContainsExactly(sut.GetBytes(65536L));
66+
Check.That(new byte[] { 0, 0, 0, 0, 1, 0, 0, 0 }).ContainsExactly(sut.GetBytes(16777216L));
67+
Check.That(new byte[] { 0, 0, 0, 1, 0, 0, 0, 0 }).ContainsExactly(sut.GetBytes(4294967296L));
68+
Check.That(new byte[] { 0, 0, 1, 0, 0, 0, 0, 0 }).ContainsExactly(sut.GetBytes(1099511627776L));
69+
Check.That(new byte[] { 0, 1, 0, 0, 0, 0, 0, 0 }).ContainsExactly(sut.GetBytes(281474976710656L));
70+
Check.That(new byte[] { 1, 0, 0, 0, 0, 0, 0, 0 }).ContainsExactly(sut.GetBytes(72057594037927936L));
71+
Check.That(new byte[] { 255, 255, 255, 255, 255, 255, 255, 255 }).ContainsExactly(sut.GetBytes(-1L));
72+
73+
Check.That(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }).ContainsExactly(sut.GetBytes(0UL));
74+
Check.That(new byte[] { 0, 0, 0, 0, 0, 0, 0, 1 }).ContainsExactly(sut.GetBytes(1UL));
75+
Check.That(new byte[] { 0, 0, 0, 0, 0, 0, 1, 0 }).ContainsExactly(sut.GetBytes(256UL));
76+
Check.That(new byte[] { 0, 0, 0, 0, 0, 1, 0, 0 }).ContainsExactly(sut.GetBytes(65536UL));
77+
Check.That(new byte[] { 0, 0, 0, 0, 1, 0, 0, 0 }).ContainsExactly(sut.GetBytes(16777216UL));
78+
Check.That(new byte[] { 0, 0, 0, 1, 0, 0, 0, 0 }).ContainsExactly(sut.GetBytes(4294967296UL));
79+
Check.That(new byte[] { 0, 0, 1, 0, 0, 0, 0, 0 }).ContainsExactly(sut.GetBytes(1099511627776UL));
80+
Check.That(new byte[] { 0, 1, 0, 0, 0, 0, 0, 0 }).ContainsExactly(sut.GetBytes(281474976710656UL));
81+
Check.That(new byte[] { 1, 0, 0, 0, 0, 0, 0, 0 }).ContainsExactly(sut.GetBytes(72057594037927936UL));
82+
Check.That(new byte[] { 255, 255, 255, 255, 255, 255, 255, 255 }).ContainsExactly(sut.GetBytes(ulong.MaxValue));
83+
}
84+
85+
[Fact]
86+
public void ToXXX()
87+
{
88+
var sut = new BigEndianBitConverter();
89+
90+
var data = new byte[] { 0, 0, 0, 0, 0, 0, 0, 3 };
91+
Check.That(sut.ToBoolean(data, 0)).IsFalse();
92+
Check.That(sut.ToBoolean(data, 7)).IsTrue();
93+
Check.That(sut.ToChar(data, 0)).IsEqualTo('0円');
94+
Check.That(sut.ToChar(data, 6)).IsEqualTo('\u0003');
95+
Check.That(sut.ToInt16(data, 0)).IsEqualTo(0);
96+
Check.That(sut.ToInt16(data, 6)).IsEqualTo(3);
97+
Check.That(sut.ToUInt16(data, 0)).IsEqualTo(0u);
98+
Check.That(sut.ToUInt16(data, 6)).IsEqualTo(3u);
99+
Check.That(sut.ToInt32(data, 0)).IsEqualTo(0);
100+
Check.That(sut.ToInt32(data, 4)).IsEqualTo(3);
101+
Check.That(sut.ToUInt32(data, 0)).IsEqualTo(0u);
102+
Check.That(sut.ToUInt32(data, 4)).IsEqualTo(3u);
103+
Check.That(sut.ToInt64(data, 0)).IsEqualTo(3L);
104+
Check.That(sut.ToUInt64(data, 0)).IsEqualTo(3UL);
105+
106+
data = new byte[] { 0x41, 0x20, 0, 0, 0, 0, 0, 0 };
107+
Check.That(sut.ToSingle(data, 0)).IsEqualTo(10.0f);
108+
Check.That(sut.ToSingle(data, 4)).IsEqualTo(0.0f);
109+
110+
data = new byte[] { 0x40, 0x24, 0, 0, 0, 0, 0, 0 };
111+
Check.That(sut.ToDouble(data, 0)).IsEqualTo(10.0);
112+
}
113+
}
114+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System;
2+
using NFluent;
3+
using ReClassNET.Util.Conversion;
4+
using Xunit;
5+
6+
namespace ReClass.NET_Tests.Util.Conversion
7+
{
8+
public class EndianBitConverterTest
9+
{
10+
[Fact]
11+
public void Properties_AreNotNull()
12+
{
13+
Check.That(EndianBitConverter.System).IsNotNull();
14+
Check.That(EndianBitConverter.Big).IsNotNull();
15+
Check.That(EndianBitConverter.Little).IsNotNull();
16+
}
17+
18+
[Fact]
19+
public void Types()
20+
{
21+
Check.That(EndianBitConverter.Big.GetType()).IsNotEqualTo(EndianBitConverter.Little.GetType());
22+
Check.That(EndianBitConverter.System.GetType()).IsEqualTo(BitConverter.IsLittleEndian ? EndianBitConverter.Little.GetType() : EndianBitConverter.Big.GetType());
23+
}
24+
}
25+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /