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
11 changes: 9 additions & 2 deletions Zstandard.Net/Zstandard.Net.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,21 @@
<Link>x86\%(FileName)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<!-- TODO: Add native binaries for linux and macOS, but only for netstndard. -->
</ItemGroup>

<ItemGroup>
<None Include="build\**\*" Pack="true" PackagePath="build\" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="System.Buffers" Version="4.5.0" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="NativeLibraryLoader">
<Version>1.0.10</Version>
</PackageReference>
</ItemGroup>

</Project>
128 changes: 127 additions & 1 deletion Zstandard.Net/ZstandardInterop.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
#if NETSTANDARD2_0
using NativeLibraryLoader;
#endif

namespace Zstandard.Net
{
internal static class ZstandardInterop
{
#if NETSTANDARD2_0
private static T Call<T>(string name) => ZStandard.LoadFunction<T>(name);

private static NativeLibrary ZStandard
{
get
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && RuntimeInformation.OSArchitecture == Architecture.X86) return new NativeLibrary(@"build\x86\libzstd.dll");
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && RuntimeInformation.OSArchitecture == Architecture.X64) return new NativeLibrary(@"build\x64\libzstd.dll");
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) return new NativeLibrary(@"build\"); //TODO: Edit to relative file location.
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) return new NativeLibrary(@"build\"); //TODO: Edit to relative file location.
else throw new PlatformNotSupportedException();
}
}
#else
static ZstandardInterop()
{
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
Expand All @@ -16,6 +34,7 @@ static ZstandardInterop()
LoadLibraryEx(file, IntPtr.Zero, LoadLibraryFlags.LOAD_LIBRARY_SEARCH_APPLICATION_DIR);
}
}
#endif

[StructLayout(LayoutKind.Sequential)]
public class Buffer
Expand All @@ -38,6 +57,112 @@ public static void ThrowIfError(UIntPtr code)
//-----------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------

#if NETSTANDARD2_0
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate uint ZSTDversionNumber();
public static uint ZSTD_versionNumber() => Call<ZSTDversionNumber>("ZSTD_versionNumber")();

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate int ZSTDmaxCLevel();
public static int ZSTD_maxCLevel() => Call<ZSTDmaxCLevel>("ZSTD_maxCLevel")();

//-----------------------------------------------------------------------------------------

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate IntPtr ZSTDcreateCStream();
public static IntPtr ZSTD_createCStream() => Call<ZSTDcreateCStream>("ZSTD_createCStream")();

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate UIntPtr ZSTDinitCStream(IntPtr zcs, int compressionLevel);
public static UIntPtr ZSTD_initCStream(IntPtr zcs, int compressionLevel) => Call<ZSTDinitCStream>("ZSTD_initCStream")(zcs, compressionLevel);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate UIntPtr ZSTDfreeCStream(IntPtr zcs);
public static UIntPtr ZSTD_freeCStream(IntPtr zcs) => Call<ZSTDfreeCStream>("ZSTD_freeCStream")(zcs);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate UIntPtr ZSTDCStreamInSize();
public static UIntPtr ZSTD_CStreamInSize() => Call<ZSTDCStreamInSize>("ZSTD_CStreamInSize")();

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate UIntPtr ZSTDCStreamOutSize();
public static UIntPtr ZSTD_CStreamOutSize() => Call<ZSTDCStreamOutSize>("ZSTD_CStreamOutSize")();

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate UIntPtr ZSTDcompressStream(IntPtr zcs, [MarshalAs(UnmanagedType.LPStruct)] Buffer outputBuffer, [MarshalAs(UnmanagedType.LPStruct)] Buffer inputBuffer);
public static UIntPtr ZSTD_compressStream(IntPtr zcs, [MarshalAs(UnmanagedType.LPStruct)] Buffer outputBuffer, [MarshalAs(UnmanagedType.LPStruct)] Buffer inputBuffer) => Call<ZSTDcompressStream>("ZSTD_compressStream")(zcs, outputBuffer, inputBuffer);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate IntPtr ZSTDcreateCDict(IntPtr dictBuffer, UIntPtr dictSize, int compressionLevel);
public static IntPtr ZSTD_createCDict(IntPtr dictBuffer, UIntPtr dictSize, int compressionLevel) => Call<ZSTDcreateCDict>("ZSTD_createCDict")(dictBuffer, dictSize, compressionLevel);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate UIntPtr ZSTDfreeCDict(IntPtr cdict);
public static UIntPtr ZSTD_freeCDict(IntPtr cdict) => Call<ZSTDfreeCDict>("ZSTD_freeCDict")(cdict);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate UIntPtr ZSTDinitCStream_usingCDict(IntPtr zcs, IntPtr cdict);
public static UIntPtr ZSTD_initCStream_usingCDict(IntPtr zcs, IntPtr cdict) => Call<ZSTDinitCStream_usingCDict>("ZSTD_initCStream_usingCDict")(zcs, cdict);

