From e50fd0f158dd9ac77fd2061ee776d2ebacf1752c Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 6 May 2023 08:11:45 +0200 Subject: [PATCH] Calculate the interop instance to use in runtime --- .../Internal/Oniguruma/ORegex.cs | 16 +- .../Internal/Oniguruma/OnigInterop.cs | 267 ++++++++++++++++-- 2 files changed, 258 insertions(+), 25 deletions(-) diff --git a/src/TextMateSharp/Internal/Oniguruma/ORegex.cs b/src/TextMateSharp/Internal/Oniguruma/ORegex.cs index eaf1efa..f408784 100644 --- a/src/TextMateSharp/Internal/Oniguruma/ORegex.cs +++ b/src/TextMateSharp/Internal/Oniguruma/ORegex.cs @@ -34,7 +34,7 @@ public unsafe ORegex(string pattern, bool ignoreCase = true, bool multiline = fa { fixed (char* patternPtr = pattern) { - _regex = OnigInterop.onigwrap_create( + _regex = OnigInterop.Instance.onigwrap_create( patternPtr, Encoding.Unicode.GetByteCount(patternPtr, pattern.Length), ignoreCaseArg, @@ -60,11 +60,11 @@ public unsafe OnigResult SafeSearch(string text, int offset = 0) lock (_syncObject) { if (_region == IntPtr.Zero) - _region = OnigInterop.onigwrap_region_new(); + _region = OnigInterop.Instance.onigwrap_region_new(); fixed (char* textPtr = text) { - OnigInterop.onigwrap_search( + OnigInterop.Instance.onigwrap_search( _regex, textPtr, Encoding.Unicode.GetByteCount(textPtr, offset), @@ -72,17 +72,17 @@ public unsafe OnigResult SafeSearch(string text, int offset = 0) _region); } - var captureCount = OnigInterop.onigwrap_num_regs(_region); + var captureCount = OnigInterop.Instance.onigwrap_num_regs(_region); Region region = null; for (var capture = 0; capture < captureCount; capture++) { - var pos = OnigInterop.onigwrap_pos(_region, capture); + var pos = OnigInterop.Instance.onigwrap_pos(_region, capture); if (capture == 0 && pos < 0) return null; - int len = pos == -1 ? 0 : OnigInterop.onigwrap_len(_region, capture); + int len = pos == -1 ? 0 : OnigInterop.Instance.onigwrap_len(_region, capture); if (region == null) region = new Region(captureCount); @@ -110,10 +110,10 @@ protected virtual void Dispose(bool disposing) _disposed = true; if (_region != IntPtr.Zero) - OnigInterop.onigwrap_region_free(_region); + OnigInterop.Instance.onigwrap_region_free(_region); if (_regex != IntPtr.Zero) - OnigInterop.onigwrap_free(_regex); + OnigInterop.Instance.onigwrap_free(_regex); } } } diff --git a/src/TextMateSharp/Internal/Oniguruma/OnigInterop.cs b/src/TextMateSharp/Internal/Oniguruma/OnigInterop.cs index a4a43db..0155752 100644 --- a/src/TextMateSharp/Internal/Oniguruma/OnigInterop.cs +++ b/src/TextMateSharp/Internal/Oniguruma/OnigInterop.cs @@ -3,30 +3,263 @@ namespace TextMateSharp.Internal.Oniguruma { + internal unsafe interface IOnigInterop + { + IntPtr onigwrap_create(char* pattern, int len, int ignoreCase, int multiline); + IntPtr onigwrap_region_new(); + void onigwrap_region_free(IntPtr region); + void onigwrap_free(IntPtr regex); + int onigwrap_search(IntPtr regex, char* text, int offset, int length, IntPtr region); + int onigwrap_num_regs(IntPtr region); + int onigwrap_pos(IntPtr region, int nth); + int onigwrap_len(IntPtr region, int nth); + } + internal unsafe class OnigInterop { - [DllImport("onigwrap", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] - internal static extern IntPtr onigwrap_create(char* pattern, int len, int ignoreCase, int multiline); + internal static IOnigInterop Instance { get; private set; } + + static OnigInterop() + { + Instance = CreateInterop(); + } + + static IOnigInterop CreateInterop() + { + if (!IsWindowsPlatform()) + return new InteropUnix(); + + if (Environment.Is64BitProcess) + return new InteropWin64(); + + return new InteropWin32(); + } + + static bool IsWindowsPlatform() + { + switch (Environment.OSVersion.Platform) + { + case PlatformID.Win32Windows: + case PlatformID.Win32NT: + case PlatformID.Win32S: + return true; + default: + return false; + } + } + + internal unsafe class InteropWin64 : IOnigInterop + { + const string ONIGWRAP = "onigwrap-x64"; + const CharSet charSet = CharSet.Unicode; + const CallingConvention convention = CallingConvention.Cdecl; + + IntPtr IOnigInterop.onigwrap_create(char* pattern, int len, int ignoreCase, int multiline) + { + return onigwrap_create(pattern, len, ignoreCase, multiline); + } + + void IOnigInterop.onigwrap_free(IntPtr regex) + { + onigwrap_free(regex); + } + + int IOnigInterop.onigwrap_len(IntPtr region, int nth) + { + return onigwrap_len(region, nth); + } + + int IOnigInterop.onigwrap_num_regs(IntPtr region) + { + return onigwrap_num_regs(region); + } + + int IOnigInterop.onigwrap_pos(IntPtr region, int nth) + { + return onigwrap_pos(region, nth); + } + + void IOnigInterop.onigwrap_region_free(IntPtr region) + { + onigwrap_region_free(region); + } + + IntPtr IOnigInterop.onigwrap_region_new() + { + return onigwrap_region_new(); + } + + int IOnigInterop.onigwrap_search(IntPtr regex, char* text, int offset, int length, IntPtr region) + { + return onigwrap_search(regex, text, offset, length, region); + } + + + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern IntPtr onigwrap_create(char* pattern, int len, int ignoreCase, int multiline); + + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern IntPtr onigwrap_region_new(); + + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern void onigwrap_region_free(IntPtr region); + + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern void onigwrap_free(IntPtr regex); + + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern int onigwrap_search(IntPtr regex, char* text, int offset, int length, IntPtr region); + + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern int onigwrap_num_regs(IntPtr region); + + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern int onigwrap_pos(IntPtr region, int nth); + + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern int onigwrap_len(IntPtr region, int nth); + } + internal unsafe class InteropWin32 : IOnigInterop + { + const string ONIGWRAP = "onigwrap-x86"; + const CharSet charSet = CharSet.Unicode; + const CallingConvention convention = CallingConvention.Cdecl; + + IntPtr IOnigInterop.onigwrap_create(char* pattern, int len, int ignoreCase, int multiline) + { + return onigwrap_create(pattern, len, ignoreCase, multiline); + } + + void IOnigInterop.onigwrap_free(IntPtr regex) + { + onigwrap_free(regex); + } + + int IOnigInterop.onigwrap_len(IntPtr region, int nth) + { + return onigwrap_len(region, nth); + } + + int IOnigInterop.onigwrap_num_regs(IntPtr region) + { + return onigwrap_num_regs(region); + } + + int IOnigInterop.onigwrap_pos(IntPtr region, int nth) + { + return onigwrap_pos(region, nth); + } + + void IOnigInterop.onigwrap_region_free(IntPtr region) + { + onigwrap_region_free(region); + } + + IntPtr IOnigInterop.onigwrap_region_new() + { + return onigwrap_region_new(); + } + + int IOnigInterop.onigwrap_search(IntPtr regex, char* text, int offset, int length, IntPtr region) + { + return onigwrap_search(regex, text, offset, length, region); + } + + + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern IntPtr onigwrap_create(char* pattern, int len, int ignoreCase, int multiline); + + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern IntPtr onigwrap_region_new(); + + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern void onigwrap_region_free(IntPtr region); + + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern void onigwrap_free(IntPtr regex); + + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern int onigwrap_search(IntPtr regex, char* text, int offset, int length, IntPtr region); + + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern int onigwrap_num_regs(IntPtr region); + + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern int onigwrap_pos(IntPtr region, int nth); + + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern int onigwrap_len(IntPtr region, int nth); + } + internal unsafe class InteropUnix : IOnigInterop + { + const string ONIGWRAP = "onigwrap"; + const CharSet charSet = CharSet.Unicode; + const CallingConvention convention = CallingConvention.Cdecl; + + IntPtr IOnigInterop.onigwrap_create(char* pattern, int len, int ignoreCase, int multiline) + { + return onigwrap_create(pattern, len, ignoreCase, multiline); + } + + void IOnigInterop.onigwrap_free(IntPtr regex) + { + onigwrap_free(regex); + } + + int IOnigInterop.onigwrap_len(IntPtr region, int nth) + { + return onigwrap_len(region, nth); + } + + int IOnigInterop.onigwrap_num_regs(IntPtr region) + { + return onigwrap_num_regs(region); + } + + int IOnigInterop.onigwrap_pos(IntPtr region, int nth) + { + return onigwrap_pos(region, nth); + } + + void IOnigInterop.onigwrap_region_free(IntPtr region) + { + onigwrap_region_free(region); + } + + IntPtr IOnigInterop.onigwrap_region_new() + { + return onigwrap_region_new(); + } + + int IOnigInterop.onigwrap_search(IntPtr regex, char* text, int offset, int length, IntPtr region) + { + return onigwrap_search(regex, text, offset, length, region); + } + + + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern IntPtr onigwrap_create(char* pattern, int len, int ignoreCase, int multiline); + + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern IntPtr onigwrap_region_new(); - [DllImport("onigwrap", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] - internal static extern IntPtr onigwrap_region_new(); - - [DllImport("onigwrap", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] - internal static extern void onigwrap_region_free(IntPtr region); + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern void onigwrap_region_free(IntPtr region); - [DllImport("onigwrap", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] - internal static extern void onigwrap_free(IntPtr regex); + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern void onigwrap_free(IntPtr regex); - [DllImport("onigwrap", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] - internal static extern int onigwrap_search(IntPtr regex, char* text, int offset, int length, IntPtr region); + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern int onigwrap_search(IntPtr regex, char* text, int offset, int length, IntPtr region); - [DllImport("onigwrap", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] - internal static extern int onigwrap_num_regs(IntPtr region); + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern int onigwrap_num_regs(IntPtr region); - [DllImport("onigwrap", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] - internal static extern int onigwrap_pos(IntPtr region, int nth); + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern int onigwrap_pos(IntPtr region, int nth); - [DllImport("onigwrap", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] - internal static extern int onigwrap_len(IntPtr region, int nth); + [DllImport(ONIGWRAP, CharSet = charSet, CallingConvention = convention)] + static extern int onigwrap_len(IntPtr region, int nth); + } } } \ No newline at end of file