mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2024-11-22 15:02:54 +08:00
Improved conversion of struct arrays to/from byte arrays
This commit is contained in:
parent
df77346daf
commit
9904e92082
@ -1449,21 +1449,31 @@ namespace CodeWalker.GameFiles
|
||||
public static byte[] ConvertArrayToBytes<T>(params T[] items) where T : struct
|
||||
{
|
||||
if (items == null) return null;
|
||||
int size = Marshal.SizeOf(typeof(T));
|
||||
int sizetot = size * items.Length;
|
||||
byte[] arrout = new byte[sizetot];
|
||||
int offset = 0;
|
||||
for (int i = 0; i < items.Length; i++)
|
||||
{
|
||||
byte[] arr = new byte[size];
|
||||
IntPtr ptr = Marshal.AllocHGlobal(size);
|
||||
Marshal.StructureToPtr(items[i], ptr, true);
|
||||
Marshal.Copy(ptr, arr, 0, size);
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
Buffer.BlockCopy(arr, 0, arrout, offset, size);
|
||||
offset += size;
|
||||
}
|
||||
return arrout;
|
||||
|
||||
var size = Marshal.SizeOf(typeof(T)) * items.Length;
|
||||
var b = new byte[size];
|
||||
GCHandle handle = GCHandle.Alloc(items, GCHandleType.Pinned);
|
||||
var h = handle.AddrOfPinnedObject();
|
||||
Marshal.Copy(h, b, 0, size);
|
||||
handle.Free();
|
||||
return b;
|
||||
|
||||
|
||||
//int size = Marshal.SizeOf(typeof(T));
|
||||
//int sizetot = size * items.Length;
|
||||
//byte[] arrout = new byte[sizetot];
|
||||
//int offset = 0;
|
||||
//for (int i = 0; i < items.Length; i++)
|
||||
//{
|
||||
// byte[] arr = new byte[size];
|
||||
// IntPtr ptr = Marshal.AllocHGlobal(size);
|
||||
// Marshal.StructureToPtr(items[i], ptr, true);
|
||||
// Marshal.Copy(ptr, arr, 0, size);
|
||||
// Marshal.FreeHGlobal(ptr);
|
||||
// Buffer.BlockCopy(arr, 0, arrout, offset, size);
|
||||
// offset += size;
|
||||
//}
|
||||
//return arrout;
|
||||
}
|
||||
|
||||
|
||||
@ -1487,11 +1497,16 @@ namespace CodeWalker.GameFiles
|
||||
{
|
||||
T[] items = new T[count];
|
||||
int itemsize = Marshal.SizeOf(typeof(T));
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
int off = offset + i * itemsize;
|
||||
items[i] = ConvertData<T>(data, off);
|
||||
}
|
||||
//for (int i = 0; i < count; i++)
|
||||
//{
|
||||
// int off = offset + i * itemsize;
|
||||
// items[i] = ConvertData<T>(data, off);
|
||||
//}
|
||||
GCHandle handle = GCHandle.Alloc(items, GCHandleType.Pinned);
|
||||
var h = handle.AddrOfPinnedObject();
|
||||
Marshal.Copy(data, offset, h, itemsize * count);
|
||||
handle.Free();
|
||||
|
||||
return items;
|
||||
}
|
||||
public static T[] ConvertDataArray<T>(Meta meta, MetaName name, Array_StructurePointer array) where T : struct
|
||||
|
@ -15848,11 +15848,17 @@ namespace CodeWalker.GameFiles
|
||||
{
|
||||
T[] items = new T[count];
|
||||
int itemsize = Marshal.SizeOf(typeof(T));
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
int off = offset + i * itemsize;
|
||||
items[i] = ConvertDataRaw<T>(data, off);
|
||||
}
|
||||
//for (int i = 0; i < count; i++)
|
||||
//{
|
||||
// int off = offset + i * itemsize;
|
||||
// items[i] = ConvertDataRaw<T>(data, off);
|
||||
//}
|
||||
|
||||
GCHandle handle = GCHandle.Alloc(items, GCHandleType.Pinned);
|
||||
var h = handle.AddrOfPinnedObject();
|
||||
Marshal.Copy(data, offset, h, itemsize * count);
|
||||
handle.Free();
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
|
@ -369,15 +369,22 @@ namespace CodeWalker.GameFiles
|
||||
//var result2 = new T[count];
|
||||
//Buffer.BlockCopy(data, 0, result2, 0, (int)length); //error: "object must be an array of primitives" :(
|
||||
|
||||
//var result = new T[count];
|
||||
//GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
|
||||
//var h = handle.AddrOfPinnedObject();
|
||||
//for (uint i = 0; i < count; i++)
|
||||
//{
|
||||
// result[i] = Marshal.PtrToStructure<T>(h + (int)(i * structsize));
|
||||
//}
|
||||
//handle.Free();
|
||||
|
||||
var result = new T[count];
|
||||
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
|
||||
GCHandle handle = GCHandle.Alloc(result, GCHandleType.Pinned);
|
||||
var h = handle.AddrOfPinnedObject();
|
||||
for (uint i = 0; i < count; i++)
|
||||
{
|
||||
result[i] = Marshal.PtrToStructure<T>(h + (int)(i * structsize));
|
||||
}
|
||||
Marshal.Copy(data, 0, h, (int)length);
|
||||
handle.Free();
|
||||
|
||||
|
||||
if (cache) arrayPool[(long)position] = result;
|
||||
|
||||
return result;
|
||||
@ -388,13 +395,21 @@ namespace CodeWalker.GameFiles
|
||||
var result = new T[count];
|
||||
var length = count * structsize;
|
||||
byte[] data = ReadBytes((int)length);
|
||||
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
|
||||
|
||||
//GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
|
||||
//var h = handle.AddrOfPinnedObject();
|
||||
//for (uint i = 0; i < count; i++)
|
||||
//{
|
||||
// result[i] = Marshal.PtrToStructure<T>(h + (int)(i * structsize));
|
||||
//}
|
||||
//handle.Free();
|
||||
|
||||
GCHandle handle = GCHandle.Alloc(result, GCHandleType.Pinned);
|
||||
var h = handle.AddrOfPinnedObject();
|
||||
for (uint i = 0; i < count; i++)
|
||||
{
|
||||
result[i] = Marshal.PtrToStructure<T>(h + (int)(i * structsize));
|
||||
}
|
||||
Marshal.Copy(data, 0, h, (int)length);
|
||||
handle.Free();
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user