Skip to content

Commit 76cf464

Browse files
committed
feat: use unmanaged constraint
1 parent cea70d8 commit 76cf464

File tree

4 files changed

+44
-58
lines changed

4 files changed

+44
-58
lines changed

RszTool/Common/JsonConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public override void Write(Utf8JsonWriter writer, object? value, JsonSerializerO
9292
}
9393

9494

95-
public class EnumJsonConverter<T> : JsonConverter<T> where T : struct
95+
public class EnumJsonConverter<T> : JsonConverter<T> where T : unmanaged
9696
{
9797
public override bool CanConvert(Type typeToConvert)
9898
{

RszTool/Common/MemoryUtils.cs

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace RszTool.Common
66
public static class MemoryUtils
77
{
88
#if !NET5_0_OR_GREATER
9-
public static ref T AsRef<T>(Span<byte> span) where T : struct
9+
public static ref T AsRef<T>(Span<byte> span) where T : unmanaged
1010
{
1111
int size = Unsafe.SizeOf<T>();
1212
if (size > (uint)span.Length)
@@ -21,46 +21,32 @@ public static ref T AsRef<T>(Span<byte> span) where T : struct
2121

2222
#else
2323
[MethodImpl(MethodImplOptions.AggressiveInlining)]
24-
public static ref T AsRef<T>(Span<byte> span) where T : struct => ref MemoryMarshal.AsRef<T>(span);
24+
public static ref T AsRef<T>(Span<byte> span) where T : unmanaged => ref MemoryMarshal.AsRef<T>(span);
2525

2626
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2727
public static Span<T> CreateSpan<T>(ref T reference, int length) => MemoryMarshal.CreateSpan(ref reference, length);
2828
#endif
2929

30-
public static object? BytesToStruct(byte[] buffer, Type type)
31-
{
32-
IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0);
33-
return Marshal.PtrToStructure(ptr, type);
34-
}
35-
36-
/// <summary>
37-
/// bytes转结构体引用
38-
/// </summary>
39-
/// <typeparam name="T"></typeparam>
40-
/// <param name="buffer"></param>
41-
/// <returns></returns>
42-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
43-
public static ref T BytesAsStructure<T>(Span<byte> buffer) where T : struct
44-
{
45-
return ref AsRef<T>(buffer);
46-
}
47-
4830
/// <summary>
4931
/// 结构体转bytes,对bytes的改动会影响原数据
5032
/// </summary>
5133
/// <typeparam name="T"></typeparam>
5234
/// <param name="value"></param>
5335
/// <returns></returns>
54-
public static Span<byte> StructureAsBytes<T>(ref T value) where T : struct
36+
public static unsafe Span<byte> StructureAsBytes<T>(ref T value) where T : unmanaged
5537
{
56-
var span = CreateSpan(ref value, 1);
57-
return MemoryMarshal.AsBytes(span);
38+
/* var span = CreateSpan(ref value, 1);
39+
return MemoryMarshal.AsBytes(span); */
40+
fixed (T* ptr = &value)
41+
{
42+
return new Span<byte>(ptr, Unsafe.SizeOf<T>());
43+
}
5844
}
5945

6046
/// <summary>
6147
/// 结构体引用转byte[]
6248
/// </summary>
63-
public static byte[] StructureRefToBytes<T>(ref T value, byte[]? buffer = null) where T : struct
49+
public static byte[] StructureRefToBytes<T>(ref T value, byte[]? buffer = null) where T : unmanaged
6450
{
6551
int size = Unsafe.SizeOf<T>();
6652
if (buffer == null || buffer.Length < size)
@@ -79,7 +65,7 @@ public static byte[] StructureRefToBytes<T>(ref T value, byte[]? buffer = null)
7965
/// 结构体转byte[]
8066
/// </summary>
8167
[MethodImpl(MethodImplOptions.AggressiveInlining)]
82-
public static byte[] StructureToBytes<T>(T value, byte[]? buffer = null) where T : struct
68+
public static byte[] StructureToBytes<T>(T value, byte[]? buffer = null) where T : unmanaged
8369
{
8470
return StructureRefToBytes(ref value, buffer);
8571
}

RszTool/FileHandler.cs

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -651,14 +651,14 @@ public bool WriteWString(string text)
651651
return WriteSpan(text.AsSpan()) && Write<ushort>(0);
652652
}
653653

654-
public T Read<T>() where T : struct
654+
public T Read<T>() where T : unmanaged
655655
{
656656
T value = default;
657657
Stream.Read(MemoryUtils.StructureAsBytes(ref value));
658658
return value;
659659
}
660660

661-
public T Read<T>(long tell, bool jumpBack = true) where T : struct
661+
public T Read<T>(long tell, bool jumpBack = true) where T : unmanaged
662662
{
663663
long pos = Tell();
664664
Seek(tell);
@@ -667,12 +667,12 @@ public T Read<T>(long tell, bool jumpBack = true) where T : struct
667667
return value;
668668
}
669669

670-
public int Read<T>(ref T value) where T : struct
670+
public int Read<T>(ref T value) where T : unmanaged
671671
{
672672
return Stream.Read(MemoryUtils.StructureAsBytes(ref value));
673673
}
674674

675-
public int Read<T>(long tell, ref T value, bool jumpBack = true) where T : struct
675+
public int Read<T>(long tell, ref T value, bool jumpBack = true) where T : unmanaged
676676
{
677677
long pos = Tell();
678678
Seek(tell);
@@ -681,13 +681,13 @@ public int Read<T>(long tell, ref T value, bool jumpBack = true) where T : struc
681681
return result;
682682
}
683683

684-
public bool Write<T>(T value) where T : struct
684+
public bool Write<T>(T value) where T : unmanaged
685685
{
686686
Stream.Write(MemoryUtils.StructureAsBytes(ref value));
687687
return true;
688688
}
689689

690-
public bool Write<T>(long tell, T value, bool jumpBack = true) where T : struct
690+
public bool Write<T>(long tell, T value, bool jumpBack = true) where T : unmanaged
691691
{
692692
long pos = Tell();
693693
Seek(tell);
@@ -696,13 +696,13 @@ public bool Write<T>(long tell, T value, bool jumpBack = true) where T : struct
696696
return result;
697697
}
698698

699-
public bool Write<T>(ref T value) where T : struct
699+
public bool Write<T>(ref T value) where T : unmanaged
700700
{
701701
Stream.Write(MemoryUtils.StructureAsBytes(ref value));
702702
return true;
703703
}
704704

705-
public bool Write<T>(long tell, ref T value, bool jumpBack = true) where T : struct
705+
public bool Write<T>(long tell, ref T value, bool jumpBack = true) where T : unmanaged
706706
{
707707
long pos = Tell();
708708
Seek(tell);
@@ -773,7 +773,7 @@ public unsafe bool WriteObject(object obj)
773773
/// 获取start..end之间的数据,长度在2-256
774774
/// 涉及unsafe操作,注意内存范围和对齐
775775
/// </summary>
776-
public static Span<byte> GetRangeSpan<TS, TE>(ref TS start, ref TE end) where TS : struct where TE : struct
776+
public static Span<byte> GetRangeSpan<TS, TE>(ref TS start, ref TE end) where TS : unmanaged where TE : unmanaged
777777
{
778778
unsafe
779779
{
@@ -792,7 +792,7 @@ public static Span<byte> GetRangeSpan<TS, TE>(ref TS start, ref TE end) where TS
792792
/// 读取数据到start..end,长度在2-256
793793
/// 涉及unsafe操作,注意内存范围和对齐
794794
/// </summary>
795-
public int ReadRange<TS, TE>(ref TS start, ref TE end) where TS : struct where TE : struct
795+
public int ReadRange<TS, TE>(ref TS start, ref TE end) where TS : unmanaged where TE : unmanaged
796796
{
797797
return Stream.Read(GetRangeSpan(ref start, ref end));
798798
}
@@ -801,7 +801,7 @@ public int ReadRange<TS, TE>(ref TS start, ref TE end) where TS : struct where T
801801
/// 写入start..end范围内的数据,长度在2-256
802802
/// 涉及unsafe操作,注意内存范围和对齐
803803
/// </summary>
804-
public bool WriteRange<TS, TE>(ref TS start, ref TE end) where TS : struct where TE : struct
804+
public bool WriteRange<TS, TE>(ref TS start, ref TE end) where TS : unmanaged where TE : unmanaged
805805
{
806806
Stream.Write(GetRangeSpan(ref start, ref end));
807807
return true;
@@ -821,7 +821,7 @@ public bool WriteBytes(byte[] buffer)
821821
}
822822

823823
/// <summary>读取数组</summary>
824-
public T[] ReadArray<T>(int length) where T : struct
824+
public T[] ReadArray<T>(int length) where T : unmanaged
825825
{
826826
if (length == 0) return [];
827827
T[] array = new T[length];
@@ -830,22 +830,22 @@ public T[] ReadArray<T>(int length) where T : struct
830830
}
831831

832832
/// <summary>读取数组</summary>
833-
public bool ReadArray<T>(T[] array) where T : struct
833+
public bool ReadArray<T>(T[] array) where T : unmanaged
834834
{
835835
Stream.Read(MemoryMarshal.AsBytes((Span<T>)array));
836836
return true;
837837
}
838838

839839
/// <summary>读取二维数组</summary>
840-
public bool ReadArray<T>(T[,] array) where T : struct
840+
public bool ReadArray<T>(T[,] array) where T : unmanaged
841841
{
842842
int length = array.GetLength(0) * array.GetLength(1);
843843
Stream.Read(MemoryMarshal.AsBytes(MemoryUtils.CreateSpan(ref array[0, 0], length)));
844844
return true;
845845
}
846846

847847
/// <summary>读取数组</summary>
848-
public bool ReadArray<T>(T[] array, int start = 0, int length = -1) where T : struct
848+
public bool ReadArray<T>(T[] array, int start = 0, int length = -1) where T : unmanaged
849849
{
850850
if (length == -1 || length > array.Length - start)
851851
{
@@ -856,7 +856,7 @@ public bool ReadArray<T>(T[] array, int start = 0, int length = -1) where T : st
856856
}
857857

858858
/// <summary>读取列表</summary>
859-
public bool ReadList<T>(List<T> list, int count) where T : struct
859+
public bool ReadList<T>(List<T> list, int count) where T : unmanaged
860860
{
861861
for (int i = 0; i < count; i++)
862862
{
@@ -866,21 +866,21 @@ public bool ReadList<T>(List<T> list, int count) where T : struct
866866
}
867867

868868
/// <summary>读取数组</summary>
869-
public bool ReadSpan<T>(Span<T> span) where T : struct
869+
public bool ReadSpan<T>(Span<T> span) where T : unmanaged
870870
{
871871
Stream.Write(MemoryMarshal.AsBytes(span));
872872
return true;
873873
}
874874

875875
/// <summary>写入数组</summary>
876-
public bool WriteArray<T>(T[] array) where T : struct
876+
public bool WriteArray<T>(T[] array) where T : unmanaged
877877
{
878878
Stream.Write(MemoryMarshal.AsBytes((ReadOnlySpan<T>)array));
879879
return true;
880880
}
881881

882882
/// <summary>写入数组</summary>
883-
public bool WriteArray<T>(T[] array, int start = 0, int length = -1) where T : struct
883+
public bool WriteArray<T>(T[] array, int start = 0, int length = -1) where T : unmanaged
884884
{
885885
if (length == -1 || length > array.Length - start)
886886
{
@@ -891,15 +891,15 @@ public bool WriteArray<T>(T[] array, int start = 0, int length = -1) where T : s
891891
}
892892

893893
/// <summary>写入二维数组</summary>
894-
public bool WriteArray<T>(T[,] array) where T : struct
894+
public bool WriteArray<T>(T[,] array) where T : unmanaged
895895
{
896896
int length = array.GetLength(0) * array.GetLength(1);
897897
Stream.Write(MemoryMarshal.AsBytes(MemoryUtils.CreateSpan(ref array[0, 0], length)));
898898
return true;
899899
}
900900

901901
/// <summary>写入列表</summary>
902-
public bool WriteList<T>(List<T> list) where T : struct
902+
public bool WriteList<T>(List<T> list) where T : unmanaged
903903
{
904904
for (int i = 0; i < list.Count; i++)
905905
{
@@ -909,7 +909,7 @@ public bool WriteList<T>(List<T> list) where T : struct
909909
}
910910

911911
/// <summary>写入数组</summary>
912-
public bool WriteSpan<T>(ReadOnlySpan<T> span) where T : struct
912+
public bool WriteSpan<T>(ReadOnlySpan<T> span) where T : unmanaged
913913
{
914914
Stream.Write(MemoryMarshal.AsBytes(span));
915915
return true;
@@ -965,7 +965,7 @@ public long FindFirst(string pattern, in SearchParam param = default, Encoding?
965965
return FindBytes(encoding.GetBytes(pattern), param);
966966
}
967967

968-
public long FindFirst<T>(T pattern, in SearchParam param = default) where T : struct
968+
public long FindFirst<T>(T pattern, in SearchParam param = default) where T : unmanaged
969969
{
970970
return FindBytes(MemoryUtils.StructureRefToBytes(ref pattern), param);
971971
}
@@ -1323,20 +1323,20 @@ public interface IFileHandlerAction
13231323
{
13241324
FileHandler Handler { get; }
13251325
bool Success { get; }
1326-
bool Handle<T>(ref T value) where T : struct;
1326+
bool Handle<T>(ref T value) where T : unmanaged;
13271327
IFileHandlerAction HandleOffsetWString(ref string value);
13281328
}
13291329

13301330

13311331
public static class IFileHandlerActionExtension
13321332
{
1333-
public static IFileHandlerAction Do<T>(this IFileHandlerAction action, ref T value) where T : struct
1333+
public static IFileHandlerAction Do<T>(this IFileHandlerAction action, ref T value) where T : unmanaged
13341334
{
13351335
action.Handle(ref value);
13361336
return action;
13371337
}
13381338

1339-
public static IFileHandlerAction Do<T>(this IFileHandlerAction action, bool condition, ref T value) where T : struct
1339+
public static IFileHandlerAction Do<T>(this IFileHandlerAction action, bool condition, ref T value) where T : unmanaged
13401340
{
13411341
return condition ? action.Do(ref value) : action;
13421342
}
@@ -1347,7 +1347,7 @@ public static IFileHandlerAction Skip(this IFileHandlerAction action, long skip)
13471347
return action;
13481348
}
13491349

1350-
public static IFileHandlerAction? Then<T>(this IFileHandlerAction action, ref T value) where T : struct
1350+
public static IFileHandlerAction? Then<T>(this IFileHandlerAction action, ref T value) where T : unmanaged
13511351
{
13521352
if (action.Handle(ref value))
13531353
{
@@ -1356,7 +1356,7 @@ public static IFileHandlerAction Skip(this IFileHandlerAction action, long skip)
13561356
return null;
13571357
}
13581358

1359-
public static IFileHandlerAction? Then<T>(this IFileHandlerAction action, bool condition, ref T value) where T : struct
1359+
public static IFileHandlerAction? Then<T>(this IFileHandlerAction action, bool condition, ref T value) where T : unmanaged
13601360
{
13611361
return condition ? action.Then(ref value) : action;
13621362
}
@@ -1369,7 +1369,7 @@ public struct FileHandlerRead(FileHandler handler) : IFileHandlerAction
13691369
public int LastResult { get; set; } = -1;
13701370
public readonly bool Success => LastResult != 0;
13711371

1372-
public bool Handle<T>(ref T value) where T : struct
1372+
public bool Handle<T>(ref T value) where T : unmanaged
13731373
{
13741374
LastResult = Handler.Read(ref value);
13751375
return Success;
@@ -1388,7 +1388,7 @@ public struct FileHandlerWrite(FileHandler handler) : IFileHandlerAction
13881388
public FileHandler Handler { get; set; } = handler;
13891389
public bool Success { get; set; }
13901390

1391-
public bool Handle<T>(ref T value) where T : struct
1391+
public bool Handle<T>(ref T value) where T : unmanaged
13921392
{
13931393
Success = Handler.Write(ref value);
13941394
return Success;

RszTool/Models.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public interface IOffsetField
1515
}
1616

1717

18-
public struct OffsetField<T> : IOffsetField where T : struct
18+
public struct OffsetField<T> : IOffsetField where T : unmanaged
1919
{
2020
public OffsetField()
2121
{
@@ -111,7 +111,7 @@ public static bool Rewrite(this IEnumerable<IModel> list, FileHandler handler)
111111
}
112112

113113

114-
public class StructModel<T> : ICloneable, IModel where T : struct
114+
public class StructModel<T> : ICloneable, IModel where T : unmanaged
115115
{
116116
public T Data = default;
117117
public long Start { get; set; } = -1;

0 commit comments

Comments
 (0)