blob: d1549ba0a0e3b36b5488a3589a7d4982e38d56dc [file] [log] [blame]
// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "composer/internal/typing_model.h"
#include <limits>
#include "base/port.h"
#include "base/scoped_ptr.h"
#include "base/string_piece.h"
namespace mozc {
namespace composer {
namespace {
// These header files are automatically generated by gen_typing_model.py.
#include "composer/internal/typing_model_12keys-hiragana.h"
#include "composer/internal/typing_model_flick-hiragana.h"
#include "composer/internal/typing_model_godan-hiragana.h"
#include "composer/internal/typing_model_qwerty_mobile-hiragana.h"
#include "composer/internal/typing_model_toggle_flick-hiragana.h"
scoped_ptr<TypingModel> g_typing_model_12keys_hiragana;
scoped_ptr<TypingModel> g_typing_model_flick_hiragana;
scoped_ptr<TypingModel> g_typing_model_godan_hiragana;
scoped_ptr<TypingModel> g_typing_model_qwerty_mobile_hiragana;
scoped_ptr<TypingModel> g_typing_model_toggle_flick_hiragana;
} // namespace
const uint8 TypingModel::kNoData = numeric_limits<uint8>::max();
const int TypingModel::kInfinity = (2 << 20); // approximately equals 1e+6
TypingModel::TypingModel(const char *characters,
size_t characters_size,
const uint8 *cost_table,
size_t cost_table_size,
const int32 *mapping_table) :
character_to_radix_table_(
new unsigned char[numeric_limits<unsigned char>::max()]),
characters_size_(characters_size),
cost_table_(cost_table),
cost_table_size_(cost_table_size),
mapping_table_(mapping_table) {
for (size_t i = 0; i < characters_size; ++i) {
character_to_radix_table_[characters[i]] = i + 1;
}
}
int TypingModel::GetCost(StringPiece key) const {
size_t index = GetIndex(key);
if (index >= cost_table_size_) {
return kInfinity;
}
uint8 cost_index = cost_table_[index];
return cost_index == kNoData ? kInfinity : mapping_table_[cost_index];
}
size_t TypingModel::GetIndex(StringPiece key) const {
const unsigned int radix = characters_size_ + 1;
size_t index = 0;
for (size_t i = 0; i < key.length(); ++i) {
index = index * radix + character_to_radix_table_[key[i]];
}
return index;
}
// static
const TypingModel *TypingModel::GetTypingModel(
const mozc::commands::Request::SpecialRomanjiTable &special_romanji_table) {
switch (special_romanji_table) {
case mozc::commands::Request::TWELVE_KEYS_TO_HIRAGANA:
if (!g_typing_model_12keys_hiragana.get()) {
g_typing_model_12keys_hiragana.reset(new TypingModel(
kKeyCharacters_12keysHiragana,
kKeyCharactersSize_12keysHiragana,
kCostTable_12keysHiragana,
kCostTableSize_12keysHiragana,
kCostMappingTable_12keysHiragana));
}
return g_typing_model_12keys_hiragana.get();
case mozc::commands::Request::FLICK_TO_HIRAGANA:
if (!g_typing_model_flick_hiragana.get()) {
g_typing_model_flick_hiragana.reset(new TypingModel(
kKeyCharacters_FlickHiragana,
kKeyCharactersSize_FlickHiragana,
kCostTable_FlickHiragana,
kCostTableSize_FlickHiragana,
kCostMappingTable_FlickHiragana));
}
return g_typing_model_flick_hiragana.get();
case mozc::commands::Request::TOGGLE_FLICK_TO_HIRAGANA:
if (!g_typing_model_toggle_flick_hiragana.get()) {
g_typing_model_toggle_flick_hiragana.reset(new TypingModel(
kKeyCharacters_ToggleFlickHiragana,
kKeyCharactersSize_ToggleFlickHiragana,
kCostTable_ToggleFlickHiragana,
kCostTableSize_ToggleFlickHiragana,
kCostMappingTable_ToggleFlickHiragana));
}
return g_typing_model_toggle_flick_hiragana.get();
case mozc::commands::Request::QWERTY_MOBILE_TO_HIRAGANA:
if (!g_typing_model_qwerty_mobile_hiragana.get()) {
g_typing_model_qwerty_mobile_hiragana.reset(new TypingModel(
kKeyCharacters_QwertyMobileHiragana,
kKeyCharactersSize_QwertyMobileHiragana,
kCostTable_QwertyMobileHiragana,
kCostTableSize_QwertyMobileHiragana,
kCostMappingTable_QwertyMobileHiragana));
}
return g_typing_model_qwerty_mobile_hiragana.get();
case mozc::commands::Request::GODAN_TO_HIRAGANA:
if (!g_typing_model_godan_hiragana.get()) {
g_typing_model_godan_hiragana.reset(new TypingModel(
kKeyCharacters_GodanHiragana,
kKeyCharactersSize_GodanHiragana,
kCostTable_GodanHiragana,
kCostTableSize_GodanHiragana,
kCostMappingTable_GodanHiragana));
}
return g_typing_model_godan_hiragana.get();
default:
return NULL;
}
}
} // namespace composer
} // namespace mozc