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

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

Issue 2159283003: [WIP][DO NOT LAND] Componentize spellcheck Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/renderer/spellchecker/hunspell_engine.h"
6
7 #include <stddef.h>
8 #include <algorithm>
9 #include <iterator>
10 #include <utility>
11
12 #include "base/files/memory_mapped_file.h"
13 #include "base/time/time.h"
14 #include "chrome/common/spellcheck_common.h"
15 #include "chrome/common/spellcheck_messages.h"
16 #include "content/public/renderer/render_thread.h"
17 #include "third_party/hunspell/src/hunspell/hunspell.hxx"
18
19 using content::RenderThread;
20
21 namespace {
22 // Maximum length of words we actually check.
23 // 64 is the observed limits for OSX system checker.
24 const size_t kMaxCheckedLen = 64;
25
26 // Maximum length of words we provide suggestions for.
27 // 24 is the observed limits for OSX system checker.
28 const size_t kMaxSuggestLen = 24;
29
30 static_assert(kMaxCheckedLen <= size_t(MAXWORDLEN),
31 "MaxCheckedLen too long");
32 static_assert(kMaxSuggestLen <= kMaxCheckedLen,
33 "MaxSuggestLen too long");
34 } // namespace
35
36 #if !defined(USE_BROWSER_SPELLCHECKER)
37 SpellingEngine* CreateNativeSpellingEngine() {
38 return new HunspellEngine();
39 }
40 #endif
41
42 HunspellEngine::HunspellEngine()
43 : hunspell_enabled_(false),
44 initialized_(false),
45 dictionary_requested_(false) {
46 // Wait till we check the first word before doing any initializing.
47 }
48
49 HunspellEngine::~HunspellEngine() {
50 }
51
52 void HunspellEngine::Init(base::File file) {
53 initialized_ = true;
54 hunspell_.reset();
55 bdict_file_.reset();
56 file_ = std::move(file);
57 hunspell_enabled_ = file_.IsValid();
58 // Delay the actual initialization of hunspell until it is needed.
59 }
60
61 void HunspellEngine::InitializeHunspell() {
62 if (hunspell_.get())
63 return;
64
65 bdict_file_.reset(new base::MemoryMappedFile);
66
67 if (bdict_file_->Initialize(std::move(file_))) {
68 hunspell_.reset(new Hunspell(bdict_file_->data(), bdict_file_->length()));
69 } else {
70 NOTREACHED() << "Could not mmap spellchecker dictionary.";
71 }
72 }
73
74 bool HunspellEngine::CheckSpelling(const base::string16& word_to_check,
75 int tag) {
76 // Assume all words that cannot be checked are valid. Since Chrome can't
77 // offer suggestions on them, either, there's no point in flagging them to
78 // the user.
79 bool word_correct = true;
80 std::string word_to_check_utf8(base::UTF16ToUTF8(word_to_check));
81
82 // Limit the size of checked words.
83 if (word_to_check_utf8.length() <= kMaxCheckedLen) {
84 // If |hunspell_| is NULL here, an error has occurred, but it's better
85 // to check rather than crash.
86 if (hunspell_.get()) {
87 // |hunspell_->spell| returns 0 if the word is misspelled.
88 word_correct = (hunspell_->spell(word_to_check_utf8.c_str()) != 0);
89 }
90 }
91
92 return word_correct;
93 }
94
95 void HunspellEngine::FillSuggestionList(
96 const base::string16& wrong_word,
97 std::vector<base::string16>* optional_suggestions) {
98 std::string wrong_word_utf8(base::UTF16ToUTF8(wrong_word));
99 if (wrong_word_utf8.length() > kMaxSuggestLen)
100 return;
101
102 // If |hunspell_| is NULL here, an error has occurred, but it's better
103 // to check rather than crash.
104 // TODO(groby): Technically, it's not. We should track down the issue.
105 if (!hunspell_.get())
106 return;
107
108 char** suggestions = NULL;
109 int number_of_suggestions =
110 hunspell_->suggest(&suggestions, wrong_word_utf8.c_str());
111
112 // Populate the vector of WideStrings.
113 for (int i = 0; i < number_of_suggestions; ++i) {
114 if (i < chrome::spellcheck_common::kMaxSuggestions)
115 optional_suggestions->push_back(base::UTF8ToUTF16(suggestions[i]));
116 free(suggestions[i]);
117 }
118 if (suggestions != NULL)
119 free(suggestions);
120 }
121
122 bool HunspellEngine::InitializeIfNeeded() {
123 if (!initialized_ && !dictionary_requested_) {
124 // RenderThread will not exist in test.
125 if (RenderThread::Get())
126 RenderThread::Get()->Send(new SpellCheckHostMsg_RequestDictionary);
127 dictionary_requested_ = true;
128 return true;
129 }
130
131 // Don't initialize if hunspell is disabled.
132 if (file_.IsValid())
133 InitializeHunspell();
134
135 return !initialized_;
136 }
137
138 bool HunspellEngine::IsEnabled() {
139 return hunspell_enabled_;
140 }
OLDNEW
« no previous file with comments | « chrome/renderer/spellchecker/hunspell_engine.h ('k') | chrome/renderer/spellchecker/platform_spelling_engine.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698