Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions wrappers/cs/Common.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Runtime.InteropServices;

namespace Pack
{
public static class Common
{
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);

public static void GetPackLibraryVersion(ref byte majorVersion, ref byte minorVersion, ref byte patchVersion)
{
getPackLibraryVersion(ref majorVersion, ref minorVersion, ref patchVersion);
}
public static PackResult GetPackInfo(in string filePath, out PackHeader header)
{

if (string.IsNullOrEmpty(filePath))
throw new ArgumentNullException(nameof(filePath));
header = new();
return (PackResult)readPackHeader(filePath, ref header);
}
}
}
15 changes: 15 additions & 0 deletions wrappers/cs/PackHeader.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}
14 changes: 14 additions & 0 deletions wrappers/cs/PackItemHeader.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}
115 changes: 115 additions & 0 deletions wrappers/cs/PackReader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
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(in 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(in ulong index)
{
if (index >= ItemCount)
throw new ArgumentOutOfRangeException(nameof(index));
return getPackItemDataSize(Handle, index);
}
public string GetItemPath(in ulong index)
{
if (index >= ItemCount)
throw new ArgumentOutOfRangeException(nameof(index));

var path = getPackItemPath(Handle, index);
return Marshal.PtrToStringAnsi(path);
}

public PackResult ReadItemData(in string path, ref byte[] data, in 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(in ulong index, ref byte[] data, in uint thread = 0)
{
var result = readPackItemData(Handle, index, data, thread);
if (result != PackResult.Success)
return result;
return PackResult.Success;
}

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(in string path, in 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 static PackResult UnpackFiles(in string filePath, in bool printProgress)
{
if (string.IsNullOrEmpty(filePath))
throw new ArgumentNullException(nameof(filePath));
return unpackFiles(filePath, printProgress);
}
}
}
22 changes: 22 additions & 0 deletions wrappers/cs/PackResult.cs
Original file line number Diff line number Diff line change
@@ -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
}
}
22 changes: 22 additions & 0 deletions wrappers/cs/PackWriter.cs
Original file line number Diff line number Diff line change
@@ -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);

public delegate void OnPackFile(UInt64 index, object o);
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));
if (filePaths.Length == 0)
throw new ArgumentNullException(nameof(filePaths));

var res = packFiles(packPath, (ulong)filePaths.Length / 2, filePaths, zipTreshold, printProgress, callback);
return res;
}
}
}