Skip to content

Commit

Permalink
Refactor: use System.Buffers.BinaryPrimitives in ByteMemoryArea.
Browse files Browse the repository at this point in the history
  • Loading branch information
uxmal committed Aug 8, 2023
1 parent 991aac8 commit 586e978
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 104 deletions.
130 changes: 39 additions & 91 deletions src/Core/Memory/ByteMemoryArea.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,10 @@

using Reko.Core.Expressions;
using Reko.Core.Lib;
using Reko.Core.Memory;
using Reko.Core.Output;
using Reko.Core.Types;
using System;
using System.Diagnostics;
using System.IO;
using System.Buffers.Binary;

namespace Reko.Core.Memory
{
Expand Down Expand Up @@ -336,15 +334,8 @@ public static bool TryReadBeInt64(byte[] image, long off, out long value)
{
if (off + 8 <= image.Length)
{
value =
((long)image[off] << 56) |
((long)image[off + 1] << 48) |
((long)image[off + 2] << 40) |
((long)image[off + 3] << 32) |
((long)image[off + 4] << 24) |
((long)image[off + 5] << 16) |
((long)image[off + 6] << 8) |
((long)image[off + 7]);
var span = image.AsSpan((int) off, 8);
value = BinaryPrimitives.ReadInt64BigEndian(span);
return true;
}
else
Expand All @@ -358,15 +349,8 @@ public static bool TryReadBeUInt64(byte[] image, long off, out ulong value)
{
if (off + 8 <= image.Length)
{
value =
((ulong)image[off] << 56) |
((ulong)image[off + 1] << 48) |
((ulong)image[off + 2] << 40) |
((ulong)image[off + 3] << 32) |
((ulong)image[off + 4] << 24) |
((ulong)image[off + 5] << 16) |
((ulong)image[off + 6] << 8) |
((ulong)image[off + 7]);
var span = image.AsSpan((int) off, 8);
value = BinaryPrimitives.ReadUInt64BigEndian(span);
return true;
}
else
Expand All @@ -375,31 +359,19 @@ public static bool TryReadBeUInt64(byte[] image, long off, out ulong value)
return false;
}
}

public static long ReadBeInt64(byte[] image, long off)
{
return ((long)image[off] << 56) |
((long)image[off + 1] << 48) |
((long)image[off + 2] << 40) |
((long)image[off + 3] << 32) |
((long)image[off + 4] << 24) |
((long)image[off + 5] << 16) |
((long)image[off + 6] << 8) |
((long)image[off + 7]);
var span = image.AsSpan((int) off, 8);
return BinaryPrimitives.ReadInt64BigEndian(span);
}

public static bool TryReadLeInt64(byte[] image, long off, out long value)
{
if (off + 8 <= image.Length)
{
value =
(long)image[off] |
((long)image[off + 1] << 8) |
((long)image[off + 2] << 16) |
((long)image[off + 3] << 24) |
((long)image[off + 4] << 32) |
((long)image[off + 5] << 40) |
((long)image[off + 6] << 48) |
((long)image[off + 7] << 56);
var span = image.AsSpan((int) off, 8);
value = BinaryPrimitives.ReadInt64LittleEndian(span);
return true;
}
else
Expand All @@ -413,15 +385,8 @@ public static bool TryReadLeUInt64(byte[] image, long off, out ulong value)
{
if (off + 8 <= image.Length)
{
value =
(ulong)image[off] |
((ulong)image[off + 1] << 8) |
((ulong)image[off + 2] << 16) |
((ulong)image[off + 3] << 24) |
((ulong)image[off + 4] << 32) |
((ulong)image[off + 5] << 40) |
((ulong)image[off + 6] << 48) |
((ulong)image[off + 7] << 56);
var span = image.AsSpan((int) off, 8);
value = BinaryPrimitives.ReadUInt64LittleEndian(span);
return true;
}
else
Expand All @@ -430,17 +395,11 @@ public static bool TryReadLeUInt64(byte[] image, long off, out ulong value)
return false;
}
}

public static long ReadLeInt64(byte[] image, long off)
{
return
(long) image[off] |
((long)image[off+1] << 8) |
((long)image[off+2] << 16) |
((long)image[off+3] << 24) |
((long)image[off+4] << 32) |
((long)image[off+5] << 40) |
((long)image[off+6] << 48) |
((long)image[off+7] << 56);
var span = image.AsSpan((int) off, 8);
return BinaryPrimitives.ReadInt64LittleEndian(span);
}

//$REVIEW: consider making this an extension method hosted in x86.
Expand All @@ -458,23 +417,16 @@ public static bool TryReadLeReal80(byte[] image, long off, out Float80 value)

public static int ReadBeInt32(byte[] abImage, long off)
{
int u =
((int)abImage[off] << 24) |
((int)abImage[off + 1] << 16) |
((int)abImage[off + 2] << 8) |
abImage[off + 3];
return u;
var span = abImage.AsSpan((int) off, 4);
return BinaryPrimitives.ReadInt32BigEndian(span);
}

public static bool TryReadBeInt32(byte[] abImage, long off, out int value)
{
if (off <= abImage.Length - 4)
{
value =
((int)abImage[off] << 24) |
((int)abImage[off + 1] << 16) |
((int)abImage[off + 2] << 8) |
abImage[off + 3];
var span = abImage.AsSpan((int) off, 4);
value = BinaryPrimitives.ReadInt32BigEndian(span);
return true;
}
else
Expand All @@ -488,10 +440,8 @@ public static bool TryReadLeInt32(byte [] abImage, uint off, out int value)
{
if (off <= abImage.Length - 4)
{
value = abImage[off] |
((int)abImage[off + 1] << 8) |
((int)abImage[off + 2] << 16) |
((int)abImage[off + 3] << 24);
var span = abImage.AsSpan((int) off, 4);
value = BinaryPrimitives.ReadInt32LittleEndian(span);
return true;
}
else
Expand All @@ -503,12 +453,10 @@ public static bool TryReadLeInt32(byte [] abImage, uint off, out int value)

public static bool TryReadLeUInt32(byte[] abImage, long off, out uint value)
{
if ((long) off <= abImage.Length - 4)
if (off <= abImage.Length - 4)
{
value = abImage[off] |
((uint)abImage[off + 1] << 8) |
((uint)abImage[off + 2] << 16) |
((uint)abImage[off + 3] << 24);
var span = abImage.AsSpan((int) off, 4);
value = BinaryPrimitives.ReadUInt32LittleEndian(span);
return true;
}
else
Expand All @@ -522,11 +470,8 @@ public static bool TryReadBeUInt32(byte[] abImage, long off, out uint value)
{
if ((long)off <= abImage.Length - 4)
{
value =
((uint)abImage[off] << 24) |
((uint)abImage[off + 1] << 16) |
((uint)abImage[off + 2] << 8) |
abImage[off + 3];
var span = abImage.AsSpan((int) off, 4);
value = BinaryPrimitives.ReadUInt32BigEndian(span);
return true;
}
else
Expand All @@ -538,18 +483,17 @@ public static bool TryReadBeUInt32(byte[] abImage, long off, out uint value)

public static int ReadLeInt32(byte[] abImage, long off)
{
int u = abImage[off] |
((int)abImage[off + 1] << 8) |
((int)abImage[off + 2] << 16) |
((int)abImage[off + 3] << 24);
return u;
var span = abImage.AsSpan((int) off, 4);
return BinaryPrimitives.ReadInt32LittleEndian(span);
}


public static bool TryReadBeInt16(byte[] img, long offset, out short value)
{
if (offset <= img.Length - 2)
{
value = (short)(img[offset] << 8 | img[offset + 1]);
var span = img.AsSpan((int) offset, 2);
value = BinaryPrimitives.ReadInt16BigEndian(span);
return true;
}
else
Expand All @@ -563,7 +507,8 @@ public static bool TryReadBeUInt16(byte[] img, long offset, out ushort value)
{
if (offset <= img.Length - 2)
{
value = (ushort)(img[offset] << 8 | img[offset + 1]);
var span = img.AsSpan((int) offset, 2);
value = BinaryPrimitives.ReadUInt16BigEndian(span);
return true;
}
else
Expand All @@ -577,7 +522,8 @@ public static bool TryReadLeInt16(byte[] img, long offset, out short value)
{
if (offset <= img.Length - 2)
{
value = (short)(img[offset] | img[offset + 1] << 8);
var span = img.AsSpan((int) offset, 2);
value = BinaryPrimitives.ReadInt16LittleEndian(span);
return true;
}
else
Expand All @@ -589,12 +535,14 @@ public static bool TryReadLeInt16(byte[] img, long offset, out short value)

public static short ReadBeInt16(byte[] img, long offset)
{
return (short)(img[offset] << 8 | img[offset + 1]);
var span = img.AsSpan((int) offset, 2);
return BinaryPrimitives.ReadInt16BigEndian(span);
}

public static short ReadLeInt16(byte[] abImage, long offset)
{
return (short)(abImage[offset] + (abImage[offset + 1] << 8));
var span = abImage.AsSpan((int) offset, 2);
return BinaryPrimitives.ReadInt16LittleEndian(span);
}

public static bool TryReadLeUInt16(byte[] abImage, long offset, out ushort us)
Expand Down
20 changes: 18 additions & 2 deletions src/UnitTests/Core/Memory/ByteMemoryAreaTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,16 @@
using Reko.Core.Expressions;
using Reko.Core.Memory;
using Reko.Core.Types;
using System;

namespace Reko.UnitTests.Core.Memory
{
[TestFixture]
public class ByteMemoryAreaTests
{
[Test]
private static byte[] eightBytes = new byte[] { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0 };

[Test]
public void PriReadLiterals()
{
var bytes = new byte [] {
Expand Down Expand Up @@ -87,5 +90,18 @@ public void TryReadLeNegativeInt()
Assert.AreSame(PrimitiveType.Int32, c.DataType);
Assert.AreEqual("-2<i32>", c.ToString());
}
}

[Test]
public void Bma_ReadLeUInt64()
{
ulong value = ByteMemoryArea.ReadBeUInt64(eightBytes, 0);
Assert.AreEqual(0x123456789ABCDEF0, value);
}

[Test]
public void Bma_ReadLeUInt64_Throws()
{
Assert.Throws<ArgumentOutOfRangeException>(() => ByteMemoryArea.ReadBeUInt64(eightBytes, 4));
}
}
}
22 changes: 11 additions & 11 deletions subjects/regression.log

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 586e978

Please sign in to comment.