r=mkaply, pedemont, jblanco, sr=kin@netscape.com, a=drivers
Check mozdev spellchecker into Mozilla - hurrah!
Not turned on yet :)
This commit is contained in:
mkaply%us.ibm.com 2003-07-24 21:39:28 +00:00
parent d436db9321
commit 53a6b6daf9
44 changed files with 66304 additions and 97 deletions

View File

@ -0,0 +1 @@
Makefile

View File

@ -1,36 +1,47 @@
# 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
# ***** 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 Original Code is Mozilla Spellchecker Component.
#
# The Initial Developer of the Original Code is
# David Einstein.
# Portions created by the Initial Developer are Copyright (C) 2001
# the Initial Developer. All Rights Reserved.
#
# Contributor(s): David Einstein <Deinst@world.std.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 *****
# 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 Developer of the Original Code is Aaron Leventhal.
# Portions created by Aaron Leventhal are Copyright (C) 2001
# Aaron Leventhal. All Rights Reserved.
# Alternatively, the contents of this file may be used under the terms
# of the GNU General Public License (the "GPL"), in which case the
# provisions of the GPL are applicable instead of those above. If you
# wish to allow use of your version of this file only under the terms of
# the GPL and not to allow others to use your version of this file under
# the MPL, indicate your decision by deleting the provisions above and
# replace them with the notice and other provisions required by the
# GPL. If you do not delete the provisions above, a recipient may use
# your version of this file under either the MPL or the GPL.
# Contributor(s):
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = src
DIRS = src idl myspell
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,2 @@
Makefile
_xpidlgen

View File

@ -0,0 +1,56 @@
# ***** 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 Original Code is Mozilla Spellchecker Component.
#
# The Initial Developer of the Original Code is
# David Einstein.
# Portions created by the Initial Developer are Copyright (C) 2001
# the Initial Developer. All Rights Reserved.
#
# Contributor(s): David Einstein <Deinst@world.std.com>
# Aleksey Nogin <ayn2@cornell.edu>
#
# 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 *****
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
MODULE = spellchecker
XPIDL_MODULE = spellchecker
include $(DEPTH)/config/autoconf.mk
XPIDLSRCS = \
mozIPersonalDictionary.idl \
mozISpellCheckingEngine.idl \
mozISpellI18NUtil.idl \
mozISpellI18NManager.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,97 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
[scriptable, uuid(24C87207-AD7B-40e0-A074-B5401D9925E6)]
/**
This interface represents a Personal Dictionary.
*/
interface mozIPersonalDictionary : nsISupports {
/* The language being spell checked (In case we want to qualify words by language */
attribute wstring language;
/* the charset that the spell checker is using */
attribute wstring charset;
/* Initialize the dictionary */
void Init();
/* Load the dictionary */
void Load();
/* Save the dictionary */
void Save();
/* Get the list of words */
void GetWordList([array, size_is(count)] out wstring words, out PRUint32 count);
/* Check a unicode string */
boolean CheckUnicode(in wstring word);
/* Check a string in the current charset */
boolean Check(in string word);
/* Add a word to the personal dictionary */
void AddWord(in wstring word, in wstring lang);
/* Remove a word from the personal dictionary */
void RemoveWord(in wstring word, in wstring lang);
/* Add a word to the ignore all list */
void IgnoreWord(in wstring word);
/* Clear the ignore list */
void EndSession();
/** These three functions are here in case we want to store previous
* misspellings and return them at the head of the misspell list.
*/
/* Add a misspelling to the list of corrections */
void AddCorrection(in wstring word,in wstring correction, in wstring lang);
/* Add a misspelling to the list of corrections */
void RemoveCorrection(in wstring word,in wstring correction, in wstring lang);
/* Get a list of previous corrections for the word */
void GetCorrection(in wstring word, [array, size_is(count)] out wstring words, out PRUint32 count);
};

View File

@ -0,0 +1,82 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
interface mozIPersonalDictionary;
[scriptable, uuid(781E555A-51CA-47a7-88BF-BF306A062DC0)]
/**
This interface represents a SpellChecker.
*/
interface mozISpellCheckingEngine : nsISupports {
/* The name of the current dictionary */
attribute wstring dictionary;
/* The charset that we are using, somone may want to know. */
readonly attribute wstring charset;
/* The language we think that we're checking */
readonly attribute wstring language;
/* Does the engine provide its own PD? */
readonly attribute boolean providesPersonalDictionary;
/* Does the engine provide its own word utils? */
readonly attribute boolean providesWordUtils;
/* The name of the engine */
readonly attribute wstring name;
/* The name of the engine */
readonly attribute wstring copyright;
/* the personal dictionary */
attribute mozIPersonalDictionary personalDictionary;
/* Get the list of dictionaries */
void GetDictionaryList([array, size_is(count)] out wstring dictionaries, out PRUint32 count);
/* check a word */
boolean Check(in wstring word);
/* get a list of suggestions for a misspelled word */
void Suggest(in wstring word,[array, size_is(count)] out wstring suggestions, out PRUint32 count);
};

View File

@ -0,0 +1,50 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
#include "mozISpellI18NUtil.idl"
[scriptable, uuid(35D0B5E6-270A-4a95-92B2-384E1806AE83)]
/**
This interface contains various I18N related code used in various places by the spell checker.
*/
interface mozISpellI18NManager : nsISupports {
mozISpellI18NUtil GetUtil(in wstring language);
};

View File

@ -0,0 +1,69 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
[scriptable, uuid(24635FE1-2C7F-4d91-9274-B1AC77D93419)]
/**
This interface contains various I18N related code used in various places by the spell checker.
*/
interface mozISpellI18NUtil : nsISupports {
const PRUint32 kCheck=0;
const PRUint32 kSuggest=1;
/* The language being spell checked*/
readonly attribute wstring language;
/* The charset that the spell checker is using */
attribute wstring charset;
/* Given a word return a list of possible root forms of that word */
void GetRootForm(in wstring word, in PRUint32 type, [array, size_is(count)] out string words, out PRUint32 count);
/* Given a word return a list of possible root forms of that word */
void FromRootForm(in wstring word, [array, size_is(icount)] in string iwords, in PRUint32 icount, [array, size_is(ocount)] out wstring owords, out PRUint32 ocount);
/* Given a unicode string and an offset find the beginning and end of the next word
* begin and end are -1 if there are no words remaining in the string
* This should really be folded into the Line/WordBreaker.
**/
void FindNextWord(in wstring word, in PRUint32 length, in PRUint32 offset, out PRInt32 begin, out PRInt32 end);
};

View File

@ -0,0 +1 @@
Makefile

View File

@ -0,0 +1,47 @@
# ***** 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 Original Code is Mozilla Spellchecker Component.
#
# The Initial Developer of the Original Code is
# David Einstein.
# Portions created by the Initial Developer are Copyright (C) 2001
# the Initial Developer. All Rights Reserved.
#
# Contributor(s): David Einstein <Deinst@world.std.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 *****
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = src dictionaries
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1 @@
Makefile

View File

@ -0,0 +1,98 @@
SET ISO-8859-1
TRY esianrtolcdugmphbyfvkw
PFX A Y 1
PFX A 0 re .
PFX I Y 1
PFX I 0 in .
PFX U Y 1
PFX U 0 un .
PFX C Y 1
PFX C 0 de .
PFX E Y 1
PFX E 0 dis .
PFX F Y 1
PFX F 0 con .
PFX K Y 1
PFX K 0 pro .
SFX V N 2
SFX V e ive e
SFX V 0 ive [^e]
SFX N Y 3
SFX N e ion e
SFX N y ication y
SFX N 0 en [^ey]
SFX X Y 3
SFX X e ions e
SFX X y ications y
SFX X 0 ens [^ey]
SFX H N 2
SFX H y ieth y
SFX H 0 th [^y]
SFX Y Y 1
SFX Y 0 ly .
SFX G Y 2
SFX G e ing e
SFX G 0 ing [^e]
SFX J Y 2
SFX J e ings e
SFX J 0 ings [^e]
SFX D Y 4
SFX D 0 d e
SFX D y ied [^aeiou]y
SFX D 0 ed [^ey]
SFX D 0 ed [aeiou]y
SFX T N 4
SFX T 0 st e
SFX T y iest [^aeiou]y
SFX T 0 est [aeiou]y
SFX T 0 est [^ey]
SFX R Y 4
SFX R 0 r e
SFX R y ier [^aeiou]y
SFX R 0 er [aeiou]y
SFX R 0 er [^ey]
SFX Z Y 4
SFX Z 0 rs e
SFX Z y iers [^aeiou]y
SFX Z 0 ers [aeiou]y
SFX Z 0 ers [^ey]
SFX S Y 4
SFX S y ies [^aeiou]y
SFX S 0 s [aeiou]y
SFX S 0 es [sxzh]
SFX S 0 s [^sxzhy]
SFX P Y 3
SFX P y iness [^aeiou]y
SFX P 0 ness [aeiou]y
SFX P 0 ness [^y]
SFX M Y 1
SFX M 0 's .
SFX B Y 3
SFX B 0 able [^aeiou]
SFX B 0 able ee
SFX B e able [^aeiou]e
SFX L Y 1
SFX L 0 ment .

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,2 @@
.deps
Makefile

View File

@ -0,0 +1,83 @@
# ***** 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 Original Code is Mozilla Spellchecker Component.
#
# The Initial Developer of the Original Code is
# David Einstein.
# Portions created by the Initial Developer are Copyright (C) 2001
# the Initial Developer. All Rights Reserved.
#
# Contributor(s): David Einstein <Deinst@world.std.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 *****
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = myspell
LIBRARY_NAME = myspell
EXPORT_LIBRARY = 1
IS_COMPONENT = 1
MODULE_NAME = mozMySpellModule
REQUIRES = xpcom \
string \
editor \
content \
layout \
dom \
necko \
widget \
gfx \
txtsvc \
uconv \
unicharutil \
spellchecker \
nspr \
$(NULL)
CPPSRCS = \
mozCStr2CStrHashtable.cpp \
mozAffixMod.cpp \
myspAffixmgr.cpp \
mozMySpell.cpp \
myspSuggestmgr.cpp \
mozMySpellFactory.cpp \
$(NULL)
EXTRA_DSO_LDOPTS = \
-L$(DIST)/bin \
-L$(DIST)/lib \
$(XPCOM_LIBS) \
$(NSPR_LIBS) \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,44 @@
/*
* Copyright 2001 Kevin B. Hendricks, Stratford, Ontario, Canada
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. All modifications to the source code must be clearly marked as
* such. Binary redistributions based on modified source code
* must be clearly marked as modified versions in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*
* NOTE: A special thanks and credit goes to Geoff Kuenning
* the creator of ispell. MySpell's affix algorithms were
* based on those of ispell which should be noted is
* copyright Geoff Kuenning et.al. and now available
* under a BSD style license. For more information on ispell
* and affix compression in general, please see:
* http://www.cs.ucla.edu/ficus-members/geoff/ispell.html
* (the home page for ispell)
*
*/

View File

@ -0,0 +1,271 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein <Deinst@world.std.com>
* Kevin Hendricks <kevin.hendricks@sympatico.ca>
*
* 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.
*
* This spellchecker is based on the MySpell spellchecker made for Open Office
* by Kevin Hendricks. Although the algorithms and code, have changed
* slightly, the architecture is still the same. The Mozilla implementation
* is designed to be compatible with the Open Office dictionaries.
* Please do not make changes to the affix or dictionary file formats
* without attempting to coordinate with Kevin. For more information
* on the original MySpell see
* http://whiteboard.openoffice.org/source/browse/whiteboard/lingucomponent/source/spellcheck/myspell/
*
* A special thanks and credit goes to Geoff Kuenning
* the creator of ispell. MySpell's affix algorithms were
* based on those of ispell which should be noted is
* copyright Geoff Kuenning et.al. and now available
* under a BSD style license. For more information on ispell
* and affix compression in general, please see:
* http://www.cs.ucla.edu/ficus-members/geoff/ispell.html
* (the home page for ispell)
*
* ***** END LICENSE BLOCK ***** */
/* based on MySpell (c) 2001 by Kevin Hendicks */
#include "mozAffixMod.h"
mozAffixState::mozAffixState()
{
mTrans=nsnull;
mMods=nsnull;
mDefault=nsnull;
}
mozAffixState::~mozAffixState()
{
clear();
}
void
mozAffixState::clear()
{
// clean out any mods
mozAffixMod * nextmod=mMods;
while(nextmod != nsnull){
mozAffixMod *temp=nextmod->next;
delete nextmod;
nextmod = temp;
}
mMods=nsnull;
//clean out transitions
mozAffixStateTrans * nexttrans=mTrans;
while(nexttrans != nsnull){
mozAffixStateTrans *temp=nexttrans->nextTrans;
delete nexttrans->nextState;
delete nexttrans;
nexttrans=temp;
}
mTrans=nsnull;
if(mDefault != nsnull){
delete mDefault;
}
mDefault=nsnull;
}
mozAffixState *
mozAffixState::nextState(char c)
{
mozAffixStateTrans * nexttrans=mTrans;
while(nexttrans != nsnull){
if(c==nexttrans->mRule) return nexttrans->nextState;
nexttrans = nexttrans->nextTrans;
}
return mDefault;
}
void
mozAffixState::addMod(const char *affix, mozAffixMod *mod)
{
mozAffixStateTrans * nexttrans=mTrans;
// figure out what kind of character we have and act accordingly
if(*affix == '['){
char *endblock=(char *)affix+1;
char *startblock=(char *)affix+1;
while((*endblock != ']')&&(*endblock != '\0')) endblock++;
if(*startblock == '^'){
char *currblock = startblock+1;
//OK, let us start with the complicated case.
//Here we sacrifice efficiency for simplicity. we are only running this at startup,
// and the lists are not going to be large anyway. First we modify all of the states
// not in the block, then we add unmodified clones for the states in the block that do
// not occur in the list already.
//first loop -- go through current states modifying if not found;
while(nexttrans != nsnull){
currblock=startblock+1;
PRBool found=PR_FALSE;
while(currblock < endblock){
if(*currblock == nexttrans->mRule){
found = PR_TRUE;
break;
}
currblock++;
}
if(!found){
nexttrans->nextState->addMod(endblock+1,mod);
}
nexttrans=nexttrans->nextTrans;
}
//second loop add new states if necessary (if they don't already exist)
currblock = startblock+1;
while(currblock < endblock){
//just add each block one at a time
PRBool found=PR_FALSE;
nexttrans=mTrans;
while(nexttrans!=nsnull){
if(nexttrans->mRule == *currblock){
found = PR_TRUE;
break;
}
nexttrans=nexttrans->nextTrans;
}
if(!found){
mozAffixState *newState=clone(mDefault);
mozAffixStateTrans *newTrans=new mozAffixStateTrans;
newTrans->mRule=*currblock;
newTrans->nextState=newState;
newTrans->nextTrans=mTrans;
mTrans=newTrans;
}
currblock++;
}
if(mDefault==nsnull) mDefault=new mozAffixState;
mDefault->addMod(endblock+1,mod);
}
else{ // a block of included characters
while(startblock < endblock){
//just add each block one at a time
PRBool found=PR_FALSE;
nexttrans=mTrans;
while(nexttrans!=nsnull){
if(nexttrans->mRule == *startblock){
nexttrans->nextState->addMod(endblock+1,mod);
found = PR_TRUE;
break;
}
nexttrans=nexttrans->nextTrans;
}
if(!found){
mozAffixState *newState=clone(mDefault);
mozAffixStateTrans *newTrans=new mozAffixStateTrans;
newTrans->mRule=*startblock;
newTrans->nextState=newState;
newTrans->nextTrans=mTrans;
mTrans=newTrans;
newState->addMod(endblock+1,mod);
}
startblock++;
}
}
}
else if(*affix == '\0'){
// all we've got to do is insert the mod;
mozAffixMod * temp= new mozAffixMod;
temp->mID=mod->mID;
temp->flags= mod->flags;
temp->mAppend.Assign( mod->mAppend);
temp->mTruncateLength = mod->mTruncateLength;
temp->next= mMods;
mMods=temp;
}
else{
// If the single character is a "." fill everything.
if (*affix == '.'){
while((nexttrans!=nsnull)){
nexttrans->nextState->addMod(affix+1,mod);
nexttrans=nexttrans->nextTrans;
}
if(mDefault==nsnull) mDefault=new mozAffixState;
mDefault->addMod(affix+1,mod);
}
else {
PRBool found=PR_FALSE;
while((nexttrans!=nsnull)){
if(nexttrans->mRule == *affix){
nexttrans->nextState->addMod(affix+1,mod);
found = PR_TRUE;
break;
}
nexttrans=nexttrans->nextTrans;
}
if(!found){
mozAffixState *newState=clone(mDefault);
mozAffixStateTrans *newTrans=new mozAffixStateTrans;
newTrans->mRule=*affix;
newTrans->nextState=newState;
newTrans->nextTrans=mTrans;
mTrans=newTrans;
newState->addMod(affix+1,mod);
}
}
}
}
mozAffixState *
mozAffixState::clone(mozAffixState * old)
{
mozAffixState *newState = new mozAffixState;
if(old != nsnull){
if(old->mDefault != nsnull){
mDefault=clone(old->mDefault);
}
mozAffixStateTrans *nexttrans=old->mTrans;
while(nexttrans != nsnull){
mozAffixStateTrans *temp = new mozAffixStateTrans;
temp->mRule = nexttrans->mRule;
temp->nextState = clone(nexttrans->nextState);
temp->nextTrans=mTrans;
mTrans=temp;
nexttrans = nexttrans->nextTrans;
}
mozAffixMod *nextMod=old->mMods;
while(nextMod!=nsnull){
mozAffixMod * temp= new mozAffixMod;
temp->mID=nextMod->mID;
temp->flags = nextMod->flags;
temp->mAppend.Assign( nextMod->mAppend);
temp->mTruncateLength = nextMod->mTruncateLength;
temp->next=mMods;
mMods=temp;
nextMod = nextMod->next;
}
}
return newState;
}

