From 3c6745f2851b9cff29260883a1fd7c25e622d6da Mon Sep 17 00:00:00 2001 From: Animeska34 <59974154+Animeska34@users.noreply.github.com> Date: Fri, 12 Jan 2024 21:11:49 +0200 Subject: [PATCH 1/3] Add updated C# Wrapper --- wrappers/cs/Common.cs | 25 +++++ wrappers/cs/PackHeader.cs | 15 +++ wrappers/cs/PackItemHeader.cs | 14 +++ wrappers/cs/PackReader.cs | 181 ++++++++++++++++++++++++++++++++++ wrappers/cs/PackResult.cs | 22 +++++ wrappers/cs/PackWriter.cs | 22 +++++ 6 files changed, 279 insertions(+) create mode 100644 wrappers/cs/Common.cs create mode 100644 wrappers/cs/PackHeader.cs create mode 100644 wrappers/cs/PackItemHeader.cs create mode 100644 wrappers/cs/PackReader.cs create mode 100644 wrappers/cs/PackResult.cs create mode 100644 wrappers/cs/PackWriter.cs diff --git a/wrappers/cs/Common.cs b/wrappers/cs/Common.cs new file mode 100644 index 0000000..affa8fe --- /dev/null +++ b/wrappers/cs/Common.cs @@ -0,0 +1,25 @@ +using System; +using System.Runtime.InteropServices; + +namespace Pack +{ + public static class Common + { + public const string LibraryPath = "pack.dll"; + [DllImport(LibraryPath)] private static extern void getPackLibraryVersion(ref byte majorVersion, ref byte minorVersion, ref byte patchVersion); + [DllImport(LibraryPath)] private static extern byte readPackHeader(string filePath, ref PackHeader header); + + public static void GetPackLibraryVersion(ref byte majorVersion, ref byte minorVersion, ref byte patchVersion) + { + getPackLibraryVersion(ref majorVersion, ref minorVersion, ref patchVersion); + } + public static PackResult GetPackInfo(string filePath, out PackHeader header) + { + + if (string.IsNullOrEmpty(filePath)) + throw new ArgumentNullException(nameof(filePath)); + header = new(); + return (PackResult)readPackHeader(filePath, ref header); + } + } +} diff --git a/wrappers/cs/PackHeader.cs b/wrappers/cs/PackHeader.cs new file mode 100644 index 0000000..4cce394 --- /dev/null +++ b/wrappers/cs/PackHeader.cs @@ -0,0 +1,15 @@ +using System.Runtime.InteropServices; + +namespace Pack +{ + [StructLayout(LayoutKind.Sequential)] + public struct PackHeader + { + public uint magic; + public byte versionMajor; + public byte versionMinor; + public byte versionPatch; + public byte isBigEndian; + public ulong itemCount; + } +} diff --git a/wrappers/cs/PackItemHeader.cs b/wrappers/cs/PackItemHeader.cs new file mode 100644 index 0000000..c82ca95 --- /dev/null +++ b/wrappers/cs/PackItemHeader.cs @@ -0,0 +1,14 @@ +using System.Runtime.InteropServices; + +namespace Pack +{ + [StructLayout(LayoutKind.Sequential)] + public struct PackItemHeader + { + public uint zipState; + public uint dataSize; + public byte pathSize; + public byte isReference; + public ulong dataOffset; + } +} diff --git a/wrappers/cs/PackReader.cs b/wrappers/cs/PackReader.cs new file mode 100644 index 0000000..389f91b --- /dev/null +++ b/wrappers/cs/PackReader.cs @@ -0,0 +1,181 @@ +using System; +using System.Runtime.InteropServices; + +namespace Pack +{ + public class PackReader + { + const CallingConvention conversion = CallingConvention.Cdecl; + [DllImport(Common.LibraryPath, CallingConvention = conversion)] protected static extern byte createFilePackReader(string filePath, bool isResourcesDirectory, uint threadCount, ref IntPtr packReader); + [DllImport(Common.LibraryPath, CallingConvention = conversion)] protected static extern void destroyPackReader(IntPtr packReader); + [DllImport(Common.LibraryPath, CallingConvention = conversion)] protected static extern ulong getPackItemCount(IntPtr packReader); + [DllImport(Common.LibraryPath, CallingConvention = conversion)] protected static extern bool getPackItemIndex(IntPtr packReader, string path, ref ulong index); + [DllImport(Common.LibraryPath, CallingConvention = conversion)] protected static extern uint getPackItemDataSize(IntPtr packReader, ulong index); + [DllImport(Common.LibraryPath, CallingConvention = conversion)] protected static extern uint getPackItemZipSize(IntPtr packReader, ulong index); + [DllImport(Common.LibraryPath, CallingConvention = conversion)] protected static extern ulong getPackItemFileOffset(IntPtr packReader, ulong index); + [DllImport(Common.LibraryPath, CallingConvention = conversion)] protected static extern bool isPackItemReference(IntPtr packReader, ulong index); + + [DllImport(Common.LibraryPath, CallingConvention = conversion)] protected static extern IntPtr getPackItemPath(IntPtr packReader, ulong index); + [DllImport(Common.LibraryPath, CallingConvention = conversion)] protected static extern PackResult readPackItemData(IntPtr packReader, ulong index, byte[] data, uint threadIndex); + [DllImport(Common.LibraryPath, CallingConvention = conversion)] protected static extern PackResult unpackFiles(string filePath, bool printProgress); + + protected IntPtr Handle; + + public ulong ItemCount => getPackItemCount(Handle); + + public PackReader(string filePath, bool isResourceDirectory = false, uint threadCount = 1) + { + var handle = IntPtr.Zero; + var result = createFilePackReader(filePath, isResourceDirectory, threadCount, ref handle); + + if (result != 0) + throw new Exception(result.ToString()); + + Handle = handle; + } + ~PackReader() + { + destroyPackReader(Handle); + } + + public bool GetItemIndex(string path, ref ulong index) + { + if (string.IsNullOrEmpty(path)) + throw new ArgumentNullException(nameof(path)); + if (path.Length > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(path)); + return getPackItemIndex(Handle, path, ref index); + } + public uint GetItemDataSize(ulong index) + { + if (index >= ItemCount) + throw new ArgumentOutOfRangeException(nameof(index)); + return getPackItemDataSize(Handle, index); + } + public string GetItemPath(ulong index) + { + if (index >= ItemCount) + throw new ArgumentOutOfRangeException(nameof(index)); + + var path = getPackItemPath(Handle, index); + return Marshal.PtrToStringAnsi(path); + } + + public PackResult ReadItemData(string path, ref byte[] data, uint thread = 0) + { + if (string.IsNullOrEmpty(path)) + throw new ArgumentNullException(nameof(path)); + if (path.Length > byte.MaxValue) + throw new ArgumentOutOfRangeException(nameof(path)); + + ulong index = 0; + if (getPackItemIndex(Handle, path, ref index)) + { + return ReadItemData(index, ref data, thread); + } + return PackResult.FailedToGetItem; + + } + + public PackResult ReadItemData(ulong index, ref byte[] data, uint thread = 0) + { + var result = readPackItemData(Handle, index, data, thread); + if (result != PackResult.Success) + return result; + return PackResult.Success; + } + + public byte[]? ReadItemData(ulong index, uint thread = 0) + { + uint size = getPackItemDataSize(Handle, index); + byte[] data = new byte[size]; + ReadItemData(index, ref data, thread); + return data; + } + public byte[]? ReadItemData(string path, uint thread = 0) + { + ulong index = 0; + if (getPackItemIndex(Handle, path, ref index)) + { + uint size = getPackItemDataSize(Handle, index); + byte[] data = new byte[size]; + ReadItemData(index, ref data, thread); + return data; + } + return null; + + } + /* + public PackResult ReadItemData(string path, ref byte[] data) + { + var buffer = IntPtr.Zero; + uint size = (uint) data.Length; + + var result = ReadItemData(path, ref buffer, ref size); + + if (result != PackResult.Success) + return result; + + if (size > int.MaxValue) + throw new ApplicationException("Unsupported item data size"); + + data = new byte[size]; + Marshal.Copy(buffer, data, 0, (int)size); + return PackResult.Success; + } + + public PackResult ReadItemData(ulong index, ref byte[] data) + { + var buffer = IntPtr.Zero; + uint size = (uint)data.Length; + + var result = ReadItemData(index, ref buffer); + + if (result != PackResult.Success) + return result; + + if (size > int.MaxValue) + throw new ApplicationException("Unsupported item data size"); + + data = new byte[size]; + Marshal.Copy(buffer, data, 0, (int)size); + return PackResult.Success; + } + + public PackResult ReadItemData(ulong index, ref string data) + { + byte[] buffer = null; + var result = ReadItemData(index, ref buffer); + + if (result != PackResult.Success) + return result; + + data = Encoding.UTF8.GetString(buffer); + return PackResult.Success; + } + public PackResult ReadItemData(string path, ref string data) + { + byte[] buffer = null; + var result = ReadItemData(path, ref buffer); + + if (result != PackResult.Success) + return result; + + data = Encoding.UTF8.GetString(buffer); + return PackResult.Success; + } + */ + /* + public void FreeBuffers() + { + freePackReaderBuffers(Handle); + } + */ + public static PackResult UnpackFiles(string filePath, bool printProgress) + { + if (string.IsNullOrEmpty(filePath)) + throw new ArgumentNullException(nameof(filePath)); + return unpackFiles(filePath, printProgress); + } + } +} diff --git a/wrappers/cs/PackResult.cs b/wrappers/cs/PackResult.cs new file mode 100644 index 0000000..ab225d5 --- /dev/null +++ b/wrappers/cs/PackResult.cs @@ -0,0 +1,22 @@ +namespace Pack +{ + public enum PackResult + { + Success = 0, + FailedToAllocate = 1, + FailedToCreateZSTD = 2, + FailedToCreateFile = 3, + FailedToOpenFile = 4, + FailedToWriteFile = 5, + FailedToReadFile = 6, + FailedToSeekFile = 7, + FailedToGetDirectory = 8, + FailedToDecompress = 9, + FailedToGetItem = 10, + BadDataSize = 11, + BadFileType = 12, + BadFileVersion = 13, + BadFileEndianness = 14, + PackResultCount = 15 + } +} diff --git a/wrappers/cs/PackWriter.cs b/wrappers/cs/PackWriter.cs new file mode 100644 index 0000000..4c54520 --- /dev/null +++ b/wrappers/cs/PackWriter.cs @@ -0,0 +1,22 @@ +using System; +using System.Runtime.InteropServices; + +namespace Pack +{ + public static class PackWriter + { + [DllImport(Common.LibraryPath, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] private static extern PackResult packFiles(string packPath, ulong fileCount, string[] filePaths, float zipThreshold, bool printProgress, OnPackFile callback, object ret); + + public delegate void OnPackFile(UInt64 index, object o); + public static PackResult PackFiles(string packPath, string[] filePaths, float zipTreshold, bool printProgress, OnPackFile callback, object ret) + { + if (string.IsNullOrEmpty(packPath)) + throw new ArgumentNullException(nameof(packPath)); + if (filePaths.Length == 0) + throw new ArgumentNullException(nameof(filePaths)); + + var res = packFiles(packPath, (ulong)filePaths.Length / 2, filePaths, zipTreshold, printProgress, callback, ret); + return res; + } + } +} From 686679c4358e4db5a21a6d47f45990449af595fa Mon Sep 17 00:00:00 2001 From: Animeska34 <59974154+Animeska34@users.noreply.github.com> Date: Thu, 16 May 2024 12:18:26 +0300 Subject: [PATCH 2/3] C# Wrapper WIP * Fix MacOS Marshal exception --- wrappers/cs/Common.cs | 4 +- wrappers/cs/PackReader.cs | 82 ++++----------------------------------- wrappers/cs/PackWriter.cs | 4 +- 3 files changed, 12 insertions(+), 78 deletions(-) diff --git a/wrappers/cs/Common.cs b/wrappers/cs/Common.cs index affa8fe..a3adaaf 100644 --- a/wrappers/cs/Common.cs +++ b/wrappers/cs/Common.cs @@ -5,7 +5,7 @@ namespace Pack { public static class Common { - public const string LibraryPath = "pack.dll"; + public const string LibraryPath = "pack"; [DllImport(LibraryPath)] private static extern void getPackLibraryVersion(ref byte majorVersion, ref byte minorVersion, ref byte patchVersion); [DllImport(LibraryPath)] private static extern byte readPackHeader(string filePath, ref PackHeader header); @@ -13,7 +13,7 @@ public static void GetPackLibraryVersion(ref byte majorVersion, ref byte minorVe { getPackLibraryVersion(ref majorVersion, ref minorVersion, ref patchVersion); } - public static PackResult GetPackInfo(string filePath, out PackHeader header) + public static PackResult GetPackInfo(in string filePath, out PackHeader header) { if (string.IsNullOrEmpty(filePath)) diff --git a/wrappers/cs/PackReader.cs b/wrappers/cs/PackReader.cs index 389f91b..30e9b60 100644 --- a/wrappers/cs/PackReader.cs +++ b/wrappers/cs/PackReader.cs @@ -38,7 +38,7 @@ public PackReader(string filePath, bool isResourceDirectory = false, uint thread destroyPackReader(Handle); } - public bool GetItemIndex(string path, ref ulong index) + public bool GetItemIndex(in string path, ref ulong index) { if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path)); @@ -46,13 +46,13 @@ public bool GetItemIndex(string path, ref ulong index) throw new ArgumentOutOfRangeException(nameof(path)); return getPackItemIndex(Handle, path, ref index); } - public uint GetItemDataSize(ulong index) + public uint GetItemDataSize(in ulong index) { if (index >= ItemCount) throw new ArgumentOutOfRangeException(nameof(index)); return getPackItemDataSize(Handle, index); } - public string GetItemPath(ulong index) + public string GetItemPath(in ulong index) { if (index >= ItemCount) throw new ArgumentOutOfRangeException(nameof(index)); @@ -61,7 +61,7 @@ public string GetItemPath(ulong index) return Marshal.PtrToStringAnsi(path); } - public PackResult ReadItemData(string path, ref byte[] data, uint thread = 0) + public PackResult ReadItemData(in string path, ref byte[] data, in uint thread = 0) { if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path)); @@ -77,7 +77,7 @@ public PackResult ReadItemData(string path, ref byte[] data, uint thread = 0) } - public PackResult ReadItemData(ulong index, ref byte[] data, uint thread = 0) + public PackResult ReadItemData(in ulong index, ref byte[] data, in uint thread = 0) { var result = readPackItemData(Handle, index, data, thread); if (result != PackResult.Success) @@ -85,14 +85,14 @@ public PackResult ReadItemData(ulong index, ref byte[] data, uint thread = 0) return PackResult.Success; } - public byte[]? ReadItemData(ulong index, uint thread = 0) + public byte[]? ReadItemData(in ulong index, in uint thread = 0) { uint size = getPackItemDataSize(Handle, index); byte[] data = new byte[size]; ReadItemData(index, ref data, thread); return data; } - public byte[]? ReadItemData(string path, uint thread = 0) + public byte[]? ReadItemData(in string path, in uint thread = 0) { ulong index = 0; if (getPackItemIndex(Handle, path, ref index)) @@ -105,73 +105,7 @@ public PackResult ReadItemData(ulong index, ref byte[] data, uint thread = 0) return null; } - /* - public PackResult ReadItemData(string path, ref byte[] data) - { - var buffer = IntPtr.Zero; - uint size = (uint) data.Length; - - var result = ReadItemData(path, ref buffer, ref size); - - if (result != PackResult.Success) - return result; - - if (size > int.MaxValue) - throw new ApplicationException("Unsupported item data size"); - - data = new byte[size]; - Marshal.Copy(buffer, data, 0, (int)size); - return PackResult.Success; - } - - public PackResult ReadItemData(ulong index, ref byte[] data) - { - var buffer = IntPtr.Zero; - uint size = (uint)data.Length; - - var result = ReadItemData(index, ref buffer); - - if (result != PackResult.Success) - return result; - - if (size > int.MaxValue) - throw new ApplicationException("Unsupported item data size"); - - data = new byte[size]; - Marshal.Copy(buffer, data, 0, (int)size); - return PackResult.Success; - } - - public PackResult ReadItemData(ulong index, ref string data) - { - byte[] buffer = null; - var result = ReadItemData(index, ref buffer); - - if (result != PackResult.Success) - return result; - - data = Encoding.UTF8.GetString(buffer); - return PackResult.Success; - } - public PackResult ReadItemData(string path, ref string data) - { - byte[] buffer = null; - var result = ReadItemData(path, ref buffer); - - if (result != PackResult.Success) - return result; - - data = Encoding.UTF8.GetString(buffer); - return PackResult.Success; - } - */ - /* - public void FreeBuffers() - { - freePackReaderBuffers(Handle); - } - */ - public static PackResult UnpackFiles(string filePath, bool printProgress) + public static PackResult UnpackFiles(in string filePath, in bool printProgress) { if (string.IsNullOrEmpty(filePath)) throw new ArgumentNullException(nameof(filePath)); diff --git a/wrappers/cs/PackWriter.cs b/wrappers/cs/PackWriter.cs index 4c54520..d7d9493 100644 --- a/wrappers/cs/PackWriter.cs +++ b/wrappers/cs/PackWriter.cs @@ -5,10 +5,10 @@ namespace Pack { public static class PackWriter { - [DllImport(Common.LibraryPath, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] private static extern PackResult packFiles(string packPath, ulong fileCount, string[] filePaths, float zipThreshold, bool printProgress, OnPackFile callback, object ret); + [DllImport(Common.LibraryPath, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] private static extern PackResult packFiles(string packPath, ulong fileCount, string[] filePaths, float zipThreshold, bool printProgress, OnPackFile callback); public delegate void OnPackFile(UInt64 index, object o); - public static PackResult PackFiles(string packPath, string[] filePaths, float zipTreshold, bool printProgress, OnPackFile callback, object ret) + public static PackResult PackFiles(in string packPath, in string[] filePaths, in float zipTreshold, in bool printProgress, OnPackFile callback) { if (string.IsNullOrEmpty(packPath)) throw new ArgumentNullException(nameof(packPath)); From 9c8d139d4862535ec767f543f8d5c1255752c06e Mon Sep 17 00:00:00 2001 From: Animeska34 <59974154+Animeska34@users.noreply.github.com> Date: Thu, 16 May 2024 12:37:37 +0300 Subject: [PATCH 3/3] Update PackWriter.cs --- wrappers/cs/PackWriter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/cs/PackWriter.cs b/wrappers/cs/PackWriter.cs index d7d9493..c46cff1 100644 --- a/wrappers/cs/PackWriter.cs +++ b/wrappers/cs/PackWriter.cs @@ -15,7 +15,7 @@ public static PackResult PackFiles(in string packPath, in string[] filePaths, in if (filePaths.Length == 0) throw new ArgumentNullException(nameof(filePaths)); - var res = packFiles(packPath, (ulong)filePaths.Length / 2, filePaths, zipTreshold, printProgress, callback, ret); + var res = packFiles(packPath, (ulong)filePaths.Length / 2, filePaths, zipTreshold, printProgress, callback); return res; } }