Add NHunspell NuGet package.

This commit is contained in:
_aLfa_ 2014-09-20 13:23:30 +02:00 committed by XhmikosR
parent b0b65e5044
commit 0f3879e08e
19 changed files with 175 additions and 3064 deletions

5
.gitignore vendored
View File

@ -17,3 +17,8 @@ SubtitleEdit-*-setup.exe
/SubtitleEdit.tgz
/tabspace.exe
/src/Languages/LanguageMaster.xml
# NuGet
/src/.nuget/NuGet.exe
/src/.nuget/NuGet.Config
/src/packages

144
src/.nuget/NuGet.targets Normal file
View File

@ -0,0 +1,144 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">$(MSBuildProjectDirectory)\..\</SolutionDir>
<!-- Enable the restore command to run before builds -->
<RestorePackages Condition=" '$(RestorePackages)' == '' ">false</RestorePackages>
<!-- Property that enables building a package from a project -->
<BuildPackage Condition=" '$(BuildPackage)' == '' ">false</BuildPackage>
<!-- Determines if package restore consent is required to restore packages -->
<RequireRestoreConsent Condition=" '$(RequireRestoreConsent)' != 'false' ">true</RequireRestoreConsent>
<!-- Download NuGet.exe if it does not already exist -->
<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">true</DownloadNuGetExe>
</PropertyGroup>
<ItemGroup Condition=" '$(PackageSources)' == '' ">
<!-- Package sources used to restore packages. By default, registered sources under %APPDATA%\NuGet\NuGet.Config will be used -->
<!-- The official NuGet package source (https://www.nuget.org/api/v2/) will be excluded if package sources are specified and it does not appear in the list -->
<!--
<PackageSource Include="https://www.nuget.org/api/v2/" />
<PackageSource Include="https://my-nuget-source/nuget/" />
-->
</ItemGroup>
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT'">
<!-- Windows specific commands -->
<NuGetToolsPath>$([System.IO.Path]::Combine($(SolutionDir), ".nuget"))</NuGetToolsPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(OS)' != 'Windows_NT'">
<!-- We need to launch nuget.exe with the mono command if we're not on windows -->
<NuGetToolsPath>$(SolutionDir).nuget</NuGetToolsPath>
</PropertyGroup>
<PropertyGroup>
<PackagesProjectConfig Condition=" '$(OS)' == 'Windows_NT'">$(MSBuildProjectDirectory)\packages.$(MSBuildProjectName.Replace(' ', '_')).config</PackagesProjectConfig>
<PackagesProjectConfig Condition=" '$(OS)' != 'Windows_NT'">$(MSBuildProjectDirectory)\packages.$(MSBuildProjectName).config</PackagesProjectConfig>
</PropertyGroup>
<PropertyGroup>
<PackagesConfig Condition="Exists('$(MSBuildProjectDirectory)\packages.config')">$(MSBuildProjectDirectory)\packages.config</PackagesConfig>
<PackagesConfig Condition="Exists('$(PackagesProjectConfig)')">$(PackagesProjectConfig)</PackagesConfig>
</PropertyGroup>
<PropertyGroup>
<!-- NuGet command -->
<NuGetExePath Condition=" '$(NuGetExePath)' == '' ">$(NuGetToolsPath)\NuGet.exe</NuGetExePath>
<PackageSources Condition=" $(PackageSources) == '' ">@(PackageSource)</PackageSources>
<NuGetCommand Condition=" '$(OS)' == 'Windows_NT'">"$(NuGetExePath)"</NuGetCommand>
<NuGetCommand Condition=" '$(OS)' != 'Windows_NT' ">mono --runtime=v4.0.30319 "$(NuGetExePath)"</NuGetCommand>
<PackageOutputDir Condition="$(PackageOutputDir) == ''">$(TargetDir.Trim('\\'))</PackageOutputDir>
<RequireConsentSwitch Condition=" $(RequireRestoreConsent) == 'true' ">-RequireConsent</RequireConsentSwitch>
<NonInteractiveSwitch Condition=" '$(VisualStudioVersion)' != '' AND '$(OS)' == 'Windows_NT' ">-NonInteractive</NonInteractiveSwitch>
<PaddedSolutionDir Condition=" '$(OS)' == 'Windows_NT'">"$(SolutionDir) "</PaddedSolutionDir>
<PaddedSolutionDir Condition=" '$(OS)' != 'Windows_NT' ">"$(SolutionDir)"</PaddedSolutionDir>
<!-- Commands -->
<RestoreCommand>$(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir)</RestoreCommand>
<BuildCommand>$(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols</BuildCommand>
<!-- We need to ensure packages are restored prior to assembly resolve -->
<BuildDependsOn Condition="$(RestorePackages) == 'true'">
RestorePackages;
$(BuildDependsOn);
</BuildDependsOn>
<!-- Make the build depend on restore packages -->
<BuildDependsOn Condition="$(BuildPackage) == 'true'">
$(BuildDependsOn);
BuildPackage;
</BuildDependsOn>
</PropertyGroup>
<Target Name="CheckPrerequisites">
<!-- Raise an error if we're unable to locate nuget.exe -->
<Error Condition="'$(DownloadNuGetExe)' != 'true' AND !Exists('$(NuGetExePath)')" Text="Unable to locate '$(NuGetExePath)'" />
<!--
Take advantage of MsBuild's build dependency tracking to make sure that we only ever download nuget.exe once.
This effectively acts as a lock that makes sure that the download operation will only happen once and all
parallel builds will have to wait for it to complete.
-->
<MsBuild Targets="_DownloadNuGet" Projects="$(MSBuildThisFileFullPath)" Properties="Configuration=NOT_IMPORTANT;DownloadNuGetExe=$(DownloadNuGetExe)" />
</Target>
<Target Name="_DownloadNuGet">
<DownloadNuGet OutputFilename="$(NuGetExePath)" Condition=" '$(DownloadNuGetExe)' == 'true' AND !Exists('$(NuGetExePath)')" />
</Target>
<Target Name="RestorePackages" DependsOnTargets="CheckPrerequisites">
<Exec Command="$(RestoreCommand)"
Condition="'$(OS)' != 'Windows_NT' And Exists('$(PackagesConfig)')" />
<Exec Command="$(RestoreCommand)"
LogStandardErrorAsError="true"
Condition="'$(OS)' == 'Windows_NT' And Exists('$(PackagesConfig)')" />
</Target>
<Target Name="BuildPackage" DependsOnTargets="CheckPrerequisites">
<Exec Command="$(BuildCommand)"
Condition=" '$(OS)' != 'Windows_NT' " />
<Exec Command="$(BuildCommand)"
LogStandardErrorAsError="true"
Condition=" '$(OS)' == 'Windows_NT' " />
</Target>
<UsingTask TaskName="DownloadNuGet" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<OutputFilename ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Reference Include="System.Core" />
<Using Namespace="System" />
<Using Namespace="System.IO" />
<Using Namespace="System.Net" />
<Using Namespace="Microsoft.Build.Framework" />
<Using Namespace="Microsoft.Build.Utilities" />
<Code Type="Fragment" Language="cs">
<![CDATA[
try {
OutputFilename = Path.GetFullPath(OutputFilename);
Log.LogMessage("Downloading latest version of NuGet.exe...");
WebClient webClient = new WebClient();
webClient.DownloadFile("https://www.nuget.org/nuget.exe", OutputFilename);
return true;
}
catch (Exception ex) {
Log.LogErrorFromException(ex);
return false;
}
]]>
</Code>
</Task>
</UsingTask>
</Project>

Binary file not shown.

Binary file not shown.

View File

@ -1,550 +0,0 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Hunspell.cs" company="Maierhofer Software and the Hunspell Developers">
// (c) by Maierhofer Software an the Hunspell Developers
// </copyright>
// <summary>
// Spell checking, morphological analysis and generation functions.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace NHunspell
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
/// <summary>
/// Spell checking, morphological analysis and generation functions.
/// </summary>
public class Hunspell : IDisposable
{
public const string HunspellNotAvailabeForProcessorArchitectureMessage = "NHunspell is not available for ProcessorArchitecture: ";
public const string HunspellX64DllName = "Hunspellx64.dll";
public const string HunspellX64DllNotFoundMessage = "Hunspell AMD 64Bit DLL not found: {0}";
public const string HunspellX86DllName = "Hunspellx86.dll";
public const string HunspellX86DllNotFoundMessage = "Hunspell Intel 32Bit DLL not found: {0}";
#region Fields
/// <summary>
/// The native dll is referenced.
/// </summary>
private bool nativeDllIsReferenced;
/// <summary>
/// The unmanaged handle of the native Hunspell object
/// </summary>
private IntPtr unmanagedHandle;
#endregion
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="Hunspell" /> class.
/// </summary>
public Hunspell()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Hunspell"/> class.
/// </summary>
/// <param name="affFile">
/// The affix file.
/// </param>
/// <param name="dictFile">
/// The dictionary file.
/// </param>
public Hunspell(string affFile, string dictFile)
{
Load(affFile, dictFile);
}
/// <summary>
/// Initializes a new instance of the <see cref="Hunspell"/> class.
/// </summary>
/// <param name="affFile">
/// The affix file.
/// </param>
/// <param name="dictFile">
/// The dictionary file.
/// </param>
/// <param name="key">
/// The key for encrypted dictionaries.
/// </param>
public Hunspell(string affFile, string dictFile, string key)
{
Load(affFile, dictFile, key);
}
/// <summary>
/// Initializes a new instance of the <see cref="Hunspell"/> class.
/// </summary>
/// <param name="affixFileData">
/// The affix file data.
/// </param>
/// <param name="dictionaryFileData">
/// The dictionary file data.
/// </param>
/// <param name="key">
/// The key for encrypted dictionaries.
/// </param>
/// <remarks>
/// Affix and dictionary data must be binary loaded Hunspell dictionaries.
/// </remarks>
public Hunspell(byte[] affixFileData, byte[] dictionaryFileData, string key)
{
Load(affixFileData, dictionaryFileData, key);
}
/// <summary>
/// Initializes a new instance of the <see cref="Hunspell"/> class.
/// </summary>
/// <param name="affixFileData">
/// The affix file data.
/// </param>
/// <param name="dictionaryFileData">
/// The dictionary file data.
/// </param>
/// <remarks>
/// Affix and dictionary data must be binary loaded Hunspell dictionaries.
/// </remarks>
public Hunspell(byte[] affixFileData, byte[] dictionaryFileData)
{
Load(affixFileData, dictionaryFileData);
}
#endregion
#region Public Properties
/// <summary>
/// Gets or sets the path to the native Hunspell DLLs.
/// </summary>
/// <value> The Path (without file name) </value>
/// <remarks>
/// <para>This property can only be set before the first use of NHunspell.</para> <para>NHunspell uses specialized DLLs with platform specific names.
/// Hunspellx86.dll is the 32Bit X86 version, Hunspellx64.dll is the 64Bit AMD64 version.</para>
/// </remarks>
public static string NativeDllPath
{
get
{
return MarshalHunspellDll.NativeDLLPath;
}
set
{
MarshalHunspellDll.NativeDLLPath = value;
}
}
/// <summary>
/// Gets a value indicating whether is disposed.
/// </summary>
public bool IsDisposed { get; private set; }
#endregion
#region Public Methods and Operators
/// <summary>
/// Adds the specified word to the internal dictionary.
/// </summary>
/// <param name="word">
/// The word to add.
/// </param>
/// <returns>
/// <c>true</c> if the word was successfully added, otherwise <c>false</c>
/// </returns>
/// <remarks>
/// The word is NOT added to the dictionary file or data or stored in some way. It is only added to the internal data of the current <see cref="Hunspell"/> class. You must store your user dictionary elsewhere and Add() all words every time you create a new <see cref="Hunspell"/> object.
/// </remarks>
public bool Add(string word)
{
if (this.unmanagedHandle == IntPtr.Zero)
{
throw new InvalidOperationException("Dictionary is not loaded");
}
MarshalHunspellDll.HunspellAdd(this.unmanagedHandle, word);
return this.Spell(word);
}
/// <summary>
/// Adds the specified word to the internal dictionary. Determines the affixes from the provided sample.
/// </summary>
/// <param name="word">
/// The word in stem form
/// </param>
/// <param name="example">
/// The example in stem form
/// </param>
/// <returns>
/// <c>true</c> if the word was successfully added, otherwise <c>false</c>
/// </returns>
/// <remarks>
/// <para>
/// The affixiation is determined by the example. The added word should have the stem form
/// </para>
/// <para>
/// The word is NOT added to the dictionary file or data or stored in some way.
/// It is only added to the internal data of the current
/// <see cref="Hunspell"/>
/// class.
/// You must store your user dictionary elsewhere and Add() all words every time you create a new
/// <see cref="Hunspell"/>
/// object.
/// </para>
/// </remarks>
/// <example>
/// bool spellBefore = hunspell.Spell("phantasos"); spellBefore = hunspell.Spell("phantasoses"); add = hunspell.AddWithAffix("phantasos","fish"); // this fantasy word is affixed like the word fish ( plural es ...) spellAfter = hunspell.Spell("phantasos"); spellAfter = hunspell.Spell("phantasoses"); // the plural (like fish) is also correct
/// </example>
public bool AddWithAffix(string word, string example)
{
if (this.unmanagedHandle == IntPtr.Zero)
{
throw new InvalidOperationException("Dictionary is not loaded");
}
MarshalHunspellDll.HunspellAddWithAffix(this.unmanagedHandle, word, example);
return this.Spell(word);
}
/// <summary>
/// Analyzes the specified word.
/// </summary>
/// <param name="word">
/// The word to analyze.
/// </param>
/// <returns>
/// List of stems and the according morphology
/// </returns>
public List<string> Analyze(string word)
{
if (this.unmanagedHandle == IntPtr.Zero)
{
throw new InvalidOperationException("Dictionary is not loaded");
}
var result = new List<string>();
IntPtr strings = MarshalHunspellDll.HunspellAnalyze(this.unmanagedHandle, word);
int stringCount = 0;
IntPtr currentString = Marshal.ReadIntPtr(strings, stringCount * IntPtr.Size);
while (currentString != IntPtr.Zero)
{
++stringCount;
result.Add(Marshal.PtrToStringUni(currentString));
currentString = Marshal.ReadIntPtr(strings, stringCount * IntPtr.Size);
}
return result;
}
/// <summary>
/// The dispose.
/// </summary>
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
/// <param name="callFromDispose">
/// The call From Dispose.
/// </param>
protected virtual void Dispose(bool callFromDispose)
{
if (this.IsDisposed)
{
return;
}
IsDisposed = true;
if (this.unmanagedHandle != IntPtr.Zero)
{
MarshalHunspellDll.HunspellFree(this.unmanagedHandle);
this.unmanagedHandle = IntPtr.Zero;
}
if (this.nativeDllIsReferenced)
{
MarshalHunspellDll.UnReferenceNativeHunspellDll();
this.nativeDllIsReferenced = false;
}
}
/// <summary>
/// Generates the specified word by a sample.
/// </summary>
/// <param name="word">
/// The word.
/// </param>
/// <param name="sample">
/// The sample.
/// </param>
/// <returns>
/// The <see cref="List{T}"/> of <see cref="String"/>.
/// </returns>
public List<string> Generate(string word, string sample)
{
if (this.unmanagedHandle == IntPtr.Zero)
{
throw new InvalidOperationException("Dictionary is not loaded");
}
var result = new List<string>();
IntPtr strings = MarshalHunspellDll.HunspellGenerate(this.unmanagedHandle, word, sample);
int stringCount = 0;
IntPtr currentString = Marshal.ReadIntPtr(strings, stringCount * IntPtr.Size);
while (currentString != IntPtr.Zero)
{
++stringCount;
result.Add(Marshal.PtrToStringUni(currentString));
currentString = Marshal.ReadIntPtr(strings, stringCount * IntPtr.Size);
}
return result;
}
/// <summary>
/// Loads the specified affix and dictionary file.
/// </summary>
/// <param name="affFile">
/// The affix file.
/// </param>
/// <param name="dictFile">
/// The dictionary file.
/// </param>
public void Load(string affFile, string dictFile)
{
Load(affFile, dictFile, null);
}
/// <summary>
/// Loads the specified affix and dictionary file.
/// </summary>
/// <param name="affFile">
/// The affix file.
/// </param>
/// <param name="dictFile">
/// The dictionary file.
/// </param>
/// <param name="key">
/// The key for encrypted dictionaries.
/// </param>
/// <exception cref="FileNotFoundException">
/// </exception>
public void Load(string affFile, string dictFile, string key)
{
affFile = Path.GetFullPath(affFile);
if (!File.Exists(affFile))
{
throw new FileNotFoundException("AFF File not found: " + affFile);
}
dictFile = Path.GetFullPath(dictFile);
if (!File.Exists(dictFile))
{
throw new FileNotFoundException("DIC File not found: " + dictFile);
}
byte[] affixData;
FileStream stream = File.OpenRead(affFile);
using (var reader = new BinaryReader(stream))
{
affixData = reader.ReadBytes((int)stream.Length);
}
byte[] dictionaryData;
stream = File.OpenRead(dictFile);
using (var reader = new BinaryReader(stream))
{
dictionaryData = reader.ReadBytes((int)stream.Length);
}
this.Load(affixData, dictionaryData, key);
}
/// <summary>
/// Loads the specified affix and dictionary data.
/// </summary>
/// <param name="affixFileData">
/// The affix file data.
/// </param>
/// <param name="dictionaryFileData">
/// The dictionary file data.
/// </param>
public void Load(byte[] affixFileData, byte[] dictionaryFileData)
{
this.Load(affixFileData, dictionaryFileData, null);
}
/// <summary>
/// Loads the specified affix and dictionary data.
/// </summary>
/// <param name="affixFileData">
/// The affix file data.
/// </param>
/// <param name="dictionaryFileData">
/// The dictionary file data.
/// </param>
/// <param name="key">
/// The key for encrypted dictionaries.
/// </param>
/// <exception cref="InvalidOperationException">
/// </exception>
public void Load(byte[] affixFileData, byte[] dictionaryFileData, string key)
{
this.HunspellInit(affixFileData, dictionaryFileData, key);
}
/// <summary>
/// Removes the specified word.
/// </summary>
/// <param name="word">
/// The word.
/// </param>
/// <returns>
/// <c>true</c> if the word was successfully removed, otherwise <c>false</c>
/// </returns>
/// <exception cref="System.InvalidOperationException">
/// Dictionary is not loaded
/// </exception>
public bool Remove(string word)
{
if (this.unmanagedHandle == IntPtr.Zero)
{
throw new InvalidOperationException("Dictionary is not loaded");
}
MarshalHunspellDll.HunspellRemove(this.unmanagedHandle, word);
return ! this.Spell(word);
}
/// <summary>
/// Spell check the word.
/// </summary>
/// <param name="word">
/// The word.
/// </param>
/// <returns>
/// <c>true</c> if word is correct, <c>false</c> otherwise
/// </returns>
public bool Spell(string word)
{
if (this.unmanagedHandle == IntPtr.Zero)
{
throw new InvalidOperationException("Dictionary is not loaded");
}
return MarshalHunspellDll.HunspellSpell(this.unmanagedHandle, word);
}
/// <summary>
/// Gets the word stems for the specified word.
/// </summary>
/// <param name="word">
/// The word.
/// </param>
/// <returns>
/// List of word stems
/// </returns>
public List<string> Stem(string word)
{
if (this.unmanagedHandle == IntPtr.Zero)
{
throw new InvalidOperationException("Dictionary is not loaded");
}
var result = new List<string>();
IntPtr strings = MarshalHunspellDll.HunspellStem(this.unmanagedHandle, word);
int stringCount = 0;
IntPtr currentString = Marshal.ReadIntPtr(strings, stringCount * IntPtr.Size);
while (currentString != IntPtr.Zero)
{
++stringCount;
result.Add(Marshal.PtrToStringUni(currentString));
currentString = Marshal.ReadIntPtr(strings, stringCount * IntPtr.Size);
}
return result;
}
/// <summary>
/// Gets a list of suggestions for the specified (misspelled) word.
/// </summary>
/// <param name="word">
/// The word.
/// </param>
/// <returns>
/// The list of suggestions
/// </returns>
public List<string> Suggest(string word)
{
if (this.unmanagedHandle == IntPtr.Zero)
{
throw new InvalidOperationException("Dictionary is not loaded");
}
var result = new List<string>();
IntPtr strings = MarshalHunspellDll.HunspellSuggest(this.unmanagedHandle, word);
int stringCount = 0;
IntPtr currentString = Marshal.ReadIntPtr(strings, stringCount * IntPtr.Size);
while (currentString != IntPtr.Zero)
{
++stringCount;
result.Add(Marshal.PtrToStringUni(currentString));
currentString = Marshal.ReadIntPtr(strings, stringCount * IntPtr.Size);
}
return result;
}
#endregion
#region Methods
/// <summary>
/// Initializes a new instance of the <see cref="Hunspell"/> class.
/// </summary>
/// <param name="affixData">
/// The affix data. (aff file data)
/// </param>
/// <param name="dictionaryData">
/// The dictionary data. (dic file Data)
/// </param>
/// <param name="key">
/// The key for encrypted dictionaries.
/// </param>
private void HunspellInit(byte[] affixData, byte[] dictionaryData, string key)
{
if (this.unmanagedHandle != IntPtr.Zero)
{
throw new InvalidOperationException("Dictionary is already loaded");
}
MarshalHunspellDll.ReferenceNativeHunspellDll();
this.nativeDllIsReferenced = true;
if (key == null)
key = string.Empty;
this.unmanagedHandle = MarshalHunspellDll.HunspellInit(affixData, new IntPtr(affixData.Length), dictionaryData, new IntPtr(dictionaryData.Length), key);
}
#endregion
}
}

View File

@ -1,264 +0,0 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Hyphen.cs" company="Maierhofer Software and the Hunspell Developers">
// (c) by Maierhofer Software an the Hunspell Developers
// </copyright>
// <summary>
// Hyphenation functions.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace NHunspell
{
using System;
using System.IO;
using System.Runtime.InteropServices;
/// <summary>
/// Hyphenation functions.
/// </summary>
public class Hyphen : IDisposable
{
#region Fields
/// <summary>
/// The native dll is referenced.
/// </summary>
private bool nativeDllIsReferenced;
/// <summary>
/// The handle to the unmanaged Hyphen object
/// </summary>
private IntPtr unmanagedHandle;
#endregion
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="Hyphen" /> class.
/// </summary>
public Hyphen()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Hyphen"/> class.
/// </summary>
/// <param name="dictFile">
/// The dictionary file.
/// </param>
public Hyphen(string dictFile)
{
Load(dictFile);
}
/// <summary>
/// Initializes a new instance of the <see cref="Hyphen"/> class.
/// </summary>
/// <param name="dictFileData">
/// The dictionary file data.
/// </param>
public Hyphen(byte[] dictFileData)
{
Load(dictFileData);
}
#endregion
#region Public Properties
/// <summary>
/// Gets or sets the path to the native Hunspell DLLs.
/// </summary>
/// <value> The Path (without file name) </value>
/// <remarks>
/// <para>This property can only be set before the first use of NHunspell.</para> <para>NHunspell uses specialized DLLs with platform specific names.
/// Hunspellx86.dll is the 32Bit X86 version, Hunspellx64.dll is the 64Bit AMD64 version.</para>
/// </remarks>
public static string NativeDllPath
{
get
{
return MarshalHunspellDll.NativeDLLPath;
}
set
{
MarshalHunspellDll.NativeDLLPath = value;
}
}
/// <summary>
/// Gets a value indicating whether is disposed.
/// </summary>
public bool IsDisposed { get; private set; }
#endregion
#region Public Methods and Operators
/// <summary>
/// The dispose.
/// </summary>
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// The dispose.
/// </summary>
/// <param name="callFromDispose">
/// The call From Dispose.
/// </param>
protected virtual void Dispose(bool callFromDispose)
{
if (this.IsDisposed)
{
return;
}
IsDisposed = true;
if (this.unmanagedHandle != IntPtr.Zero)
{
MarshalHunspellDll.HyphenFree(this.unmanagedHandle);
this.unmanagedHandle = IntPtr.Zero;
}
if (this.nativeDllIsReferenced)
{
MarshalHunspellDll.UnReferenceNativeHunspellDll();
this.nativeDllIsReferenced = false;
}
}
/// <summary>
/// Hyphenates the specified word.
/// </summary>
/// <param name="word">
/// The word.
/// </param>
/// <returns>
/// A <see cref="HyphenResult"/> object with data for simple and complex hyphenation
/// </returns>
public HyphenResult Hyphenate(string word)
{
if (this.unmanagedHandle == IntPtr.Zero)
{
throw new InvalidOperationException("Dictionary is not loaded");
}
if (string.IsNullOrEmpty(word))
{
return null;
}
IntPtr buffer = MarshalHunspellDll.HyphenHyphenate(this.unmanagedHandle, word);
IntPtr hyphenatedWord = Marshal.ReadIntPtr(buffer);
int bufferOffset = IntPtr.Size;
IntPtr hyphenationPoints = Marshal.ReadIntPtr(buffer, bufferOffset);
bufferOffset += IntPtr.Size;
IntPtr hyphenationRep = Marshal.ReadIntPtr(buffer, bufferOffset);
bufferOffset += IntPtr.Size;
IntPtr hyphenationPos = Marshal.ReadIntPtr(buffer, bufferOffset);
bufferOffset += IntPtr.Size;
IntPtr hyphenationCut = Marshal.ReadIntPtr(buffer, bufferOffset);
bufferOffset += IntPtr.Size;
var hyphenationPointsArray = new byte[Math.Max(word.Length - 1, 1)];
var hyphenationRepArray = new string[Math.Max(word.Length - 1, 1)];
var hyphenationPosArray = new int[Math.Max(word.Length - 1, 1)];
var hyphenationCutArray = new int[Math.Max(word.Length - 1, 1)];
for (int i = 0; i < word.Length - 1; ++i)
{
hyphenationPointsArray[i] = Marshal.ReadByte(hyphenationPoints, i);
if (hyphenationRep != IntPtr.Zero)
{
IntPtr repString = Marshal.ReadIntPtr(hyphenationRep, i * IntPtr.Size);
if (repString != IntPtr.Zero)
{
hyphenationRepArray[i] = Marshal.PtrToStringUni(repString);
}
hyphenationPosArray[i] = Marshal.ReadInt32(hyphenationPos, i * sizeof(int));
hyphenationCutArray[i] = Marshal.ReadInt32(hyphenationCut, i * sizeof(int));
}
}
var result = new HyphenResult(Marshal.PtrToStringUni(hyphenatedWord), hyphenationPointsArray, hyphenationRepArray, hyphenationPosArray, hyphenationCutArray);
return result;
}
/// <summary>
/// Loads the specified dictionary file.
/// </summary>
/// <param name="dictFile">
/// The dictionary file.
/// </param>
/// <exception cref="FileNotFoundException">
/// </exception>
public void Load(string dictFile)
{
dictFile = Path.GetFullPath(dictFile);
if (!File.Exists(dictFile))
{
throw new FileNotFoundException("DIC File not found: " + dictFile);
}
byte[] dictionaryData;
FileStream stream = File.OpenRead(dictFile);
using (var reader = new BinaryReader(stream))
{
dictionaryData = reader.ReadBytes((int)stream.Length);
}
Load(dictionaryData);
}
/// <summary>
/// Loads the specified dictionary file data.
/// </summary>
/// <param name="dictFileData">
/// The dictionary file data.
/// </param>
/// <exception cref="InvalidOperationException">
/// </exception>
public void Load(byte[] dictFileData)
{
this.Init(dictFileData);
}
#endregion
#region Methods
/// <summary>
/// The init.
/// </summary>
/// <param name="dictionaryData">
/// The dictionary data.
/// </param>
private void Init(byte[] dictionaryData)
{
if (this.unmanagedHandle != IntPtr.Zero)
{
throw new InvalidOperationException("Dictionary is already loaded");
}
MarshalHunspellDll.ReferenceNativeHunspellDll();
this.nativeDllIsReferenced = true;
this.unmanagedHandle = MarshalHunspellDll.HyphenInit(dictionaryData, new IntPtr(dictionaryData.Length));
}
#endregion
}
}

View File

@ -1,156 +0,0 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="HyphenResult.cs" company="Maierhofer Software and the Hunspell Developers">
// (c) by Maierhofer Software an the Hunspell Developers
// </copyright>
// <summary>
// Holds the result of a hyphenation with <see cref="Hyphen" /> .
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace NHunspell
{
/// <summary>
/// Holds the result of a hyphenation with <see cref="Hyphen" /> .
/// </summary>
public class HyphenResult
{
#region Fields
/// <summary>
/// The cut.
/// </summary>
private readonly int[] cut;
/// <summary>
/// The points.
/// </summary>
private readonly byte[] points;
/*
rep: NULL (only standard hyph.), or replacements (hyphenation points
signed with `=' in replacements);
pos: NULL, or difference of the actual position and the beginning
positions of the change in input words;
cut: NULL, or counts of the removed characters of the original words
at hyphenation,
Note: rep, pos, cut are complementary arrays to the hyphens, indexed with the
character positions of the input word.
*/
/// <summary>
/// The pos.
/// </summary>
private readonly int[] pos;
/// <summary>
/// The rep.
/// </summary>
private readonly string[] rep;
/// <summary>
/// The word.
/// </summary>
private readonly string word;
#endregion
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="HyphenResult"/> class.
/// </summary>
/// <param name="hyphenatedWord">
/// The hyphenated word.
/// </param>
/// <param name="hyphenationPoints">
/// The hyphenation points.
/// </param>
/// <param name="hyphenationRep">
/// The hyphenation rep.
/// </param>
/// <param name="hyphenationPos">
/// The hyphenation pos.
/// </param>
/// <param name="hyphenationCut">
/// The hyphenation cut.
/// </param>
public HyphenResult(string hyphenatedWord, byte[] hyphenationPoints, string[] hyphenationRep, int[] hyphenationPos, int[] hyphenationCut)
{
this.word = hyphenatedWord;
this.points = hyphenationPoints;
this.rep = hyphenationRep;
this.pos = hyphenationPos;
this.cut = hyphenationCut;
}
#endregion
#region Public Properties
/// <summary>
/// Gets the hyphenated word.
/// </summary>
/// <remarks>
/// The hyphentaion points are marked with a equal sign '='.
/// </remarks>
/// <value> The hyphenated word. </value>
public string HyphenatedWord
{
get
{
return this.word;
}
}
/// <summary>
/// Gets the hyphenation cuts.
/// </summary>
/// <value> The hyphenation cuts. </value>
public int[] HyphenationCuts
{
get
{
return this.cut;
}
}
/// <summary>
/// Gets the hyphenation points.
/// </summary>
/// <value> The hyphenation points. </value>
public byte[] HyphenationPoints
{
get
{
return this.points;
}
}
/// <summary>
/// Gets the hyphenation positions.
/// </summary>
/// <value> The hyphenation positions. </value>
public int[] HyphenationPositions
{
get
{
return this.pos;
}
}
/// <summary>
/// Gets the hyphenation replacements.
/// </summary>
/// <value> The hyphenation replacements. </value>
public string[] HyphenationReplacements
{
get
{
return this.rep;
}
}
#endregion
}
}

View File

@ -1,233 +0,0 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="LanguageConfig.cs" company="Maierhofer Software and the Hunspell Developers">
// (c) by Maierhofer Software an the Hunspell Developers
// </copyright>
// <summary>
// provides configuration data for a specific language like the open office dictionaries.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace NHunspell
{
using System;
using System.IO;
/// <summary>
/// provides configuration data for a specific language like the open office dictionaries.
/// </summary>
public class LanguageConfig
{
#region Fields
/// <summary>
/// The hunspell aff file.
/// </summary>
private string hunspellAffFile;
/// <summary>
/// The hunspell dict file.
/// </summary>
private string hunspellDictFile;
/// <summary>
/// The hyphen dict file.
/// </summary>
private string hyphenDictFile;
/// <summary>
/// The language code.
/// </summary>
private string languageCode;
/// <summary>
/// The my thes dat file.
/// </summary>
private string myThesDatFile;
/// <summary>
/// The my thes idx file.
/// </summary>
private string myThesIdxFile;
/// <summary>
/// The processors.
/// </summary>
private int processors;
#endregion
#region Public Properties
/// <summary>
/// Gets or sets the hunspell affix file.
/// </summary>
/// <value> The hunspell aff file. </value>
public string HunspellAffFile
{
get
{
return this.hunspellAffFile;
}
set
{
string fullPath = Path.GetFullPath(value);
if (!File.Exists(fullPath))
{
throw new FileNotFoundException("Hunspell Aff file not found: " + fullPath);
}
this.hunspellAffFile = fullPath;
}
}
/// <summary>
/// Gets or sets the hunspell dictionary file.
/// </summary>
/// <value> The hunspell dict file. </value>
public string HunspellDictFile
{
get
{
return this.hunspellDictFile;
}
set
{
string fullPath = Path.GetFullPath(value);
if (!File.Exists(fullPath))
{
throw new FileNotFoundException("Hunspell Dict file not found: " + fullPath);
}
this.hunspellDictFile = fullPath;
}
}
/// <summary>
/// Gets or sets the key for encrypted dictionaries.
/// </summary>
/// <value> The hunspell key. </value>
public string HunspellKey { get; set; }
/// <summary>
/// Gets or sets the hyphen dictionary file.
/// </summary>
/// <value> The hyphen dict file. </value>
public string HyphenDictFile
{
get
{
return this.hyphenDictFile;
}
set
{
string fullPath = Path.GetFullPath(value);
if (!File.Exists(fullPath))
{
throw new FileNotFoundException("Hyphen Dict file not found: " + fullPath);
}
this.hyphenDictFile = fullPath;
}
}
/// <summary>
/// Gets or sets the language code.
/// </summary>
/// <value> The language code. </value>
public string LanguageCode
{
get
{
return this.languageCode;
}
set
{
if (value == null)
{
throw new ArgumentNullException("value", "LanguageCode cannot be null");
}
if (value.Length == 0)
{
throw new ArgumentException("LanguageCode cannot be empty");
}
this.languageCode = value.ToLower();
}
}
/// <summary>
/// Gets or sets MYThes data file.
/// </summary>
/// <value> My thes dat file. </value>
public string MyThesDatFile
{
get
{
return this.myThesDatFile;
}
set
{
string fullPath = Path.GetFullPath(value);
if (!File.Exists(fullPath))
{
throw new FileNotFoundException("MyThes Dat file not found: " + fullPath);
}
this.myThesDatFile = fullPath;
}
}
/// <summary>
/// Gets or sets the MyThes index file.
/// </summary>
/// <value> My thes idx file. </value>
public string MyThesIdxFile
{
get
{
return this.myThesIdxFile;
}
set
{
string fullPath = Path.GetFullPath(value);
if (!File.Exists(fullPath))
{
throw new FileNotFoundException("MyThes Idx file not found: " + fullPath);
}
this.myThesIdxFile = fullPath;
}
}
/// <summary>
/// Gets or sets the processors (cores) used by the <see cref="SpellFactory" /> .
/// </summary>
/// <value> The processors. </value>
public int Processors
{
get
{
return this.processors;
}
set
{
if (value < 1)
{
throw new ArgumentOutOfRangeException("value", "Processors must be greater than 0");
}
this.processors = value;
}
}
#endregion
}
}

View File

@ -1,9 +0,0 @@
NHunspell Tri-Licence:
* GPL (http://www.gnu.org/copyleft/gpl.html)
* LGPL (http://www.gnu.org/licenses/lgpl.html)
* MPL (http://www.mozilla.org/MPL/MPL-1.1.html)
Copyright: Thomas Maierhofer, Lazlo Nemeth and all contributing authors.
If you use NHunspell and like it, please put a link on http://nhunspell.sourceforge.net/
or write something in your blog about it. Thanks.

View File

@ -1,429 +0,0 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Marshalling.cs" company="Maierhofer Software and the Hunspell Developers">
// (c) by Maierhofer Software an the Hunspell Developers
// </copyright>
// <summary>
// The marshal hunspell dll.
// </summary>
//
// nikse.dk: Added attributes to all delegates regarding calling convension: [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
// http://stackoverflow.com/questions/2390407/pinvokestackimbalance-c-sharp-call-to-unmanaged-c-function/2738125#comment2825285_2738125
// --------------------------------------------------------------------------------------------------------------------
namespace NHunspell
{
using System;
using System.IO;
using System.Runtime.InteropServices;
using Nikse.SubtitleEdit.Logic;
/// <summary>
/// The marshal hunspell dll.
/// </summary>
internal static class MarshalHunspellDll
{
#region Static Fields
/// <summary>
/// The hunspell add.
/// </summary>
internal static HunspellAddDelegate HunspellAdd;
/// <summary>
/// The hunspell add with affix.
/// </summary>
internal static HunspellAddWithAffixDelegate HunspellAddWithAffix;
/// <summary>
/// The hunspell analyze.
/// </summary>
internal static HunspellAnalyzeDelegate HunspellAnalyze;
/// <summary>
/// The hunspell free.
/// </summary>
internal static HunspellFreeDelegate HunspellFree;
/// <summary>
/// The hunspell generate.
/// </summary>
internal static HunspellGenerateDelegate HunspellGenerate;
/// <summary>
/// The hunspell init.
/// </summary>
internal static HunspellInitDelegate HunspellInit;
/// <summary>
/// The hunspell remove.
/// </summary>
internal static HunspellRemoveDelegate HunspellRemove;
/// <summary>
/// The hunspell spell.
/// </summary>
internal static HunspellSpellDelegate HunspellSpell;
/// <summary>
/// The hunspell stem.
/// </summary>
internal static HunspellStemDelegate HunspellStem;
/// <summary>
/// The hunspell suggest.
/// </summary>
internal static HunspellSuggestDelegate HunspellSuggest;
/// <summary>
/// The hyphen free.
/// </summary>
internal static HyphenFreeDelegate HyphenFree;
/// <summary>
/// The hyphen hyphenate.
/// </summary>
internal static HyphenHyphenateDelegate HyphenHyphenate;
/// <summary>
/// The hyphen init.
/// </summary>
internal static HyphenInitDelegate HyphenInit;
/// <summary>
/// The native dll reference count lock.
/// </summary>
private static readonly object nativeDllReferenceCountLock = new object();
/// <summary>
/// The dll handle.
/// </summary>
private static IntPtr dllHandle = IntPtr.Zero;
/// <summary>
/// The native dll path.
/// </summary>
private static string nativeDLLPath;
/// <summary>
/// The native dll reference count.
/// </summary>
private static int nativeDllReferenceCount;
#endregion
// Hunspell
#region Delegates
/// <summary>
/// The hunspell add delegate.
/// </summary>
/// <param name="handle"> The handle. </param>
/// <param name="word"> The word. </param>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate bool HunspellAddDelegate(IntPtr handle, [MarshalAs(UnmanagedType.LPWStr)] string word);
/// <summary>
/// The hunspell add with affix delegate.
/// </summary>
/// <param name="handle"> The handle. </param>
/// <param name="word"> The word. </param>
/// <param name="example"> The example. </param>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate bool HunspellAddWithAffixDelegate(IntPtr handle, [MarshalAs(UnmanagedType.LPWStr)] string word, [MarshalAs(UnmanagedType.LPWStr)] string example);
/// <summary>
/// The hunspell analyze delegate.
/// </summary>
/// <param name="handle"> The handle. </param>
/// <param name="word"> The word. </param>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate IntPtr HunspellAnalyzeDelegate(IntPtr handle, [MarshalAs(UnmanagedType.LPWStr)] string word);
/// <summary>
/// The hunspell free delegate.
/// </summary>
/// <param name="handle"> The handle. </param>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void HunspellFreeDelegate(IntPtr handle);
/// <summary>
/// The hunspell generate delegate.
/// </summary>
/// <param name="handle"> The handle. </param>
/// <param name="word"> The word. </param>
/// <param name="word2"> The word 2. </param>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate IntPtr HunspellGenerateDelegate(IntPtr handle, [MarshalAs(UnmanagedType.LPWStr)] string word, [MarshalAs(UnmanagedType.LPWStr)] string word2);
/// <summary>
/// The hunspell init delegate.
/// </summary>
/// <param name="affixData"> The affix data. </param>
/// <param name="affixDataSize"> The affix data size. </param>
/// <param name="dictionaryData"> The dictionary data. </param>
/// <param name="dictionaryDataSize"> The dictionary data size. </param>
/// <param name="key"> The key. </param>
//internal delegate IntPtr HunspellInitDelegate([MarshalAs(UnmanagedType.LPArray)] byte[] affixData, IntPtr affixDataSize, [MarshalAs(UnmanagedType.LPArray)] byte[] dictionaryData, IntPtr dictionaryDataSize, string key);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate IntPtr HunspellInitDelegate([MarshalAs(UnmanagedType.LPArray)] byte[] affixData, IntPtr affixDataSize, [MarshalAs(UnmanagedType.LPArray)] byte[] dictionaryData, IntPtr dictionaryDataSize, [MarshalAs(UnmanagedType.LPWStr)] string key);
/// <summary>
/// The hunspell remove delegate.
/// </summary>
/// <param name="handle">
/// The handle.
/// </param>
/// <param name="word">
/// The word.
/// </param>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate bool HunspellRemoveDelegate(IntPtr handle, [MarshalAs(UnmanagedType.LPWStr)] string word);
/// <summary>
/// The hunspell spell delegate.
/// </summary>
/// <param name="handle"> The handle. </param>
/// <param name="word"> The word. </param>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate bool HunspellSpellDelegate(IntPtr handle, [MarshalAs(UnmanagedType.LPWStr)] string word);
/// <summary>
/// The hunspell stem delegate.
/// </summary>
/// <param name="handle"> The handle. </param>
/// <param name="word"> The word. </param>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate IntPtr HunspellStemDelegate(IntPtr handle, [MarshalAs(UnmanagedType.LPWStr)] string word);
/// <summary>
/// The hunspell suggest delegate.
/// </summary>
/// <param name="handle"> The handle. </param>
/// <param name="word"> The word. </param>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate IntPtr HunspellSuggestDelegate(IntPtr handle, [MarshalAs(UnmanagedType.LPWStr)] string word);
/// <summary>
/// The hyphen free delegate.
/// </summary>
/// <param name="handle"> The handle. </param>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void HyphenFreeDelegate(IntPtr handle);
/// <summary>
/// The hyphen hyphenate delegate.
/// </summary>
/// <param name="handle"> The handle. </param>
/// <param name="word"> The word. </param>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate IntPtr HyphenHyphenateDelegate(IntPtr handle, [MarshalAs(UnmanagedType.LPWStr)] string word);
/// <summary>
/// The hyphen init delegate.
/// </summary>
/// <param name="dictData"> The dict data. </param>
/// <param name="dictDataSize"> The dict data size. </param>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate IntPtr HyphenInitDelegate([MarshalAs(UnmanagedType.LPArray)] byte[] dictData, IntPtr dictDataSize);
#endregion
#region Enums
#endregion
#region Properties
/// <summary>
/// Gets or sets NativeDLLPath.
/// </summary>
/// <exception cref="InvalidOperationException"></exception>
internal static string NativeDLLPath
{
get
{
if (nativeDLLPath == null)
{
nativeDLLPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, AppDomain.CurrentDomain.RelativeSearchPath ?? string.Empty);
}
return nativeDLLPath;
}
set
{
if (dllHandle != IntPtr.Zero)
{
throw new InvalidOperationException("Native Library is already loaded");
}
nativeDLLPath = value;
}
}
#endregion
#region Methods
/// <summary>
/// References the native hunspell DLL.
/// </summary>
/// <exception cref="System.DllNotFoundException"></exception>
/// <exception cref="System.NotSupportedException"></exception>
internal static void ReferenceNativeHunspellDll()
{
lock (nativeDllReferenceCountLock)
{
if (nativeDllReferenceCount == 0)
{
if (dllHandle != IntPtr.Zero)
{
throw new InvalidOperationException("Native Dll handle is not Zero");
}
try
{
// Initialze the dynamic marshall Infrastructure to call the 32Bit (x86) or the 64Bit (x64) Dll respectively
var info = new NativeMethods.SYSTEM_INFO();
NativeMethods.GetSystemInfo(ref info);
// Load the correct DLL according to the processor architecture
switch (info.wProcessorArchitecture)
{
case NativeMethods.PROCESSOR_ARCHITECTURE.Intel:
string pathx86 = NativeDLLPath;
if (!String.IsNullOrEmpty(pathx86) && !pathx86.EndsWith("\\"))
{
pathx86 += "\\";
}
pathx86 += Hunspell.HunspellX86DllName;
dllHandle = NativeMethods.LoadLibrary(pathx86);
if (dllHandle == IntPtr.Zero)
{
throw new DllNotFoundException(string.Format(Hunspell.HunspellX86DllNotFoundMessage, pathx86));
}
break;
case NativeMethods.PROCESSOR_ARCHITECTURE.Amd64:
string pathx64 = NativeDLLPath;
if (!String.IsNullOrEmpty(pathx64) && !pathx64.EndsWith("\\"))
{
pathx64 += "\\";
}
pathx64 += Hunspell.HunspellX64DllName;
dllHandle = NativeMethods.LoadLibrary(pathx64);
if (dllHandle == IntPtr.Zero)
{
throw new DllNotFoundException(string.Format(Hunspell.HunspellX64DllNotFoundMessage, pathx64));
}
break;
default:
throw new NotSupportedException(Hunspell.HunspellNotAvailabeForProcessorArchitectureMessage + info.wProcessorArchitecture);
}
HunspellInit = (HunspellInitDelegate)GetDelegate("HunspellInit", typeof(HunspellInitDelegate));
HunspellFree = (HunspellFreeDelegate)GetDelegate("HunspellFree", typeof(HunspellFreeDelegate));
HunspellAdd = (HunspellAddDelegate)GetDelegate("HunspellAdd", typeof(HunspellAddDelegate));
HunspellAddWithAffix = (HunspellAddWithAffixDelegate)GetDelegate("HunspellAddWithAffix", typeof(HunspellAddWithAffixDelegate));
HunspellRemove = (HunspellRemoveDelegate)GetDelegate("HunspellRemove", typeof(HunspellRemoveDelegate));
HunspellSpell = (HunspellSpellDelegate)GetDelegate("HunspellSpell", typeof(HunspellSpellDelegate));
HunspellSuggest = (HunspellSuggestDelegate)GetDelegate("HunspellSuggest", typeof(HunspellSuggestDelegate));
HunspellAnalyze = (HunspellAnalyzeDelegate)GetDelegate("HunspellAnalyze", typeof(HunspellAnalyzeDelegate));
HunspellStem = (HunspellStemDelegate)GetDelegate("HunspellStem", typeof(HunspellStemDelegate));
HunspellGenerate = (HunspellGenerateDelegate)GetDelegate("HunspellGenerate", typeof(HunspellGenerateDelegate));
HyphenInit = (HyphenInitDelegate)GetDelegate("HyphenInit", typeof(HyphenInitDelegate));
HyphenFree = (HyphenFreeDelegate)GetDelegate("HyphenFree", typeof(HyphenFreeDelegate));
HyphenHyphenate = (HyphenHyphenateDelegate)GetDelegate("HyphenHyphenate", typeof(HyphenHyphenateDelegate));
}
catch
{
if (dllHandle != IntPtr.Zero)
{
NativeMethods.FreeLibrary(dllHandle);
dllHandle = IntPtr.Zero;
}
throw;
}
}
++nativeDllReferenceCount;
}
}
/// <summary>
/// The un reference native hunspell dll.
/// </summary>
/// <exception cref="InvalidOperationException">
/// </exception>
internal static void UnReferenceNativeHunspellDll()
{
lock (nativeDllReferenceCountLock)
{
if (nativeDllReferenceCount <= 0)
{
throw new InvalidOperationException("native DLL reference count is <= 0");
}
--nativeDllReferenceCount;
if (nativeDllReferenceCount == 0)
{
if (dllHandle == IntPtr.Zero)
{
throw new InvalidOperationException("Native DLL handle is Zero");
}
NativeMethods.FreeLibrary(dllHandle);
dllHandle = IntPtr.Zero;
}
}
}
/// <summary>
/// The get delegate.
/// </summary>
/// <param name="procName">
/// The proc name.
/// </param>
/// <param name="delegateType">
/// The delegate type.
/// </param>
/// <returns>
/// The <see cref="Delegate"/>.
/// </returns>
/// <exception cref="EntryPointNotFoundException">
/// </exception>
private static Delegate GetDelegate(string procName, Type delegateType)
{
IntPtr procAdress = NativeMethods.GetProcAddress(dllHandle, procName);
if (procAdress == IntPtr.Zero)
{
throw new EntryPointNotFoundException("Function: " + procName);
}
return Marshal.GetDelegateForFunctionPointer(procAdress, delegateType);
}
#endregion
}
}

View File

@ -1,469 +0,0 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MyThes.cs" company="Maierhofer Software and the Hunspell Developers">
// (c) by Maierhofer Software an the Hunspell Developers
// </copyright>
// <summary>
// provides thesaurus functions to get synonyms for a word
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace NHunspell
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
/// <summary>
/// provides thesaurus functions to get synonyms for a word
/// </summary>
public class MyThes
{
#region Fields
/// <summary>
/// The dictionary lock.
/// </summary>
private readonly object dictionaryLock = new object();
/// <summary>
/// The synonyms.
/// </summary>
private readonly Dictionary<string, ThesMeaning[]> synonyms = new Dictionary<string, ThesMeaning[]>();
#endregion
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="MyThes" /> class.
/// </summary>
public MyThes()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MyThes"/> class.
/// </summary>
/// <param name="datBytes">
/// The thesaurus dictionary bytes.
/// </param>
public MyThes(byte[] datBytes)
{
Load(datBytes);
}
/// <summary>
/// Initializes a new instance of the <see cref="MyThes"/> class.
/// </summary>
/// <param name="datFile">
/// The path to the thesaurus dictionary file.
/// </param>
public MyThes(string datFile)
{
Load(datFile);
}
/// <summary>
/// Initializes a new instance of the <see cref="MyThes"/> class.
/// </summary>
/// <param name="idxFile">
/// The thesuarus idx file.
/// </param>
/// <param name="datFile">
/// The thesaurus dat file.
/// </param>
/// <remarks>
/// This function is obsolete, idx File is not longer needed, <see cref="MyThes"/> works now completely in memory
/// </remarks>
[Obsolete("idx File is not longer needed, MyThes works completely in memory")]
public MyThes(string idxFile, string datFile)
{
Load(datFile);
}
#endregion
#region Public Methods and Operators
/// <summary>
/// Gets the .NET encoding for the specified dictionary encoding.
/// </summary>
/// <param name="encoding">
/// The encoding.
/// </param>
/// <returns>
/// The <see cref="Encoding"/>.
/// </returns>
/// <exception cref="NotSupportedException">
/// </exception>
public static Encoding GetEncoding(string encoding)
{
encoding = encoding.Trim().ToLower();
switch (encoding)
{
case "utf-8":
case "utf8":
return Encoding.GetEncoding(65001);
case "iso8859-1":
case "iso-8859-1":
return Encoding.GetEncoding(28591);
case "iso8859-2":
case "iso-8859-2":
return Encoding.GetEncoding(28592);
case "iso8859-3":
case "iso-8859-3":
return Encoding.GetEncoding(28593);
case "iso8859-4":
case "iso-8859-4":
return Encoding.GetEncoding(28594);
case "iso8859-5":
case "iso-8859-5":
return Encoding.GetEncoding(28595);
case "iso8859-6":
case "iso-8859-6":
return Encoding.GetEncoding(28596);
case "iso8859-7":
case "iso-8859-7":
return Encoding.GetEncoding(28597);
case "iso8859-8":
case "iso-8859-8":
return Encoding.GetEncoding(28598);
case "iso8859-9":
case "iso-8859-9":
return Encoding.GetEncoding(28599);
case "iso8859-13":
case "iso-8859-13":
return Encoding.GetEncoding(28603);
case "iso8859-15":
case "iso-8859-15":
return Encoding.GetEncoding(28605);
case "windows-1250":
case "microsoft-cp1250":
return Encoding.GetEncoding(1250);
case "windows-1251":
case "microsoft-cp1251":
return Encoding.GetEncoding(1251);
case "windows-1252":
case "microsoft-cp1252":
return Encoding.GetEncoding(1252);
case "windows-1253":
case "microsoft-cp1253":
return Encoding.GetEncoding(1253);
case "windows-1254":
case "microsoft-cp1254":
return Encoding.GetEncoding(1254);
case "windows-1255":
case "microsoft-cp1255":
return Encoding.GetEncoding(1255);
case "windows-1256":
case "microsoft-cp1256":
return Encoding.GetEncoding(1256);
case "windows-1257":
case "microsoft-cp1257":
return Encoding.GetEncoding(1257);
case "windows-1258":
case "microsoft-cp1258":
return Encoding.GetEncoding(1258);
case "windows-1259":
case "microsoft-cp1259":
return Encoding.GetEncoding(1259);
case "koi8-r":
case "koi8-u":
return Encoding.GetEncoding(20866);
default:
throw new NotSupportedException("Encoding: " + encoding + " is not supported");
}
}
/// <summary>
/// Loads the thesaurus from a in memory dictionary.
/// </summary>
/// <param name="dictionaryBytes">
/// The dictionary Bytes.
/// </param>
public void Load(byte[] dictionaryBytes)
{
if (this.synonyms.Count > 0)
{
throw new InvalidOperationException("Thesaurus already loaded");
}
int currentPos = 0;
int currentLength = GetLineLength(dictionaryBytes, currentPos);
string fileEncoding = Encoding.ASCII.GetString(dictionaryBytes, currentPos, currentLength);
Encoding enc = GetEncoding(fileEncoding);
currentPos += currentLength;
string word = string.Empty;
var meanings = new List<ThesMeaning>();
while (currentPos < dictionaryBytes.Length)
{
currentPos += GetCrLfLength(dictionaryBytes, currentPos);
currentLength = GetLineLength(dictionaryBytes, currentPos);
string lineText = enc.GetString(dictionaryBytes, currentPos, currentLength).Trim();
if (lineText.Length > 0)
{
string[] tokens = lineText.Split('|');
if (tokens.Length > 0)
{
if (!tokens[0].StartsWith("-") && !(tokens[0].StartsWith("(") && tokens[0].EndsWith(")")))
{
lock (this.dictionaryLock)
{
if (word.Length > 0 && ! this.synonyms.ContainsKey(word.ToLower()))
{
this.synonyms.Add(word.ToLower(), meanings.ToArray());
}
}
meanings = new List<ThesMeaning>();
word = tokens[0];
}
else
{
var currentSynonyms = new List<string>();
string description = null;
for (int tokIndex = 1; tokIndex < tokens.Length; ++tokIndex)
{
currentSynonyms.Add(tokens[tokIndex]);
if (tokIndex == 1)
{
description = tokens[tokIndex];
}
}
var meaning = new ThesMeaning(description, currentSynonyms);
meanings.Add(meaning);
}
}
}
currentPos += currentLength;
}
lock (this.dictionaryLock)
{
if (word.Length > 0 && !this.synonyms.ContainsKey(word.ToLower()))
{
this.synonyms.Add(word.ToLower(), meanings.ToArray());
}
}
}
/// <summary>
/// Loads the thesaurus from the specified dictionary file.
/// </summary>
/// <param name="dictionaryFile">
/// The dictionary file.
/// </param>
public void Load(string dictionaryFile)
{
dictionaryFile = Path.GetFullPath(dictionaryFile);
if (!File.Exists(dictionaryFile))
{
throw new FileNotFoundException("DAT File not found: " + dictionaryFile);
}
byte[] dictionaryData;
FileStream stream = File.OpenRead(dictionaryFile);
using (var reader = new BinaryReader(stream))
{
dictionaryData = reader.ReadBytes((int)stream.Length);
}
Load(dictionaryData);
}
/// <summary>
/// Lookups synonyms for the specified word.
/// </summary>
/// <param name="word">
/// The word to lookup
/// </param>
/// <returns>
/// list of synonyms
/// </returns>
public ThesResult Lookup(string word)
{
if (this.synonyms.Count == 0)
{
throw new InvalidOperationException("Thesaurus not loaded");
}
word = word.ToLower();
ThesMeaning[] meanings;
lock (this.dictionaryLock)
{
if (!this.synonyms.TryGetValue(word, out meanings))
{
return null;
}
}
var result = new ThesResult(new List<ThesMeaning>(meanings), false);
return result;
}
/// <summary>
/// Lookups the specified word with word stemming and generation
/// </summary>
/// <param name="word">
/// The word.
/// </param>
/// <param name="stemming">
/// The <see cref="Hunspell"/> object for stemming and generation.
/// </param>
/// <returns>
/// The <see cref="ThesResult"/>.
/// </returns>
public ThesResult Lookup(string word, Hunspell stemming)
{
if (this.synonyms.Count == 0)
{
throw new InvalidOperationException("Thesaurus not loaded");
}
ThesResult result = this.Lookup(word);
if (result != null)
{
return result;
}
List<string> stems = stemming.Stem(word);
if (stems == null || stems.Count == 0)
{
return null;
}
var meanings = new List<ThesMeaning>();
foreach (var stem in stems)
{
ThesResult stemSynonyms = this.Lookup(stem);
if (stemSynonyms != null)
{
foreach (var meaning in stemSynonyms.Meanings)
{
var currentSynonyms = new List<string>();
foreach (var synonym in meaning.Synonyms)
{
List<string> generatedSynonyms = stemming.Generate(synonym, word);
foreach (var generatedSynonym in generatedSynonyms)
{
currentSynonyms.Add(generatedSynonym);
}
}
if (currentSynonyms.Count > 0)
{
meanings.Add(new ThesMeaning(meaning.Description, currentSynonyms));
}
}
}
}
if (meanings.Count > 0)
{
return new ThesResult(meanings, true);
}
return null;
}
#endregion
#region Methods
/// <summary>
/// The get cr lf length.
/// </summary>
/// <param name="buffer">
/// The buffer.
/// </param>
/// <param name="pos">
/// The pos.
/// </param>
/// <returns>
/// The get cr lf length.
/// </returns>
/// <exception cref="ArgumentException">
/// </exception>
private static int GetCrLfLength(byte[] buffer, int pos)
{
if (buffer[pos] == 10)
{
if (buffer.Length > pos + 1 && buffer[pos] == 13)
{
return 2;
}
return 1;
}
if (buffer[pos] == 13)
{
if (buffer.Length > pos + 1 && buffer[pos] == 10)
{
return 2;
}
return 1;
}
throw new ArgumentException("buffer[pos] dosen't point to CR or LF");
}
/// <summary>
/// Gets the length of the line.
/// </summary>
/// <param name="buffer">
/// The buffer.
/// </param>
/// <param name="start">
/// The start.
/// </param>
/// <returns>
/// The get line length.
/// </returns>
private static int GetLineLength(byte[] buffer, int start)
{
for (int i = start; i < buffer.Length; ++i)
{
if (buffer[i] == 10 || buffer[i] == 13)
{
return i - start;
}
}
return buffer.Length - start;
}
#endregion
}
}

View File

@ -1,163 +0,0 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="SpellEngine.cs" company="Maierhofer Software and the Hunspell Developers">
// (c) by Maierhofer Software an the Hunspell Developers
// </copyright>
// <summary>
// Holds <see cref="SpellFactory" /> objects for different languages. Allows thread save spell checking
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace NHunspell
{
using System;
using System.Collections.Generic;
/// <summary>
/// Holds <see cref="SpellFactory" /> objects for different languages. Allows thread save spell checking
/// </summary>
public class SpellEngine : IDisposable
{
#region Fields
/// <summary>
/// The dictionary lock.
/// </summary>
private readonly object dictionaryLock;
/// <summary>
/// The languages.
/// </summary>
private Dictionary<string, SpellFactory> languages;
/// <summary>
/// The processors.
/// </summary>
private int processors;
#endregion
#region Constructor
/// <summary>
/// Initializes a new instance of the <see cref="SpellEngine" /> class.
/// </summary>
public SpellEngine()
{
this.processors = Environment.ProcessorCount;
this.languages = new Dictionary<string, SpellFactory>();
this.dictionaryLock = new object();
}
#endregion
#region Public Properties
/// <summary>
/// Gets a value indicating whether this instance is disposed.
/// </summary>
/// <value> <c>true</c> if this instance is disposed; otherwise, <c>false</c> . </value>
public bool IsDisposed
{
get
{
lock (this.dictionaryLock) return this.languages == null;
}
}
/// <summary>
/// Gets or sets the used processors (cores).
/// </summary>
/// <value> The processors (cores). </value>
public int Processors
{
get
{
return this.processors;
}
set
{
if (value < 1)
{
throw new ArgumentOutOfRangeException("value", "Processors must be greater than 0");
}
this.processors = value;
}
}
#endregion
#region Public Indexers
/// <summary>
/// Gets the <see cref="NHunspell.SpellFactory"/> with the specified language.
/// </summary>
/// <param name="language">
/// The language.
/// </param>
/// <value>
/// the language
/// </value>
/// <returns>
/// The <see cref="SpellFactory"/>.
/// </returns>
public SpellFactory this[string language]
{
get
{
lock (this.dictionaryLock) return this.languages[language.ToLower()];
}
}
#endregion
#region Public Methods and Operators
/// <summary>
/// Adds the language.
/// </summary>
/// <param name="config">
/// The language configuration.
/// </param>
public void AddLanguage(LanguageConfig config)
{
string languageCode = config.LanguageCode;
languageCode = languageCode.ToLower();
if (config.Processors < 1)
{
config.Processors = this.Processors;
}
var factory = new SpellFactory(config);
lock (this.dictionaryLock) this.languages.Add(languageCode, factory);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (!this.IsDisposed)
{
lock (this.dictionaryLock)
{
foreach (var factory in this.languages.Values)
{
factory.Dispose();
}
this.languages = null;
}
}
}
}
#endregion
}
}

View File

@ -1,491 +0,0 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="SpellFactory.cs" company="Maierhofer Software and the Hunspell Developers">
// (c) by Maierhofer Software an the Hunspell Developers
// </copyright>
// <summary>
// Enables spell checking, hyphenation and thesaurus based synonym lookup in a thread safe manner.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace NHunspell
{
using System;
using System.Collections.Generic;
using System.Threading;
/// <summary>
/// Enables spell checking, hyphenation and thesaurus based synonym lookup in a thread safe manner.
/// </summary>
public class SpellFactory : IDisposable
{
#region Fields
/// <summary>
/// The processors.
/// </summary>
private readonly int processors;
/// <summary>
/// The disposed.
/// </summary>
private volatile bool disposed;
/// <summary>
/// The hunspell semaphore.
/// </summary>
private Semaphore hunspellSemaphore;
/// <summary>
/// The hunspells.
/// </summary>
private Stack<Hunspell> hunspells;
private object hunspellsLock = new object();
/// <summary>
/// The hyphen semaphore.
/// </summary>
private Semaphore hyphenSemaphore;
/// <summary>
/// The hyphens.
/// </summary>
private Stack<Hyphen> hyphens;
private object hyphensLock = new object();
/// <summary>
/// The my thes semaphore.
/// </summary>
private Semaphore myThesSemaphore;
/// <summary>
/// The my theses.
/// </summary>
private Stack<MyThes> myTheses;
private object myThesesLock = new object();
#endregion
Hunspell HunspellsPop()
{
if (this.IsDisposed)
{
throw new ObjectDisposedException("SpellFactory");
}
if (this.hunspells == null)
{
throw new InvalidOperationException("Hunspell Dictionary isn't loaded");
}
this.hunspellSemaphore.WaitOne();
lock (hunspellsLock)
{
return this.hunspells.Pop();
}
}
void HunspellsPush(Hunspell hunspell)
{
lock (hunspellsLock)
{
this.hunspells.Push(hunspell);
}
hunspellSemaphore.Release();
}
Hyphen HyphenPop()
{
if (this.IsDisposed)
{
throw new ObjectDisposedException("SpellFactory");
}
if (this.hyphens == null)
{
throw new InvalidOperationException("Hyphen Dictionary isn't loaded");
}
this.hyphenSemaphore.WaitOne();
lock (hyphensLock)
{
return this.hyphens.Pop();
}
}
void HyphenPush(Hyphen hyphen)
{
lock (hyphensLock)
{
this.hyphens.Push(hyphen);
}
hyphenSemaphore.Release();
}
MyThes MyThesPop()
{
if (this.IsDisposed)
{
throw new ObjectDisposedException("SpellFactory");
}
if (this.myTheses == null)
{
throw new InvalidOperationException("MyThes Dictionary isn't loaded");
}
this.myThesSemaphore.WaitOne();
lock (myThesesLock)
{
return this.myTheses.Pop();
}
}
void MyThesPush(MyThes myThes)
{
lock (myThesesLock)
{
this.myTheses.Push(myThes);
}
myThesSemaphore.Release();
}
#region Constructor
/// <summary>
/// Initializes a new instance of the <see cref="SpellFactory"/> class.
/// </summary>
/// <param name="config">
/// The configuration of the language.
/// </param>
public SpellFactory(LanguageConfig config)
{
this.processors = config.Processors;
if (config.HunspellAffFile != null && config.HunspellAffFile.Length > 0)
{
this.hunspells = new Stack<Hunspell>(this.processors);
for (int count = 0; count < this.processors; ++count)
{
if (config.HunspellKey != null && config.HunspellKey.Length > 0)
{
this.hunspells.Push(new Hunspell(config.HunspellAffFile, config.HunspellDictFile, config.HunspellKey));
}
else
{
this.hunspells.Push(new Hunspell(config.HunspellAffFile, config.HunspellDictFile));
}
}
}
if (config.HyphenDictFile != null && config.HyphenDictFile.Length > 0)
{
this.hyphens = new Stack<Hyphen>(this.processors);
for (int count = 0; count < this.processors; ++count)
{
this.hyphens.Push(new Hyphen(config.HyphenDictFile));
}
}
if (config.MyThesIdxFile != null && config.MyThesIdxFile.Length > 0)
{
this.myTheses = new Stack<MyThes>(this.processors);
for (int count = 0; count < this.processors; ++count)
{
this.myTheses.Push(new MyThes(config.MyThesDatFile));
}
}
this.hunspellSemaphore = new Semaphore(this.processors, this.processors);
this.hyphenSemaphore = new Semaphore(this.processors, this.processors);
this.myThesSemaphore = new Semaphore(this.processors, this.processors);
}
#endregion
#region Public Properties
/// <summary>
/// Gets a value indicating whether this instance is disposed.
/// </summary>
/// <value> <c>true</c> if this instance is disposed; otherwise, <c>false</c> . </value>
public bool IsDisposed
{
get
{
return this.disposed;
}
}
#endregion
#region Public Methods and Operators
/// <summary>
/// Analyzes the specified word.
/// </summary>
/// <param name="word">
/// The word.
/// </param>
/// <returns>
/// List of strings with the morphology. One string per word stem
/// </returns>
public List<string> Analyze(string word)
{
Hunspell hunspell = this.HunspellsPop();
try
{
return hunspell.Analyze(word);
}
finally
{
this.HunspellsPush(hunspell);
}
}
/// <summary>
/// Generates the specified word by example.
/// </summary>
/// <param name="word">
/// The word.
/// </param>
/// <param name="sample">
/// The sample.
/// </param>
/// <returns>
/// List of generated words, one per word stem
/// </returns>
public List<string> Generate(string word, string sample)
{
Hunspell hunspell = this.HunspellsPop();
try
{
return hunspell.Generate(word, sample);
}
finally
{
this.HunspellsPush(hunspell);
}
}
/// <summary>
/// Hyphenates the specified word.
/// </summary>
/// <param name="word">
/// The word.
/// </param>
/// <returns>
/// the result of the hyphenation
/// </returns>
public HyphenResult Hyphenate(string word)
{
Hyphen hyphen = this.HyphenPop();
try
{
return hyphen.Hyphenate(word);
}
finally
{
this.HyphenPush(hyphen);
}
}
/// <summary>
/// Look up the synonyms for the word.
/// </summary>
/// <param name="word">
/// The word.
/// </param>
/// <param name="useGeneration">
/// if set to <c>true</c> use generation to get synonyms over the word stem.
/// </param>
/// <returns>
/// The <see cref="ThesResult"/>.
/// </returns>
public ThesResult LookupSynonyms(string word, bool useGeneration)
{
MyThes currentThes = null;
Hunspell currentHunspell = null;
try
{
currentThes = this.MyThesPop();
if (useGeneration)
{
currentHunspell = this.HunspellsPop();
return currentThes.Lookup(word, currentHunspell);
}
return currentThes.Lookup(word);
}
finally
{
if (currentThes != null)
{
this.MyThesPush(currentThes);
}
if (currentHunspell != null)
{
this.HunspellsPush(currentHunspell);
}
}
}
/// <summary>
/// Spell check the specified word.
/// </summary>
/// <param name="word">
/// The word.
/// </param>
/// <returns>
/// true if word is correct, otherwise false.
/// </returns>
public bool Spell(string word)
{
Hunspell hunspell = this.HunspellsPop();
try
{
return hunspell.Spell(word);
}
finally
{
this.HunspellsPush(hunspell);
}
}
/// <summary>
/// Stems the specified word.
/// </summary>
/// <param name="word">
/// The word.
/// </param>
/// <returns>
/// list of word stems
/// </returns>
public List<string> Stem(string word)
{
Hunspell hunspell = this.HunspellsPop();
try
{
return hunspell.Stem(word);
}
finally
{
this.HunspellsPush(hunspell);
}
}
/// <summary>
/// The suggest.
/// </summary>
/// <param name="word">
/// The word.
/// </param>
/// <returns>
/// The <see cref="List{T}"/> of <see cref="String"/>.
/// </returns>
/// <exception cref="ObjectDisposedException">
/// </exception>
/// <exception cref="InvalidOperationException">
/// </exception>
public List<string> Suggest(string word)
{
Hunspell hunspell = this.HunspellsPop();
try
{
return hunspell.Suggest(word);
}
finally
{
this.HunspellsPush(hunspell);
}
}
#endregion
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
Semaphore currentHunspellSemaphore = this.hunspellSemaphore;
if (!this.IsDisposed)
{
this.disposed = true; // Alle Threads werden ab jetzt mit Disposed Exception abgewiesen
for (int semaphoreCount = 0; semaphoreCount < this.processors; ++semaphoreCount)
{
this.hunspellSemaphore.WaitOne();
// Complete Ownership will be taken, to guarrantee other threads are completed
}
if (this.hunspells != null)
{
foreach (var hunspell in this.hunspells)
{
hunspell.Dispose();
}
}
this.hunspellSemaphore.Release(this.processors);
this.hunspellSemaphore.Dispose();
this.hunspellSemaphore = null;
this.hunspells = null;
for (int semaphoreCount = 0; semaphoreCount < this.processors; ++semaphoreCount)
{
this.hyphenSemaphore.WaitOne();
// Complete Ownership will be taken, to guarrantee other threads are completed
}
if (this.hyphens != null)
{
foreach (var hyphen in this.hyphens)
{
hyphen.Dispose();
}
}
this.hyphenSemaphore.Release(this.processors);
this.hyphenSemaphore.Dispose();
this.hyphenSemaphore = null;
this.hyphens = null;
for (int semaphoreCount = 0; semaphoreCount < this.processors; ++semaphoreCount)
{
this.myThesSemaphore.WaitOne();
// Complete Ownership will be taken, to guarrantee other threads are completed
}
if (this.myTheses != null)
{
foreach (var myThes in this.myTheses)
{
// myThes.Dispose();
}
}
this.myThesSemaphore.Release(this.processors);
this.myThesSemaphore.Dispose();
this.myThesSemaphore = null;
this.myTheses = null;
}
}
}
}
}