View File

@ -0,0 +1,99 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein <Deinst@world.std.com>
* Kevin Hendricks <kevin.hendricks@sympatico.ca>
*
* 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.
*
* This spellchecker is based on the MySpell spellchecker made for Open Office
* by Kevin Hendricks. Although the algorithms and code, have changed
* slightly, the architecture is still the same. The Mozilla implementation
* is designed to be compatible with the Open Office dictionaries.
* Please do not make changes to the affix or dictionary file formats
* without attempting to coordinate with Kevin. For more information
* on the original MySpell see
* http://whiteboard.openoffice.org/source/browse/whiteboard/lingucomponent/source/spellcheck/myspell/
*
* A special thanks and credit goes to Geoff Kuenning
* the creator of ispell. MySpell's affix algorithms were
* based on those of ispell which should be noted is
* copyright Geoff Kuenning et.al. and now available
* under a BSD style license. For more information on ispell
* and affix compression in general, please see:
* http://www.cs.ucla.edu/ficus-members/geoff/ispell.html
* (the home page for ispell)
*
* ***** END LICENSE BLOCK ***** */
#ifndef mozAffixMod_h__
#define mozAffixMod_h__
#include "nsString.h"
struct mozAffixMod
{
char mID; //character identifier.
nsSharableCString mAppend; //Standard ending to append
PRUint16 flags; //flags
PRUint16 mTruncateLength; //length of special ending to remove
mozAffixMod* next;
};
class mozAffixState;
struct mozAffixStateTrans
{
char mRule;
mozAffixState *nextState;
mozAffixStateTrans *nextTrans;
};
class mozAffixState
{
public:
mozAffixState();
~mozAffixState();
// we are splitting this into two seperate states
mozAffixState *nextState(char c);
void addMod(const char* affix, mozAffixMod *mod);
mozAffixMod *getMod(){return mMods;}
void clear();
protected:
mozAffixState * clone(mozAffixState* old);
private:
mozAffixStateTrans *mTrans;
mozAffixState *mDefault;
//a list of next states
mozAffixMod *mMods;
};
#endif // mozAffixMod_h__

View File

@ -0,0 +1,101 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein <Deinst@world.std.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 "mozCStr2CStrHashtable.h"
#include "nsCRT.h"
#include "nsMemory.h"
static void* PR_CALLBACK
CloneCString(nsHashKey *aKey, void *aData, void* closure)
{
return nsCRT::strdup((const char*)aData);
}
static PRBool PR_CALLBACK
DeleteCString(nsHashKey *aKey, void *aData, void* closure)
{
nsMemory::Free((char*)aData);
return PR_TRUE;
}
mozCStr2CStrHashtable::mozCStr2CStrHashtable()
: mHashtable(CloneCString, nsnull, DeleteCString, nsnull, 16)
{
}
mozCStr2CStrHashtable::~mozCStr2CStrHashtable()
{
}
nsresult
mozCStr2CStrHashtable::Put(const char *key, const char* aData)
{
char* value = strdup(aData);
if (value == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
nsCStringKey k(key);
char* oldValue = (char*)mHashtable.Put(&k, value);
if (oldValue)
free(oldValue);
return NS_OK;
}
char*
mozCStr2CStrHashtable::Get(const char *key)
{
nsCStringKey k(key);
const char* value = (const char*)mHashtable.Get(&k);
if (value == nsnull)
return nsnull;
return strdup(value);
}
nsresult
mozCStr2CStrHashtable::Remove(const char *key)
{
nsCStringKey k(key);
char* oldValue = (char*)mHashtable.Remove(&k);
if (oldValue)
nsMemory::Free(oldValue);
return NS_OK;
}
void
mozCStr2CStrHashtable::Reset()
{
mHashtable.Reset();
}

View File

@ -0,0 +1,57 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein <Deinst@world.std.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 mozCStr2CStrHashtable_h__
#define mozCStr2CStrHashtable_h__
#include "nsHashtable.h"
class mozCStr2CStrHashtable
{
public:
mozCStr2CStrHashtable();
virtual ~mozCStr2CStrHashtable();
nsresult Put(const char *key, const char* aData);
char* Get(const char *key);
nsresult Remove(const char *key);
void Reset();
protected:
nsObjectHashtable mHashtable;
};
#endif

View File

@ -0,0 +1,325 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein <Deinst@world.std.com>
* Kevin Hendricks <kevin.hendricks@sympatico.ca>
*
* 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.
*
* This spellchecker is based on the MySpell spellchecker made for Open Office
* by Kevin Hendricks. Although the algorithms and code, have changed
* slightly, the architecture is still the same. The Mozilla implementation
* is designed to be compatible with the Open Office dictionaries.
* Please do not make changes to the affix or dictionary file formats
* without attempting to coordinate with Kevin. For more information
* on the original MySpell see
* http://whiteboard.openoffice.org/source/browse/whiteboard/lingucomponent/source/spellcheck/myspell/
*
* A special thanks and credit goes to Geoff Kuenning
* the creator of ispell. MySpell's affix algorithms were
* based on those of ispell which should be noted is
* copyright Geoff Kuenning et.al. and now available
* under a BSD style license. For more information on ispell
* and affix compression in general, please see:
* http://www.cs.ucla.edu/ficus-members/geoff/ispell.html
* (the home page for ispell)
*
* ***** END LICENSE BLOCK ***** */
/* based on MySpell (c) 2001 by Kevin Hendicks */
#include "mozMySpell.h"
#include "nsReadableUtils.h"
#include "nsIFile.h"
#include "nsXPIDLString.h"
#include "nsISimpleEnumerator.h"
#include "nsDirectoryService.h"
#include "nsDirectoryServiceDefs.h"
#include "mozISpellI18NManager.h"
NS_IMPL_ISUPPORTS1(mozMySpell, mozISpellCheckingEngine)
const PRInt32 kFirstDirSize=8;
mozMySpell::mozMySpell()
{
NS_INIT_ISUPPORTS();
}
mozMySpell::~mozMySpell()
{
}
/* attribute wstring dictionary; */
NS_IMETHODIMP mozMySpell::GetDictionary(PRUnichar * *aDictionary)
{
nsresult res=NS_OK;
NS_PRECONDITION(aDictionary != nsnull, "null ptr");
if(!aDictionary){
res = NS_ERROR_NULL_POINTER;
}
else{
*aDictionary = ToNewUnicode(mDictionary);
if(!aDictionary) res = NS_ERROR_OUT_OF_MEMORY;
}
return res;
}
/* set the Dictionary.
* This also Loads the dictionary and initializes the converter using the dictionaries converter
*/
NS_IMETHODIMP mozMySpell::SetDictionary(const PRUnichar * aDictionary)
{
if(!aDictionary)
return NS_ERROR_NULL_POINTER;
nsresult res=NS_OK;
if (!mDictionary.Equals(aDictionary)&&!(*aDictionary == 0)){
mDictionary = aDictionary;
res=mAMgr.Load(mDictionary);
if(NS_FAILED(res)){
NS_WARNING("Dictionary load failed");
return res;
}
mSMgr.setup(mAMgr.get_try_string(),64,&mAMgr);
nsString encoding=mAMgr.get_encoding();
nsString language;
PRInt32 pos = mDictionary.FindChar('-');
if(pos == -1){
language.Assign(NS_LITERAL_STRING("en"));
}
else{
language = Substring(mDictionary,0,pos);
}
nsCOMPtr<mozISpellI18NManager> serv(do_GetService("@mozilla.org/spellchecker/i18nmanager;1", &res));
if(serv && NS_SUCCEEDED(res)){
res = serv->GetUtil(language.get(),getter_AddRefs(mConverter));
if(NS_SUCCEEDED(res))
res=mConverter->SetCharset(encoding.get());
}
}
return res;
}
/* readonly attribute wstring charset; */
NS_IMETHODIMP mozMySpell::GetCharset(PRUnichar * *aCharset)
{
nsresult res=NS_OK;
NS_PRECONDITION(aCharset != nsnull, "null ptr");
if(!aCharset){
res = NS_ERROR_NULL_POINTER;
}
else{
*aCharset = ToNewUnicode(mAMgr.get_encoding());
if(!aCharset) res = NS_ERROR_OUT_OF_MEMORY;
}
return res;
}
/* readonly attribute wstring language; */
NS_IMETHODIMP mozMySpell::GetLanguage(PRUnichar * *aLanguage)
{
nsresult res=NS_OK;
NS_PRECONDITION(aLanguage != nsnull, "null ptr");
if(aLanguage){
res = NS_ERROR_NULL_POINTER;
}
else{
nsString language;
PRInt32 pos = mDictionary.FindChar('-');
if(pos == -1){
language.Assign(NS_LITERAL_STRING("en"));
}
else{
language = Substring(mDictionary,0,pos);
}
*aLanguage = ToNewUnicode(language);
if(!aLanguage) res = NS_ERROR_OUT_OF_MEMORY;
}
return res;
}
/* readonly attribute boolean providesPersonalDictionary; */
NS_IMETHODIMP mozMySpell::GetProvidesPersonalDictionary(PRBool *aProvidesPersonalDictionary)
{
if(!aProvidesPersonalDictionary) return NS_ERROR_NULL_POINTER;
*aProvidesPersonalDictionary=PR_FALSE;
return NS_OK;
}
/* readonly attribute boolean providesWordUtils; */
NS_IMETHODIMP mozMySpell::GetProvidesWordUtils(PRBool *aProvidesWordUtils)
{
if(!aProvidesWordUtils) return NS_ERROR_NULL_POINTER;
*aProvidesWordUtils=PR_FALSE;
return NS_OK;
}
/* readonly attribute wstring name; */
NS_IMETHODIMP mozMySpell::GetName(PRUnichar * *aName)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* readonly attribute wstring copyright; */
NS_IMETHODIMP mozMySpell::GetCopyright(PRUnichar * *aCopyright)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* attribute mozIPersonalDictionary personalDictionary; */
NS_IMETHODIMP mozMySpell::GetPersonalDictionary(mozIPersonalDictionary * *aPersonalDictionary)
{
return mAMgr.GetPersonalDictionary(aPersonalDictionary);
}
NS_IMETHODIMP mozMySpell::SetPersonalDictionary(mozIPersonalDictionary * aPersonalDictionary)
{
return mAMgr.SetPersonalDictionary(aPersonalDictionary);
}
/* void GetDictionaryList ([array, size_is (count)] out wstring dictionaries, out PRUint32 count); */
NS_IMETHODIMP mozMySpell::GetDictionaryList(PRUnichar ***dictionaries, PRUint32 *count)
{
nsresult res;
if(!dictionaries || !count){
return NS_ERROR_NULL_POINTER;
}
nsCOMPtr<nsIFile> aFile;
nsCOMPtr<nsISimpleEnumerator> dirEntries;
PRBool hasMore = PR_FALSE;
PRInt32 tempCount=0, i, arraySize = kFirstDirSize;;
PRUnichar **newPtr, **tmpPtr;
res=NS_OK;
*dictionaries = 0;
*count=0;
res = NS_GetSpecialDirectory(NS_XPCOM_COMPONENT_DIR, getter_AddRefs(aFile));
if (NS_FAILED(res)) return res;
if(!aFile)return NS_ERROR_FAILURE;
res = aFile->Append(NS_LITERAL_STRING("myspell"));
if (NS_FAILED(res)) return res;
res = aFile->GetDirectoryEntries(getter_AddRefs(dirEntries));
if (NS_FAILED(res)) return res;
if(!dirEntries)return NS_ERROR_FAILURE;
tmpPtr = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *)*kFirstDirSize);
if (!tmpPtr)
return NS_ERROR_OUT_OF_MEMORY;
while (NS_SUCCEEDED(dirEntries->HasMoreElements(&hasMore)) && hasMore) {
nsCOMPtr<nsISupports> nextItem;
nsCOMPtr<nsIFile> theFile;
dirEntries->GetNext(getter_AddRefs(nextItem));
theFile = do_QueryInterface(nextItem);
if(theFile){
nsString fileName;
theFile->GetLeafName(fileName);
PRInt32 dotLocation = fileName.FindChar('.');
if((dotLocation != -1) && Substring(fileName,dotLocation,4).Equals(NS_LITERAL_STRING(".dic"))){
if(tempCount >= arraySize){
arraySize = 2 * tempCount;
newPtr = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *) * arraySize);
if (! newPtr){
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(tempCount, tmpPtr);
return NS_ERROR_OUT_OF_MEMORY;
}
for(i=0;i<tempCount;i++){
newPtr[i] = tmpPtr[i];
}
nsMemory::Free(tmpPtr);
tmpPtr=newPtr;
}
tmpPtr[tempCount++] = ToNewUnicode(Substring(fileName,0,dotLocation));
}
}
}
*dictionaries=tmpPtr;
*count=tempCount;
return res;
}
/* boolean Check (in wstring word); */
NS_IMETHODIMP mozMySpell::Check(const PRUnichar *aWord, PRBool *_retval)
{
if(!aWord || !_retval || !mConverter )
return NS_ERROR_NULL_POINTER;
char **tmpPtr;
PRUint32 count,i;
nsresult res;
*_retval = PR_FALSE;
res = mConverter->GetRootForm(aWord, mozISpellI18NUtil::kCheck, &tmpPtr, &count);
if(NS_FAILED(res)) return res;
for(i=0;i<count;i++){
*_retval = mAMgr.check(nsDependentCString(tmpPtr[i]));
if(*_retval) break;
}
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, tmpPtr);
return res;
}
/* void Suggest (in wstring word, [array, size_is (count)] out wstring suggestions, out PRUint32 count); */
NS_IMETHODIMP mozMySpell::Suggest(const PRUnichar *aword, PRUnichar ***suggestions, PRUint32 *scount)
{
if(!suggestions || !scount || !mConverter){
return NS_ERROR_NULL_POINTER;
}
*suggestions = 0;
*scount=0;
char **tmpPtr;
nsAutoString word(aword);
char **slst=nsnull;
PRUint32 count;
PRUint32 ccount=0;
nsresult res;
res = mConverter->GetRootForm(aword, mozISpellI18NUtil::kSuggest, &tmpPtr, &count);
if(NS_FAILED(res)) return res;
for(PRUint32 i=0;(i<count)&&!NS_FAILED(res);i++){
res = mSMgr.suggest(&slst,nsDependentCString(tmpPtr[i]),&ccount);
}
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, tmpPtr);
res=mConverter->FromRootForm(aword,(const char **)slst,ccount,suggestions,scount);
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(ccount, slst);
return res;
}

View File

@ -0,0 +1,92 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein <Deinst@world.std.com>
* Kevin Hendricks <kevin.hendricks@sympatico.ca>
*
* 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.
*
* This spellchecker is based on the MySpell spellchecker made for Open Office
* by Kevin Hendricks. Although the algorithms and code, have changed
* slightly, the architecture is still the same. The Mozilla implementation
* is designed to be compatible with the Open Office dictionaries.
* Please do not make changes to the affix or dictionary file formats
* without attempting to coordinate with Kevin. For more information
* on the original MySpell see
* http://whiteboard.openoffice.org/source/browse/whiteboard/lingucomponent/source/spellcheck/myspell/
*
* A special thanks and credit goes to Geoff Kuenning
* the creator of ispell. MySpell's affix algorithms were
* based on those of ispell which should be noted is
* copyright Geoff Kuenning et.al. and now available
* under a BSD style license. For more information on ispell
* and affix compression in general, please see:
* http://www.cs.ucla.edu/ficus-members/geoff/ispell.html
* (the home page for ispell)
*
* ***** END LICENSE BLOCK ***** */
#ifndef mozMySpell_h__
#define mozMySpell_h__
#include "mozISpellCheckingEngine.h"
#include "nsString.h"
#include "myspAffixmgr.h"
#include "myspSuggestmgr.h"
#include "mozIPersonalDictionary.h"
#include "mozISpellI18NUtil.h"
#define MOZ_MYSPELL_CONTRACTID "@mozilla.org/spellchecker/myspell;1"
#define MOZ_MYSPELL_CID \
{ /* D1EE1205-3F96-4a0f-ABFE-09E8C54C9E9A} */ \
0xD1EE1205, 0x3F96, 0x4a0f, \
{ 0xAB, 0xFE, 0x09, 0xE8, 0xC5, 0x4C, 0x9E, 0x9A} }
class mozMySpell : public mozISpellCheckingEngine
{
public:
NS_DECL_ISUPPORTS
NS_DECL_MOZISPELLCHECKINGENGINE
mozMySpell();
virtual ~mozMySpell();
protected:
nsCOMPtr<mozISpellI18NUtil> mConverter;
nsString mDictionary;
myspAffixMgr mAMgr;
myspSuggestMgr mSMgr;
};
#endif

View File

@ -0,0 +1,63 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein <Deinst@world.std.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 "nsIGenericFactory.h"
#include "mozMySpell.h"
////////////////////////////////////////////////////////////////////////
// Define the contructor function for the objects
//
// NOTE: This creates an instance of objects by using the default constructor
//
NS_GENERIC_FACTORY_CONSTRUCTOR(mozMySpell)
////////////////////////////////////////////////////////////////////////
// Define a table of CIDs implemented by this module along with other
// information like the function to create an instance, contractid, and
// class name.
//
static nsModuleComponentInfo components[] = {
{ NULL, MOZ_MYSPELL_CID, MOZ_MYSPELL_CONTRACTID, mozMySpellConstructor }
};
////////////////////////////////////////////////////////////////////////
// Implement the NSGetModule() exported function for your module
// and the entire implementation of the module object.
//
NS_IMPL_NSGETMODULE(mozMySpellModule, components)

View File

