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