View File

@ -1,80 +0,0 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ThesMeaning.cs" company="Maierhofer Software and the Hunspell Developers">
// (c) by Maierhofer Software an the Hunspell Developers
// </copyright>
// <summary>
// Holds a meaning and its synonyms
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace NHunspell
{
using System.Collections.Generic;
/// <summary>
/// Holds a meaning and its synonyms
/// </summary>
public class ThesMeaning
{
#region Fields
/// <summary>
/// The description.
/// </summary>
private readonly string description;
/// <summary>
/// The synonyms.
/// </summary>
private readonly List<string> synonyms;
#endregion
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="ThesMeaning"/> class.
/// </summary>
/// <param name="description">
/// The meaning description.
/// </param>
/// <param name="synonyms">
/// The synonyms for this meaning.
/// </param>
public ThesMeaning(string description, List<string> synonyms)
{
this.description = description;
this.synonyms = synonyms;
}
#endregion
#region Public Properties
/// <summary>
/// Gets the description of the meaning.
/// </summary>
/// <value> The description. </value>
public string Description
{
get
{
return this.description;
}
}
/// <summary>
/// Gets the synonyms of the meaning.
/// </summary>
/// <value> The synonyms. </value>
public List<string> Synonyms
{
get
{
return this.synonyms;
}
}
#endregion
}
}