@ -0,0 +1,509 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein <Deinst@world.std.com>
* Kevin Hendricks <kevin.hendricks@sympatico.ca>
*
* 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.
*
* This spellchecker is based on the MySpell spellchecker made for Open Office
* by Kevin Hendricks. Although the algorithms and code, have changed
* slightly, the architecture is still the same. The Mozilla implementation
* is designed to be compatible with the Open Office dictionaries.
* Please do not make changes to the affix or dictionary file formats
* without attempting to coordinate with Kevin. For more information
* on the original MySpell see
* http://whiteboard.openoffice.org/source/browse/whiteboard/lingucomponent/source/spellcheck/myspell/
*
* A special thanks and credit goes to Geoff Kuenning
* the creator of ispell. MySpell's affix algorithms were
* based on those of ispell which should be noted is
* copyright Geoff Kuenning et.al. and now available
* under a BSD style license. For more information on ispell
* and affix compression in general, please see:
* http://www.cs.ucla.edu/ficus-members/geoff/ispell.html
* (the home page for ispell)
*
* ***** END LICENSE BLOCK ***** */
#include "myspAffixmgr.h"
#include "nsIFile.h"
#include "nsReadCLine.h"
#include "nsReadableUtils.h"
#include "nsDirectoryServiceDefs.h"
#include "plstr.h"
#include "nsNetUtil.h"
static PRInt32 SplitString(nsACString &in,nsSharableCString out[],PRInt32 size);
static void doubleReverseHack(nsACString &s);
myspAffixMgr::myspAffixMgr()
{
}
myspAffixMgr::~myspAffixMgr()
{
mPersonalDictionary = nsnull;
}
nsresult myspAffixMgr::GetPersonalDictionary(mozIPersonalDictionary * *aPersonalDictionary)
{
*aPersonalDictionary = mPersonalDictionary;
NS_IF_ADDREF(*aPersonalDictionary);
return NS_OK;
}
nsresult myspAffixMgr::SetPersonalDictionary(mozIPersonalDictionary * aPersonalDictionary)
{
mPersonalDictionary = aPersonalDictionary;
return NS_OK;
}
nsresult
myspAffixMgr::Load(const nsString& aDictionary)
{
nsresult res=NS_OK;
nsCOMPtr<nsIFile> dicFile;
nsCOMPtr<nsIFile> affFile;
PRBool fileExists;
//get the directory
res = NS_GetSpecialDirectory(NS_XPCOM_COMPONENT_DIR, getter_AddRefs(dicFile));
if(NS_FAILED(res)) return res;
if(!dicFile)return NS_ERROR_FAILURE;
res = dicFile->Append(NS_LITERAL_STRING("myspell"));
if(NS_FAILED(res)) return res;
res = dicFile->Exists(&fileExists);
if(NS_FAILED(res)) return res;
if(!fileExists) return NS_ERROR_FAILURE;
res = dicFile->Clone(getter_AddRefs(affFile));
if(NS_FAILED(res)) return res;
if(!dicFile)return NS_ERROR_FAILURE;
//get the affix file
nsString affName=aDictionary;
affName.Append(NS_LITERAL_STRING(".aff"));
res=affFile->Append(affName);
if(NS_FAILED(res)) return res;
res = affFile->Exists(&fileExists);
if(NS_FAILED(res)) return res;
if(!fileExists) return NS_ERROR_FAILURE;
//get the dictionary file
nsString dicName=aDictionary;
dicName.Append(NS_LITERAL_STRING(".dic"));
res=dicFile->Append(dicName);
if(NS_FAILED(res)) return res;
res = dicFile->Exists(&fileExists);
if(NS_FAILED(res)) return res;
if(!fileExists) return NS_ERROR_FAILURE;
// load the affixFile
nsCOMPtr<nsIInputStream> affStream;
res = NS_NewLocalFileInputStream(getter_AddRefs(affStream), affFile);
if(NS_FAILED(res)) return res;
if(!affStream)return NS_ERROR_FAILURE;
res = parse_file(affStream);
res = mPersonalDictionary->SetCharset(mEncoding.get());
if(NS_FAILED(res)) return res;
PRInt32 pos=aDictionary.FindChar('-');
if(pos<1) pos = 2; // FIXME should be min of 2 and aDictionary.Length()
nsAutoString lang;
lang.Assign(Substring(aDictionary,0,pos));
res = mPersonalDictionary->SetLanguage(lang.get());
if(NS_FAILED(res)) return res;
// load the dictionary
nsCOMPtr<nsIInputStream> dicStream;
res = NS_NewLocalFileInputStream(getter_AddRefs(dicStream), dicFile);
if(NS_FAILED(res)) return res;
if(!dicStream)return NS_ERROR_FAILURE;
res = LoadDictionary(dicStream);
return res;
}
// read in aff file and build up prefix and suffix data structures
nsresult myspAffixMgr::parse_file(nsIInputStream *strm)
{
PRInt32 j;
PRInt32 numents;
nsLineBuffer *lineBuffer;
nsresult res;
res= NS_InitLineBuffer(&lineBuffer);
nsCAutoString line;
PRBool moreData=PR_TRUE;
PRInt32 pos;
nsSharableCString cmds[5];
mozAffixMod newMod;
prefixes.clear();
suffixes.clear();
numents = 0; // number of affentry structures to parse
char flag='\0'; // affix char identifier
{
PRInt16 ff=0;
char ft;
// read in each line ignoring any that do not
// start with PFX or SFX
while (moreData) {
NS_ReadLine(strm,lineBuffer,line,&moreData);
/* parse in the try string */
if (Substring(line,0,3).Equals("TRY")) {
pos = line.FindChar(' ');
if(pos != -1){
trystring = Substring(line,pos+1,line.Length()-pos-1);
}
}
/* parse in the name of the character set used by the .dict and .aff */
if (Substring(line,0,3).Equals("SET")) {
pos = line.FindChar(' ');
if(pos != -1){
nsCAutoString cencoding;
cencoding.Assign(Substring(line,pos+1,line.Length()-pos-1));
cencoding.CompressWhitespace(PR_TRUE,PR_TRUE);
mEncoding.AssignWithConversion(cencoding.get());
}
}
// get the type of this affix: P - prefix, S - suffix
ft = ' ';
if (Substring(line,0,3).Equals("PFX")) ft = 'P';
if (Substring(line,0,3).Equals("SFX")) ft = 'S';
if (ft != ' ') {
numents = 0;
ff=0;
// split line into pieces
PRInt32 numFields=SplitString(line,cmds,5);
if(numFields > 1)flag=cmds[1].First();
if((numFields > 2)&&(cmds[2].First()=='Y'))ff=XPRODUCT;
if(numFields >3)numents = atoi(cmds[3].get());
// now parse numents affentries for this affix
for (j=0; (j < numents)&&moreData; j++) {
NS_ReadLine(strm,lineBuffer,line,&moreData);
PRInt32 numFields=SplitString(line,cmds,5);
nsSharableString tempStr;
if((numFields < 5)||(cmds[1].First()!=flag)){ //consistency check
//complain loudly
continue;
}
if(cmds[3].Equals("0")){
cmds[3].Truncate();
}
newMod.flags = ff;
newMod.mID = flag;
newMod.mTruncateLength=cmds[3].Length();
if(ft == 'P'){
if(cmds[2].Equals("0")){
newMod.mAppend.Assign("");
if(!cmds[4].Equals(".")){
cmds[3].Append(cmds[4]);
}
}
else{ // cmds[2] != 0
newMod.mAppend.Assign( cmds[2]);
if((cmds[2].Length()>cmds[4].Length())||!cmds[2].Equals(Substring(cmds[4],0,cmds[2].Length()))){
//complain loudly
continue;
}
cmds[3].Append(Substring(cmds[4],cmds[2].Length(),cmds[4].Length()-cmds[2].Length()));
}
prefixes.addMod(cmds[3].get(),&newMod);
}
else{ // suffix
nsSharableCString suffixTest;
if(cmds[2].Equals("0")){
newMod.mAppend.Assign("");
if(!cmds[4].Equals(".")){
suffixTest.Assign(cmds[4]);
suffixTest.Append(cmds[3]);
}
else{
suffixTest.Assign( cmds[3]);
}
}
else{ // cmds[2] != 0
newMod.mAppend.Assign( cmds[2]);
if((cmds[2].Length()>cmds[4].Length())||
!cmds[2].Equals(Substring(cmds[4],cmds[4].Length()-cmds[2].Length(),cmds[2].Length()))){
//complain loudly
continue;
}
suffixTest=Substring(cmds[4],0,cmds[4].Length()-cmds[2].Length());
suffixTest.Append(cmds[3]);
}
if(suffixTest.Length() != 0)doubleReverseHack(suffixTest);
suffixes.addMod(suffixTest.get(),&newMod);
}
}
}
}
}
return NS_OK;
}
nsresult
myspAffixMgr::LoadDictionary(nsIInputStream *strm)
{
nsLineBuffer *lineBuffer;
nsresult res;
res= NS_InitLineBuffer(&lineBuffer);
nsCAutoString line;
PRBool moreData;
PRInt32 pos;
nsACString::const_iterator begin1,end1,begin2,end2;
// first read the first line of file to get hash table size */
mHashTable.Reset();
res = NS_ReadLine(strm,lineBuffer,line,&moreData);
// loop through all words on much list and add to hash
// table and create word and affix strings
while (moreData) {
res = NS_ReadLine(strm,lineBuffer,line,&moreData);
// split each line into word and affix char strings
pos = line.FindChar('/');
if(pos==-1){
line.BeginReading(begin1);
line.EndReading(end1);
begin2=end2=begin1;
}
else{
line.BeginReading(begin1);
begin2=end1=begin1;
end1.advance(pos);
begin2.advance(pos+1);
line.EndReading(end2);
}
// add the word and its index
mHashTable.Put(PromiseFlatCString(Substring(begin1,end1)).get(),PromiseFlatCString(Substring(begin2,end2)).get());
}
return NS_OK;
}
// return text encoding of dictionary
nsString myspAffixMgr::get_encoding()
{
return mEncoding;
}
// return the preferred try string for suggestions
nsCString myspAffixMgr::get_try_string()
{
return trystring;
}
PRBool
myspAffixMgr::prefixCheck(const nsAFlatCString &word)
{
nsACString::const_iterator end,curr;
nsSharableCString tempWord;
mozAffixState *currState= &prefixes;
const char * he = NULL;
PRUint32 wLength=word.Length();
word.BeginReading(curr);
word.EndReading(end);
while((curr!=end)&&(currState!=nsnull)){
// check the current mods
mozAffixMod *currMod=currState->getMod();
while(currMod != nsnull){
tempWord.Assign(currMod->mAppend);
tempWord.Append(Substring(word,currMod->mTruncateLength,wLength - currMod->mTruncateLength));
he = mHashTable.Get(tempWord.get());;
if((he != nsnull)&&(PL_strchr(he, currMod->mID))) return PR_TRUE;
if(((currMod->flags)&XPRODUCT)&&suffixCheck(tempWord,PR_TRUE,currMod->mID)) return PR_TRUE;
currMod = currMod->next;
}
currState=currState->nextState(*curr);
curr++;
}
if(currState != nsnull){
mozAffixMod *currMod=currState->getMod();
while(currMod != nsnull){
tempWord.Assign(currMod->mAppend);
tempWord.Append(Substring(word,currMod->mTruncateLength,wLength - currMod->mTruncateLength));
he=mHashTable.Get(tempWord.get());
if((he != nsnull)&&(PL_strchr(he, currMod->mID))) return PR_TRUE;
// no need to check cross product, we reached the end of the word.
currMod = currMod->next;
}
}
return PR_FALSE;
}
PRBool myspAffixMgr::suffixCheck(const nsAFlatCString &word,PRBool cross,char crossID)
{
nsACString::const_iterator start,curr;
nsSharableCString tempWord;
mozAffixState *currState= &suffixes;
const char * he = NULL;
PRUint32 wLength=word.Length();
word.EndReading(curr);
word.BeginReading(start);
while((curr!=start)&&(currState!=nsnull)){
// check the current mods
mozAffixMod *currMod=currState->getMod();
while(currMod != nsnull){
tempWord=Substring(word,0,wLength - currMod->mTruncateLength);
tempWord.Append(currMod->mAppend);
he = mHashTable.Get(tempWord.get());;
if((he != nsnull)&&PL_strchr(he, currMod->mID)&&((!cross)||PL_strchr(he, crossID))) return PR_TRUE;
currMod = currMod->next;
}
curr--;
currState=currState->nextState(*curr);
}
//Ok, we've read the last character of the word, but who knows,
//we could still get a match en-US "her" for example. Mozdev bug 895
if(currState != nsnull){
mozAffixMod *currMod=currState->getMod();
while(currMod != nsnull){
tempWord=Substring(word,0,wLength - currMod->mTruncateLength);
tempWord.Append(currMod->mAppend);
he = mHashTable.Get(tempWord.get());;
if((he != nsnull)&&PL_strchr(he, currMod->mID)&&((!cross)||PL_strchr(he, crossID))) return PR_TRUE;
currMod = currMod->next;
}
}
return PR_FALSE;
}
PRBool myspAffixMgr::check(const nsAFlatCString &word)
{
const char * he = NULL;
he = mHashTable.Get(word.get());;
if(he != nsnull) return PR_TRUE;
if(prefixCheck(word))return PR_TRUE;
if(suffixCheck(word))return PR_TRUE;
PRBool good=PR_FALSE;
nsresult res = mPersonalDictionary->Check(word.get(),&good);
if(NS_FAILED(res))
return PR_FALSE;
return good;
}
static PRInt32
SplitString(nsACString &in,nsSharableCString out[],PRInt32 size)
{
nsACString::const_iterator startWord;
nsACString::const_iterator endWord;
nsACString::const_iterator endLine;
PRInt32 pos=0;
in.BeginReading(startWord);
in.EndReading(endLine);
while((pos < size)&&(startWord!=endLine)){
while((startWord!=endLine)&&(*startWord == ' '))startWord++;
endWord=startWord;
while((endWord!=endLine)&&(*endWord != ' '))endWord++;
if(startWord != endWord){
out[pos++] = Substring(startWord,endWord);
}
startWord=endWord;
}
return pos;
}
/*
reverse the suffix search string so that we put it into the tree in reverse.
we need to reverse the blocks so that the ^ in negated blocks occurs first.
*/
static void doubleReverseHack(nsACString &s)
{
nsACString::iterator start,end,curr;
char temp;
s.BeginWriting(start);
s.EndWriting(end);
curr=start;
while(start!=end){
if(*start=='['){
curr=start;
while((curr!=end)&&(*curr != ']')) curr++;
while(start != curr){
temp=*curr;
*curr=*start;
*start=temp;
start++;
if(start==curr)break;
curr--;
}
while((start != end)&&(*start != '[')) start++;
if(*start != '[')start++;
}
start++;
}
s.BeginWriting(start);
end--;
while(start != end){
temp = *start;
*start = *end;
*end=temp;
start++;
if(start == end)break;
end--;
}
}

View File

@ -0,0 +1,114 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein <Deinst@world.std.com>
* Kevin Hendricks <kevin.hendricks@sympatico.ca>
*
* 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.
*
* This spellchecker is based on the MySpell spellchecker made for Open Office
* by Kevin Hendricks. Although the algorithms and code, have changed
* slightly, the architecture is still the same. The Mozilla implementation
* is designed to be compatible with the Open Office dictionaries.
* Please do not make changes to the affix or dictionary file formats
* without attempting to coordinate with Kevin. For more information
* on the original MySpell see
* http://whiteboard.openoffice.org/source/browse/whiteboard/lingucomponent/source/spellcheck/myspell/
*
* A special thanks and credit goes to Geoff Kuenning
* the creator of ispell. MySpell's affix algorithms were
* based on those of ispell which should be noted is
* copyright Geoff Kuenning et.al. and now available
* under a BSD style license. For more information on ispell
* and affix compression in general, please see:
* http://www.cs.ucla.edu/ficus-members/geoff/ispell.html
* (the home page for ispell)
*
* ***** END LICENSE BLOCK ***** */
#ifndef _AFFIXMGR_HXX_
#define _AFFIXMGR_HXX_
#include "nsString.h"
#include "mozIPersonalDictionary.h"
#include "mozCStr2CStrHashtable.h"
#include "mozAffixMod.h"
#include "nsNetUtil.h"
/* Modifications for mozilla Copyright 2001 David Einstein Deinst@world.std.com */
// shamelesly stolen from nsDirectoryService.cpp
// Probably should move to nsDirectoryService.h?
#if defined(XP_MAC)
#define COMPONENT_DIRECTORY "Components"
#else
#define COMPONENT_DIRECTORY "components"
#endif
#define MAXAFFIXES 256
#define XPRODUCT 1
class myspPrefix;
class myspSuffix;
class myspAffixMgr
{
public:
myspAffixMgr();
~myspAffixMgr();
nsresult GetPersonalDictionary(mozIPersonalDictionary * *aPersonalDictionary);
nsresult SetPersonalDictionary(mozIPersonalDictionary * aPersonalDictionary);
PRBool check(const nsAFlatCString &word);
nsString get_encoding();
nsCString get_try_string();
nsresult Load(const nsString& aDictionary);
protected:
PRBool prefixCheck(const nsAFlatCString &word);
PRBool suffixCheck(const nsAFlatCString &word,PRBool cross=PR_FALSE,char crossID=' ');
nsresult LoadDictionary(nsIInputStream *strm);
nsresult parse_file(nsIInputStream *strm);
mozAffixState prefixes;
mozAffixState suffixes;
nsCString trystring;
nsString mEncoding;
mozCStr2CStrHashtable mHashTable;
nsCOMPtr<mozIPersonalDictionary> mPersonalDictionary;
};
#endif

View File

