Skip to content

Commit

Permalink
Merge pull request #52 from danipen/improve-interop
Browse files Browse the repository at this point in the history
Improve interop for win-x86 and win-x64
  • Loading branch information
danipen authored May 8, 2023
2 parents 0a9d0d6 + d9e7464 commit c2d1d7d
Show file tree
Hide file tree
Showing 7 changed files with 271 additions and 34 deletions.
Binary file not shown.
Binary file not shown.
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
269 changes: 251 additions & 18 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 class OnigInterop
internal static 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 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);
}

[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);
internal static IOnigInterop Instance { get; private set; }

[DllImport("onigwrap", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
internal static extern void onigwrap_free(IntPtr regex);
static OnigInterop()
{
Instance = CreateInterop();
}

[DllImport("onigwrap", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
internal static extern int onigwrap_search(IntPtr regex, char* text, int offset, int length, IntPtr region);
static IOnigInterop CreateInterop()
{
if (!IsWindowsPlatform())
return new InteropUnix();

[DllImport("onigwrap", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
internal static extern int onigwrap_num_regs(IntPtr region);
if (Environment.Is64BitProcess)
return new InteropWin64();

[DllImport("onigwrap", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
internal static extern int onigwrap_pos(IntPtr region, int nth);
return new InteropWin32();
}

[DllImport("onigwrap", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
internal static extern int onigwrap_len(IntPtr region, int nth);
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, 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);
}
}
}
20 changes: 12 additions & 8 deletions src/TextMateSharp/TextMateSharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,13 @@ TextMateSharp uses a wrapper around Oniguruma regex engine. Read below to learn

<ItemGroup>
<!-- native oniguruma library for Windows -->
<ContentWithTargetPath Include="Internal\Oniguruma\Native\win-x86\onigwrap.dll" Condition=" '$(OS)' == 'Windows_NT' ">
<ContentWithTargetPath Include="Internal\Oniguruma\Native\win-x86\onigwrap-x86.dll" Condition=" '$(OS)' == 'Windows_NT' ">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>onigwrap.dll</TargetPath>
<TargetPath>onigwrap-x86.dll</TargetPath>
</ContentWithTargetPath>
<ContentWithTargetPath Include="Internal\Oniguruma\Native\win-x64\onigwrap-x64.dll" Condition=" '$(OS)' == 'Windows_NT' ">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>onigwrap-x64.dll</TargetPath>
</ContentWithTargetPath>
<!-- native oniguruma library for Linux -->
<ContentWithTargetPath Include="Internal\Oniguruma\Native\linux\libonigwrap.so" Condition=" '$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' ">
Expand All @@ -40,16 +44,16 @@ TextMateSharp uses a wrapper around Oniguruma regex engine. Read below to learn

<ItemGroup>
<!-- native oniguruma library for Windows-x86 in nuget package -->
<Content Include="Internal\Oniguruma\Native\win-x86\onigwrap.dll">
<Link>onigwrap.dll</Link>
<PackagePath>runtimes/win-x86/native/onigwrap.dll</PackagePath>
<Content Include="Internal\Oniguruma\Native\win-x86\onigwrap-x86.dll">
<Link>onigwrap-x86.dll</Link>
<PackagePath>runtimes/win-x86/native/onigwrap-x86.dll</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<!-- native oniguruma library for Windows-x64 in nuget package -->
<Content Include="Internal\Oniguruma\Native\win-x64\onigwrap.dll">
<Link>onigwrap.dll</Link>
<PackagePath>runtimes/win-x64/native/onigwrap.dll</PackagePath>
<Content Include="Internal\Oniguruma\Native\win-x64\onigwrap-x64.dll">
<Link>onigwrap-x64.dll</Link>
<PackagePath>runtimes/win-x64/native/onigwrap-x64.dll</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
Expand Down

0 comments on commit c2d1d7d

Please sign in to comment.