mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-13 12:14:16 +01:00
Merge pull request #249 from pohky/master
This commit is contained in:
commit
b1b6621c2a
1 changed files with 31 additions and 25 deletions
|
|
@ -59,7 +59,7 @@ namespace Dalamud
|
||||||
/// <param name="result">The resulting object.</param>
|
/// <param name="result">The resulting object.</param>
|
||||||
/// <returns>Whether or not the read succeeded.</returns>
|
/// <returns>Whether or not the read succeeded.</returns>
|
||||||
public static bool Read<T>(IntPtr address, out T result) where T : struct {
|
public static bool Read<T>(IntPtr address, out T result) where T : struct {
|
||||||
if (!ReadBytes(address, SizeOf<T>(), out var buffer)) {
|
if (!ReadBytes(address, SizeCache<T>.Size, out var buffer)) {
|
||||||
result = default;
|
result = default;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -82,19 +82,14 @@ namespace Dalamud
|
||||||
public static T[] Read<T>(IntPtr address, int count) where T : struct
|
public static T[] Read<T>(IntPtr address, int count) where T : struct
|
||||||
{
|
{
|
||||||
var size = SizeOf<T>();
|
var size = SizeOf<T>();
|
||||||
|
if (!ReadBytes(address, count * size, out var buffer))
|
||||||
|
return null;
|
||||||
var result = new T[count];
|
var result = new T[count];
|
||||||
|
using var mem = new LocalMemory(buffer.Length);
|
||||||
var readSucceeded = true;
|
mem.Write(buffer);
|
||||||
for (var i = 0; i < count; i++) {
|
for (var i = 0; i < result.Length; i++)
|
||||||
var success = Read<T>(address + i * size, out var res);
|
result[i] = mem.Read<T>(i * size);
|
||||||
|
return result;
|
||||||
if (!success)
|
|
||||||
readSucceeded = false;
|
|
||||||
|
|
||||||
result[i] = res;
|
|
||||||
}
|
|
||||||
|
|
||||||
return !readSucceeded ? null : result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -106,7 +101,7 @@ namespace Dalamud
|
||||||
/// <returns>Whether or not the write succeeded.</returns>
|
/// <returns>Whether or not the write succeeded.</returns>
|
||||||
public static bool Write<T>(IntPtr address, T obj) where T : struct
|
public static bool Write<T>(IntPtr address, T obj) where T : struct
|
||||||
{
|
{
|
||||||
using var mem = new LocalMemory(SizeOf<T>());
|
using var mem = new LocalMemory(SizeCache<T>.Size);
|
||||||
mem.Write(obj);
|
mem.Write(obj);
|
||||||
return WriteBytes(address, mem.Read());
|
return WriteBytes(address, mem.Read());
|
||||||
}
|
}
|
||||||
|
|
@ -122,11 +117,11 @@ namespace Dalamud
|
||||||
{
|
{
|
||||||
if (objArray == null || objArray.Length == 0)
|
if (objArray == null || objArray.Length == 0)
|
||||||
return true;
|
return true;
|
||||||
var size = SizeOf<T>();
|
var size = SizeCache<T>.Size;
|
||||||
|
using var mem = new LocalMemory(objArray.Length * size);
|
||||||
for (var i = 0; i < objArray.Length; i++)
|
for (var i = 0; i < objArray.Length; i++)
|
||||||
if (!Write(address + i * size, objArray[i]))
|
mem.Write(objArray[i], i * size);
|
||||||
return false;
|
return WriteBytes(address, mem.Read());
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -208,12 +203,23 @@ namespace Dalamud
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type to inspect.</typeparam>
|
/// <typeparam name="T">The type to inspect.</typeparam>
|
||||||
/// <returns>The size of the passed type.</returns>
|
/// <returns>The size of the passed type.</returns>
|
||||||
public static int SizeOf<T>()
|
public static int SizeOf<T>() where T: struct
|
||||||
|
{
|
||||||
|
return SizeCache<T>.Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SizeCache<T>
|
||||||
|
{
|
||||||
|
// ReSharper disable once StaticMemberInGenericType
|
||||||
|
public static readonly int Size;
|
||||||
|
|
||||||
|
static SizeCache()
|
||||||
{
|
{
|
||||||
var type = typeof(T);
|
var type = typeof(T);
|
||||||
if (type.IsEnum)
|
if (type.IsEnum)
|
||||||
type = type.GetEnumUnderlyingType();
|
type = type.GetEnumUnderlyingType();
|
||||||
return Type.GetTypeCode(type) == TypeCode.Boolean ? 1 : Marshal.SizeOf(type);
|
Size = Type.GetTypeCode(type) == TypeCode.Boolean ? 1 : Marshal.SizeOf(type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Imports
|
private static class Imports
|
||||||
|
|
@ -246,9 +252,9 @@ namespace Dalamud
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T Read<T>() => (T)Marshal.PtrToStructure(this.hGlobal, typeof(T));
|
public T Read<T>(int offset = 0) => (T)Marshal.PtrToStructure(this.hGlobal + offset, typeof(T));
|
||||||
public void Write(byte[] data, int index = 0) => Marshal.Copy(data, index, this.hGlobal, this.size);
|
public void Write(byte[] data, int index = 0) => Marshal.Copy(data, index, this.hGlobal, this.size);
|
||||||
public void Write<T>(T data) => Marshal.StructureToPtr(data, this.hGlobal, false);
|
public void Write<T>(T data, int offset = 0) => Marshal.StructureToPtr(data, this.hGlobal + offset, false);
|
||||||
~LocalMemory() => Dispose();
|
~LocalMemory() => Dispose();
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue