This source file includes following definitions.
- CreateNativeSpellingEngine
- dictionary_requested_
- Init
- InitializeHunspell
- CheckSpelling
- FillSuggestionList
- InitializeIfNeeded
- IsEnabled
#include "chrome/renderer/spellchecker/hunspell_engine.h"
#include <algorithm>
#include <iterator>
#include "base/files/memory_mapped_file.h"
#include "base/metrics/histogram.h"
#include "base/time/time.h"
#include "chrome/common/spellcheck_common.h"
#include "chrome/common/spellcheck_messages.h"
#include "content/public/renderer/render_thread.h"
#include "third_party/hunspell/src/hunspell/hunspell.hxx"
using base::TimeTicks;
using content::RenderThread;
namespace {
const size_t kMaxCheckedLen = 64;
const size_t kMaxSuggestLen = 24;
COMPILE_ASSERT(kMaxCheckedLen <= size_t(MAXWORDLEN), MaxCheckedLen_too_long);
COMPILE_ASSERT(kMaxSuggestLen <= kMaxCheckedLen, MaxSuggestLen_too_long);
}
#if !defined(OS_MACOSX)
SpellingEngine* CreateNativeSpellingEngine() {
return new HunspellEngine();
}
#endif
HunspellEngine::HunspellEngine()
: hunspell_enabled_(false),
initialized_(false),
dictionary_requested_(false) {
}
HunspellEngine::~HunspellEngine() {
}
void HunspellEngine::Init(base::File file) {
initialized_ = true;
hunspell_.reset();
bdict_file_.reset();
file_ = file.Pass();
hunspell_enabled_ = file_.IsValid();
}
void HunspellEngine::InitializeHunspell() {
if (hunspell_.get())
return;
bdict_file_.reset(new base::MemoryMappedFile);
if (bdict_file_->Initialize(file_.Pass())) {
TimeTicks debug_start_time = base::Histogram::DebugNow();
hunspell_.reset(new Hunspell(bdict_file_->data(), bdict_file_->length()));
DHISTOGRAM_TIMES("Spellcheck.InitTime",
base::Histogram::DebugNow() - debug_start_time);
} else {
NOTREACHED() << "Could not mmap spellchecker dictionary.";
}
}
bool HunspellEngine::CheckSpelling(const base::string16& word_to_check,
int tag) {
bool word_correct = true;
std::string word_to_check_utf8(base::UTF16ToUTF8(word_to_check));
if (word_to_check_utf8.length() <= kMaxCheckedLen) {
if (hunspell_.get()) {
word_correct = (hunspell_->spell(word_to_check_utf8.c_str()) != 0);
}
}
return word_correct;
}
void HunspellEngine::FillSuggestionList(
const base::string16& wrong_word,
std::vector<base::string16>* optional_suggestions) {
std::string wrong_word_utf8(base::UTF16ToUTF8(wrong_word));
if (wrong_word_utf8.length() > kMaxSuggestLen)
return;
if (!hunspell_.get())
return;
char** suggestions = NULL;
int number_of_suggestions =
hunspell_->suggest(&suggestions, wrong_word_utf8.c_str());
for (int i = 0; i < number_of_suggestions; ++i) {
if (i < chrome::spellcheck_common::kMaxSuggestions)
optional_suggestions->push_back(base::UTF8ToUTF16(suggestions[i]));
free(suggestions[i]);
}
if (suggestions != NULL)
free(suggestions);
}
bool HunspellEngine::InitializeIfNeeded() {
if (!initialized_ && !dictionary_requested_) {
if (RenderThread::Get())
RenderThread::Get()->Send(new SpellCheckHostMsg_RequestDictionary);
dictionary_requested_ = true;
return true;
}
if (file_.IsValid())
InitializeHunspell();
return !initialized_;
}
bool HunspellEngine::IsEnabled() {
return hunspell_enabled_;
}