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