View File

@ -1,80 +0,0 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ThesResult.cs" company="Maierhofer Software and the Hunspell Developers">
// (c) by Maierhofer Software an the Hunspell Developers
// </copyright>
// <summary>
// Holds the result of a <see cref="MyThes" /> synonym lookup
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace NHunspell
{
using System.Collections.Generic;
/// <summary>
/// Holds the result of a <see cref="MyThes" /> synonym lookup
/// </summary>
public class ThesResult
{
#region Fields
/// <summary>
/// The generated by stem.
/// </summary>
private readonly bool generatedByStem;
/// <summary>
/// The meanings.
/// </summary>
private readonly List<ThesMeaning> meanings;
#endregion
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="ThesResult"/> class.
/// </summary>
/// <param name="meanings">
/// The meanings.
/// </param>
/// <param name="generatedByStem">
/// if set to <c>true</c> , the meanings are generated by word stemming.
/// </param>
public ThesResult(List<ThesMeaning> meanings, bool generatedByStem)
{
this.meanings = meanings;
this.generatedByStem = generatedByStem;
}
#endregion
#region Public Properties
/// <summary>
/// Gets a value indicating whether the meanings are generated by word stemming.
/// </summary>
/// <value> <c>true</c> if the meanings are generated by word stemming; otherwise, <c>false</c> . </value>
public bool IsGenerated
{
get
{
return this.generatedByStem;
}
}
/// <summary>
/// Gets the meanings.
/// </summary>
/// <value> The meanings. </value>
public List<ThesMeaning> Meanings
{
get
{
return this.meanings;
}
}
#endregion
}
}

