diff --git a/Dalamud/SafeMemory.cs b/Dalamud/SafeMemory.cs
index 03eb398cd..c8a06895d 100644
--- a/Dalamud/SafeMemory.cs
+++ b/Dalamud/SafeMemory.cs
@@ -59,7 +59,7 @@ namespace Dalamud
/// The resulting object.
/// Whether or not the read succeeded.
public static bool Read(IntPtr address, out T result) where T : struct {
- if (!ReadBytes(address, SizeOf(), out var buffer)) {
+ if (!ReadBytes(address, SizeCache.Size, out var buffer)) {
result = default;
return false;
}
@@ -82,19 +82,14 @@ namespace Dalamud
public static T[] Read(IntPtr address, int count) where T : struct
{
var size = SizeOf();
+ if (!ReadBytes(address, count * size, out var buffer))
+ return null;
var result = new T[count];
-
- var readSucceeded = true;
- for (var i = 0; i < count; i++) {
- var success = Read(address + i * size, out var res);
-
- if (!success)
- readSucceeded = false;
-
- result[i] = res;
- }
-
- return !readSucceeded ? null : result;
+ using var mem = new LocalMemory(buffer.Length);
+ mem.Write(buffer);
+ for (var i = 0; i < result.Length; i++)
+ result[i] = mem.Read(i * size);
+ return result;
}
///
@@ -106,7 +101,7 @@ namespace Dalamud
/// Whether or not the write succeeded.
public static bool Write(IntPtr address, T obj) where T : struct
{
- using var mem = new LocalMemory(SizeOf());
+ using var mem = new LocalMemory(SizeCache.Size);
mem.Write(obj);
return WriteBytes(address, mem.Read());
}
@@ -122,11 +117,11 @@ namespace Dalamud
{
if (objArray == null || objArray.Length == 0)
return true;
- var size = SizeOf();
+ var size = SizeCache.Size;
+ using var mem = new LocalMemory(objArray.Length * size);
for (var i = 0; i < objArray.Length; i++)
- if (!Write(address + i * size, objArray[i]))
- return false;
- return true;
+ mem.Write(objArray[i], i * size);
+ return WriteBytes(address, mem.Read());
}
///
@@ -208,12 +203,23 @@ namespace Dalamud
///
/// The type to inspect.
/// The size of the passed type.
- public static int SizeOf()
+ public static int SizeOf() where T: struct
{
- var type = typeof(T);
- if (type.IsEnum)
- type = type.GetEnumUnderlyingType();
- return Type.GetTypeCode(type) == TypeCode.Boolean ? 1 : Marshal.SizeOf(type);
+ return SizeCache.Size;
+ }
+
+ private static class SizeCache
+ {
+ // ReSharper disable once StaticMemberInGenericType
+ public static readonly int Size;
+
+ static SizeCache()
+ {
+ var type = typeof(T);
+ if (type.IsEnum)
+ type = type.GetEnumUnderlyingType();
+ Size = Type.GetTypeCode(type) == TypeCode.Boolean ? 1 : Marshal.SizeOf(type);
+ }
}
private static class Imports
@@ -246,9 +252,9 @@ namespace Dalamud
return bytes;
}
- public T Read() => (T)Marshal.PtrToStructure(this.hGlobal, typeof(T));
+ public T Read(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(T data) => Marshal.StructureToPtr(data, this.hGlobal, false);
+ public void Write(T data, int offset = 0) => Marshal.StructureToPtr(data, this.hGlobal + offset, false);
~LocalMemory() => Dispose();
public void Dispose()