Skip to content

Commit 1608c07

Browse files
committed
Use more efficient number to bit string conversion.
1 parent b1a45f9 commit 1608c07

File tree

5 files changed

+177
-21
lines changed

5 files changed

+177
-21
lines changed

ReClass.NET/Nodes/BitFieldNode.cs

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
using System;
22
using System.Diagnostics.Contracts;
33
using System.Drawing;
4-
using System.Text;
54
using ReClassNET.Memory;
65
using ReClassNET.UI;
6+
using ReClassNET.Util;
77

88
namespace ReClassNET.Nodes
99
{
@@ -94,33 +94,17 @@ private string ConvertValueToGroupedBitString(MemoryBuffer memory)
9494
Contract.Requires(memory != null);
9595
Contract.Ensures(Contract.Result<string>() != null);
9696

97-
string str;
9897
switch(bits)
9998
{
10099
case 64:
101-
str = Convert.ToString(memory.ReadInt64(Offset), 2);
102-
break;
100+
return BitString.ToString(memory.ReadInt64(Offset));
103101
case 32:
104-
str = Convert.ToString(memory.ReadInt32(Offset), 2);
105-
break;
102+
return BitString.ToString(memory.ReadInt32(Offset));
106103
case 16:
107-
str = Convert.ToString(memory.ReadInt16(Offset), 2);
108-
break;
104+
return BitString.ToString(memory.ReadInt16(Offset));
109105
default:
110-
str = Convert.ToString(memory.ReadUInt8(Offset), 2);
111-
break;
106+
return BitString.ToString(memory.ReadUInt8(Offset));
112107
}
113-
114-
str = str.PadLeft(bits, '0');
115-
116-
var sb = new StringBuilder(str);
117-
118-
for (var i = bits - 4; i > 0; i -= 4)
119-
{
120-
sb.Insert(i, ' ');
121-
}
122-
123-
return sb.ToString();
124108
}
125109

126110
public override Size Draw(ViewInfo view, int x, int y)

ReClass.NET/ReClass.NET.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,7 @@
383383
<Compile Include="UI\PlaceholderTextBox.cs">
384384
<SubType>Component</SubType>
385385
</Compile>
386+
<Compile Include="Util\BitString.cs" />
386387
<Compile Include="Util\CircularBuffer.cs" />
387388
<Compile Include="Util\CommandLineArgs.cs" />
388389
<Compile Include="Util\CustomDataMap.cs" />

ReClass.NET/Util/BitString.cs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
using System;
2+
using System.Text;
3+
4+
namespace ReClassNET.Util
5+
{
6+
public static class BitString
7+
{
8+
/// <summary>
9+
/// Converts the value to the corresponding bit string.
10+
/// Format: 0000 0000
11+
/// </summary>
12+
/// <param name="value">The value to convert.</param>
13+
/// <returns>The corresponding bit string.</returns>
14+
public static string ToString(byte value)
15+
{
16+
return AddPaddingAndBuildBlocks(8, Convert.ToString(value, 2));
17+
}
18+
19+
/// <summary>
20+
/// Converts the value to the corresponding bit string.
21+
/// Format: 0000 0000 0000 0000
22+
/// </summary>
23+
/// <param name="value">The value to convert.</param>
24+
/// <returns>The corresponding bit string.</returns>
25+
public static string ToString(short value)
26+
{
27+
return AddPaddingAndBuildBlocks(16, Convert.ToString(value, 2));
28+
}
29+
30+
/// <summary>
31+
/// Converts the value to the corresponding bit string.
32+
/// Format: 0000 0000 0000 0000 0000 0000 0000 0000
33+
/// </summary>
34+
/// <param name="value">The value to convert.</param>
35+
/// <returns>The corresponding bit string.</returns>
36+
public static string ToString(int value)
37+
{
38+
return AddPaddingAndBuildBlocks(32, Convert.ToString(value, 2));
39+
}
40+
41+
/// <summary>
42+
/// Converts the value to the corresponding bit string.
43+
/// Format: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
44+
/// </summary>
45+
/// <param name="value">The value to convert.</param>
46+
/// <returns>The corresponding bit string.</returns>
47+
public static string ToString(long value)
48+
{
49+
return AddPaddingAndBuildBlocks(64, Convert.ToString(value, 2));
50+
}
51+
52+
private static string AddPaddingAndBuildBlocks(int bits, string value)
53+
{
54+
var sb = new StringBuilder(bits);
55+
56+
var padding = bits - value.Length;
57+
58+
// Add full padding blocks.
59+
while (padding > 4)
60+
{
61+
sb.Append("0000 ");
62+
padding -= 4;
63+
}
64+
65+
// Add only a part of a block.
66+
if (padding > 0)
67+
{
68+
// {padding} 0 bits
69+
for (var i = 0; i < padding; ++i)
70+
{
71+
sb.Append('0');
72+
}
73+
74+
// and {4 - padding} bits of the value.
75+
sb.Append(value, 0, 4 - padding);
76+
77+
if (value.Length > padding)
78+
{
79+
sb.Append(' ');
80+
}
81+
}
82+
83+
// Add all remaining blocks.
84+
for (var i = padding == 0 ? 0 : 4 - padding; i < value.Length; i += 4)
85+
{
86+
sb.Append(value, i, 4);
87+
if (i < value.Length - 4)
88+
{
89+
sb.Append(' ');
90+
}
91+
}
92+
93+
return sb.ToString();
94+
}
95+
}
96+
}

