Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,10 @@ sealed class NumberDocumentViewerToolTipProvider : IDocumentViewerToolTipProvide
return null;
}

static readonly (int @base, int groupSize)[] numberBases = new (int, int)[] {
(2, 4),
(8, 4),
(10, 3),
(16, 4),
static readonly (int @base, int groupSize, string groupSeparator)[] numberBases = new (int, int, string)[] {
(2, 4, " "),
(10, 3, "_"),
(16, 0, string.Empty),
};
object Create(IDocumentViewerToolTipProviderContext context, Func<StringBuilder, int, string> toBase) {
var provider = context.Create();
Expand All @@ -74,26 +73,26 @@ object Create(IDocumentViewerToolTipProviderContext context, Func<StringBuilder,
provider.Output.Write(BoxedTextColor.Text, " ");
var numStr = toBase(sb, info.@base);
if (info.groupSize != 0)
numStr = NumberUtils.AddDigitSeparators(sb, numStr, info.groupSize, "_");
numStr = NumberUtils.AddDigitSeparators(sb, numStr, info.groupSize, info.groupSeparator);
provider.Output.Write(BoxedTextColor.Number, numStr);
}

return provider.Create();
}

object CreateSByte(IDocumentViewerToolTipProviderContext context, sbyte value) => Create(context, (sb, n) => NumberUtils.ToString(sb, n, value));
object CreateByte(IDocumentViewerToolTipProviderContext context, byte value) => Create(context, (sb, n) => NumberUtils.ToString(sb, n, value));
object CreateInt16(IDocumentViewerToolTipProviderContext context, short value) => Create(context, (sb, n) => NumberUtils.ToString(sb, n, value));
object CreateUInt16(IDocumentViewerToolTipProviderContext context, ushort value) => Create(context, (sb, n) => NumberUtils.ToString(sb, n, value));
object CreateInt32(IDocumentViewerToolTipProviderContext context, int value) => Create(context, (sb, n) => NumberUtils.ToString(sb, n, value));
object CreateUInt32(IDocumentViewerToolTipProviderContext context, uint value) => Create(context, (sb, n) => NumberUtils.ToString(sb, n, value));
object CreateInt64(IDocumentViewerToolTipProviderContext context, long value) => Create(context, (sb, n) => NumberUtils.ToString(sb, n, value));
object CreateUInt64(IDocumentViewerToolTipProviderContext context, ulong value) => Create(context, (sb, n) => NumberUtils.ToString(sb, n, value));
object CreateSByte(IDocumentViewerToolTipProviderContext context, sbyte value) => Create(context, (sb, n) => NumberUtils.ToString(sb, n, value, sizeof(sbyte)));
object CreateByte(IDocumentViewerToolTipProviderContext context, byte value) => Create(context, (sb, n) => NumberUtils.ToString(sb, n, value, sizeof(byte)));
object CreateInt16(IDocumentViewerToolTipProviderContext context, short value) => Create(context, (sb, n) => NumberUtils.ToString(sb, n, value, sizeof(short)));
object CreateUInt16(IDocumentViewerToolTipProviderContext context, ushort value) => Create(context, (sb, n) => NumberUtils.ToString(sb, n, value, sizeof(ushort)));
object CreateInt32(IDocumentViewerToolTipProviderContext context, int value) => Create(context, (sb, n) => NumberUtils.ToString(sb, n, value, sizeof(int)));
object CreateUInt32(IDocumentViewerToolTipProviderContext context, uint value) => Create(context, (sb, n) => NumberUtils.ToString(sb, n, value, sizeof(uint)));
object CreateInt64(IDocumentViewerToolTipProviderContext context, long value) => Create(context, (sb, n) => NumberUtils.ToString(sb, n, value, sizeof(long)));
object CreateUInt64(IDocumentViewerToolTipProviderContext context, ulong value) => Create(context, (sb, n) => NumberUtils.ToString(sb, n, value, sizeof(ulong)));

object CreateFloat(IDocumentViewerToolTipProviderContext context, string valueStr, string serializedFormatStr, string serializedValueStr, Func<string> getRawValue) {
object CreateFloat(IDocumentViewerToolTipProviderContext context, string valueStr, string serializedFormatStr, string serializedValueStr, Func<StringBuilder, string> getRawValue) {
var provider = context.Create();
provider.Image = DsImages.ConstantPublic;

Comment thread
3fbaea00 marked this conversation as resolved.
var sb = new StringBuilder();

provider.Output.Write(BoxedTextColor.Number, valueStr);
Expand All @@ -104,8 +103,7 @@ object CreateFloat(IDocumentViewerToolTipProviderContext context, string valueSt
provider.Output.Write(BoxedTextColor.Number, serializedValueStr);
provider.Output.WriteLine();

var rawValueStr = getRawValue();
rawValueStr = "0x" + NumberUtils.AddDigitSeparators(sb, rawValueStr, 4, "_");
var rawValueStr = getRawValue(sb);
provider.Output.Write(BoxedTextColor.Text, dnSpy_Resources.RawValue);
provider.Output.Write(BoxedTextColor.Text, " ");
provider.Output.Write(BoxedTextColor.Number, rawValueStr);
Expand All @@ -115,16 +113,18 @@ object CreateFloat(IDocumentViewerToolTipProviderContext context, string valueSt

object CreateSingle(IDocumentViewerToolTipProviderContext context, float value) {
const string format = "G9";
const bool upper = true;
uint rawValue = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
return CreateFloat(context, value.ToString(), format, value.ToString(format),
() => rawValue.ToString("X8"));
sb => NumberUtils.ToFixedSizeHexadecimalArray(sb, rawValue, 4, upper));
}

object CreateDouble(IDocumentViewerToolTipProviderContext context, double value) {
const string format = "G17";
const bool upper = true;
ulong rawValue = BitConverter.ToUInt64(BitConverter.GetBytes(value), 0);
return CreateFloat(context, value.ToString(), format, value.ToString(format),
() => rawValue.ToString("X16"));
sb => NumberUtils.ToFixedSizeHexadecimalArray(sb, rawValue, 8, upper));
}
}
}
63 changes: 50 additions & 13 deletions dnSpy/dnSpy/Documents/Tabs/DocViewer/ToolTips/NumberUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,22 @@ You should have received a copy of the GNU General Public License

namespace dnSpy.Documents.Tabs.DocViewer.ToolTips {
static class NumberUtils {
internal static string ToString(StringBuilder sb, int @base, long value) {
if (value < 0)
return "-" + ToString(sb, @base, (ulong)(-value));
return ToString(sb, @base, (ulong)value);
internal static string ToString(StringBuilder sb, int @base, long value, int @sizeof) {
if (@base == 10 && value < 0)
return "-" + ToString(sb, @base, (ulong)(-value), @sizeof);
return ToString(sb, @base, unchecked((ulong)value), @sizeof);
}

internal static string ToString(StringBuilder sb, int @base, ulong value) {
internal static string ToString(StringBuilder sb, int @base, ulong value, int @sizeof) {
const int digits = 0;
const bool upper = true;

switch (@base) {
case 2: return ToBinary(sb, value, digits);
case 8: return ToOctal(sb, value, digits);
case 10: return value.ToString();
case 16: return ToHexadecimal(sb, value, digits, upper);
default: throw new ArgumentOutOfRangeException(nameof(@base));
case 2: return ToBinary(sb, value, digits, @sizeof << 3);
case 8: return ToOctal(sb, value, digits, @sizeof << 2);
case 10: return value.ToString();
case 16: return ToHexadecimal(sb, value, digits, @sizeof << 1, upper);
default: throw new ArgumentOutOfRangeException(nameof(@base));
}
Comment thread
3fbaea00 marked this conversation as resolved.
}

Expand All @@ -60,7 +60,35 @@ internal static string AddDigitSeparators(StringBuilder sb, string rawNumber, in
return sb.ToString();
}

static string ToHexadecimal(StringBuilder sb, ulong value, int digits, bool upper) {
internal static string ToFixedSizeHexadecimalArray(StringBuilder sb, ulong value, int bytesCount, bool upper) {
sb.Clear();

char hexHigh = upper ? (char)('A' - 10) : (char)('a' - 10);
while (bytesCount > 0) {
int ldigit = (int)(value & 0xF);
value >>= 4;
int hdigit = (int)(value & 0xF);
value >>= 4;
bytesCount--;

if (hdigit > 9)
sb.Append((char)(hdigit + hexHigh));
else
sb.Append((char)(hdigit + '0'));

if (ldigit > 9)
sb.Append((char)(ldigit + hexHigh));
else
sb.Append((char)(ldigit + '0'));

if (bytesCount != 0)
sb.Append(' ');
}

return sb.ToString();
}

static string ToHexadecimal(StringBuilder sb, ulong value, int digits, int maxDigits, bool upper) {
sb.Clear();

if (digits == 0) {
Expand All @@ -73,6 +101,9 @@ static string ToHexadecimal(StringBuilder sb, ulong value, int digits, bool uppe
}
}

if (digits > maxDigits)
digits = maxDigits;

char hexHigh = upper ? (char)('A' - 10) : (char)('a' - 10);
for (int i = 0; i < digits; i++) {
int digit = (int)((value >> ((digits - i - 1) << 2)) & 0xF);
Expand All @@ -85,7 +116,7 @@ static string ToHexadecimal(StringBuilder sb, ulong value, int digits, bool uppe
return sb.ToString();
}

static string ToOctal(StringBuilder sb, ulong value, int digits) {
static string ToOctal(StringBuilder sb, ulong value, int digits, int maxDigits) {
sb.Clear();

if (digits == 0) {
Expand All @@ -98,6 +129,9 @@ static string ToOctal(StringBuilder sb, ulong value, int digits) {
}
}

if (digits > maxDigits)
digits = maxDigits;

for (int i = 0; i < digits; i++) {
int digit = (int)((value >> (digits - i - 1) * 3) & 7);
sb.Append((char)(digit + '0'));
Expand All @@ -106,7 +140,7 @@ static string ToOctal(StringBuilder sb, ulong value, int digits) {
return sb.ToString();
}

static string ToBinary(StringBuilder sb, ulong value, int digits) {
static string ToBinary(StringBuilder sb, ulong value, int digits, int maxDigits) {
sb.Clear();

if (digits == 0) {
Expand All @@ -119,6 +153,9 @@ static string ToBinary(StringBuilder sb, ulong value, int digits) {
}
}

if (digits > maxDigits)
digits = maxDigits;

for (int i = 0; i < digits; i++) {
int digit = (int)((value >> (digits - i - 1)) & 1);
sb.Append((char)(digit + '0'));
Expand Down
Loading