@ -0,0 +1,348 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein <Deinst@world.std.com>
* Kevin Hendricks <kevin.hendricks@sympatico.ca>
*
* 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.
*
* This spellchecker is based on the MySpell spellchecker made for Open Office
* by Kevin Hendricks. Although the algorithms and code, have changed
* slightly, the architecture is still the same. The Mozilla implementation
* is designed to be compatible with the Open Office dictionaries.
* Please do not make changes to the affix or dictionary file formats
* without attempting to coordinate with Kevin. For more information
* on the original MySpell see
* http://whiteboard.openoffice.org/source/browse/whiteboard/lingucomponent/source/spellcheck/myspell/
*
* A special thanks and credit goes to Geoff Kuenning
* the creator of ispell. MySpell's affix algorithms were
* based on those of ispell which should be noted is
* copyright Geoff Kuenning et.al. and now available
* under a BSD style license. For more information on ispell
* and affix compression in general, please see:
* http://www.cs.ucla.edu/ficus-members/geoff/ispell.html
* (the home page for ispell)
*
* ***** END LICENSE BLOCK ***** */
#include "myspSuggestmgr.h"
#include "plstr.h"
#include "nsReadableUtils.h"
#include "nsMemory.h"
myspSuggestMgr::myspSuggestMgr()
{
}
myspSuggestMgr::~myspSuggestMgr()
{
pAMgr = nsnull;
maxSug = 0;
}
void
myspSuggestMgr::setup(const nsAFlatCString &tryme, int maxn, myspAffixMgr *aptr)
{
// register affix manager and check in string of chars to
// try when building candidate suggestions
pAMgr = aptr;
ctry = tryme;
maxSug = maxn;
}
// generate suggestions for a mispelled word
// pass in address of array of char * pointers
nsresult myspSuggestMgr::suggest(char ***slst,const nsAFlatCString &word, PRUint32 *num)
{
if(!num || !slst)
return NS_ERROR_NULL_POINTER;
nsresult res;
PRUint32 nsug;
PRUint32 i;
char **wlst;
if(!(*slst)){
nsug=0;
wlst=(char **)nsMemory::Alloc(sizeof(char *)*maxSug);
if(!wlst)
return NS_ERROR_OUT_OF_MEMORY;
for(i=0;i<maxSug;i++)
wlst[i]=nsnull;
}
else{
wlst=*slst;
nsug=*num;
}
// did we forget to add a char
res = forgotchar(wlst, word, &nsug);
// did we swap the order of chars by mistake
if ((nsug < maxSug) && NS_SUCCEEDED(res)){
res = swapchar(wlst, word, &nsug);
}
// did we add a char that should not be there
if ((nsug < maxSug) && NS_SUCCEEDED(res)){
res = extrachar(wlst, word, &nsug);
}
// did we just hit the wrong key in place of a good char
if ((nsug < maxSug) && NS_SUCCEEDED(res)){
res = badchar(wlst, word, &nsug);
}
// perhaps we forgot to hit space and two words ran together
if ((nsug < maxSug) && NS_SUCCEEDED(res)){
res = twowords(wlst, word, &nsug);
}
if(NS_FAILED(res)){
for (i=0;i<maxSug; i++)
if (wlst[i] != NULL) nsMemory::Free(wlst[i]);
nsMemory::Free(wlst);
*slst = 0;
*num=0;
}
else{
*slst=wlst;
*num=nsug;
}
return res;
}
// error is wrong char in place of correct one
nsresult myspSuggestMgr::badchar(char ** wlst,const nsAFlatCString &word, PRUint32 *ns)
{
char tmpc;
nsSharableCString candidate;
PRBool cwrd;
PRUint32 i,j,k;
PRUint32 wl = word.Length();
candidate.Assign(word);
nsACString::iterator candIt;
for (i=0,candidate.BeginWriting(candIt); i < wl; i++,candIt++) {
tmpc = *candIt;
for (j=0; j < ctry.Length(); j++) {
if (ctry[j] == tmpc) continue;
*candIt = ctry[j];
cwrd = PR_TRUE;
for(k=0;k < *ns;k++){
if (candidate.Equals(wlst[k]) ){
cwrd = PR_FALSE;
break;
}
}
if (cwrd && pAMgr->check(candidate)) {
if (*ns < maxSug) {
wlst[*ns] = ToNewCString(candidate);
if(!wlst[*ns])
return NS_ERROR_OUT_OF_MEMORY;
(*ns)++;
} else return NS_OK;
}
*candIt = tmpc;
}
}
return NS_OK;
}
// error is word has an extra letter it does not need
nsresult myspSuggestMgr::extrachar(char ** wlst,const nsAFlatCString &word, PRUint32 *ns)
{
PRBool cwrd;
nsString stCand;
nsSharableCString candidate;
PRUint32 k;
PRUint32 wl = word.Length();
if (wl < 2) return 0;
// try omitting one char of word at a time
candidate.Assign(Substring(word,1,wl-1));
nsACString::iterator r;
nsACString::const_iterator p,end;
word.EndReading(end);
for (word.BeginReading(p),candidate.BeginWriting(r); p != end; ) {
cwrd = PR_TRUE;
for(k=0;k < *ns;k++){
if (candidate.Equals(wlst[k])){
cwrd = PR_FALSE;
break;
}
}
if (cwrd && pAMgr->check(candidate)) {
if (*ns < maxSug) {
wlst[*ns] = ToNewCString(candidate);
if(!wlst[*ns])
return NS_ERROR_OUT_OF_MEMORY;
(*ns)++;
} else return NS_OK;
}
*r++ = *p++;
}
return NS_OK;
}
// error is mising a letter it needs
nsresult myspSuggestMgr::forgotchar(char **wlst,const nsAFlatCString &word, PRUint32 *ns)
{
PRBool cwrd;
nsString stCand;
nsSharableCString candidate;
PRUint32 i,k;
candidate.Assign(" ");
candidate.Append(word);
nsACString::iterator q;
nsACString::const_iterator p,end;
word.EndReading(end);
// try inserting a tryme character before every letter
for (word.BeginReading(p), candidate.BeginWriting(q); p != end; ) {
for ( i = 0; i < ctry.Length(); i++) {
*q = ctry[i];
cwrd = PR_TRUE;
for(k=0;k < *ns;k++){
if (candidate.Equals(wlst[k]) ){
cwrd = PR_FALSE;
break;
}
}
if (cwrd && pAMgr->check(candidate)) {
if (*ns < maxSug) {
wlst[*ns] = ToNewCString(candidate);
if(!wlst[*ns])
return NS_ERROR_OUT_OF_MEMORY;
(*ns)++;
} else return NS_OK;
}
}
*q++ = *p++;
}
// now try adding one to end */
for ( i = 0; i < ctry.Length(); i++) {
*q = ctry[i];
cwrd = PR_TRUE;
for(k=0;k < *ns;k++){
if (candidate.Equals(wlst[k])){
cwrd = PR_FALSE;
break;
}
}
if (cwrd && pAMgr->check(candidate)) {
if (*ns < maxSug) {
wlst[*ns] = ToNewCString(candidate);
if(!wlst[*ns])
return NS_ERROR_OUT_OF_MEMORY;
(*ns)++;
} else return NS_OK;
}
}
return NS_OK;
}
/* error is should have been two words */
nsresult myspSuggestMgr::twowords(char ** wlst,const nsAFlatCString &word, PRUint32 *ns)
{
nsSharableCString candidate;
nsString stCand;
PRUint32 pos;
PRUint32 wl=word.Length();
if (wl < 3) return NS_OK;
candidate.Assign(word);
nsSharableCString temp;
// split the string into two pieces after every char
// if both pieces are good words make them a suggestion
for (pos = 1; pos < wl; pos++) {
temp.Assign(Substring(candidate,0,pos));
if (pAMgr->check(temp)) {
temp.Assign(Substring(candidate,pos,wl-pos));
if (pAMgr->check(temp)) {
if (*ns < maxSug) {
candidate.Insert(' ',pos);
wlst[*ns] = ToNewCString(candidate);
if(!wlst[*ns])
return NS_ERROR_OUT_OF_MEMORY;
(*ns)++;
} else return NS_OK;
}
}
}
return NS_OK;
}
// error is adjacent letter were swapped
nsresult myspSuggestMgr::swapchar(char **wlst,const nsAFlatCString &word, PRUint32 *ns)
{
nsSharableCString candidate;
char tmpc;
PRBool cwrd;
nsString stCand;
PRUint32 k;
candidate.Assign(word);
nsACString::iterator p,q,end;
candidate.EndWriting(end);
for (candidate.BeginWriting(p),q=p, q++; q != end; p++,q++) {
tmpc = *p;
*p = *q;
*q = tmpc;
cwrd = PR_TRUE;
for(k=0;k < *ns;k++){
if (candidate.Equals(wlst[k])){
cwrd = PR_FALSE;
break;
}
}
if (cwrd && pAMgr->check(candidate)) {
if (*ns < maxSug) {
wlst[*ns] = ToNewCString(candidate);
if(!wlst[*ns])
return NS_ERROR_OUT_OF_MEMORY;
(*ns)++;
} else return NS_OK;
}
tmpc = *p;
*p = *q;
*q = tmpc;
}
return NS_OK;
}

View File

@ -0,0 +1,91 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein <Deinst@world.std.com>
* Kevin Hendricks <kevin.hendricks@sympatico.ca>
*
* 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.
*
* This spellchecker is based on the MySpell spellchecker made for Open Office
* by Kevin Hendricks. Although the algorithms and code, have changed
* slightly, the architecture is still the same. The Mozilla implementation
* is designed to be compatible with the Open Office dictionaries.
* Please do not make changes to the affix or dictionary file formats
* without attempting to coordinate with Kevin. For more information
* on the original MySpell see
* http://whiteboard.openoffice.org/source/browse/whiteboard/lingucomponent/source/spellcheck/myspell/
*
* A special thanks and credit goes to Geoff Kuenning
* the creator of ispell. MySpell's affix algorithms were
* based on those of ispell which should be noted is
* copyright Geoff Kuenning et.al. and now available
* under a BSD style license. For more information on ispell
* and affix compression in general, please see:
* http://www.cs.ucla.edu/ficus-members/geoff/ispell.html
* (the home page for ispell)
*
* ***** END LICENSE BLOCK ***** */
#ifndef _SUGGESTMGR_HXX_
#define _SUGGESTMGR_HXX_
#include "license.readme"
#include "nsString.h"
#include "nsVoidArray.h"
#include "myspAffixmgr.h"
#include "nsString.h"
/* Modifications for mozilla Copyright 2001 David Einstein Deinst@world.std.com */
class myspSuggestMgr
{
nsSharableCString ctry;
myspAffixMgr* pAMgr;
PRUint32 maxSug;
public:
myspSuggestMgr();
~myspSuggestMgr();
void setup(const nsAFlatCString &tryme, int maxn, myspAffixMgr *aptr);
nsresult suggest(char ***slst, const nsAFlatCString &word, PRUint32 *num);
protected:
nsresult forgotchar(char **wlst,const nsAFlatCString &word, PRUint32 *num);
nsresult swapchar(char **wlst,const nsAFlatCString &word, PRUint32 *num);
nsresult extrachar(char **wlst,const nsAFlatCString &word, PRUint32 *num);
nsresult badchar(char **wlst,const nsAFlatCString &word, PRUint32 *num);
nsresult twowords(char **wlst,const nsAFlatCString &word, PRUint32 *num);
};
#endif

View File

@ -0,0 +1,124 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein <Deinst@world.std.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 nsReadCLine_h__
#define nsReadCLine_h__
//This is shameless and obvious theft from nsReadLine.h
#include "nsReadLine.h"
#include "nsString.h"
static nsresult
NS_ReadLine (nsIInputStream* aStream, nsLineBuffer * aBuffer,
nsACString & aLine, PRBool *more) {
nsresult rv = NS_OK;
PRUint32 bytesRead;
nsCAutoString temp;
*more = PR_TRUE;
PRBool eolStarted = PR_FALSE;
char eolchar='\0';
aLine.Truncate();
while (1) { // will be returning out of this loop on eol or eof
if (aBuffer->empty) { // buffer is empty. Read into it.
rv = aStream->Read(aBuffer->buf, kLineBufferSize, &bytesRead);
if (NS_FAILED(rv)) // read failed
return rv;
if (bytesRead == 0) { // end of file
*more = PR_FALSE;
return NS_OK;
}
aBuffer->end = aBuffer->buf + bytesRead;
aBuffer->empty = PR_FALSE;
*(aBuffer->end) = '\0'; // null-terminate this thing
}
// walk the buffer looking for an end-of-line
while (aBuffer->current < aBuffer->end) {
if (eolStarted) {
if ((eolchar == '\n' && *(aBuffer->current) == '\r') ||
(eolchar == '\r' && *(aBuffer->current) == '\n')) { // line end
(aBuffer->current)++;
aBuffer->start = aBuffer->current;
}
eolStarted = PR_FALSE;
return NS_OK;
} else if (*(aBuffer->current) == '\n' ||
*(aBuffer->current) == '\r') { // line end
eolStarted = PR_TRUE;
eolchar = *(aBuffer->current);
*(aBuffer->current) = '\0';
temp.Assign(aBuffer->start);
aLine.Append(temp);
(aBuffer->current)++;
aBuffer->start = aBuffer->current;
} else {
eolStarted = PR_FALSE;
(aBuffer->current)++;
}
}
// append whatever we currently have to the string
temp.Assign(aBuffer->start);
aLine.Append(temp);
// we've run out of buffer. Begin anew
aBuffer->current = aBuffer->start = aBuffer->buf;
aBuffer->empty = PR_TRUE;
if (eolStarted) { // have to read another char and possibly skip over it
rv = aStream->Read(aBuffer->buf, 1, &bytesRead);
if (NS_FAILED(rv)) // read failed
return rv;
if (bytesRead == 0) { // end of file
*more = PR_FALSE;
return NS_OK;
}
if ((eolchar == '\n' && *(aBuffer->buf) == '\r') ||
(eolchar == '\r' && *(aBuffer->buf) == '\n')) {
// Just return and all is good -- we've skipped the extra newline char
return NS_OK;
} else {
// we have a byte that we should look at later
aBuffer->empty = PR_FALSE;
aBuffer->end = aBuffer->buf + 1;
*(aBuffer->end) = '\0';
}
}
}
}
#endif // nsReadCLine_h__

View File

@ -0,0 +1,2 @@
.deps
Makefile

View File

