Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(385)

Side by Side Diff: chrome/renderer/spellchecker/hunspell_engine.cc

Issue 11445002: Sync user's custom spellcheck dictionary (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Add server-side size limit tests Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <algorithm>
8 #include <iterator>
9
7 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
8 #include "base/time.h" 11 #include "base/time.h"
9 #include "chrome/common/spellcheck_common.h" 12 #include "chrome/common/spellcheck_common.h"
10 #include "chrome/common/spellcheck_messages.h" 13 #include "chrome/common/spellcheck_messages.h"
11 #include "content/public/renderer/render_thread.h" 14 #include "content/public/renderer/render_thread.h"
12 #include "third_party/hunspell/src/hunspell/hunspell.hxx" 15 #include "third_party/hunspell/src/hunspell/hunspell.hxx"
13 16
14 using base::TimeTicks; 17 using base::TimeTicks;
15 using content::RenderThread; 18 using content::RenderThread;
16 19
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 52
50 bdict_file_.reset(new file_util::MemoryMappedFile); 53 bdict_file_.reset(new file_util::MemoryMappedFile);
51 54
52 if (bdict_file_->Initialize(file_)) { 55 if (bdict_file_->Initialize(file_)) {
53 TimeTicks debug_start_time = base::Histogram::DebugNow(); 56 TimeTicks debug_start_time = base::Histogram::DebugNow();
54 57
55 hunspell_.reset( 58 hunspell_.reset(
56 new Hunspell(bdict_file_->data(), bdict_file_->length())); 59 new Hunspell(bdict_file_->data(), bdict_file_->length()));
57 60
58 // Add custom words to Hunspell. 61 // Add custom words to Hunspell.
59 chrome::spellcheck_common::WordList::iterator it; 62 AddWordsToHunspell(custom_words_);
60 for (it = custom_words_.begin(); it != custom_words_.end(); ++it)
61 AddWordToHunspell(*it);
62 63
63 DHISTOGRAM_TIMES("Spellcheck.InitTime", 64 DHISTOGRAM_TIMES("Spellcheck.InitTime",
64 base::Histogram::DebugNow() - debug_start_time); 65 base::Histogram::DebugNow() - debug_start_time);
65 } else { 66 } else {
66 NOTREACHED() << "Could not mmap spellchecker dictionary."; 67 NOTREACHED() << "Could not mmap spellchecker dictionary.";
67 } 68 }
68 } 69 }
69 70
70 void HunspellEngine::AddWordToHunspell(const std::string& word) { 71 void HunspellEngine::AddWordsToHunspell(const std::vector<std::string>& words) {
71 if (!word.empty() && word.length() < MAXWORDLEN) 72 std::string word;
72 hunspell_->add(word.c_str()); 73 for (chrome::spellcheck_common::WordList::const_iterator it = words.begin();
74 it != words.end();
75 ++it) {
76 word = *it;
77 if (!word.empty() && word.length() < MAXWORDLEN)
78 hunspell_->add(word.c_str());
79 }
73 } 80 }
74 81
75 void HunspellEngine::RemoveWordFromHunspell(const std::string& word) { 82 void HunspellEngine::RemoveWordsFromHunspell(
76 if (!word.empty() && word.length() < MAXWORDLEN) 83 const std::vector<std::string>& words) {
77 hunspell_->remove(word.c_str()); 84 std::string word;
85 for (std::vector<std::string>::const_iterator it = words.begin();
86 it != words.end();
87 ++it) {
88 word = *it;
89 if (!word.empty() && word.length() < MAXWORDLEN)
90 hunspell_->remove(word.c_str());
91 }
78 } 92 }
79 93
80 bool HunspellEngine::CheckSpelling(const string16& word_to_check, int tag) { 94 bool HunspellEngine::CheckSpelling(const string16& word_to_check, int tag) {
81 bool word_correct = false; 95 bool word_correct = false;
82 std::string word_to_check_utf8(UTF16ToUTF8(word_to_check)); 96 std::string word_to_check_utf8(UTF16ToUTF8(word_to_check));
83 // Hunspell shouldn't let us exceed its max, but check just in case 97 // Hunspell shouldn't let us exceed its max, but check just in case
84 if (word_to_check_utf8.length() < MAXWORDLEN) { 98 if (word_to_check_utf8.length() < MAXWORDLEN) {
85 if (hunspell_.get()) { 99 if (hunspell_.get()) {
86 // |hunspell_->spell| returns 0 if the word is spelled correctly and 100 // |hunspell_->spell| returns 0 if the word is spelled correctly and
87 // non-zero otherwsie. 101 // non-zero otherwise.
88 word_correct = (hunspell_->spell(word_to_check_utf8.c_str()) != 0); 102 word_correct = (hunspell_->spell(word_to_check_utf8.c_str()) != 0);
89 } else { 103 } else {
90 // If |hunspell_| is NULL here, an error has occurred, but it's better 104 // If |hunspell_| is NULL here, an error has occurred, but it's better
91 // to check rather than crash. 105 // to check rather than crash.
92 word_correct = true; 106 word_correct = true;
93 } 107 }
94 } 108 }
95 109
96 return word_correct; 110 return word_correct;
97 } 111 }
(...skipping 14 matching lines...) Expand all
112 // Populate the vector of WideStrings. 126 // Populate the vector of WideStrings.
113 for (int i = 0; i < number_of_suggestions; ++i) { 127 for (int i = 0; i < number_of_suggestions; ++i) {
114 if (i < chrome::spellcheck_common::kMaxSuggestions) 128 if (i < chrome::spellcheck_common::kMaxSuggestions)
115 optional_suggestions->push_back(UTF8ToUTF16(suggestions[i])); 129 optional_suggestions->push_back(UTF8ToUTF16(suggestions[i]));
116 free(suggestions[i]); 130 free(suggestions[i]);
117 } 131 }
118 if (suggestions != NULL) 132 if (suggestions != NULL)
119 free(suggestions); 133 free(suggestions);
120 } 134 }
121 135
122 void HunspellEngine::OnWordAdded(const std::string& word) { 136 void HunspellEngine::OnWordsAddedRemoved(
137 const std::vector<std::string>& words_added,
138 const std::vector<std::string>& words_removed) {
123 if (!hunspell_.get()) { 139 if (!hunspell_.get()) {
124 // Save it for later---add it when hunspell is initialized. 140 // Save it for later---add it when hunspell is initialized.
125 custom_words_.push_back(word); 141 custom_words_.insert(custom_words_.end(),
142 words_added.begin(),
143 words_added.end());
144 // Remove words.
145 std::vector<std::string> words_removed_copy(words_removed);
146 std::sort(words_removed_copy.begin(), words_removed_copy.end());
147 std::sort(custom_words_.begin(), custom_words_.end());
148 std::vector<std::string> updated_custom_words;
149 std::set_difference(custom_words_.begin(),
150 custom_words_.end(),
151 words_removed_copy.begin(),
152 words_removed_copy.end(),
153 std::back_inserter(updated_custom_words));
154 std::swap(custom_words_, updated_custom_words);
126 } else { 155 } else {
127 AddWordToHunspell(word); 156 AddWordsToHunspell(words_added);
157 RemoveWordsFromHunspell(words_removed);
128 } 158 }
129 } 159 }
130 160
131 void HunspellEngine::OnWordRemoved(const std::string& word) {
132 if (!hunspell_.get()) {
133 chrome::spellcheck_common::WordList::iterator it = std::find(
134 custom_words_.begin(), custom_words_.end(), word);
135 if (it != custom_words_.end())
136 custom_words_.erase(it);
137 } else {
138 RemoveWordFromHunspell(word);
139 }
140 }
141
142 bool HunspellEngine::InitializeIfNeeded() { 161 bool HunspellEngine::InitializeIfNeeded() {
143 if (!initialized_ && !dictionary_requested_) { 162 if (!initialized_ && !dictionary_requested_) {
144 // RenderThread will not exist in test. 163 // RenderThread will not exist in test.
145 if (RenderThread::Get()) 164 if (RenderThread::Get())
146 RenderThread::Get()->Send(new SpellCheckHostMsg_RequestDictionary); 165 RenderThread::Get()->Send(new SpellCheckHostMsg_RequestDictionary);
147 dictionary_requested_ = true; 166 dictionary_requested_ = true;
148 return true; 167 return true;
149 } 168 }
150 169
151 // Don't initialize if hunspell is disabled. 170 // Don't initialize if hunspell is disabled.
152 if (file_ != base::kInvalidPlatformFileValue) 171 if (file_ != base::kInvalidPlatformFileValue)
153 InitializeHunspell(); 172 InitializeHunspell();
154 173
155 return !initialized_; 174 return !initialized_;
156 } 175 }
157 176
158 bool HunspellEngine::IsEnabled() { 177 bool HunspellEngine::IsEnabled() {
159 return file_ != base::kInvalidPlatformFileValue; 178 return file_ != base::kInvalidPlatformFileValue;
160 } 179 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698