diff --git a/SngTool/SngLib/LargeFile.cs b/SngTool/SngLib/LargeFile.cs index 903a2c5..25db200 100644 --- a/SngTool/SngLib/LargeFile.cs +++ b/SngTool/SngLib/LargeFile.cs @@ -1,3 +1,6 @@ +using System; +using System.IO; +using System.Threading.Tasks; using System.Buffers; using Cysharp.Collections; diff --git a/SngTool/SngLib/NativeByteArray/NativeByteArray.cs b/SngTool/SngLib/NativeByteArray/NativeByteArray.cs index d8de498..622657c 100644 --- a/SngTool/SngLib/NativeByteArray/NativeByteArray.cs +++ b/SngTool/SngLib/NativeByteArray/NativeByteArray.cs @@ -1,5 +1,9 @@ #nullable enable +#if NET6_0_OR_GREATER +#define WITH_INTEROPSERVICES_NATIVEMEMORY +#endif + using System; using System.Buffers; using System.Collections.Generic; @@ -57,11 +61,22 @@ public NativeByteArray(long length, bool skipZeroClear = false, bool addMemoryPr { if (skipZeroClear) { +#if WITH_INTEROPSERVICES_NATIVEMEMORY buffer = (byte*)NativeMemory.Alloc(checked((nuint)length), 1); +#else + int byteCount = (int)checked((uint)length) * 1; + buffer = (byte*)Marshal.AllocHGlobal(byteCount); +#endif } else { +#if WITH_INTEROPSERVICES_NATIVEMEMORY buffer = (byte*)NativeMemory.AllocZeroed(checked((nuint)length), 1); +#else + int byteCount = (int)checked((uint)length) * 1; + buffer = (byte*)Marshal.AllocHGlobal(byteCount); + Unsafe.InitBlockUnaligned(buffer, 0, (uint)byteCount); +#endif } if (addMemoryPressure) @@ -109,7 +124,19 @@ public bool Resize(long newLength) // This vastly reduces the total number of re-allocations // with the drawback of increasing memory usage somewhat newLength = NextPO2(newLength); +#if WITH_INTEROPSERVICES_NATIVEMEMORY buffer = (byte*)NativeMemory.Realloc(buffer, (nuint)newLength); +#else + int byteCount = (int)newLength; + byte* newBuffer = (byte*)Marshal.AllocHGlobal(byteCount); + + Span src = new Span(buffer, (int)length); + Span dst = new Span(newBuffer, (int)byteCount); + src.CopyTo(dst); + + Marshal.FreeHGlobal((IntPtr)buffer); + buffer = newBuffer; +#endif allocatedLength = newLength; length = newLength; @@ -291,7 +318,11 @@ void DisposeCore() isDisposed = true; if (Unsafe.IsNullRef(ref Unsafe.AsRef(buffer))) return; +#if WITH_INTEROPSERVICES_NATIVEMEMORY NativeMemory.Free(buffer); +#else + Marshal.FreeHGlobal((IntPtr)buffer); +#endif if (addMemoryPressure) { GC.RemoveMemoryPressure(length * Unsafe.SizeOf()); diff --git a/SngTool/SngLib/NativeByteArray/NativeByteArrayExtensions.cs b/SngTool/SngLib/NativeByteArray/NativeByteArrayExtensions.cs index a6bd073..40a6769 100644 --- a/SngTool/SngLib/NativeByteArray/NativeByteArrayExtensions.cs +++ b/SngTool/SngLib/NativeByteArray/NativeByteArrayExtensions.cs @@ -1,6 +1,6 @@ #nullable enable -#if !NETSTANDARD2_0 && !UNITY_2019_1_OR_NEWER +#if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER using System; using System.IO; diff --git a/SngTool/SngLib/SngFile.cs b/SngTool/SngLib/SngFile.cs index 65084c4..1dd5eb0 100644 --- a/SngTool/SngLib/SngFile.cs +++ b/SngTool/SngLib/SngFile.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using Cysharp.Collections; @@ -11,8 +12,8 @@ public class SngFile : IDisposable public bool metadataAvailable; - public Dictionary Metadata = new(); - public Dictionary Files = new(); + public Dictionary Metadata = new Dictionary(); + public Dictionary Files = new Dictionary(); public void AddFile(string fileName, NativeByteArray? data) { diff --git a/SngTool/SngLib/SngSerializer.cs b/SngTool/SngLib/SngSerializer.cs index 5b929d0..48b3ced 100644 --- a/SngTool/SngLib/SngSerializer.cs +++ b/SngTool/SngLib/SngSerializer.cs @@ -1,8 +1,12 @@ using System; +using System.Collections.Generic; using System.IO; using System.IO.MemoryMappedFiles; +using System.Linq; using System.Numerics; using System.Text; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using BinaryEx; using Cysharp.Collections; @@ -75,7 +79,16 @@ private static void DoMaskData(Span data, long filePos) Vector dataVector = new Vector(data.Slice(byteIndex)); Vector maskedData = dataVector ^ dataIndexVectors![lookupIndex & lookupSizeMask]; +#if NET5_0_OR_GREATER maskedData.CopyTo(data.Slice(byteIndex)); +#else + var destination = data.Slice(byteIndex); + if (destination.Length < Vector.Count) + { + throw new ArgumentException("Destination is too short"); + } + Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(data.Slice(byteIndex)), maskedData); +#endif } long endOfVecFilePos = filePos + totalVecElements;