View File

@ -25,128 +25,6 @@ namespace Nikse.SubtitleEdit.Logic
#endregion Hunspell
#region structures
/// <summary>
/// The processo r_ architecture.
/// </summary>
internal enum PROCESSOR_ARCHITECTURE : ushort
{
/// <summary>
/// The intel.
/// </summary>
Intel = 0,
/// <summary>
/// The mips.
/// </summary>
MIPS = 1,
/// <summary>
/// The alpha.
/// </summary>
Alpha = 2,
/// <summary>
/// The ppc.
/// </summary>
PPC = 3,
/// <summary>
/// The shx.
/// </summary>
SHX = 4,
/// <summary>
/// The arm.
/// </summary>
ARM = 5,
/// <summary>
/// The i a 64.
/// </summary>
IA64 = 6,
/// <summary>
/// The alpha 64.
/// </summary>
Alpha64 = 7,
/// <summary>
/// The amd 64.
/// </summary>
Amd64 = 9,
/// <summary>
/// The unknown.
/// </summary>
Unknown = 0xFFFF
}
/// <summary>
/// The syste m_ info.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal struct SYSTEM_INFO
{
/// <summary>
/// The w processor architecture.
/// </summary>
internal PROCESSOR_ARCHITECTURE wProcessorArchitecture;
/// <summary>
/// The w reserved.
/// </summary>
internal ushort wReserved;
/// <summary>
/// The dw page size.
/// </summary>
internal uint dwPageSize;
/// <summary>
/// The lp minimum application address.
/// </summary>
internal IntPtr lpMinimumApplicationAddress;
/// <summary>
/// The lp maximum application address.
/// </summary>
internal IntPtr lpMaximumApplicationAddress;
/// <summary>
/// The dw active processor mask.
/// </summary>
internal IntPtr dwActiveProcessorMask;
/// <summary>
/// The dw number of processors.
/// </summary>
internal uint dwNumberOfProcessors;
/// <summary>
/// The dw processor type.
/// </summary>
internal uint dwProcessorType;
/// <summary>
/// The dw allocation granularity.
/// </summary>
internal uint dwAllocationGranularity;
/// <summary>
/// The dw processor level.
/// </summary>
internal ushort dwProcessorLevel;
/// <summary>
/// The dw processor revision.
/// </summary>
internal ushort dwProcessorRevision;
}
#endregion structures
#region Win32 API
// Win32 API functions for dynamically loading DLLs
@ -163,9 +41,6 @@ namespace Nikse.SubtitleEdit.Logic
[DllImport("user32.dll")]
internal static extern short GetKeyState(int vKey);
[DllImport("kernel32.dll")]
internal static extern void GetSystemInfo([MarshalAs(UnmanagedType.Struct)] ref SYSTEM_INFO lpSystemInfo);
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool AttachConsole(int dwProcessId);

