diff options
Diffstat (limited to 'extensions/spellcheck/hunspell/glue')
13 files changed, 1337 insertions, 0 deletions
diff --git a/extensions/spellcheck/hunspell/glue/PRemoteSpellcheckEngine.ipdl b/extensions/spellcheck/hunspell/glue/PRemoteSpellcheckEngine.ipdl new file mode 100644 index 000000000..7fd918364 --- /dev/null +++ b/extensions/spellcheck/hunspell/glue/PRemoteSpellcheckEngine.ipdl @@ -0,0 +1,22 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +include protocol PContent; + +namespace mozilla { + +sync protocol PRemoteSpellcheckEngine { + manager PContent; + +parent: + async __delete__(); + + sync Check(nsString aWord) returns (bool aIsMisspelled); + + sync CheckAndSuggest(nsString aWord) returns (bool aIsMisspelled, nsString[] aSuggestions); + + sync SetDictionary(nsString aDictionary) returns (bool success); +}; + +} // namespace mozilla diff --git a/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineChild.cpp b/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineChild.cpp new file mode 100644 index 000000000..dadfb2963 --- /dev/null +++ b/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineChild.cpp @@ -0,0 +1,21 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "RemoteSpellCheckEngineChild.h" + +namespace mozilla { + +RemoteSpellcheckEngineChild::RemoteSpellcheckEngineChild(mozSpellChecker *aOwner) + : mOwner(aOwner) +{ +} + +RemoteSpellcheckEngineChild::~RemoteSpellcheckEngineChild() +{ + // null out the owner's SpellcheckEngineChild to prevent state corruption + // during shutdown + mOwner->DeleteRemoteEngine(); +} + +} //namespace mozilla diff --git a/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineChild.h b/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineChild.h new file mode 100644 index 000000000..2cc40ce1f --- /dev/null +++ b/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineChild.h @@ -0,0 +1,27 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef RemoteSpellcheckEngineChild_h_ +#define RemoteSpellcheckEngineChild_h_ + +#include "mozilla/PRemoteSpellcheckEngineChild.h" +#include "mozSpellChecker.h" + +class mozSpellChecker; + +namespace mozilla { + +class RemoteSpellcheckEngineChild : public mozilla::PRemoteSpellcheckEngineChild +{ +public: + explicit RemoteSpellcheckEngineChild(mozSpellChecker *aOwner); + virtual ~RemoteSpellcheckEngineChild(); + +private: + mozSpellChecker *mOwner; +}; + +} //namespace mozilla + +#endif // RemoteSpellcheckEngineChild_h_ diff --git a/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineParent.cpp b/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineParent.cpp new file mode 100644 index 000000000..ce20b4e19 --- /dev/null +++ b/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineParent.cpp @@ -0,0 +1,63 @@ +/* vim: set ts=2 sw=2 sts=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "RemoteSpellCheckEngineParent.h" +#include "nsISpellChecker.h" +#include "nsServiceManagerUtils.h" + +namespace mozilla { + +RemoteSpellcheckEngineParent::RemoteSpellcheckEngineParent() +{ + mSpellChecker = do_CreateInstance(NS_SPELLCHECKER_CONTRACTID); +} + +RemoteSpellcheckEngineParent::~RemoteSpellcheckEngineParent() +{ +} + +bool +RemoteSpellcheckEngineParent::RecvSetDictionary( + const nsString& aDictionary, + bool* success) +{ + nsresult rv = mSpellChecker->SetCurrentDictionary(aDictionary); + *success = NS_SUCCEEDED(rv); + return true; +} + +bool +RemoteSpellcheckEngineParent::RecvCheck( + const nsString& aWord, + bool* aIsMisspelled) +{ + nsresult rv = mSpellChecker->CheckWord(aWord, aIsMisspelled, nullptr); + + // If CheckWord failed, we can't tell whether the word is correctly spelled. + if (NS_FAILED(rv)) + *aIsMisspelled = false; + return true; +} + +bool +RemoteSpellcheckEngineParent::RecvCheckAndSuggest( + const nsString& aWord, + bool* aIsMisspelled, + InfallibleTArray<nsString>* aSuggestions) +{ + nsresult rv = mSpellChecker->CheckWord(aWord, aIsMisspelled, aSuggestions); + if (NS_FAILED(rv)) { + aSuggestions->Clear(); + *aIsMisspelled = false; + } + return true; +} + +void +RemoteSpellcheckEngineParent::ActorDestroy(ActorDestroyReason aWhy) +{ +} + +} // namespace mozilla diff --git a/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineParent.h b/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineParent.h new file mode 100644 index 000000000..c0bb51139 --- /dev/null +++ b/extensions/spellcheck/hunspell/glue/RemoteSpellCheckEngineParent.h @@ -0,0 +1,39 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef RemoteSpellcheckEngineParent_h_ +#define RemoteSpellcheckEngineParent_h_ + +#include "mozilla/PRemoteSpellcheckEngineParent.h" +#include "nsCOMPtr.h" + +class nsISpellChecker; + +namespace mozilla { + +class RemoteSpellcheckEngineParent : public PRemoteSpellcheckEngineParent +{ +public: + RemoteSpellcheckEngineParent(); + + virtual ~RemoteSpellcheckEngineParent(); + + virtual void ActorDestroy(ActorDestroyReason aWhy) override; + + virtual bool RecvSetDictionary(const nsString& aDictionary, + bool* success) override; + + virtual bool RecvCheck(const nsString& aWord, bool* aIsMisspelled) override; + + virtual bool RecvCheckAndSuggest(const nsString& aWord, + bool* aIsMisspelled, + InfallibleTArray<nsString>* aSuggestions) + override; + +private: + nsCOMPtr<nsISpellChecker> mSpellChecker; +}; + +} // namespace mozilla + +#endif diff --git a/extensions/spellcheck/hunspell/glue/hunspell_alloc_hooks.h b/extensions/spellcheck/hunspell/glue/hunspell_alloc_hooks.h new file mode 100644 index 000000000..729e66b8e --- /dev/null +++ b/extensions/spellcheck/hunspell/glue/hunspell_alloc_hooks.h @@ -0,0 +1,58 @@ +/******* BEGIN LICENSE BLOCK ******* + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Initial Developers of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developers + * are Copyright (C) 2011 the Initial Developers. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + ******* END LICENSE BLOCK *******/ + +#ifndef alloc_hooks_h__ +#define alloc_hooks_h__ + +/** + * This file is force-included in hunspell code. Its purpose is to add memory + * reporting to hunspell without modifying its code, in order to ease future + * upgrades. + * + * This file is force-included through mozilla-config.h which is generated + * during the configure step. + * + * Currently, the memory allocated using operator new/new[] is not being + * tracked, but that's OK, since almost all of the memory used by Hunspell is + * allocated using C memory allocation functions. + */ + +#include "mozilla/mozalloc.h" +#include "mozHunspellAllocator.h" + +#define malloc(size) HunspellAllocator::CountingMalloc(size) +#define calloc(count, size) HunspellAllocator::CountingCalloc(count, size) +#define free(ptr) HunspellAllocator::CountingFree(ptr) +#define realloc(ptr, size) HunspellAllocator::CountingRealloc(ptr, size) + +#endif diff --git a/extensions/spellcheck/hunspell/glue/hunspell_fopen_hooks.h b/extensions/spellcheck/hunspell/glue/hunspell_fopen_hooks.h new file mode 100644 index 000000000..a841567b9 --- /dev/null +++ b/extensions/spellcheck/hunspell/glue/hunspell_fopen_hooks.h @@ -0,0 +1,87 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef fopen_hooks_h__ +#define fopen_hooks_h__ + +/** + * This file is force-included in hunspell code. Its purpose is to add + * readahead to fopen() calls in hunspell without modifying its code, in order + * to ease future upgrades. + * + * This file is force-included through mozilla-config.h which is generated + * during the configure step. + */ + +#include "mozilla/FileUtils.h" +#include <stdio.h> +#include <string.h> + +#if defined(XP_WIN) +#include "nsNativeCharsetUtils.h" +#include "nsString.h" + +#include <fcntl.h> +#include <windows.h> +// Hunspell defines a function named near. Windef.h #defines near. +#undef near +// mozHunspell defines a function named RemoveDirectory. +#undef RemoveDirectory +#endif /* defined(XP_WIN) */ + +inline FILE* +hunspell_fopen_readahead(const char* filename, const char* mode) +{ + if (!filename || !mode) { + return nullptr; + } + // Fall back to libc's fopen for modes not supported by ReadAheadFile + if (!strchr(mode, 'r') || strchr(mode, '+')) { + return fopen(filename, mode); + } + int fd = -1; +#if defined(XP_WIN) + // filename is obtained via the nsIFile::nativePath attribute, so + // it is using the Windows ANSI code page, NOT UTF-8! + nsAutoString utf16Filename; + nsresult rv = NS_CopyNativeToUnicode(nsDependentCString(filename), + utf16Filename); + if (NS_FAILED(rv)) { + return nullptr; + } + HANDLE handle = INVALID_HANDLE_VALUE; + mozilla::ReadAheadFile(utf16Filename.get(), 0, SIZE_MAX, &handle); + if (handle == INVALID_HANDLE_VALUE) { + return nullptr; + } + int flags = _O_RDONLY; + // MSVC CRT's _open_osfhandle only supports adding _O_TEXT, not _O_BINARY + if (strchr(mode, 't')) { + // Force translated mode + flags |= _O_TEXT; + } + // Import the Win32 fd into the CRT + fd = _open_osfhandle((intptr_t)handle, flags); + if (fd < 0) { + CloseHandle(handle); + return nullptr; + } +#else + mozilla::ReadAheadFile(filename, 0, SIZE_MAX, &fd); + if (fd < 0) { + return nullptr; + } +#endif /* defined(XP_WIN) */ + + FILE* file = fdopen(fd, mode); + if (!file) { + close(fd); + } + return file; +} + +#define fopen(filename, mode) hunspell_fopen_readahead(filename, mode) + +#endif /* fopen_hooks_h__ */ + diff --git a/extensions/spellcheck/hunspell/glue/moz.build b/extensions/spellcheck/hunspell/glue/moz.build new file mode 100644 index 000000000..1e1d9711a --- /dev/null +++ b/extensions/spellcheck/hunspell/glue/moz.build @@ -0,0 +1,39 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +SOURCES += [ + 'mozHunspell.cpp', + 'mozHunspellDirProvider.cpp', + 'RemoteSpellCheckEngineChild.cpp', + 'RemoteSpellCheckEngineParent.cpp', +] + +FINAL_LIBRARY = 'xul' + +if CONFIG['MOZ_SYSTEM_HUNSPELL']: + CXXFLAGS += CONFIG['MOZ_HUNSPELL_CFLAGS'] +else: + LOCAL_INCLUDES += ['../src'] + +LOCAL_INCLUDES += [ + '/dom/base', + '/extensions/spellcheck/src', +] + +include('/ipc/chromium/chromium-config.mozbuild') + +IPDL_SOURCES = [ + 'PRemoteSpellcheckEngine.ipdl', +] + +EXPORTS.mozilla += [ + 'RemoteSpellCheckEngineChild.h', + 'RemoteSpellCheckEngineParent.h', +] + +# This variable is referenced in configure.in. Make sure to change that file +# too if you need to change this variable. +DEFINES['HUNSPELL_STATIC'] = True diff --git a/extensions/spellcheck/hunspell/glue/mozHunspell.cpp b/extensions/spellcheck/hunspell/glue/mozHunspell.cpp new file mode 100644 index 000000000..87ffbc661 --- /dev/null +++ b/extensions/spellcheck/hunspell/glue/mozHunspell.cpp @@ -0,0 +1,623 @@ +/******* BEGIN LICENSE BLOCK ******* + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) + * and László Németh (Hunspell). Portions created by the Initial Developers + * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. + * + * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) + * David Einstein (deinst@world.std.com) + * Michiel van Leeuwen (mvl@exedo.nl) + * Caolan McNamara (cmc@openoffice.org) + * László Németh (nemethl@gyorsposta.hu) + * Davide Prina + * Giuseppe Modugno + * Gianluca Turconi + * Simon Brouwer + * Noll Janos + * Biro Arpad + * Goldman Eleonora + * Sarlos Tamas + * Bencsath Boldizsar + * Halacsy Peter + * Dvornik Laszlo + * Gefferth Andras + * Nagy Viktor + * Varga Daniel + * Chris Halls + * Rene Engelhard + * Bram Moolenaar + * Dafydd Jones + * Harri Pitkanen + * Andras Timar + * Tor Lillqvist + * Jesper Kristensen (mail@jesperkristensen.dk) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + ******* END LICENSE BLOCK *******/ + +#include "mozHunspell.h" +#include "nsReadableUtils.h" +#include "nsXPIDLString.h" +#include "nsIObserverService.h" +#include "nsISimpleEnumerator.h" +#include "nsIDirectoryEnumerator.h" +#include "nsIFile.h" +#include "nsDirectoryServiceUtils.h" +#include "nsDirectoryServiceDefs.h" +#include "mozISpellI18NManager.h" +#include "nsUnicharUtilCIID.h" +#include "nsUnicharUtils.h" +#include "nsCRT.h" +#include "mozInlineSpellChecker.h" +#include "mozilla/Services.h" +#include <stdlib.h> +#include "nsIPrefService.h" +#include "nsIPrefBranch.h" +#include "mozilla/dom/EncodingUtils.h" +#include "mozilla/dom/ContentParent.h" + +using mozilla::dom::ContentParent; +using mozilla::dom::EncodingUtils; + +NS_IMPL_CYCLE_COLLECTING_ADDREF(mozHunspell) +NS_IMPL_CYCLE_COLLECTING_RELEASE(mozHunspell) + +NS_INTERFACE_MAP_BEGIN(mozHunspell) + NS_INTERFACE_MAP_ENTRY(mozISpellCheckingEngine) + NS_INTERFACE_MAP_ENTRY(nsIObserver) + NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) + NS_INTERFACE_MAP_ENTRY(nsIMemoryReporter) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozISpellCheckingEngine) + NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(mozHunspell) +NS_INTERFACE_MAP_END + +NS_IMPL_CYCLE_COLLECTION(mozHunspell, + mPersonalDictionary, + mEncoder, + mDecoder) + +template<> mozilla::Atomic<size_t> mozilla::CountingAllocatorBase<HunspellAllocator>::sAmount(0); + +mozHunspell::mozHunspell() + : mHunspell(nullptr) +{ +#ifdef DEBUG + // There must be only one instance of this class: it reports memory based on + // a single static count in HunspellAllocator. + static bool hasRun = false; + MOZ_ASSERT(!hasRun); + hasRun = true; +#endif +} + +nsresult +mozHunspell::Init() +{ + LoadDictionaryList(false); + + nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); + if (obs) { + obs->AddObserver(this, "profile-do-change", true); + obs->AddObserver(this, "profile-after-change", true); + } + + mozilla::RegisterWeakMemoryReporter(this); + + return NS_OK; +} + +mozHunspell::~mozHunspell() +{ + mozilla::UnregisterWeakMemoryReporter(this); + + mPersonalDictionary = nullptr; + delete mHunspell; +} + +NS_IMETHODIMP mozHunspell::GetDictionary(char16_t **aDictionary) +{ + NS_ENSURE_ARG_POINTER(aDictionary); + + *aDictionary = ToNewUnicode(mDictionary); + return *aDictionary ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* set the Dictionary. + * This also Loads the dictionary and initializes the converter using the dictionaries converter + */ +NS_IMETHODIMP mozHunspell::SetDictionary(const char16_t *aDictionary) +{ + NS_ENSURE_ARG_POINTER(aDictionary); + + if (nsDependentString(aDictionary).IsEmpty()) { + delete mHunspell; + mHunspell = nullptr; + mDictionary.Truncate(); + mAffixFileName.Truncate(); + mLanguage.Truncate(); + mDecoder = nullptr; + mEncoder = nullptr; + + return NS_OK; + } + + nsIFile* affFile = mDictionaries.GetWeak(nsDependentString(aDictionary)); + if (!affFile) + return NS_ERROR_FILE_NOT_FOUND; + + nsAutoCString dictFileName, affFileName; + + // XXX This isn't really good. nsIFile->NativePath isn't safe for all + // character sets on Windows. + // A better way would be to QI to nsIFile, and get a filehandle + // from there. Only problem is that hunspell wants a path + + nsresult rv = affFile->GetNativePath(affFileName); + NS_ENSURE_SUCCESS(rv, rv); + + if (mAffixFileName.Equals(affFileName.get())) + return NS_OK; + + dictFileName = affFileName; + int32_t dotPos = dictFileName.RFindChar('.'); + if (dotPos == -1) + return NS_ERROR_FAILURE; + + dictFileName.SetLength(dotPos); + dictFileName.AppendLiteral(".dic"); + + // SetDictionary can be called multiple times, so we might have a + // valid mHunspell instance which needs cleaned up. + delete mHunspell; + + mDictionary = aDictionary; + mAffixFileName = affFileName; + + mHunspell = new Hunspell(affFileName.get(), + dictFileName.get()); + if (!mHunspell) + return NS_ERROR_OUT_OF_MEMORY; + + nsDependentCString label(mHunspell->get_dic_encoding()); + nsAutoCString encoding; + if (!EncodingUtils::FindEncodingForLabelNoReplacement(label, encoding)) { + return NS_ERROR_UCONV_NOCONV; + } + mEncoder = EncodingUtils::EncoderForEncoding(encoding); + mDecoder = EncodingUtils::DecoderForEncoding(encoding); + + if (mEncoder) + mEncoder->SetOutputErrorBehavior(mEncoder->kOnError_Signal, nullptr, '?'); + + int32_t pos = mDictionary.FindChar('-'); + if (pos == -1) + pos = mDictionary.FindChar('_'); + + if (pos == -1) + mLanguage.Assign(mDictionary); + else + mLanguage = Substring(mDictionary, 0, pos); + + return NS_OK; +} + +NS_IMETHODIMP mozHunspell::GetLanguage(char16_t **aLanguage) +{ + NS_ENSURE_ARG_POINTER(aLanguage); + + if (mDictionary.IsEmpty()) + return NS_ERROR_NOT_INITIALIZED; + + *aLanguage = ToNewUnicode(mLanguage); + return *aLanguage ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +NS_IMETHODIMP mozHunspell::GetProvidesPersonalDictionary(bool *aProvidesPersonalDictionary) +{ + NS_ENSURE_ARG_POINTER(aProvidesPersonalDictionary); + + *aProvidesPersonalDictionary = false; + return NS_OK; +} + +NS_IMETHODIMP mozHunspell::GetProvidesWordUtils(bool *aProvidesWordUtils) +{ + NS_ENSURE_ARG_POINTER(aProvidesWordUtils); + + *aProvidesWordUtils = false; + return NS_OK; +} + +NS_IMETHODIMP mozHunspell::GetName(char16_t * *aName) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP mozHunspell::GetCopyright(char16_t * *aCopyright) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP mozHunspell::GetPersonalDictionary(mozIPersonalDictionary * *aPersonalDictionary) +{ + *aPersonalDictionary = mPersonalDictionary; + NS_IF_ADDREF(*aPersonalDictionary); + return NS_OK; +} + +NS_IMETHODIMP mozHunspell::SetPersonalDictionary(mozIPersonalDictionary * aPersonalDictionary) +{ + mPersonalDictionary = aPersonalDictionary; + return NS_OK; +} + +NS_IMETHODIMP mozHunspell::GetDictionaryList(char16_t ***aDictionaries, + uint32_t *aCount) +{ + if (!aDictionaries || !aCount) + return NS_ERROR_NULL_POINTER; + + uint32_t count = 0; + char16_t** dicts = + (char16_t**) moz_xmalloc(sizeof(char16_t*) * mDictionaries.Count()); + + for (auto iter = mDictionaries.Iter(); !iter.Done(); iter.Next()) { + dicts[count] = ToNewUnicode(iter.Key()); + if (!dicts[count]) { + while (count) { + --count; + free(dicts[count]); + } + free(dicts); + return NS_ERROR_OUT_OF_MEMORY; + } + + ++count; + } + + *aDictionaries = dicts; + *aCount = count; + + return NS_OK; +} + +void +mozHunspell::LoadDictionaryList(bool aNotifyChildProcesses) +{ + mDictionaries.Clear(); + + nsresult rv; + + nsCOMPtr<nsIProperties> dirSvc = + do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID); + if (!dirSvc) + return; + + // find built in dictionaries, or dictionaries specified in + // spellchecker.dictionary_path in prefs + nsCOMPtr<nsIFile> dictDir; + + // check preferences first + nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID)); + if (prefs) { + nsCString extDictPath; + rv = prefs->GetCharPref("spellchecker.dictionary_path", getter_Copies(extDictPath)); + if (NS_SUCCEEDED(rv)) { + // set the spellchecker.dictionary_path + rv = NS_NewNativeLocalFile(extDictPath, true, getter_AddRefs(dictDir)); + } + } + if (!dictDir) { + // spellcheck.dictionary_path not found, set internal path + rv = dirSvc->Get(DICTIONARY_SEARCH_DIRECTORY, + NS_GET_IID(nsIFile), getter_AddRefs(dictDir)); + } + if (dictDir) { + LoadDictionariesFromDir(dictDir); + } + else { + // try to load gredir/dictionaries + nsCOMPtr<nsIFile> greDir; + rv = dirSvc->Get(NS_GRE_DIR, + NS_GET_IID(nsIFile), getter_AddRefs(greDir)); + if (NS_SUCCEEDED(rv)) { + greDir->AppendNative(NS_LITERAL_CSTRING("dictionaries")); + LoadDictionariesFromDir(greDir); + } + + // try to load appdir/dictionaries only if different than gredir + nsCOMPtr<nsIFile> appDir; + rv = dirSvc->Get(NS_XPCOM_CURRENT_PROCESS_DIR, + NS_GET_IID(nsIFile), getter_AddRefs(appDir)); + bool equals; + if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(appDir->Equals(greDir, &equals)) && !equals) { + appDir->AppendNative(NS_LITERAL_CSTRING("dictionaries")); + LoadDictionariesFromDir(appDir); + } + } + + // find dictionaries in DICPATH + char* dicEnv = PR_GetEnv("DICPATH"); + if (dicEnv) { + // do a two-pass dance so dictionaries are loaded right-to-left as preference + nsTArray<nsCOMPtr<nsIFile>> dirs; + nsAutoCString env(dicEnv); // assume dicEnv is UTF-8 + + char* currPath = nullptr; + char* nextPaths = env.BeginWriting(); + while ((currPath = NS_strtok(":", &nextPaths))) { + nsCOMPtr<nsIFile> dir; + rv = NS_NewNativeLocalFile(nsCString(currPath), true, getter_AddRefs(dir)); + if (NS_SUCCEEDED(rv)) { + dirs.AppendElement(dir); + } + } + + // load them in reverse order so they override each other properly + for (int32_t i = dirs.Length() - 1; i >= 0; i--) { + LoadDictionariesFromDir(dirs[i]); + } + } + + // find dictionaries from extensions requiring restart + nsCOMPtr<nsISimpleEnumerator> dictDirs; + rv = dirSvc->Get(DICTIONARY_SEARCH_DIRECTORY_LIST, + NS_GET_IID(nsISimpleEnumerator), getter_AddRefs(dictDirs)); + if (NS_FAILED(rv)) + return; + + bool hasMore; + while (NS_SUCCEEDED(dictDirs->HasMoreElements(&hasMore)) && hasMore) { + nsCOMPtr<nsISupports> elem; + dictDirs->GetNext(getter_AddRefs(elem)); + + dictDir = do_QueryInterface(elem); + if (dictDir) + LoadDictionariesFromDir(dictDir); + } + + // find dictionaries from restartless extensions + for (int32_t i = 0; i < mDynamicDirectories.Count(); i++) { + LoadDictionariesFromDir(mDynamicDirectories[i]); + } + + // Now we have finished updating the list of dictionaries, update the current + // dictionary and any editors which may use it. + mozInlineSpellChecker::UpdateCanEnableInlineSpellChecking(); + + if (aNotifyChildProcesses) { + ContentParent::NotifyUpdatedDictionaries(); + } + + // Check if the current dictionary is still available. + // If not, try to replace it with another dictionary of the same language. + if (!mDictionary.IsEmpty()) { + rv = SetDictionary(mDictionary.get()); + if (NS_SUCCEEDED(rv)) + return; + } + + // If the current dictionary has gone, and we don't have a good replacement, + // set no current dictionary. + if (!mDictionary.IsEmpty()) { + SetDictionary(EmptyString().get()); + } +} + +NS_IMETHODIMP +mozHunspell::LoadDictionariesFromDir(nsIFile* aDir) +{ + nsresult rv; + + bool check = false; + rv = aDir->Exists(&check); + if (NS_FAILED(rv) || !check) + return NS_ERROR_UNEXPECTED; + + rv = aDir->IsDirectory(&check); + if (NS_FAILED(rv) || !check) + return NS_ERROR_UNEXPECTED; + + nsCOMPtr<nsISimpleEnumerator> e; + rv = aDir->GetDirectoryEntries(getter_AddRefs(e)); + if (NS_FAILED(rv)) + return NS_ERROR_UNEXPECTED; + + nsCOMPtr<nsIDirectoryEnumerator> files(do_QueryInterface(e)); + if (!files) + return NS_ERROR_UNEXPECTED; + + nsCOMPtr<nsIFile> file; + while (NS_SUCCEEDED(files->GetNextFile(getter_AddRefs(file))) && file) { + nsAutoString leafName; + file->GetLeafName(leafName); + if (!StringEndsWith(leafName, NS_LITERAL_STRING(".dic"))) + continue; + + nsAutoString dict(leafName); + dict.SetLength(dict.Length() - 4); // magic length of ".dic" + + // check for the presence of the .aff file + leafName = dict; + leafName.AppendLiteral(".aff"); + file->SetLeafName(leafName); + rv = file->Exists(&check); + if (NS_FAILED(rv) || !check) + continue; + +#ifdef DEBUG_bsmedberg + printf("Adding dictionary: %s\n", NS_ConvertUTF16toUTF8(dict).get()); +#endif + + // Replace '_' separator with '-' + dict.ReplaceChar("_", '-'); + + mDictionaries.Put(dict, file); + } + + return NS_OK; +} + +nsresult mozHunspell::ConvertCharset(const char16_t* aStr, char ** aDst) +{ + NS_ENSURE_ARG_POINTER(aDst); + NS_ENSURE_TRUE(mEncoder, NS_ERROR_NULL_POINTER); + + int32_t outLength; + int32_t inLength = NS_strlen(aStr); + nsresult rv = mEncoder->GetMaxLength(aStr, inLength, &outLength); + NS_ENSURE_SUCCESS(rv, rv); + + *aDst = (char *) moz_xmalloc(sizeof(char) * (outLength+1)); + NS_ENSURE_TRUE(*aDst, NS_ERROR_OUT_OF_MEMORY); + + rv = mEncoder->Convert(aStr, &inLength, *aDst, &outLength); + if (NS_SUCCEEDED(rv)) + (*aDst)[outLength] = '\0'; + + return rv; +} + +NS_IMETHODIMP +mozHunspell::CollectReports(nsIHandleReportCallback* aHandleReport, + nsISupports* aData, bool aAnonymize) +{ + MOZ_COLLECT_REPORT( + "explicit/spell-check", KIND_HEAP, UNITS_BYTES, + HunspellAllocator::MemoryAllocated(), + "Memory used by the spell-checking engine."); + + return NS_OK; +} + +NS_IMETHODIMP mozHunspell::Check(const char16_t *aWord, bool *aResult) +{ + NS_ENSURE_ARG_POINTER(aWord); + NS_ENSURE_ARG_POINTER(aResult); + NS_ENSURE_TRUE(mHunspell, NS_ERROR_FAILURE); + + nsXPIDLCString charsetWord; + nsresult rv = ConvertCharset(aWord, getter_Copies(charsetWord)); + NS_ENSURE_SUCCESS(rv, rv); + + *aResult = !!mHunspell->spell(charsetWord); + + + if (!*aResult && mPersonalDictionary) + rv = mPersonalDictionary->Check(aWord, mLanguage.get(), aResult); + + return rv; +} + +NS_IMETHODIMP mozHunspell::Suggest(const char16_t *aWord, char16_t ***aSuggestions, uint32_t *aSuggestionCount) +{ + NS_ENSURE_ARG_POINTER(aSuggestions); + NS_ENSURE_ARG_POINTER(aSuggestionCount); + NS_ENSURE_TRUE(mHunspell, NS_ERROR_FAILURE); + + nsresult rv; + *aSuggestionCount = 0; + + nsXPIDLCString charsetWord; + rv = ConvertCharset(aWord, getter_Copies(charsetWord)); + NS_ENSURE_SUCCESS(rv, rv); + + char ** wlst; + *aSuggestionCount = mHunspell->suggest(&wlst, charsetWord); + + if (*aSuggestionCount) { + *aSuggestions = (char16_t **)moz_xmalloc(*aSuggestionCount * sizeof(char16_t *)); + if (*aSuggestions) { + uint32_t index = 0; + for (index = 0; index < *aSuggestionCount && NS_SUCCEEDED(rv); ++index) { + // Convert the suggestion to utf16 + int32_t inLength = strlen(wlst[index]); + int32_t outLength; + rv = mDecoder->GetMaxLength(wlst[index], inLength, &outLength); + if (NS_SUCCEEDED(rv)) + { + (*aSuggestions)[index] = (char16_t *) moz_xmalloc(sizeof(char16_t) * (outLength+1)); + if ((*aSuggestions)[index]) + { + rv = mDecoder->Convert(wlst[index], &inLength, (*aSuggestions)[index], &outLength); + if (NS_SUCCEEDED(rv)) + (*aSuggestions)[index][outLength] = 0; + } + else + rv = NS_ERROR_OUT_OF_MEMORY; + } + } + + if (NS_FAILED(rv)) + NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(index, *aSuggestions); // free the char16_t strings up to the point at which the error occurred + } + else // if (*aSuggestions) + rv = NS_ERROR_OUT_OF_MEMORY; + } + + NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(*aSuggestionCount, wlst); + return rv; +} + +NS_IMETHODIMP +mozHunspell::Observe(nsISupports* aSubj, const char *aTopic, + const char16_t *aData) +{ + NS_ASSERTION(!strcmp(aTopic, "profile-do-change") + || !strcmp(aTopic, "profile-after-change"), + "Unexpected observer topic"); + + LoadDictionaryList(false); + + return NS_OK; +} + +NS_IMETHODIMP mozHunspell::AddDirectory(nsIFile *aDir) +{ + mDynamicDirectories.AppendObject(aDir); + LoadDictionaryList(true); + return NS_OK; +} + +NS_IMETHODIMP mozHunspell::RemoveDirectory(nsIFile *aDir) +{ + mDynamicDirectories.RemoveObject(aDir); + LoadDictionaryList(true); + +#ifdef MOZ_THUNDERBIRD + /* + * This notification is needed for Thunderbird. Thunderbird derives the dictionary + * from the document's "lang" attribute. If a dictionary is removed, + * we need to change the "lang" attribute. + */ + nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); + if (obs) { + obs->NotifyObservers(nullptr, + SPELLCHECK_DICTIONARY_REMOVE_NOTIFICATION, + nullptr); + } +#endif + return NS_OK; +} diff --git a/extensions/spellcheck/hunspell/glue/mozHunspell.h b/extensions/spellcheck/hunspell/glue/mozHunspell.h new file mode 100644 index 000000000..01ef741aa --- /dev/null +++ b/extensions/spellcheck/hunspell/glue/mozHunspell.h @@ -0,0 +1,125 @@ +/******* BEGIN LICENSE BLOCK ******* + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) + * and László Németh (Hunspell). Portions created by the Initial Developers + * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. + * + * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca) + * David Einstein (deinst@world.std.com) + * Michiel van Leeuwen (mvl@exedo.nl) + * Caolan McNamara (cmc@openoffice.org) + * László Németh (nemethl@gyorsposta.hu) + * Davide Prina + * Giuseppe Modugno + * Gianluca Turconi + * Simon Brouwer + * Noll Janos + * Biro Arpad + * Goldman Eleonora + * Sarlos Tamas + * Bencsath Boldizsar + * Halacsy Peter + * Dvornik Laszlo + * Gefferth Andras + * Nagy Viktor + * Varga Daniel + * Chris Halls + * Rene Engelhard + * Bram Moolenaar + * Dafydd Jones + * Harri Pitkanen + * Andras Timar + * Tor Lillqvist + * Jesper Kristensen (mail@jesperkristensen.dk) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + ******* END LICENSE BLOCK *******/ + +#ifndef mozHunspell_h__ +#define mozHunspell_h__ + +#include <hunspell.hxx> +#include "mozISpellCheckingEngine.h" +#include "mozIPersonalDictionary.h" +#include "nsString.h" +#include "nsCOMPtr.h" +#include "nsCOMArray.h" +#include "nsIMemoryReporter.h" +#include "nsIObserver.h" +#include "nsIUnicodeEncoder.h" +#include "nsIUnicodeDecoder.h" +#include "nsInterfaceHashtable.h" +#include "nsWeakReference.h" +#include "nsCycleCollectionParticipant.h" +#include "mozHunspellAllocator.h" + +#define MOZ_HUNSPELL_CONTRACTID "@mozilla.org/spellchecker/engine;1" +#define MOZ_HUNSPELL_CID \ +/* 56c778e4-1bee-45f3-a689-886692a97fe7 */ \ +{ 0x56c778e4, 0x1bee, 0x45f3, \ + { 0xa6, 0x89, 0x88, 0x66, 0x92, 0xa9, 0x7f, 0xe7 } } + +class mozHunspell final : public mozISpellCheckingEngine, + public nsIObserver, + public nsSupportsWeakReference, + public nsIMemoryReporter +{ +public: + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_MOZISPELLCHECKINGENGINE + NS_DECL_NSIOBSERVER + NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(mozHunspell, mozISpellCheckingEngine) + + mozHunspell(); + + nsresult Init(); + + void LoadDictionaryList(bool aNotifyChildProcesses); + + // helper method for converting a word to the charset of the dictionary + nsresult ConvertCharset(const char16_t* aStr, char ** aDst); + + NS_DECL_NSIMEMORYREPORTER + +protected: + virtual ~mozHunspell(); + + nsCOMPtr<mozIPersonalDictionary> mPersonalDictionary; + nsCOMPtr<nsIUnicodeEncoder> mEncoder; + nsCOMPtr<nsIUnicodeDecoder> mDecoder; + + // Hashtable matches dictionary name to .aff file + nsInterfaceHashtable<nsStringHashKey, nsIFile> mDictionaries; + nsString mDictionary; + nsString mLanguage; + nsCString mAffixFileName; + + // dynamic dirs used to search for dictionaries + nsCOMArray<nsIFile> mDynamicDirectories; + + Hunspell *mHunspell; +}; + +#endif diff --git a/extensions/spellcheck/hunspell/glue/mozHunspellAllocator.h b/extensions/spellcheck/hunspell/glue/mozHunspellAllocator.h new file mode 100644 index 000000000..219d4a5dd --- /dev/null +++ b/extensions/spellcheck/hunspell/glue/mozHunspellAllocator.h @@ -0,0 +1,16 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozHunspellAllocator_h__ +#define mozHunspellAllocator_h__ + +#include "mozilla/CountingAllocatorBase.h" + +class HunspellAllocator : public mozilla::CountingAllocatorBase<HunspellAllocator> +{ +}; + +#endif diff --git a/extensions/spellcheck/hunspell/glue/mozHunspellDirProvider.cpp b/extensions/spellcheck/hunspell/glue/mozHunspellDirProvider.cpp new file mode 100644 index 000000000..00758b0c3 --- /dev/null +++ b/extensions/spellcheck/hunspell/glue/mozHunspellDirProvider.cpp @@ -0,0 +1,140 @@ +/******* BEGIN LICENSE BLOCK ******* + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) + * and László Németh (Hunspell). Portions created by the Initial Developers + * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. + * + * Contributor(s): Benjamin Smedberg (benjamin@smedbergs.us) (Original Code) + * László Németh (nemethl@gyorsposta.hu) + * Ryan VanderMeulen (ryanvm@gmail.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + ******* END LICENSE BLOCK *******/ + +#include "mozHunspellDirProvider.h" +#include "nsXULAppAPI.h" +#include "nsString.h" + +#include "mozISpellCheckingEngine.h" +#include "nsICategoryManager.h" + +NS_IMPL_ISUPPORTS(mozHunspellDirProvider, + nsIDirectoryServiceProvider, + nsIDirectoryServiceProvider2) + +NS_IMETHODIMP +mozHunspellDirProvider::GetFile(const char *aKey, bool *aPersist, + nsIFile* *aResult) +{ + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +mozHunspellDirProvider::GetFiles(const char *aKey, + nsISimpleEnumerator* *aResult) +{ + if (strcmp(aKey, DICTIONARY_SEARCH_DIRECTORY_LIST) != 0) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr<nsIProperties> dirSvc = + do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID); + if (!dirSvc) + return NS_ERROR_FAILURE; + + nsCOMPtr<nsISimpleEnumerator> list; + nsresult rv = dirSvc->Get(XRE_EXTENSIONS_DIR_LIST, + NS_GET_IID(nsISimpleEnumerator), + getter_AddRefs(list)); + if (NS_FAILED(rv)) + return rv; + + nsCOMPtr<nsISimpleEnumerator> e = new AppendingEnumerator(list); + if (!e) + return NS_ERROR_OUT_OF_MEMORY; + + *aResult = nullptr; + e.swap(*aResult); + return NS_SUCCESS_AGGREGATE_RESULT; +} + +NS_IMPL_ISUPPORTS(mozHunspellDirProvider::AppendingEnumerator, + nsISimpleEnumerator) + +NS_IMETHODIMP +mozHunspellDirProvider::AppendingEnumerator::HasMoreElements(bool *aResult) +{ + *aResult = mNext ? true : false; + return NS_OK; +} + +NS_IMETHODIMP +mozHunspellDirProvider::AppendingEnumerator::GetNext(nsISupports* *aResult) +{ + if (aResult) + NS_ADDREF(*aResult = mNext); + + mNext = nullptr; + + nsresult rv; + + // Ignore all errors + + bool more; + while (NS_SUCCEEDED(mBase->HasMoreElements(&more)) && more) { + nsCOMPtr<nsISupports> nextbasesupp; + mBase->GetNext(getter_AddRefs(nextbasesupp)); + + nsCOMPtr<nsIFile> nextbase(do_QueryInterface(nextbasesupp)); + if (!nextbase) + continue; + + nextbase->Clone(getter_AddRefs(mNext)); + if (!mNext) + continue; + + mNext->AppendNative(NS_LITERAL_CSTRING("dictionaries")); + + bool exists; + rv = mNext->Exists(&exists); + if (NS_SUCCEEDED(rv) && exists) + break; + + mNext = nullptr; + } + + return NS_OK; +} + +mozHunspellDirProvider::AppendingEnumerator::AppendingEnumerator + (nsISimpleEnumerator* aBase) : + mBase(aBase) +{ + // Initialize mNext to begin + GetNext(nullptr); +} + +char const *const +mozHunspellDirProvider::kContractID = "@mozilla.org/spellcheck/dir-provider;1"; diff --git a/extensions/spellcheck/hunspell/glue/mozHunspellDirProvider.h b/extensions/spellcheck/hunspell/glue/mozHunspellDirProvider.h new file mode 100644 index 000000000..60ab23be8 --- /dev/null +++ b/extensions/spellcheck/hunspell/glue/mozHunspellDirProvider.h @@ -0,0 +1,77 @@ +/******* BEGIN LICENSE BLOCK ******* + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Initial Developers of the Original Code are Kevin Hendricks (MySpell) + * and László Németh (Hunspell). Portions created by the Initial Developers + * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved. + * + * Contributor(s): Benjamin Smedberg (benjamin@smedbergs.us) (Original Code) + * László Németh (nemethl@gyorsposta.hu) + * Ryan VanderMeulen (ryanvm@gmail.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + ******* END LICENSE BLOCK *******/ + +#ifndef mozHunspellDirProvider_h__ +#define mozHunspellDirProvider_h__ + +#include "nsIDirectoryService.h" +#include "nsIFile.h" +#include "nsISimpleEnumerator.h" +#include "mozilla/Attributes.h" + +class mozHunspellDirProvider final : + public nsIDirectoryServiceProvider2 +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIDIRECTORYSERVICEPROVIDER + NS_DECL_NSIDIRECTORYSERVICEPROVIDER2 + + static char const *const kContractID; + +private: + ~mozHunspellDirProvider() {} + + class AppendingEnumerator final : public nsISimpleEnumerator + { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSISIMPLEENUMERATOR + + explicit AppendingEnumerator(nsISimpleEnumerator* aBase); + + private: + ~AppendingEnumerator() {} + + nsCOMPtr<nsISimpleEnumerator> mBase; + nsCOMPtr<nsIFile> mNext; + }; +}; + +#define HUNSPELLDIRPROVIDER_CID \ +{ 0x64d6174c, 0x1496, 0x4ffd, \ + { 0x87, 0xf2, 0xda, 0x26, 0x70, 0xf8, 0x89, 0x34 } } + +#endif // mozHunspellDirProvider |