OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "hunspell_engine.h" | 5 #include "hunspell_engine.h" |
6 | 6 |
7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
8 #include "base/time.h" | 8 #include "base/time.h" |
9 #include "chrome/common/spellcheck_common.h" | 9 #include "chrome/common/spellcheck_common.h" |
10 #include "chrome/common/spellcheck_messages.h" | 10 #include "chrome/common/spellcheck_messages.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 | 49 |
50 bdict_file_.reset(new file_util::MemoryMappedFile); | 50 bdict_file_.reset(new file_util::MemoryMappedFile); |
51 | 51 |
52 if (bdict_file_->Initialize(file_)) { | 52 if (bdict_file_->Initialize(file_)) { |
53 TimeTicks debug_start_time = base::Histogram::DebugNow(); | 53 TimeTicks debug_start_time = base::Histogram::DebugNow(); |
54 | 54 |
55 hunspell_.reset( | 55 hunspell_.reset( |
56 new Hunspell(bdict_file_->data(), bdict_file_->length())); | 56 new Hunspell(bdict_file_->data(), bdict_file_->length())); |
57 | 57 |
58 // Add custom words to Hunspell. | 58 // Add custom words to Hunspell. |
59 chrome::spellcheck_common::WordList::iterator it; | 59 AddWordsToHunspell(custom_words_); |
60 for (it = custom_words_.begin(); it != custom_words_.end(); ++it) | |
61 AddWordToHunspell(*it); | |
62 | 60 |
63 DHISTOGRAM_TIMES("Spellcheck.InitTime", | 61 DHISTOGRAM_TIMES("Spellcheck.InitTime", |
64 base::Histogram::DebugNow() - debug_start_time); | 62 base::Histogram::DebugNow() - debug_start_time); |
65 } else { | 63 } else { |
66 NOTREACHED() << "Could not mmap spellchecker dictionary."; | 64 NOTREACHED() << "Could not mmap spellchecker dictionary."; |
67 } | 65 } |
68 } | 66 } |
69 | 67 |
70 void HunspellEngine::AddWordToHunspell(const std::string& word) { | 68 void HunspellEngine::AddWordsToHunspell(const std::vector<std::string>& words) { |
71 if (!word.empty() && word.length() < MAXWORDLEN) | 69 std::string word; |
72 hunspell_->add(word.c_str()); | 70 for (chrome::spellcheck_common::WordList::const_iterator it = words.begin(); |
| 71 it != words.end(); |
| 72 ++it) { |
| 73 word = *it; |
| 74 if (!word.empty() && word.length() < MAXWORDLEN) |
| 75 hunspell_->add(word.c_str()); |
| 76 } |
73 } | 77 } |
74 | 78 |
75 void HunspellEngine::RemoveWordFromHunspell(const std::string& word) { | 79 void HunspellEngine::RemoveWordsFromHunspell( |
76 if (!word.empty() && word.length() < MAXWORDLEN) | 80 const std::vector<std::string>& words) { |
77 hunspell_->remove(word.c_str()); | 81 std::string word; |
| 82 for (std::vector<std::string>::const_iterator it = words.begin(); |
| 83 it != words.end(); |
| 84 ++it) { |
| 85 word = *it; |
| 86 if (!word.empty() && word.length() < MAXWORDLEN) |
| 87 hunspell_->remove(word.c_str()); |
| 88 } |
78 } | 89 } |
79 | 90 |
80 bool HunspellEngine::CheckSpelling(const string16& word_to_check, int tag) { | 91 bool HunspellEngine::CheckSpelling(const string16& word_to_check, int tag) { |
81 bool word_correct = false; | 92 bool word_correct = false; |
82 std::string word_to_check_utf8(UTF16ToUTF8(word_to_check)); | 93 std::string word_to_check_utf8(UTF16ToUTF8(word_to_check)); |
83 // Hunspell shouldn't let us exceed its max, but check just in case | 94 // Hunspell shouldn't let us exceed its max, but check just in case |
84 if (word_to_check_utf8.length() < MAXWORDLEN) { | 95 if (word_to_check_utf8.length() < MAXWORDLEN) { |
85 if (hunspell_.get()) { | 96 if (hunspell_.get()) { |
86 // |hunspell_->spell| returns 0 if the word is spelled correctly and | 97 // |hunspell_->spell| returns 0 if the word is spelled correctly and |
87 // non-zero otherwsie. | 98 // non-zero otherwise. |
88 word_correct = (hunspell_->spell(word_to_check_utf8.c_str()) != 0); | 99 word_correct = (hunspell_->spell(word_to_check_utf8.c_str()) != 0); |
89 } else { | 100 } else { |
90 // If |hunspell_| is NULL here, an error has occurred, but it's better | 101 // If |hunspell_| is NULL here, an error has occurred, but it's better |
91 // to check rather than crash. | 102 // to check rather than crash. |
92 word_correct = true; | 103 word_correct = true; |
93 } | 104 } |
94 } | 105 } |
95 | 106 |
96 return word_correct; | 107 return word_correct; |
97 } | 108 } |
(...skipping 14 matching lines...) Expand all Loading... |
112 // Populate the vector of WideStrings. | 123 // Populate the vector of WideStrings. |
113 for (int i = 0; i < number_of_suggestions; ++i) { | 124 for (int i = 0; i < number_of_suggestions; ++i) { |
114 if (i < chrome::spellcheck_common::kMaxSuggestions) | 125 if (i < chrome::spellcheck_common::kMaxSuggestions) |
115 optional_suggestions->push_back(UTF8ToUTF16(suggestions[i])); | 126 optional_suggestions->push_back(UTF8ToUTF16(suggestions[i])); |
116 free(suggestions[i]); | 127 free(suggestions[i]); |
117 } | 128 } |
118 if (suggestions != NULL) | 129 if (suggestions != NULL) |
119 free(suggestions); | 130 free(suggestions); |
120 } | 131 } |
121 | 132 |
122 void HunspellEngine::OnWordAdded(const std::string& word) { | 133 void HunspellEngine::OnWordsAdded(const std::vector<std::string>& words) { |
123 if (!hunspell_.get()) { | 134 if (!hunspell_.get()) { |
124 // Save it for later---add it when hunspell is initialized. | 135 // Save it for later---add it when hunspell is initialized. |
125 custom_words_.push_back(word); | 136 custom_words_.insert(custom_words_.end(), words.begin(), words.end()); |
126 } else { | 137 } else { |
127 AddWordToHunspell(word); | 138 AddWordsToHunspell(words); |
128 } | 139 } |
129 } | 140 } |
130 | 141 |
131 void HunspellEngine::OnWordRemoved(const std::string& word) { | 142 void HunspellEngine::OnWordsRemoved(const std::vector<std::string>& words) { |
132 if (!hunspell_.get()) { | 143 if (!hunspell_.get()) { |
133 chrome::spellcheck_common::WordList::iterator it = std::find( | 144 std::vector<std::string>::iterator it2; |
134 custom_words_.begin(), custom_words_.end(), word); | 145 for (std::vector<std::string>::const_iterator it = words.begin(); |
135 if (it != custom_words_.end()) | 146 it != words.end(); |
136 custom_words_.erase(it); | 147 ++it) { |
| 148 it2 = std::find(custom_words_.begin(), custom_words_.end(), *it); |
| 149 if (it2 != custom_words_.end()) |
| 150 custom_words_.erase(it2); |
| 151 } |
137 } else { | 152 } else { |
138 RemoveWordFromHunspell(word); | 153 RemoveWordsFromHunspell(words); |
139 } | 154 } |
140 } | 155 } |
141 | 156 |
142 bool HunspellEngine::InitializeIfNeeded() { | 157 bool HunspellEngine::InitializeIfNeeded() { |
143 if (!initialized_ && !dictionary_requested_) { | 158 if (!initialized_ && !dictionary_requested_) { |
144 // RenderThread will not exist in test. | 159 // RenderThread will not exist in test. |
145 if (RenderThread::Get()) | 160 if (RenderThread::Get()) |
146 RenderThread::Get()->Send(new SpellCheckHostMsg_RequestDictionary); | 161 RenderThread::Get()->Send(new SpellCheckHostMsg_RequestDictionary); |
147 dictionary_requested_ = true; | 162 dictionary_requested_ = true; |
148 return true; | 163 return true; |
149 } | 164 } |
150 | 165 |
151 // Don't initialize if hunspell is disabled. | 166 // Don't initialize if hunspell is disabled. |
152 if (file_ != base::kInvalidPlatformFileValue) | 167 if (file_ != base::kInvalidPlatformFileValue) |
153 InitializeHunspell(); | 168 InitializeHunspell(); |
154 | 169 |
155 return !initialized_; | 170 return !initialized_; |
156 } | 171 } |
157 | 172 |
158 bool HunspellEngine::IsEnabled() { | 173 bool HunspellEngine::IsEnabled() { |
159 return file_ != base::kInvalidPlatformFileValue; | 174 return file_ != base::kInvalidPlatformFileValue; |
160 } | 175 } |
OLD | NEW |