LCOV - app.info - extensions/spellcheck/hunspell/src/mozHunspell.cpp

LCOV - code coverage report
| Current view: | directory - extensions/spellcheck/hunspell/src - mozHunspell.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 280 | 148 | 52.9 %
| Date: | 2012-07-07 | Functions: | 45 | 20 | 44.4 %

           1                 : /******* BEGIN LICENSE BLOCK *******
           2                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           3                 :  *
           4                 :  * The contents of this file are subject to the Mozilla Public License Version
           5                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           6                 :  * the License. You may obtain a copy of the License at
           7                 :  * http://www.mozilla.org/MPL/
           8                 :  *
           9                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          10                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          11                 :  * for the specific language governing rights and limitations under the
          12                 :  * License.
          13                 :  *
          14                 :  * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
          15                 :  * and László Németh (Hunspell). Portions created by the Initial Developers
          16                 :  * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
          17                 :  *
          18                 :  * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
          19                 :  *                 David Einstein (deinst@world.std.com)
          20                 :  *                 Michiel van Leeuwen (mvl@exedo.nl)
          21                 :  *                 Caolan McNamara (cmc@openoffice.org)
          22                 :  *                 László Németh (nemethl@gyorsposta.hu)
          23                 :  *                 Davide Prina
          24                 :  *                 Giuseppe Modugno
          25                 :  *                 Gianluca Turconi
          26                 :  *                 Simon Brouwer
          27                 :  *                 Noll Janos
          28                 :  *                 Biro Arpad
          29                 :  *                 Goldman Eleonora
          30                 :  *                 Sarlos Tamas
          31                 :  *                 Bencsath Boldizsar
          32                 :  *                 Halacsy Peter
          33                 :  *                 Dvornik Laszlo
          34                 :  *                 Gefferth Andras
          35                 :  *                 Nagy Viktor
          36                 :  *                 Varga Daniel
          37                 :  *                 Chris Halls
          38                 :  *                 Rene Engelhard
          39                 :  *                 Bram Moolenaar
          40                 :  *                 Dafydd Jones
          41                 :  *                 Harri Pitkanen
          42                 :  *                 Andras Timar
          43                 :  *                 Tor Lillqvist
          44                 :  *                 Jesper Kristensen (mail@jesperkristensen.dk)
          45                 :  *
          46                 :  * Alternatively, the contents of this file may be used under the terms of
          47                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
          48                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          49                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          50                 :  * of those above. If you wish to allow use of your version of this file only
          51                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          52                 :  * use your version of this file under the terms of the MPL, indicate your
          53                 :  * decision by deleting the provisions above and replace them with the notice
          54                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          55                 :  * the provisions above, a recipient may use your version of this file under
          56                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          57                 :  *
          58                 :  ******* END LICENSE BLOCK *******/
          59                 :
          60                 : #include "mozHunspell.h"
          61                 : #include "nsReadableUtils.h"
          62                 : #include "nsXPIDLString.h"
          63                 : #include "nsIObserverService.h"
          64                 : #include "nsISimpleEnumerator.h"
          65                 : #include "nsIDirectoryEnumerator.h"
          66                 : #include "nsIFile.h"
          67                 : #include "nsDirectoryServiceUtils.h"
          68                 : #include "nsDirectoryServiceDefs.h"
          69                 : #include "mozISpellI18NManager.h"
          70                 : #include "nsICharsetConverterManager.h"
          71                 : #include "nsUnicharUtilCIID.h"
          72                 : #include "nsUnicharUtils.h"
          73                 : #include "nsCRT.h"
          74                 : #include "mozInlineSpellChecker.h"
          75                 : #include "mozilla/Services.h"
          76                 : #include <stdlib.h>
          77                 : #include "nsIMemoryReporter.h"
          78                 :
          79                 : static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
          80                 : static NS_DEFINE_CID(kUnicharUtilCID, NS_UNICHARUTIL_CID);
          81                 :
          82              11 : NS_IMPL_CYCLE_COLLECTING_ADDREF(mozHunspell)
          83              11 : NS_IMPL_CYCLE_COLLECTING_RELEASE(mozHunspell)
          84                 :
          85              22 : NS_INTERFACE_MAP_BEGIN(mozHunspell)
          86              22 :   NS_INTERFACE_MAP_ENTRY(mozISpellCheckingEngine)
          87              19 :   NS_INTERFACE_MAP_ENTRY(nsIObserver)
          88              19 :   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
          89              17 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozISpellCheckingEngine)
          90              14 :   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(mozHunspell)
          91               8 : NS_INTERFACE_MAP_END
          92                 :
          93            1464 : NS_IMPL_CYCLE_COLLECTION_3(mozHunspell,
          94                 :                            mPersonalDictionary,
          95                 :                            mEncoder,
          96                 :                            mDecoder)
          97                 :
          98                 : // Memory reporting stuff.
          99                 : static PRInt64 gHunspellAllocatedSize = 0;
         100                 :
         101            5007 : NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(HunspellMallocSizeOfForCounterInc, "hunspell")
         102            5015 : NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN_UN(HunspellMallocSizeOfForCounterDec)
         103                 :
         104            5007 : void HunspellReportMemoryAllocation(void* ptr) {
         105            5007 :   gHunspellAllocatedSize += HunspellMallocSizeOfForCounterInc(ptr);
         106            5007 : }
         107            5015 : void HunspellReportMemoryDeallocation(void* ptr) {
         108            5015 :   gHunspellAllocatedSize -= HunspellMallocSizeOfForCounterDec(ptr);
         109            5015 : }
         110               0 : static PRInt64 HunspellGetCurrentAllocatedSize() {
         111               0 :   return gHunspellAllocatedSize;
         112                 : }
         113                 :
         114               1 : NS_MEMORY_REPORTER_IMPLEMENT(Hunspell,
         115                 :     "explicit/spell-check",
         116                 :     KIND_HEAP,
         117                 :     UNITS_BYTES,
         118                 :     HunspellGetCurrentAllocatedSize,
         119                 :     "Memory used by the Hunspell spell checking engine.  This number accounts "
         120                 :     "for the memory in use by Hunspell's internal data structures."
         121               3 : )
         122                 :
         123                 : nsresult
         124               1 : mozHunspell::Init()
         125                 : {
         126               1 :   if (!mDictionaries.Init())
         127               0 :     return NS_ERROR_OUT_OF_MEMORY;
         128                 :
         129               1 :   LoadDictionaryList();
         130                 :
         131               2 :   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
         132               1 :   if (obs) {
         133               1 :     obs->AddObserver(this, "profile-do-change", true);
         134               1 :     obs->AddObserver(this, "profile-after-change", true);
         135                 :   }
         136                 :
         137               1 :   mHunspellReporter = new NS_MEMORY_REPORTER_NAME(Hunspell);
         138               1 :   NS_RegisterMemoryReporter(mHunspellReporter);
         139                 :
         140               1 :   return NS_OK;
         141                 : }
         142                 :
         143               3 : mozHunspell::~mozHunspell()
         144                 : {
         145               1 :   mPersonalDictionary = nsnull;
         146               1 :   delete mHunspell;
         147                 :
         148               1 :   NS_UnregisterMemoryReporter(mHunspellReporter);
         149               4 : }
         150                 :
         151                 : /* attribute wstring dictionary; */
         152               0 : NS_IMETHODIMP mozHunspell::GetDictionary(PRUnichar **aDictionary)
         153                 : {
         154               0 :   NS_ENSURE_ARG_POINTER(aDictionary);
         155                 :
         156               0 :   *aDictionary = ToNewUnicode(mDictionary);
         157               0 :   return *aDictionary ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
         158                 : }
         159                 :
         160                 : /* set the Dictionary.
         161                 :  * This also Loads the dictionary and initializes the converter using the dictionaries converter
         162                 :  */
         163             110 : NS_IMETHODIMP mozHunspell::SetDictionary(const PRUnichar *aDictionary)
         164                 : {
         165             110 :   NS_ENSURE_ARG_POINTER(aDictionary);
         166                 :
         167             110 :   if (nsDependentString(aDictionary).IsEmpty()) {
         168               0 :     delete mHunspell;
         169               0 :     mHunspell = nsnull;
         170               0 :     mDictionary.AssignLiteral("");
         171               0 :     mAffixFileName.AssignLiteral("");
         172               0 :     mLanguage.AssignLiteral("");
         173               0 :     mDecoder = nsnull;
         174               0 :     mEncoder = nsnull;
         175                 :
         176               0 :     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
         177               0 :     if (obs) {
         178               0 :       obs->NotifyObservers(nsnull,
         179                 :                            SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION,
         180               0 :                            nsnull);
         181                 :     }
         182               0 :     return NS_OK;
         183                 :   }
         184                 :
         185             110 :   nsIFile* affFile = mDictionaries.GetWeak(nsDependentString(aDictionary));
         186             110 :   if (!affFile)
         187               0 :     return NS_ERROR_FILE_NOT_FOUND;
         188                 :
         189             220 :   nsCAutoString dictFileName, affFileName;
         190                 :
         191                 :   // XXX This isn't really good. nsIFile->NativePath isn't safe for all
         192                 :   // character sets on Windows.
         193                 :   // A better way would be to QI to nsILocalFile, and get a filehandle
         194                 :   // from there. Only problem is that hunspell wants a path
         195                 :
         196             110 :   nsresult rv = affFile->GetNativePath(affFileName);
         197             110 :   NS_ENSURE_SUCCESS(rv, rv);
         198                 :
         199             110 :   if (mAffixFileName.Equals(affFileName.get()))
         200               0 :     return NS_OK;
         201                 :
         202             110 :   dictFileName = affFileName;
         203             110 :   PRInt32 dotPos = dictFileName.RFindChar('.');
         204             110 :   if (dotPos == -1)
         205               0 :     return NS_ERROR_FAILURE;
         206                 :
         207             110 :   dictFileName.SetLength(dotPos);
         208             110 :   dictFileName.AppendLiteral(".dic");
         209                 :
         210                 :   // SetDictionary can be called multiple times, so we might have a
         211                 :   // valid mHunspell instance which needs cleaned up.
         212             110 :   delete mHunspell;
         213                 :
         214             110 :   mDictionary = aDictionary;
         215             110 :   mAffixFileName = affFileName;
         216                 :
         217                 :   mHunspell = new Hunspell(affFileName.get(),
         218             220 :                          dictFileName.get());
         219             110 :   if (!mHunspell)
         220               0 :     return NS_ERROR_OUT_OF_MEMORY;
         221                 :
         222                 :   nsCOMPtr<nsICharsetConverterManager> ccm =
         223             220 :     do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
         224             110 :   NS_ENSURE_SUCCESS(rv, rv);
         225                 :
         226             220 :   rv = ccm->GetUnicodeDecoder(mHunspell->get_dic_encoding(),
         227             220 :                               getter_AddRefs(mDecoder));
         228             110 :   NS_ENSURE_SUCCESS(rv, rv);
         229                 :
         230             220 :   rv = ccm->GetUnicodeEncoder(mHunspell->get_dic_encoding(),
         231             220 :                               getter_AddRefs(mEncoder));
         232             110 :   NS_ENSURE_SUCCESS(rv, rv);
         233                 :
         234                 :
         235             110 :   if (mEncoder)
         236             110 :     mEncoder->SetOutputErrorBehavior(mEncoder->kOnError_Signal, nsnull, '?');
         237                 :
         238             110 :   PRInt32 pos = mDictionary.FindChar('-');
         239             110 :   if (pos == -1)
         240             110 :     pos = mDictionary.FindChar('_');
         241                 :
         242             110 :   if (pos == -1)
         243              96 :     mLanguage.Assign(mDictionary);
         244                 :   else
         245              14 :     mLanguage = Substring(mDictionary, 0, pos);
         246                 :
         247             220 :   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
         248             110 :   if (obs) {
         249             110 :     obs->NotifyObservers(nsnull,
         250                 :                          SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION,
         251             110 :                          nsnull);
         252                 :   }
         253                 :
         254             110 :   return NS_OK;
         255                 : }
         256                 :
         257                 : /* readonly attribute wstring language; */
         258               0 : NS_IMETHODIMP mozHunspell::GetLanguage(PRUnichar **aLanguage)
         259                 : {
         260               0 :   NS_ENSURE_ARG_POINTER(aLanguage);
         261                 :
         262               0 :   if (mDictionary.IsEmpty())
         263               0 :     return NS_ERROR_NOT_INITIALIZED;
         264                 :
         265               0 :   *aLanguage = ToNewUnicode(mLanguage);
         266               0 :   return *aLanguage ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
         267                 : }
         268                 :
         269                 : /* readonly attribute boolean providesPersonalDictionary; */
         270               0 : NS_IMETHODIMP mozHunspell::GetProvidesPersonalDictionary(bool *aProvidesPersonalDictionary)
         271                 : {
         272               0 :   NS_ENSURE_ARG_POINTER(aProvidesPersonalDictionary);
         273                 :
         274               0 :   *aProvidesPersonalDictionary = false;
         275               0 :   return NS_OK;
         276                 : }
         277                 :
         278                 : /* readonly attribute boolean providesWordUtils; */
         279               0 : NS_IMETHODIMP mozHunspell::GetProvidesWordUtils(bool *aProvidesWordUtils)
         280                 : {
         281               0 :   NS_ENSURE_ARG_POINTER(aProvidesWordUtils);
         282                 :
         283               0 :   *aProvidesWordUtils = false;
         284               0 :   return NS_OK;
         285                 : }
         286                 :
         287                 : /* readonly attribute wstring name; */
         288               0 : NS_IMETHODIMP mozHunspell::GetName(PRUnichar * *aName)
         289                 : {
         290               0 :   return NS_ERROR_NOT_IMPLEMENTED;
         291                 : }
         292                 :
         293                 : /* readonly attribute wstring copyright; */
         294               0 : NS_IMETHODIMP mozHunspell::GetCopyright(PRUnichar * *aCopyright)
         295                 : {
         296               0 :   return NS_ERROR_NOT_IMPLEMENTED;
         297                 : }
         298                 :
         299                 : /* attribute mozIPersonalDictionary personalDictionary; */
         300               0 : NS_IMETHODIMP mozHunspell::GetPersonalDictionary(mozIPersonalDictionary * *aPersonalDictionary)
         301                 : {
         302               0 :   *aPersonalDictionary = mPersonalDictionary;
         303               0 :   NS_IF_ADDREF(*aPersonalDictionary);
         304               0 :   return NS_OK;
         305                 : }
         306                 :
         307               0 : NS_IMETHODIMP mozHunspell::SetPersonalDictionary(mozIPersonalDictionary * aPersonalDictionary)
         308                 : {
         309               0 :   mPersonalDictionary = aPersonalDictionary;
         310               0 :   return NS_OK;
         311                 : }
         312                 :
         313                 : struct AppendNewStruct
         314                 : {
         315                 :   PRUnichar **dics;
         316                 :   PRUint32 count;
         317                 :   bool failed;
         318                 : };
         319                 :
         320                 : static PLDHashOperator
         321               0 : AppendNewString(const nsAString& aString, nsIFile* aFile, void* aClosure)
         322                 : {
         323               0 :   AppendNewStruct *ans = (AppendNewStruct*) aClosure;
         324               0 :   ans->dics[ans->count] = ToNewUnicode(aString);
         325               0 :   if (!ans->dics[ans->count]) {
         326               0 :     ans->failed = true;
         327               0 :     return PL_DHASH_STOP;
         328                 :   }
         329                 :
         330               0 :   ++ans->count;
         331               0 :   return PL_DHASH_NEXT;
         332                 : }
         333                 :
         334                 : /* void GetDictionaryList ([array, size_is (count)] out wstring dictionaries, out PRUint32 count); */
         335               0 : NS_IMETHODIMP mozHunspell::GetDictionaryList(PRUnichar ***aDictionaries,
         336                 :                                             PRUint32 *aCount)
         337                 : {
         338               0 :   if (!aDictionaries || !aCount)
         339               0 :     return NS_ERROR_NULL_POINTER;
         340                 :
         341                 :   AppendNewStruct ans = {
         342               0 :     (PRUnichar**) NS_Alloc(sizeof(PRUnichar*) * mDictionaries.Count()),
         343                 :     0,
         344                 :     false
         345               0 :   };
         346                 :
         347                 :   // This pointer is used during enumeration
         348               0 :   mDictionaries.EnumerateRead(AppendNewString, &ans);
         349                 :
         350               0 :   if (ans.failed) {
         351               0 :     while (ans.count) {
         352               0 :       --ans.count;
         353               0 :       NS_Free(ans.dics[ans.count]);
         354                 :     }
         355               0 :     NS_Free(ans.dics);
         356               0 :     return NS_ERROR_OUT_OF_MEMORY;
         357                 :   }
         358                 :
         359               0 :   *aDictionaries = ans.dics;
         360               0 :   *aCount = ans.count;
         361                 :
         362               0 :   return NS_OK;
         363                 : }
         364                 :
         365                 : void
         366               1 : mozHunspell::LoadDictionaryList()
         367                 : {
         368               1 :   mDictionaries.Clear();
         369                 :
         370                 :   nsresult rv;
         371                 :
         372                 :   nsCOMPtr<nsIProperties> dirSvc =
         373               2 :     do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
         374               1 :   if (!dirSvc)
         375                 :     return;
         376                 :
         377                 :   // find built in dictionaries
         378               2 :   nsCOMPtr<nsIFile> dictDir;
         379               1 :   rv = dirSvc->Get(DICTIONARY_SEARCH_DIRECTORY,
         380               1 :                    NS_GET_IID(nsIFile), getter_AddRefs(dictDir));
         381               1 :   if (NS_SUCCEEDED(rv)) {
         382               0 :     LoadDictionariesFromDir(dictDir);
         383                 :   }
         384                 :   else {
         385                 :     // try to load gredir/dictionaries
         386               2 :     nsCOMPtr<nsIFile> greDir;
         387               1 :     rv = dirSvc->Get(NS_GRE_DIR,
         388               1 :                      NS_GET_IID(nsIFile), getter_AddRefs(greDir));
         389               1 :     if (NS_SUCCEEDED(rv)) {
         390               1 :       greDir->AppendNative(NS_LITERAL_CSTRING("dictionaries"));
         391               1 :       LoadDictionariesFromDir(greDir);
         392                 :     }
         393                 :
         394                 :     // try to load appdir/dictionaries only if different than gredir
         395               2 :     nsCOMPtr<nsIFile> appDir;
         396               1 :     rv = dirSvc->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
         397               1 :                      NS_GET_IID(nsIFile), getter_AddRefs(appDir));
         398                 :     bool equals;
         399               1 :     if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(appDir->Equals(greDir, &equals)) && !equals) {
         400               1 :       appDir->AppendNative(NS_LITERAL_CSTRING("dictionaries"));
         401               1 :       LoadDictionariesFromDir(appDir);
         402                 :     }
         403                 :   }
         404                 :
         405                 :   // find dictionaries from extensions requiring restart
         406               2 :   nsCOMPtr<nsISimpleEnumerator> dictDirs;
         407               1 :   rv = dirSvc->Get(DICTIONARY_SEARCH_DIRECTORY_LIST,
         408               1 :                    NS_GET_IID(nsISimpleEnumerator), getter_AddRefs(dictDirs));
         409               1 :   if (NS_FAILED(rv))
         410                 :     return;
         411                 :
         412                 :   bool hasMore;
         413               0 :   while (NS_SUCCEEDED(dictDirs->HasMoreElements(&hasMore)) && hasMore) {
         414               0 :     nsCOMPtr<nsISupports> elem;
         415               0 :     dictDirs->GetNext(getter_AddRefs(elem));
         416                 :
         417               0 :     dictDir = do_QueryInterface(elem);
         418               0 :     if (dictDir)
         419               0 :       LoadDictionariesFromDir(dictDir);
         420                 :   }
         421                 :
         422                 :   // find dictionaries from restartless extensions
         423               0 :   for (PRUint32 i = 0; i < mDynamicDirectories.Count(); i++) {
         424               0 :     LoadDictionariesFromDir(mDynamicDirectories[i]);
         425                 :   }
         426                 :
         427                 :   // Now we have finished updating the list of dictionaries, update the current
         428                 :   // dictionary and any editors which may use it.
         429               0 :   mozInlineSpellChecker::UpdateCanEnableInlineSpellChecking();
         430                 :
         431                 :   // Check if the current dictionary is still available.
         432                 :   // If not, try to replace it with another dictionary of the same language.
         433               0 :   if (!mDictionary.IsEmpty()) {
         434               0 :     rv = SetDictionary(mDictionary.get());
         435               0 :     if (NS_SUCCEEDED(rv))
         436                 :       return;
         437                 :   }
         438                 :
         439                 :   // If the current dictionary has gone, and we don't have a good replacement,
         440                 :   // set no current dictionary.
         441               0 :   if (!mDictionary.IsEmpty()) {
         442               0 :     SetDictionary(EmptyString().get());
         443                 :   }
         444                 : }
         445                 :
         446                 : NS_IMETHODIMP
         447               3 : mozHunspell::LoadDictionariesFromDir(nsIFile* aDir)
         448                 : {
         449                 :   nsresult rv;
         450                 :
         451               3 :   bool check = false;
         452               3 :   rv = aDir->Exists(&check);
         453               3 :   if (NS_FAILED(rv) || !check)
         454               0 :     return NS_ERROR_UNEXPECTED;
         455                 :
         456               3 :   rv = aDir->IsDirectory(&check);
         457               3 :   if (NS_FAILED(rv) || !check)
         458               0 :     return NS_ERROR_UNEXPECTED;
         459                 :
         460               6 :   nsCOMPtr<nsISimpleEnumerator> e;
         461               3 :   rv = aDir->GetDirectoryEntries(getter_AddRefs(e));
         462               3 :   if (NS_FAILED(rv))
         463               0 :     return NS_ERROR_UNEXPECTED;
         464                 :
         465               6 :   nsCOMPtr<nsIDirectoryEnumerator> files(do_QueryInterface(e));
         466               3 :   if (!files)
         467               0 :     return NS_ERROR_UNEXPECTED;
         468                 :
         469               6 :   nsCOMPtr<nsIFile> file;
         470             571 :   while (NS_SUCCEEDED(files->GetNextFile(getter_AddRefs(file))) && file) {
         471            1130 :     nsAutoString leafName;
         472             565 :     file->GetLeafName(leafName);
         473             565 :     if (!StringEndsWith(leafName, NS_LITERAL_STRING(".dic")))
         474             451 :       continue;
         475                 :
         476             228 :     nsAutoString dict(leafName);
         477             114 :     dict.SetLength(dict.Length() - 4); // magic length of ".dic"
         478                 :
         479                 :     // check for the presence of the .aff file
         480             114 :     leafName = dict;
         481             114 :     leafName.AppendLiteral(".aff");
         482             114 :     file->SetLeafName(leafName);
         483             114 :     rv = file->Exists(&check);
         484             114 :     if (NS_FAILED(rv) || !check)
         485               0 :       continue;
         486                 :
         487                 : #ifdef DEBUG_bsmedberg
         488                 :     printf("Adding dictionary: %s\n", NS_ConvertUTF16toUTF8(dict).get());
         489                 : #endif
         490                 :
         491             228 :     mDictionaries.Put(dict, file);
         492                 :   }
         493                 :
         494               3 :   return NS_OK;
         495                 : }
         496                 :
         497            1030 : nsresult mozHunspell::ConvertCharset(const PRUnichar* aStr, char ** aDst)
         498                 : {
         499            1030 :   NS_ENSURE_ARG_POINTER(aDst);
         500            1030 :   NS_ENSURE_TRUE(mEncoder, NS_ERROR_NULL_POINTER);
         501                 :
         502                 :   PRInt32 outLength;
         503            1030 :   PRInt32 inLength = nsCRT::strlen(aStr);
         504            1030 :   nsresult rv = mEncoder->GetMaxLength(aStr, inLength, &outLength);
         505            1030 :   NS_ENSURE_SUCCESS(rv, rv);
         506                 :
         507            1030 :   *aDst = (char *) nsMemory::Alloc(sizeof(char) * (outLength+1));
         508            1030 :   NS_ENSURE_TRUE(*aDst, NS_ERROR_OUT_OF_MEMORY);
         509                 :
         510            1030 :   rv = mEncoder->Convert(aStr, &inLength, *aDst, &outLength);
         511            1030 :   if (NS_SUCCEEDED(rv))
         512            1030 :     (*aDst)[outLength] = '\0';
         513                 :
         514            1030 :   return rv;
         515                 : }
         516                 :
         517                 : /* boolean Check (in wstring word); */
         518            1030 : NS_IMETHODIMP mozHunspell::Check(const PRUnichar *aWord, bool *aResult)
         519                 : {
         520            1030 :   NS_ENSURE_ARG_POINTER(aWord);
         521            1030 :   NS_ENSURE_ARG_POINTER(aResult);
         522            1030 :   NS_ENSURE_TRUE(mHunspell, NS_ERROR_FAILURE);
         523                 :
         524            2060 :   nsXPIDLCString charsetWord;
         525            1030 :   nsresult rv = ConvertCharset(aWord, getter_Copies(charsetWord));
         526            1030 :   NS_ENSURE_SUCCESS(rv, rv);
         527                 :
         528            1030 :   *aResult = !!mHunspell->spell(charsetWord);
         529                 :
         530                 :
         531            1030 :   if (!*aResult && mPersonalDictionary)
         532               0 :     rv = mPersonalDictionary->Check(aWord, mLanguage.get(), aResult);
         533                 :
         534            1030 :   return rv;
         535                 : }
         536                 :
         537                 : /* void Suggest (in wstring word, [array, size_is (count)] out wstring suggestions, out PRUint32 count); */
         538               0 : NS_IMETHODIMP mozHunspell::Suggest(const PRUnichar *aWord, PRUnichar ***aSuggestions, PRUint32 *aSuggestionCount)
         539                 : {
         540               0 :   NS_ENSURE_ARG_POINTER(aSuggestions);
         541               0 :   NS_ENSURE_ARG_POINTER(aSuggestionCount);
         542               0 :   NS_ENSURE_TRUE(mHunspell, NS_ERROR_FAILURE);
         543                 :
         544                 :   nsresult rv;
         545               0 :   *aSuggestionCount = 0;
         546                 :
         547               0 :   nsXPIDLCString charsetWord;
         548               0 :   rv = ConvertCharset(aWord, getter_Copies(charsetWord));
         549               0 :   NS_ENSURE_SUCCESS(rv, rv);
         550                 :
         551                 :   char ** wlst;
         552               0 :   *aSuggestionCount = mHunspell->suggest(&wlst, charsetWord);
         553                 :
         554               0 :   if (*aSuggestionCount) {
         555               0 :     *aSuggestions  = (PRUnichar **)nsMemory::Alloc(*aSuggestionCount * sizeof(PRUnichar *));
         556               0 :     if (*aSuggestions) {
         557               0 :       PRUint32 index = 0;
         558               0 :       for (index = 0; index < *aSuggestionCount && NS_SUCCEEDED(rv); ++index) {
         559                 :         // Convert the suggestion to utf16
         560               0 :         PRInt32 inLength = nsCRT::strlen(wlst[index]);
         561                 :         PRInt32 outLength;
         562               0 :         rv = mDecoder->GetMaxLength(wlst[index], inLength, &outLength);
         563               0 :         if (NS_SUCCEEDED(rv))
         564                 :         {
         565               0 :           (*aSuggestions)[index] = (PRUnichar *) nsMemory::Alloc(sizeof(PRUnichar) * (outLength+1));
         566               0 :           if ((*aSuggestions)[index])
         567                 :           {
         568               0 :             rv = mDecoder->Convert(wlst[index], &inLength, (*aSuggestions)[index], &outLength);
         569               0 :             if (NS_SUCCEEDED(rv))
         570               0 :               (*aSuggestions)[index][outLength] = 0;
         571                 :           }
         572                 :           else
         573               0 :             rv = NS_ERROR_OUT_OF_MEMORY;
         574                 :         }
         575                 :       }
         576                 :
         577               0 :       if (NS_FAILED(rv))
         578               0 :         NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(index, *aSuggestions); // free the PRUnichar strings up to the point at which the error occurred
         579                 :     }
         580                 :     else // if (*aSuggestions)
         581               0 :       rv = NS_ERROR_OUT_OF_MEMORY;
         582                 :   }
         583                 :
         584               0 :   NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(*aSuggestionCount, wlst);
         585               0 :   return rv;
         586                 : }
         587                 :
         588                 : NS_IMETHODIMP
         589               0 : mozHunspell::Observe(nsISupports* aSubj, const char *aTopic,
         590                 :                     const PRUnichar *aData)
         591                 : {
         592               0 :   NS_ASSERTION(!strcmp(aTopic, "profile-do-change")
         593                 :                || !strcmp(aTopic, "profile-after-change"),
         594                 :                "Unexpected observer topic");
         595                 :
         596               0 :   LoadDictionaryList();
         597                 :
         598               0 :   return NS_OK;
         599                 : }
         600                 :
         601                 : /* void addDirectory(in nsIFile dir); */
         602               0 : NS_IMETHODIMP mozHunspell::AddDirectory(nsIFile *aDir)
         603                 : {
         604               0 :   mDynamicDirectories.AppendObject(aDir);
         605               0 :   LoadDictionaryList();
         606               0 :   return NS_OK;
         607                 : }
         608                 :
         609                 : /* void removeDirectory(in nsIFile dir); */
         610               0 : NS_IMETHODIMP mozHunspell::RemoveDirectory(nsIFile *aDir)
         611                 : {
         612               0 :   mDynamicDirectories.RemoveObject(aDir);
         613               0 :   LoadDictionaryList();
         614               0 :   return NS_OK;
         615            4392 : }

Generated by: LCOV version 1.7