diff options
11 files changed, 229 insertions, 197 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 2add2921b..54d842f09 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -324,6 +324,12 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions, setKeyboard(mKeyboardSet.getSymbolsShiftedKeyboard()); } + // Implements {@link KeyboardState.SwitchActions}. + @Override + public void requestUpdatingShiftState() { + mState.onUpdateShiftState(mInputMethodService.getCurrentAutoCapsState()); + } + public boolean isInMomentarySwitchState() { return mState.isInMomentarySwitchState(); } diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java index f54bdbb05..42f069c83 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java @@ -53,6 +53,11 @@ public class KeyboardState { public void setSymbolsKeyboard(); public void setSymbolsShiftedKeyboard(); + + /** + * Request to call back {@link KeyboardState#onUpdateShiftState(boolean)}. + */ + public void requestUpdatingShiftState(); } private KeyboardShiftState mKeyboardShiftState = new KeyboardShiftState(); @@ -212,6 +217,7 @@ public class KeyboardState { mSwitchState = SWITCH_STATE_ALPHA; setShiftLocked(mPrevMainKeyboardWasShiftLocked); mPrevMainKeyboardWasShiftLocked = false; + mSwitchActions.requestUpdatingShiftState(); } private void setSymbolsKeyboard() { diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 59de798d8..e60f55060 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -1019,7 +1019,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar @Override public boolean onEvaluateFullscreenMode() { - return super.onEvaluateFullscreenMode() && mSettingsValues.mUseFullScreenMode; + // Reread resource value here, because this method is called by framework anytime as needed. + final boolean isFullscreenModeAllowed = + mSettingsValues.isFullscreenModeAllowed(getResources()); + return super.onEvaluateFullscreenMode() && isFullscreenModeAllowed; } @Override diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java index 83b27f7fe..0ae28d3fc 100644 --- a/java/src/com/android/inputmethod/latin/SettingsValues.java +++ b/java/src/com/android/inputmethod/latin/SettingsValues.java @@ -41,7 +41,6 @@ public class SettingsValues { private final String mSymbolsExcludedFromWordSeparators; public final String mWordSeparators; public final CharSequence mHintToSaveText; - public final boolean mUseFullScreenMode; // From preferences, in the same order as xml/prefs.xml: public final boolean mAutoCap; @@ -107,7 +106,6 @@ public class SettingsValues { mWordSeparators = createWordSeparators(mMagicSpaceStrippers, mMagicSpaceSwappers, mSymbolsExcludedFromWordSeparators, res); mHintToSaveText = context.getText(R.string.hint_add_to_dictionary); - mUseFullScreenMode = res.getBoolean(R.bool.config_use_fullscreen_mode); // Get the settings preferences mAutoCap = prefs.getBoolean(Settings.PREF_AUTO_CAP, true); @@ -294,6 +292,10 @@ public class SettingsValues { return mVoiceKeyOnMain; } + public boolean isFullscreenModeAllowed(Resources res) { + return res.getBoolean(R.bool.config_use_fullscreen_mode); + } + // Accessed from the settings interface, hence public public static float getCurrentKeypressSoundVolume(final SharedPreferences sp, final Resources res) { diff --git a/native/src/binary_format.h b/native/src/binary_format.h index 9944fa2bd..1d74998f6 100644 --- a/native/src/binary_format.h +++ b/native/src/binary_format.h @@ -61,7 +61,9 @@ inline int BinaryFormat::detectFormat(const uint8_t* const dict) { } inline int BinaryFormat::getGroupCountAndForwardPointer(const uint8_t* const dict, int* pos) { - return dict[(*pos)++]; + const int msb = dict[(*pos)++]; + if (msb < 0x80) return msb; + return ((msb & 0x7F) << 8) | dict[(*pos)++]; } inline uint8_t BinaryFormat::getFlagsAndForwardPointer(const uint8_t* const dict, int* pos) { diff --git a/native/src/dictionary.h b/native/src/dictionary.h index 79d377a4f..90d7148d5 100644 --- a/native/src/dictionary.h +++ b/native/src/dictionary.h @@ -56,16 +56,7 @@ class Dictionary { // public static utility methods // static inline methods should be defined in the header file - static unsigned short getChar(const unsigned char *dict, int *pos); - static int getCount(const unsigned char *dict, int *pos); - static bool getTerminal(const unsigned char *dict, int *pos); - static int getAddress(const unsigned char *dict, int *pos); - static int getFreq(const unsigned char *dict, const bool isLatestDictVersion, int *pos); static int wideStrLen(unsigned short *str); - // returns next sibling's position - static int setDictionaryValues(const unsigned char *dict, const bool isLatestDictVersion, - const int pos, unsigned short *c, int *childrenPosition, - bool *terminal, int *freq); private: bool hasBigram(); @@ -87,56 +78,6 @@ class Dictionary { // public static utility methods // static inline methods should be defined in the header file -inline unsigned short Dictionary::getChar(const unsigned char *dict, int *pos) { - unsigned short ch = (unsigned short) (dict[(*pos)++] & 0xFF); - // If the code is 255, then actual 16 bit code follows (in big endian) - if (ch == 0xFF) { - ch = ((dict[*pos] & 0xFF) << 8) | (dict[*pos + 1] & 0xFF); - (*pos) += 2; - } - return ch; -} - -inline int Dictionary::getCount(const unsigned char *dict, int *pos) { - return dict[(*pos)++] & 0xFF; -} - -inline bool Dictionary::getTerminal(const unsigned char *dict, int *pos) { - return (dict[*pos] & FLAG_TERMINAL_MASK) > 0; -} - -inline int Dictionary::getAddress(const unsigned char *dict, int *pos) { - int address = 0; - if ((dict[*pos] & FLAG_ADDRESS_MASK) == 0) { - *pos += 1; - } else { - address += (dict[*pos] & (ADDRESS_MASK >> 16)) << 16; - address += (dict[*pos + 1] & 0xFF) << 8; - address += (dict[*pos + 2] & 0xFF); - *pos += 3; - } - return address; -} - -inline int Dictionary::getFreq(const unsigned char *dict, - const bool isLatestDictVersion, int *pos) { - int freq = dict[(*pos)++] & 0xFF; - if (isLatestDictVersion) { - // skipping bigram - int bigramExist = (dict[*pos] & FLAG_BIGRAM_READ); - if (bigramExist > 0) { - int nextBigramExist = 1; - while (nextBigramExist > 0) { - (*pos) += 3; - nextBigramExist = (dict[(*pos)++] & FLAG_BIGRAM_CONTINUED); - } - } else { - (*pos)++; - } - } - return freq; -} - inline int Dictionary::wideStrLen(unsigned short *str) { if (!str) return 0; unsigned short *end = str; @@ -144,22 +85,6 @@ inline int Dictionary::wideStrLen(unsigned short *str) { end++; return end - str; } - -inline int Dictionary::setDictionaryValues(const unsigned char *dict, - const bool isLatestDictVersion, const int pos, unsigned short *c,int *childrenPosition, - bool *terminal, int *freq) { - int position = pos; - // -- at char - *c = Dictionary::getChar(dict, &position); - // -- at flag/add - *terminal = Dictionary::getTerminal(dict, &position); - *childrenPosition = Dictionary::getAddress(dict, &position); - // -- after address or flag - *freq = (*terminal) ? Dictionary::getFreq(dict, isLatestDictVersion, &position) : 1; - // returns next sibling's position - return position; -} - } // namespace latinime #endif // LATINIME_DICTIONARY_H diff --git a/native/src/unigram_dictionary.cpp b/native/src/unigram_dictionary.cpp index 1cff4d838..85e7e9bf2 100644 --- a/native/src/unigram_dictionary.cpp +++ b/native/src/unigram_dictionary.cpp @@ -277,7 +277,7 @@ void UnigramDictionary::getSuggestionCandidates(const bool useFullEditDistance, doAutoCompletion, maxErrors); int rootPosition = ROOT_POS; // Get the number of children of root, then increment the position - int childCount = Dictionary::getCount(DICT_ROOT, &rootPosition); + int childCount = BinaryFormat::getGroupCountAndForwardPointer(DICT_ROOT, &rootPosition); int outputIndex = 0; correction->initCorrectionState(rootPosition, childCount, (inputLength <= 0)); @@ -523,9 +523,10 @@ int UnigramDictionary::getMostFrequentWordLikeInner(const uint16_t * const inWor int maxFreq = -1; const uint8_t* const root = DICT_ROOT; - mStackChildCount[0] = root[0]; + int startPos = 0; + mStackChildCount[0] = BinaryFormat::getGroupCountAndForwardPointer(root, &startPos); mStackInputIndex[0] = 0; - mStackSiblingPos[0] = 1; + mStackSiblingPos[0] = startPos; while (depth >= 0) { const int charGroupCount = mStackChildCount[depth]; int pos = mStackSiblingPos[depth]; diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTests.java index 9dc1fac3e..a47e2e5a1 100644 --- a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTests.java +++ b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTests.java @@ -19,101 +19,8 @@ package com.android.inputmethod.keyboard.internal; import android.test.AndroidTestCase; import com.android.inputmethod.keyboard.Keyboard; -import com.android.inputmethod.keyboard.internal.KeyboardState.SwitchActions; public class KeyboardStateTests extends AndroidTestCase { - private static final int ALPHABET_UNSHIFTED = 0; - private static final int ALPHABET_MANUAL_SHIFTED = 1; - private static final int ALPHABET_AUTOMATIC_SHIFTED = 2; - private static final int ALPHABET_SHIFT_LOCKED = 3; - private static final int SYMBOLS_UNSHIFTED = 4; - private static final int SYMBOLS_SHIFTED = 5; - - static class MockKeyboardSwitcher implements KeyboardState.SwitchActions { - public int mLayout = ALPHABET_UNSHIFTED; - - public boolean mAutoCaps = NO_AUTO_CAPS; - - final KeyboardState mState = new KeyboardState(this); - - @Override - public void setAlphabetKeyboard() { - mLayout = ALPHABET_UNSHIFTED; - } - - @Override - public void setShifted(int shiftMode) { - if (shiftMode == SwitchActions.UNSHIFT) { - mLayout = ALPHABET_UNSHIFTED; - } else if (shiftMode == SwitchActions.MANUAL_SHIFT) { - mLayout = ALPHABET_MANUAL_SHIFTED; - } else if (shiftMode == SwitchActions.AUTOMATIC_SHIFT) { - mLayout = ALPHABET_AUTOMATIC_SHIFTED; - } - } - - @Override - public void setShiftLocked(boolean shiftLocked) { - if (shiftLocked) { - mLayout = ALPHABET_SHIFT_LOCKED; - } else { - mLayout = ALPHABET_UNSHIFTED; - } - } - - @Override - public void setSymbolsKeyboard() { - mLayout = SYMBOLS_UNSHIFTED; - } - - @Override - public void setSymbolsShiftedKeyboard() { - mLayout = SYMBOLS_SHIFTED; - } - - public void toggleCapsLock() { - mState.onToggleCapsLock(); - } - - public void updateShiftState() { - mState.onUpdateShiftState(mAutoCaps); - } - - public void loadKeyboard(String layoutSwitchBackSymbols, - boolean hasDistinctMultitouch) { - mState.onLoadKeyboard(layoutSwitchBackSymbols, hasDistinctMultitouch); - } - - public void onPressShift(boolean withSliding) { - mState.onPressShift(withSliding); - } - - public void onReleaseShift(boolean withSliding) { - mState.onReleaseShift(withSliding); - } - - public void onPressSymbol() { - mState.onPressSymbol(); - } - - public void onReleaseSymbol() { - mState.onReleaseSymbol(); - } - - public void onOtherKeyPressed() { - mState.onOtherKeyPressed(); - } - - public void onCodeInput(int code, boolean isSinglePointer) { - mState.onCodeInput(code, isSinglePointer, mAutoCaps); - } - - public void onCancelInput(boolean isSinglePointer) { - mState.onCancelInput(isSinglePointer); - } - - } - private MockKeyboardSwitcher mSwitcher; @Override @@ -134,31 +41,31 @@ public class KeyboardStateTests extends AndroidTestCase { // Argument for KeyboardState.onCodeInput. private static final boolean SINGLE = true; private static final boolean MULTI = false; - private static final boolean NO_AUTO_CAPS = false; + static final boolean NO_AUTO_CAPS = false; private static final boolean AUTO_CAPS = true; private void assertAlphabetNormal() { - assertEquals(ALPHABET_UNSHIFTED, mSwitcher.mLayout); + assertTrue(mSwitcher.assertAlphabetNormal()); } private void assertAlphabetManualShifted() { - assertEquals(ALPHABET_MANUAL_SHIFTED, mSwitcher.mLayout); + assertTrue(mSwitcher.assertAlphabetManualShifted()); } private void assertAlphabetAutomaticShifted() { - assertEquals(ALPHABET_AUTOMATIC_SHIFTED, mSwitcher.mLayout); + assertTrue(mSwitcher.assertAlphabetAutomaticShifted()); } private void assertAlphabetShiftLocked() { - assertEquals(ALPHABET_SHIFT_LOCKED, mSwitcher.mLayout); + assertTrue(mSwitcher.assertAlphabetShiftLocked()); } private void assertSymbolsNormal() { - assertEquals(SYMBOLS_UNSHIFTED, mSwitcher.mLayout); + assertTrue(mSwitcher.assertSymbolsNormal()); } private void assertSymbolsShifted() { - assertEquals(SYMBOLS_SHIFTED, mSwitcher.mLayout); + assertTrue(mSwitcher.assertSymbolsShifted()); } // Initial state test. @@ -227,7 +134,7 @@ public class KeyboardStateTests extends AndroidTestCase { // Automatic upper case test public void testAutomaticUpperCase() { - mSwitcher.mAutoCaps = AUTO_CAPS; + mSwitcher.setAutoCapsMode(AUTO_CAPS); // Update shift state with auto caps enabled. mSwitcher.updateShiftState(); assertAlphabetAutomaticShifted(); diff --git a/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java b/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java new file mode 100644 index 000000000..d5c647cd2 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.keyboard.internal; + +import com.android.inputmethod.keyboard.internal.KeyboardState.SwitchActions; + +public class MockKeyboardSwitcher implements KeyboardState.SwitchActions { + public static final String WORD_SEPARATORS = " ,."; + + private static final int ALPHABET_UNSHIFTED = 0; + private static final int ALPHABET_MANUAL_SHIFTED = 1; + private static final int ALPHABET_AUTOMATIC_SHIFTED = 2; + private static final int ALPHABET_SHIFT_LOCKED = 3; + private static final int SYMBOLS_UNSHIFTED = 4; + private static final int SYMBOLS_SHIFTED = 5; + + private int mLayout = ALPHABET_UNSHIFTED; + + private boolean mAutoCapsMode = KeyboardStateTests.NO_AUTO_CAPS; + // Following InputConnection's behavior. Simulating InputType.TYPE_TEXT_FLAG_CAP_WORDS. + private boolean mAutoCapsState = true; + + private final KeyboardState mState = new KeyboardState(this); + + public boolean assertAlphabetNormal() { + return mLayout == ALPHABET_UNSHIFTED; + } + + public boolean assertAlphabetManualShifted() { + return mLayout == ALPHABET_MANUAL_SHIFTED; + } + + public boolean assertAlphabetAutomaticShifted() { + return mLayout == ALPHABET_AUTOMATIC_SHIFTED; + } + + public boolean assertAlphabetShiftLocked() { + return mLayout == ALPHABET_SHIFT_LOCKED; + } + + public boolean assertSymbolsNormal() { + return mLayout == SYMBOLS_UNSHIFTED; + } + + public boolean assertSymbolsShifted() { + return mLayout == SYMBOLS_SHIFTED; + } + + public void setAutoCapsMode(boolean autoCaps) { + mAutoCapsMode = autoCaps; + } + + @Override + public void setAlphabetKeyboard() { + mLayout = ALPHABET_UNSHIFTED; + } + + @Override + public void setShifted(int shiftMode) { + if (shiftMode == SwitchActions.UNSHIFT) { + mLayout = ALPHABET_UNSHIFTED; + } else if (shiftMode == SwitchActions.MANUAL_SHIFT) { + mLayout = ALPHABET_MANUAL_SHIFTED; + } else if (shiftMode == SwitchActions.AUTOMATIC_SHIFT) { + mLayout = ALPHABET_AUTOMATIC_SHIFTED; + } + } + + @Override + public void setShiftLocked(boolean shiftLocked) { + if (shiftLocked) { + mLayout = ALPHABET_SHIFT_LOCKED; + } else { + mLayout = ALPHABET_UNSHIFTED; + } + } + + @Override + public void setSymbolsKeyboard() { + mLayout = SYMBOLS_UNSHIFTED; + } + + @Override + public void setSymbolsShiftedKeyboard() { + mLayout = SYMBOLS_SHIFTED; + } + + @Override + public void requestUpdatingShiftState() { + mState.onUpdateShiftState(mAutoCapsMode && mAutoCapsState); + } + + public void toggleCapsLock() { + mState.onToggleCapsLock(); + } + + public void updateShiftState() { + mState.onUpdateShiftState(mAutoCapsMode && mAutoCapsState); + } + + public void loadKeyboard(String layoutSwitchBackSymbols, + boolean hasDistinctMultitouch) { + mState.onLoadKeyboard(layoutSwitchBackSymbols, hasDistinctMultitouch); + } + + public void onPressShift(boolean withSliding) { + mState.onPressShift(withSliding); + } + + public void onReleaseShift(boolean withSliding) { + mState.onReleaseShift(withSliding); + } + + public void onPressSymbol() { + mState.onPressSymbol(); + } + + public void onReleaseSymbol() { + mState.onReleaseSymbol(); + } + + public void onOtherKeyPressed() { + mState.onOtherKeyPressed(); + } + + public void onCodeInput(int code, boolean isSinglePointer) { + mAutoCapsState = (WORD_SEPARATORS.indexOf(code) >= 0); + mState.onCodeInput(code, isSinglePointer, mAutoCapsMode && mAutoCapsState); + } + + public void onCancelInput(boolean isSinglePointer) { + mState.onCancelInput(isSinglePointer); + } +}
\ No newline at end of file diff --git a/tools/makedict/src/com/android/inputmethod/latin/BinaryDictInputOutput.java b/tools/makedict/src/com/android/inputmethod/latin/BinaryDictInputOutput.java index fcbb645f5..ae54c5d77 100644 --- a/tools/makedict/src/com/android/inputmethod/latin/BinaryDictInputOutput.java +++ b/tools/makedict/src/com/android/inputmethod/latin/BinaryDictInputOutput.java @@ -144,7 +144,6 @@ public class BinaryDictInputOutput { private static final int GROUP_CHARACTERS_TERMINATOR = 0x1F; - private static final int GROUP_COUNT_SIZE = 1; private static final int GROUP_TERMINATOR_SIZE = 1; private static final int GROUP_FLAGS_SIZE = 1; private static final int GROUP_FREQUENCY_SIZE = 1; @@ -155,9 +154,8 @@ public class BinaryDictInputOutput { private static final int NO_CHILDREN_ADDRESS = Integer.MIN_VALUE; private static final int INVALID_CHARACTER = -1; - // Limiting to 127 for upward compatibility - // TODO: implement a scheme to be able to shoot 256 chargroups in a node - private static final int MAX_CHARGROUPS_IN_A_NODE = 127; + private static final int MAX_CHARGROUPS_FOR_ONE_BYTE_CHARGROUP_COUNT = 0x7F; // 127 + private static final int MAX_CHARGROUPS_IN_A_NODE = 0x7FFF; // 32767 private static final int MAX_TERMINAL_FREQUENCY = 255; @@ -267,6 +265,22 @@ public class BinaryDictInputOutput { } /** + * Compute the binary size of the group count for a node + * @param node the node + * @return the size of the group count, either 1 or 2 bytes. + */ + private static int getGroupCountSize(final Node node) { + if (MAX_CHARGROUPS_FOR_ONE_BYTE_CHARGROUP_COUNT >= node.mData.size()) { + return 1; + } else if (MAX_CHARGROUPS_IN_A_NODE >= node.mData.size()) { + return 2; + } else { + throw new RuntimeException("Can't have more than " + MAX_CHARGROUPS_IN_A_NODE + + " groups in a node (found " + node.mData.size() +")"); + } + } + + /** * Compute the maximum size of a CharGroup, assuming 3-byte addresses for everything. * * @param group the CharGroup to compute the size of. @@ -295,7 +309,7 @@ public class BinaryDictInputOutput { * @param node the node to compute the maximum size of. */ private static void setNodeMaximumSize(Node node) { - int size = GROUP_COUNT_SIZE; + int size = getGroupCountSize(node); for (CharGroup g : node.mData) { final int groupSize = getCharGroupMaximumSize(g); g.mCachedSize = groupSize; @@ -394,7 +408,7 @@ public class BinaryDictInputOutput { * @param dict the dictionary in which the word/attributes are to be found. */ private static void computeActualNodeSize(Node node, FusionDictionary dict) { - int size = GROUP_COUNT_SIZE; + int size = getGroupCountSize(node); for (CharGroup group : node.mData) { int groupSize = GROUP_FLAGS_SIZE + getGroupCharactersSize(group); if (group.isTerminal()) groupSize += GROUP_FREQUENCY_SIZE; @@ -437,12 +451,13 @@ public class BinaryDictInputOutput { int nodeOffset = 0; for (Node n : flatNodes) { n.mCachedAddress = nodeOffset; + int groupCountSize = getGroupCountSize(n); int groupOffset = 0; for (CharGroup g : n.mData) { - g.mCachedAddress = GROUP_COUNT_SIZE + nodeOffset + groupOffset; + g.mCachedAddress = groupCountSize + nodeOffset + groupOffset; groupOffset += g.mCachedSize; } - if (groupOffset + GROUP_COUNT_SIZE != n.mCachedSize) { + if (groupOffset + groupCountSize != n.mCachedSize) { throw new RuntimeException("Bug : Stored and computed node size differ"); } nodeOffset += n.mCachedSize; @@ -629,13 +644,20 @@ public class BinaryDictInputOutput { private static int writePlacedNode(FusionDictionary dict, byte[] buffer, Node node) { int index = node.mCachedAddress; - final int size = node.mData.size(); - if (size > MAX_CHARGROUPS_IN_A_NODE) - throw new RuntimeException("A node has a group count over 127 (" + size + ")."); - - buffer[index++] = (byte)size; + final int groupCount = node.mData.size(); + final int countSize = getGroupCountSize(node); + if (1 == countSize) { + buffer[index++] = (byte)groupCount; + } else if (2 == countSize) { + // We need to signal 2-byte size by setting the top bit of the MSB to 1, so + // we | 0x80 to do this. + buffer[index++] = (byte)((groupCount >> 8) | 0x80); + buffer[index++] = (byte)(groupCount & 0xFF); + } else { + throw new RuntimeException("Strange size from getGroupCountSize : " + countSize); + } int groupAddress = index; - for (int i = 0; i < size; ++i) { + for (int i = 0; i < groupCount; ++i) { CharGroup group = node.mData.get(i); if (index != group.mCachedAddress) throw new RuntimeException("Bug: write index is not " + "the same as the cached address of the group"); diff --git a/tools/makedict/src/com/android/inputmethod/latin/FusionDictionary.java b/tools/makedict/src/com/android/inputmethod/latin/FusionDictionary.java index 2327e1972..3ab206d80 100644 --- a/tools/makedict/src/com/android/inputmethod/latin/FusionDictionary.java +++ b/tools/makedict/src/com/android/inputmethod/latin/FusionDictionary.java @@ -435,6 +435,16 @@ public class FusionDictionary implements Iterable<Word> { } /** + * Helper method to find out whether a word is in the dict or not. + */ + public boolean hasWord(final String s) { + if (null == s || "".equals(s)) { + throw new RuntimeException("Can't search for a null or empty string"); + } + return null != findWordInTree(mRoot, s); + } + + /** * Recursively count the number of character groups in a given branch of the trie. * * @param node the parent node. |