17898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project/* 27898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Copyright (C) 2009 The Android Open Source Project 37898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * 47898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 57898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * you may not use this file except in compliance with the License. 67898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * You may obtain a copy of the License at 77898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * 87898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 97898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * 107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * See the License for the specific language governing permissions and 147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * limitations under the License. 157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#include <stdio.h> 187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#include <string.h> 197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#include <assert.h> 207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#include "../include/dictdef.h" 217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#ifdef ___BUILD_MODEL___ 237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#include "../include/spellingtable.h" 247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#endif 257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#include "../include/spellingtrie.h" 277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectnamespace ime_pinyin { 297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source ProjectSpellingTrie* SpellingTrie::instance_ = NULL; 317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project// z/c/s is for Zh/Ch/Sh 337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectconst char SpellingTrie::kHalfId2Sc_[kFullSplIdStart + 1] = 347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project "0ABCcDEFGHIJKLMNOPQRSsTUVWXYZz"; 357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project// Bit 0 : is it a Shengmu char? 377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project// Bit 1 : is it a Yunmu char? (one char is a Yunmu) 387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project// Bit 2 : is it enabled in ShouZiMu(first char) mode? 397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectunsigned char SpellingTrie::char_flags_[] = { 407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // a b c d e f g 417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // h i j k l m n 437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // o p q r s t 457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // u v w x y z 477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 0x00, 0x00, 0x01, 0x01, 0x01, 0x01 487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project}; 497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectint compare_spl(const void* p1, const void* p2) { 517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return strcmp((const char*)(p1), (const char*)(p2)); 527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source ProjectSpellingTrie::SpellingTrie() { 557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spelling_buf_ = NULL; 567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spelling_size_ = 0; 577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spelling_num_ = 0; 587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spl_ym_ids_ = NULL; 597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr_queried_ = NULL; 607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16_queried_ = NULL; 617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project root_ = NULL; 627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project dumb_node_ = NULL; 637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splitter_node_ = NULL; 647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project instance_ = NULL; 657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project ym_buf_ = NULL; 667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project f2h_ = NULL; 677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project szm_enable_shm(true); 697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project szm_enable_ym(true); 707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#ifdef ___BUILD_MODEL___ 727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_num_ = 0; 737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#endif 747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source ProjectSpellingTrie::~SpellingTrie() { 777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL != spelling_buf_) 787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project delete [] spelling_buf_; 797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL != splstr_queried_) 817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project delete [] splstr_queried_; 827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL != splstr16_queried_) 847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project delete [] splstr16_queried_; 857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL != spl_ym_ids_) 877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project delete [] spl_ym_ids_; 887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL != root_) { 907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project free_son_trie(root_); 917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project delete root_; 927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL != dumb_node_) { 957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project delete [] dumb_node_; 967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL != splitter_node_) { 997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project delete [] splitter_node_; 1007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL != instance_) { 1037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project delete instance_; 1047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project instance_ = NULL; 1057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL != ym_buf_) 1087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project delete [] ym_buf_; 1097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL != f2h_) 1117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project delete [] f2h_; 1127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 1137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectbool SpellingTrie::if_valid_id_update(uint16 *splid) const { 1157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL == splid || 0 == *splid) 1167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 1177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (*splid >= kFullSplIdStart) 1197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return true; 1207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (*splid < kFullSplIdStart) { 1217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project char ch = kHalfId2Sc_[*splid]; 1227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (ch > 'Z') { 1237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return true; 1247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else { 1257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (szm_is_enabled(ch)) { 1267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return true; 1277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else if (is_yunmu_char(ch)) { 1287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project assert(h2f_num_[*splid] > 0); 1297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project *splid = h2f_start_[*splid]; 1307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return true; 1317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 1357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 1367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectbool SpellingTrie::is_half_id(uint16 splid) const { 1387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (0 == splid || splid >= kFullSplIdStart) 1397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 1407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return true; 1427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 1437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectbool SpellingTrie::is_full_id(uint16 splid) const { 1457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (splid < kFullSplIdStart || splid >= kFullSplIdStart + spelling_num_) 1467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 1477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return true; 1487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 1497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectbool SpellingTrie::half_full_compatible(uint16 half_id, uint16 full_id) const { 1517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project uint16 half_fr_full = full_to_half(full_id); 1527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (half_fr_full == half_id) 1547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return true; 1557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // &~0x20 is used to conver the char to upper case. 1577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // So that Zh/Ch/Sh(whose char is z/c/s) can be matched with Z/C/S. 1587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project char ch_f = (kHalfId2Sc_[half_fr_full] & (~0x20)); 1597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project char ch_h = kHalfId2Sc_[half_id]; 1607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (ch_f == ch_h) 1617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return true; 1627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 1647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 1657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectbool SpellingTrie::is_half_id_yunmu(uint16 splid) const { 1677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (0 == splid || splid >= kFullSplIdStart) 1687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 1697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project char ch = kHalfId2Sc_[splid]; 1717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // If ch >= 'a', that means the half id is one of Zh/Ch/Sh 1727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (ch >= 'a') { 1737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 1747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return char_flags_[ch - 'A'] & kHalfIdYunmuMask; 1777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 1787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectbool SpellingTrie::is_shengmu_char(char ch) const { 1807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return char_flags_[ch - 'A'] & kHalfIdShengmuMask; 1817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 1827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectbool SpellingTrie::is_yunmu_char(char ch) const { 1847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return char_flags_[ch - 'A'] & kHalfIdYunmuMask; 1857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 1867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectbool SpellingTrie::is_szm_char(char ch) const { 1887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return is_shengmu_char(ch) || is_yunmu_char(ch); 1897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 1907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectbool SpellingTrie::szm_is_enabled(char ch) const { 1927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return char_flags_[ch - 'A'] & kHalfIdSzmMask; 1937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 1947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectvoid SpellingTrie::szm_enable_shm(bool enable) { 1967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (enable) { 1977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project for (char ch = 'A'; ch <= 'Z'; ch++) { 1987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (is_shengmu_char(ch)) 1997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project char_flags_[ch - 'A'] = char_flags_[ch - 'A'] | kHalfIdSzmMask; 2007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else { 2027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project for (char ch = 'A'; ch <= 'Z'; ch++) { 2037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (is_shengmu_char(ch)) 2047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project char_flags_[ch - 'A'] = char_flags_[ch - 'A'] & (kHalfIdSzmMask ^ 0xff); 2057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 2087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectvoid SpellingTrie::szm_enable_ym(bool enable) { 2107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (enable) { 2117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project for (char ch = 'A'; ch <= 'Z'; ch++) { 2127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (is_yunmu_char(ch)) 2137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project char_flags_[ch - 'A'] = char_flags_[ch - 'A'] | kHalfIdSzmMask; 2147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else { 2167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project for (char ch = 'A'; ch <= 'Z'; ch++) { 2177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (is_yunmu_char(ch)) 2187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project char_flags_[ch - 'A'] = char_flags_[ch - 'A'] & (kHalfIdSzmMask ^ 0xff); 2197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 2227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectbool SpellingTrie::is_szm_enabled(char ch) const { 2247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return char_flags_[ch - 'A'] & kHalfIdSzmMask; 2257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 2267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectconst SpellingTrie* SpellingTrie::get_cpinstance() { 2287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return &get_instance(); 2297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 2307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source ProjectSpellingTrie& SpellingTrie::get_instance() { 2327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL == instance_) 2337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project instance_ = new SpellingTrie(); 2347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return *instance_; 2367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 2377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectuint16 SpellingTrie::half2full_num(uint16 half_id) const { 2397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL == root_ || half_id >= kFullSplIdStart) 2407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return 0; 2417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return h2f_num_[half_id]; 2427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 2437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectuint16 SpellingTrie::half_to_full(uint16 half_id, uint16 *spl_id_start) const { 2457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL == spl_id_start || NULL == root_ || half_id >= kFullSplIdStart) 2467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return 0; 2477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project *spl_id_start = h2f_start_[half_id]; 2497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return h2f_num_[half_id]; 2507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 2517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectuint16 SpellingTrie::full_to_half(uint16 full_id) const { 2537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL == root_ || full_id < kFullSplIdStart || 2547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project full_id > spelling_num_ + kFullSplIdStart) 2557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return 0; 2567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return f2h_[full_id - kFullSplIdStart]; 2587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 2597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectvoid SpellingTrie::free_son_trie(SpellingNode* node) { 2617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL == node) 2627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return; 2637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project for (size_t pos = 0; pos < node->num_of_son; pos++) { 2657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project free_son_trie(node->first_son + pos); 2667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL != node->first_son) 2697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project delete [] node->first_son; 2707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 2717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectbool SpellingTrie::construct(const char* spelling_arr, size_t item_size, 2737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project size_t item_num, float score_amplifier, 2747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project unsigned char average_score) { 2757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (spelling_arr == NULL) 2767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 2777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project memset(h2f_start_, 0, sizeof(uint16) * kFullSplIdStart); 2797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project memset(h2f_num_, 0, sizeof(uint16) * kFullSplIdStart); 2807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // If the arr is the same as the buf, means this function is called by 2827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // load_table(), the table data are ready; otherwise the array should be 2837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // saved. 2847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (spelling_arr != spelling_buf_) { 2857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL != spelling_buf_) 2867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project delete [] spelling_buf_; 2877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spelling_buf_ = new char[item_size * item_num]; 2887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL == spelling_buf_) 2897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 2907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project memcpy(spelling_buf_, spelling_arr, sizeof(char) * item_size * item_num); 2917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spelling_size_ = item_size; 2947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spelling_num_ = item_num; 2957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project score_amplifier_ = score_amplifier; 2977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project average_score_ = average_score; 2987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL != splstr_queried_) 3007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project delete [] splstr_queried_; 3017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr_queried_ = new char[spelling_size_]; 3027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL == splstr_queried_) 3037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 3047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL != splstr16_queried_) 3067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project delete [] splstr16_queried_; 3077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16_queried_ = new char16[spelling_size_]; 3087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL == splstr16_queried_) 3097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 3107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // First, sort the buf to ensure they are in ascendant order 3127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project qsort(spelling_buf_, spelling_num_, spelling_size_, compare_spl); 3137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#ifdef ___BUILD_MODEL___ 3157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_num_ = 1; 3167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#endif 3177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project root_ = new SpellingNode(); 3197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project memset(root_, 0, sizeof(SpellingNode)); 3207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project dumb_node_ = new SpellingNode(); 3227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project memset(dumb_node_, 0, sizeof(SpellingNode)); 3237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project dumb_node_->score = average_score_; 3247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splitter_node_ = new SpellingNode(); 3267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project memset(splitter_node_, 0, sizeof(SpellingNode)); 3277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splitter_node_->score = average_score_; 3287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project memset(level1_sons_, 0, sizeof(SpellingNode*) * kValidSplCharNum); 3307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project root_->first_son = construct_spellings_subset(0, spelling_num_, 0, root_); 3327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // Root's score should be cleared. 3347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project root_->score = 0; 3357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL == root_->first_son) 3377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 3387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project h2f_start_[0] = h2f_num_[0] = 0; 3407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (!build_f2h()) 3427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 3437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#ifdef ___BUILD_MODEL___ 3457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (kPrintDebug0) { 3467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project printf("---SpellingTrie Nodes: %d\n", node_num_); 3477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return build_ym_info(); 3497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#else 3507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return true; 3517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#endif 3527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 3537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#ifdef ___BUILD_MODEL___ 3557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectconst char* SpellingTrie::get_ym_str(const char *spl_str) { 3567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project bool start_ZCS = false; 3577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (is_shengmu_char(*spl_str)) { 3587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if ('Z' == *spl_str || 'C' == *spl_str || 'S' == *spl_str) 3597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project start_ZCS = true; 3607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spl_str += 1; 3617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (start_ZCS && 'h' == *spl_str) 3627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spl_str += 1; 3637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return spl_str; 3657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 3667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectbool SpellingTrie::build_ym_info() { 3687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project bool sucess; 3697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project SpellingTable *spl_table = new SpellingTable(); 3707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project sucess = spl_table->init_table(kMaxPinyinSize - 1, 2 * kMaxYmNum, false); 3727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project assert(sucess); 3737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project for (uint16 pos = 0; pos < spelling_num_; pos++) { 3757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project const char *spl_str = spelling_buf_ + spelling_size_ * pos; 3767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spl_str = get_ym_str(spl_str); 3777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if ('\0' != spl_str[0]) { 3787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project sucess = spl_table->put_spelling(spl_str, 0); 3797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project assert(sucess); 3807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project size_t ym_item_size; // '\0' is included 3847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project size_t ym_num; 3857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project const char* ym_buf; 3867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project ym_buf = spl_table->arrange(&ym_item_size, &ym_num); 3877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL != ym_buf_) 3897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project delete [] ym_buf_; 3907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project ym_buf_ = new char[ym_item_size * ym_num]; 3917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL == ym_buf_) { 3927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project delete spl_table; 3937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 3947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project memcpy(ym_buf_, ym_buf, sizeof(char) * ym_item_size * ym_num); 3977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project ym_size_ = ym_item_size; 3987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project ym_num_ = ym_num; 3997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project delete spl_table; 4017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // Generate the maping from the spelling ids to the Yunmu ids. 4037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (spl_ym_ids_) 4047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project delete spl_ym_ids_; 4057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spl_ym_ids_ = new uint8[spelling_num_ + kFullSplIdStart]; 4067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL == spl_ym_ids_) 4077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 4087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project memset(spl_ym_ids_, 0, sizeof(uint8) * (spelling_num_ + kFullSplIdStart)); 4107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project for (uint16 id = 1; id < spelling_num_ + kFullSplIdStart; id++) { 4127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project const char *str = get_spelling_str(id); 4137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project str = get_ym_str(str); 4157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if ('\0' != str[0]) { 4167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project uint8 ym_id = get_ym_id(str); 4177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spl_ym_ids_[id] = ym_id; 4187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project assert(ym_id > 0); 4197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else { 4207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spl_ym_ids_[id] = 0; 4217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return true; 4247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 4257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#endif 4267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source ProjectSpellingNode* SpellingTrie::construct_spellings_subset( 4287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project size_t item_start, size_t item_end, size_t level, SpellingNode* parent) { 4297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (level >= spelling_size_ || item_end <= item_start || NULL == parent) 4307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return NULL; 4317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project SpellingNode *first_son = NULL; 4337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project uint16 num_of_son = 0; 4347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project unsigned char min_son_score = 255; 4357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project const char *spelling_last_start = spelling_buf_ + spelling_size_ * item_start; 4377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project char char_for_node = spelling_last_start[level]; 4387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project assert(char_for_node >= 'A' && char_for_node <= 'Z' || 4397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 'h' == char_for_node); 4407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // Scan the array to find how many sons 4427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project for (size_t i = item_start + 1; i < item_end; i++) { 4437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project const char *spelling_current = spelling_buf_ + spelling_size_ * i; 4447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project char char_current = spelling_current[level]; 4457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (char_current != char_for_node) { 4467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project num_of_son++; 4477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project char_for_node = char_current; 4487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project num_of_son++; 4517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // Allocate memory 4537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#ifdef ___BUILD_MODEL___ 4547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_num_ += num_of_son; 4557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#endif 4567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project first_son = new SpellingNode[num_of_son]; 4577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project memset(first_son, 0, sizeof(SpellingNode)*num_of_son); 4587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // Now begin construct tree 4607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project size_t son_pos = 0; 4617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spelling_last_start = spelling_buf_ + spelling_size_ * item_start; 4637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project char_for_node = spelling_last_start[level]; 4647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project bool spelling_endable = true; 4667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (spelling_last_start[level + 1] != '\0') 4677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spelling_endable = false; 4687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project size_t item_start_next = item_start; 4707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project for (size_t i = item_start + 1; i < item_end; i++) { 4727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project const char *spelling_current = spelling_buf_ + spelling_size_ * i; 4737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project char char_current = spelling_current[level]; 4747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project assert(is_valid_spl_char(char_current)); 4757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (char_current != char_for_node) { 4777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // Construct a node 4787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project SpellingNode *node_current = first_son + son_pos; 4797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_current->char_this_node = char_for_node; 4807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // For quick search in the first level 4827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (0 == level) 4837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project level1_sons_[char_for_node - 'A'] = node_current; 4847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (spelling_endable) { 4867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_current->spelling_idx = kFullSplIdStart + item_start_next; 4877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (spelling_last_start[level + 1] != '\0' || i - item_start_next > 1) { 4907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project size_t real_start = item_start_next; 4917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (spelling_last_start[level + 1] == '\0') 4927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project real_start++; 4937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_current->first_son = 4957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project construct_spellings_subset(real_start, i, level + 1, 4967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_current); 4977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (real_start == item_start_next + 1) { 4997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project uint16 score_this = static_cast<unsigned char>( 5007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spelling_last_start[spelling_size_ - 1]); 5017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (score_this < node_current->score) 5027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_current->score = score_this; 5037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else { 5057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_current->first_son = NULL; 5067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_current->score = static_cast<unsigned char>( 5077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spelling_last_start[spelling_size_ - 1]); 5087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (node_current->score < min_son_score) 5117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project min_son_score = node_current->score; 5127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project bool is_half = false; 5147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (level == 0 && is_szm_char(char_for_node)) { 5157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_current->spelling_idx = 5167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project static_cast<uint16>(char_for_node - 'A' + 1); 5177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (char_for_node > 'C') 5197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_current->spelling_idx++; 5207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (char_for_node > 'S') 5217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_current->spelling_idx++; 5227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project h2f_num_[node_current->spelling_idx] = i - item_start_next; 5247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project is_half = true; 5257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else if (level == 1 && char_for_node == 'h') { 5267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project char ch_level0 = spelling_last_start[0]; 5277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project uint16 part_id = 0; 5287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (ch_level0 == 'C') 5297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project part_id = 'C' - 'A' + 1 + 1; 5307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project else if (ch_level0 == 'S') 5317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project part_id = 'S' - 'A' + 1 + 2; 5327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project else if (ch_level0 == 'Z') 5337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project part_id = 'Z' - 'A' + 1 + 3; 5347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (0 != part_id) { 5357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_current->spelling_idx = part_id; 5367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project h2f_num_[node_current->spelling_idx] = i - item_start_next; 5377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project is_half = true; 5387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (is_half) { 5427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (h2f_num_[node_current->spelling_idx] > 0) 5437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project h2f_start_[node_current->spelling_idx] = 5447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project item_start_next + kFullSplIdStart; 5457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project else 5467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project h2f_start_[node_current->spelling_idx] = 0; 5477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // for next sibling 5507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spelling_last_start = spelling_current; 5517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project char_for_node = char_current; 5527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project item_start_next = i; 5537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spelling_endable = true; 5547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (spelling_current[level + 1] != '\0') 5557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spelling_endable = false; 5567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project son_pos++; 5587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // the last one 5627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project SpellingNode *node_current = first_son + son_pos; 5637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_current->char_this_node = char_for_node; 5647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // For quick search in the first level 5667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (0 == level) 5677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project level1_sons_[char_for_node - 'A'] = node_current; 5687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (spelling_endable) { 5707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_current->spelling_idx = kFullSplIdStart + item_start_next; 5717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (spelling_last_start[level + 1] != '\0' || 5747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project item_end - item_start_next > 1) { 5757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project size_t real_start = item_start_next; 5767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (spelling_last_start[level + 1] == '\0') 5777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project real_start++; 5787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_current->first_son = 5807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project construct_spellings_subset(real_start, item_end, level + 1, 5817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_current); 5827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (real_start == item_start_next + 1) { 5847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project uint16 score_this = static_cast<unsigned char>( 5857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spelling_last_start[spelling_size_ - 1]); 5867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (score_this < node_current->score) 5877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_current->score = score_this; 5887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else { 5907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_current->first_son = NULL; 5917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_current->score = static_cast<unsigned char>( 5927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spelling_last_start[spelling_size_ - 1]); 5937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 5947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (node_current->score < min_son_score) 5967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project min_son_score = node_current->score; 5977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 5987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project assert(son_pos + 1 == num_of_son); 5997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project bool is_half = false; 6017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (level == 0 && szm_is_enabled(char_for_node)) { 6027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_current->spelling_idx = static_cast<uint16>(char_for_node - 'A' + 1); 6037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (char_for_node > 'C') 6057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_current->spelling_idx++; 6067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (char_for_node > 'S') 6077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_current->spelling_idx++; 6087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project h2f_num_[node_current->spelling_idx] = item_end - item_start_next; 6107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project is_half = true; 6117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else if (level == 1 && char_for_node == 'h') { 6127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project char ch_level0 = spelling_last_start[0]; 6137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project uint16 part_id = 0; 6147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (ch_level0 == 'C') 6157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project part_id = 'C' - 'A' + 1 + 1; 6167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project else if (ch_level0 == 'S') 6177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project part_id = 'S' - 'A' + 1 + 2; 6187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project else if (ch_level0 == 'Z') 6197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project part_id = 'Z' - 'A' + 1 + 3; 6207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (0 != part_id) { 6217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project node_current->spelling_idx = part_id; 6227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project h2f_num_[node_current->spelling_idx] = item_end - item_start_next; 6237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project is_half = true; 6247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 6257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 6267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (is_half) { 6277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (h2f_num_[node_current->spelling_idx] > 0) 6287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project h2f_start_[node_current->spelling_idx] = 6297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project item_start_next + kFullSplIdStart; 6307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project else 6317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project h2f_start_[node_current->spelling_idx] = 0; 6327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 6337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project parent->num_of_son = num_of_son; 6357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project parent->score = min_son_score; 6367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return first_son; 6377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 6387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectbool SpellingTrie::save_spl_trie(FILE *fp) { 6407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL == fp || NULL == spelling_buf_) 6417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 6427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (fwrite(&spelling_size_, sizeof(size_t), 1, fp) != 1) 6447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 6457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (fwrite(&spelling_num_, sizeof(size_t), 1, fp) != 1) 6477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 6487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (fwrite(&score_amplifier_, sizeof(float), 1, fp) != 1) 6507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 6517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (fwrite(&average_score_, sizeof(unsigned char), 1, fp) != 1) 6537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 6547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (fwrite(spelling_buf_, sizeof(char) * spelling_size_, 6567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spelling_num_, fp) != spelling_num_) 6577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 6587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return true; 6607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 6617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectbool SpellingTrie::load_spl_trie(FILE *fp) { 6637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL == fp) 6647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 6657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (fread(&spelling_size_, sizeof(size_t), 1, fp) != 1) 6677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 6687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (fread(&spelling_num_, sizeof(size_t), 1, fp) != 1) 6707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 6717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (fread(&score_amplifier_, sizeof(float), 1, fp) != 1) 6737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 6747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (fread(&average_score_, sizeof(unsigned char), 1, fp) != 1) 6767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 6777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL != spelling_buf_) 6797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project delete [] spelling_buf_; 6807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spelling_buf_ = new char[spelling_size_ * spelling_num_]; 6827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL == spelling_buf_) 6837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 6847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (fread(spelling_buf_, sizeof(char) * spelling_size_, 6867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spelling_num_, fp) != spelling_num_) 6877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 6887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return construct(spelling_buf_, spelling_size_, spelling_num_, 6907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project score_amplifier_, average_score_); 6917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 6927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 6937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectbool SpellingTrie::build_f2h() { 6947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL != f2h_) 6957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project delete [] f2h_; 6967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project f2h_ = new uint16[spelling_num_]; 6977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL == f2h_) 6987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 6997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 7007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project for (uint16 hid = 0; hid < kFullSplIdStart; hid++) { 7017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project for (uint16 fid = h2f_start_[hid]; 7027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project fid < h2f_start_[hid] + h2f_num_[hid]; fid++) 7037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project f2h_[fid - kFullSplIdStart] = hid; 7047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 7057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 7067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return true; 7077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 7087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 7097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectsize_t SpellingTrie::get_spelling_num() { 7107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return spelling_num_; 7117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 7127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 7137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectuint8 SpellingTrie::get_ym_id(const char *ym_str) { 7147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL == ym_str || NULL == ym_buf_) 7157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return 0; 7167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 7177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project for (uint8 pos = 0; pos < ym_num_; pos++) 7187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (strcmp(ym_buf_ + ym_size_ * pos, ym_str) == 0) 7197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return pos + 1; 7207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 7217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return 0; 7227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 7237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 7247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectconst char* SpellingTrie::get_spelling_str(uint16 splid) { 7257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr_queried_[0] = '\0'; 7267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 7277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (splid >= kFullSplIdStart) { 7287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splid -= kFullSplIdStart; 7297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project snprintf(splstr_queried_, spelling_size_, "%s", 7307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project spelling_buf_ + splid * spelling_size_); 7317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else { 7327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (splid == 'C' - 'A' + 1 + 1) { 7337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project snprintf(splstr_queried_, spelling_size_, "%s", "Ch"); 7347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else if (splid == 'S' - 'A' + 1 + 2) { 7357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project snprintf(splstr_queried_, spelling_size_, "%s", "Sh"); 7367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else if (splid == 'Z' - 'A' + 1 + 3) { 7377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project snprintf(splstr_queried_, spelling_size_, "%s", "Zh"); 7387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else { 7397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (splid > 'C' - 'A' + 1) 7407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splid--; 7417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (splid > 'S' - 'A' + 1) 7427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splid--; 7437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr_queried_[0] = 'A' + splid - 1; 7447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr_queried_[1] = '\0'; 7457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 7467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 7477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return splstr_queried_; 7487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 7497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 7507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectconst char16* SpellingTrie::get_spelling_str16(uint16 splid) { 7517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16_queried_[0] = '\0'; 7527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 7537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (splid >= kFullSplIdStart) { 7547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splid -= kFullSplIdStart; 7557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project for (size_t pos = 0; pos < spelling_size_; pos++) { 7567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16_queried_[pos] = static_cast<char16> 7577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project (spelling_buf_[splid * spelling_size_ + pos]); 7587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 7597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else { 7607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (splid == 'C' - 'A' + 1 + 1) { 7617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16_queried_[0] = static_cast<char16>('C'); 7627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16_queried_[1] = static_cast<char16>('h'); 7637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16_queried_[2] = static_cast<char16>('\0'); 7647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else if (splid == 'S' - 'A' + 1 + 2) { 7657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16_queried_[0] = static_cast<char16>('S'); 7667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16_queried_[1] = static_cast<char16>('h'); 7677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16_queried_[2] = static_cast<char16>('\0'); 7687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else if (splid == 'Z' - 'A' + 1 + 3) { 7697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16_queried_[0] = static_cast<char16>('Z'); 7707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16_queried_[1] = static_cast<char16>('h'); 7717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16_queried_[2] = static_cast<char16>('\0'); 7727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else { 7737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (splid > 'C' - 'A' + 1) 7747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splid--; 7757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (splid > 'S' - 'A' + 1) 7767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splid--; 7777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16_queried_[0] = 'A' + splid - 1; 7787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16_queried_[1] = '\0'; 7797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 7807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 7817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return splstr16_queried_; 7827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 7837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 7847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectsize_t SpellingTrie::get_spelling_str16(uint16 splid, char16 *splstr16, 7857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project size_t splstr16_len) { 7867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (NULL == splstr16 || splstr16_len < kMaxPinyinSize + 1) return 0; 7877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 7887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (splid >= kFullSplIdStart) { 7897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splid -= kFullSplIdStart; 7907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project for (size_t pos = 0; pos <= kMaxPinyinSize; pos++) { 7917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16[pos] = static_cast<char16> 7927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project (spelling_buf_[splid * spelling_size_ + pos]); 7937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (static_cast<char16>('\0') == splstr16[pos]) { 7947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return pos; 7957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 7967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 7977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else { 7987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (splid == 'C' - 'A' + 1 + 1) { 7997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16[0] = static_cast<char16>('C'); 8007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16[1] = static_cast<char16>('h'); 8017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16[2] = static_cast<char16>('\0'); 8027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return 2; 8037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else if (splid == 'S' - 'A' + 1 + 2) { 8047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16[0] = static_cast<char16>('S'); 8057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16[1] = static_cast<char16>('h'); 8067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16[2] = static_cast<char16>('\0'); 8077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return 2; 8087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else if (splid == 'Z' - 'A' + 1 + 3) { 8097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16[0] = static_cast<char16>('Z'); 8107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16[1] = static_cast<char16>('h'); 8117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16[2] = static_cast<char16>('\0'); 8127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return 2; 8137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else { 8147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (splid > 'C' - 'A' + 1) 8157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splid--; 8167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (splid > 'S' - 'A' + 1) 8177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splid--; 8187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16[0] = 'A' + splid - 1; 8197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project splstr16[1] = '\0'; 8207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return 1; 8217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 8227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 8237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 8247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // Not reachable. 8257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return 0; 8267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 8277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 8287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} // namespace ime_pinyin 829