@ -1,82 +1,85 @@
# 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
# ***** 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 Original Code is Mozilla Spellchecker Component.
#
# The Initial Developer of the Original Code is
# David Einstein.
# Portions created by the Initial Developer are Copyright (C) 2001
# the Initial Developer. All Rights Reserved.
#
# Contributor(s): David Einstein <Deinst@world.std.com>
# Aleksey Nogin <ayn2@cornell.edu>
#
# 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 *****
# 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 Developer of the Original Code is Aaron Leventhal.
# Portions created by Aaron Leventhal are Copyright (C) 2001
# Aaron Leventhal. All Rights Reserved.
# Alternatively, the contents of this file may be used under the terms
# of the GNU General Public License (the "GPL"), in which case the
# provisions of the GPL are applicable instead of those above. If you
# wish to allow use of your version of this file only under the terms of
# the GPL and not to allow others to use your version of this file under
# the MPL, indicate your decision by deleting the provisions above and
# replace them with the notice and other provisions required by the
# GPL. If you do not delete the provisions above, a recipient may use
# your version of this file under either the MPL or the GPL.
# Contributor(s):
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = spellcheckcontroller
LIBRARY_NAME = spellcheckcontroller
EXPORT_LIBRARY = 1
IS_COMPONENT = 1
MODULE_NAME = nsSpellCheckController
ifneq ($(OS_ARCH),WINNT)
SHORT_LIBNAME = spchckcntl
endif
REQUIRES = string \
xpcom \
dom \
docshell \
gfx \
layout \
content \
widget \
htmlparser \
necko \
unicharutil \
lwbrk \
MODULE = spellchecker
LIBRARY_NAME = spellchecker
SHORT_LIBNAME = spellchk
EXPORT_LIBRARY = 1
IS_COMPONENT = 1
MODULE_NAME = mozSpellcheckerModule
REQUIRES = xpcom \
string \
editor \
content \
layout \
dom \
necko \
widget \
pref \
gfx \
txtsvc \
uconv \
lwbrk \
editor \
pref \
spellcheck \
unicharutil \
$(NULL)
CPPSRCS = \
nsSpellCheckController.cpp \
nsSpellCheckUtils.cpp \
nsSpellCheckModule.cpp \
$(NULL)
CPPSRCS = \
mozSpellCheckerFactory.cpp \
mozSpellChecker.cpp \
mozPersonalDictionary.cpp \
mozEnglishWordUtils.cpp \
mozGenericWordUtils.cpp \
mozSpellI18NManager.cpp \
nsAVLTree.cpp \
$(NULL)
EXTRA_DSO_LIBS = \
gkgfx \
$(NULL)
EXTRA_DSO_LDOPTS += \
$(LIBS_DIR) \
$(MOZ_UNICHARUTIL_LIBS) \
$(EXTRA_DSO_LIBS) \
$(MOZ_COMPONENT_LIBS)
EXTRA_DSO_LDOPTS = \
-L$(DIST)/bin \
-L$(DIST)/lib \
$(XPCOM_LIBS) \
$(NSPR_LIBS) \
$(NULL)
include $(topsrcdir)/config/rules.mk

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,389 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein Deinst@world.std.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 "mozEnglishWordUtils.h"
#include "nsICharsetConverterManager.h"
#include "nsICharsetAlias.h"
#include "nsUnicharUtilCIID.h"
#include "nsReadableUtils.h"
#include "nsIServiceManager.h"
#include "nsCRT.h"
#include "cattable.h"
static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
static NS_DEFINE_CID(kUnicharUtilCID, NS_UNICHARUTIL_CID);
NS_IMPL_ISUPPORTS1(mozEnglishWordUtils, mozISpellI18NUtil)
mozEnglishWordUtils::mozEnglishWordUtils()
{
NS_INIT_ISUPPORTS();
/* member initializers and constructor code */
mLanguage.Assign(NS_LITERAL_STRING("en"));
}
mozEnglishWordUtils::~mozEnglishWordUtils()
{
/* destructor code */
}
/* attribute wstring language; */
NS_IMETHODIMP mozEnglishWordUtils::GetLanguage(PRUnichar * *aLanguage)
{
nsresult res=NS_OK;
NS_PRECONDITION(aLanguage != nsnull, "null ptr");
if(!aLanguage){
res = NS_ERROR_NULL_POINTER;
}
else{
*aLanguage = ToNewUnicode(mLanguage);
if(!aLanguage) res = NS_ERROR_OUT_OF_MEMORY;
}
return res;
}
/* attribute wstring charset; */
NS_IMETHODIMP mozEnglishWordUtils::GetCharset(PRUnichar * *aCharset)
{
nsresult res=NS_OK;
NS_PRECONDITION(aCharset != nsnull, "null ptr");
if(!aCharset){
res = NS_ERROR_NULL_POINTER;
}
else{
*aCharset = ToNewUnicode(mCharset);
if(!aCharset) res = NS_ERROR_OUT_OF_MEMORY;
}
return res;
}
NS_IMETHODIMP mozEnglishWordUtils::SetCharset(const PRUnichar * aCharset)
{
nsresult res;
mCharset = aCharset;
nsCAutoString convCharset;
convCharset.AssignWithConversion(mCharset);
nsCOMPtr<nsICharsetConverterManager> ccm = do_GetService(kCharsetConverterManagerCID, &res);
if (NS_FAILED(res)) return res;
if(!ccm) return NS_ERROR_FAILURE;
res=ccm->GetUnicodeEncoder(convCharset.get(),getter_AddRefs(mEncoder));
if(mEncoder && NS_SUCCEEDED(res)){
res=mEncoder->SetOutputErrorBehavior(mEncoder->kOnError_Signal,nsnull,'?');
}
if (NS_FAILED(res)) return res;
res=ccm->GetUnicodeDecoder(convCharset.get(),getter_AddRefs(mDecoder));
if (NS_FAILED(res)) return res;
res = nsServiceManager::GetService(kUnicharUtilCID,NS_GET_IID(nsICaseConversion), getter_AddRefs(mCaseConv));
return res;
}
/* void GetRootForm (in wstring aWord, in PRUint32 type, [array, size_is (count)] out string words, out PRUint32 count); */
// convert aWord to the spellcheck charset and return the possible root forms.
// If convertion errors occur, return an empty list.
NS_IMETHODIMP mozEnglishWordUtils::GetRootForm(const PRUnichar *aWord, PRUint32 type, char ***words, PRUint32 *count)
{
nsAutoString word(aWord);
nsresult res;
char **tmpPtr;
PRUnichar *tWord;
PRInt32 inLength,outLength;
*count = 0;
mozEnglishWordUtils::myspCapitalization ct = captype(word);
switch (ct)
{
case HuhCap:
case NoCap:
tmpPtr = (char **)nsMemory::Alloc(sizeof(char *));
inLength = word.Length();
res = mEncoder->GetMaxLength(word.get(),inLength,&outLength);
if(NS_FAILED(res)|| res == NS_ERROR_UENC_NOMAPPING){
nsMemory::Free(tmpPtr);
*words=nsnull;
break;
}
tmpPtr[0] = (char *) nsMemory::Alloc(sizeof(char) * (outLength+1));
res = mEncoder->Convert(aWord,&inLength,tmpPtr[0],&outLength);
tmpPtr[0][outLength]='\0';
if(NS_FAILED(res)|| res == NS_ERROR_UENC_NOMAPPING){
nsMemory::Free(tmpPtr[0]);
nsMemory::Free(tmpPtr);
*words=nsnull;
break;
}
*words = tmpPtr;
*count = 1;
break;
case AllCap:
tmpPtr = (char **)nsMemory::Alloc(sizeof(char *)*3);
inLength = word.Length();
res = mEncoder->GetMaxLength(word.get(),inLength,&outLength);
if(NS_FAILED(res)|| res == NS_ERROR_UENC_NOMAPPING){
nsMemory::Free(tmpPtr);
*words=nsnull;
break;
}
tmpPtr[0] = (char *) nsMemory::Alloc(sizeof(char) * (outLength+1));
res = mEncoder->Convert(aWord,&inLength,tmpPtr[0],&outLength);
if(NS_FAILED(res)|| res == NS_ERROR_UENC_NOMAPPING){
nsMemory::Free(tmpPtr[0]);
nsMemory::Free(tmpPtr);
*words=nsnull;
break;
}
tmpPtr[0][outLength]='\0';
inLength = word.Length();
tWord=ToNewUnicode(word);
mCaseConv->ToLower(tWord,tWord,inLength);
res = mEncoder->GetMaxLength(tWord,inLength,&outLength);
if(NS_FAILED(res)|| res == NS_ERROR_UENC_NOMAPPING){
nsMemory::Free(tmpPtr[0]);
nsMemory::Free(tmpPtr);
*words=nsnull;
break;
}
tmpPtr[1] = (char *) nsMemory::Alloc(sizeof(char) * (outLength+1));
res = mEncoder->Convert(tWord,&inLength,tmpPtr[1],&outLength);
if(NS_FAILED(res)|| res == NS_ERROR_UENC_NOMAPPING){
nsMemory::Free(tmpPtr[0]);
nsMemory::Free(tmpPtr[1]);
nsMemory::Free(tmpPtr);
*words=nsnull;
break;
}
tmpPtr[1][outLength]='\0';
nsMemory::Free(tWord);
tWord=ToNewUnicode(word);
mCaseConv->ToLower(tWord,tWord,inLength);
mCaseConv->ToUpper(tWord,tWord,1);
res = mEncoder->GetMaxLength(tWord,inLength,&outLength);
if(NS_FAILED(res)|| res == NS_ERROR_UENC_NOMAPPING){
nsMemory::Free(tmpPtr[0]);
nsMemory::Free(tmpPtr[1]);
nsMemory::Free(tmpPtr);
*words=nsnull;
break;
}
tmpPtr[2] = (char *) nsMemory::Alloc(sizeof(char) * (outLength+1));
res = mEncoder->Convert(tWord,&inLength,tmpPtr[2],&outLength);
if(NS_FAILED(res)|| res == NS_ERROR_UENC_NOMAPPING){
nsMemory::Free(tmpPtr[0]);
nsMemory::Free(tmpPtr[1]);
nsMemory::Free(tmpPtr[2]);
nsMemory::Free(tmpPtr);
*words=nsnull;
break;
}
tmpPtr[2][outLength]='\0';
nsMemory::Free(tWord);
*words = tmpPtr;
*count = 3;
break;
case InitCap:
tmpPtr = (char **)nsMemory::Alloc(sizeof(char *)*2);
inLength = word.Length();
res = mEncoder->GetMaxLength(word.get(),inLength,&outLength);
if(NS_FAILED(res)|| res == NS_ERROR_UENC_NOMAPPING){
nsMemory::Free(tmpPtr);
*words=nsnull;
break;
}
tmpPtr[0] = (char *) nsMemory::Alloc(sizeof(char) * (outLength+1));
res = mEncoder->Convert(aWord,&inLength,tmpPtr[0],&outLength);
if(NS_FAILED(res)|| res == NS_ERROR_UENC_NOMAPPING){
nsMemory::Free(tmpPtr[0]);
nsMemory::Free(tmpPtr);
*words=nsnull;
break;
}
tmpPtr[0][outLength]='\0';
tWord=ToNewUnicode(word);
inLength = word.Length();
mCaseConv->ToLower(tWord,tWord,inLength);
res = mEncoder->GetMaxLength(tWord,inLength,&outLength);
if(NS_FAILED(res)|| res == NS_ERROR_UENC_NOMAPPING){
nsMemory::Free(tmpPtr[0]);
nsMemory::Free(tmpPtr);
*words=nsnull;
break;
}
tmpPtr[1] = (char *) nsMemory::Alloc(sizeof(char) * (outLength+1));
res = mEncoder->Convert(tWord,&inLength,tmpPtr[1],&outLength);
if(NS_FAILED(res)|| res == NS_ERROR_UENC_NOMAPPING){
nsMemory::Free(tmpPtr[1]);
nsMemory::Free(tmpPtr[0]);
nsMemory::Free(tmpPtr);
*words=nsnull;
break;
}
nsMemory::Free(tWord);
tmpPtr[1][outLength]='\0';
*words = tmpPtr;
*count = 2;
break;
default:
res=NS_ERROR_FAILURE; // should never get here;
break;
}
return res;
}
// This needs vast improvement -- take the charset from he ISpell dictionary
static PRBool ucIsAlpha(PRUnichar c)
{
if(5==GetCat(c)) return PR_TRUE;
return PR_FALSE;
}
/* void FindNextWord (in wstring word, in PRUint32 length, in PRUint32 offset, out PRUint32 begin, out PRUint32 end); */
NS_IMETHODIMP mozEnglishWordUtils::FindNextWord(const PRUnichar *word, PRUint32 length, PRUint32 offset, PRInt32 *begin, PRInt32 *end)
{
const PRUnichar *p = word + offset;
const PRUnichar *endbuf = word + length;
const PRUnichar *startWord=p;
if(p<endbuf){
while((p < endbuf) && (!ucIsAlpha(*p)))
{
p++;
}
startWord=p;
while((p < endbuf) && ((ucIsAlpha(*p))||(*p=='\'')))
{
p++;
}
while((p > startWord)&&(*(p-1) == '\'')){ // trim trailing apostrophes
p--;
}
}
else{
startWord = endbuf;
}
if(startWord == endbuf){
*begin = -1;
*end = -1;
}
else{
*begin = startWord-word;
*end = p-word;
}
return NS_OK;
}
mozEnglishWordUtils::myspCapitalization
mozEnglishWordUtils::captype(const nsString &word)
{
if(!mCaseConv) return HuhCap; //punt
PRUnichar* lword=ToNewUnicode(word);
mCaseConv->ToUpper(lword,lword,word.Length());
if(word.Equals(lword)){
nsMemory::Free(lword);
return AllCap;
}
mCaseConv->ToLower(lword,lword,word.Length());
if(word.Equals(lword)){
nsMemory::Free(lword);
return NoCap;
}
PRInt32 length=word.Length();
if(Substring(word,1,length-1).Equals(lword+1)){
nsMemory::Free(lword);
return InitCap;
}
nsMemory::Free(lword);
return HuhCap;
}
// Convert the list of words in iwords to the same capitalization aWord and
// convert them to unicode then return them in owords.
NS_IMETHODIMP mozEnglishWordUtils::FromRootForm(const PRUnichar *aWord, const char **iwords, PRUint32 icount, PRUnichar ***owords, PRUint32 *ocount)
{
nsAutoString word(aWord);
nsresult res = NS_OK;
PRInt32 inLength,outLength;
PRUnichar **tmpPtr = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *)*icount);
if (!tmpPtr)
return NS_ERROR_OUT_OF_MEMORY;
mozEnglishWordUtils::myspCapitalization ct = captype(word);
for(PRUint32 i=0;i<icount;i++){
inLength = nsCRT::strlen(iwords[i]);
res = mDecoder->GetMaxLength(iwords[i],inLength,&outLength);
if(NS_FAILED(res))
break;
tmpPtr[i] = (PRUnichar *) nsMemory::Alloc(sizeof(PRUnichar *) * (outLength+1));
res = mDecoder->Convert(iwords[i],&inLength,tmpPtr[i],&outLength);
tmpPtr[i][outLength]=0;
nsAutoString capTest(tmpPtr[i]);
mozEnglishWordUtils::myspCapitalization newCt=captype(capTest);
if(newCt == NoCap){
switch(ct)
{
case HuhCap:
case NoCap:
break;
case AllCap:
res=mCaseConv->ToUpper(tmpPtr[i],tmpPtr[i],outLength);
break;
case InitCap:
res=mCaseConv->ToUpper(tmpPtr[i],tmpPtr[i],1);
break;
default:
res=NS_ERROR_FAILURE; // should never get here;
break;
}
}
}
if(NS_SUCCEEDED(res)){
*owords = tmpPtr;
*ocount = icount;
}
return res;
}

View File

@ -0,0 +1,71 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein Deinst@world.std.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 mozEnglishWordUtils_h__
#define mozEnglishWordUtils_h__
#include "nsCOMPtr.h"
#include "mozISpellI18NUtil.h"
#include "nsIUnicodeEncoder.h"
#include "nsIUnicodeDecoder.h"
#include "nsString.h"
#include "nsICaseConversion.h"
class mozEnglishWordUtils : public mozISpellI18NUtil
{
public:
NS_DECL_ISUPPORTS
NS_DECL_MOZISPELLI18NUTIL
mozEnglishWordUtils();
virtual ~mozEnglishWordUtils();
/* additional members */
enum myspCapitalization{
NoCap,InitCap,AllCap,HuhCap
};
protected:
mozEnglishWordUtils::myspCapitalization captype(const nsString &word);
nsString mLanguage;
nsString mCharset;
nsCOMPtr<nsIUnicodeEncoder> mEncoder;
nsCOMPtr<nsIUnicodeDecoder> mDecoder;
nsCOMPtr<nsICaseConversion> mCaseConv;
};
#endif

View File

