diff options
-rw-r--r-- | native/src/binary_format.h | 4 | ||||
-rw-r--r-- | native/src/dictionary.h | 75 | ||||
-rw-r--r-- | native/src/unigram_dictionary.cpp | 7 | ||||
-rw-r--r-- | tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTests.java | 113 | ||||
-rw-r--r-- | tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java | 148 |
5 files changed, 163 insertions, 184 deletions
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 bbae5a864..ca7f0be0c 100644 --- a/native/src/unigram_dictionary.cpp +++ b/native/src/unigram_dictionary.cpp @@ -280,7 +280,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)); @@ -507,9 +507,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 006a57266..a47e2e5a1 100644 --- a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTests.java +++ b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTests.java @@ -19,105 +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; - } - - @Override - public void requestUpdatingShiftState() { - mState.onUpdateShiftState(mAutoCaps); - } - - 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 @@ -138,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. @@ -231,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 |