1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /* enchant
3  * Copyright (C) 2003 Dom Lachowicz
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02110-1301, USA.
19  *
20  * In addition, as a special exception, Dom Lachowicz
21  * gives permission to link the code of this program with
22  * non-LGPL Spelling Provider libraries (eg: a MSFT Office
23  * spell checker backend) and distribute linked combinations including
24  * the two.  You must obey the GNU Lesser General Public License in all
25  * respects for all of the code used other than said providers.  If you modify
26  * this file, you may extend this exception to your version of the
27  * file, but you are not obligated to do so.  If you do not wish to
28  * do so, delete this exception statement from your version.
29  */
30 
31 #ifndef ENCHANT_PLUS_PLUS_H
32 #define ENCHANT_PLUS_PLUS_H
33 
34 #include <enchant.h>
35 #include <string>
36 #include <vector>
37 #include <exception>
38 
39 namespace enchant
40 {
41 	class Broker;
42 
43 	class Exception : public std::exception
44 		{
45 		public:
Exception(const char * ex)46 			explicit Exception (const char * ex)
47 				: std::exception (), m_ex ("") {
48 				if (ex)
49 					m_ex = ex;
50 			}
51 
~Exception()52 			virtual ~Exception () throw() {
53 			}
54 
what()55 			virtual const char * what () throw() {
56 				return m_ex.c_str();
57 			}
58 
59 		private:
60 			Exception ();
61 
62 			std::string m_ex;
63 		};
64 
65 	class Dict
66 		{
67 			friend class enchant::Broker;
68 
69 		public:
70 
~Dict()71 			~Dict () {
72 				enchant_broker_free_dict (m_broker, m_dict);
73 			}
74 
check(const std::string & utf8word)75 			bool check (const std::string & utf8word) {
76 				int val;
77 
78 				val = enchant_dict_check (m_dict, utf8word.c_str(),
79 							  utf8word.size());
80 				if (val == 0)
81 					return true;
82 				else if (val > 0)
83 					return false;
84 				else {
85 					throw enchant::Exception (enchant_dict_get_error (m_dict));
86 				}
87 
88 				return false; // never reached
89 			}
90 
suggest(const std::string & utf8word,std::vector<std::string> & out_suggestions)91 			void suggest (const std::string & utf8word,
92 				      std::vector<std::string> & out_suggestions) {
93 				size_t n_suggs;
94 				char ** suggs;
95 
96 				out_suggestions.clear ();
97 
98 				suggs = enchant_dict_suggest (m_dict, utf8word.c_str(),
99 							      utf8word.size(), &n_suggs);
100 
101 				if (suggs && n_suggs) {
102 					for (size_t i = 0; i < n_suggs; i++) {
103 						out_suggestions.push_back (suggs[i]);
104 					}
105 
106 					enchant_dict_free_string_list (m_dict, suggs);
107 				}
108 			}
109 
suggest(const std::string & utf8word)110 			std::vector<std::string> suggest (const std::string & utf8word) {
111 				std::vector<std::string> result;
112 				suggest (utf8word, result);
113 				return result;
114 			}
115 
add(const std::string & utf8word)116 			void add (const std::string & utf8word) {
117 				enchant_dict_add (m_dict, utf8word.c_str(),
118 							 utf8word.size());
119 			}
120 
add_to_session(const std::string & utf8word)121 			void add_to_session (const std::string & utf8word) {
122 				enchant_dict_add_to_session (m_dict, utf8word.c_str(),
123 							     utf8word.size());
124 			}
125 
is_added(const std::string & utf8word)126 			void is_added (const std::string & utf8word) {
127 				enchant_dict_is_added (m_dict, utf8word.c_str(),
128 							     utf8word.size());
129 			}
130 
remove(const std::string & utf8word)131 			void remove (const std::string & utf8word) {
132 				enchant_dict_remove (m_dict, utf8word.c_str(),
133 							 utf8word.size());
134 			}
135 
remove_from_session(const std::string & utf8word)136 			void remove_from_session (const std::string & utf8word) {
137 				enchant_dict_remove_from_session (m_dict, utf8word.c_str(),
138 							     utf8word.size());
139 			}
140 
is_removed(const std::string & utf8word)141 			void is_removed (const std::string & utf8word) {
142 				enchant_dict_is_removed (m_dict, utf8word.c_str(),
143 							     utf8word.size());
144 			}
145 
store_replacement(const std::string & utf8bad,const std::string & utf8good)146 			void store_replacement (const std::string & utf8bad,
147 						const std::string & utf8good) {
148 				enchant_dict_store_replacement (m_dict,
149 								utf8bad.c_str(), utf8bad.size(),
150 								utf8good.c_str(), utf8good.size());
151 			}
152 
get_lang()153 			const std::string & get_lang () const {
154 				return m_lang;
155 			}
156 
get_provider_name()157 			const std::string & get_provider_name () const {
158 				return m_provider_name;
159 			}
160 
get_provider_desc()161 			const std::string & get_provider_desc () const {
162 				return m_provider_desc;
163 			}
164 
get_provider_file()165 			const std::string & get_provider_file () const {
166 				return m_provider_file;
167 			}
168 
169 			/* deprecated */
add_to_personal(const std::string & utf8word)170 			void add_to_personal (const std::string & utf8word) {
171 				return add (utf8word);
172 			}
173 
174 			/* deprecated */
add_to_pwl(const std::string & utf8word)175 			void add_to_pwl (const std::string & utf8word) {
176 				return add (utf8word);
177 			}
178 		private:
179 
180 			// space reserved for API/ABI expansion
181 			void * _private[5];
182 
s_describe_fn(const char * const lang,const char * const provider_name,const char * const provider_desc,const char * const provider_file,void * user_data)183 			static void s_describe_fn (const char * const lang,
184 						   const char * const provider_name,
185 						   const char * const provider_desc,
186 						   const char * const provider_file,
187 						   void * user_data) {
188 				enchant::Dict * dict = static_cast<enchant::Dict *> (user_data);
189 
190 				dict->m_lang = lang;
191 				dict->m_provider_name = provider_name;
192 				dict->m_provider_desc = provider_desc;
193 				dict->m_provider_file = provider_file;
194 			}
195 
Dict(EnchantDict * dict,EnchantBroker * broker)196 			Dict (EnchantDict * dict, EnchantBroker * broker)
197 				: m_dict (dict), m_broker (broker) {
198 				enchant_dict_describe (m_dict, s_describe_fn, this);
199 			}
200 
201 			// private, unimplemented
202 			Dict ();
203 			Dict (const Dict & rhs);
204 			Dict& operator=(const Dict & rhs);
205 
206 			EnchantDict * m_dict;
207 			EnchantBroker * m_broker;
208 
209 			std::string m_lang;
210 			std::string m_provider_name;
211 			std::string m_provider_desc;
212 			std::string m_provider_file;
213 		}; // class enchant::Dict
214 
215 	class Broker
216 		{
217 
218 		public:
219 
instance()220 			static Broker * instance () {
221 				return &m_instance;
222 			}
223 
request_dict(const std::string & lang)224 			Dict * request_dict (const std::string & lang) {
225 				EnchantDict * dict = enchant_broker_request_dict (m_broker, lang.c_str());
226 
227 				if (!dict) {
228 					throw enchant::Exception (enchant_broker_get_error (m_broker));
229 					return 0; // never reached
230 				}
231 
232 				return new Dict (dict, m_broker);
233 			}
234 
request_pwl_dict(const std::string & pwl)235 			Dict * request_pwl_dict (const std::string & pwl) {
236 				EnchantDict * dict = enchant_broker_request_pwl_dict (m_broker, pwl.c_str());
237 
238 				if (!dict) {
239 					throw enchant::Exception (enchant_broker_get_error (m_broker));
240 					return 0; // never reached
241 				}
242 
243 				return new Dict (dict, m_broker);
244 			}
245 
dict_exists(const std::string & lang)246 			bool dict_exists (const std::string & lang) {
247 				if (enchant_broker_dict_exists (m_broker, lang.c_str()))
248 					return true;
249 				return false;
250 			}
251 
set_ordering(const std::string & tag,const std::string & ordering)252 			void set_ordering (const std::string & tag, const std::string & ordering) {
253 				enchant_broker_set_ordering (m_broker, tag.c_str(), ordering.c_str());
254 			}
255 
256 			void describe (EnchantBrokerDescribeFn fn, void * user_data = NULL) {
257 				enchant_broker_describe (m_broker, fn, user_data);
258 			}
259 
260 			void list_dicts (EnchantDictDescribeFn fn, void * user_data = NULL) {
261 				enchant_broker_list_dicts (m_broker, fn, user_data);
262 			}
263 
264 		private:
265 
266 			// space reserved for API/ABI expansion
267 			void * _private[5];
268 
Broker()269 			Broker ()
270 				: m_broker (enchant_broker_init ())
271 				{
272 				}
273 
~Broker()274 			~Broker () {
275 				enchant_broker_free (m_broker);
276 			}
277 
278 			// not implemented
279 			Broker (const Broker & rhs);
280 			Broker& operator=(const Broker & rhs);
281 
282 			static Broker m_instance;
283 
284 			EnchantBroker * m_broker;
285 		}; // class enchant::Broker
286 
287 	// define the broker instance
288 	Broker Broker::m_instance;
289 
290 } // enchant namespace
291 
292 #endif /* ENCHANT_PLUS_PLUS_H */
293