@ -0,0 +1,87 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein Deinst@world.std.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 "mozGenericWordUtils.h"
NS_IMPL_ISUPPORTS1(mozGenericWordUtils, mozISpellI18NUtil)
// do something sensible but generic ... eventually. For now whine.
mozGenericWordUtils::mozGenericWordUtils()
{
NS_INIT_ISUPPORTS();
/* member initializers and constructor code */
}
mozGenericWordUtils::~mozGenericWordUtils()
{
/* destructor code */
}
/* readonly attribute wstring language; */
NS_IMETHODIMP mozGenericWordUtils::GetLanguage(PRUnichar * *aLanguage)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* attribute wstring charset; */
NS_IMETHODIMP mozGenericWordUtils::GetCharset(PRUnichar * *aCharset)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP mozGenericWordUtils::SetCharset(const PRUnichar * aCharset)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* void GetRootForm (in wstring word, in PRUint32 type, [array, size_is (count)] out string words, out PRUint32 count); */
NS_IMETHODIMP mozGenericWordUtils::GetRootForm(const PRUnichar *word, PRUint32 type, char ***words, PRUint32 *count)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* void FromRootForm (in wstring word, [array, size_is (icount)] in string iwords, in PRUint32 icount, [array, size_is (ocount)] out wstring owords, out PRUint32 ocount); */
NS_IMETHODIMP mozGenericWordUtils::FromRootForm(const PRUnichar *word, const char **iwords, PRUint32 icount, PRUnichar ***owords, PRUint32 *ocount)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* void FindNextWord (in wstring word, in PRUint32 length, in PRUint32 offset, out PRUint32 begin, out PRUint32 end); */
NS_IMETHODIMP mozGenericWordUtils::FindNextWord(const PRUnichar *word, PRUint32 length, PRUint32 offset, PRInt32 *begin, PRInt32 *end)
{
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@ -0,0 +1,54 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein Deinst@world.std.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 mozGenericWordUtils_h__
#define mozGenericWordUtils_h__
#include "nsCOMPtr.h"
#include "mozISpellI18NUtil.h"
class mozGenericWordUtils : public mozISpellI18NUtil
{
public:
NS_DECL_ISUPPORTS
NS_DECL_MOZISPELLI18NUTIL
mozGenericWordUtils();
virtual ~mozGenericWordUtils();
};
#endif

View File

@ -0,0 +1,635 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein <Deinst@world.std.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 "mozPersonalDictionary.h"
#include "nsIUnicharInputStream.h"
#include "nsReadableUtils.h"
#include "nsIFile.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsICharsetConverterManager.h"
#include "nsICharsetAlias.h"
#include "nsAVLTree.h"
#include "nsIObserverService.h"
#include "nsIPref.h"
#include "nsCRT.h"
#include "nsNetUtil.h"
#define MOZ_PERSONAL_DICT_NAME "persdict.dat"
static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
const int kMaxWordLen=256;
#define spellchecker_savePref "spellchecker.savePDEverySession"
static PRBool SessionSave=PR_FALSE;
/**
* This is the most braindead implementation of a personal dictionary possible.
* There is not much complexity needed, though. It could be made much faster,
* and probably should, but I don't see much need for more in terms of interface.
*
* Allowing personal words to be associated with only certain dictionaries maybe.
*
* TODO:
* Implement the suggestion record.
*/
NS_IMPL_ISUPPORTS3(mozPersonalDictionary, mozIPersonalDictionary, nsIObserver, nsSupportsWeakReference);
/* AVL node functors */
/*
* String comparitor for Unicode tree
**/
class StringNodeComparitor: public nsAVLNodeComparitor {
public:
StringNodeComparitor(){}
virtual ~StringNodeComparitor(){}
virtual PRInt32 operator() (void *item1,void *item2){
return nsCRT::strcmp((PRUnichar *)item1,(PRUnichar *)item2);
}
};
/*
* String comparitor for charset tree
**/
class CStringNodeComparitor: public nsAVLNodeComparitor {
public:
CStringNodeComparitor(){}
virtual ~CStringNodeComparitor(){}
virtual PRInt32 operator() (void *item1,void *item2){
return nsCRT::strcmp((char *)item1,(char *)item2);
}
};
/*
* the generic deallocator
**/
class DeallocatorFunctor: public nsAVLNodeFunctor {
public:
DeallocatorFunctor(){}
virtual ~DeallocatorFunctor(){}
virtual void* operator() (void * anItem){
nsMemory::Free(anItem);
return nsnull;
}
};
static StringNodeComparitor *gStringNodeComparitor;
static CStringNodeComparitor *gCStringNodeComparitor;
static DeallocatorFunctor *gDeallocatorFunctor;
/*
* Functor for copying the unicode tree to the charset tree with conversion
**/
class ConvertedCopyFunctor: public nsAVLNodeFunctor {
public:
ConvertedCopyFunctor(nsIUnicodeEncoder* anEncoder, nsAVLTree *aNewTree):newTree(aNewTree),encoder(anEncoder){
res = NS_OK;
}
virtual ~ConvertedCopyFunctor(){}
nsresult GetResult(){return res;}
virtual void* operator() (void * anItem){
if(NS_SUCCEEDED(res)){
PRUnichar * word=(PRUnichar *) anItem;
PRInt32 inLength,outLength;
inLength = nsCRT::strlen(word);
res = encoder->GetMaxLength(word,inLength,&outLength);
if(NS_FAILED(res))
return nsnull;
char * tmp = (char *) nsMemory::Alloc(sizeof(PRUnichar *) * (outLength+1));
res = encoder->Convert(word,&inLength,tmp,&outLength);
if(res == NS_ERROR_UENC_NOMAPPING){
res = NS_OK; // word just doesnt fit in our charset -- assume that it is the wrong language.
nsMemory::Free(tmp);
}
else{
tmp[outLength]='\0';
newTree->AddItem(tmp);
}
}
return nsnull;
}
protected:
nsresult res;
nsAVLTree *newTree;
nsCOMPtr<nsIUnicodeEncoder> encoder;
};
/*
* Copy the tree to a waiiting aray of Unichar pointers.
* All the strings are newly created. It is the callers responsibility to free them
**/
class CopyToArrayFunctor: public nsAVLNodeFunctor {
public:
CopyToArrayFunctor(PRUnichar **tabulaRasa){
data = tabulaRasa;
count =0;
res = NS_OK;
}
virtual ~CopyToArrayFunctor(){}
nsresult GetResult(){return res;}
virtual void* operator() (void * anItem){
PRUnichar * word=(PRUnichar *) anItem;
if(NS_SUCCEEDED(res)){
data[count]=ToNewUnicode(nsDependentString(word));
if(!data[count]) res = NS_ERROR_OUT_OF_MEMORY;
return (void*) (data[count++]);
}
return nsnull;
}
protected:
nsresult res;
PRUnichar **data;
PRUint32 count;
};
/*
* Copy the tree to an open file.
**/
class CopyToStreamFunctor: public nsAVLNodeFunctor {
public:
CopyToStreamFunctor(nsIOutputStream *aStream):mStream(aStream){
res = NS_OK;
}
virtual ~CopyToStreamFunctor(){}
nsresult GetResult(){return res;}
virtual void* operator() (void * anItem){
nsString word((PRUnichar *) anItem);
if(NS_SUCCEEDED(res)){
PRUint32 bytesWritten;
word.Append(NS_LITERAL_STRING("\n"));
NS_ConvertUCS2toUTF8 UTF8word(word);
res = mStream->Write(UTF8word.get(),UTF8word.Length(),&bytesWritten);
}
return nsnull;
}
protected:
nsresult res;
nsIOutputStream* mStream;
};
mozPersonalDictionary::mozPersonalDictionary():mUnicodeTree(nsnull),mCharsetTree(nsnull),mUnicodeIgnoreTree(nsnull),mCharsetIgnoreTree(nsnull)
{
NS_INIT_ISUPPORTS();
NS_ASSERTION(!gStringNodeComparitor,"Someone's been writing in my statics! I'm a Singleton Bear!");
if(!gStringNodeComparitor){
gStringNodeComparitor = new StringNodeComparitor;
gCStringNodeComparitor = new CStringNodeComparitor;
gDeallocatorFunctor = new DeallocatorFunctor;
}
}
mozPersonalDictionary::~mozPersonalDictionary()
{
delete mUnicodeTree;
delete mCharsetTree;
delete mUnicodeIgnoreTree;
delete mCharsetIgnoreTree;
}
int PR_CALLBACK
SpellcheckerSavePrefChanged(const char * newpref, void * data)
{
nsresult rv;
nsCOMPtr<nsIPref> prefs(do_GetService(NS_PREF_CONTRACTID, &rv));
if(NS_SUCCEEDED(rv)&&prefs) {
if(NS_FAILED(prefs->GetBoolPref(spellchecker_savePref,&SessionSave))){
SessionSave = PR_TRUE;
}
}
else{
SessionSave = PR_TRUE;
}
return 0;
}
NS_IMETHODIMP mozPersonalDictionary::Init()
{
nsresult rv;
nsCOMPtr<nsIObserverService> svc =
do_GetService("@mozilla.org/observer-service;1", &rv);
if (NS_SUCCEEDED(rv) && svc) {
// Register as an oserver of shutdown
rv = svc->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_TRUE);
// Register as an observer of profile changes
if (NS_SUCCEEDED(rv))
rv = svc->AddObserver(this, "profile-before-change", PR_TRUE);
if (NS_SUCCEEDED(rv))
rv = svc->AddObserver(this, "profile-after-change", PR_TRUE);
}
if(NS_FAILED(rv)) return rv;
nsCOMPtr<nsIPref> prefs(do_GetService(NS_PREF_CONTRACTID, &rv));
if(NS_SUCCEEDED(rv)&&prefs) {
if(NS_FAILED(prefs->GetBoolPref(spellchecker_savePref, &SessionSave))){
SessionSave = PR_TRUE;
}
prefs->RegisterCallback(spellchecker_savePref,SpellcheckerSavePrefChanged,nsnull);
}
else{
SessionSave = PR_FALSE;
}
if(NS_FAILED(rv)) return rv;
return Load();
}
/* attribute wstring language; */
NS_IMETHODIMP mozPersonalDictionary::GetLanguage(PRUnichar * *aLanguage)
{
nsresult res=NS_OK;
NS_PRECONDITION(aLanguage != nsnull, "null ptr");
if(!aLanguage){
res = NS_ERROR_NULL_POINTER;
}
else{
*aLanguage = ToNewUnicode(mLanguage);
if(!aLanguage) res = NS_ERROR_OUT_OF_MEMORY;
}
return res;
}
NS_IMETHODIMP mozPersonalDictionary::SetLanguage(const PRUnichar * aLanguage)
{
mLanguage = aLanguage;
return NS_OK;
}
/* attribute wstring charset; */
NS_IMETHODIMP mozPersonalDictionary::GetCharset(PRUnichar * *aCharset)
{
nsresult res=NS_OK;
NS_PRECONDITION(aCharset != nsnull, "null ptr");
if(!aCharset){
res = NS_ERROR_NULL_POINTER;
}
else{
*aCharset = ToNewUnicode(mLanguage);
if(!aCharset) res = NS_ERROR_OUT_OF_MEMORY;
}
return res;
}
NS_IMETHODIMP mozPersonalDictionary::SetCharset(const PRUnichar * aCharset)
{
nsresult res;
mCharset = aCharset;
nsCAutoString convCharset;
convCharset.AssignWithConversion(mCharset);
nsCOMPtr<nsICharsetConverterManager> ccm = do_GetService(kCharsetConverterManagerCID, &res);
if (NS_FAILED(res)) return res;
if(!ccm) return NS_ERROR_FAILURE;
res=ccm->GetUnicodeEncoder(convCharset.get(),getter_AddRefs(mEncoder));
if (NS_FAILED(res)) return res;
if(!mEncoder) return NS_ERROR_FAILURE;
if(mEncoder && NS_SUCCEEDED(res)){
res=mEncoder->SetOutputErrorBehavior(mEncoder->kOnError_Signal,nsnull,'?');
}
if(mEncoder && mUnicodeTree){
delete mCharsetTree;
mCharsetTree = new nsAVLTree(*gCStringNodeComparitor,gDeallocatorFunctor);
ConvertedCopyFunctor converter(mEncoder,mCharsetTree);
mUnicodeTree->ForEachDepthFirst(converter);
}
if(mEncoder && mUnicodeIgnoreTree){
delete mCharsetIgnoreTree;
mCharsetIgnoreTree = new nsAVLTree(*gCStringNodeComparitor,gDeallocatorFunctor);
ConvertedCopyFunctor converter(mEncoder,mCharsetIgnoreTree);
mUnicodeIgnoreTree->ForEachDepthFirst(converter);
}
return res;
}
/* void Load (); */
NS_IMETHODIMP mozPersonalDictionary::Load()
{
//FIXME Deinst -- get dictionary name from prefs;
nsresult res;
nsCOMPtr<nsIFile> theFile;
PRBool dictExists;
res = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(theFile));
if(NS_FAILED(res)) return res;
if(!theFile)return NS_ERROR_FAILURE;
res = theFile->Append(NS_LITERAL_STRING(MOZ_PERSONAL_DICT_NAME));
if(NS_FAILED(res)) return res;
res = theFile->Exists(&dictExists);
if(NS_FAILED(res)) return res;
if(!dictExists) {
//create new user dictionary
nsCOMPtr<nsIOutputStream> outStream;
NS_NewLocalFileOutputStream(getter_AddRefs(outStream), theFile, PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE ,0664);
CopyToStreamFunctor writer(outStream);
if(NS_FAILED(res)) return res;
if(!outStream)return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIInputStream> inStream;
NS_NewLocalFileInputStream(getter_AddRefs(inStream), theFile);
nsCOMPtr<nsIUnicharInputStream> convStream;
res = NS_NewUTF8ConverterStream(getter_AddRefs(convStream), inStream, 0);
if(NS_FAILED(res)) return res;
// we're rereading get rid of the old data -- we shouldn't have any, but...
delete mUnicodeTree;
mUnicodeTree = new nsAVLTree(*gStringNodeComparitor,gDeallocatorFunctor);
PRUnichar c;
PRUint32 nRead;
PRBool done = PR_FALSE;
do{ // read each line of text into the string array.
if( (NS_OK != convStream->Read(&c, 1, &nRead)) || (nRead != 1)) break;
while(!done && ((c == '\n') || (c == '\r'))){
if( (NS_OK != convStream->Read(&c, 1, &nRead)) || (nRead != 1)) done = PR_TRUE;
}
if (!done){
nsAutoString word;
while((c != '\n') && (c != '\r') && !done){
word.Append(c);
if( (NS_OK != convStream->Read(&c, 1, &nRead)) || (nRead != 1)) done = PR_TRUE;
}
mUnicodeTree->AddItem((void *)ToNewUnicode(word));
}
}while(!done);
mDirty = PR_FALSE;
return res;
}
/* void Save (); */
NS_IMETHODIMP mozPersonalDictionary::Save()
{
nsCOMPtr<nsIFile> theFile;
nsresult res;
if(!mDirty) return NS_OK;
//FIXME Deinst -- get dictionary name from prefs;
res = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(theFile));
if(NS_FAILED(res)) return res;
if(!theFile)return NS_ERROR_FAILURE;
res = theFile->Append(NS_LITERAL_STRING(MOZ_PERSONAL_DICT_NAME));
if(NS_FAILED(res)) return res;
nsCOMPtr<nsIOutputStream> outStream;
NS_NewLocalFileOutputStream(getter_AddRefs(outStream), theFile, PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE ,0664);
CopyToStreamFunctor writer(outStream);
if(NS_FAILED(res)) return res;
if(!outStream)return NS_ERROR_FAILURE;
if (mUnicodeTree) mUnicodeTree->ForEach(writer);
mDirty = PR_FALSE;
return NS_OK;
}
/* void GetWordList ([array, size_is (count)] out wstring words, out PRUint32 count); */
NS_IMETHODIMP mozPersonalDictionary::GetWordList(PRUnichar ***words, PRUint32 *count)
{
if(!words || !count)
return NS_ERROR_NULL_POINTER;
*words=0;
*count=0;
PRUnichar **tmpPtr = 0;
if(!mUnicodeTree){
return NS_OK;
}
tmpPtr = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *) * (mUnicodeTree->GetCount()));
if (!tmpPtr)
return NS_ERROR_OUT_OF_MEMORY;
CopyToArrayFunctor pitneyBowes(tmpPtr);
mUnicodeTree->ForEach(pitneyBowes);
nsresult res = pitneyBowes.GetResult();
if(NS_SUCCEEDED(res)){
*count = mUnicodeTree->GetCount();
*words = tmpPtr;
}
return res;
}
/* boolean CheckUnicode (in wstring word); */
NS_IMETHODIMP mozPersonalDictionary::CheckUnicode(const PRUnichar *word, PRBool *_retval)
{
if(!word || !_retval || !mUnicodeTree)
return NS_ERROR_NULL_POINTER;
if(mUnicodeTree->FindItem((void *)word)){
*_retval = PR_TRUE;
}
else{
if(mUnicodeIgnoreTree&&mUnicodeIgnoreTree->FindItem((void *)word)){
*_retval = PR_TRUE;
}
else{
*_retval = PR_FALSE;
}
}
return NS_OK;
}
/* boolean Check (in string word); */
NS_IMETHODIMP mozPersonalDictionary::Check(const char *word, PRBool *_retval)
{
if(!word || !_retval || !mCharsetTree)
return NS_ERROR_NULL_POINTER;
if(mCharsetTree->FindItem((void *)word)){
*_retval = PR_TRUE;
}
else{
if(mCharsetIgnoreTree&&mCharsetIgnoreTree->FindItem((void *)word)){
*_retval = PR_TRUE;
}
else{
*_retval = PR_FALSE;
}
}
return NS_OK;
}
/* void AddWord (in wstring word); */
NS_IMETHODIMP mozPersonalDictionary::AddWord(const PRUnichar *word, const PRUnichar *lang)
{
nsAutoString temp(word);
if(mUnicodeTree) mUnicodeTree->AddItem(ToNewUnicode(nsDependentString(word)));
mDirty=PR_TRUE;
nsresult res=NS_OK;
if(mCharsetTree&&mEncoder){
PRInt32 inLength,outLength;
inLength = nsCRT::strlen(word);
res = mEncoder->GetMaxLength(word,inLength,&outLength);
if(NS_FAILED(res))
return res;
char * tmp = (char *) nsMemory::Alloc(sizeof(PRUnichar *) * (outLength+1));
res = mEncoder->Convert(word,&inLength,tmp,&outLength);
if(NS_FAILED(res))
return res;
tmp[outLength]='\0';
mCharsetTree->AddItem(tmp);
}
return res;
}
/* void RemoveWord (in wstring word); */
NS_IMETHODIMP mozPersonalDictionary::RemoveWord(const PRUnichar *word, const PRUnichar *lang)
{
nsAutoString temp(word);
if(mUnicodeTree) mUnicodeTree->RemoveItem((void *)word);
mDirty=PR_TRUE;
nsresult res=NS_OK;
if(mCharsetTree&&mEncoder){
PRInt32 inLength,outLength;
inLength = nsCRT::strlen(word);
res = mEncoder->GetMaxLength(word,inLength,&outLength);
if(NS_FAILED(res))
return res;
char * tmp = (char *) nsMemory::Alloc(sizeof(PRUnichar *) * (outLength+1));
res = mEncoder->Convert(word,&inLength,tmp,&outLength);
if(NS_FAILED(res))
return res;
tmp[outLength]='\0';
mCharsetTree->AddItem(tmp);
}
return res;
}
/* void IgnoreWord (in wstring word); */
NS_IMETHODIMP mozPersonalDictionary::IgnoreWord(const PRUnichar *word)
{
if(!mUnicodeIgnoreTree){
mUnicodeIgnoreTree=new nsAVLTree(*gStringNodeComparitor,gDeallocatorFunctor);
}
if(!mUnicodeIgnoreTree){
return NS_ERROR_OUT_OF_MEMORY;
}
mUnicodeIgnoreTree->AddItem(ToNewUnicode(nsDependentString(word)));
if(!mCharsetIgnoreTree){
mCharsetIgnoreTree=new nsAVLTree(*gCStringNodeComparitor,gDeallocatorFunctor);
}
if(!mCharsetIgnoreTree){
return NS_ERROR_OUT_OF_MEMORY;
}
if(mCharsetIgnoreTree&&mEncoder){
PRInt32 inLength,outLength;
nsresult res;
inLength = nsCRT::strlen(word);
res = mEncoder->GetMaxLength(word,inLength,&outLength);
if(NS_FAILED(res))
return res;
char * tmp = (char *) nsMemory::Alloc(sizeof(PRUnichar *) * (outLength+1));
res = mEncoder->Convert(word,&inLength,tmp,&outLength);
if(NS_FAILED(res))
return res;
tmp[outLength]='\0';
mCharsetIgnoreTree->AddItem(tmp);
}
return NS_OK;
}
/* void EndSession (); */
NS_IMETHODIMP mozPersonalDictionary::EndSession()
{
if(SessionSave)Save();
delete mUnicodeIgnoreTree;
delete mCharsetIgnoreTree;
mUnicodeIgnoreTree=nsnull;
mCharsetIgnoreTree=nsnull;
return NS_OK;
}
/* void AddCorrection (in wstring word, in wstring correction); */
NS_IMETHODIMP mozPersonalDictionary::AddCorrection(const PRUnichar *word, const PRUnichar *correction, const PRUnichar *lang)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* void RemoveCorrection (in wstring word, in wstring correction); */
NS_IMETHODIMP mozPersonalDictionary::RemoveCorrection(const PRUnichar *word, const PRUnichar *correction, const PRUnichar *lang)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* void GetCorrection (in wstring word, [array, size_is (count)] out wstring words, out PRUint32 count); */
NS_IMETHODIMP mozPersonalDictionary::GetCorrection(const PRUnichar *word, PRUnichar ***words, PRUint32 *count)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* void observe (in nsISupports aSubject, in string aTopic, in wstring aData); */
NS_IMETHODIMP mozPersonalDictionary::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData)
{
if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
Save();
delete mUnicodeTree;
delete mCharsetTree;
delete mUnicodeIgnoreTree;
delete mCharsetIgnoreTree;
mUnicodeTree=nsnull;
mCharsetTree=nsnull;
mUnicodeIgnoreTree=nsnull;
mCharsetIgnoreTree=nsnull;
}
else if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
Save();
delete mUnicodeTree;
delete mCharsetTree;
delete mUnicodeIgnoreTree;
delete mCharsetIgnoreTree;
mUnicodeTree=nsnull;
mCharsetTree=nsnull;
mUnicodeIgnoreTree=nsnull;
mCharsetIgnoreTree=nsnull;
}
if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
Load();
}
return NS_OK;
}