View File

@ -17,6 +17,9 @@
<RootNamespace>Nikse.SubtitleEdit</RootNamespace>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<NuGetPackageImportStamp>de8d0e94</NuGetPackageImportStamp>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">.\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
@ -49,6 +52,11 @@
<EmbedInteropTypes>True</EmbedInteropTypes>
<HintPath>DLLs\Interop.QuartzTypeLib.dll</HintPath>
</Reference>
<Reference Include="NHunspell, Version=1.2.5359.26126, Culture=neutral, PublicKeyToken=1ac793ea843b4366, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>packages\NHunspell.1.2.5359.26126\lib\net\NHunspell.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Drawing" />
<Reference Include="System.Web.Services" />
@ -779,16 +787,6 @@
<Compile Include="Logic\LanguageDeserializer.cs" />
<Compile Include="Logic\MurMurHash3.cs" />
<Compile Include="Logic\NativeMethods.cs" />
<Compile Include="Logic\NHunspell\Hunspell.cs" />
<Compile Include="Logic\NHunspell\Hyphen.cs" />
<Compile Include="Logic\NHunspell\HyphenResult.cs" />
<Compile Include="Logic\NHunspell\LanguageConfig.cs" />
<Compile Include="Logic\NHunspell\Marshalling.cs" />
<Compile Include="Logic\NHunspell\MyThes.cs" />
<Compile Include="Logic\NHunspell\SpellEngine.cs" />
<Compile Include="Logic\NHunspell\SpellFactory.cs" />
<Compile Include="Logic\NHunspell\ThesMeaning.cs" />
<Compile Include="Logic\NHunspell\ThesResult.cs" />
<Compile Include="Logic\NikseBitmapImageSplitter.cs" />
<Compile Include="Logic\DetectEncoding\EncodingTools.cs" />
<Compile Include="Logic\DetectEncoding\Multilang\CMLangConvertCharset.cs" />
@ -1557,6 +1555,7 @@
<DependentUpon>SyncPointsSync.cs</DependentUpon>
</EmbeddedResource>
<None Include="app.config" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
@ -1737,8 +1736,6 @@
<None Include="DLLs\Interop.QuartzTypeLib.dll" />
<Content Include="..\Changelog.txt" />
<Content Include="..\gpl.txt" />
<None Include="Dlls\Hunspellx64.dll" />
<None Include="Dlls\Hunspellx86.dll" />
<EmbeddedResource Include="Controls\VideoPlayerContainer.resx">
<DependentUpon>VideoPlayerContainer.cs</DependentUpon>
<SubType>Designer</SubType>
@ -1824,7 +1821,6 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<SubType>Designer</SubType>
</Content>
<Content Include="Logic\NHunspell\Licence.txt" />
<None Include="Resources\pictureBoxFastForward.Image.png" />
<None Include="Resources\pictureBoxFastForwardMouseDown.Image.png" />
<None Include="Resources\pictureBoxFastForwardMouseOver.Image.png" />
@ -1911,11 +1907,17 @@
</PreBuildEvent>
</PropertyGroup>
<PropertyGroup>
<PostBuildEvent>COPY /Y /V "$(ProjectDir)Dlls\Hunspellx86.dll" "$(TargetDir)"
COPY /Y /V "$(ProjectDir)Dlls\Hunspellx64.dll" "$(TargetDir)"
<PostBuildEvent>COPY /Y /V "$(ProjectDir)packages\NHunspell.1.2.5359.26126\content\*.dll" "$(TargetDir)"
COPY /Y /V "$(ProjectDir)Dlls\Interop.QuartzTypeLib.dll" "$(TargetDir)"
"$(ProjectDir)..\build_helpers.bat" lang</PostBuildEvent>
</PropertyGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
</Target>
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">

View File

@ -21,6 +21,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateAssemblyInfo", "Updat
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateLanguageFiles", "UpdateLanguageFiles\UpdateLanguageFiles.csproj", "{36BCA2A7-EE6B-45FD-AF90-D3F76A84DA76}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{E5F70420-EF49-403E-851F-700953769937}"
ProjectSection(SolutionItems) = preProject
.nuget\NuGet.targets = .nuget\NuGet.targets
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU

4
src/packages.config Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NHunspell" version="1.2.5359.26126" targetFramework="net40-Client" />
</packages>