From b527d5550e4d426e32cf45d30a28e2a72d9fd3d3 Mon Sep 17 00:00:00 2001 From: Thomas Corwin Date: Wed, 22 Aug 2018 19:00:53 -0400 Subject: [PATCH 1/3] Added NativeLibraryLoader package for netstandard2.0. --- Zstandard.Net/Zstandard.Net.csproj | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Zstandard.Net/Zstandard.Net.csproj b/Zstandard.Net/Zstandard.Net.csproj index 456eddd..c0cebd8 100644 --- a/Zstandard.Net/Zstandard.Net.csproj +++ b/Zstandard.Net/Zstandard.Net.csproj @@ -24,14 +24,21 @@ x86\%(FileName)%(Extension) PreserveNewest + - + - + + + + 1.0.10 + + + From 2a24e387099435a0f4571e5a9332795ea4ea6f8c Mon Sep 17 00:00:00 2001 From: Thomas Corwin Date: Wed, 22 Aug 2018 19:11:40 -0400 Subject: [PATCH 2/3] Added support for Linux and macOS. Just need native binaries. --- Zstandard.Net/ZstandardInterop.cs | 132 +++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 3 deletions(-) diff --git a/Zstandard.Net/ZstandardInterop.cs b/Zstandard.Net/ZstandardInterop.cs index 348e993..c71d1e8 100644 --- a/Zstandard.Net/ZstandardInterop.cs +++ b/Zstandard.Net/ZstandardInterop.cs @@ -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(string name) => ZStandard.LoadFunction(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\x86\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) @@ -16,6 +34,7 @@ static ZstandardInterop() LoadLibraryEx(file, IntPtr.Zero, LoadLibraryFlags.LOAD_LIBRARY_SEARCH_APPLICATION_DIR); } } +#endif [StructLayout(LayoutKind.Sequential)] public class Buffer @@ -29,8 +48,8 @@ public static void ThrowIfError(UIntPtr code) { if (ZSTD_isError(code)) { - var errorPtr = ZSTD_getErrorName(code); - var errorMsg = Marshal.PtrToStringAnsi(errorPtr); + IntPtr errorPtr = ZSTD_getErrorName(code); + string errorMsg = Marshal.PtrToStringAnsi(errorPtr); throw new IOException(errorMsg); } } @@ -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("ZSTD_versionNumber")(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate int ZSTDmaxCLevel(); + public static int ZSTD_maxCLevel() => Call("ZSTD_maxCLevel")(); + + //----------------------------------------------------------------------------------------- + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate IntPtr ZSTDcreateCStream(); + public static IntPtr ZSTD_createCStream() => Call("ZSTD_createCStream")(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate UIntPtr ZSTDinitCStream(IntPtr zcs, int compressionLevel); + public static UIntPtr ZSTD_initCStream(IntPtr zcs, int compressionLevel) => Call("ZSTD_initCStream")(zcs, compressionLevel); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate UIntPtr ZSTDfreeCStream(IntPtr zcs); + public static UIntPtr ZSTD_freeCStream(IntPtr zcs) => Call("ZSTD_freeCStream")(zcs); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate UIntPtr ZSTDCStreamInSize(); + public static UIntPtr ZSTD_CStreamInSize() => Call("ZSTD_CStreamInSize")(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate UIntPtr ZSTDCStreamOutSize(); + public static UIntPtr ZSTD_CStreamOutSize() => Call("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("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("ZSTD_createCDict")(dictBuffer, dictSize, compressionLevel); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate UIntPtr ZSTDfreeCDict(IntPtr cdict); + public static UIntPtr ZSTD_freeCDict(IntPtr cdict) => Call("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("ZSTD_initCStream_usingCDict")(zcs, cdict); + + //----------------------------------------------------------------------------------------- + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate IntPtr ZSTDcreateDStream(); + public static IntPtr ZSTD_createDStream() => Call("ZSTD_createDStream")(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate UIntPtr ZSTDinitDStream(IntPtr zds); + public static UIntPtr ZSTD_initDStream(IntPtr zds) => Call("ZSTD_initDStream")(zds); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate UIntPtr ZSTDfreeDStream(IntPtr zds); + public static UIntPtr ZSTD_freeDStream(IntPtr zds) => Call("ZSTD_freeDStream")(zds); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate UIntPtr ZSTDDStreamInSize(); + public static UIntPtr ZSTD_DStreamInSize() => Call("ZSTD_DStreamInSize")(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate UIntPtr ZSTDDStreamOutSize(); + public static UIntPtr ZSTD_DStreamOutSize() => Call("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("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("ZSTD_createDDict")(dictBuffer, dictSize); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate UIntPtr ZSTDfreeDDict(IntPtr ddict); + public static UIntPtr ZSTD_freeDDict(IntPtr ddict) => Call("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("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("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("ZSTD_endStream")(zcs, outputBuffer); + + //----------------------------------------------------------------------------------------- + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate bool ZSTDisError(UIntPtr code); + public static bool ZSTD_isError(UIntPtr code) => Call("ZSTD_isError")(code); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate IntPtr ZSTDgetErrorName(UIntPtr code); + public static IntPtr ZSTD_getErrorName(UIntPtr code) => Call("ZSTD_getErrorName")(code); + +#else [Flags] private enum LoadLibraryFlags : uint { @@ -131,7 +256,7 @@ 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)] @@ -139,5 +264,6 @@ private enum LoadLibraryFlags : uint [DllImport("libzstd", CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr ZSTD_getErrorName(UIntPtr code); +#endif } } From 0f4f8ca253cebfe2459d2d44fabaa7b4f6068560 Mon Sep 17 00:00:00 2001 From: Thomas Corwin Date: Sat, 25 Aug 2018 13:31:01 -0400 Subject: [PATCH 3/3] Fixed a typo, and undid refactoring changes. --- Zstandard.Net/ZstandardInterop.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Zstandard.Net/ZstandardInterop.cs b/Zstandard.Net/ZstandardInterop.cs index c71d1e8..2c7a1d2 100644 --- a/Zstandard.Net/ZstandardInterop.cs +++ b/Zstandard.Net/ZstandardInterop.cs @@ -17,7 +17,7 @@ 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\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(); @@ -48,8 +48,8 @@ public static void ThrowIfError(UIntPtr code) { if (ZSTD_isError(code)) { - IntPtr errorPtr = ZSTD_getErrorName(code); - string errorMsg = Marshal.PtrToStringAnsi(errorPtr); + var errorPtr = ZSTD_getErrorName(code); + var errorMsg = Marshal.PtrToStringAnsi(errorPtr); throw new IOException(errorMsg); } }