View File

@ -0,0 +1,81 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein Deinst@world.std.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 mozPersonalDictionary_h__
#define mozPersonalDictionary_h__
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsVoidArray.h"
#include "mozIPersonalDictionary.h"
#include "nsIUnicodeEncoder.h"
#include "nsIObserver.h"
#include "nsWeakReference.h"
class nsAVLTree;
#define MOZ_PERSONALDICTIONARY_CONTRACTID "@mozilla.org/spellchecker/personaldictionary;1"
#define MOZ_PERSONALDICTIONARY_CID \
{ /* FC17F1C5-367A-4d04-84A5-AF7E8F973699} */ \
0xFC17F1C5, 0x367A, 0x4d04, \
{ 0x84, 0xA5, 0xAF, 0x7E, 0x8F, 0x97, 0x36, 0x99} }
class mozPersonalDictionary : public mozIPersonalDictionary,
public nsIObserver,
public nsSupportsWeakReference
{
public:
NS_DECL_ISUPPORTS
NS_DECL_MOZIPERSONALDICTIONARY
NS_DECL_NSIOBSERVER
mozPersonalDictionary();
virtual ~mozPersonalDictionary();
protected:
nsStringArray mDictionary; /* use something a little smarter eventually*/
PRBool mDirty; /* has the dictionary been modified */
nsString mCharset; /* charset that the spell checker is using */
nsString mLanguage; /* the name of the language currently in use */
nsAVLTree *mUnicodeTree; /* the dictionary entries */
nsAVLTree *mCharsetTree; /* the dictionary entries in the current charset */
nsAVLTree *mUnicodeIgnoreTree; /* the ignore all entries */
nsAVLTree *mCharsetIgnoreTree; /* the ignore all entries in the current charset */
nsCOMPtr<nsIUnicodeEncoder> mEncoder; /*Encoder to use to compare with spellchecker word */
};
#endif

View File

@ -0,0 +1,408 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein Deinst@world.std.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 "mozSpellChecker.h"
#include "nsIServiceManager.h"
#include "mozISpellI18NManager.h"
NS_IMPL_ISUPPORTS1(mozSpellChecker, nsISpellChecker)
mozSpellChecker::mozSpellChecker()
{
NS_INIT_ISUPPORTS();
mDictionaryName.SetLength(0);
nsresult rv;
mPersonalDictionary = do_GetService("@mozilla.org/spellchecker/personaldictionary;1",&rv);
if (NS_FAILED(rv)) {
NS_ERROR("Could not get personal Dictionary");
}
mSpellCheckingEngine = do_GetService("@mozilla.org/spellchecker/myspell;1",&rv);
if (NS_FAILED(rv)) {
NS_ERROR("Could not get spell checker");
}
mPersonalDictionary->Init();
mSpellCheckingEngine->SetPersonalDictionary(mPersonalDictionary);
}
mozSpellChecker::~mozSpellChecker()
{
if(mPersonalDictionary){
// mPersonalDictionary->Save();
mPersonalDictionary->EndSession();
}
mSpellCheckingEngine = nsnull;
mPersonalDictionary = nsnull;
}
NS_IMETHODIMP
mozSpellChecker::SetDocument(nsITextServicesDocument *aDoc, PRBool aFromStartofDoc)
{
mTsDoc = aDoc;
mFromStart = aFromStartofDoc;
return NS_OK;
}
NS_IMETHODIMP
mozSpellChecker::NextMisspelledWord(nsString *aWord, nsStringArray *aSuggestions)
{
if(!aSuggestions||!mConverter)
return NS_ERROR_NULL_POINTER;
PRUint32 selOffset;
PRInt32 begin,end;
nsresult result;
result = SetupDoc(&selOffset);
PRBool isMisspelled,done;
if (NS_FAILED(result))
return result;
while( NS_SUCCEEDED(mTsDoc->IsDone(&done)) && !done )
{
nsString str;
result = mTsDoc->GetCurrentTextBlock(&str);
if (NS_FAILED(result))
return result;
do{
result = mConverter->FindNextWord(str.get(),str.Length(),selOffset,&begin,&end);
if(NS_SUCCEEDED(result)&&(begin != -1)){
nsString currWord;
currWord=Substring(str,begin,end-begin);
result = CheckWord(&currWord,&isMisspelled,aSuggestions);
if(isMisspelled){
*aWord = currWord;
mTsDoc->SetSelection(begin, end-begin);
mTsDoc->ScrollSelectionIntoView();
return NS_OK;
}
}
selOffset = end;
}while(end != -1);
mTsDoc->NextBlock();
selOffset=0;
}
return NS_OK;
}
NS_IMETHODIMP
mozSpellChecker::CheckWord(const nsString *aWord, PRBool *aIsMisspelled, nsStringArray *aSuggestions)
{
nsresult result;
PRBool correct;
if(!mSpellCheckingEngine)
return NS_ERROR_NULL_POINTER;
*aIsMisspelled = PR_FALSE;
result = mSpellCheckingEngine->Check(aWord->get(),&correct);
if(NS_FAILED(result))
return result;
if(!correct){
if(aSuggestions){
PRUint32 count,i;
PRUnichar **words;
nsAutoString temp;
mSpellCheckingEngine->Suggest(aWord->get(),&words,&count);
for(i=0;i<count;i++){
temp.Assign(words[i]);
aSuggestions->AppendString(temp);
}
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, words);
}
if(aIsMisspelled){
*aIsMisspelled = PR_TRUE;
}
}
return NS_OK;
}
NS_IMETHODIMP
mozSpellChecker::Replace(const nsString *aOldWord, const nsString *aNewWord, PRBool aAllOccurrences)
{
if(!mConverter)
return NS_ERROR_NULL_POINTER;
if(aAllOccurrences){
PRUint32 selOffset;
PRInt32 startBlock,currentBlock,currOffset;
PRInt32 begin,end;
PRBool done;
nsresult result;
nsAutoString str;
// find out where we are
result = SetupDoc(&selOffset);
if(NS_FAILED(result))
return result;
result = GetCurrentBlockIndex(mTsDoc,&startBlock);
if(NS_FAILED(result))
return result;
//start at the beginning
result = mTsDoc->FirstBlock();
currOffset=0;
currentBlock = 0;
while( NS_SUCCEEDED(mTsDoc->IsDone(&done)) && !done )
{
result = mTsDoc->GetCurrentTextBlock(&str);
do{
result = mConverter->FindNextWord(str.get(),str.Length(),currOffset,&begin,&end);
if(NS_SUCCEEDED(result)&&(begin != -1)){
if(aOldWord->Equals(Substring(str,begin,end-begin))){
// if we are before the current selection point but in the same block
// move the selection point forwards
if((currentBlock == startBlock)&&(begin < (PRInt32) selOffset)){
selOffset += (aNewWord->Length()-aOldWord->Length());
if(selOffset < 0) selOffset=0;
}
mTsDoc->SetSelection(begin, end-begin);
mTsDoc->InsertText(aNewWord);
mTsDoc->GetCurrentTextBlock(&str);
end += (aNewWord->Length()-aOldWord->Length()); // recursion was cute in GEB, not here.
}
}
currOffset = end;
}while(currOffset != -1);
mTsDoc->NextBlock();
currentBlock++;
currOffset=0;
}
// We are done replacing. Put the selection point back where we found it (or equivalent);
result = mTsDoc->FirstBlock();
currentBlock = 0;
while(( NS_SUCCEEDED(mTsDoc->IsDone(&done)) && !done ) &&(currentBlock < startBlock)){
mTsDoc->NextBlock();
}
if( NS_SUCCEEDED(mTsDoc->IsDone(&done)) && !done ){
nsString str; // regenerate the offset table
result = mTsDoc->GetCurrentTextBlock(&str); // this seems necessary. I'm not 100% sure why
mTsDoc->SetSelection(selOffset,0);
}
}
else{
mTsDoc->InsertText(aNewWord);
}
return NS_OK;
}
NS_IMETHODIMP
mozSpellChecker::IgnoreAll(const nsString *aWord)
{
if(mPersonalDictionary){
mPersonalDictionary->IgnoreWord(aWord->get());
}
return NS_OK;
}
NS_IMETHODIMP
mozSpellChecker::AddWordToPersonalDictionary(const nsString *aWord)
{
nsresult res;
PRUnichar empty=0;
if(!aWord||!mPersonalDictionary)
return NS_ERROR_NULL_POINTER;
res = mPersonalDictionary->AddWord(aWord->get(),&empty);
return res;
}
NS_IMETHODIMP
mozSpellChecker::RemoveWordFromPersonalDictionary(const nsString *aWord)
{
nsresult res;
PRUnichar empty=0;
if(!aWord||!mPersonalDictionary)
return NS_ERROR_NULL_POINTER;
res = mPersonalDictionary->RemoveWord(aWord->get(),&empty);
return res;
}
NS_IMETHODIMP
mozSpellChecker::GetPersonalDictionary(nsStringArray *aWordList)
{
nsAutoString temp;
PRUint32 count,i;
PRUnichar **words;
if(!aWordList || !mPersonalDictionary)
return NS_ERROR_NULL_POINTER;
mPersonalDictionary->GetWordList(&words,&count);
for(i=0;i<count;i++){
temp.Assign(words[i]);
aWordList->AppendString(temp);
}
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, words);
return NS_OK;
}
NS_IMETHODIMP
mozSpellChecker::GetDictionaryList(nsStringArray *aDictionaryList)
{
nsAutoString temp;
PRUint32 count,i;
PRUnichar **words;
if(!aDictionaryList || !mSpellCheckingEngine)
return NS_ERROR_NULL_POINTER;
mSpellCheckingEngine->GetDictionaryList(&words,&count);
for(i=0;i<count;i++){
temp.Assign(words[i]);
aDictionaryList->AppendString(temp);
}
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, words);
return NS_OK;
}
NS_IMETHODIMP
mozSpellChecker::GetCurrentDictionary(nsString *aDictionary)
{
NS_ENSURE_ARG_POINTER(aDictionary);
nsXPIDLString dictname;
nsresult res;
res=mSpellCheckingEngine->GetDictionary(getter_Copies(dictname));
if(NS_SUCCEEDED(res))
*aDictionary = dictname;
return NS_OK;
}
NS_IMETHODIMP
mozSpellChecker::SetCurrentDictionary(const nsString *aDictionary)
{
NS_ENSURE_ARG_POINTER(aDictionary);
if(!mSpellCheckingEngine)
return NS_ERROR_NULL_POINTER;
nsresult res;
res = mSpellCheckingEngine->SetDictionary(aDictionary->get());
if(NS_FAILED(res)){
NS_WARNING("Dictionary load failed");
return res;
}
nsXPIDLString language;
nsCOMPtr<mozISpellI18NManager> serv(do_GetService("@mozilla.org/spellchecker/i18nmanager;1", &res));
if(serv && NS_SUCCEEDED(res)){
res = serv->GetUtil(language.get(),getter_AddRefs(mConverter));
}
return res;
}
nsresult
mozSpellChecker::SetupDoc(PRUint32 *outBlockOffset)
{
nsresult rv;
nsITextServicesDocument::TSDBlockSelectionStatus blockStatus;
PRInt32 selOffset;
PRInt32 selLength;
*outBlockOffset = 0;
if (!mFromStart)
{
rv = mTsDoc->LastSelectedBlock(&blockStatus, &selOffset, &selLength);
if (NS_SUCCEEDED(rv) && (blockStatus != nsITextServicesDocument::eBlockNotFound))
{
switch (blockStatus)
{
case nsITextServicesDocument::eBlockOutside: // No TB in S, but found one before/after S.
case nsITextServicesDocument::eBlockPartial: // S begins or ends in TB but extends outside of TB.
// the TS doc points to the block we want.
*outBlockOffset = selOffset + selLength;
break;
case nsITextServicesDocument::eBlockInside: // S extends beyond the start and end of TB.
// we want the block after this one.
rv = mTsDoc->NextBlock();
*outBlockOffset = 0;
break;
case nsITextServicesDocument::eBlockContains: // TB contains entire S.
*outBlockOffset = selOffset + selLength;
break;
case nsITextServicesDocument::eBlockNotFound: // There is no text block (TB) in or before the selection (S).
default:
NS_NOTREACHED("Shouldn't ever get this status");
}
}
else //failed to get last sel block. Just start at beginning
{
rv = mTsDoc->FirstBlock();
*outBlockOffset = 0;
}
}
else // we want the first block
{
rv = mTsDoc->FirstBlock();
mFromStart = PR_FALSE;
}
return rv;
}
// utility method to discover which block we're in. The TSDoc interface doesn't give
// us this, because it can't assume a read-only document.
// shamelessly stolen from nsTextServicesDocument
nsresult
mozSpellChecker::GetCurrentBlockIndex(nsITextServicesDocument *aDoc, PRInt32 *outBlockIndex)
{
PRInt32 blockIndex = 0;
PRBool isDone = PR_FALSE;
nsresult result = NS_OK;
do
{
aDoc->PrevBlock();
result = aDoc->IsDone(&isDone);
if (!isDone)
blockIndex ++;
} while (NS_SUCCEEDED(result) && !isDone);
*outBlockIndex = blockIndex;
return result;
}

View File

@ -0,0 +1,86 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein Deinst@world.std.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 mozSpellChecker_h__
#define mozSpellChecker_h__
#include "nsCOMPtr.h"
#include "nsISpellChecker.h"
#include "nsString.h"
#include "nsITextServicesDocument.h"
#include "mozIPersonalDictionary.h"
#include "mozISpellCheckingEngine.h"
#include "nsVoidArray.h"
#include "mozISpellI18NUtil.h"
class mozSpellChecker : public nsISpellChecker
{
public:
NS_DECL_ISUPPORTS
mozSpellChecker();
virtual ~mozSpellChecker();
// nsISpellChecker
NS_IMETHOD SetDocument(nsITextServicesDocument *aDoc, PRBool aFromStartofDoc);
NS_IMETHOD NextMisspelledWord(nsString *aWord, nsStringArray *aSuggestions);
NS_IMETHOD CheckWord(const nsString *aWord, PRBool *aIsMisspelled, nsStringArray *aSuggestions);
NS_IMETHOD Replace(const nsString *aOldWord, const nsString *aNewWord, PRBool aAllOccurrences);
NS_IMETHOD IgnoreAll(const nsString *aWord);
NS_IMETHOD AddWordToPersonalDictionary(const nsString *aWord);
NS_IMETHOD RemoveWordFromPersonalDictionary(const nsString *aWord);
NS_IMETHOD GetPersonalDictionary(nsStringArray *aWordList);
NS_IMETHOD GetDictionaryList(nsStringArray *aDictionaryList);
NS_IMETHOD GetCurrentDictionary(nsString *aDictionary);
NS_IMETHOD SetCurrentDictionary(const nsString *aDictionary);
protected:
nsCOMPtr<mozISpellI18NUtil> mConverter;
nsCOMPtr<nsITextServicesDocument> mTsDoc;
nsCOMPtr<mozIPersonalDictionary> mPersonalDictionary;
nsString mDictionaryName;
nsCOMPtr<mozISpellCheckingEngine> mSpellCheckingEngine;
PRBool mFromStart;
nsStringArray mIgnoreList;
nsresult SetupDoc(PRUint32 *outBlockOffset);
nsresult GetCurrentBlockIndex(nsITextServicesDocument *aDoc, PRInt32 *outBlockIndex);
};
#endif // mozSpellChecker_h__

View File

@ -0,0 +1,76 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein <Deinst@world.std.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 "nsIGenericFactory.h"
#include "mozSpellChecker.h"
#include "nsTextServicesCID.h"
#include "mozPersonalDictionary.h"
#include "mozSpellI18NManager.h"
#define NS_SPELLCHECKER_CID \
{ /* 8227f019-afc7-461e-b030-9f185d7a0e29 */ \
0x8227F019, 0xAFC7, 0x461e, \
{ 0xB0, 0x30, 0x9F, 0x18, 0x5D, 0x7A, 0x0E, 0x29} }
////////////////////////////////////////////////////////////////////////
// Define the contructor function for the objects
//
// NOTE: This creates an instance of objects by using the default constructor
//
NS_GENERIC_FACTORY_CONSTRUCTOR(mozSpellChecker)
NS_GENERIC_FACTORY_CONSTRUCTOR(mozPersonalDictionary)
NS_GENERIC_FACTORY_CONSTRUCTOR(mozSpellI18NManager)
////////////////////////////////////////////////////////////////////////
// Define a table of CIDs implemented by this module along with other
// information like the function to create an instance, contractid, and
// class name.
//
static nsModuleComponentInfo components[] = {
{ NULL, NS_SPELLCHECKER_CID, NS_SPELLCHECKER_CONTRACTID, mozSpellCheckerConstructor },
{ NULL, MOZ_PERSONALDICTIONARY_CID, MOZ_PERSONALDICTIONARY_CONTRACTID, mozPersonalDictionaryConstructor },
{ NULL, MOZ_SPELLI18NMANAGER_CID, MOZ_SPELLI18NMANAGER_CONTRACTID, mozSpellI18NManagerConstructor }
};
////////////////////////////////////////////////////////////////////////
// Implement the NSGetModule() exported function for your module
// and the entire implementation of the module object.
//
NS_IMPL_NSGETMODULE(mozSpellCheckerModule, components)

View File