ReClass.NET_Tests/ReClass.NET_Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
<Compile Include="MemoryScanner\BytePatternTest.cs" />
8282
<Compile Include="Memory\MemoryBufferTest.cs" />
8383
<Compile Include="Properties\AssemblyInfo.cs" />
84+
<Compile Include="Util\BitStringTest.cs" />
8485
<Compile Include="Util\CircularBufferTest.cs" />
8586
<Compile Include="Util\CommandLineArgsTest.cs" />
8687
<Compile Include="Util\CustomDataMapTest.cs" />
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using NFluent;
7+
using ReClassNET.Util;
8+
using Xunit;
9+
10+
namespace ReClass.NET_Tests.Util
11+
{
12+
public class BitStringTest
13+
{
14+
[Theory]
15+
[InlineData(0, "0000 0000")]
16+
[InlineData(1, "0000 0001")]
17+
[InlineData(127, "0111 1111")]
18+
[InlineData(128, "1000 0000")]
19+
[InlineData(255, "1111 1111")]
20+
[InlineData(0b1010_1010, "1010 1010")]
21+
public void TestToStringByte(byte value, string expected)
22+
{
23+
Check.That(BitString.ToString(value)).IsEqualTo(expected);
24+
}
25+
26+
[Theory]
27+
[InlineData(0, "0000 0000 0000 0000")]
28+
[InlineData(1, "0000 0000 0000 0001")]
29+
[InlineData(127, "0000 0000 0111 1111")]
30+
[InlineData(128, "0000 0000 1000 0000")]
31+
[InlineData(255, "0000 0000 1111 1111")]
32+
[InlineData(short.MaxValue, "0111 1111 1111 1111")]
33+
[InlineData(short.MinValue, "1000 0000 0000 0000")]
34+
[InlineData(unchecked((short)0b1010_1010_1010_1010), "1010 1010 1010 1010")]
35+
public void TestToStringShort(short value, string expected)
36+
{
37+
Check.That(BitString.ToString(value)).IsEqualTo(expected);
38+
}
39+
40+
[Theory]
41+
[InlineData(0, "0000 0000 0000 0000 0000 0000 0000 0000")]
42+
[InlineData(1, "0000 0000 0000 0000 0000 0000 0000 0001")]
43+
[InlineData(127, "0000 0000 0000 0000 0000 0000 0111 1111")]
44+
[InlineData(128, "0000 0000 0000 0000 0000 0000 1000 0000")]
45+
[InlineData(255, "0000 0000 0000 0000 0000 0000 1111 1111")]
46+
[InlineData(short.MaxValue, "0000 0000 0000 0000 0111 1111 1111 1111")]
47+
[InlineData(short.MinValue, "1111 1111 1111 1111 1000 0000 0000 0000")]
48+
[InlineData(int.MaxValue, "0111 1111 1111 1111 1111 1111 1111 1111")]
49+
[InlineData(int.MinValue, "1000 0000 0000 0000 0000 0000 0000 0000")]
50+
[InlineData(unchecked((int)0b1010_1010_1010_1010_1010_1010_1010_1010), "1010 1010 1010 1010 1010 1010 1010 1010")]
51+
public void TestToStringInt(int value, string expected)
52+
{
53+
Check.That(BitString.ToString(value)).IsEqualTo(expected);
54+
}
55+
56+
[Theory]
57+
[InlineData(0, "0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000")]
58+
[InlineData(1, "0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001")]
59+
[InlineData(127, "0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0111 1111")]
60+
[InlineData(128, "0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1000 0000")]
61+
[InlineData(255, "0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 1111")]
62+
[InlineData(short.MaxValue, "0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0111 1111 1111 1111")]
63+
[InlineData(short.MinValue, "1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1000 0000 0000 0000")]
64+
[InlineData(int.MaxValue, "0000 0000 0000 0000 0000 0000 0000 0000 0111 1111 1111 1111 1111 1111 1111 1111")]
65+
[InlineData(int.MinValue, "1111 1111 1111 1111 1111 1111 1111 1111 1000 0000 0000 0000 0000 0000 0000 0000")]
66+
[InlineData(long.MaxValue, "0111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111")]
67+
[InlineData(long.MinValue, "1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000")]
68+
[InlineData(unchecked((long)0b1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010), "1010 1010 1010 1010 1010 1010 1010 1010 1010 1010 1010 1010 1010 1010 1010 1010")]
69+
public void TestToStringLong(long value, string expected)
70+
{
71+
Check.That(BitString.ToString(value)).IsEqualTo(expected);
72+
}
73+
}
74+
}

0 commit comments

Comments
 (0)