BizHawk/BizHawk.BizInvoke/WaterboxUtils.cs

142 lines
2.8 KiB
C#

using System;
using System.IO;
using System.Security.Cryptography;
namespace BizHawk.BizInvoke
{
public static class WaterboxUtils
{
/// <summary>
/// copy `len` bytes from `src` to `dest`
/// </summary>
public static void CopySome(Stream src, Stream dst, long len)
{
var buff = new byte[4096];
while (len > 0)
{
int r = src.Read(buff, 0, (int)Math.Min(len, 4096));
dst.Write(buff, 0, r);
len -= r;
}
}
public static byte[] Hash(byte[] data)
{
using var h = SHA1.Create();
return h.ComputeHash(data);
}
public static byte[] Hash(Stream s)
{
using var h = SHA1.Create();
return h.ComputeHash(s);
}
public static unsafe void ZeroMemory(IntPtr mem, long length)
{
byte* p = (byte*)mem;
byte* end = p + length;
while (p < end)
{
*p++ = 0;
}
}
/// <summary>
/// system page size
/// </summary>
public static int PageSize { get; }
/// <summary>
/// bitshift corresponding to PageSize
/// </summary>
public static int PageShift { get; }
/// <summary>
/// bitmask corresponding to PageSize
/// </summary>
public static ulong PageMask { get; }
static WaterboxUtils()
{
int p = PageSize = Environment.SystemPageSize;
while (p != 1)
{
p >>= 1;
PageShift++;
}
PageMask = (ulong)(PageSize - 1);
}
/// <summary>
/// true if addr is aligned
/// </summary>
public static bool Aligned(ulong addr)
{
return (addr & PageMask) == 0;
}
/// <summary>
/// align address down to previous page boundary
/// </summary>
public static ulong AlignDown(ulong addr)
{
return addr & ~PageMask;
}
/// <summary>
/// align address up to next page boundary
/// </summary>
public static ulong AlignUp(ulong addr)
{
return ((addr - 1) | PageMask) + 1;
}
/// <summary>
/// return the minimum number of pages needed to hold size
/// </summary>
public static int PagesNeeded(ulong size)
{
return (int)((size + PageMask) >> PageShift);
}
}
// C# is annoying: arithmetic operators for native ints are not exposed.
// So we store them as long/ulong instead in many places, and use these helpers
// to convert to IntPtr when needed
public static class Z
{
public static IntPtr US(ulong l)
{
if (IntPtr.Size == 8)
return (IntPtr)(long)l;
else
return (IntPtr)(int)l;
}
public static UIntPtr UU(ulong l)
{
if (UIntPtr.Size == 8)
return (UIntPtr)l;
else
return (UIntPtr)(uint)l;
}
public static IntPtr SS(long l)
{
if (IntPtr.Size == 8)
return (IntPtr)l;
else
return (IntPtr)(int)l;
}
public static UIntPtr SU(long l)
{
if (UIntPtr.Size == 8)
return (UIntPtr)(ulong)l;
else
return (UIntPtr)(uint)l;
}
}
}