OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/renderer/spellchecker/spellcheck.h" | 5 #include "chrome/renderer/spellchecker/spellcheck.h" |
6 | 6 |
7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/histogram.h" | 8 #include "base/histogram.h" |
9 #include "base/time.h" | 9 #include "base/time.h" |
10 #include "chrome/common/render_messages.h" | 10 #include "chrome/common/render_messages.h" |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 new Hunspell(bdict_file_->data(), bdict_file_->length())); | 175 new Hunspell(bdict_file_->data(), bdict_file_->length())); |
176 | 176 |
177 // Add custom words to Hunspell. | 177 // Add custom words to Hunspell. |
178 for (std::vector<std::string>::iterator it = custom_words_.begin(); | 178 for (std::vector<std::string>::iterator it = custom_words_.begin(); |
179 it != custom_words_.end(); ++it) { | 179 it != custom_words_.end(); ++it) { |
180 AddWordToHunspell(*it); | 180 AddWordToHunspell(*it); |
181 } | 181 } |
182 | 182 |
183 DHISTOGRAM_TIMES("Spellcheck.InitTime", | 183 DHISTOGRAM_TIMES("Spellcheck.InitTime", |
184 TimeTicks::Now() - start_time); | 184 TimeTicks::Now() - start_time); |
| 185 } else { |
| 186 NOTREACHED() << "Could not mmap spellchecker dictionary."; |
185 } | 187 } |
186 } | 188 } |
187 | 189 |
188 void SpellCheck::AddWordToHunspell(const std::string& word) { | 190 void SpellCheck::AddWordToHunspell(const std::string& word) { |
189 if (!word.empty() && word.length() < MAXWORDUTF8LEN) | 191 if (!word.empty() && word.length() < MAXWORDUTF8LEN) |
190 hunspell_->add(word.c_str()); | 192 hunspell_->add(word.c_str()); |
191 } | 193 } |
192 | 194 |
193 bool SpellCheck::InitializeIfNeeded() { | 195 bool SpellCheck::InitializeIfNeeded() { |
194 if (is_using_platform_spelling_engine_) | 196 if (is_using_platform_spelling_engine_) |
195 return false; | 197 return false; |
196 | 198 |
197 if (!initialized_) { | 199 if (!initialized_) { |
198 RenderThread::current()->Send( | 200 RenderThread::current()->Send( |
199 new ViewHostMsg_SpellChecker_RequestDictionary); | 201 new ViewHostMsg_SpellChecker_RequestDictionary); |
200 initialized_ = true; | 202 initialized_ = true; |
201 return true; | 203 return true; |
202 } | 204 } |
203 | 205 |
204 // Check if the platform spellchecker is being used. | 206 // Don't initialize if hunspell is disabled. |
205 if (file_ != base::kInvalidPlatformFileValue) { | 207 if (file_ != base::kInvalidPlatformFileValue) |
206 // If it isn't, init hunspell. | |
207 InitializeHunspell(); | 208 InitializeHunspell(); |
208 } | |
209 | 209 |
210 return false; | 210 return false; |
211 } | 211 } |
212 | 212 |
213 // When called, relays the request to check the spelling to the proper | 213 // When called, relays the request to check the spelling to the proper |
214 // backend, either hunspell or a platform-specific backend. | 214 // backend, either hunspell or a platform-specific backend. |
215 bool SpellCheck::CheckSpelling(const string16& word_to_check, int tag) { | 215 bool SpellCheck::CheckSpelling(const string16& word_to_check, int tag) { |
216 bool word_correct = false; | 216 bool word_correct = false; |
217 | 217 |
218 if (is_using_platform_spelling_engine_) { | 218 if (is_using_platform_spelling_engine_) { |
219 RenderThread::current()->Send( | 219 RenderThread::current()->Send( |
220 new ViewHostMsg_SpellChecker_PlatformCheckSpelling(word_to_check, tag, | 220 new ViewHostMsg_SpellChecker_PlatformCheckSpelling(word_to_check, tag, |
221 &word_correct)); | 221 &word_correct)); |
222 } else { | 222 } else { |
223 std::string word_to_check_utf8(UTF16ToUTF8(word_to_check)); | 223 std::string word_to_check_utf8(UTF16ToUTF8(word_to_check)); |
224 // Hunspell shouldn't let us exceed its max, but check just in case | 224 // Hunspell shouldn't let us exceed its max, but check just in case |
225 if (word_to_check_utf8.length() < MAXWORDUTF8LEN) { | 225 if (word_to_check_utf8.length() < MAXWORDUTF8LEN) { |
226 // |hunspell_->spell| returns 0 if the word is spelled correctly and | 226 if (hunspell_.get()) { |
227 // non-zero otherwsie. | 227 // |hunspell_->spell| returns 0 if the word is spelled correctly and |
228 word_correct = (hunspell_->spell(word_to_check_utf8.c_str()) != 0); | 228 // non-zero otherwsie. |
| 229 word_correct = (hunspell_->spell(word_to_check_utf8.c_str()) != 0); |
| 230 } else { |
| 231 // If |hunspell_| is NULL here, an error has occurred, but it's better |
| 232 // to check rather than crash. |
| 233 word_correct = true; |
| 234 } |
229 } | 235 } |
230 } | 236 } |
231 | 237 |
232 return word_correct; | 238 return word_correct; |
233 } | 239 } |
234 | 240 |
235 void SpellCheck::FillSuggestionList( | 241 void SpellCheck::FillSuggestionList( |
236 const string16& wrong_word, | 242 const string16& wrong_word, |
237 std::vector<string16>* optional_suggestions) { | 243 std::vector<string16>* optional_suggestions) { |
238 if (is_using_platform_spelling_engine_) { | 244 if (is_using_platform_spelling_engine_) { |
239 RenderThread::current()->Send( | 245 RenderThread::current()->Send( |
240 new ViewHostMsg_SpellChecker_PlatformFillSuggestionList( | 246 new ViewHostMsg_SpellChecker_PlatformFillSuggestionList( |
241 wrong_word, optional_suggestions)); | 247 wrong_word, optional_suggestions)); |
242 return; | 248 return; |
243 } | 249 } |
| 250 |
| 251 // If |hunspell_| is NULL here, an error has occurred, but it's better |
| 252 // to check rather than crash. |
| 253 if (!hunspell_.get()) |
| 254 return; |
| 255 |
244 char** suggestions; | 256 char** suggestions; |
245 int number_of_suggestions = | 257 int number_of_suggestions = |
246 hunspell_->suggest(&suggestions, UTF16ToUTF8(wrong_word).c_str()); | 258 hunspell_->suggest(&suggestions, UTF16ToUTF8(wrong_word).c_str()); |
247 | 259 |
248 // Populate the vector of WideStrings. | 260 // Populate the vector of WideStrings. |
249 for (int i = 0; i < number_of_suggestions; i++) { | 261 for (int i = 0; i < number_of_suggestions; i++) { |
250 if (i < SpellCheckCommon::kMaxSuggestions) | 262 if (i < SpellCheckCommon::kMaxSuggestions) |
251 optional_suggestions->push_back(UTF8ToUTF16(suggestions[i])); | 263 optional_suggestions->push_back(UTF8ToUTF16(suggestions[i])); |
252 free(suggestions[i]); | 264 free(suggestions[i]); |
253 } | 265 } |
(...skipping 12 matching lines...) Expand all Loading... |
266 | 278 |
267 string16 word; | 279 string16 word; |
268 int word_start; | 280 int word_start; |
269 int word_length; | 281 int word_length; |
270 while (word_iterator.GetNextWord(&word, &word_start, &word_length)) { | 282 while (word_iterator.GetNextWord(&word, &word_start, &word_length)) { |
271 if (!CheckSpelling(word, tag)) | 283 if (!CheckSpelling(word, tag)) |
272 return false; | 284 return false; |
273 } | 285 } |
274 return true; | 286 return true; |
275 } | 287 } |
OLD | NEW |