BinaryDictionary.java revision 6ba8de2a608dfe4865b0b59a753f2d2abbedeeff
1923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/* 2443c360d0afdbab091994244f045f4756feaf2b4Jean-Baptiste Queru * Copyright (C) 2008 The Android Open Source Project 3e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa * 4923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * use this file except in compliance with the License. You may obtain a copy of 6923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * the License at 7e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa * 8923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa * 10923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * License for the specific language governing permissions and limitations under 14923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * the License. 15923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 16923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 17923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectpackage com.android.inputmethod.latin; 18923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 19fa086c90760bc2bedf0b74eacb0fed3bf7ebc2b7Tadashi G. Takaokaimport android.content.Context; 20fa086c90760bc2bedf0b74eacb0fed3bf7ebc2b7Tadashi G. Takaoka 21ab72a97d7ce44230a0c824797d1675a5ca354a56Tadashi G. Takaokaimport com.android.inputmethod.keyboard.ProximityInfo; 22ab72a97d7ce44230a0c824797d1675a5ca354a56Tadashi G. Takaoka 23923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport java.util.Arrays; 24923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 25923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/** 26923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Implements a static, compacted, binary dictionary of standard words. 27923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 28923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectpublic class BinaryDictionary extends Dictionary { 29923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 30cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard public static final String DICTIONARY_PACK_AUTHORITY = 31cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard "com.android.inputmethod.latin.dictionarypack"; 32cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard 33979f8690967ff5409fe18f5085858ccdb8e0ccf1satok /** 34cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard * There is a difference between what java and native code can handle. 35979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * This value should only be used in BinaryDictionary.java 36979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * It is necessary to keep it at this value because some languages e.g. German have 37979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * really long words. 38979f8690967ff5409fe18f5085858ccdb8e0ccf1satok */ 398fbd55229243cb66c03d5ea1f79dfb39f596590dsatok public static final int MAX_WORD_LENGTH = 48; 402e04770adfc16344f69d316efd3ed0a617ede330Tadashi G. Takaoka public static final int MAX_WORDS = 18; 41979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 42979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private static final String TAG = "BinaryDictionary"; 43979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private static final int MAX_BIGRAMS = 60; 44923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 45923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private static final int TYPED_LETTER_MULTIPLIER = 2; 46923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 47979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private int mDicTypeId; 485fdcd7d5cd9d39d41568aa1412a4b1a866c05d3aTadashi G. Takaoka private long mNativeDict; 496ba8de2a608dfe4865b0b59a753f2d2abbedeeffsatok private final int[] mInputCodes = new int[MAX_WORD_LENGTH]; 5030088259480130e5bac5c2028e2c7c3e6d4c51a2satok private final char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_WORDS]; 5130088259480130e5bac5c2028e2c7c3e6d4c51a2satok private final char[] mOutputChars_bigrams = new char[MAX_WORD_LENGTH * MAX_BIGRAMS]; 52e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka private final int[] mScores = new int[MAX_WORDS]; 53e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka private final int[] mBigramScores = new int[MAX_BIGRAMS]; 54923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 55071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka public static final Flag FLAG_REQUIRES_GERMAN_UMLAUT_PROCESSING = 56c899038eee5c01d520a2707cca01ee093a674d05Jean Chalard new Flag(R.bool.config_require_umlaut_processing, 0x1); 57cc78d03a62412e647d4c1373e88a4a2637244ed5Jean Chalard public static final Flag FLAG_REQUIRES_FRENCH_LIGATURES_PROCESSING = 58cc78d03a62412e647d4c1373e88a4a2637244ed5Jean Chalard new Flag(R.bool.config_require_ligatures_processing, 0x4); 59c899038eee5c01d520a2707cca01ee093a674d05Jean Chalard 60673cebf9e97289b3b0cd343ff7193dff69684a48Jean Chalard // FULL_EDIT_DISTANCE is a flag that forces the dictionary to use full words 61673cebf9e97289b3b0cd343ff7193dff69684a48Jean Chalard // when computing edit distance, instead of the default behavior of stopping 62673cebf9e97289b3b0cd343ff7193dff69684a48Jean Chalard // the evaluation at the size the user typed. 6340a5f6fa4df529bf21813d54fc20ffe5b3cbe436satok public static final Flag FLAG_USE_FULL_EDIT_DISTANCE = new Flag(0x2); 6440a5f6fa4df529bf21813d54fc20ffe5b3cbe436satok 65c899038eee5c01d520a2707cca01ee093a674d05Jean Chalard // Can create a new flag from extravalue : 66c899038eee5c01d520a2707cca01ee093a674d05Jean Chalard // public static final Flag FLAG_MYFLAG = 67c899038eee5c01d520a2707cca01ee093a674d05Jean Chalard // new Flag("my_flag", 0x02); 68071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka 69673cebf9e97289b3b0cd343ff7193dff69684a48Jean Chalard // ALL_CONFIG_FLAGS is a collection of flags that enable reading all flags from configuration. 70673cebf9e97289b3b0cd343ff7193dff69684a48Jean Chalard // This is but a mask - it does not mean the flags will be on, only that the configuration 71673cebf9e97289b3b0cd343ff7193dff69684a48Jean Chalard // will be read for this particular flag. 72673cebf9e97289b3b0cd343ff7193dff69684a48Jean Chalard public static final Flag[] ALL_CONFIG_FLAGS = { 73071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka // Here should reside all flags that trigger some special processing 74071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka // These *must* match the definition in UnigramDictionary enum in 75071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka // unigram_dictionary.h so please update both at the same time. 76673cebf9e97289b3b0cd343ff7193dff69684a48Jean Chalard // Please note that flags created with a resource are of type CONFIG while flags 77673cebf9e97289b3b0cd343ff7193dff69684a48Jean Chalard // created with a string are of type EXTRAVALUE. These behave like masks, and the 78673cebf9e97289b3b0cd343ff7193dff69684a48Jean Chalard // actual value will be read from the configuration/extra value at run time for 79673cebf9e97289b3b0cd343ff7193dff69684a48Jean Chalard // the configuration at dictionary creation time. 80071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka FLAG_REQUIRES_GERMAN_UMLAUT_PROCESSING, 81cc78d03a62412e647d4c1373e88a4a2637244ed5Jean Chalard FLAG_REQUIRES_FRENCH_LIGATURES_PROCESSING, 82071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka }; 83071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka 84c2bbc6a4499a6da979381fa0e8e6e855a5ac6aa4Jean Chalard private int mFlags = 0; 85923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 86923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project /** 874250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard * Constructor for the binary dictionary. This is supposed to be called from the 884250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard * dictionary factory. 894250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard * All implementations should pass null into flagArray, except for testing purposes. 904250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard * @param context the context to access the environment from. 914250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard * @param filename the name of the file to read through native code. 924250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard * @param offset the offset of the dictionary data within the file. 934250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard * @param length the length of the binary data. 944250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard * @param flagArray the flags to limit the dictionary to, or null for default. 95923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 964250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard public BinaryDictionary(final Context context, 974250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard final String filename, final long offset, final long length, Flag[] flagArray) { 984250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard // Note: at the moment a binary dictionary is always of the "main" type. 994250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard // Initializing this here will help transitioning out of the scheme where 1004250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard // the Suggest class knows everything about every single dictionary. 1014250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard mDicTypeId = Suggest.DIC_MAIN; 1024250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard // TODO: Stop relying on the state of SubtypeSwitcher, get it as a parameter 103673cebf9e97289b3b0cd343ff7193dff69684a48Jean Chalard mFlags = Flag.initFlags(null == flagArray ? ALL_CONFIG_FLAGS : flagArray, context, 1044250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard SubtypeSwitcher.getInstance()); 1054250eb27f54f8fedc388fe4825b0646a88778744Jean Chalard loadDictionary(filename, offset, length); 106979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 107979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 108eaef1c500703b4ee378821884c7b108815ed2983Ken Wakasa static { 109cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka JniUtils.loadNativeLibrary(); 110eaef1c500703b4ee378821884c7b108815ed2983Ken Wakasa } 111c2bbc6a4499a6da979381fa0e8e6e855a5ac6aa4Jean Chalard 1125fdcd7d5cd9d39d41568aa1412a4b1a866c05d3aTadashi G. Takaoka private native long openNative(String sourceDir, long dictOffset, long dictSize, 1136ba8de2a608dfe4865b0b59a753f2d2abbedeeffsatok int typedLetterMultiplier, int fullWordMultiplier, int maxWordLength, int maxWords); 1145fdcd7d5cd9d39d41568aa1412a4b1a866c05d3aTadashi G. Takaoka private native void closeNative(long dict); 1155fdcd7d5cd9d39d41568aa1412a4b1a866c05d3aTadashi G. Takaoka private native boolean isValidWordNative(long dict, char[] word, int wordLength); 1165fdcd7d5cd9d39d41568aa1412a4b1a866c05d3aTadashi G. Takaoka private native int getSuggestionsNative(long dict, long proximityInfo, int[] xCoordinates, 117c2bbc6a4499a6da979381fa0e8e6e855a5ac6aa4Jean Chalard int[] yCoordinates, int[] inputCodes, int codesSize, int flags, char[] outputChars, 118e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka int[] scores); 1195fdcd7d5cd9d39d41568aa1412a4b1a866c05d3aTadashi G. Takaoka private native int getBigramsNative(long dict, char[] prevWord, int prevWordLength, 120e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka int[] inputCodes, int inputCodesLength, char[] outputChars, int[] scores, 1216ba8de2a608dfe4865b0b59a753f2d2abbedeeffsatok int maxWordLength, int maxBigrams); 122be0cf72253f15bff6abdeaa79f60a56f06ab7b86satok private static native double calcNormalizedScoreNative( 123be0cf72253f15bff6abdeaa79f60a56f06ab7b86satok char[] before, int beforeLength, char[] after, int afterLength, int score); 124be0cf72253f15bff6abdeaa79f60a56f06ab7b86satok private static native int editDistanceNative( 125be0cf72253f15bff6abdeaa79f60a56f06ab7b86satok char[] before, int beforeLength, char[] after, int afterLength); 126979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 12733e0b1e79e464ac48a09433bbfcbb17ded620452Tadashi G. Takaoka private final void loadDictionary(String path, long startOffset, long length) { 12833e0b1e79e464ac48a09433bbfcbb17ded620452Tadashi G. Takaoka mNativeDict = openNative(path, startOffset, length, 1296ba8de2a608dfe4865b0b59a753f2d2abbedeeffsatok TYPED_LETTER_MULTIPLIER, FULL_WORD_SCORE_MULTIPLIER, MAX_WORD_LENGTH, MAX_WORDS); 130979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 131979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 132979f8690967ff5409fe18f5085858ccdb8e0ccf1satok @Override 133979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public void getBigrams(final WordComposer codes, final CharSequence previousWord, 134887f11ee43ad621aa6ad93d535ab7f48dec73fc7Tadashi G. Takaoka final WordCallback callback) { 135da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa if (mNativeDict == 0) return; 136da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa 137979f8690967ff5409fe18f5085858ccdb8e0ccf1satok char[] chars = previousWord.toString().toCharArray(); 138979f8690967ff5409fe18f5085858ccdb8e0ccf1satok Arrays.fill(mOutputChars_bigrams, (char) 0); 139e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka Arrays.fill(mBigramScores, 0); 140979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 141979f8690967ff5409fe18f5085858ccdb8e0ccf1satok int codesSize = codes.size(); 142979f8690967ff5409fe18f5085858ccdb8e0ccf1satok Arrays.fill(mInputCodes, -1); 143ad290d6505247171e1e8437446c6f5d148a01778Jean Chalard if (codesSize > 0) { 14401ab7c8b59a7f12862fbd95fb252e56719f1757fsatok mInputCodes[0] = codes.getCodeAt(0); 145ad290d6505247171e1e8437446c6f5d148a01778Jean Chalard } 146979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 147979f8690967ff5409fe18f5085858ccdb8e0ccf1satok int count = getBigramsNative(mNativeDict, chars, chars.length, mInputCodes, codesSize, 1486ba8de2a608dfe4865b0b59a753f2d2abbedeeffsatok mOutputChars_bigrams, mBigramScores, MAX_WORD_LENGTH, MAX_BIGRAMS); 1496ca3ac08ed536c415ac68913e23fde175b5e3f4dJean Chalard if (count > MAX_BIGRAMS) { 1506ca3ac08ed536c415ac68913e23fde175b5e3f4dJean Chalard count = MAX_BIGRAMS; 1516ca3ac08ed536c415ac68913e23fde175b5e3f4dJean Chalard } 152979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 153f5cded1c6cf0f39df13750d4f9f5ba66c1b32964satok for (int j = 0; j < count; ++j) { 154ad290d6505247171e1e8437446c6f5d148a01778Jean Chalard if (codesSize > 0 && mBigramScores[j] < 1) break; 155f5cded1c6cf0f39df13750d4f9f5ba66c1b32964satok final int start = j * MAX_WORD_LENGTH; 156979f8690967ff5409fe18f5085858ccdb8e0ccf1satok int len = 0; 157f5cded1c6cf0f39df13750d4f9f5ba66c1b32964satok while (len < MAX_WORD_LENGTH && mOutputChars_bigrams[start + len] != 0) { 158f5cded1c6cf0f39df13750d4f9f5ba66c1b32964satok ++len; 159979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 160979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (len > 0) { 161e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka callback.addWord(mOutputChars_bigrams, start, len, mBigramScores[j], 1626e082cb30dbe1a8cc314b474dc1377b85fdb25c2Jean Chalard mDicTypeId, Dictionary.BIGRAM); 163979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 164979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 165923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 166923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 167043f7841985916717f4fa821fe3e423daf3ff2f5Jean Chalard // proximityInfo may not be null. 168923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 169043f7841985916717f4fa821fe3e423daf3ff2f5Jean Chalard public void getWords(final WordComposer codes, final WordCallback callback, 170043f7841985916717f4fa821fe3e423daf3ff2f5Jean Chalard final ProximityInfo proximityInfo) { 171043f7841985916717f4fa821fe3e423daf3ff2f5Jean Chalard final int count = getSuggestions(codes, proximityInfo, mOutputChars, mScores); 1726f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka 1736f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka for (int j = 0; j < count; ++j) { 174e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka if (mScores[j] < 1) break; 1756f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka final int start = j * MAX_WORD_LENGTH; 1766f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka int len = 0; 1776f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka while (len < MAX_WORD_LENGTH && mOutputChars[start + len] != 0) { 1786f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka ++len; 1796f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka } 1806f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka if (len > 0) { 181e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka callback.addWord(mOutputChars, start, len, mScores[j], mDicTypeId, 1826e082cb30dbe1a8cc314b474dc1377b85fdb25c2Jean Chalard Dictionary.UNIGRAM); 1836f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka } 1846f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka } 1856f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka } 1866f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka 1876f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka /* package for test */ boolean isValidDictionary() { 1886f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka return mNativeDict != 0; 1896f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka } 1906f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka 191043f7841985916717f4fa821fe3e423daf3ff2f5Jean Chalard // proximityInfo may not be null. 192043f7841985916717f4fa821fe3e423daf3ff2f5Jean Chalard /* package for test */ int getSuggestions(final WordComposer codes, 193043f7841985916717f4fa821fe3e423daf3ff2f5Jean Chalard final ProximityInfo proximityInfo, char[] outputChars, int[] scores) { 1946f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka if (!isValidDictionary()) return -1; 195da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa 196923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final int codesSize = codes.size(); 197979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Won't deal with really long words. 1986f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka if (codesSize > MAX_WORD_LENGTH - 1) return -1; 19930088259480130e5bac5c2028e2c7c3e6d4c51a2satok 200887f11ee43ad621aa6ad93d535ab7f48dec73fc7Tadashi G. Takaoka Arrays.fill(mInputCodes, WordComposer.NOT_A_CODE); 201923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project for (int i = 0; i < codesSize; i++) { 20201ab7c8b59a7f12862fbd95fb252e56719f1757fsatok mInputCodes[i] = codes.getCodeAt(i); 203923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2042e04770adfc16344f69d316efd3ed0a617ede330Tadashi G. Takaoka Arrays.fill(outputChars, (char) 0); 205e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka Arrays.fill(scores, 0); 206c3df2d6fd27f3a5b84040b59aece3367769f0cb6Amith Yamasani 2076f4eba814a7f8426617db61f928a965209ebf359Tadashi G. Takaoka return getSuggestionsNative( 208043f7841985916717f4fa821fe3e423daf3ff2f5Jean Chalard mNativeDict, proximityInfo.getNativeProximityInfo(), 2098fbd55229243cb66c03d5ea1f79dfb39f596590dsatok codes.getXCoordinates(), codes.getYCoordinates(), mInputCodes, codesSize, 210e7a2512aa3666e1b891dc7dfc5a0cb28fd66bea9Tadashi G. Takaoka mFlags, outputChars, scores); 211923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 212923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 213be0cf72253f15bff6abdeaa79f60a56f06ab7b86satok public static double calcNormalizedScore(String before, String after, int score) { 214be0cf72253f15bff6abdeaa79f60a56f06ab7b86satok return calcNormalizedScoreNative(before.toCharArray(), before.length(), 215be0cf72253f15bff6abdeaa79f60a56f06ab7b86satok after.toCharArray(), after.length(), score); 216be0cf72253f15bff6abdeaa79f60a56f06ab7b86satok } 217be0cf72253f15bff6abdeaa79f60a56f06ab7b86satok 218be0cf72253f15bff6abdeaa79f60a56f06ab7b86satok public static int editDistance(String before, String after) { 219be0cf72253f15bff6abdeaa79f60a56f06ab7b86satok return editDistanceNative( 220be0cf72253f15bff6abdeaa79f60a56f06ab7b86satok before.toCharArray(), before.length(), after.toCharArray(), after.length()); 221be0cf72253f15bff6abdeaa79f60a56f06ab7b86satok } 222be0cf72253f15bff6abdeaa79f60a56f06ab7b86satok 223923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 224923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean isValidWord(CharSequence word) { 225923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (word == null) return false; 226f590a497393eb77875017010e9a36cf33b095e3cAmith Yamasani char[] chars = word.toString().toCharArray(); 227923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return isValidWordNative(mNativeDict, chars, chars.length); 228923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 229c3df2d6fd27f3a5b84040b59aece3367769f0cb6Amith Yamasani 23036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani @Override 231923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public synchronized void close() { 232da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa closeInternal(); 233da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa } 234da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa 235da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa private void closeInternal() { 236923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mNativeDict != 0) { 237923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project closeNative(mNativeDict); 238923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mNativeDict = 0; 239923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 240923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 241923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 242923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 243923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project protected void finalize() throws Throwable { 244da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa try { 245da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa closeInternal(); 246da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa } finally { 247da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa super.finalize(); 248da50e1e98dadc3733c615dfb8d87fe8b4688c782Ken Wakasa } 249923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 250923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project} 251