@ -0,0 +1,74 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein Deinst@world.std.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 "mozSpellI18NManager.h"
#include "mozEnglishWordUtils.h"
#include "mozGenericWordUtils.h"
#include "nsString.h"
NS_IMPL_ISUPPORTS1(mozSpellI18NManager, mozISpellI18NManager)
mozSpellI18NManager::mozSpellI18NManager()
{
NS_INIT_ISUPPORTS();
/* member initializers and constructor code */
}
mozSpellI18NManager::~mozSpellI18NManager()
{
/* destructor code */
}
/* mozISpellI18NUtil GetUtil (in wstring language); */
NS_IMETHODIMP mozSpellI18NManager::GetUtil(const PRUnichar *aLanguage, mozISpellI18NUtil **_retval)
{
if( NULL == _retval) {
return NS_ERROR_NULL_POINTER;
}
*_retval = NULL;
nsAutoString lang;
lang.Assign(aLanguage);
if(lang.EqualsWithConversion("en")){
*_retval = new mozEnglishWordUtils;
}
else{
*_retval = new mozEnglishWordUtils;
}
NS_IF_ADDREF(*_retval);
return NS_OK;
}

View File

@ -0,0 +1,61 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** 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 Original Code is Mozilla Spellchecker Component.
*
* The Initial Developer of the Original Code is
* David Einstein.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): David Einstein Deinst@world.std.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 mozSpellI18NManager_h__
#define mozSpellI18NManager_h__
#include "nsCOMPtr.h"
#include "mozISpellI18NManager.h"
#define MOZ_SPELLI18NMANAGER_CONTRACTID "@mozilla.org/spellchecker/i18nmanager;1"
#define MOZ_SPELLI18NMANAGER_CID \
{ /* {F30F3CC0-840F-4a83-AC0E-FD343D3A44A0} */ \
0xf30f3cc0, 0x840f, 0x4a83, \
{ 0xac, 0xe, 0xfd, 0x34, 0x3d, 0x3a, 0x44, 0xa0} }
class mozSpellI18NManager : public mozISpellI18NManager
{
public:
NS_DECL_ISUPPORTS
NS_DECL_MOZISPELLI18NMANAGER
mozSpellI18NManager();
virtual ~mozSpellI18NManager();
};
#endif

View File

@ -0,0 +1,636 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsAVLTree.h"
enum eLean {eLeft,eNeutral,eRight};
struct nsAVLNode {
public:
nsAVLNode(void* aValue) {
mLeft=0;
mRight=0;
mSkew=eNeutral;
mValue=aValue;
}
nsAVLNode* mLeft;
nsAVLNode* mRight;
eLean mSkew;
void* mValue;
};
/************************************************************
Now begin the tree class. Don't forget that the comparison
between nodes must occur via the comparitor function,
otherwise all you're testing is pointer addresses.
************************************************************/
/** ------------------------------------------------
*
*
* @update gess 4/22/98
* @param
* @return
*/ //----------------------------------------------
nsAVLTree::nsAVLTree(nsAVLNodeComparitor& aComparitor,
nsAVLNodeFunctor* aDeallocator) :
mComparitor(aComparitor), mDeallocator(aDeallocator) {
mRoot=0;
mCount=0;
}
static void
avlDeleteTree(nsAVLNode* aNode){
if (aNode) {
avlDeleteTree(aNode->mLeft);
avlDeleteTree(aNode->mRight);
delete aNode;
}
}
/**
*
* @update gess12/27/98
* @param
* @return
*/
nsAVLTree::~nsAVLTree(){
if (mDeallocator) {
ForEachDepthFirst(*mDeallocator);
}
avlDeleteTree(mRoot);
}
class CDoesntExist: public nsAVLNodeFunctor {
public:
CDoesntExist(const nsAVLTree& anotherTree) : mOtherTree(anotherTree) {
}
virtual void* operator()(void* anItem) {
void* result=mOtherTree.FindItem(anItem);
if(result)
return nsnull;
return anItem;
}
protected:
const nsAVLTree& mOtherTree;
};
/**
* This method compares two trees (members by identity).
* @update gess12/27/98
* @param tree to compare against
* @return true if they are identical (contain same stuff).
*/
PRBool nsAVLTree::operator==(const nsAVLTree& aCopy) const{
CDoesntExist functor(aCopy);
void* theItem=FirstThat(functor);
PRBool result=PRBool(!theItem);
return result;
}
/**
*
* @update gess12/27/98
* @param
* @return
*/
static void
avlRotateRight(nsAVLNode*& aRootNode){
nsAVLNode* ptr2;
nsAVLNode* ptr3;
ptr2=aRootNode->mRight;
if(ptr2->mSkew==eRight) {
aRootNode->mRight=ptr2->mLeft;
ptr2->mLeft=aRootNode;
aRootNode->mSkew=eNeutral;
aRootNode=ptr2;
}
else {
ptr3=ptr2->mLeft;
ptr2->mLeft=ptr3->mRight;
ptr3->mRight=ptr2;
aRootNode->mRight=ptr3->mLeft;
ptr3->mLeft=aRootNode;
if(ptr3->mSkew==eLeft)
ptr2->mSkew=eRight;
else ptr2->mSkew=eNeutral;
if(ptr3->mSkew==eRight)
aRootNode->mSkew=eLeft;
else aRootNode->mSkew=eNeutral;
aRootNode=ptr3;
}
aRootNode->mSkew=eNeutral;
return;
}
/**
*
* @update gess12/27/98
* @param
* @return
*/
static void
avlRotateLeft(nsAVLNode*& aRootNode){
nsAVLNode* ptr2;
nsAVLNode* ptr3;
ptr2=aRootNode->mLeft;
if(ptr2->mSkew==eLeft) {
aRootNode->mLeft=ptr2->mRight;
ptr2->mRight=aRootNode;
aRootNode->mSkew=eNeutral;
aRootNode=ptr2;
}
else {
ptr3=ptr2->mRight;
ptr2->mRight=ptr3->mLeft;
ptr3->mLeft=ptr2;
aRootNode->mLeft=ptr3->mRight;
ptr3->mRight=aRootNode;
if(ptr3->mSkew==eRight)
ptr2->mSkew=eLeft;
else ptr2->mSkew=eNeutral;
if(ptr3->mSkew==eLeft)
aRootNode->mSkew=eRight;
else aRootNode->mSkew=eNeutral;
aRootNode=ptr3;
}
aRootNode->mSkew=eNeutral;
return;
}
/** ------------------------------------------------
*
*
* @update gess 4/22/98
* @param
* @return
*/ //----------------------------------------------
static eAVLStatus
avlInsert(nsAVLNode*& aRootNode, nsAVLNode* aNewNode,
nsAVLNodeComparitor& aComparitor) {
eAVLStatus result=eAVL_unknown;
if(!aRootNode) {
aRootNode = aNewNode;
return eAVL_ok;
}
if(aNewNode==aRootNode->mValue) {
return eAVL_duplicate;
}
PRInt32 theCompareResult=aComparitor(aRootNode->mValue,aNewNode->mValue);
if(0 < theCompareResult) { //if(anItem<aRootNode->mValue)
result=avlInsert(aRootNode->mLeft,aNewNode,aComparitor);
if(eAVL_ok==result) {
switch(aRootNode->mSkew){
case eLeft:
avlRotateLeft(aRootNode);
result=eAVL_fail;
break;
case eRight:
aRootNode->mSkew=eNeutral;
result=eAVL_fail;
break;
case eNeutral:
aRootNode->mSkew=eLeft;
break;
} //switch
}//if
} //if
else {
result=avlInsert(aRootNode->mRight,aNewNode,aComparitor);
if(eAVL_ok==result) {
switch(aRootNode->mSkew){
case eLeft:
aRootNode->mSkew=eNeutral;
result=eAVL_fail;
break;
case eRight:
avlRotateRight(aRootNode);
result=eAVL_fail;
break;
case eNeutral:
aRootNode->mSkew=eRight;
break;
} //switch
}
} //if
return result;
}
/** ------------------------------------------------
*
*
* @update gess 4/22/98
* @param
* @return
*/ //----------------------------------------------
static void
avlBalanceLeft(nsAVLNode*& aRootNode, PRBool& delOk){
nsAVLNode* ptr2;
nsAVLNode* ptr3;
eLean balnc2;
eLean balnc3;
switch(aRootNode->mSkew){
case eLeft:
ptr2=aRootNode->mLeft;
balnc2=ptr2->mSkew;
if(balnc2!=eRight) {
aRootNode->mLeft=ptr2->mRight;
ptr2->mRight=aRootNode;
if(balnc2==eNeutral){
aRootNode->mSkew=eLeft;
ptr2->mSkew=eRight;
delOk=PR_FALSE;
}
else{
aRootNode->mSkew=eNeutral;
ptr2->mSkew=eNeutral;
}
aRootNode=ptr2;
}
else{
ptr3=ptr2->mRight;
balnc3=ptr3->mSkew;
ptr2->mRight=ptr3->mLeft;
ptr3->mLeft=ptr2;
aRootNode->mLeft=ptr3->mRight;
ptr3->mRight=aRootNode;
if(balnc3==eRight) {
ptr2->mSkew=eLeft;
}
else {
ptr2->mSkew=eNeutral;
}
if(balnc3==eLeft) {
aRootNode->mSkew=eRight;
}
else {
aRootNode->mSkew=eNeutral;
}
aRootNode=ptr3;
ptr3->mSkew=eNeutral;
}
break;
case eRight:
aRootNode->mSkew=eNeutral;
break;
case eNeutral:
aRootNode->mSkew=eLeft;
delOk=PR_FALSE;
break;
}//switch
return;
}
/** ------------------------------------------------
*
*
* @update gess 4/22/98
* @param
* @return
*/ //----------------------------------------------
static void
avlBalanceRight(nsAVLNode*& aRootNode, PRBool& delOk){
nsAVLNode* ptr2;
nsAVLNode* ptr3;
eLean balnc2;
eLean balnc3;
switch(aRootNode->mSkew){
case eLeft:
aRootNode->mSkew=eNeutral;
break;
case eRight:
ptr2=aRootNode->mRight;
balnc2=ptr2->mSkew;
if(balnc2!=eLeft) {
aRootNode->mRight=ptr2->mLeft;
ptr2->mLeft=aRootNode;
if(balnc2==eNeutral){
aRootNode->mSkew=eRight;
ptr2->mSkew=eLeft;
delOk=PR_FALSE;
}
else{
aRootNode->mSkew=eNeutral;
ptr2->mSkew=eNeutral;
}
aRootNode=ptr2;
}
else{
ptr3=ptr2->mLeft;
balnc3=ptr3->mSkew;
ptr2->mLeft=ptr3->mRight;
ptr3->mRight=ptr2;
aRootNode->mRight=ptr3->mLeft;
ptr3->mLeft=aRootNode;
if(balnc3==eLeft) {
ptr2->mSkew=eRight;
}
else {
ptr2->mSkew=eNeutral;
}
if(balnc3==eRight) {
aRootNode->mSkew=eLeft;
}
else {
aRootNode->mSkew=eNeutral;
}
aRootNode=ptr3;
ptr3->mSkew=eNeutral;
}
break;
case eNeutral:
aRootNode->mSkew=eRight;
delOk=PR_FALSE;
break;
}//switch
return;
}
/** ------------------------------------------------
*
*
* @update gess 4/22/98
* @param
* @return
*/ //----------------------------------------------
static eAVLStatus
avlRemoveChildren(nsAVLNode*& aRootNode,nsAVLNode*& anotherNode, PRBool& delOk){
eAVLStatus result=eAVL_ok;
if(!anotherNode->mRight){
aRootNode->mValue=anotherNode->mValue; //swap
anotherNode=anotherNode->mLeft;
delOk=PR_TRUE;
}
else{
avlRemoveChildren(aRootNode,anotherNode->mRight,delOk);
if(delOk)
avlBalanceLeft(anotherNode,delOk);
}
return result;
}
/** ------------------------------------------------
*
*
* @update gess 4/22/98
* @param
* @return
*/ //----------------------------------------------
static eAVLStatus
avlRemove(nsAVLNode*& aRootNode, void* anItem, PRBool& delOk,
nsAVLNodeComparitor& aComparitor){
eAVLStatus result=eAVL_ok;
if(!aRootNode)
delOk=PR_FALSE;
else {
PRInt32 cmp=aComparitor(anItem,aRootNode->mValue);
if(cmp<0){
avlRemove(aRootNode->mLeft,anItem,delOk,aComparitor);
if(delOk)
avlBalanceRight(aRootNode,delOk);
}
else if(cmp>0){
avlRemove(aRootNode->mRight,anItem,delOk,aComparitor);
if(delOk)
avlBalanceLeft(aRootNode,delOk);
}
else{ //they match...
nsAVLNode* temp=aRootNode;
if(!aRootNode->mRight) {
aRootNode=aRootNode->mLeft;
delOk=PR_TRUE;
delete temp;
}
else if(!aRootNode->mLeft) {
aRootNode=aRootNode->mRight;
delOk=PR_TRUE;
delete temp;
}
else {
avlRemoveChildren(aRootNode,aRootNode->mLeft,delOk);
if(delOk)
avlBalanceRight(aRootNode,delOk);
}
}
}
return result;
}
/** ------------------------------------------------
*
*
* @update gess 4/22/98
* @param
* @return
*/ //----------------------------------------------
eAVLStatus
nsAVLTree::AddItem(void* anItem){
eAVLStatus result=eAVL_ok;
nsAVLNode* theNewNode=new nsAVLNode(anItem);
result=avlInsert(mRoot,theNewNode,mComparitor);
if(eAVL_duplicate!=result)
mCount++;
else {
delete theNewNode;
}
return result;
}
/** ------------------------------------------------
*
*
* @update gess 4/22/98
* @param
* @return
*/ //----------------------------------------------
void* nsAVLTree::FindItem(void* aValue) const{
nsAVLNode* result=mRoot;
PRInt32 count=0;
while(result) {
count++;
PRInt32 cmp=mComparitor(aValue,result->mValue);
if(0==cmp) {
//we matched...
break;
}
else if(0>cmp){
//theNode was greater...
result=result->mLeft;
}
else {
//aValue is greater...
result=result->mRight;
}
}
if(result) {
return result->mValue;
}
return nsnull;
}
/**
*
* @update gess12/30/98
* @param
* @return
*/
eAVLStatus
nsAVLTree::RemoveItem(void* aValue){
PRBool delOk=PR_TRUE;
eAVLStatus result=avlRemove(mRoot,aValue,delOk,mComparitor);
if(eAVL_ok==result)
mCount--;
return result;
}
/**
*
* @update gess9/11/98
* @param
* @return
*/
static void
avlForEachDepthFirst(nsAVLNode* aNode, nsAVLNodeFunctor& aFunctor){
if(aNode) {
avlForEachDepthFirst(aNode->mLeft,aFunctor);
avlForEachDepthFirst(aNode->mRight,aFunctor);
aFunctor(aNode->mValue);
}
}
/**
*
* @update gess9/11/98
* @param
* @return
*/
void
nsAVLTree::ForEachDepthFirst(nsAVLNodeFunctor& aFunctor) const{
::avlForEachDepthFirst(mRoot,aFunctor);
}
/**
*
* @update gess9/11/98
* @param
* @return
*/
static void
avlForEach(nsAVLNode* aNode, nsAVLNodeFunctor& aFunctor) {
if(aNode) {
avlForEach(aNode->mLeft,aFunctor);
aFunctor(aNode->mValue);
avlForEach(aNode->mRight,aFunctor);
}
}
/**
*
* @update gess9/11/98
* @param
* @return
*/
void
nsAVLTree::ForEach(nsAVLNodeFunctor& aFunctor) const{
::avlForEach(mRoot,aFunctor);
}
/**
*
* @update gess9/11/98
* @param
* @return
*/
static void*
avlFirstThat(nsAVLNode* aNode, nsAVLNodeFunctor& aFunctor) {
void* result=nsnull;
if(aNode) {
result = avlFirstThat(aNode->mLeft,aFunctor);
if (result) {
return result;
}
result = aFunctor(aNode->mValue);
if (result) {
return result;
}
result = avlFirstThat(aNode->mRight,aFunctor);
}
return result;
}
/**
*
* @update gess9/11/98
* @param
* @return
*/
void*
nsAVLTree::FirstThat(nsAVLNodeFunctor& aFunctor) const{
return ::avlFirstThat(mRoot,aFunctor);
}

View File

@ -0,0 +1,93 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. 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 NPL, 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 NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsAVLTree_h___
#define nsAVLTree_h___
#include "nscore.h"
enum eAVLStatus {eAVL_unknown,eAVL_ok,eAVL_fail,eAVL_duplicate};
struct nsAVLNode;
/**
*
* @update gess12/26/98
* @param anObject1 is the first object to be compared
* @param anObject2 is the second object to be compared
* @return -1,0,1 if object1 is less, equal, greater than object2
*/
class nsAVLNodeComparitor {
public:
virtual PRInt32 operator()(void* anItem1,void* anItem2)=0;
};
class nsAVLNodeFunctor {
public:
virtual void* operator()(void* anItem)=0;
};
class nsAVLTree {
public:
nsAVLTree(nsAVLNodeComparitor& aComparitor, nsAVLNodeFunctor* aDeallocator);
~nsAVLTree(void);
PRBool operator==(const nsAVLTree& aOther) const;
PRInt32 GetCount(void) const {return mCount;}
//main functions...
eAVLStatus AddItem(void* anItem);
eAVLStatus RemoveItem(void* anItem);
void* FindItem(void* anItem) const;
void ForEach(nsAVLNodeFunctor& aFunctor) const;
void ForEachDepthFirst(nsAVLNodeFunctor& aFunctor) const;
void* FirstThat(nsAVLNodeFunctor& aFunctor) const;
protected:
nsAVLNode* mRoot;
PRInt32 mCount;
nsAVLNodeComparitor& mComparitor;
nsAVLNodeFunctor* mDeallocator;
};
#endif /* nsAVLTree_h___ */