Skip to content

Commit

Permalink
Calculate the interop instance to use in runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
danipen committed May 6, 2023
1 parent 7dd83eb commit e50fd0f
Show file tree
Hide file tree
Showing 2 changed files with 258 additions and 25 deletions.
16 changes: 8 additions & 8 deletions src/TextMateSharp/Internal/Oniguruma/ORegex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -60,29 +60,29 @@ 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),
Encoding.Unicode.GetByteCount(textPtr, text.Length),
_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);
Expand Down Expand Up @@ -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);
}
}
}
Expand Down
267 changes: 250 additions & 17 deletions src/TextMateSharp/Internal/Oniguruma/OnigInterop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}

0 comments on commit e50fd0f

Please sign in to comment.