1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// The |Feedback| object keeps track of each instance of user feedback in a map
// |misspellings_|. This is a map from uint32 hashes to |Misspelling| objects.
//
// Each misspelling should be present in only one renderer process. The
// |Feedback| objects keeps track of misspelling-renderer relationship in the
// |renderers_| map of renderer process identifiers to a set of hashes.
//
// When the user adds a misspelling to their custom dictionary, all of the
// |Misspelling| objects with the same misspelled string are updated. The
// |Feedback| object facilitates efficient access to these misspellings through
// a |text_| map of misspelled strings to a set of hashes.
#include "chrome/browser/spellchecker/feedback.h"
#include <algorithm>
#include <iterator>
#include "base/stl_util.h"
namespace spellcheck {
Feedback::Feedback() {
}
Feedback::~Feedback() {
}
Misspelling* Feedback::GetMisspelling(uint32 hash) {
HashMisspellingMap::iterator misspelling_it = misspellings_.find(hash);
if (misspelling_it == misspellings_.end())
return NULL;
return &misspelling_it->second;
}
void Feedback::FinalizeRemovedMisspellings(
int renderer_process_id,
const std::vector<uint32>& remaining_markers) {
RendererHashesMap::iterator renderer_it =
renderers_.find(renderer_process_id);
if (renderer_it == renderers_.end() || renderer_it->second.empty())
return;
HashCollection& renderer_hashes = renderer_it->second;
HashCollection remaining_hashes(remaining_markers.begin(),
remaining_markers.end());
std::vector<uint32> removed_hashes =
base::STLSetDifference<std::vector<uint32> >(renderer_hashes,
remaining_hashes);
for (std::vector<uint32>::const_iterator hash_it = removed_hashes.begin();
hash_it != removed_hashes.end();
++hash_it) {
HashMisspellingMap::iterator misspelling_it = misspellings_.find(*hash_it);
if (misspelling_it != misspellings_.end() &&
!misspelling_it->second.action.IsFinal()) {
misspelling_it->second.action.Finalize();
}
}
}
bool Feedback::RendererHasMisspellings(int renderer_process_id) const {
RendererHashesMap::const_iterator renderer_it =
renderers_.find(renderer_process_id);
return renderer_it != renderers_.end() && !renderer_it->second.empty();
}
std::vector<Misspelling> Feedback::GetMisspellingsInRenderer(
int renderer_process_id) const {
std::vector<Misspelling> misspellings_in_renderer;
RendererHashesMap::const_iterator renderer_it =
renderers_.find(renderer_process_id);
if (renderer_it == renderers_.end() || renderer_it->second.empty())
return misspellings_in_renderer;
const HashCollection& renderer_hashes = renderer_it->second;
for (HashCollection::const_iterator hash_it = renderer_hashes.begin();
hash_it != renderer_hashes.end();
++hash_it) {
HashMisspellingMap::const_iterator misspelling_it =
misspellings_.find(*hash_it);
if (misspelling_it != misspellings_.end())
misspellings_in_renderer.push_back(misspelling_it->second);
}
return misspellings_in_renderer;
}
void Feedback::EraseFinalizedMisspellings(int renderer_process_id) {
RendererHashesMap::iterator renderer_it =
renderers_.find(renderer_process_id);
if (renderer_it == renderers_.end())
return;
HashCollection& renderer_hashes = renderer_it->second;
for (HashCollection::const_iterator hash_it = renderer_hashes.begin();
hash_it != renderer_hashes.end();) {
HashMisspellingMap::iterator misspelling_it = misspellings_.find(*hash_it);
HashCollection::iterator erasable_hash_it = hash_it;
++hash_it;
if (misspelling_it == misspellings_.end())
continue;
const Misspelling& misspelling = misspelling_it->second;
if (!misspelling.action.IsFinal())
continue;
renderer_hashes.erase(erasable_hash_it);
text_[misspelling.GetMisspelledString()].erase(misspelling.hash);
misspellings_.erase(misspelling_it);
}
if (renderer_hashes.empty())
renderers_.erase(renderer_it);
}
bool Feedback::HasMisspelling(uint32 hash) const {
return !!misspellings_.count(hash);
}
void Feedback::AddMisspelling(int renderer_process_id,
const Misspelling& misspelling) {
HashMisspellingMap::iterator misspelling_it =
misspellings_.find(misspelling.hash);
if (misspelling_it != misspellings_.end()) {
const Misspelling& existing_misspelling = misspelling_it->second;
text_[existing_misspelling.GetMisspelledString()].erase(misspelling.hash);
for (RendererHashesMap::iterator renderer_it = renderers_.begin();
renderer_it != renderers_.end();) {
HashCollection& renderer_hashes = renderer_it->second;
RendererHashesMap::iterator erasable_renderer_it = renderer_it;
++renderer_it;
renderer_hashes.erase(misspelling.hash);
if (renderer_hashes.empty())
renderers_.erase(erasable_renderer_it);
}
}
misspellings_[misspelling.hash] = misspelling;
text_[misspelling.GetMisspelledString()].insert(misspelling.hash);
renderers_[renderer_process_id].insert(misspelling.hash);
}
bool Feedback::Empty() const {
return misspellings_.empty();
}
std::vector<int> Feedback::GetRendersWithMisspellings() const {
std::vector<int> renderers_with_misspellings;
for (RendererHashesMap::const_iterator renderer_it = renderers_.begin();
renderer_it != renderers_.end();
++renderer_it) {
if (!renderer_it->second.empty())
renderers_with_misspellings.push_back(renderer_it->first);
}
return renderers_with_misspellings;
}
void Feedback::FinalizeAllMisspellings() {
for (HashMisspellingMap::iterator misspelling_it = misspellings_.begin();
misspelling_it != misspellings_.end();
++misspelling_it) {
if (!misspelling_it->second.action.IsFinal())
misspelling_it->second.action.Finalize();
}
}
std::vector<Misspelling> Feedback::GetAllMisspellings() const {
std::vector<Misspelling> all_misspellings;
for (HashMisspellingMap::const_iterator misspelling_it =
misspellings_.begin();
misspelling_it != misspellings_.end();
++misspelling_it) {
all_misspellings.push_back(misspelling_it->second);
}
return all_misspellings;
}
void Feedback::Clear() {
misspellings_.clear();
text_.clear();
renderers_.clear();
}
const std::set<uint32>& Feedback::FindMisspellings(
const base::string16& misspelled_text) const {
const TextHashesMap::const_iterator text_it = text_.find(misspelled_text);
return text_it == text_.end() ? empty_hash_collection_ : text_it->second;
}
} // namespace spellcheck
|