//-----------------------------------------------------------------------------------------

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate IntPtr ZSTDcreateDStream();
public static IntPtr ZSTD_createDStream() => Call<ZSTDcreateDStream>("ZSTD_createDStream")();

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate UIntPtr ZSTDinitDStream(IntPtr zds);
public static UIntPtr ZSTD_initDStream(IntPtr zds) => Call<ZSTDinitDStream>("ZSTD_initDStream")(zds);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate UIntPtr ZSTDfreeDStream(IntPtr zds);
public static UIntPtr ZSTD_freeDStream(IntPtr zds) => Call<ZSTDfreeDStream>("ZSTD_freeDStream")(zds);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate UIntPtr ZSTDDStreamInSize();
public static UIntPtr ZSTD_DStreamInSize() => Call<ZSTDDStreamInSize>("ZSTD_DStreamInSize")();

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate UIntPtr ZSTDDStreamOutSize();
public static UIntPtr ZSTD_DStreamOutSize() => Call<ZSTDDStreamOutSize>("ZSTD_DStreamOutSize")();

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate UIntPtr ZSTDdecompressStream(IntPtr zds, [MarshalAs(UnmanagedType.LPStruct)] Buffer outputBuffer, [MarshalAs(UnmanagedType.LPStruct)] Buffer inputBuffer);
public static UIntPtr ZSTD_decompressStream(IntPtr zds, [MarshalAs(UnmanagedType.LPStruct)] Buffer outputBuffer, [MarshalAs(UnmanagedType.LPStruct)] Buffer inputBuffer) => Call<ZSTDdecompressStream>("ZSTD_decompressStream")(zds, outputBuffer, inputBuffer);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate IntPtr ZSTDcreateDDict(IntPtr dictBuffer, UIntPtr dictSize);
public static IntPtr ZSTD_createDDict(IntPtr dictBuffer, UIntPtr dictSize) => Call<ZSTDcreateDDict>("ZSTD_createDDict")(dictBuffer, dictSize);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate UIntPtr ZSTDfreeDDict(IntPtr ddict);
public static UIntPtr ZSTD_freeDDict(IntPtr ddict) => Call<ZSTDfreeDDict>("ZSTD_freeDDict")(ddict);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate UIntPtr ZSTDinitDStream_usingDDict(IntPtr zds, IntPtr ddict);
public static UIntPtr ZSTD_initDStream_usingDDict(IntPtr zds, IntPtr ddict) => Call<ZSTDinitDStream_usingDDict>("ZSTD_initDStream_usingDDict")(zds, ddict);

//-----------------------------------------------------------------------------------------

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate UIntPtr ZSTDflushStream(IntPtr zcs, [MarshalAs(UnmanagedType.LPStruct)] Buffer outputBuffer);
public static UIntPtr ZSTD_flushStream(IntPtr zcs, [MarshalAs(UnmanagedType.LPStruct)] Buffer outputBuffer) => Call<ZSTDflushStream>("ZSTD_flushStream")(zcs, outputBuffer);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate UIntPtr ZSTDendStream(IntPtr zcs, [MarshalAs(UnmanagedType.LPStruct)] Buffer outputBuffer);
public static UIntPtr ZSTD_endStream(IntPtr zcs, [MarshalAs(UnmanagedType.LPStruct)] Buffer outputBuffer) => Call<ZSTDendStream>("ZSTD_endStream")(zcs, outputBuffer);

//-----------------------------------------------------------------------------------------

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate bool ZSTDisError(UIntPtr code);
public static bool ZSTD_isError(UIntPtr code) => Call<ZSTDisError>("ZSTD_isError")(code);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate IntPtr ZSTDgetErrorName(UIntPtr code);
public static IntPtr ZSTD_getErrorName(UIntPtr code) => Call<ZSTDgetErrorName>("ZSTD_getErrorName")(code);

#else
[Flags]
private enum LoadLibraryFlags : uint
{
Expand Down Expand Up @@ -131,13 +256,14 @@ private enum LoadLibraryFlags : uint

[DllImport("libzstd", CallingConvention = CallingConvention.Cdecl)]
public static extern UIntPtr ZSTD_endStream(IntPtr zcs, [MarshalAs(UnmanagedType.LPStruct)] Buffer outputBuffer);

//-----------------------------------------------------------------------------------------

[DllImport("libzstd", CallingConvention = CallingConvention.Cdecl)]
internal static extern bool ZSTD_isError(UIntPtr code);

[DllImport("libzstd", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr ZSTD_getErrorName(UIntPtr code);
#endif
}
}