aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--java/res/values-mn-rMN/strings.xml2
-rw-r--r--java/res/xml-sw600dp/key_azerty3_right.xml29
-rw-r--r--java/res/xml/key_azerty3_right.xml37
-rw-r--r--java/res/xml/rowkeys_azerty3.xml15
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionary.java14
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java1
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java1
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java6
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/DictionaryHeader.java2
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/FormatSpec.java41
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java82
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/PtNodeInfo.java3
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java1
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java1
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java1
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java1
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/WeightedString.java62
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/WordProperty.java1
-rw-r--r--java/src/com/android/inputmethod/latin/utils/CombinedFormatUtils.java2
-rw-r--r--java/src/com/android/inputmethod/latin/utils/StringUtils.java40
-rw-r--r--native/jni/NativeFileList.mk4
-rw-r--r--native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp67
-rw-r--r--native/jni/src/defines.h3
-rw-r--r--native/jni/src/suggest/core/dicnode/dic_node.cpp2
-rw-r--r--native/jni/src/suggest/core/dicnode/dic_node.h2
-rw-r--r--native/jni/src/suggest/core/dicnode/dic_node_priority_queue.h3
-rw-r--r--native/jni/src/suggest/core/dicnode/dic_node_utils.cpp5
-rw-r--r--native/jni/src/suggest/core/dicnode/dic_nodes_cache.h3
-rw-r--r--native/jni/src/suggest/core/dicnode/internal/dic_node_state_output.h4
-rw-r--r--native/jni/src/suggest/core/dicnode/internal/dic_node_state_prevword.h3
-rw-r--r--native/jni/src/suggest/core/dicnode/internal/dic_node_state_scoring.h3
-rw-r--r--native/jni/src/suggest/core/dictionary/bigram_dictionary.cpp82
-rw-r--r--native/jni/src/suggest/core/dictionary/bigram_dictionary.h7
-rw-r--r--native/jni/src/suggest/core/dictionary/dictionary.cpp39
-rw-r--r--native/jni/src/suggest/core/dictionary/dictionary.h15
-rw-r--r--native/jni/src/suggest/core/dictionary/digraph_utils.cpp10
-rw-r--r--native/jni/src/suggest/core/layout/proximity_info.cpp3
-rw-r--r--native/jni/src/suggest/core/layout/proximity_info_state.cpp3
-rw-r--r--native/jni/src/suggest/core/layout/proximity_info_state.h2
-rw-r--r--native/jni/src/suggest/core/layout/proximity_info_state_utils.cpp30
-rw-r--r--native/jni/src/suggest/core/layout/proximity_info_utils.h7
-rw-r--r--native/jni/src/suggest/core/layout/touch_position_correction_utils.h4
-rw-r--r--native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h5
-rw-r--r--native/jni/src/suggest/core/result/suggested_word.h83
-rw-r--r--native/jni/src/suggest/core/result/suggestion_results.cpp77
-rw-r--r--native/jni/src/suggest/core/result/suggestion_results.h53
-rw-r--r--native/jni/src/suggest/core/result/suggestions_output_utils.cpp8
-rw-r--r--native/jni/src/suggest/core/session/dic_traverse_session.h4
-rw-r--r--native/jni/src/suggest/core/suggest.h6
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/header/header_policy.cpp4
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/shortcut/ver4_shortcut_list_policy.h4
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.cpp44
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.h1
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h11
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/single_dict_content.h10
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/sparse_table_dict_content.h20
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.cpp30
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h10
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp26
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h19
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.cpp2
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/utils/dict_file_writing_utils.cpp10
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.cpp11
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/utils/mmapped_buffer.cpp10
-rw-r--r--native/jni/src/suggest/policyimpl/dictionary/utils/mmapped_buffer.h8
-rw-r--r--native/jni/src/suggest/policyimpl/utils/edit_distance.h12
-rw-r--r--native/jni/src/utils/autocorrection_threshold_utils.cpp3
-rw-r--r--native/jni/src/utils/exclusive_ownership_pointer.h81
-rw-r--r--tests/src/com/android/inputmethod/keyboard/layout/AlphabetShifted.java46
-rw-r--r--tests/src/com/android/inputmethod/keyboard/layout/Qwerty.java46
-rw-r--r--tests/src/com/android/inputmethod/keyboard/layout/Symbols.java187
-rw-r--r--tests/src/com/android/inputmethod/keyboard/layout/SymbolsShifted.java142
-rw-r--r--tests/src/com/android/inputmethod/keyboard/layout/expected/ActualKeyboardBuilder.java200
-rw-r--r--tests/src/com/android/inputmethod/keyboard/layout/expected/LayoutBase.java143
-rw-r--r--tests/src/com/android/inputmethod/keyboard/layout/tests/LayoutTestsBase.java197
-rw-r--r--tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishUS.java98
-rw-r--r--tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java2
-rw-r--r--tests/src/com/android/inputmethod/latin/FusionDictionaryTests.java3
-rw-r--r--tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java1
-rw-r--r--tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java2
-rw-r--r--tools/dicttool/Android.mk8
-rw-r--r--tools/dicttool/NativeLib.mk8
-rw-r--r--tools/dicttool/src/com/android/inputmethod/latin/dicttool/CombinedInputOutput.java4
-rw-r--r--tools/dicttool/src/com/android/inputmethod/latin/dicttool/Diff.java2
-rw-r--r--tools/dicttool/src/com/android/inputmethod/latin/dicttool/Info.java2
-rw-r--r--tools/dicttool/src/com/android/inputmethod/latin/dicttool/XmlDictInputOutput.java4
-rw-r--r--tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java2
-rw-r--r--tools/dicttool/tests/com/android/inputmethod/latin/makedict/BinaryDictEncoderFlattenTreeTests.java2
-rw-r--r--tools/dicttool/tests/com/android/inputmethod/latin/makedict/FusionDictionaryTest.java2
89 files changed, 1732 insertions, 564 deletions
diff --git a/java/res/values-mn-rMN/strings.xml b/java/res/values-mn-rMN/strings.xml
index ef8181faf..6c9740329 100644
--- a/java/res/values-mn-rMN/strings.xml
+++ b/java/res/values-mn-rMN/strings.xml
@@ -167,7 +167,7 @@
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"Суулгах толь бичгийн файлыг сонгоно уу"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"<xliff:g id="LANGUAGE_NAME">%s</xliff:g>-д зориулсан энэ файлыг үнэхээр суулгах уу?"</string>
<string name="error" msgid="8940763624668513648">"Алдаа гарсан"</string>
- <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Харилцагчдын толь бичгийг хаях"</string>
+ <string name="prefs_dump_contacts_dict" msgid="7227327764402323097">"Харилцагчдын толь бичгийг жагсаах"</string>
<string name="prefs_dump_user_dict" msgid="294870685041741951">"Хувийн толь бичгийг хаях"</string>
<string name="prefs_dump_user_history_dict" msgid="6821075152449554628">"Хэрэглэгчийн түүхийн толь бичгийг хаях"</string>
<string name="prefs_dump_personalization_dict" msgid="7558387996151745284">"Хувийн тохиргоотой толь бичгийг хаях"</string>
diff --git a/java/res/xml-sw600dp/key_azerty3_right.xml b/java/res/xml-sw600dp/key_azerty3_right.xml
deleted file mode 100644
index 25b0e52b8..000000000
--- a/java/res/xml-sw600dp/key_azerty3_right.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <Key
- latin:keySpec=":"
- latin:keyHintLabel=";"
- latin:moreKeys=";"
- latin:keyStyle="hasShiftedLetterHintStyle" />
-</merge>
diff --git a/java/res/xml/key_azerty3_right.xml b/java/res/xml/key_azerty3_right.xml
deleted file mode 100644
index 85a066613..000000000
--- a/java/res/xml/key_azerty3_right.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 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.
-*/
--->
-
-<merge
- xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
->
- <switch>
- <case
- latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLockShifted"
- >
- <Key
- latin:keySpec="\?" />
- </case>
- <default>
- <Key
- latin:keySpec="\'"
- latin:moreKeys="!text/more_keys_for_single_quote" />
- </default>
- </switch>
-</merge>
diff --git a/java/res/xml/rowkeys_azerty3.xml b/java/res/xml/rowkeys_azerty3.xml
index 0aa215305..c955e237c 100644
--- a/java/res/xml/rowkeys_azerty3.xml
+++ b/java/res/xml/rowkeys_azerty3.xml
@@ -37,6 +37,17 @@
<Key
latin:keySpec="n"
latin:moreKeys="!text/more_keys_for_n" />
- <include
- latin:keyboardLayout="@xml/key_azerty3_right" />
+ <switch>
+ <case
+ latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLockShifted"
+ >
+ <Key
+ latin:keySpec="\?" />
+ </case>
+ <default>
+ <Key
+ latin:keySpec="\'"
+ latin:moreKeys="!text/more_keys_for_single_quote" />
+ </default>
+ </switch>
</merge>
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index a3a329a71..544fd0319 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -25,7 +25,7 @@ import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.makedict.DictionaryHeader;
import com.android.inputmethod.latin.makedict.FormatSpec;
-import com.android.inputmethod.latin.makedict.FusionDictionary.DictionaryOptions;
+import com.android.inputmethod.latin.makedict.FormatSpec.DictionaryOptions;
import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
import com.android.inputmethod.latin.makedict.WordProperty;
import com.android.inputmethod.latin.personalization.PersonalizationHelper;
@@ -87,6 +87,7 @@ public final class BinaryDictionary extends Dictionary {
private final String mDictFilePath;
private final boolean mIsUpdatable;
private final int[] mInputCodePoints = new int[MAX_WORD_LENGTH];
+ private final int[] mOutputSuggestionCount = new int[1];
private final int[] mOutputCodePoints = new int[MAX_WORD_LENGTH * MAX_RESULTS];
private final int[] mSpaceIndices = new int[MAX_RESULTS];
private final int[] mOutputScores = new int[MAX_RESULTS];
@@ -158,10 +159,10 @@ public final class BinaryDictionary extends Dictionary {
ArrayList<int[]> outBigramTargets, ArrayList<int[]> outBigramProbabilityInfo,
ArrayList<int[]> outShortcutTargets, ArrayList<Integer> outShortcutProbabilities);
private static native int getNextWordNative(long dict, int token, int[] outCodePoints);
- private static native int getSuggestionsNative(long dict, long proximityInfo,
+ private static native void getSuggestionsNative(long dict, long proximityInfo,
long traverseSession, int[] xCoordinates, int[] yCoordinates, int[] times,
int[] pointerIds, int[] inputCodePoints, int inputSize, int commitPoint,
- int[] suggestOptions, int[] prevWordCodePointArray,
+ int[] suggestOptions, int[] prevWordCodePointArray, int[] outputSuggestionCount,
int[] outputCodePoints, int[] outputScores, int[] outputIndices, int[] outputTypes,
int[] outputAutoCommitFirstWordConfidence);
private static native void addUnigramWordNative(long dict, int[] word, int probability,
@@ -258,12 +259,13 @@ public final class BinaryDictionary extends Dictionary {
mNativeSuggestOptions.setIsGesture(isGesture);
mNativeSuggestOptions.setAdditionalFeaturesOptions(additionalFeaturesOptions);
// proximityInfo and/or prevWordForBigrams may not be null.
- final int count = getSuggestionsNative(mNativeDict, proximityInfo.getNativeProximityInfo(),
+ getSuggestionsNative(mNativeDict, proximityInfo.getNativeProximityInfo(),
getTraverseSession(sessionId).getSession(), ips.getXCoordinates(),
ips.getYCoordinates(), ips.getTimes(), ips.getPointerIds(), mInputCodePoints,
inputSize, 0 /* commitPoint */, mNativeSuggestOptions.getOptions(),
- prevWordCodePointArray, mOutputCodePoints, mOutputScores, mSpaceIndices,
- mOutputTypes, mOutputAutoCommitFirstWordConfidence);
+ prevWordCodePointArray, mOutputSuggestionCount, mOutputCodePoints, mOutputScores,
+ mSpaceIndices, mOutputTypes, mOutputAutoCommitFirstWordConfidence);
+ final int count = mOutputSuggestionCount[0];
final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList();
for (int j = 0; j < count; ++j) {
final int start = j * MAX_WORD_LENGTH;
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
index 25e1bcd25..b534bcb09 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java
@@ -17,7 +17,6 @@
package com.android.inputmethod.latin.makedict;
import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import java.io.File;
import java.io.IOException;
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
index 1593dea4f..39bd98bad 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java
@@ -22,7 +22,6 @@ import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer;
import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
-import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index caf3cf354..a180f1c29 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -18,13 +18,7 @@ package com.android.inputmethod.latin.makedict;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer;
-import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
-import com.android.inputmethod.latin.utils.ByteArrayDictBuffer;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
diff --git a/java/src/com/android/inputmethod/latin/makedict/DictionaryHeader.java b/java/src/com/android/inputmethod/latin/makedict/DictionaryHeader.java
index b32eb9195..df447fd75 100644
--- a/java/src/com/android/inputmethod/latin/makedict/DictionaryHeader.java
+++ b/java/src/com/android/inputmethod/latin/makedict/DictionaryHeader.java
@@ -16,8 +16,8 @@
package com.android.inputmethod.latin.makedict;
+import com.android.inputmethod.latin.makedict.FormatSpec.DictionaryOptions;
import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
-import com.android.inputmethod.latin.makedict.FusionDictionary.DictionaryOptions;
/**
* Class representing dictionary header.
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index 484bb4b23..07217e48e 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -21,6 +21,8 @@ import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.makedict.DictDecoder.DictionaryBufferFactory;
import java.io.File;
+import java.util.Date;
+import java.util.HashMap;
/**
* Dictionary File Format Specification.
@@ -323,6 +325,45 @@ public final class FormatSpec {
}
/**
+ * Options global to the dictionary.
+ */
+ public static final class DictionaryOptions {
+ public final HashMap<String, String> mAttributes;
+ public DictionaryOptions(final HashMap<String, String> attributes) {
+ mAttributes = attributes;
+ }
+ @Override
+ public String toString() { // Convenience method
+ return toString(0, false);
+ }
+ public String toString(final int indentCount, final boolean plumbing) {
+ final StringBuilder indent = new StringBuilder();
+ if (plumbing) {
+ indent.append("H:");
+ } else {
+ for (int i = 0; i < indentCount; ++i) {
+ indent.append(" ");
+ }
+ }
+ final StringBuilder s = new StringBuilder();
+ for (final String optionKey : mAttributes.keySet()) {
+ s.append(indent);
+ s.append(optionKey);
+ s.append(" = ");
+ if ("date".equals(optionKey) && !plumbing) {
+ // Date needs a number of milliseconds, but the dictionary contains seconds
+ s.append(new Date(
+ 1000 * Long.parseLong(mAttributes.get(optionKey))).toString());
+ } else {
+ s.append(mAttributes.get(optionKey));
+ }
+ s.append("\n");
+ }
+ return s.toString();
+ }
+ }
+
+ /**
* Returns new dictionary decoder.
*
* @param dictFile the dictionary file.
diff --git a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
index 8f73b27b5..f60b3af4f 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
@@ -18,12 +18,11 @@ package com.android.inputmethod.latin.makedict;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.makedict.FormatSpec.DictionaryOptions;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
@@ -67,46 +66,6 @@ public final class FusionDictionary implements Iterable<WordProperty> {
}
/**
- * A string with a probability.
- *
- * This represents an "attribute", that is either a bigram or a shortcut.
- */
- public static final class WeightedString {
- public final String mWord;
- public ProbabilityInfo mProbabilityInfo;
-
- public WeightedString(final String word, final int probability) {
- this(word, new ProbabilityInfo(probability));
- }
-
- public WeightedString(final String word, final ProbabilityInfo probabilityInfo) {
- mWord = word;
- mProbabilityInfo = probabilityInfo;
- }
-
- public int getProbability() {
- return mProbabilityInfo.mProbability;
- }
-
- public void setProbability(final int probability) {
- mProbabilityInfo = new ProbabilityInfo(probability);
- }
-
- @Override
- public int hashCode() {
- return Arrays.hashCode(new Object[] { mWord, mProbabilityInfo});
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) return true;
- if (!(o instanceof WeightedString)) return false;
- final WeightedString w = (WeightedString)o;
- return mWord.equals(w.mWord) && mProbabilityInfo.equals(w.mProbabilityInfo);
- }
- }
-
- /**
* PtNode is a group of characters, with probability information, shortcut targets, bigrams,
* and children (Pt means Patricia Trie).
*
@@ -320,45 +279,6 @@ public final class FusionDictionary implements Iterable<WordProperty> {
}
}
- /**
- * Options global to the dictionary.
- */
- public static final class DictionaryOptions {
- public final HashMap<String, String> mAttributes;
- public DictionaryOptions(final HashMap<String, String> attributes) {
- mAttributes = attributes;
- }
- @Override
- public String toString() { // Convenience method
- return toString(0, false);
- }
- public String toString(final int indentCount, final boolean plumbing) {
- final StringBuilder indent = new StringBuilder();
- if (plumbing) {
- indent.append("H:");
- } else {
- for (int i = 0; i < indentCount; ++i) {
- indent.append(" ");
- }
- }
- final StringBuilder s = new StringBuilder();
- for (final String optionKey : mAttributes.keySet()) {
- s.append(indent);
- s.append(optionKey);
- s.append(" = ");
- if ("date".equals(optionKey) && !plumbing) {
- // Date needs a number of milliseconds, but the dictionary contains seconds
- s.append(new Date(
- 1000 * Long.parseLong(mAttributes.get(optionKey))).toString());
- } else {
- s.append(mAttributes.get(optionKey));
- }
- s.append("\n");
- }
- return s.toString();
- }
- }
-
public final DictionaryOptions mOptions;
public final PtNodeArray mRootNodeArray;
diff --git a/java/src/com/android/inputmethod/latin/makedict/PtNodeInfo.java b/java/src/com/android/inputmethod/latin/makedict/PtNodeInfo.java
index f52117c6c..862e8c101 100644
--- a/java/src/com/android/inputmethod/latin/makedict/PtNodeInfo.java
+++ b/java/src/com/android/inputmethod/latin/makedict/PtNodeInfo.java
@@ -16,15 +16,12 @@
package com.android.inputmethod.latin.makedict;
-import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
-
import java.util.ArrayList;
/**
* Raw PtNode info straight out of a file. This will contain numbers for addresses.
*/
public final class PtNodeInfo {
-
public final int mOriginalAddress;
public final int mEndAddress;
public final int mFlags;
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java
index ab24fbc84..7091c119e 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java
@@ -20,7 +20,6 @@ import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.BinaryDictionary;
import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding;
import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer;
-import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import com.android.inputmethod.latin.utils.CollectionUtils;
import java.io.File;
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java
index e247f0121..a286190cb 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java
@@ -21,7 +21,6 @@ import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncodin
import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
-import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import java.io.File;
import java.io.FileNotFoundException;
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java
index afe82317e..f3fad7e99 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java
@@ -18,7 +18,6 @@ package com.android.inputmethod.latin.makedict;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.BinaryDictionary;
-import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.FileUtils;
diff --git a/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java b/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java
index a50bad90a..dab9a4315 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java
@@ -21,7 +21,6 @@ import com.android.inputmethod.latin.BinaryDictionary;
import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
-import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import com.android.inputmethod.latin.utils.BinaryDictionaryUtils;
import com.android.inputmethod.latin.utils.LocaleUtils;
diff --git a/java/src/com/android/inputmethod/latin/makedict/WeightedString.java b/java/src/com/android/inputmethod/latin/makedict/WeightedString.java
new file mode 100644
index 000000000..f6782df9e
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/makedict/WeightedString.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2014 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.latin.makedict;
+
+import com.android.inputmethod.annotations.UsedForTesting;
+
+import java.util.Arrays;
+
+/**
+ * A string with a probability.
+ *
+ * This represents an "attribute", that is either a bigram or a shortcut.
+ */
+public final class WeightedString {
+ public final String mWord;
+ public ProbabilityInfo mProbabilityInfo;
+
+ public WeightedString(final String word, final int probability) {
+ this(word, new ProbabilityInfo(probability));
+ }
+
+ public WeightedString(final String word, final ProbabilityInfo probabilityInfo) {
+ mWord = word;
+ mProbabilityInfo = probabilityInfo;
+ }
+
+ @UsedForTesting
+ public int getProbability() {
+ return mProbabilityInfo.mProbability;
+ }
+
+ public void setProbability(final int probability) {
+ mProbabilityInfo = new ProbabilityInfo(probability);
+ }
+
+ @Override
+ public int hashCode() {
+ return Arrays.hashCode(new Object[] { mWord, mProbabilityInfo});
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) return true;
+ if (!(o instanceof WeightedString)) return false;
+ final WeightedString w = (WeightedString)o;
+ return mWord.equals(w.mWord) && mProbabilityInfo.equals(w.mProbabilityInfo);
+ }
+} \ No newline at end of file
diff --git a/java/src/com/android/inputmethod/latin/makedict/WordProperty.java b/java/src/com/android/inputmethod/latin/makedict/WordProperty.java
index 1fc61e10a..d94cec424 100644
--- a/java/src/com/android/inputmethod/latin/makedict/WordProperty.java
+++ b/java/src/com/android/inputmethod/latin/makedict/WordProperty.java
@@ -18,7 +18,6 @@ package com.android.inputmethod.latin.makedict;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.BinaryDictionary;
-import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.CombinedFormatUtils;
import com.android.inputmethod.latin.utils.StringUtils;
diff --git a/java/src/com/android/inputmethod/latin/utils/CombinedFormatUtils.java b/java/src/com/android/inputmethod/latin/utils/CombinedFormatUtils.java
index bb7ae2f9b..c66007537 100644
--- a/java/src/com/android/inputmethod/latin/utils/CombinedFormatUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/CombinedFormatUtils.java
@@ -18,8 +18,8 @@ package com.android.inputmethod.latin.utils;
import com.android.inputmethod.latin.makedict.DictionaryHeader;
import com.android.inputmethod.latin.makedict.ProbabilityInfo;
+import com.android.inputmethod.latin.makedict.WeightedString;
import com.android.inputmethod.latin.makedict.WordProperty;
-import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import java.util.HashMap;
diff --git a/java/src/com/android/inputmethod/latin/utils/StringUtils.java b/java/src/com/android/inputmethod/latin/utils/StringUtils.java
index e7932b5a6..b9d526b5f 100644
--- a/java/src/com/android/inputmethod/latin/utils/StringUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/StringUtils.java
@@ -507,4 +507,44 @@ public final class StringUtils {
return codePointCount(casedText) == 1
? casedText.codePointAt(0) : CODE_UNSPECIFIED;
}
+
+ @UsedForTesting
+ public static class Stringizer<E> {
+ public String stringize(final E element) {
+ return element != null ? element.toString() : "null";
+ }
+
+ @UsedForTesting
+ public final String join(final E[] array) {
+ return joinStringArray(toStringArray(array), null /* delimiter */);
+ }
+
+ @UsedForTesting
+ public final String join(final E[] array, final String delimiter) {
+ return joinStringArray(toStringArray(array), delimiter);
+ }
+
+ protected String[] toStringArray(final E[] array) {
+ final String[] stringArray = new String[array.length];
+ for (int index = 0; index < array.length; index++) {
+ stringArray[index] = stringize(array[index]);
+ }
+ return stringArray;
+ }
+
+ protected String joinStringArray(final String[] stringArray, final String delimiter) {
+ if (stringArray == null) {
+ return "null";
+ }
+ if (delimiter == null) {
+ return Arrays.toString(stringArray);
+ }
+ final StringBuilder sb = new StringBuilder();
+ for (int index = 0; index < stringArray.length; index++) {
+ sb.append(index == 0 ? "[" : delimiter);
+ sb.append(stringArray[index]);
+ }
+ return sb + "]";
+ }
+ }
}
diff --git a/native/jni/NativeFileList.mk b/native/jni/NativeFileList.mk
index 1f5824608..2ee4caa42 100644
--- a/native/jni/NativeFileList.mk
+++ b/native/jni/NativeFileList.mk
@@ -40,8 +40,10 @@ LATIN_IME_CORE_SRC_FILES := \
proximity_info_state.cpp \
proximity_info_state_utils.cpp) \
suggest/core/policy/weighting.cpp \
- suggest/core/result/suggestions_output_utils.cpp \
suggest/core/session/dic_traverse_session.cpp \
+ $(addprefix suggest/core/result/, \
+ suggestion_results.cpp \
+ suggestions_output_utils.cpp) \
$(addprefix suggest/policyimpl/dictionary/, \
header/header_policy.cpp \
header/header_read_write_utils.cpp \
diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
index 7a7816d5a..eec354abc 100644
--- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
+++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
@@ -25,6 +25,7 @@
#include "jni_common.h"
#include "suggest/core/dictionary/dictionary.h"
#include "suggest/core/dictionary/word_property.h"
+#include "suggest/core/result/suggestion_results.h"
#include "suggest/core/suggest_options.h"
#include "suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.h"
#include "utils/char_utils.h"
@@ -46,15 +47,16 @@ static jlong latinime_BinaryDictionary_open(JNIEnv *env, jclass clazz, jstring s
char sourceDirChars[sourceDirUtf8Length + 1];
env->GetStringUTFRegion(sourceDir, 0, env->GetStringLength(sourceDir), sourceDirChars);
sourceDirChars[sourceDirUtf8Length] = '\0';
- DictionaryStructureWithBufferPolicy::StructurePolicyPtr dictionaryStructureWithBufferPolicy =
+ DictionaryStructureWithBufferPolicy::StructurePolicyPtr dictionaryStructureWithBufferPolicy(
DictionaryStructureWithBufferPolicyFactory::newDictionaryStructureWithBufferPolicy(
sourceDirChars, static_cast<int>(dictOffset), static_cast<int>(dictSize),
- isUpdatable == JNI_TRUE);
- if (!dictionaryStructureWithBufferPolicy.get()) {
+ isUpdatable == JNI_TRUE));
+ if (!dictionaryStructureWithBufferPolicy) {
return 0;
}
- Dictionary *const dictionary = new Dictionary(env, dictionaryStructureWithBufferPolicy);
+ Dictionary *const dictionary =
+ new Dictionary(env, std::move(dictionaryStructureWithBufferPolicy));
PROF_END(66);
PROF_CLOSE;
return reinterpret_cast<jlong>(dictionary);
@@ -138,15 +140,20 @@ static int latinime_BinaryDictionary_getFormatVersion(JNIEnv *env, jclass clazz,
return headerPolicy->getFormatVersionNumber();
}
-static int latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jclass clazz, jlong dict,
+static void latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jclass clazz, jlong dict,
jlong proximityInfo, jlong dicTraverseSession, jintArray xCoordinatesArray,
jintArray yCoordinatesArray, jintArray timesArray, jintArray pointerIdsArray,
jintArray inputCodePointsArray, jint inputSize, jint commitPoint, jintArray suggestOptions,
- jintArray prevWordCodePointsForBigrams, jintArray outputCodePointsArray,
- jintArray scoresArray, jintArray spaceIndicesArray, jintArray outputTypesArray,
- jintArray outputAutoCommitFirstWordConfidenceArray) {
+ jintArray prevWordCodePointsForBigrams, jintArray outSuggestionCount,
+ jintArray outCodePointsArray, jintArray outScoresArray, jintArray outSpaceIndicesArray,
+ jintArray outTypesArray, jintArray outAutoCommitFirstWordConfidenceArray) {
Dictionary *dictionary = reinterpret_cast<Dictionary *>(dict);
- if (!dictionary) return 0;
+ // Assign 0 to outSuggestionCount here in case of returning earlier in this method.
+ int count = 0;
+ env->SetIntArrayRegion(outSuggestionCount, 0, 1 /* len */, &count);
+ if (!dictionary) {
+ return;
+ }
ProximityInfo *pInfo = reinterpret_cast<ProximityInfo *>(proximityInfo);
DicTraverseSession *traverseSession =
reinterpret_cast<DicTraverseSession *>(dicTraverseSession);
@@ -161,7 +168,7 @@ static int latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jclass clazz, j
const jsize prevWordCodePointsLength =
prevWordCodePointsForBigrams ? env->GetArrayLength(prevWordCodePointsForBigrams) : 0;
int prevWordCodePointsInternal[prevWordCodePointsLength];
- int *prevWordCodePoints = 0;
+ int *prevWordCodePoints = nullptr;
env->GetIntArrayRegion(xCoordinatesArray, 0, inputSize, xCoordinates);
env->GetIntArrayRegion(yCoordinatesArray, 0, inputSize, yCoordinates);
env->GetIntArrayRegion(timesArray, 0, inputSize, times);
@@ -180,26 +187,26 @@ static int latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jclass clazz, j
// Output values
/* By the way, let's check the output array length here to make sure */
- const jsize outputCodePointsLength = env->GetArrayLength(outputCodePointsArray);
+ const jsize outputCodePointsLength = env->GetArrayLength(outCodePointsArray);
if (outputCodePointsLength != (MAX_WORD_LENGTH * MAX_RESULTS)) {
AKLOGE("Invalid outputCodePointsLength: %d", outputCodePointsLength);
ASSERT(false);
- return 0;
+ return;
}
- const jsize scoresLength = env->GetArrayLength(scoresArray);
+ const jsize scoresLength = env->GetArrayLength(outScoresArray);
if (scoresLength != MAX_RESULTS) {
AKLOGE("Invalid scoresLength: %d", scoresLength);
ASSERT(false);
- return 0;
+ return;
}
int outputCodePoints[outputCodePointsLength];
int scores[scoresLength];
- const jsize spaceIndicesLength = env->GetArrayLength(spaceIndicesArray);
+ const jsize spaceIndicesLength = env->GetArrayLength(outSpaceIndicesArray);
int spaceIndices[spaceIndicesLength];
- const jsize outputTypesLength = env->GetArrayLength(outputTypesArray);
+ const jsize outputTypesLength = env->GetArrayLength(outTypesArray);
int outputTypes[outputTypesLength];
const jsize outputAutoCommitFirstWordConfidenceLength =
- env->GetArrayLength(outputAutoCommitFirstWordConfidenceArray);
+ env->GetArrayLength(outAutoCommitFirstWordConfidenceArray);
// We only use the first result, as obviously we will only ever autocommit the first one
ASSERT(outputAutoCommitFirstWordConfidenceLength == 1);
int outputAutoCommitFirstWordConfidence[outputAutoCommitFirstWordConfidenceLength];
@@ -209,26 +216,30 @@ static int latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jclass clazz, j
memset(outputTypes, 0, sizeof(outputTypes));
memset(outputAutoCommitFirstWordConfidence, 0, sizeof(outputAutoCommitFirstWordConfidence));
- int count;
if (givenSuggestOptions.isGesture() || inputSize > 0) {
+ // TODO: Use SuggestionResults to return suggestions.
count = dictionary->getSuggestions(pInfo, traverseSession, xCoordinates, yCoordinates,
times, pointerIds, inputCodePoints, inputSize, prevWordCodePoints,
prevWordCodePointsLength, commitPoint, &givenSuggestOptions, outputCodePoints,
scores, spaceIndices, outputTypes, outputAutoCommitFirstWordConfidence);
} else {
- count = dictionary->getBigrams(prevWordCodePoints, prevWordCodePointsLength,
- outputCodePoints, scores, outputTypes);
+ SuggestionResults suggestionResults(MAX_RESULTS);
+ dictionary->getPredictions(prevWordCodePoints, prevWordCodePointsLength,
+ &suggestionResults);
+ suggestionResults.outputSuggestions(env, outSuggestionCount, outCodePointsArray,
+ outScoresArray, outSpaceIndicesArray, outTypesArray,
+ outAutoCommitFirstWordConfidenceArray);
+ return;
}
// Copy back the output values
- env->SetIntArrayRegion(outputCodePointsArray, 0, outputCodePointsLength, outputCodePoints);
- env->SetIntArrayRegion(scoresArray, 0, scoresLength, scores);
- env->SetIntArrayRegion(spaceIndicesArray, 0, spaceIndicesLength, spaceIndices);
- env->SetIntArrayRegion(outputTypesArray, 0, outputTypesLength, outputTypes);
- env->SetIntArrayRegion(outputAutoCommitFirstWordConfidenceArray, 0,
+ env->SetIntArrayRegion(outSuggestionCount, 0, 1 /* len */, &count);
+ env->SetIntArrayRegion(outCodePointsArray, 0, outputCodePointsLength, outputCodePoints);
+ env->SetIntArrayRegion(outScoresArray, 0, scoresLength, scores);
+ env->SetIntArrayRegion(outSpaceIndicesArray, 0, spaceIndicesLength, spaceIndices);
+ env->SetIntArrayRegion(outTypesArray, 0, outputTypesLength, outputTypes);
+ env->SetIntArrayRegion(outAutoCommitFirstWordConfidenceArray, 0,
outputAutoCommitFirstWordConfidenceLength, outputAutoCommitFirstWordConfidence);
-
- return count;
}
static jint latinime_BinaryDictionary_getProbability(JNIEnv *env, jclass clazz, jlong dict,
@@ -495,7 +506,7 @@ static const JNINativeMethod sMethods[] = {
},
{
const_cast<char *>("getSuggestionsNative"),
- const_cast<char *>("(JJJ[I[I[I[I[III[I[I[I[I[I[I[I)I"),
+ const_cast<char *>("(JJJ[I[I[I[I[III[I[I[I[I[I[I[I[I)V"),
reinterpret_cast<void *>(latinime_BinaryDictionary_getSuggestions)
},
{
diff --git a/native/jni/src/defines.h b/native/jni/src/defines.h
index 0715fbd70..4c57af0ba 100644
--- a/native/jni/src/defines.h
+++ b/native/jni/src/defines.h
@@ -344,9 +344,6 @@ static inline void prof_out(void) {
#define MAX_POINTER_COUNT 1
#define MAX_POINTER_COUNT_G 2
-template<typename T> AK_FORCE_INLINE const T &min(const T &a, const T &b) { return a < b ? a : b; }
-template<typename T> AK_FORCE_INLINE const T &max(const T &a, const T &b) { return a > b ? a : b; }
-
// DEBUG
#define INPUTLENGTH_FOR_DEBUG (-1)
#define MIN_OUTPUT_INDEX_FOR_DEBUG (-1)
diff --git a/native/jni/src/suggest/core/dicnode/dic_node.cpp b/native/jni/src/suggest/core/dicnode/dic_node.cpp
index de088c7d0..73855977e 100644
--- a/native/jni/src/suggest/core/dicnode/dic_node.cpp
+++ b/native/jni/src/suggest/core/dicnode/dic_node.cpp
@@ -25,7 +25,7 @@ DicNode::DicNode(const DicNode &dicNode)
#endif
mDicNodeProperties(dicNode.mDicNodeProperties), mDicNodeState(dicNode.mDicNodeState),
mIsCachedForNextSuggestion(dicNode.mIsCachedForNextSuggestion), mIsUsed(dicNode.mIsUsed),
- mReleaseListener(0) {
+ mReleaseListener(nullptr) {
/* empty */
}
diff --git a/native/jni/src/suggest/core/dicnode/dic_node.h b/native/jni/src/suggest/core/dicnode/dic_node.h
index 558667eb0..b812f8ff4 100644
--- a/native/jni/src/suggest/core/dicnode/dic_node.h
+++ b/native/jni/src/suggest/core/dicnode/dic_node.h
@@ -93,7 +93,7 @@ class DicNode {
mProfiler(),
#endif
mDicNodeProperties(), mDicNodeState(), mIsCachedForNextSuggestion(false),
- mIsUsed(false), mReleaseListener(0) {}
+ mIsUsed(false), mReleaseListener(nullptr) {}
DicNode(const DicNode &dicNode);
DicNode &operator=(const DicNode &dicNode);
diff --git a/native/jni/src/suggest/core/dicnode/dic_node_priority_queue.h b/native/jni/src/suggest/core/dicnode/dic_node_priority_queue.h
index 7461f0cc6..1f02731a5 100644
--- a/native/jni/src/suggest/core/dicnode/dic_node_priority_queue.h
+++ b/native/jni/src/suggest/core/dicnode/dic_node_priority_queue.h
@@ -17,6 +17,7 @@
#ifndef LATINIME_DIC_NODE_PRIORITY_QUEUE_H
#define LATINIME_DIC_NODE_PRIORITY_QUEUE_H
+#include <algorithm>
#include <queue>
#include <vector>
@@ -49,7 +50,7 @@ class DicNodePriorityQueue : public DicNodeReleaseListener {
AK_FORCE_INLINE void setMaxSize(const int maxSize) {
ASSERT(maxSize <= mCapacity);
- mMaxSize = min(maxSize, mCapacity);
+ mMaxSize = std::min(maxSize, mCapacity);
}
AK_FORCE_INLINE void clearAndResizeToCapacity() {
diff --git a/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp b/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp
index 71bcab6cb..a6ea68c29 100644
--- a/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp
+++ b/native/jni/src/suggest/core/dicnode/dic_node_utils.cpp
@@ -16,6 +16,7 @@
#include "suggest/core/dicnode/dic_node_utils.h"
+#include <algorithm>
#include <cstring>
#include "suggest/core/dicnode/dic_node.h"
@@ -117,7 +118,7 @@ namespace latinime {
}
actualLength0 = i + 1;
}
- actualLength0 = min(actualLength0, MAX_WORD_LENGTH);
+ actualLength0 = std::min(actualLength0, MAX_WORD_LENGTH);
memmove(dest, src0, actualLength0 * sizeof(dest[0]));
if (!src1 || length1 == 0) {
return actualLength0;
@@ -129,7 +130,7 @@ namespace latinime {
}
actualLength1 = i + 1;
}
- actualLength1 = min(actualLength1, MAX_WORD_LENGTH - actualLength0);
+ actualLength1 = std::min(actualLength1, MAX_WORD_LENGTH - actualLength0);
memmove(&dest[actualLength0], src1, actualLength1 * sizeof(dest[0]));
return actualLength0 + actualLength1;
}
diff --git a/native/jni/src/suggest/core/dicnode/dic_nodes_cache.h b/native/jni/src/suggest/core/dicnode/dic_nodes_cache.h
index 8493b6a8b..c31c056f5 100644
--- a/native/jni/src/suggest/core/dicnode/dic_nodes_cache.h
+++ b/native/jni/src/suggest/core/dicnode/dic_nodes_cache.h
@@ -17,6 +17,7 @@
#ifndef LATINIME_DIC_NODES_CACHE_H
#define LATINIME_DIC_NODES_CACHE_H
+#include <algorithm>
#include <stdint.h>
#include "defines.h"
@@ -51,7 +52,7 @@ class DicNodesCache {
// We want to use the max capacity for the current active dic node queue.
mActiveDicNodes->clearAndResizeToCapacity();
// nextActiveSize is used to limit the next iteration's active dic node size.
- const int nextActiveSizeFittingToTheCapacity = min(nextActiveSize, getCacheCapacity());
+ const int nextActiveSizeFittingToTheCapacity = std::min(nextActiveSize, getCacheCapacity());
mNextActiveDicNodes->clearAndResize(nextActiveSizeFittingToTheCapacity);
mTerminalDicNodes->clearAndResize(terminalSize);
// We want to use the max capacity for the cached dic nodes that will be used for the
diff --git a/native/jni/src/suggest/core/dicnode/internal/dic_node_state_output.h b/native/jni/src/suggest/core/dicnode/internal/dic_node_state_output.h
index fc6851099..abafc0edf 100644
--- a/native/jni/src/suggest/core/dicnode/internal/dic_node_state_output.h
+++ b/native/jni/src/suggest/core/dicnode/internal/dic_node_state_output.h
@@ -17,6 +17,7 @@
#ifndef LATINIME_DIC_NODE_STATE_OUTPUT_H
#define LATINIME_DIC_NODE_STATE_OUTPUT_H
+#include <algorithm>
#include <cstring> // for memmove()
#include <stdint.h>
@@ -49,7 +50,8 @@ class DicNodeStateOutput {
void addMergedNodeCodePoints(const uint16_t mergedNodeCodePointCount,
const int *const mergedNodeCodePoints) {
if (mergedNodeCodePoints) {
- const int additionalCodePointCount = min(static_cast<int>(mergedNodeCodePointCount),
+ const int additionalCodePointCount = std::min(
+ static_cast<int>(mergedNodeCodePointCount),
MAX_WORD_LENGTH - mOutputtedCodePointCount);
memmove(&mCodePointsBuf[mOutputtedCodePointCount], mergedNodeCodePoints,
additionalCodePointCount * sizeof(mCodePointsBuf[0]));
diff --git a/native/jni/src/suggest/core/dicnode/internal/dic_node_state_prevword.h b/native/jni/src/suggest/core/dicnode/internal/dic_node_state_prevword.h
index e7108d976..7868f7853 100644
--- a/native/jni/src/suggest/core/dicnode/internal/dic_node_state_prevword.h
+++ b/native/jni/src/suggest/core/dicnode/internal/dic_node_state_prevword.h
@@ -17,6 +17,7 @@
#ifndef LATINIME_DIC_NODE_STATE_PREVWORD_H
#define LATINIME_DIC_NODE_STATE_PREVWORD_H
+#include <algorithm>
#include <cstring> // for memset() and memmove()
#include <stdint.h>
@@ -69,7 +70,7 @@ class DicNodeStatePrevWord {
const int prevWordNodePos, const int *const src0, const int16_t length0,
const int *const src1, const int16_t length1,
const int prevWordSecondWordFirstInputIndex, const int lastInputIndex) {
- mPrevWordCount = min(prevWordCount, static_cast<int16_t>(MAX_RESULTS));
+ mPrevWordCount = std::min(prevWordCount, static_cast<int16_t>(MAX_RESULTS));
mPrevWordProbability = prevWordProbability;
mPrevWordPtNodePos = prevWordNodePos;
int twoWordsLen =
diff --git a/native/jni/src/suggest/core/dicnode/internal/dic_node_state_scoring.h b/native/jni/src/suggest/core/dicnode/internal/dic_node_state_scoring.h
index 11c201e52..18b7d736a 100644
--- a/native/jni/src/suggest/core/dicnode/internal/dic_node_state_scoring.h
+++ b/native/jni/src/suggest/core/dicnode/internal/dic_node_state_scoring.h
@@ -17,6 +17,7 @@
#ifndef LATINIME_DIC_NODE_STATE_SCORING_H
#define LATINIME_DIC_NODE_STATE_SCORING_H
+#include <algorithm>
#include <stdint.h>
#include "defines.h"
@@ -199,7 +200,7 @@ class DicNodeStateScoring {
mNormalizedCompoundDistance = mSpatialDistance + mLanguageDistance;
} else {
mNormalizedCompoundDistance = (mSpatialDistance + mLanguageDistance)
- / static_cast<float>(max(1, totalInputIndex));
+ / static_cast<float>(std::max(1, totalInputIndex));
}
}
};
diff --git a/native/jni/src/suggest/core/dictionary/bigram_dictionary.cpp b/native/jni/src/suggest/core/dictionary/bigram_dictionary.cpp
index d0b96b0fe..f793363a8 100644
--- a/native/jni/src/suggest/core/dictionary/bigram_dictionary.cpp
+++ b/native/jni/src/suggest/core/dictionary/bigram_dictionary.cpp
@@ -14,16 +14,18 @@
* limitations under the License.
*/
-#include <cstring>
-
#define LOG_TAG "LatinIME: bigram_dictionary.cpp"
#include "bigram_dictionary.h"
+#include <algorithm>
+#include <cstring>
+
#include "defines.h"
#include "suggest/core/dictionary/binary_dictionary_bigrams_iterator.h"
#include "suggest/core/dictionary/dictionary.h"
#include "suggest/core/policy/dictionary_structure_with_buffer_policy.h"
+#include "suggest/core/result/suggestion_results.h"
#include "utils/char_utils.h"
namespace latinime {
@@ -39,71 +41,13 @@ BigramDictionary::BigramDictionary(
BigramDictionary::~BigramDictionary() {
}
-void BigramDictionary::addWordBigram(int *word, int length, int probability, int *bigramProbability,
- int *bigramCodePoints, int *outputTypes) const {
- if (length >= MAX_WORD_LENGTH) {
- length = MAX_WORD_LENGTH - 1;
- }
- word[length] = 0;
- if (DEBUG_DICT_FULL) {
-#ifdef FLAG_DBG
- char s[length + 1];
- for (int i = 0; i <= length; i++) s[i] = static_cast<char>(word[i]);
- AKLOGI("Bigram: Found word = %s, freq = %d :", s, probability);
-#endif
- }
-
- // Find the right insertion point
- int insertAt = 0;
- while (insertAt < MAX_RESULTS) {
- if (probability > bigramProbability[insertAt] || (bigramProbability[insertAt] == probability
- && length < CharUtils::getCodePointCount(MAX_WORD_LENGTH,
- bigramCodePoints + insertAt * MAX_WORD_LENGTH))) {
- break;
- }
- insertAt++;
- }
- if (DEBUG_DICT_FULL) {
- AKLOGI("Bigram: InsertAt -> %d MAX_RESULTS: %d", insertAt, MAX_RESULTS);
- }
- if (insertAt >= MAX_RESULTS) {
- return;
- }
- // Shift result buffers to insert the new entry.
- memmove(bigramProbability + (insertAt + 1), bigramProbability + insertAt,
- (MAX_RESULTS - insertAt - 1) * sizeof(bigramProbability[0]));
- memmove(outputTypes + (insertAt + 1), outputTypes + insertAt,
- (MAX_RESULTS - insertAt - 1) * sizeof(outputTypes[0]));
- memmove(bigramCodePoints + (insertAt + 1) * MAX_WORD_LENGTH,
- bigramCodePoints + insertAt * MAX_WORD_LENGTH,
- (MAX_RESULTS - insertAt - 1) * sizeof(bigramCodePoints[0]) * MAX_WORD_LENGTH);
- // Put the result.
- bigramProbability[insertAt] = probability;
- outputTypes[insertAt] = Dictionary::KIND_PREDICTION;
- int *dest = bigramCodePoints + insertAt * MAX_WORD_LENGTH;
- while (length--) {
- *dest++ = *word++;
- }
- *dest = 0; // NULL terminate
- if (DEBUG_DICT_FULL) {
- AKLOGI("Bigram: Added word at %d", insertAt);
- }
-}
-
/* Parameters :
* prevWord: the word before, the one for which we need to look up bigrams.
* prevWordLength: its length.
- * outBigramCodePoints: an array for output, at the same format as outwords for getSuggestions.
- * outBigramProbability: an array to output frequencies.
- * outputTypes: an array to output types.
- * This method returns the number of bigrams this word has, for backward compatibility.
+ * outSuggestionResults: SuggestionResults to put the predictions.
*/
-int BigramDictionary::getPredictions(const int *prevWord, const int prevWordLength,
- int *const outBigramCodePoints, int *const outBigramProbability,
- int *const outputTypes) const {
- // TODO: remove unused arguments, and refrain from storing stuff in members of this class
- // TODO: have "in" arguments before "out" ones, and make out args explicit in the name
-
+void BigramDictionary::getPredictions(const int *prevWord, const int prevWordLength,
+ SuggestionResults *const outSuggestionResults) const {
int pos = getBigramListPositionForWord(prevWord, prevWordLength,
false /* forceLowerCaseSearch */);
// getBigramListPositionForWord returns 0 if this word isn't in the dictionary or has no bigrams
@@ -113,11 +57,10 @@ int BigramDictionary::getPredictions(const int *prevWord, const int prevWordLeng
true /* forceLowerCaseSearch */);
}
// If still no bigrams, we really don't have them!
- if (NOT_A_DICT_POS == pos) return 0;
+ if (NOT_A_DICT_POS == pos) return;
- int bigramCount = 0;
int unigramProbability = 0;
- int bigramBuffer[MAX_WORD_LENGTH];
+ int bigramCodePoints[MAX_WORD_LENGTH];
BinaryDictionaryBigramsIterator bigramsIt(
mDictionaryStructurePolicy->getBigramsStructurePolicy(), pos);
while (bigramsIt.hasNext()) {
@@ -127,7 +70,7 @@ int BigramDictionary::getPredictions(const int *prevWord, const int prevWordLeng
}
const int codePointCount = mDictionaryStructurePolicy->
getCodePointsAndProbabilityAndReturnCodePointCount(bigramsIt.getBigramPos(),
- MAX_WORD_LENGTH, bigramBuffer, &unigramProbability);
+ MAX_WORD_LENGTH, bigramCodePoints, &unigramProbability);
if (codePointCount <= 0) {
continue;
}
@@ -138,11 +81,8 @@ int BigramDictionary::getPredictions(const int *prevWord, const int prevWordLeng
// here, but it can't get too bad.
const int probability = mDictionaryStructurePolicy->getProbability(
unigramProbability, bigramsIt.getProbability());
- addWordBigram(bigramBuffer, codePointCount, probability, outBigramProbability,
- outBigramCodePoints, outputTypes);
- ++bigramCount;
+ outSuggestionResults->addPrediction(bigramCodePoints, codePointCount, probability);
}
- return min(bigramCount, MAX_RESULTS);
}
// Returns a pointer to the start of the bigram list.
diff --git a/native/jni/src/suggest/core/dictionary/bigram_dictionary.h b/native/jni/src/suggest/core/dictionary/bigram_dictionary.h
index 8af7ee75d..12aaf20d3 100644
--- a/native/jni/src/suggest/core/dictionary/bigram_dictionary.h
+++ b/native/jni/src/suggest/core/dictionary/bigram_dictionary.h
@@ -22,21 +22,20 @@
namespace latinime {
class DictionaryStructureWithBufferPolicy;
+class SuggestionResults;
class BigramDictionary {
public:
BigramDictionary(const DictionaryStructureWithBufferPolicy *const dictionaryStructurePolicy);
- int getPredictions(const int *word, int length, int *outBigramCodePoints,
- int *outBigramProbability, int *outputTypes) const;
+ void getPredictions(const int *word, int length,
+ SuggestionResults *const outSuggestionResults) const;
int getBigramProbability(const int *word1, int length1, const int *word2, int length2) const;
~BigramDictionary();
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(BigramDictionary);
- void addWordBigram(int *word, int length, int probability, int *bigramProbability,
- int *bigramCodePoints, int *outputTypes) const;
int getBigramListPositionForWord(const int *prevWord, const int prevWordLength,
const bool forceLowerCaseSearch) const;
diff --git a/native/jni/src/suggest/core/dictionary/dictionary.cpp b/native/jni/src/suggest/core/dictionary/dictionary.cpp
index 035232f7a..ffa96e167 100644
--- a/native/jni/src/suggest/core/dictionary/dictionary.cpp
+++ b/native/jni/src/suggest/core/dictionary/dictionary.cpp
@@ -34,9 +34,9 @@ namespace latinime {
const int Dictionary::HEADER_ATTRIBUTE_BUFFER_SIZE = 32;
-Dictionary::Dictionary(JNIEnv *env, const DictionaryStructureWithBufferPolicy::StructurePolicyPtr
- &dictionaryStructureWithBufferPolicy)
- : mDictionaryStructureWithBufferPolicy(dictionaryStructureWithBufferPolicy),
+Dictionary::Dictionary(JNIEnv *env, DictionaryStructureWithBufferPolicy::StructurePolicyPtr
+ dictionaryStructureWithBufferPolicy)
+ : mDictionaryStructureWithBufferPolicy(std::move(dictionaryStructureWithBufferPolicy)),
mBigramDictionary(new BigramDictionary(mDictionaryStructureWithBufferPolicy.get())),
mGestureSuggest(new Suggest(GestureSuggestPolicyFactory::getGestureSuggestPolicy())),
mTypingSuggest(new Suggest(TypingSuggestPolicyFactory::getTypingSuggestPolicy())) {
@@ -53,7 +53,7 @@ int Dictionary::getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession
if (suggestOptions->isGesture()) {
DicTraverseSession::initSessionInstance(
traverseSession, this, prevWordCodePoints, prevWordLength, suggestOptions);
- result = mGestureSuggest.get()->getSuggestions(proximityInfo, traverseSession, xcoordinates,
+ result = mGestureSuggest->getSuggestions(proximityInfo, traverseSession, xcoordinates,
ycoordinates, times, pointerIds, inputCodePoints, inputSize, commitPoint, outWords,
outputScores, spaceIndices, outputTypes, outputAutoCommitFirstWordConfidence);
if (DEBUG_DICT) {
@@ -63,7 +63,7 @@ int Dictionary::getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession
} else {
DicTraverseSession::initSessionInstance(
traverseSession, this, prevWordCodePoints, prevWordLength, suggestOptions);
- result = mTypingSuggest.get()->getSuggestions(proximityInfo, traverseSession, xcoordinates,
+ result = mTypingSuggest->getSuggestions(proximityInfo, traverseSession, xcoordinates,
ycoordinates, times, pointerIds, inputCodePoints, inputSize, commitPoint,
outWords, outputScores, spaceIndices, outputTypes,
outputAutoCommitFirstWordConfidence);
@@ -74,12 +74,11 @@ int Dictionary::getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession
}
}
-int Dictionary::getBigrams(const int *word, int length, int *outWords, int *outputScores,
- int *outputTypes) const {
+void Dictionary::getPredictions(const int *word, int length,
+ SuggestionResults *const outSuggestionResults) const {
TimeKeeper::setCurrentTime();
- if (length <= 0) return 0;
- return mBigramDictionary.get()->getPredictions(word, length, outWords, outputScores,
- outputTypes);
+ if (length <= 0) return;
+ mBigramDictionary->getPredictions(word, length, outSuggestionResults);
}
int Dictionary::getProbability(const int *word, int length) const {
@@ -95,7 +94,7 @@ int Dictionary::getProbability(const int *word, int length) const {
int Dictionary::getBigramProbability(const int *word0, int length0, const int *word1,
int length1) const {
TimeKeeper::setCurrentTime();
- return mBigramDictionary.get()->getBigramProbability(word0, length0, word1, length1);
+ return mBigramDictionary->getBigramProbability(word0, length0, word1, length1);
}
void Dictionary::addUnigramWord(const int *const word, const int length, const int probability,
@@ -103,7 +102,7 @@ void Dictionary::addUnigramWord(const int *const word, const int length, const i
const int shortcutProbability, const bool isNotAWord, const bool isBlacklisted,
const int timestamp) {
TimeKeeper::setCurrentTime();
- mDictionaryStructureWithBufferPolicy.get()->addUnigramWord(word, length, probability,
+ mDictionaryStructureWithBufferPolicy->addUnigramWord(word, length, probability,
shortcutTargetCodePoints, shortcutLength, shortcutProbability, isNotAWord,
isBlacklisted, timestamp);
}
@@ -111,48 +110,48 @@ void Dictionary::addUnigramWord(const int *const word, const int length, const i
void Dictionary::addBigramWords(const int *const word0, const int length0, const int *const word1,
const int length1, const int probability, const int timestamp) {
TimeKeeper::setCurrentTime();
- mDictionaryStructureWithBufferPolicy.get()->addBigramWords(word0, length0, word1, length1,
+ mDictionaryStructureWithBufferPolicy->addBigramWords(word0, length0, word1, length1,
probability, timestamp);
}
void Dictionary::removeBigramWords(const int *const word0, const int length0,
const int *const word1, const int length1) {
TimeKeeper::setCurrentTime();
- mDictionaryStructureWithBufferPolicy.get()->removeBigramWords(word0, length0, word1, length1);
+ mDictionaryStructureWithBufferPolicy->removeBigramWords(word0, length0, word1, length1);
}
void Dictionary::flush(const char *const filePath) {
TimeKeeper::setCurrentTime();
- mDictionaryStructureWithBufferPolicy.get()->flush(filePath);
+ mDictionaryStructureWithBufferPolicy->flush(filePath);
}
void Dictionary::flushWithGC(const char *const filePath) {
TimeKeeper::setCurrentTime();
- mDictionaryStructureWithBufferPolicy.get()->flushWithGC(filePath);
+ mDictionaryStructureWithBufferPolicy->flushWithGC(filePath);
}
bool Dictionary::needsToRunGC(const bool mindsBlockByGC) {
TimeKeeper::setCurrentTime();
- return mDictionaryStructureWithBufferPolicy.get()->needsToRunGC(mindsBlockByGC);
+ return mDictionaryStructureWithBufferPolicy->needsToRunGC(mindsBlockByGC);
}
void Dictionary::getProperty(const char *const query, const int queryLength, char *const outResult,
const int maxResultLength) {
TimeKeeper::setCurrentTime();
- return mDictionaryStructureWithBufferPolicy.get()->getProperty(query, queryLength, outResult,
+ return mDictionaryStructureWithBufferPolicy->getProperty(query, queryLength, outResult,
maxResultLength);
}
const WordProperty Dictionary::getWordProperty(const int *const codePoints,
const int codePointCount) {
TimeKeeper::setCurrentTime();
- return mDictionaryStructureWithBufferPolicy.get()->getWordProperty(
+ return mDictionaryStructureWithBufferPolicy->getWordProperty(
codePoints, codePointCount);
}
int Dictionary::getNextWordAndNextToken(const int token, int *const outCodePoints) {
TimeKeeper::setCurrentTime();
- return mDictionaryStructureWithBufferPolicy.get()->getNextWordAndNextToken(
+ return mDictionaryStructureWithBufferPolicy->getNextWordAndNextToken(
token, outCodePoints);
}
diff --git a/native/jni/src/suggest/core/dictionary/dictionary.h b/native/jni/src/suggest/core/dictionary/dictionary.h
index c58be8475..2dea9fff8 100644
--- a/native/jni/src/suggest/core/dictionary/dictionary.h
+++ b/native/jni/src/suggest/core/dictionary/dictionary.h
@@ -18,6 +18,7 @@
#define LATINIME_DICTIONARY_H
#include <stdint.h>
+#include <memory>
#include "defines.h"
#include "jni.h"
@@ -26,13 +27,13 @@
#include "suggest/core/policy/dictionary_header_structure_policy.h"
#include "suggest/core/policy/dictionary_structure_with_buffer_policy.h"
#include "suggest/core/suggest_interface.h"
-#include "utils/exclusive_ownership_pointer.h"
namespace latinime {
class DictionaryStructureWithBufferPolicy;
class DicTraverseSession;
class ProximityInfo;
+class SuggestionResults;
class SuggestOptions;
class WordProperty;
@@ -58,8 +59,8 @@ class Dictionary {
static const int KIND_FLAG_POSSIBLY_OFFENSIVE = 0x80000000;
static const int KIND_FLAG_EXACT_MATCH = 0x40000000;
- Dictionary(JNIEnv *env, const DictionaryStructureWithBufferPolicy::StructurePolicyPtr
- &dictionaryStructureWithBufferPolicy);
+ Dictionary(JNIEnv *env, DictionaryStructureWithBufferPolicy::StructurePolicyPtr
+ dictionaryStructureWithBufferPolicy);
int getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession *traverseSession,
int *xcoordinates, int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints,
@@ -67,8 +68,8 @@ class Dictionary {
const SuggestOptions *const suggestOptions, int *outWords, int *outputScores,
int *spaceIndices, int *outputTypes, int *outputAutoCommitFirstWordConfidence) const;
- int getBigrams(const int *word, int length, int *outWords, int *outputScores,
- int *outputTypes) const;
+ void getPredictions(const int *word, int length,
+ SuggestionResults *const outSuggestionResults) const;
int getProbability(const int *word, int length) const;
@@ -108,8 +109,8 @@ class Dictionary {
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(Dictionary);
- typedef ExclusiveOwnershipPointer<BigramDictionary> BigramDictionaryPtr;
- typedef ExclusiveOwnershipPointer<SuggestInterface> SuggestInterfacePtr;
+ typedef std::unique_ptr<BigramDictionary> BigramDictionaryPtr;
+ typedef std::unique_ptr<SuggestInterface> SuggestInterfacePtr;
static const int HEADER_ATTRIBUTE_BUFFER_SIZE;
diff --git a/native/jni/src/suggest/core/dictionary/digraph_utils.cpp b/native/jni/src/suggest/core/dictionary/digraph_utils.cpp
index 5f9b8f3e2..bb2ce5012 100644
--- a/native/jni/src/suggest/core/dictionary/digraph_utils.cpp
+++ b/native/jni/src/suggest/core/dictionary/digraph_utils.cpp
@@ -84,7 +84,7 @@ const DigraphUtils::DigraphType DigraphUtils::USED_DIGRAPH_TYPES[] =
}
/**
- * Returns the digraph for the input composite glyph codepoint, or 0 if none exists.
+ * Returns the digraph for the input composite glyph codepoint, or nullptr if none exists.
* compositeGlyphCodePoint: the method returns the digraph corresponding to this codepoint.
*/
/* static */ const DigraphUtils::digraph_t *DigraphUtils::getDigraphForCodePoint(
@@ -96,17 +96,17 @@ const DigraphUtils::DigraphType DigraphUtils::USED_DIGRAPH_TYPES[] =
return digraph;
}
}
- return 0;
+ return nullptr;
}
/**
- * Returns the digraph for the input composite glyph codepoint, or 0 if none exists.
+ * Returns the digraph for the input composite glyph codepoint, or nullptr if none exists.
* digraphType: the type of digraphs supported.
* compositeGlyphCodePoint: the method returns the digraph corresponding to this codepoint.
*/
/* static */ const DigraphUtils::digraph_t *DigraphUtils::getDigraphForDigraphTypeAndCodePoint(
const DigraphUtils::DigraphType digraphType, const int compositeGlyphCodePoint) {
- const DigraphUtils::digraph_t *digraphs = 0;
+ const DigraphUtils::digraph_t *digraphs = nullptr;
const int compositeGlyphLowerCodePoint = CharUtils::toLowerCase(compositeGlyphCodePoint);
const int digraphsSize =
DigraphUtils::getAllDigraphsForDigraphTypeAndReturnSize(digraphType, &digraphs);
@@ -115,7 +115,7 @@ const DigraphUtils::DigraphType DigraphUtils::USED_DIGRAPH_TYPES[] =
return &digraphs[i];
}
}
- return 0;
+ return nullptr;
}
} // namespace latinime
diff --git a/native/jni/src/suggest/core/layout/proximity_info.cpp b/native/jni/src/suggest/core/layout/proximity_info.cpp
index ee8e59ef9..8b3ae4db8 100644
--- a/native/jni/src/suggest/core/layout/proximity_info.cpp
+++ b/native/jni/src/suggest/core/layout/proximity_info.cpp
@@ -18,6 +18,7 @@
#include "suggest/core/layout/proximity_info.h"
+#include <algorithm>
#include <cstring>
#include <cmath>
@@ -63,7 +64,7 @@ ProximityInfo::ProximityInfo(JNIEnv *env, const jstring localeJStr,
static_cast<float>(mostCommonKeyWidth))),
CELL_WIDTH((keyboardWidth + gridWidth - 1) / gridWidth),
CELL_HEIGHT((keyboardHeight + gridHeight - 1) / gridHeight),
- KEY_COUNT(min(keyCount, MAX_KEY_COUNT_IN_A_KEYBOARD)),
+ KEY_COUNT(std::min(keyCount, MAX_KEY_COUNT_IN_A_KEYBOARD)),
KEYBOARD_WIDTH(keyboardWidth), KEYBOARD_HEIGHT(keyboardHeight),
KEYBOARD_HYPOTENUSE(hypotf(KEYBOARD_WIDTH, KEYBOARD_HEIGHT)),
HAS_TOUCH_POSITION_CORRECTION_DATA(keyCount > 0 && keyXCoordinates && keyYCoordinates
diff --git a/native/jni/src/suggest/core/layout/proximity_info_state.cpp b/native/jni/src/suggest/core/layout/proximity_info_state.cpp
index 40c3448ef..2919904e5 100644
--- a/native/jni/src/suggest/core/layout/proximity_info_state.cpp
+++ b/native/jni/src/suggest/core/layout/proximity_info_state.cpp
@@ -18,6 +18,7 @@
#include "suggest/core/layout/proximity_info_state.h"
+#include <algorithm>
#include <cstring> // for memset() and memmove()
#include <sstream> // for debug prints
#include <vector>
@@ -171,7 +172,7 @@ float ProximityInfoState::getPointToKeyLength(
const int keyId = mProximityInfo->getKeyIndexOf(codePoint);
if (keyId != NOT_AN_INDEX) {
const int index = inputIndex * mProximityInfo->getKeyCount() + keyId;
- return min(mSampledNormalizedSquaredLengthCache[index], mMaxPointToKeyLength);
+ return std::min(mSampledNormalizedSquaredLengthCache[index], mMaxPointToKeyLength);
}
if (CharUtils::isIntentionalOmissionCodePoint(codePoint)) {
return 0.0f;
diff --git a/native/jni/src/suggest/core/layout/proximity_info_state.h b/native/jni/src/suggest/core/layout/proximity_info_state.h
index e941e43d8..9abd69a66 100644
--- a/native/jni/src/suggest/core/layout/proximity_info_state.h
+++ b/native/jni/src/suggest/core/layout/proximity_info_state.h
@@ -43,7 +43,7 @@ class ProximityInfoState {
// Defined here //
/////////////////////////////////////////
AK_FORCE_INLINE ProximityInfoState()
- : mProximityInfo(0), mMaxPointToKeyLength(0.0f), mAverageSpeed(0.0f),
+ : mProximityInfo(nullptr), mMaxPointToKeyLength(0.0f), mAverageSpeed(0.0f),
mHasTouchPositionCorrectionData(false), mMostCommonKeyWidthSquare(0),
mKeyCount(0), mCellHeight(0), mCellWidth(0), mGridHeight(0), mGridWidth(0),
mIsContinuousSuggestionPossible(false), mHasBeenUpdatedByGeometricInput(false),
diff --git a/native/jni/src/suggest/core/layout/proximity_info_state_utils.cpp b/native/jni/src/suggest/core/layout/proximity_info_state_utils.cpp
index f84615487..867f59843 100644
--- a/native/jni/src/suggest/core/layout/proximity_info_state_utils.cpp
+++ b/native/jni/src/suggest/core/layout/proximity_info_state_utils.cpp
@@ -241,7 +241,7 @@ namespace latinime {
// Calculate velocity by using distances and durations of
// ProximityInfoParams::NUM_POINTS_FOR_SPEED_CALCULATION points for both forward and
// backward.
- const int forwardNumPoints = min(inputSize - 1,
+ const int forwardNumPoints = std::min(inputSize - 1,
index + ProximityInfoParams::NUM_POINTS_FOR_SPEED_CALCULATION);
for (int j = index; j < forwardNumPoints; ++j) {
if (i < sampledInputSize - 1 && j >= (*sampledInputIndice)[i + 1]) {
@@ -251,7 +251,7 @@ namespace latinime {
xCoordinates[j + 1], yCoordinates[j + 1]);
duration += times[j + 1] - times[j];
}
- const int backwardNumPoints = max(0,
+ const int backwardNumPoints = std::max(0,
index - ProximityInfoParams::NUM_POINTS_FOR_SPEED_CALCULATION);
for (int j = index - 1; j >= backwardNumPoints; --j) {
if (i > 0 && j < (*sampledInputIndice)[i - 1]) {
@@ -273,7 +273,7 @@ namespace latinime {
// Direction calculation.
sampledDirections->resize(sampledInputSize - 1);
- for (int i = max(0, lastSavedInputSize - 1); i < sampledInputSize - 1; ++i) {
+ for (int i = std::max(0, lastSavedInputSize - 1); i < sampledInputSize - 1; ++i) {
(*sampledDirections)[i] = getDirection(sampledInputXs, sampledInputYs, i, i + 1);
}
return averageSpeed;
@@ -610,7 +610,7 @@ namespace latinime {
const int inputIndex, const int keyId) {
if (keyId != NOT_AN_INDEX) {
const int index = inputIndex * keyCount + keyId;
- return min((*sampledNormalizedSquaredLengthCache)[index], maxPointToKeyLength);
+ return std::min((*sampledNormalizedSquaredLengthCache)[index], maxPointToKeyLength);
}
// If the char is not a key on the keyboard then return the max length.
return static_cast<float>(MAX_VALUE_FOR_WEIGHTING);
@@ -651,13 +651,13 @@ namespace latinime {
}
if (i == 0) {
- skipProbability *= min(1.0f,
+ skipProbability *= std::min(1.0f,
nearestKeyDistance * ProximityInfoParams::NEAREST_DISTANCE_WEIGHT
+ ProximityInfoParams::NEAREST_DISTANCE_BIAS);
// Promote the first point
skipProbability *= ProximityInfoParams::SKIP_FIRST_POINT_PROBABILITY;
} else if (i == sampledInputSize - 1) {
- skipProbability *= min(1.0f,
+ skipProbability *= std::min(1.0f,
nearestKeyDistance * ProximityInfoParams::NEAREST_DISTANCE_WEIGHT_FOR_LAST
+ ProximityInfoParams::NEAREST_DISTANCE_BIAS_FOR_LAST);
// Promote the last point
@@ -668,17 +668,17 @@ namespace latinime {
&& speedRate
< (*sampledSpeedRates)[i + 1] - ProximityInfoParams::SPEED_MARGIN) {
if (currentAngle < ProximityInfoParams::CORNER_ANGLE_THRESHOLD) {
- skipProbability *= min(1.0f, speedRate
+ skipProbability *= std::min(1.0f, speedRate
* ProximityInfoParams::SLOW_STRAIGHT_WEIGHT_FOR_SKIP_PROBABILITY);
} else {
// If the angle is small enough, we promote this point more. (e.g. pit vs put)
- skipProbability *= min(1.0f,
+ skipProbability *= std::min(1.0f,
speedRate * ProximityInfoParams::SPEED_WEIGHT_FOR_SKIP_PROBABILITY
+ ProximityInfoParams::MIN_SPEED_RATE_FOR_SKIP_PROBABILITY);
}
}
- skipProbability *= min(1.0f,
+ skipProbability *= std::min(1.0f,
speedRate * nearestKeyDistance * ProximityInfoParams::NEAREST_DISTANCE_WEIGHT
+ ProximityInfoParams::NEAREST_DISTANCE_BIAS);
@@ -708,10 +708,10 @@ namespace latinime {
// (1.0f - skipProbability).
const float inputCharProbability = 1.0f - skipProbability;
- const float speedxAngleRate = min(speedRate * currentAngle / M_PI_F
+ const float speedxAngleRate = std::min(speedRate * currentAngle / M_PI_F
* ProximityInfoParams::SPEEDxANGLE_WEIGHT_FOR_STANDARD_DEVIATION,
ProximityInfoParams::MAX_SPEEDxANGLE_RATE_FOR_STANDARD_DEVIATION);
- const float speedxNearestKeyDistanceRate = min(speedRate * nearestKeyDistance
+ const float speedxNearestKeyDistanceRate = std::min(speedRate * nearestKeyDistance
* ProximityInfoParams::SPEEDxNEAREST_WEIGHT_FOR_STANDARD_DEVIATION,
ProximityInfoParams::MAX_SPEEDxNEAREST_RATE_FOR_STANDARD_DEVIATION);
const float sigma = speedxAngleRate + speedxNearestKeyDistanceRate
@@ -828,7 +828,7 @@ namespace latinime {
// Decrease key probabilities of points which don't have the highest probability of that key
// among nearby points. Probabilities of the first point and the last point are not suppressed.
- for (int i = max(start, 1); i < sampledInputSize; ++i) {
+ for (int i = std::max(start, 1); i < sampledInputSize; ++i) {
for (int j = i + 1; j < sampledInputSize; ++j) {
if (!suppressCharProbabilities(
mostCommonKeyWidth, sampledInputSize, sampledLengthCache, i, j,
@@ -836,7 +836,7 @@ namespace latinime {
break;
}
}
- for (int j = i - 1; j >= max(start, 0); --j) {
+ for (int j = i - 1; j >= std::max(start, 0); --j) {
if (!suppressCharProbabilities(
mostCommonKeyWidth, sampledInputSize, sampledLengthCache, i, j,
charProbabilities)) {
@@ -879,7 +879,7 @@ namespace latinime {
if (i >= lastSavedInputSize) {
(*sampledSearchKeySets)[i].reset();
}
- for (int j = max(i, lastSavedInputSize); j < sampledInputSize; ++j) {
+ for (int j = std::max(i, lastSavedInputSize); j < sampledInputSize; ++j) {
// TODO: Investigate if this is required. This may not fail.
if ((*sampledLengthCache)[j] - (*sampledLengthCache)[i] >= readForwordLength) {
break;
@@ -930,7 +930,7 @@ namespace latinime {
(*charProbabilities)[index0][NOT_AN_INDEX] += suppression;
// Add the probability of the same key nearby index1
- const float probabilityGain = min(suppression
+ const float probabilityGain = std::min(suppression
* ProximityInfoParams::SUPPRESSION_WEIGHT_FOR_PROBABILITY_GAIN,
(*charProbabilities)[index1][NOT_AN_INDEX]
* ProximityInfoParams::SKIP_PROBABALITY_WEIGHT_FOR_PROBABILITY_GAIN);
diff --git a/native/jni/src/suggest/core/layout/proximity_info_utils.h b/native/jni/src/suggest/core/layout/proximity_info_utils.h
index 6d2c11b09..310bbdb62 100644
--- a/native/jni/src/suggest/core/layout/proximity_info_utils.h
+++ b/native/jni/src/suggest/core/layout/proximity_info_utils.h
@@ -100,6 +100,10 @@ class ProximityInfoUtils {
const float dotProduct = ray1x * ray2x + ray1y * ray2y;
const float lineLengthSqr = GeometryUtils::SQUARE_FLOAT(ray2x)
+ GeometryUtils::SQUARE_FLOAT(ray2y);
+ if (lineLengthSqr <= 0.0f) {
+ // Return point to the point distance.
+ return getSquaredDistanceFloat(x, y, x1, y1);
+ }
const float projectionLengthSqr = dotProduct / lineLengthSqr;
float projectionX;
@@ -125,7 +129,7 @@ class ProximityInfoUtils {
struct NormalDistribution {
public:
NormalDistribution(const float u, const float sigma)
- : mU(u), mSigma(sigma),
+ : mU(u),
mPreComputedNonExpPart(1.0f / sqrtf(2.0f * M_PI_F
* GeometryUtils::SQUARE_FLOAT(sigma))),
mPreComputedExponentPart(-1.0f / (2.0f * GeometryUtils::SQUARE_FLOAT(sigma))) {}
@@ -139,7 +143,6 @@ class ProximityInfoUtils {
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(NormalDistribution);
const float mU; // mean value
- const float mSigma; // standard deviation
const float mPreComputedNonExpPart; // = 1 / sqrt(2 * PI * sigma^2)
const float mPreComputedExponentPart; // = -1 / (2 * sigma^2)
}; // struct NormalDistribution
diff --git a/native/jni/src/suggest/core/layout/touch_position_correction_utils.h b/native/jni/src/suggest/core/layout/touch_position_correction_utils.h
index 9130e87d3..14074c13d 100644
--- a/native/jni/src/suggest/core/layout/touch_position_correction_utils.h
+++ b/native/jni/src/suggest/core/layout/touch_position_correction_utils.h
@@ -17,6 +17,8 @@
#ifndef LATINIME_TOUCH_POSITION_CORRECTION_UTILS_H
#define LATINIME_TOUCH_POSITION_CORRECTION_UTILS_H
+#include <algorithm>
+
#include "defines.h"
#include "suggest/core/layout/proximity_info_params.h"
@@ -34,7 +36,7 @@ class TouchPositionCorrectionUtils {
static const float R2 = 1.0f;
const float x = normalizedSquaredDistance;
if (!isTouchPositionCorrectionEnabled) {
- return min(C, x);
+ return std::min(C, x);
}
// factor is a piecewise linear function like:
diff --git a/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h b/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h
index 38e8ff183..b6dc7d006 100644
--- a/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h
+++ b/native/jni/src/suggest/core/policy/dictionary_structure_with_buffer_policy.h
@@ -17,9 +17,10 @@
#ifndef LATINIME_DICTIONARY_STRUCTURE_POLICY_H
#define LATINIME_DICTIONARY_STRUCTURE_POLICY_H
+#include <memory>
+
#include "defines.h"
#include "suggest/core/dictionary/word_property.h"
-#include "utils/exclusive_ownership_pointer.h"
namespace latinime {
@@ -35,7 +36,7 @@ class DictionaryShortcutsStructurePolicy;
*/
class DictionaryStructureWithBufferPolicy {
public:
- typedef ExclusiveOwnershipPointer<DictionaryStructureWithBufferPolicy> StructurePolicyPtr;
+ typedef std::unique_ptr<DictionaryStructureWithBufferPolicy> StructurePolicyPtr;
virtual ~DictionaryStructureWithBufferPolicy() {}
diff --git a/native/jni/src/suggest/core/result/suggested_word.h b/native/jni/src/suggest/core/result/suggested_word.h
new file mode 100644
index 000000000..48b29d6a6
--- /dev/null
+++ b/native/jni/src/suggest/core/result/suggested_word.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef LATINIME_SUGGESTED_WORD_H
+#define LATINIME_SUGGESTED_WORD_H
+
+#include <vector>
+
+#include "defines.h"
+#include "suggest/core/dictionary/dictionary.h"
+
+namespace latinime {
+
+class SuggestedWord {
+ public:
+ class Comparator {
+ public:
+ bool operator()(const SuggestedWord &left, const SuggestedWord &right) {
+ if (left.getScore() != right.getScore()) {
+ return left.getScore() < right.getScore();
+ }
+ return left.getCodePointCount() > right.getCodePointCount();
+ }
+
+ private:
+ DISALLOW_ASSIGNMENT_OPERATOR(Comparator);
+ };
+
+ SuggestedWord(const int *const codePoints, const int codePointCount,
+ const int score, const int type, const int indexToPartialCommit,
+ const int autoCommitFirstWordConfidence)
+ : mCodePoints(codePoints, codePoints + codePointCount), mScore(score),
+ mType(type), mIndexToPartialCommit(indexToPartialCommit),
+ mAutoCommitFirstWordConfidence(autoCommitFirstWordConfidence) {}
+
+ const int *getCodePoint() const {
+ return &mCodePoints.at(0);
+ }
+
+ int getCodePointCount() const {
+ return mCodePoints.size();
+ }
+
+ int getScore() const {
+ return mScore;
+ }
+
+ int getType() const {
+ return mType;
+ }
+
+ int getIndexToPartialCommit() const {
+ return mIndexToPartialCommit;
+ }
+
+ int getAutoCommitFirstWordConfidence() const {
+ return mAutoCommitFirstWordConfidence;
+ }
+
+ private:
+ DISALLOW_DEFAULT_CONSTRUCTOR(SuggestedWord);
+
+ std::vector<int> mCodePoints;
+ int mScore;
+ int mType;
+ int mIndexToPartialCommit;
+ int mAutoCommitFirstWordConfidence;
+};
+} // namespace latinime
+#endif /* LATINIME_SUGGESTED_WORD_H */
diff --git a/native/jni/src/suggest/core/result/suggestion_results.cpp b/native/jni/src/suggest/core/result/suggestion_results.cpp
new file mode 100644
index 000000000..2be757d83
--- /dev/null
+++ b/native/jni/src/suggest/core/result/suggestion_results.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include "suggest/core/result/suggestion_results.h"
+
+namespace latinime {
+
+void SuggestionResults::outputSuggestions(JNIEnv *env, jintArray outSuggestionCount,
+ jintArray outputCodePointsArray, jintArray outScoresArray, jintArray outSpaceIndicesArray,
+ jintArray outTypesArray, jintArray outAutoCommitFirstWordConfidenceArray) {
+ int outputIndex = 0;
+ while (!mSuggestedWords.empty()) {
+ const SuggestedWord &suggestedWord = mSuggestedWords.top();
+ suggestedWord.getCodePointCount();
+ const int start = outputIndex * MAX_WORD_LENGTH;
+ env->SetIntArrayRegion(outputCodePointsArray, start, suggestedWord.getCodePointCount(),
+ suggestedWord.getCodePoint());
+ if (suggestedWord.getCodePointCount() < MAX_WORD_LENGTH) {
+ const int terminal = 0;
+ env->SetIntArrayRegion(outputCodePointsArray, start + suggestedWord.getCodePointCount(),
+ 1 /* len */, &terminal);
+ }
+ const int score = suggestedWord.getScore();
+ env->SetIntArrayRegion(outScoresArray, outputIndex, 1 /* len */, &score);
+ const int indexToPartialCommit = suggestedWord.getIndexToPartialCommit();
+ env->SetIntArrayRegion(outSpaceIndicesArray, outputIndex, 1 /* len */,
+ &indexToPartialCommit);
+ const int type = suggestedWord.getType();
+ env->SetIntArrayRegion(outTypesArray, outputIndex, 1 /* len */, &type);
+ if (mSuggestedWords.size() == 1) {
+ const int autoCommitFirstWordConfidence =
+ suggestedWord.getAutoCommitFirstWordConfidence();
+ env->SetIntArrayRegion(outAutoCommitFirstWordConfidenceArray, 0 /* start */,
+ 1 /* len */, &autoCommitFirstWordConfidence);
+ }
+ ++outputIndex;
+ mSuggestedWords.pop();
+ }
+ env->SetIntArrayRegion(outSuggestionCount, 0 /* start */, 1 /* len */, &outputIndex);
+}
+
+void SuggestionResults::addPrediction(const int *const codePoints, const int codePointCount,
+ const int probability) {
+ if (codePointCount <= 0 || codePointCount > MAX_WORD_LENGTH
+ || probability == NOT_A_PROBABILITY) {
+ // Invalid word.
+ return;
+ }
+ // Use probability as a score of the word.
+ const int score = probability;
+ if (getSuggestionCount() >= mMaxSuggestionCount) {
+ const SuggestedWord &mWorstSuggestion = mSuggestedWords.top();
+ if (score > mWorstSuggestion.getScore() || (score == mWorstSuggestion.getScore()
+ && codePointCount < mWorstSuggestion.getCodePointCount())) {
+ mSuggestedWords.pop();
+ } else {
+ return;
+ }
+ }
+ mSuggestedWords.push(SuggestedWord(codePoints, codePointCount, score,
+ Dictionary::KIND_PREDICTION, NOT_AN_INDEX, NOT_A_FIRST_WORD_CONFIDENCE));
+}
+
+} // namespace latinime
diff --git a/native/jni/src/suggest/core/result/suggestion_results.h b/native/jni/src/suggest/core/result/suggestion_results.h
new file mode 100644
index 000000000..0b841ca19
--- /dev/null
+++ b/native/jni/src/suggest/core/result/suggestion_results.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#ifndef LATINIME_SUGGESTION_RESULTS_H
+#define LATINIME_SUGGESTION_RESULTS_H
+
+#include <queue>
+#include <vector>
+
+#include "defines.h"
+#include "jni.h"
+#include "suggest/core/result/suggested_word.h"
+
+namespace latinime {
+
+class SuggestionResults {
+ public:
+ explicit SuggestionResults(const int maxSuggestionCount)
+ : mMaxSuggestionCount(maxSuggestionCount), mSuggestedWords() {}
+
+ // Returns suggestion count.
+ void outputSuggestions(JNIEnv *env, jintArray outSuggestionCount, jintArray outCodePointsArray,
+ jintArray outScoresArray, jintArray outSpaceIndicesArray, jintArray outTypesArray,
+ jintArray outAutoCommitFirstWordConfidenceArray);
+
+ void addPrediction(const int *const codePoints, const int codePointCount, const int score);
+
+ int getSuggestionCount() const {
+ return mSuggestedWords.size();
+ }
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(SuggestionResults);
+
+ const int mMaxSuggestionCount;
+ std::priority_queue<
+ SuggestedWord, std::vector<SuggestedWord>, SuggestedWord::Comparator> mSuggestedWords;
+};
+} // namespace latinime
+#endif // LATINIME_SUGGESTION_RESULTS_H
diff --git a/native/jni/src/suggest/core/result/suggestions_output_utils.cpp b/native/jni/src/suggest/core/result/suggestions_output_utils.cpp
index e9fb3b885..19912f2ac 100644
--- a/native/jni/src/suggest/core/result/suggestions_output_utils.cpp
+++ b/native/jni/src/suggest/core/result/suggestions_output_utils.cpp
@@ -16,6 +16,8 @@
#include "suggest/core/result/suggestions_output_utils.h"
+#include <algorithm>
+
#include "suggest/core/dicnode/dic_node.h"
#include "suggest/core/dicnode/dic_node_utils.h"
#include "suggest/core/dictionary/binary_dictionary_shortcut_iterator.h"
@@ -36,7 +38,7 @@ const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
#if DEBUG_EVALUATE_MOST_PROBABLE_STRING
const int terminalSize = 0;
#else
- const int terminalSize = min(MAX_RESULTS,
+ const int terminalSize = std::min(MAX_RESULTS,
static_cast<int>(traverseSession->getDicTraverseCache()->terminalSize()));
#endif
DicNode terminals[MAX_RESULTS]; // Avoiding non-POD variable length array
@@ -245,12 +247,12 @@ const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
// shortcut entry's score == its base entry's score - 1
shortcutScore = finalScore;
// Protection against int underflow
- shortcutScore = max(S_INT_MIN + 1, shortcutScore) - 1;
+ shortcutScore = std::max(S_INT_MIN + 1, shortcutScore) - 1;
kind = Dictionary::KIND_SHORTCUT;
}
outputTypes[outputWordIndex] = kind;
outputScores[outputWordIndex] = shortcutScore;
- outputScores[outputWordIndex] = max(S_INT_MIN + 1, shortcutScore) - 1;
+ outputScores[outputWordIndex] = std::max(S_INT_MIN + 1, shortcutScore) - 1;
const int startIndex2 = outputWordIndex * MAX_WORD_LENGTH;
DicNodeUtils::appendTwoWords(0, 0, shortcutTarget, shortcutTargetStringLength,
&outputCodePoints[startIndex2]);
diff --git a/native/jni/src/suggest/core/session/dic_traverse_session.h b/native/jni/src/suggest/core/session/dic_traverse_session.h
index 6e4dda44d..b718fb57a 100644
--- a/native/jni/src/suggest/core/session/dic_traverse_session.h
+++ b/native/jni/src/suggest/core/session/dic_traverse_session.h
@@ -59,8 +59,8 @@ class DicTraverseSession {
}
AK_FORCE_INLINE DicTraverseSession(JNIEnv *env, jstring localeStr, bool usesLargeCache)
- : mPrevWordPtNodePos(NOT_A_DICT_POS), mProximityInfo(0),
- mDictionary(0), mSuggestOptions(0), mDicNodesCache(usesLargeCache),
+ : mPrevWordPtNodePos(NOT_A_DICT_POS), mProximityInfo(nullptr),
+ mDictionary(nullptr), mSuggestOptions(nullptr), mDicNodesCache(usesLargeCache),
mMultiBigramMap(), mInputSize(0), mPartiallyCommited(false), mMaxPointerCount(1),
mMultiWordCostMultiplier(1.0f) {
// NOTE: mProximityInfoStates is an array of instances.
diff --git a/native/jni/src/suggest/core/suggest.h b/native/jni/src/suggest/core/suggest.h
index b1d12ad9a..c42986ad6 100644
--- a/native/jni/src/suggest/core/suggest.h
+++ b/native/jni/src/suggest/core/suggest.h
@@ -42,9 +42,9 @@ class Weighting;
class Suggest : public SuggestInterface {
public:
AK_FORCE_INLINE Suggest(const SuggestPolicy *const suggestPolicy)
- : TRAVERSAL(suggestPolicy ? suggestPolicy->getTraversal() : 0),
- SCORING(suggestPolicy ? suggestPolicy->getScoring() : 0),
- WEIGHTING(suggestPolicy ? suggestPolicy->getWeighting() : 0) {}
+ : TRAVERSAL(suggestPolicy ? suggestPolicy->getTraversal() : nullptr),
+ SCORING(suggestPolicy ? suggestPolicy->getScoring() : nullptr),
+ WEIGHTING(suggestPolicy ? suggestPolicy->getWeighting() : nullptr) {}
AK_FORCE_INLINE virtual ~Suggest() {}
int getSuggestions(ProximityInfo *pInfo, void *traverseSession, int *inputXs, int *inputYs,
int *times, int *pointerIds, int *inputCodePoints, int inputSize, int commitPoint,
diff --git a/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.cpp
index 7c7b05ca8..ecc9fdab1 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/header/header_policy.cpp
@@ -16,6 +16,8 @@
#include "suggest/policyimpl/dictionary/header/header_policy.h"
+#include <algorithm>
+
namespace latinime {
// Note that these are corresponding definitions in Java side in DictionaryHeader.
@@ -72,7 +74,7 @@ void HeaderPolicy::readHeaderValueOrQuestionMark(const char *const key, int *out
outValue[1] = '\0';
return;
}
- const int terminalIndex = min(static_cast<int>(it->second.size()), outValueSize - 1);
+ const int terminalIndex = std::min(static_cast<int>(it->second.size()), outValueSize - 1);
for (int i = 0; i < terminalIndex; ++i) {
outValue[i] = it->second[i];
}
diff --git a/native/jni/src/suggest/policyimpl/dictionary/shortcut/ver4_shortcut_list_policy.h b/native/jni/src/suggest/policyimpl/dictionary/shortcut/ver4_shortcut_list_policy.h
index ae863af57..f2fa5b75b 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/shortcut/ver4_shortcut_list_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/shortcut/ver4_shortcut_list_policy.h
@@ -31,8 +31,7 @@ class Ver4ShortcutListPolicy : public DictionaryShortcutsStructurePolicy {
public:
Ver4ShortcutListPolicy(ShortcutDictContent *const shortcutDictContent,
const TerminalPositionLookupTable *const terminalPositionLookupTable)
- : mShortcutDictContent(shortcutDictContent),
- mTerminalPositionLookupTable(terminalPositionLookupTable) {}
+ : mShortcutDictContent(shortcutDictContent) {}
~Ver4ShortcutListPolicy() {}
@@ -104,7 +103,6 @@ class Ver4ShortcutListPolicy : public DictionaryShortcutsStructurePolicy {
DISALLOW_IMPLICIT_CONSTRUCTORS(Ver4ShortcutListPolicy);
ShortcutDictContent *const mShortcutDictContent;
- const TerminalPositionLookupTable *const mTerminalPositionLookupTable;
};
} // namespace latinime
#endif // LATINIME_VER4_SHORTCUT_LIST_POLICY_H
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.cpp
index 04f119803..79bcf6fa4 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.cpp
@@ -41,7 +41,7 @@ namespace latinime {
if (isUpdatable) {
AKLOGE("One file dictionaries don't support updating. path: %s", path);
ASSERT(false);
- return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(0);
+ return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(nullptr);
}
return newPolicyforFileDict(path, bufOffset, size);
}
@@ -55,13 +55,13 @@ namespace latinime {
getHeaderFilePathInDictDir(path, headerFilePathBufSize, headerFilePath);
// Allocated buffer in MmapedBuffer::openBuffer() will be freed in the destructor of
// MmappedBufferPtr if the instance has the responsibility.
- MmappedBuffer::MmappedBufferPtr mmappedBuffer = MmappedBuffer::openBuffer(headerFilePath,
- isUpdatable);
- if (!mmappedBuffer.get()) {
- return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(0);
+ MmappedBuffer::MmappedBufferPtr mmappedBuffer(
+ MmappedBuffer::openBuffer(headerFilePath, isUpdatable));
+ if (!mmappedBuffer) {
+ return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(nullptr);
}
- switch (FormatUtils::detectFormatVersion(mmappedBuffer.get()->getBuffer(),
- mmappedBuffer.get()->getBufferSize())) {
+ switch (FormatUtils::detectFormatVersion(mmappedBuffer->getBuffer(),
+ mmappedBuffer->getBufferSize())) {
case FormatUtils::VERSION_2:
AKLOGE("Given path is a directory but the format is version 2. path: %s", path);
break;
@@ -72,25 +72,25 @@ namespace latinime {
Ver4DictConstants::HEADER_FILE_EXTENSION, dictDirPathBufSize, dictPath)) {
AKLOGE("Dictionary file name is not valid as a ver4 dictionary. path: %s", path);
ASSERT(false);
- return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(0);
+ return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(nullptr);
}
- const Ver4DictBuffers::Ver4DictBuffersPtr dictBuffers =
- Ver4DictBuffers::openVer4DictBuffers(dictPath, mmappedBuffer);
- if (!dictBuffers.get() || !dictBuffers.get()->isValid()) {
+ Ver4DictBuffers::Ver4DictBuffersPtr dictBuffers(
+ Ver4DictBuffers::openVer4DictBuffers(dictPath, std::move(mmappedBuffer)));
+ if (!dictBuffers || !dictBuffers->isValid()) {
AKLOGE("DICT: The dictionary doesn't satisfy ver4 format requirements. path: %s",
path);
ASSERT(false);
- return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(0);
+ return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(nullptr);
}
return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(
- new Ver4PatriciaTriePolicy(dictBuffers));
+ new Ver4PatriciaTriePolicy(std::move(dictBuffers)));
}
default:
AKLOGE("DICT: dictionary format is unknown, bad magic number. path: %s", path);
break;
}
ASSERT(false);
- return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(0);
+ return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(nullptr);
}
/* static */ DictionaryStructureWithBufferPolicy::StructurePolicyPtr
@@ -98,16 +98,16 @@ namespace latinime {
const char *const path, const int bufOffset, const int size) {
// Allocated buffer in MmapedBuffer::openBuffer() will be freed in the destructor of
// MmappedBufferPtr if the instance has the responsibility.
- MmappedBuffer::MmappedBufferPtr mmappedBuffer = MmappedBuffer::openBuffer(path, bufOffset,
- size, false /* isUpdatable */);
- if (!mmappedBuffer.get()) {
- return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(0);
+ MmappedBuffer::MmappedBufferPtr mmappedBuffer(
+ MmappedBuffer::openBuffer(path, bufOffset, size, false /* isUpdatable */));
+ if (!mmappedBuffer) {
+ return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(nullptr);
}
- switch (FormatUtils::detectFormatVersion(mmappedBuffer.get()->getBuffer(),
- mmappedBuffer.get()->getBufferSize())) {
+ switch (FormatUtils::detectFormatVersion(mmappedBuffer->getBuffer(),
+ mmappedBuffer->getBufferSize())) {
case FormatUtils::VERSION_2:
return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(
- new PatriciaTriePolicy(mmappedBuffer));
+ new PatriciaTriePolicy(std::move(mmappedBuffer)));
case FormatUtils::VERSION_4:
AKLOGE("Given path is a file but the format is version 4. path: %s", path);
break;
@@ -116,7 +116,7 @@ namespace latinime {
break;
}
ASSERT(false);
- return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(0);
+ return DictionaryStructureWithBufferPolicy::StructurePolicyPtr(nullptr);
}
/* static */ void DictionaryStructureWithBufferPolicyFactory::getHeaderFilePathInDictDir(
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.h b/native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.h
index 45ab52931..9454ddf33 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/dictionary_structure_with_buffer_policy_factory.h
@@ -21,7 +21,6 @@
#include "defines.h"
#include "suggest/core/policy/dictionary_structure_with_buffer_policy.h"
-#include "utils/exclusive_ownership_pointer.h"
namespace latinime {
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h
index 6a2345a05..11a40de55 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v2/patricia_trie_policy.h
@@ -37,12 +37,11 @@ class DicNodeVector;
class PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy {
public:
- PatriciaTriePolicy(const MmappedBuffer::MmappedBufferPtr &mmappedBuffer)
- : mMmappedBuffer(mmappedBuffer),
- mHeaderPolicy(mMmappedBuffer.get()->getBuffer(), FormatUtils::VERSION_2),
- mDictRoot(mMmappedBuffer.get()->getBuffer() + mHeaderPolicy.getSize()),
- mDictBufferSize(mMmappedBuffer.get()->getBufferSize()
- - mHeaderPolicy.getSize()),
+ PatriciaTriePolicy(MmappedBuffer::MmappedBufferPtr mmappedBuffer)
+ : mMmappedBuffer(std::move(mmappedBuffer)),
+ mHeaderPolicy(mMmappedBuffer->getBuffer(), FormatUtils::VERSION_2),
+ mDictRoot(mMmappedBuffer->getBuffer() + mHeaderPolicy.getSize()),
+ mDictBufferSize(mMmappedBuffer->getBufferSize() - mHeaderPolicy.getSize()),
mBigramListPolicy(mDictRoot), mShortcutListPolicy(mDictRoot),
mPtNodeReader(mDictRoot, mDictBufferSize, &mBigramListPolicy, &mShortcutListPolicy),
mPtNodeArrayReader(mDictRoot, mDictBufferSize),
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/single_dict_content.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/single_dict_content.h
index 9064b7e72..215642234 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/single_dict_content.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/single_dict_content.h
@@ -31,14 +31,14 @@ class SingleDictContent : public DictContent {
SingleDictContent(const char *const dictPath, const char *const contentFileName,
const bool isUpdatable)
: mMmappedBuffer(MmappedBuffer::openBuffer(dictPath, contentFileName, isUpdatable)),
- mExpandableContentBuffer(mMmappedBuffer.get() ? mMmappedBuffer.get()->getBuffer() : 0,
- mMmappedBuffer.get() ? mMmappedBuffer.get()->getBufferSize() : 0,
+ mExpandableContentBuffer(mMmappedBuffer ? mMmappedBuffer->getBuffer() : nullptr,
+ mMmappedBuffer ? mMmappedBuffer->getBufferSize() : 0,
BufferWithExtendableBuffer::DEFAULT_MAX_ADDITIONAL_BUFFER_SIZE),
- mIsValid(mMmappedBuffer.get() != 0) {}
+ mIsValid(mMmappedBuffer) {}
SingleDictContent()
- : mMmappedBuffer(0), mExpandableContentBuffer(Ver4DictConstants::MAX_DICTIONARY_SIZE),
- mIsValid(true) {}
+ : mMmappedBuffer(nullptr),
+ mExpandableContentBuffer(Ver4DictConstants::MAX_DICTIONARY_SIZE), mIsValid(true) {}
virtual ~SingleDictContent() {}
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/sparse_table_dict_content.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/sparse_table_dict_content.h
index a82e3f50a..fb6c88eef 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/sparse_table_dict_content.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/content/sparse_table_dict_content.h
@@ -38,25 +38,25 @@ class SparseTableDictContent : public DictContent {
MmappedBuffer::openBuffer(dictPath, lookupTableFileName, isUpdatable)),
mAddressTableBuffer(
MmappedBuffer::openBuffer(dictPath, addressTableFileName, isUpdatable)),
- mContentBuffer(MmappedBuffer::openBuffer(dictPath, contentFileName, isUpdatable)),
+ mContentBuffer(
+ MmappedBuffer::openBuffer(dictPath, contentFileName, isUpdatable)),
mExpandableLookupTableBuffer(
- mLookupTableBuffer.get() ? mLookupTableBuffer.get()->getBuffer() : 0,
- mLookupTableBuffer.get() ? mLookupTableBuffer.get()->getBufferSize() : 0,
+ mLookupTableBuffer ? mLookupTableBuffer->getBuffer() : nullptr,
+ mLookupTableBuffer ? mLookupTableBuffer->getBufferSize() : 0,
BufferWithExtendableBuffer::DEFAULT_MAX_ADDITIONAL_BUFFER_SIZE),
mExpandableAddressTableBuffer(
- mAddressTableBuffer.get() ? mAddressTableBuffer.get()->getBuffer() : 0,
- mAddressTableBuffer.get() ? mAddressTableBuffer.get()->getBufferSize() : 0,
+ mAddressTableBuffer ? mAddressTableBuffer->getBuffer() : nullptr,
+ mAddressTableBuffer ? mAddressTableBuffer->getBufferSize() : 0,
BufferWithExtendableBuffer::DEFAULT_MAX_ADDITIONAL_BUFFER_SIZE),
- mExpandableContentBuffer(mContentBuffer.get() ? mContentBuffer.get()->getBuffer() : 0,
- mContentBuffer.get() ? mContentBuffer.get()->getBufferSize() : 0,
+ mExpandableContentBuffer(mContentBuffer ? mContentBuffer->getBuffer() : nullptr,
+ mContentBuffer ? mContentBuffer->getBufferSize() : 0,
BufferWithExtendableBuffer::DEFAULT_MAX_ADDITIONAL_BUFFER_SIZE),
mAddressLookupTable(&mExpandableLookupTableBuffer, &mExpandableAddressTableBuffer,
sparseTableBlockSize, sparseTableDataSize),
- mIsValid(mLookupTableBuffer.get() != 0 && mAddressTableBuffer.get() != 0
- && mContentBuffer.get() != 0) {}
+ mIsValid(mLookupTableBuffer && mAddressTableBuffer && mContentBuffer) {}
SparseTableDictContent(const int sparseTableBlockSize, const int sparseTableDataSize)
- : mLookupTableBuffer(0), mAddressTableBuffer(0), mContentBuffer(0),
+ : mLookupTableBuffer(), mAddressTableBuffer(), mContentBuffer(),
mExpandableLookupTableBuffer(Ver4DictConstants::MAX_DICTIONARY_SIZE),
mExpandableAddressTableBuffer(Ver4DictConstants::MAX_DICTIONARY_SIZE),
mExpandableContentBuffer(Ver4DictConstants::MAX_DICTIONARY_SIZE),
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.cpp
index 59dedee72..9319ea982 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.cpp
@@ -27,15 +27,15 @@
namespace latinime {
/* static */ Ver4DictBuffers::Ver4DictBuffersPtr Ver4DictBuffers::openVer4DictBuffers(
- const char *const dictPath, const MmappedBuffer::MmappedBufferPtr &headerBuffer) {
- if (!headerBuffer.get()) {
+ const char *const dictPath, MmappedBuffer::MmappedBufferPtr headerBuffer) {
+ if (!headerBuffer) {
ASSERT(false);
AKLOGE("The header buffer must be valid to open ver4 dict buffers.");
- return Ver4DictBuffersPtr(0);
+ return Ver4DictBuffersPtr(nullptr);
}
// TODO: take only dictDirPath, and open both header and trie files in the constructor below
- return Ver4DictBuffersPtr(new Ver4DictBuffers(
- dictPath, headerBuffer, headerBuffer.get()->isUpdatable()));
+ const bool isUpdatable = headerBuffer->isUpdatable();
+ return Ver4DictBuffersPtr(new Ver4DictBuffers(dictPath, std::move(headerBuffer), isUpdatable));
}
bool Ver4DictBuffers::flushHeaderAndDictBuffers(const char *const dictDirPath,
@@ -113,27 +113,25 @@ bool Ver4DictBuffers::flushHeaderAndDictBuffers(const char *const dictDirPath,
}
Ver4DictBuffers::Ver4DictBuffers(const char *const dictPath,
- const MmappedBuffer::MmappedBufferPtr &headerBuffer, const bool isUpdatable)
- : mHeaderBuffer(headerBuffer),
+ MmappedBuffer::MmappedBufferPtr headerBuffer, const bool isUpdatable)
+ : mHeaderBuffer(std::move(headerBuffer)),
mDictBuffer(MmappedBuffer::openBuffer(dictPath,
Ver4DictConstants::TRIE_FILE_EXTENSION, isUpdatable)),
- mHeaderPolicy(headerBuffer.get()->getBuffer(), FormatUtils::VERSION_4),
- mExpandableHeaderBuffer(headerBuffer.get() ? headerBuffer.get()->getBuffer() : 0,
+ mHeaderPolicy(mHeaderBuffer->getBuffer(), FormatUtils::VERSION_4),
+ mExpandableHeaderBuffer(mHeaderBuffer ? mHeaderBuffer->getBuffer() : nullptr,
mHeaderPolicy.getSize(),
BufferWithExtendableBuffer::DEFAULT_MAX_ADDITIONAL_BUFFER_SIZE),
- mExpandableTrieBuffer(mDictBuffer.get() ? mDictBuffer.get()->getBuffer() : 0,
- mDictBuffer.get() ? mDictBuffer.get()->getBufferSize() : 0,
+ mExpandableTrieBuffer(mDictBuffer ? mDictBuffer->getBuffer() : nullptr,
+ mDictBuffer ? mDictBuffer->getBufferSize() : 0,
BufferWithExtendableBuffer::DEFAULT_MAX_ADDITIONAL_BUFFER_SIZE),
mTerminalPositionLookupTable(dictPath, isUpdatable),
- mProbabilityDictContent(dictPath, mHeaderPolicy.hasHistoricalInfoOfWords(),
- isUpdatable),
- mBigramDictContent(dictPath, mHeaderPolicy.hasHistoricalInfoOfWords(),
- isUpdatable),
+ mProbabilityDictContent(dictPath, mHeaderPolicy.hasHistoricalInfoOfWords(), isUpdatable),
+ mBigramDictContent(dictPath, mHeaderPolicy.hasHistoricalInfoOfWords(), isUpdatable),
mShortcutDictContent(dictPath, isUpdatable),
mIsUpdatable(isUpdatable) {}
Ver4DictBuffers::Ver4DictBuffers(const HeaderPolicy *const headerPolicy)
- : mHeaderBuffer(0), mDictBuffer(0), mHeaderPolicy(),
+ : mHeaderBuffer(nullptr), mDictBuffer(nullptr), mHeaderPolicy(),
mExpandableHeaderBuffer(Ver4DictConstants::MAX_DICTIONARY_SIZE),
mExpandableTrieBuffer(Ver4DictConstants::MAX_DICTIONARY_SIZE),
mTerminalPositionLookupTable(),
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h
index 776bb9882..ab756bb41 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_dict_buffers.h
@@ -17,6 +17,8 @@
#ifndef LATINIME_VER4_DICT_BUFFER_H
#define LATINIME_VER4_DICT_BUFFER_H
+#include <memory>
+
#include "defines.h"
#include "suggest/policyimpl/dictionary/header/header_policy.h"
#include "suggest/policyimpl/dictionary/structure/v4/content/bigram_dict_content.h"
@@ -31,10 +33,10 @@ namespace latinime {
class Ver4DictBuffers {
public:
- typedef ExclusiveOwnershipPointer<Ver4DictBuffers> Ver4DictBuffersPtr;
+ typedef std::unique_ptr<Ver4DictBuffers> Ver4DictBuffersPtr;
static Ver4DictBuffersPtr openVer4DictBuffers(const char *const dictDirPath,
- const MmappedBuffer::MmappedBufferPtr &headerBuffer);
+ MmappedBuffer::MmappedBufferPtr headerBuffer);
static AK_FORCE_INLINE Ver4DictBuffersPtr createVer4DictBuffers(
const HeaderPolicy *const headerPolicy) {
@@ -42,7 +44,7 @@ class Ver4DictBuffers {
}
AK_FORCE_INLINE bool isValid() const {
- return mHeaderBuffer.get() && mDictBuffer.get() && mHeaderPolicy.isValid()
+ return mHeaderBuffer && mDictBuffer && mHeaderPolicy.isValid()
&& mProbabilityDictContent.isValid() && mTerminalPositionLookupTable.isValid()
&& mBigramDictContent.isValid() && mShortcutDictContent.isValid();
}
@@ -118,7 +120,7 @@ class Ver4DictBuffers {
DISALLOW_COPY_AND_ASSIGN(Ver4DictBuffers);
Ver4DictBuffers(const char *const dictDirPath,
- const MmappedBuffer::MmappedBufferPtr &headerBuffer, const bool isUpdatable);
+ const MmappedBuffer::MmappedBufferPtr headerBuffer, const bool isUpdatable);
Ver4DictBuffers(const HeaderPolicy *const headerPolicy);
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp
index 4d1b0dadb..1a38a27ff 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.cpp
@@ -135,7 +135,7 @@ int Ver4PatriciaTriePolicy::getShortcutPositionOfPtNode(const int ptNodePos) con
if (ptNodeParams.isDeleted()) {
return NOT_A_DICT_POS;
}
- return mBuffers.get()->getShortcutDictContent()->getShortcutListHeadPos(
+ return mBuffers->getShortcutDictContent()->getShortcutListHeadPos(
ptNodeParams.getTerminalId());
}
@@ -147,7 +147,7 @@ int Ver4PatriciaTriePolicy::getBigramsPositionOfPtNode(const int ptNodePos) cons
if (ptNodeParams.isDeleted()) {
return NOT_A_DICT_POS;
}
- return mBuffers.get()->getBigramDictContent()->getBigramListHeadPos(
+ return mBuffers->getBigramDictContent()->getBigramListHeadPos(
ptNodeParams.getTerminalId());
}
@@ -155,7 +155,7 @@ bool Ver4PatriciaTriePolicy::addUnigramWord(const int *const word, const int len
const int probability, const int *const shortcutTargetCodePoints, const int shortcutLength,
const int shortcutProbability, const bool isNotAWord, const bool isBlacklisted,
const int timestamp) {
- if (!mBuffers.get()->isUpdatable()) {
+ if (!mBuffers->isUpdatable()) {
AKLOGI("Warning: addUnigramWord() is called for non-updatable dictionary.");
return false;
}
@@ -205,7 +205,7 @@ bool Ver4PatriciaTriePolicy::addUnigramWord(const int *const word, const int len
bool Ver4PatriciaTriePolicy::addBigramWords(const int *const word0, const int length0,
const int *const word1, const int length1, const int probability,
const int timestamp) {
- if (!mBuffers.get()->isUpdatable()) {
+ if (!mBuffers->isUpdatable()) {
AKLOGI("Warning: addBigramWords() is called for non-updatable dictionary.");
return false;
}
@@ -243,7 +243,7 @@ bool Ver4PatriciaTriePolicy::addBigramWords(const int *const word0, const int le
bool Ver4PatriciaTriePolicy::removeBigramWords(const int *const word0, const int length0,
const int *const word1, const int length1) {
- if (!mBuffers.get()->isUpdatable()) {
+ if (!mBuffers->isUpdatable()) {
AKLOGI("Warning: addBigramWords() is called for non-updatable dictionary.");
return false;
}
@@ -276,7 +276,7 @@ bool Ver4PatriciaTriePolicy::removeBigramWords(const int *const word0, const int
}
void Ver4PatriciaTriePolicy::flush(const char *const filePath) {
- if (!mBuffers.get()->isUpdatable()) {
+ if (!mBuffers->isUpdatable()) {
AKLOGI("Warning: flush() is called for non-updatable dictionary. filePath: %s", filePath);
return;
}
@@ -287,7 +287,7 @@ void Ver4PatriciaTriePolicy::flush(const char *const filePath) {
}
void Ver4PatriciaTriePolicy::flushWithGC(const char *const filePath) {
- if (!mBuffers.get()->isUpdatable()) {
+ if (!mBuffers->isUpdatable()) {
AKLOGI("Warning: flushWithGC() is called for non-updatable dictionary.");
return;
}
@@ -298,11 +298,11 @@ void Ver4PatriciaTriePolicy::flushWithGC(const char *const filePath) {
}
bool Ver4PatriciaTriePolicy::needsToRunGC(const bool mindsBlockByGC) const {
- if (!mBuffers.get()->isUpdatable()) {
+ if (!mBuffers->isUpdatable()) {
AKLOGI("Warning: needsToRunGC() is called for non-updatable dictionary.");
return false;
}
- if (mBuffers.get()->isNearSizeLimit()) {
+ if (mBuffers->isNearSizeLimit()) {
// Additional buffer size is near the limit.
return true;
} else if (mHeaderPolicy->getExtendedRegionSize() + mDictBuffer->getUsedAdditionalBufferSize()
@@ -354,7 +354,7 @@ const WordProperty Ver4PatriciaTriePolicy::getWordProperty(const int *const code
std::vector<int> codePointVector(ptNodeParams.getCodePoints(),
ptNodeParams.getCodePoints() + ptNodeParams.getCodePointCount());
const ProbabilityEntry probabilityEntry =
- mBuffers.get()->getProbabilityDictContent()->getProbabilityEntry(
+ mBuffers->getProbabilityDictContent()->getProbabilityEntry(
ptNodeParams.getTerminalId());
const HistoricalInfo *const historicalInfo = probabilityEntry.getHistoricalInfo();
// Fetch bigram information.
@@ -362,9 +362,9 @@ const WordProperty Ver4PatriciaTriePolicy::getWordProperty(const int *const code
const int bigramListPos = getBigramsPositionOfPtNode(ptNodePos);
if (bigramListPos != NOT_A_DICT_POS) {
int bigramWord1CodePoints[MAX_WORD_LENGTH];
- const BigramDictContent *const bigramDictContent = mBuffers.get()->getBigramDictContent();
+ const BigramDictContent *const bigramDictContent = mBuffers->getBigramDictContent();
const TerminalPositionLookupTable *const terminalPositionLookupTable =
- mBuffers.get()->getTerminalPositionLookupTable();
+ mBuffers->getTerminalPositionLookupTable();
bool hasNext = true;
int readingPos = bigramListPos;
while (hasNext) {
@@ -400,7 +400,7 @@ const WordProperty Ver4PatriciaTriePolicy::getWordProperty(const int *const code
if (shortcutPos != NOT_A_DICT_POS) {
int shortcutTarget[MAX_WORD_LENGTH];
const ShortcutDictContent *const shortcutDictContent =
- mBuffers.get()->getShortcutDictContent();
+ mBuffers->getShortcutDictContent();
bool hasNext = true;
while (hasNext) {
int shortcutTargetLength = 0;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h
index 639c153a1..cffb1f64d 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_policy.h
@@ -37,17 +37,16 @@ namespace latinime {
class DicNode;
class DicNodeVector;
-// TODO: Implement.
class Ver4PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy {
public:
- Ver4PatriciaTriePolicy(const Ver4DictBuffers::Ver4DictBuffersPtr &buffers)
- : mBuffers(buffers), mHeaderPolicy(mBuffers.get()->getHeaderPolicy()),
- mDictBuffer(mBuffers.get()->getWritableTrieBuffer()),
- mBigramPolicy(mBuffers.get()->getMutableBigramDictContent(),
- mBuffers.get()->getTerminalPositionLookupTable(), mHeaderPolicy),
- mShortcutPolicy(mBuffers.get()->getMutableShortcutDictContent(),
- mBuffers.get()->getTerminalPositionLookupTable()),
- mNodeReader(mDictBuffer, mBuffers.get()->getProbabilityDictContent(), mHeaderPolicy),
+ Ver4PatriciaTriePolicy(Ver4DictBuffers::Ver4DictBuffersPtr buffers)
+ : mBuffers(std::move(buffers)), mHeaderPolicy(mBuffers->getHeaderPolicy()),
+ mDictBuffer(mBuffers->getWritableTrieBuffer()),
+ mBigramPolicy(mBuffers->getMutableBigramDictContent(),
+ mBuffers->getTerminalPositionLookupTable(), mHeaderPolicy),
+ mShortcutPolicy(mBuffers->getMutableShortcutDictContent(),
+ mBuffers->getTerminalPositionLookupTable()),
+ mNodeReader(mDictBuffer, mBuffers->getProbabilityDictContent(), mHeaderPolicy),
mPtNodeArrayReader(mDictBuffer),
mNodeWriter(mDictBuffer, mBuffers.get(), mHeaderPolicy, &mNodeReader,
&mPtNodeArrayReader, &mBigramPolicy, &mShortcutPolicy),
@@ -132,7 +131,7 @@ class Ver4PatriciaTriePolicy : public DictionaryStructureWithBufferPolicy {
static const int MARGIN_TO_REFUSE_DYNAMIC_OPERATIONS;
static const int MIN_DICT_SIZE_TO_REFUSE_DYNAMIC_OPERATIONS;
- Ver4DictBuffers::Ver4DictBuffersPtr mBuffers;
+ const Ver4DictBuffers::Ver4DictBuffersPtr mBuffers;
const HeaderPolicy *const mHeaderPolicy;
BufferWithExtendableBuffer *const mDictBuffer;
Ver4BigramListPolicy mBigramPolicy;
diff --git a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.cpp b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.cpp
index 3907c84a0..2b1f60e5d 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/structure/v4/ver4_patricia_trie_writing_helper.cpp
@@ -67,7 +67,7 @@ bool Ver4PatriciaTrieWritingHelper::writeToDictFileWithGC(const int rootPtNodeAr
unigramCount, bigramCount, 0 /* extendedRegionSize */, &headerBuffer)) {
return false;
}
- return dictBuffers.get()->flushHeaderAndDictBuffers(dictDirPath, &headerBuffer);
+ return dictBuffers->flushHeaderAndDictBuffers(dictDirPath, &headerBuffer);
}
bool Ver4PatriciaTrieWritingHelper::runGC(const int rootPtNodeArrayPos,
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/dict_file_writing_utils.cpp b/native/jni/src/suggest/policyimpl/dictionary/utils/dict_file_writing_utils.cpp
index faef72079..4459e86a3 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/dict_file_writing_utils.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/dict_file_writing_utils.cpp
@@ -48,17 +48,17 @@ const char *const DictFileWritingUtils::TEMP_FILE_SUFFIX_FOR_WRITING_DICT_FILE =
const std::vector<int> localeAsCodePointVector,
const DictionaryHeaderStructurePolicy::AttributeMap *const attributeMap) {
HeaderPolicy headerPolicy(FormatUtils::VERSION_4, localeAsCodePointVector, attributeMap);
- Ver4DictBuffers::Ver4DictBuffersPtr dictBuffers =
- Ver4DictBuffers::createVer4DictBuffers(&headerPolicy);
+ Ver4DictBuffers::Ver4DictBuffersPtr dictBuffers(
+ Ver4DictBuffers::createVer4DictBuffers(&headerPolicy));
headerPolicy.fillInAndWriteHeaderToBuffer(true /* updatesLastDecayedTime */,
0 /* unigramCount */, 0 /* bigramCount */,
- 0 /* extendedRegionSize */, dictBuffers.get()->getWritableHeaderBuffer());
+ 0 /* extendedRegionSize */, dictBuffers->getWritableHeaderBuffer());
if (!DynamicPtWritingUtils::writeEmptyDictionary(
- dictBuffers.get()->getWritableTrieBuffer(), 0 /* rootPos */)) {
+ dictBuffers->getWritableTrieBuffer(), 0 /* rootPos */)) {
AKLOGE("Empty ver4 dictionary structure cannot be created on memory.");
return false;
}
- return dictBuffers.get()->flush(dirPath);
+ return dictBuffers->flush(dirPath);
}
/* static */ bool DictFileWritingUtils::flushAllHeaderAndBodyToFile(const char *const filePath,
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.cpp b/native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.cpp
index 35e05d77a..bac4d4eba 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/forgetting_curve_utils.cpp
@@ -16,6 +16,7 @@
#include "suggest/policyimpl/dictionary/utils/forgetting_curve_utils.h"
+#include <algorithm>
#include <cmath>
#include <stdlib.h>
@@ -72,7 +73,7 @@ const ForgettingCurveUtils::ProbabilityTable ForgettingCurveUtils::sProbabilityT
headerPolicy->getForgettingCurveDurationToLevelDown());
return sProbabilityTable.getProbability(
headerPolicy->getForgettingCurveProbabilityValuesTableId(), historicalInfo->getLevel(),
- min(max(elapsedTimeStepCount, 0), MAX_ELAPSED_TIME_STEP_COUNT));
+ std::min(std::max(elapsedTimeStepCount, 0), MAX_ELAPSED_TIME_STEP_COUNT));
}
/* static */ int ForgettingCurveUtils::getProbability(const int unigramProbability,
@@ -80,11 +81,11 @@ const ForgettingCurveUtils::ProbabilityTable ForgettingCurveUtils::sProbabilityT
if (unigramProbability == NOT_A_PROBABILITY) {
return NOT_A_PROBABILITY;
} else if (bigramProbability == NOT_A_PROBABILITY) {
- return min(backoff(unigramProbability), MAX_PROBABILITY);
+ return std::min(backoff(unigramProbability), MAX_PROBABILITY);
} else {
// TODO: Investigate better way to handle bigram probability.
- return min(max(unigramProbability, bigramProbability + MULTIPLIER_TWO_IN_PROBABILITY_SCALE),
- MAX_PROBABILITY);
+ return std::min(std::max(unigramProbability,
+ bigramProbability + MULTIPLIER_TWO_IN_PROBABILITY_SCALE), MAX_PROBABILITY);
}
}
@@ -183,7 +184,7 @@ ForgettingCurveUtils::ProbabilityTable::ProbabilityTable() : mTables() {
-1.0f * static_cast<float>(timeStepCount)
/ static_cast<float>(MAX_ELAPSED_TIME_STEP_COUNT + 1));
mTables[tableId][level][timeStepCount] =
- min(max(static_cast<int>(probability), 1), MAX_PROBABILITY);
+ std::min(std::max(static_cast<int>(probability), 1), MAX_PROBABILITY);
}
}
}
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/mmapped_buffer.cpp b/native/jni/src/suggest/policyimpl/dictionary/utils/mmapped_buffer.cpp
index e88d6e0a9..d3e0c237f 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/mmapped_buffer.cpp
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/mmapped_buffer.cpp
@@ -33,7 +33,7 @@ namespace latinime {
const int mmapFd = open(path, O_RDONLY);
if (mmapFd < 0) {
AKLOGE("DICT: Can't open the source. path=%s errno=%d", path, errno);
- return MmappedBufferPtr(0);
+ return MmappedBufferPtr(nullptr);
}
const int pagesize = sysconf(_SC_PAGESIZE);
const int offset = bufferOffset % pagesize;
@@ -45,13 +45,13 @@ namespace latinime {
if (mmappedBuffer == MAP_FAILED) {
AKLOGE("DICT: Can't mmap dictionary. errno=%d", errno);
close(mmapFd);
- return MmappedBufferPtr(0);
+ return MmappedBufferPtr(nullptr);
}
uint8_t *const buffer = static_cast<uint8_t *>(mmappedBuffer) + offset;
if (!buffer) {
AKLOGE("DICT: buffer is null");
close(mmapFd);
- return MmappedBufferPtr(0);
+ return MmappedBufferPtr(nullptr);
}
return MmappedBufferPtr(new MmappedBuffer(buffer, bufferSize, mmappedBuffer, alignedSize,
mmapFd, isUpdatable));
@@ -61,7 +61,7 @@ namespace latinime {
const char *const path, const bool isUpdatable) {
const int fileSize = FileUtils::getFileSize(path);
if (fileSize == -1) {
- return MmappedBufferPtr(0);
+ return MmappedBufferPtr(nullptr);
} else if (fileSize == 0) {
return MmappedBufferPtr(new MmappedBuffer(isUpdatable));
} else {
@@ -76,7 +76,7 @@ namespace latinime {
const int filePathLength = snprintf(filePath, filePathBufferSize, "%s%s", dirPath,
fileName);
if (filePathLength >= filePathBufferSize) {
- return 0;
+ return MmappedBufferPtr(nullptr);
}
return openBuffer(filePath, isUpdatable);
}
diff --git a/native/jni/src/suggest/policyimpl/dictionary/utils/mmapped_buffer.h b/native/jni/src/suggest/policyimpl/dictionary/utils/mmapped_buffer.h
index 73a733b0c..f73716c8e 100644
--- a/native/jni/src/suggest/policyimpl/dictionary/utils/mmapped_buffer.h
+++ b/native/jni/src/suggest/policyimpl/dictionary/utils/mmapped_buffer.h
@@ -17,16 +17,16 @@
#ifndef LATINIME_MMAPPED_BUFFER_H
#define LATINIME_MMAPPED_BUFFER_H
+#include <memory>
#include <stdint.h>
#include "defines.h"
-#include "utils/exclusive_ownership_pointer.h"
namespace latinime {
class MmappedBuffer {
public:
- typedef ExclusiveOwnershipPointer<MmappedBuffer> MmappedBufferPtr;
+ typedef std::unique_ptr<const MmappedBuffer> MmappedBufferPtr;
static MmappedBufferPtr openBuffer(const char *const path,
const int bufferOffset, const int bufferSize, const bool isUpdatable);
@@ -60,8 +60,8 @@ class MmappedBuffer {
// Empty file. We have to handle an empty file as a valid part of a dictionary.
AK_FORCE_INLINE MmappedBuffer(const bool isUpdatable)
- : mBuffer(0), mBufferSize(0), mMmappedBuffer(0), mAlignedSize(0), mMmapFd(0),
- mIsUpdatable(isUpdatable) {}
+ : mBuffer(nullptr), mBufferSize(0), mMmappedBuffer(nullptr), mAlignedSize(0),
+ mMmapFd(0), mIsUpdatable(isUpdatable) {}
DISALLOW_IMPLICIT_CONSTRUCTORS(MmappedBuffer);
diff --git a/native/jni/src/suggest/policyimpl/utils/edit_distance.h b/native/jni/src/suggest/policyimpl/utils/edit_distance.h
index 0871c37ce..4cfd0b3f3 100644
--- a/native/jni/src/suggest/policyimpl/utils/edit_distance.h
+++ b/native/jni/src/suggest/policyimpl/utils/edit_distance.h
@@ -17,6 +17,8 @@
#ifndef LATINIME_EDIT_DISTANCE_H
#define LATINIME_EDIT_DISTANCE_H
+#include <algorithm>
+
#include "defines.h"
#include "suggest/policyimpl/utils/edit_distance_policy.h"
@@ -38,13 +40,13 @@ class EditDistance {
for (int i = 0; i < beforeLength; ++i) {
for (int j = 0; j < afterLength; ++j) {
- dp[(afterLength + 1) * (i + 1) + (j + 1)] = min(
+ dp[(afterLength + 1) * (i + 1) + (j + 1)] = std::min(
dp[(afterLength + 1) * i + (j + 1)] + policy->getInsertionCost(i, j),
- min(dp[(afterLength + 1) * (i + 1) + j] + policy->getDeletionCost(i, j),
- dp[(afterLength + 1) * i + j]
- + policy->getSubstitutionCost(i, j)));
+ std::min(
+ dp[(afterLength + 1) * (i + 1) + j] + policy->getDeletionCost(i, j),
+ dp[(afterLength + 1) * i + j] + policy->getSubstitutionCost(i, j)));
if (policy->allowTransposition(i, j)) {
- dp[(afterLength + 1) * (i + 1) + (j + 1)] = min(
+ dp[(afterLength + 1) * (i + 1) + (j + 1)] = std::min(
dp[(afterLength + 1) * (i + 1) + (j + 1)],
dp[(afterLength + 1) * (i - 1) + (j - 1)]
+ policy->getTranspositionCost(i, j));
diff --git a/native/jni/src/utils/autocorrection_threshold_utils.cpp b/native/jni/src/utils/autocorrection_threshold_utils.cpp
index 1f8ee0814..349786a27 100644
--- a/native/jni/src/utils/autocorrection_threshold_utils.cpp
+++ b/native/jni/src/utils/autocorrection_threshold_utils.cpp
@@ -16,6 +16,7 @@
#include "utils/autocorrection_threshold_utils.h"
+#include <algorithm>
#include <cmath>
#include "defines.h"
@@ -99,7 +100,7 @@ const int AutocorrectionThresholdUtils::FULL_WORD_MULTIPLIER = 2;
const float maxScore = score >= S_INT_MAX ? static_cast<float>(S_INT_MAX)
: static_cast<float>(MAX_INITIAL_SCORE)
* powf(static_cast<float>(TYPED_LETTER_MULTIPLIER),
- static_cast<float>(min(beforeLength, afterLength - spaceCount)))
+ static_cast<float>(std::min(beforeLength, afterLength - spaceCount)))
* static_cast<float>(FULL_WORD_MULTIPLIER);
return (static_cast<float>(score) / maxScore) * weight;
diff --git a/native/jni/src/utils/exclusive_ownership_pointer.h b/native/jni/src/utils/exclusive_ownership_pointer.h
deleted file mode 100644
index 081802e8b..000000000
--- a/native/jni/src/utils/exclusive_ownership_pointer.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2013, 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.
- */
-
-#ifndef LATINIME_EXCLUSIVE_OWNERSHIP_POINTER_H
-#define LATINIME_EXCLUSIVE_OWNERSHIP_POINTER_H
-
-#include "defines.h"
-
-namespace latinime {
-
-template<class T>
-class ExclusiveOwnershipPointer {
- public:
- // This instance become an owner of the raw pointer.
- AK_FORCE_INLINE ExclusiveOwnershipPointer(T *const rawPointer)
- : mPointer(rawPointer),
- mSharedOwnerPtr(new (ExclusiveOwnershipPointer<T> *)(this)) {}
-
- // Move the ownership.
- AK_FORCE_INLINE ExclusiveOwnershipPointer(const ExclusiveOwnershipPointer<T> &pointer)
- : mPointer(pointer.mPointer), mSharedOwnerPtr(pointer.mSharedOwnerPtr) {
- transferOwnership(&pointer);
- }
-
- AK_FORCE_INLINE ~ExclusiveOwnershipPointer() {
- deletePointersIfHavingOwnership();
- }
-
- AK_FORCE_INLINE T *get() const {
- return mPointer;
- }
-
- private:
- // This class allows to copy and ensures only one instance has the ownership of the
- // managed pointer.
- DISALLOW_DEFAULT_CONSTRUCTOR(ExclusiveOwnershipPointer);
- DISALLOW_ASSIGNMENT_OPERATOR(ExclusiveOwnershipPointer);
-
- void transferOwnership(const ExclusiveOwnershipPointer<T> *const src) {
- if (*mSharedOwnerPtr != src) {
- AKLOGE("Failed to transfer the ownership because src is not the current owner."
- "src: %p, owner: %p", src, *mSharedOwnerPtr);
- ASSERT(false);
- return;
- }
- // Transfer the ownership from src to this instance.
- *mSharedOwnerPtr = this;
- }
-
- void deletePointersIfHavingOwnership() {
- if (mSharedOwnerPtr && *mSharedOwnerPtr == this) {
- if (mPointer) {
- if (DEBUG_DICT) {
- AKLOGI("Releasing pointer: %p", mPointer);
- }
- delete mPointer;
- }
- delete mSharedOwnerPtr;
- }
- }
-
- T *mPointer;
- // mSharedOwnerPtr points a shared memory space where the instance which has the ownership is
- // stored.
- ExclusiveOwnershipPointer<T> **mSharedOwnerPtr;
-};
-} // namespace latinime
-#endif /* LATINIME_EXCLUSIVE_OWNERSHIP_POINTER_H */
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/AlphabetShifted.java b/tests/src/com/android/inputmethod/keyboard/layout/AlphabetShifted.java
new file mode 100644
index 000000000..be3ed12de
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/AlphabetShifted.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014 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.layout;
+
+import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+import com.android.inputmethod.keyboard.layout.expected.LayoutBase;
+import com.android.inputmethod.latin.Constants;
+
+import java.util.Locale;
+
+/**
+ * The generic upper case alphabet keyboard layout.
+ */
+public final class AlphabetShifted extends LayoutBase {
+ public static ExpectedKey[][] getAlphabet(final ExpectedKey[][] lowerCaseKeyboard,
+ final Locale locale) {
+ final ExpectedKey[][] upperCaseKeyboard = ExpectedKeyboardBuilder.toUpperCase(
+ lowerCaseKeyboard, locale);
+ return new ExpectedKeyboardBuilder(upperCaseKeyboard)
+ .replaceKeyOfAll(SHIFT_KEY, SHIFTED_SHIFT_KEY)
+ .build();
+ }
+
+ // Icon id.
+ private static final int ICON_SHIFTED_SHIFT = KeyboardIconsSet.getIconId("shift_key_shifted");
+
+ // Functional key.
+ private static final ExpectedKey SHIFTED_SHIFT_KEY = key(
+ ICON_SHIFTED_SHIFT, Constants.CODE_SHIFT, CAPSLOCK_MORE_KEY);
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Qwerty.java b/tests/src/com/android/inputmethod/keyboard/layout/Qwerty.java
new file mode 100644
index 000000000..f7179b739
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Qwerty.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014 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.layout;
+
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+import com.android.inputmethod.keyboard.layout.expected.LayoutBase;
+
+/**
+ * The QWERTY alphabet keyboard.
+ */
+public final class Qwerty extends LayoutBase {
+ public static ExpectedKey[][] getAlphabet(final boolean isPhone) {
+ return toCommonAlphabet(ALPHABET_COMMON, isPhone);
+ }
+
+ private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder(10, 9, 7, 3)
+ .setLabelsOfRow(1, "q", "w", "e", "r", "t", "y", "u", "i", "o", "p")
+ .setMoreKeysOf("q", "1")
+ .setMoreKeysOf("w", "2")
+ .setMoreKeysOf("e", "3")
+ .setMoreKeysOf("r", "4")
+ .setMoreKeysOf("t", "5")
+ .setMoreKeysOf("y", "6")
+ .setMoreKeysOf("u", "7")
+ .setMoreKeysOf("i", "8")
+ .setMoreKeysOf("o", "9")
+ .setMoreKeysOf("p", "0")
+ .setLabelsOfRow(2, "a", "s", "d", "f", "g", "h", "j", "k", "l")
+ .setLabelsOfRow(3, "z", "x", "c", "v", "b", "n", "m")
+ .build();
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Symbols.java b/tests/src/com/android/inputmethod/keyboard/layout/Symbols.java
new file mode 100644
index 000000000..03d7f07e9
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/Symbols.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2014 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.layout;
+
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+import com.android.inputmethod.keyboard.layout.expected.LayoutBase;
+import com.android.inputmethod.latin.Constants;
+
+/**
+ * The symbols keyboard layout.
+ */
+public final class Symbols extends LayoutBase {
+ public static ExpectedKey[][] getSymbols(final boolean isPhone) {
+ return isPhone ? toPhoneSymbol(SYMBOLS_COMMON) : toTabletSymbols(SYMBOLS_COMMON);
+ }
+
+ // Functional keys.
+ public static final ExpectedKey ALPHABET_KEY = key("ABC", Constants.CODE_SWITCH_ALPHA_SYMBOL);
+ public static final ExpectedKey SYMBOLS_SHIFT_KEY = key("= \\ <", Constants.CODE_SHIFT);
+ public static final ExpectedKey TABLET_SYMBOLS_SHIFT_KEY = key("~ [ <", Constants.CODE_SHIFT);
+
+ // Common symbols keyboard layout.
+ public static final ExpectedKey[][] SYMBOLS_COMMON = new ExpectedKeyboardBuilder(10, 9, 7, 5)
+ .setLabelsOfRow(1, "1", "2", "3", "4", "5", "6", "7", "8", "9", "0")
+ // U+00B9: "¹" SUPERSCRIPT ONE
+ // U+00BD: "½" VULGAR FRACTION ONE HALF
+ // U+2153: "⅓" VULGAR FRACTION ONE THIRD
+ // U+00BC: "¼" VULGAR FRACTION ONE QUARTER
+ // U+215B: "⅛" VULGAR FRACTION ONE EIGHTH
+ .setMoreKeysOf("1", "\u00B9", "\u00BD", "\u2153", "\u00BC", "\u215B")
+ // U+00B2: "²" SUPERSCRIPT TWO
+ // U+2154: "⅔" VULGAR FRACTION TWO THIRDS
+ .setMoreKeysOf("2", "\u00B2", "\u2154")
+ // U+00B3: "³" SUPERSCRIPT THREE
+ // U+00BE: "¾" VULGAR FRACTION THREE QUARTERS
+ // U+215C: "⅜" VULGAR FRACTION THREE EIGHTHS
+ .setMoreKeysOf("3", "\u00B3", "\u00BE", "\u215C")
+ // U+2074: "⁴" SUPERSCRIPT FOUR
+ .setMoreKeysOf("4", "\u2074")
+ // U+215D: "⅝" VULGAR FRACTION FIVE EIGHTHS
+ .setMoreKeysOf("5", "\u215D")
+ // U+215E: "⅞" VULGAR FRACTION SEVEN EIGHTHS
+ .setMoreKeysOf("7", "\u215E")
+ // U+207F: "ⁿ" SUPERSCRIPT LATIN SMALL LETTER N
+ // U+2205: "∅" EMPTY SET
+ .setMoreKeysOf("0", "\u207F", "\u2205")
+ .setLabelsOfRow(2, "@", "#", "$", "%", "&", "-", "+", "(", ")")
+ // U+00A2: "¢" CENT SIGN
+ // U+00A3: "£" POUND SIGN
+ // U+20AC: "€" EURO SIGN
+ // U+00A5: "¥" YEN SIGN
+ // U+20B1: "₱" PESO SIGN
+ .setMoreKeysOf("$", "\u00A2", "\u00A3", "\u20AC", "\u00A5", "\u20B1")
+ // U+2030: "‰" PER MILLE SIGN
+ .setMoreKeysOf("%", "\u2030")
+ // U+2013: "–" EN DASH
+ // U+2014: "—" EM DASH
+ // U+00B7: "·" MIDDLE DOT
+ .setMoreKeysOf("-", "_", "\u2013", "\u2014", "\u00B7")
+ // U+00B1: "±" PLUS-MINUS SIGN
+ .setMoreKeysOf("+", "\u00B1")
+ .setMoreKeysOf("(", "<", "{", "[")
+ .setMoreKeysOf(")", ">", "}", "]")
+ .setLabelsOfRow(3, "*", "\"", "'", ":", ";", "!", "?")
+ // U+2020: "†" DAGGER
+ // U+2021: "‡" DOUBLE DAGGER
+ // U+2605: "★" BLACK STAR
+ .setMoreKeysOf("*", "\u2020", "\u2021", "\u2605")
+ // U+201E: "„" DOUBLE LOW-9 QUOTATION MARK
+ // U+201C: "“" LEFT DOUBLE QUOTATION MARK
+ // U+201D: "”" RIGHT DOUBLE QUOTATION MARK
+ // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+ // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+ .setMoreKeysOf("\"", "\u201E", "\u201C", "\u201D", "\u00AB", "\u00BB")
+ // U+201A: "‚" SINGLE LOW-9 QUOTATION MARK
+ // U+2018: "‘" LEFT SINGLE QUOTATION MARK
+ // U+2019: "’" RIGHT SINGLE QUOTATION MARK
+ // U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+ // U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+ .setMoreKeysOf("'", "\u201A", "\u2018", "\u2019", "\u2039", "\u203A")
+ // U+00A1: "¡" INVERTED EXCLAMATION MARK
+ .setMoreKeysOf("!", "\u00A1")
+ // U+00BF: "¿" INVERTED QUESTION MARK
+ .setMoreKeysOf("?", "\u00BF")
+ .setLabelsOfRow(4, "_", "/", " ", ",", ".")
+ // U+2026: "…" HORIZONTAL ELLIPSIS
+ .setMoreKeysOf(".", "\u2026")
+ .build();
+
+ private static ExpectedKey[][] toPhoneSymbol(final ExpectedKey[][] common) {
+ return new ExpectedKeyboardBuilder(common)
+ .addKeysOnTheLeftOfRow(3, Symbols.SYMBOLS_SHIFT_KEY)
+ .addKeysOnTheRightOfRow(3, DELETE_KEY)
+ .addKeysOnTheLeftOfRow(4, Symbols.ALPHABET_KEY)
+ .addKeysOnTheRightOfRow(4, key(ENTER_KEY, EMOJI_KEY))
+ .build();
+ }
+
+ private static ExpectedKey[][] toTabletSymbols(final ExpectedKey[][] common) {
+ return new ExpectedKeyboardBuilder(common)
+ .addKeysOnTheLeftOfRow(3,
+ key("\\"), key("="))
+ .addKeysOnTheRightOfRow(1, DELETE_KEY)
+ .addKeysOnTheRightOfRow(2, ENTER_KEY)
+ .addKeysOnTheLeftOfRow(3, Symbols.TABLET_SYMBOLS_SHIFT_KEY)
+ .addKeysOnTheRightOfRow(3, Symbols.TABLET_SYMBOLS_SHIFT_KEY)
+ .addKeysOnTheLeftOfRow(4, Symbols.ALPHABET_KEY)
+ .addKeysOnTheRightOfRow(4, EMOJI_KEY)
+ .build();
+ }
+
+ // Helper method to add currency symbols for Euro.
+ public static ExpectedKeyboardBuilder euro(final ExpectedKeyboardBuilder builder) {
+ return builder
+ // U+20AC: "€" EURO SIGN
+ // U+00A2: "¢" CENT SIGN
+ // U+00A3: "£" POUND SIGN
+ // U+00A5: "¥" YEN SIGN
+ // U+20B1: "₱" PESO SIGN
+ .replaceKeyOfLabel("$", key("\u20AC",
+ moreKey("\u00A2"), moreKey("\u00A3"), moreKey("$"),
+ moreKey("\u00A5"), moreKey("\u20B1")));
+ }
+
+ // Helper method to add single quotes "more keys".
+ // "9LLR" means "9-low/Left quotation marks, Left/Right-pointing angle quotation marks".
+ public static ExpectedKeyboardBuilder singleQuotes9LLR(final ExpectedKeyboardBuilder builder) {
+ return builder
+ // U+2019: "’" RIGHT SINGLE QUOTATION MARK
+ // U+201A: "‚" SINGLE LOW-9 QUOTATION MARK
+ // U+2018: "‘" LEFT SINGLE QUOTATION MARK
+ // U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+ // U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+ .setMoreKeysOf("'", "\u2019", "\u201A", "\u2018", "\u2039", "\u203A");
+ }
+
+ // Helper method to add single quotes "more keys".
+ // "9LLR" means "9-low/Left quotation marks, Right/Left-pointing angle quotation marks".
+ public static ExpectedKeyboardBuilder singleQuotes9LRL(final ExpectedKeyboardBuilder builder) {
+ return builder
+ // U+2019: "’" RIGHT SINGLE QUOTATION MARK
+ // U+201A: "‚" SINGLE LOW-9 QUOTATION MARK
+ // U+2018: "‘" LEFT SINGLE QUOTATION MARK
+ // U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+ // U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+ .setMoreKeysOf("'", "\u2019", "\u201A", "\u2018", "\u203A", "\u2039");
+ }
+
+ // Helper method to add double quotes "more keys".
+ // "9LLR" means "9-low/Left quotation marks, Left/Right-pointing angle quotation marks".
+ public static ExpectedKeyboardBuilder doubleQuotes9LLR(final ExpectedKeyboardBuilder builder) {
+ return builder
+ // U+201D: "”" RIGHT DOUBLE QUOTATION MARK
+ // U+201E: "„" DOUBLE LOW-9 QUOTATION MARK
+ // U+201C: "“" LEFT DOUBLE QUOTATION MARK
+ // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+ // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+ .setMoreKeysOf("\"", "\u201D", "\u201E", "\u201C", "\u00AB", "\u00BB");
+ }
+
+ // Helper method to add double quotes "more keys".
+ // "9LLR" means "9-low/Left quotation marks, Right/Left-pointing angle quotation marks".
+ public static ExpectedKeyboardBuilder doubleQuotes9LRL(final ExpectedKeyboardBuilder builder) {
+ return builder
+ // U+201D: "”" RIGHT DOUBLE QUOTATION MARK
+ // U+201E: "„" DOUBLE LOW-9 QUOTATION MARK
+ // U+201C: "“" LEFT DOUBLE QUOTATION MARK
+ // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+ // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+ .setMoreKeysOf("\"", "\u201D", "\u201E", "\u201C", "\u00BB", "\u00AB");
+ }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/SymbolsShifted.java b/tests/src/com/android/inputmethod/keyboard/layout/SymbolsShifted.java
new file mode 100644
index 000000000..368f9db46
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/SymbolsShifted.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2014 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.layout;
+
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+import com.android.inputmethod.keyboard.layout.expected.LayoutBase;
+import com.android.inputmethod.latin.Constants;
+
+/**
+ * The symbols shifted keyboard layout.
+ */
+public final class SymbolsShifted extends LayoutBase {
+ public static ExpectedKey[][] getSymbolsShifted(final boolean isPhone) {
+ return isPhone ? toPhoneSymbolsShifted(SYMBOLS_SHIFTED_COMMON)
+ : toTabletSymbolsShifted(SYMBOLS_SHIFTED_COMMON);
+ }
+
+ // Functional key.
+ public static final ExpectedKey BACK_TO_SYMBOLS_KEY = key("?123", Constants.CODE_SHIFT);
+
+ // Common symbols shifted keyboard layout.
+ public static final ExpectedKey[][] SYMBOLS_SHIFTED_COMMON =
+ new ExpectedKeyboardBuilder(10, 9, 7, 5)
+ // U+0060: "`" GRAVE ACCENT
+ // U+2022: "•" BULLET
+ // U+221A: "√" SQUARE ROOT
+ // U+03C0: "π" GREEK SMALL LETTER PI
+ // U+00F7: "÷" DIVISION SIGN
+ // U+00D7: "×" MULTIPLICATION SIGN
+ // U+00B6: "¶" PILCROW SIGN
+ // U+2206: "∆" INCREMENT
+ .setLabelsOfRow(1,
+ "~", "\u0060", "|", "\u2022", "\u221A",
+ "\u03C0", "\u00F7", "\u00D7", "\u00B6", "\u2206")
+ // U+2022: "•" BULLET
+ // U+266A: "♪" EIGHTH NOTE
+ // U+2665: "♥" BLACK HEART SUIT
+ // U+2660: "♠" BLACK SPADE SUIT
+ // U+2666: "♦" BLACK DIAMOND SUIT
+ // U+2663: "♣" BLACK CLUB SUIT
+ .setMoreKeysOf("\u2022", "\u266A", "\u2665", "\u2660", "\u2666", "\u2663")
+ // U+03C0: "π" GREEK SMALL LETTER PI
+ // U+03A0: "Π" GREEK CAPITAL LETTER PI
+ .setMoreKeysOf("\u03C0", "\u03A0")
+ // U+00B6: "¶" PILCROW SIGN
+ // U+00A7: "§" SECTION SIGN
+ .setMoreKeysOf("\u00B6", "\u00A7")
+ // U+00A3: "£" POUND SIGN
+ // U+00A2: "¢" CENT SIGN
+ // U+20AC: "€" EURO SIGN
+ // U+00A5: "¥" YEN SIGN
+ // U+00B0: "°" DEGREE SIGN
+ .setLabelsOfRow(2,
+ "\u00A3", "\u00A2", "\u20AC", "\u00A5", "^",
+ "\u00B0", "=", "{", "}")
+ // U+2191: "↑" UPWARDS ARROW
+ // U+2193: "↓" DOWNWARDS ARROW
+ // U+2190: "←" LEFTWARDS ARROW
+ // U+2192: "→" RIGHTWARDS ARROW
+ .setMoreKeysOf("^", "\u2191", "\u2193", "\u2190", "\u2192")
+ // U+00B0: "°" DEGREE SIGN
+ // U+2032: "′" PRIME
+ // U+2033: "″" DOUBLE PRIME
+ .setMoreKeysOf("\u00B0", "\u2032", "\u2033")
+ // U+2260: "≠" NOT EQUAL TO
+ // U+2248: "≈" ALMOST EQUAL TO
+ // U+221E: "∞" INFINITY
+ .setMoreKeysOf("=", "\u2260", "\u2248", "\u221E")
+ // U+00A9: "©" COPYRIGHT SIGN
+ // U+00AE: "®" REGISTERED SIGN
+ // U+2122: "™" TRADE MARK SIGN
+ // U+2105: "℅" CARE OF
+ .setLabelsOfRow(3,
+ "\\", "\u00A9", "\u00AE", "\u2122", "\u2105",
+ "[", "]")
+ .setLabelsOfRow(4,
+ "<", ">", " ", ",", ".")
+ // U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+ // U+2264: "≤" LESS-THAN OR EQUAL TO
+ // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+ .setMoreKeysOf("<", "\u2039", "\u2264", "\u00AB")
+ // U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+ // U+2265: "≥" GREATER-THAN EQUAL TO
+ // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+ .setMoreKeysOf(">", "\u203A", "\u2265", "\u00BB")
+ // U+2026: "…" HORIZONTAL ELLIPSIS
+ .setMoreKeysOf(".", "\u2026")
+ .build();
+
+ private static ExpectedKey[][] toPhoneSymbolsShifted(final ExpectedKey[][] common) {
+ return new ExpectedKeyboardBuilder(common)
+ .addKeysOnTheLeftOfRow(3, BACK_TO_SYMBOLS_KEY)
+ .addKeysOnTheRightOfRow(3, DELETE_KEY)
+ .addKeysOnTheLeftOfRow(4, Symbols.ALPHABET_KEY)
+ .addKeysOnTheRightOfRow(4, key(ENTER_KEY, EMOJI_KEY))
+ .build();
+ }
+
+ private static ExpectedKey[][] toTabletSymbolsShifted(final ExpectedKey[][] common) {
+ return new ExpectedKeyboardBuilder(common)
+ // U+00BF: "¿" INVERTED QUESTION MARK
+ // U+00A1: "¡" INVERTED EXCLAMATION MARK
+ .addKeysOnTheRightOfRow(3,
+ key("\u00A1"), key("\u00BF"))
+ .addKeysOnTheRightOfRow(1, DELETE_KEY)
+ .addKeysOnTheRightOfRow(2, ENTER_KEY)
+ .addKeysOnTheLeftOfRow(3, BACK_TO_SYMBOLS_KEY)
+ .addKeysOnTheRightOfRow(3, BACK_TO_SYMBOLS_KEY)
+ .addKeysOnTheLeftOfRow(4, Symbols.ALPHABET_KEY)
+ .addKeysOnTheRightOfRow(4, EMOJI_KEY)
+ .build();
+ }
+
+ // Helper method to add currency symbols for Euro.
+ public static ExpectedKeyboardBuilder euro(final ExpectedKeyboardBuilder builder) {
+ return builder
+ // U+00A5: "¥" YEN SIGN
+ // U+00A2: "¢" CENT SIGN
+ .replaceKeyOfLabel("\u00A5", key("\u00A2"))
+ // U+20AC: "€" EURO SIGN
+ // U+00A2: "¢" CENT SIGN
+ .replaceKeyOfLabel("\u20AC", key("$", moreKey("\u00A2")))
+ // U+00A2: "¢" CENT SIGN
+ // U+00A5: "¥" YEN SIGN
+ .replaceKeyOfLabel("\u00A2", key("\u00A5"));
+ }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/expected/ActualKeyboardBuilder.java b/tests/src/com/android/inputmethod/keyboard/layout/expected/ActualKeyboardBuilder.java
new file mode 100644
index 000000000..577f43e17
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/expected/ActualKeyboardBuilder.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2014 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.layout.expected;
+
+import com.android.inputmethod.keyboard.Key;
+import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
+import com.android.inputmethod.keyboard.internal.MoreKeySpec;
+import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+/**
+ * This class builds an actual keyboard for unit test.
+ */
+public final class ActualKeyboardBuilder extends AbstractKeyboardBuilder<Key> {
+ // Comparator to sort {@link Key}s from top-left to bottom-right order.
+ private static final Comparator<Key> ROW_COLUMN_COMPARATOR = new Comparator<Key>() {
+ @Override
+ public int compare(final Key lhs, final Key rhs) {
+ if (lhs.getY() < rhs.getY()) return -1;
+ if (lhs.getY() > rhs.getY()) return 1;
+ if (lhs.getX() < rhs.getX()) return -1;
+ if (lhs.getX() > rhs.getX()) return 1;
+ return 0;
+ }
+ };
+
+ private static ArrayList<Key> filterOutSpacerAndSortKeys(final Key[] keys) {
+ final ArrayList<Key> filteredKeys = CollectionUtils.newArrayList();
+ for (final Key key : keys) {
+ if (key.isSpacer()) {
+ continue;
+ }
+ filteredKeys.add(key);
+ }
+ Collections.sort(filteredKeys, ROW_COLUMN_COMPARATOR);
+ return filteredKeys;
+ }
+
+ /**
+ * Create the keyboard that consists of the array of rows of the actual keyboard's keys.
+ * @param keys the array of keys of the actual keyboard.
+ * @return the actual keyboard grouped with rows.
+ */
+ public static Key[][] buildKeyboard(final Key[] keys) {
+ // Filter out spacer and sort keys from top-left to bottom-right order to prepare to
+ // create rows.
+ final ArrayList<Key> sortedKeys = filterOutSpacerAndSortKeys(keys);
+
+ // Grouping keys into rows.
+ final ArrayList<ArrayList<Key>> rows = CollectionUtils.newArrayList();
+ ArrayList<Key> elements = CollectionUtils.newArrayList();
+ int lastY = sortedKeys.get(0).getY();
+ for (final Key key : sortedKeys) {
+ if (lastY != key.getY()) {
+ // A new row is starting.
+ lastY = key.getY();
+ rows.add(elements);
+ elements = CollectionUtils.newArrayList();
+ }
+ elements.add(key);
+ }
+ rows.add(elements); // Add the last row.
+
+ // Calculate each dimension of rows and create a builder.
+ final int[] dimensions = new int[rows.size()];
+ for (int rowIndex = 0; rowIndex < dimensions.length; rowIndex++) {
+ dimensions[rowIndex] = rows.get(rowIndex).size();
+ }
+ final ActualKeyboardBuilder builder = new ActualKeyboardBuilder(dimensions);
+
+ for (int rowIndex = 0; rowIndex < rows.size(); rowIndex++) {
+ final int row = rowIndex + 1;
+ final ArrayList<Key> rowKeys = rows.get(rowIndex);
+ builder.setRowAt(row, rowKeys.toArray(new Key[rowKeys.size()]));
+ }
+ return builder.build();
+ }
+
+ private ActualKeyboardBuilder(final int ... dimensions) {
+ super(dimensions);
+ }
+
+ @Override
+ Key defaultElement() { return null; }
+
+ @Override
+ Key[] newArray(final int size) { return new Key[size]; }
+
+ @Override
+ Key[][] newArrayOfArray(final int size) { return new Key[size][]; }
+
+ // Helper class to create concise representation from the key specification.
+ static class MoreKeySpecStringizer extends StringUtils.Stringizer<MoreKeySpec> {
+ static final MoreKeySpecStringizer STRINGIZER = new MoreKeySpecStringizer();
+
+ @Override
+ public String stringize(final MoreKeySpec spec) {
+ return toString(spec.mLabel, spec.mIconId, spec.mOutputText, spec.mCode);
+ }
+
+ static String toString(final String label, final int iconId, final String outputText,
+ final int code) {
+ final String visual = (iconId != KeyboardIconsSet.ICON_UNDEFINED)
+ ? KeyboardIconsSet.getIconName(iconId) : label;
+ final String output;
+ if (code == Constants.CODE_OUTPUT_TEXT) {
+ output = outputText;
+ } else if (code < Constants.CODE_SPACE) {
+ output = Constants.printableCode(code);
+ } else {
+ output = StringUtils.newSingleCodePointString(code);
+ }
+ if (visual.equals(output)) {
+ return visual;
+ }
+ return visual + "|" + output;
+ }
+ }
+
+ // Helper class to create concise representation from the key.
+ static class KeyStringizer extends StringUtils.Stringizer<Key> {
+ static final KeyStringizer STRINGIZER = new KeyStringizer();
+
+ @Override
+ public String stringize(final Key key) {
+ if (key == null) {
+ return "NULL";
+ }
+ if (key.isSpacer()) {
+ return "SPACER";
+ }
+ final StringBuilder sb = new StringBuilder();
+ sb.append(MoreKeySpecStringizer.toString(
+ key.getLabel(), key.getIconId(), key.getOutputText(), key.getCode()));
+ final MoreKeySpec[] moreKeys = key.getMoreKeys();
+ if (moreKeys == null) {
+ return sb.toString();
+ }
+ sb.append("^");
+ sb.append(MoreKeySpecStringizer.STRINGIZER.join(moreKeys));
+ return sb.toString();
+ }
+ }
+
+ /**
+ * Convert the key to human readable string.
+ * @param key the key to be converted to string.
+ * @return the human readable representation of <code>key</code>.
+ */
+ public static String toString(final Key key) {
+ return KeyStringizer.STRINGIZER.stringize(key);
+ }
+
+ /**
+ * Convert the keyboard row to human readable string.
+ * @param keys the keyboard row to be converted to string.
+ * @return the human readable representation of <code>keys</code>.
+ */
+ public static String toString(final Key[] keys) {
+ return KeyStringizer.STRINGIZER.join(keys);
+ }
+
+ // Helper class to create concise representation from the array of the key.
+ static class KeyArrayStringizer extends StringUtils.Stringizer<Key[]> {
+ static final KeyArrayStringizer STRINGIZER = new KeyArrayStringizer();
+
+ @Override
+ public String stringize(final Key[] keyArray) {
+ return KeyStringizer.STRINGIZER.join(keyArray);
+ }
+ }
+
+ /**
+ * Convert the keyboard to human readable string.
+ * @param rows the keyboard to be converted to string.
+ * @return the human readable representation of <code>rows</code>.
+ */
+ public static String toString(final Key[][] rows) {
+ return KeyArrayStringizer.STRINGIZER.join(rows, "\n" /* delimiter */);
+ }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/expected/LayoutBase.java b/tests/src/com/android/inputmethod/keyboard/layout/expected/LayoutBase.java
new file mode 100644
index 000000000..1aeb8c0cd
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/expected/LayoutBase.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2014 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.layout.expected;
+
+import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
+import com.android.inputmethod.latin.Constants;
+
+/**
+ * Base class to create an expected keyboard for unit test.
+ */
+public class LayoutBase {
+ // Those helper methods have a lower case name to be readable when defining expected keyboard
+ // layouts.
+
+ // Helper method to create {@link ExpectedKey} object that has the label.
+ public static ExpectedKey key(final String label, final ExpectedKey ... moreKeys) {
+ return ExpectedKey.newInstance(label, moreKeys);
+ }
+
+ // Helper method to create {@link ExpectedKey} object that has the label and the output text.
+ public static ExpectedKey key(final String label, final String outputText,
+ final ExpectedKey ... moreKeys) {
+ return ExpectedKey.newInstance(label, outputText, moreKeys);
+ }
+
+ // Helper method to create {@link ExpectedKey} object that has the label and the output code.
+ public static ExpectedKey key(final String label, final int code,
+ final ExpectedKey ... moreKeys) {
+ return ExpectedKey.newInstance(label, code, moreKeys);
+ }
+
+ // Helper method to create {@link ExpectedKey} object that has the icon and the output code.
+ public static ExpectedKey key(final int iconId, final int code,
+ final ExpectedKey ... moreKeys) {
+ return ExpectedKey.newInstance(iconId, code, moreKeys);
+ }
+
+ // Helper method to create {@link ExpectedKey} object that has new "more keys".
+ public static ExpectedKey key(final ExpectedKey key, final ExpectedKey ... moreKeys) {
+ return ExpectedKey.newInstance(key.getVisual(), key.getOutput(), moreKeys);
+ }
+
+ // Helper method to create {@link ExpectedKey} object for "more key" that has the label.
+ public static ExpectedKey moreKey(final String label) {
+ return ExpectedKey.newInstance(label);
+ }
+
+ // Helper method to create {@link ExpectedKey} object for "more key" that has the label and the
+ // output text.
+ public static ExpectedKey moreKey(final String label, final String outputText) {
+ return ExpectedKey.newInstance(label, outputText);
+ }
+
+ // Helper method to create {@link ExpectedKey} object for "more key" that has the label and the
+ // output code.
+ public static ExpectedKey moreKey(final String label, final int code) {
+ return ExpectedKey.newInstance(label, code);
+ }
+
+ // Icon ids.
+ private static final int ICON_SHIFT = KeyboardIconsSet.getIconId("shift_key");
+ private static final int ICON_DELETE = KeyboardIconsSet.getIconId("delete_key");
+ private static final int ICON_SETTINGS = KeyboardIconsSet.getIconId("settings_key");
+ private static final int ICON_ENTER = KeyboardIconsSet.getIconId("enter_key");
+ private static final int ICON_EMOJI = KeyboardIconsSet.getIconId("emoji_key");
+
+ // Functional keys.
+ public static final ExpectedKey CAPSLOCK_MORE_KEY = key(" ", Constants.CODE_CAPSLOCK);
+ public static final ExpectedKey SHIFT_KEY = key(ICON_SHIFT, Constants.CODE_SHIFT);
+ public static final ExpectedKey DELETE_KEY = key(ICON_DELETE, Constants.CODE_DELETE);
+ public static final ExpectedKey SYMBOLS_KEY = key("?123", Constants.CODE_SWITCH_ALPHA_SYMBOL);
+ public static final ExpectedKey SETTINGS_KEY = key(ICON_SETTINGS, Constants.CODE_SETTINGS);
+ public static final ExpectedKey ENTER_KEY = key(ICON_ENTER, Constants.CODE_ENTER);
+ public static final ExpectedKey EMOJI_KEY = key(ICON_EMOJI, Constants.CODE_EMOJI);
+
+ // Punctuation more keys for phone form factor.
+ public static final String[] PHONE_PUNCTUATION_MORE_KEYS = {
+ ";", "/", "(", ")", "#", "!", ",", "?",
+ "&", "%", "+", "\"", "-", ":", "'", "@"
+ };
+
+ // Punctuation more keys for tablet form factor.
+ public static final String[] TABLET_PUNCTUATION_MORE_KEYS = {
+ ";", "/", "(", ")", "#", "'", ",",
+ "&", "%", "+", "\"", "-", ":", "@"
+ };
+
+ private static ExpectedKeyboardBuilder toPhoneAlphabet(final ExpectedKeyboardBuilder builder) {
+ return builder
+ .addKeysOnTheLeftOfRow(3, key(SHIFT_KEY, CAPSLOCK_MORE_KEY))
+ .addKeysOnTheRightOfRow(3, DELETE_KEY)
+ .setLabelsOfRow(4, ",", " ", ".")
+ .setMoreKeysOf(",", SETTINGS_KEY)
+ .setMoreKeysOf(".", PHONE_PUNCTUATION_MORE_KEYS)
+ .addKeysOnTheLeftOfRow(4, SYMBOLS_KEY)
+ .addKeysOnTheRightOfRow(4, key(ENTER_KEY, EMOJI_KEY));
+ }
+
+ // Helper method to create alphabet layout for tablet by adding special function keys except
+ // shift key.
+ public static ExpectedKeyboardBuilder toTabletAlphabetWithoutShiftKeys(
+ final ExpectedKeyboardBuilder builder) {
+ return builder
+ // U+00BF: "¿" INVERTED QUESTION MARK
+ // U+00A1: "¡" INVERTED EXCLAMATION MARK
+ .addKeysOnTheRightOfRow(3,
+ key("!", moreKey("\u00A1")), key("?", moreKey("\u00BF")))
+ .addKeysOnTheRightOfRow(1, DELETE_KEY)
+ .addKeysOnTheRightOfRow(2, ENTER_KEY)
+ .setLabelsOfRow(4, "/", " ", ",", ".")
+ .setMoreKeysOf(".", TABLET_PUNCTUATION_MORE_KEYS)
+ .addKeysOnTheLeftOfRow(4, SYMBOLS_KEY, SETTINGS_KEY)
+ .addKeysOnTheRightOfRow(4, EMOJI_KEY);
+ }
+
+ // Helper method to create alphabet layout by adding special function keys.
+ public static ExpectedKey[][] toCommonAlphabet(final ExpectedKey[][] common,
+ final boolean isPhone) {
+ final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(common);
+ if (isPhone) {
+ toPhoneAlphabet(builder);
+ } else {
+ toTabletAlphabetWithoutShiftKeys(builder);
+ builder.addKeysOnTheLeftOfRow(3, key(SHIFT_KEY, CAPSLOCK_MORE_KEY))
+ .addKeysOnTheRightOfRow(3, key(SHIFT_KEY, CAPSLOCK_MORE_KEY));
+ }
+ return builder.build();
+ }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/LayoutTestsBase.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/LayoutTestsBase.java
new file mode 100644
index 000000000..427e7de49
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/LayoutTestsBase.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2014 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.layout.tests;
+
+import android.util.Log;
+import android.view.inputmethod.InputMethodSubtype;
+
+import com.android.inputmethod.keyboard.Key;
+import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.keyboard.KeyboardId;
+import com.android.inputmethod.keyboard.KeyboardLayoutSet;
+import com.android.inputmethod.keyboard.KeyboardLayoutSetTestsBase;
+import com.android.inputmethod.keyboard.layout.AlphabetShifted;
+import com.android.inputmethod.keyboard.layout.Symbols;
+import com.android.inputmethod.keyboard.layout.SymbolsShifted;
+import com.android.inputmethod.keyboard.layout.expected.ActualKeyboardBuilder;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+import com.android.inputmethod.keyboard.layout.expected.LayoutBase;
+import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
+
+import java.util.Arrays;
+import java.util.Locale;
+
+/**
+ * Base class for keyboard layout unit test.
+ */
+abstract class LayoutTestsBase extends KeyboardLayoutSetTestsBase {
+ private InputMethodSubtype mSubtype;
+ private String mLogTag;
+ private KeyboardLayoutSet mKeyboardLayoutSet;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mSubtype = getSubtype(getTestLocale(), getTestKeyboardLayout());
+ mLogTag = SubtypeLocaleUtils.getSubtypeNameForLogging(mSubtype) + "/"
+ + (isPhone() ? "phone" : "tablet");
+ mKeyboardLayoutSet = createKeyboardLayoutSet(mSubtype, null /* editorInfo */);
+ }
+
+ // Those helper methods have a lower case name to be readable when defining expected keyboard
+ // layouts.
+
+ // Helper method to create {@link ExpectedKey} object that has the label.
+ static ExpectedKey key(final String label, final ExpectedKey ... moreKeys) {
+ return LayoutBase.key(label, moreKeys);
+ }
+
+ // Helper method to create {@link ExpectedKey} object that has the label and the output text.
+ static ExpectedKey key(final String label, final String outputText,
+ final ExpectedKey ... moreKeys) {
+ return LayoutBase.key(label, outputText, moreKeys);
+ }
+
+ // Helper method to create {@link ExpectedKey} object for "more key" that has the label.
+ static ExpectedKey moreKey(final String label) {
+ return LayoutBase.moreKey(label);
+ }
+
+ // Helper method to create {@link ExpectedKey} object for "more key" that has the label and the
+ // output text.
+ static ExpectedKey moreKey(final String label, final String outputText) {
+ return LayoutBase.moreKey(label, outputText);
+ }
+
+ // Locale for testing subtype.
+ abstract Locale getTestLocale();
+
+ // Keyboard layout name for testing subtype.
+ abstract String getTestKeyboardLayout();
+
+ // Alphabet keyboard for testing subtype.
+ abstract ExpectedKey[][] getAlphabet(final boolean isPhone);
+
+ // Alphabet automatic shifted keyboard for testing subtype.
+ ExpectedKey[][] getAlphabetAutomaticShifted(final boolean isPhone) {
+ return AlphabetShifted.getAlphabet(getAlphabet(isPhone), getTestLocale());
+ }
+
+ // Alphabet manual shifted keyboard for testing subtype.
+ ExpectedKey[][] getAlphabetManualShifted(final boolean isPhone) {
+ return AlphabetShifted.getAlphabet(getAlphabet(isPhone), getTestLocale());
+ }
+
+ // Alphabet shift locked keyboard for testing subtype.
+ ExpectedKey[][] getAlphabetShiftLocked(final boolean isPhone) {
+ return AlphabetShifted.getAlphabet(getAlphabet(isPhone), getTestLocale());
+ }
+
+ // Alphabet shift lock shifted keyboard for testing subtype.
+ ExpectedKey[][] getAlphabetShiftLockShifted(final boolean isPhone) {
+ return AlphabetShifted.getAlphabet(getAlphabet(isPhone), getTestLocale());
+ }
+
+ // Symbols keyboard for testing subtype.
+ ExpectedKey[][] getSymbols(final boolean isPhone) {
+ return Symbols.getSymbols(isPhone);
+ }
+
+ // Symbols shifted keyboard for testing subtype.
+ ExpectedKey[][] getSymbolsShifted(final boolean isPhone) {
+ return SymbolsShifted.getSymbolsShifted(isPhone);
+ }
+
+ // TODO: Add phone, phone symbols, number, number password layout tests.
+
+ public final void testAlphabet() {
+ final int elementId = KeyboardId.ELEMENT_ALPHABET;
+ doKeyboardTests(elementId, getAlphabet(isPhone()));
+ }
+
+ public final void testAlphabetAutomaticShifted() {
+ final int elementId = KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED;
+ doKeyboardTests(elementId, getAlphabetAutomaticShifted(isPhone()));
+ }
+
+ public final void testAlphabetManualShifted() {
+ final int elementId = KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED;
+ doKeyboardTests(elementId, getAlphabetManualShifted(isPhone()));
+ }
+
+ public final void testAlphabetShiftLocked() {
+ final int elementId = KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED;
+ doKeyboardTests(elementId, getAlphabetShiftLocked(isPhone()));
+ }
+
+ public final void testAlphabetShiftLockShifted() {
+ final int elementId = KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED;
+ doKeyboardTests(elementId, getAlphabetShiftLockShifted(isPhone()));
+ }
+
+ public final void testSymbols() {
+ final int elementId = KeyboardId.ELEMENT_SYMBOLS;
+ doKeyboardTests(elementId, getSymbols(isPhone()));
+ }
+
+ public final void testSymbolsShifted() {
+ final int elementId = KeyboardId.ELEMENT_SYMBOLS_SHIFTED;
+ doKeyboardTests(elementId, getSymbolsShifted(isPhone()));
+ }
+
+ // Comparing expected keyboard and actual keyboard.
+ private void doKeyboardTests(final int elementId, final ExpectedKey[][] expectedKeyboard) {
+ // Skip test if no keyboard is defined.
+ if (expectedKeyboard == null) {
+ return;
+ }
+ final String tag = mLogTag + "/" + KeyboardId.elementIdToName(elementId);
+ // Create actual keyboard object.
+ final Keyboard keyboard = mKeyboardLayoutSet.getKeyboard(elementId);
+ // Create actual keyboard to be compared with the expected keyboard.
+ final Key[][] actualKeyboard = ActualKeyboardBuilder.buildKeyboard(keyboard.getKeys());
+
+ // Dump human readable definition of expected/actual keyboards.
+ Log.d(tag, "expected=\n" + ExpectedKeyboardBuilder.toString(expectedKeyboard));
+ Log.d(tag, "actual =\n" + ActualKeyboardBuilder.toString(actualKeyboard));
+ // Test both keyboards have the same number of rows.
+ assertEquals(tag + " labels"
+ + "\nexpected=" + Arrays.deepToString(expectedKeyboard)
+ + "\nactual =" + ActualKeyboardBuilder.toString(actualKeyboard),
+ expectedKeyboard.length, actualKeyboard.length);
+ for (int r = 0; r < actualKeyboard.length; r++) {
+ final int row = r + 1;
+ // Test both keyboards' rows have the same number of columns.
+ assertEquals(tag + " labels row=" + row
+ + "\nexpected=" + Arrays.toString(expectedKeyboard[r])
+ + "\nactual =" + ActualKeyboardBuilder.toString(actualKeyboard[r]),
+ expectedKeyboard[r].length, actualKeyboard[r].length);
+ for (int c = 0; c < actualKeyboard[r].length; c++) {
+ final int column = c + 1;
+ final Key actualKey = actualKeyboard[r][c];
+ final ExpectedKey expectedKey = expectedKeyboard[r][c];
+ // Test both keyboards' keys have the same visual outlook and key output.
+ assertTrue(tag + " labels row,column=" + row + "," + column
+ + "\nexpected=" + expectedKey
+ + "\nactual =" + ActualKeyboardBuilder.toString(actualKey),
+ expectedKey.equalsTo(actualKey));
+ }
+ }
+ }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishUS.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishUS.java
new file mode 100644
index 000000000..0792a5789
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishUS.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2014 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.layout.tests;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.inputmethod.keyboard.layout.Qwerty;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
+import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
+
+import java.util.Locale;
+
+/**
+ * en_US: English (United States)/qwerty
+ */
+@SmallTest
+public final class TestsEnglishUS extends LayoutTestsBase {
+ @Override
+ Locale getTestLocale() {
+ return new Locale("en", "US");
+ }
+
+ @Override
+ String getTestKeyboardLayout() {
+ return "qwerty";
+ }
+
+ @Override
+ ExpectedKey[][] getAlphabet(final boolean isPhone) {
+ final ExpectedKey[][] keyboard = Qwerty.getAlphabet(isPhone);
+ final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(keyboard);
+ setAccentedLetters(builder);
+ return builder.build();
+ }
+
+ static ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) {
+ return builder
+ // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
+ // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
+ // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
+ // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
+ // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
+ .setMoreKeysOf("e", "3", "\u00E8", "\u00E9", "\u00EA", "\u00EB", "\u0113")
+ // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
+ // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
+ // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
+ // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
+ // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
+ .setMoreKeysOf("u", "7", "\u00FB", "\u00FC", "\u00F9", "\u00FA", "\u016B")
+ // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
+ // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
+ // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
+ // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
+ // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
+ .setMoreKeysOf("i", "8", "\u00EE", "\u00EF", "\u00ED", "\u012B", "\u00EC")
+ // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
+ // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
+ // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
+ // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
+ // U+0153: "œ" LATIN SMALL LIGATURE OE
+ // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
+ // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
+ // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
+ .setMoreKeysOf("o",
+ "9", "\u00F4", "\u00F6", "\u00F2", "\u00F3", "\u0153", "\u00F8", "\u014D",
+ "\u00F5")
+ // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE
+ // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX
+ // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
+ // U+00E6: "æ" LATIN SMALL LETTER AE
+ // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE
+ // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
+ // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON
+ .setMoreKeysOf("a",
+ "\u00E0", "\u00E1", "\u00E2", "\u00E4", "\u00E6", "\u00E3", "\u00E5",
+ "\u0101")
+ // U+00DF: "ß" LATIN SMALL LETTER SHARP S
+ .setMoreKeysOf("s", "\u00DF")
+ // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
+ .setMoreKeysOf("c", "\u00E7")
+ // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
+ .setMoreKeysOf("n", "\u00F1");
+ }
+}
diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java
index 4f9245ce0..d9c35c497 100644
--- a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java
+++ b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java
@@ -23,7 +23,7 @@ import android.util.Pair;
import com.android.inputmethod.latin.makedict.CodePointUtils;
import com.android.inputmethod.latin.makedict.FormatSpec;
-import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
+import com.android.inputmethod.latin.makedict.WeightedString;
import com.android.inputmethod.latin.makedict.WordProperty;
import com.android.inputmethod.latin.utils.BinaryDictionaryUtils;
import com.android.inputmethod.latin.utils.FileUtils;
diff --git a/tests/src/com/android/inputmethod/latin/FusionDictionaryTests.java b/tests/src/com/android/inputmethod/latin/FusionDictionaryTests.java
index cf528d010..09309bcc0 100644
--- a/tests/src/com/android/inputmethod/latin/FusionDictionaryTests.java
+++ b/tests/src/com/android/inputmethod/latin/FusionDictionaryTests.java
@@ -19,6 +19,7 @@ package com.android.inputmethod.latin;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
+import com.android.inputmethod.latin.makedict.FormatSpec.DictionaryOptions;
import com.android.inputmethod.latin.makedict.FusionDictionary;
import com.android.inputmethod.latin.makedict.ProbabilityInfo;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
@@ -32,7 +33,7 @@ import java.util.HashMap;
public class FusionDictionaryTests extends AndroidTestCase {
public void testFindWordInTree() {
FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
- new FusionDictionary.DictionaryOptions(new HashMap<String,String>()));
+ new DictionaryOptions(new HashMap<String,String>()));
dict.add("abc", new ProbabilityInfo(10), null, false /* isNotAWord */);
assertNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "aaa"));
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
index 80978df97..4bf61747c 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
@@ -28,7 +28,6 @@ import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer;
import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
-import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
import com.android.inputmethod.latin.utils.BinaryDictionaryUtils;
import com.android.inputmethod.latin.utils.ByteArrayDictBuffer;
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java
index 79f3e0dc9..5a3eba801 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java
@@ -16,8 +16,8 @@
package com.android.inputmethod.latin.makedict;
+import com.android.inputmethod.latin.makedict.FormatSpec.DictionaryOptions;
import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
-import com.android.inputmethod.latin.makedict.FusionDictionary.DictionaryOptions;
import java.io.File;
import java.util.HashMap;
diff --git a/tools/dicttool/Android.mk b/tools/dicttool/Android.mk
index b1dd7f653..c0a55626a 100644
--- a/tools/dicttool/Android.mk
+++ b/tools/dicttool/Android.mk
@@ -13,6 +13,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+# HACK: Temporarily disable host tool build on Mac until the build system is ready for C++11.
+LATINIME_HOST_OSNAME := $(shell uname -s)
+ifneq ($(LATINIME_HOST_OSNAME), Darwin) # TODO: Remove this
+
LATINIME_DICTTOOL_AOSP_LOCAL_PATH := $(call my-dir)
LOCAL_PATH := $(LATINIME_DICTTOOL_AOSP_LOCAL_PATH)
LATINIME_HOST_NATIVE_LIBNAME := liblatinime-aosp-dicttool-host
@@ -74,10 +78,14 @@ LOCAL_JAVA_LIBRARIES := junit
LOCAL_ADDITIONAL_DEPENDENCIES := $(LATINIME_HOST_NATIVE_LIBNAME)
LOCAL_JAR_MANIFEST := etc/manifest.txt
LOCAL_MODULE := dicttool_aosp
+LOCAL_IS_HOST_MODULE := true
include $(BUILD_HOST_JAVA_LIBRARY)
include $(LOCAL_PATH)/etc/Android.mk
+endif # Darwin - TODO: Remove this
+
# Clear our private variables
LATINIME_DICTTOOL_AOSP_LOCAL_PATH :=
LATINIME_LOCAL_DIR :=
+LATINIME_HOST_OSNAME :=
diff --git a/tools/dicttool/NativeLib.mk b/tools/dicttool/NativeLib.mk
index 26b677447..95f767dc9 100644
--- a/tools/dicttool/NativeLib.mk
+++ b/tools/dicttool/NativeLib.mk
@@ -13,6 +13,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+# HACK: Temporarily disable host tool build on Mac until the build system is ready for C++11.
+LATINIME_HOST_OSNAME := $(shell uname -s)
+ifneq ($(LATINIME_HOST_OSNAME), Darwin) # TODO: Remove this
+
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
@@ -49,9 +53,13 @@ LOCAL_SRC_FILES := \
$(addprefix $(LATINIME_NATIVE_SRC_DIR)/, $(LATIN_IME_CORE_SRC_FILES))
LOCAL_MODULE := $(LATINIME_HOST_NATIVE_LIBNAME)
+LOCAL_IS_HOST_MODULE := true
include $(BUILD_HOST_SHARED_LIBRARY)
+endif # Darwin - TODO: Remove this
+
# Clear our private variables
include $(LOCAL_PATH)/$(LATINIME_NATIVE_JNI_DIR)/CleanupNativeFileList.mk
LATINIME_DIR_RELATIVE_TO_DICTTOOL := ../..
+LATINIME_HOST_OSNAME :=
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/CombinedInputOutput.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/CombinedInputOutput.java
index b6795ea6d..391328fda 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/CombinedInputOutput.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/CombinedInputOutput.java
@@ -17,11 +17,11 @@
package com.android.inputmethod.latin.dicttool;
import com.android.inputmethod.latin.makedict.FormatSpec;
+import com.android.inputmethod.latin.makedict.FormatSpec.DictionaryOptions;
import com.android.inputmethod.latin.makedict.FusionDictionary;
-import com.android.inputmethod.latin.makedict.FusionDictionary.DictionaryOptions;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
-import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import com.android.inputmethod.latin.makedict.ProbabilityInfo;
+import com.android.inputmethod.latin.makedict.WeightedString;
import com.android.inputmethod.latin.makedict.WordProperty;
import com.android.inputmethod.latin.utils.CombinedFormatUtils;
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Diff.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Diff.java
index ce9b9f306..cd3d4d393 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Diff.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Diff.java
@@ -18,7 +18,7 @@ package com.android.inputmethod.latin.dicttool;
import com.android.inputmethod.latin.makedict.FusionDictionary;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
-import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
+import com.android.inputmethod.latin.makedict.WeightedString;
import com.android.inputmethod.latin.makedict.WordProperty;
import java.util.Arrays;
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Info.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Info.java
index 178df5cec..9b2567fd3 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Info.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Info.java
@@ -19,7 +19,7 @@ package com.android.inputmethod.latin.dicttool;
import com.android.inputmethod.latin.makedict.FormatSpec;
import com.android.inputmethod.latin.makedict.FusionDictionary;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
-import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
+import com.android.inputmethod.latin.makedict.WeightedString;
import com.android.inputmethod.latin.makedict.WordProperty;
import java.util.Arrays;
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/XmlDictInputOutput.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/XmlDictInputOutput.java
index 2ac842a80..17e77dca1 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/XmlDictInputOutput.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/XmlDictInputOutput.java
@@ -16,11 +16,11 @@
package com.android.inputmethod.latin.dicttool;
+import com.android.inputmethod.latin.makedict.FormatSpec.DictionaryOptions;
import com.android.inputmethod.latin.makedict.FusionDictionary;
-import com.android.inputmethod.latin.makedict.FusionDictionary.DictionaryOptions;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
-import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import com.android.inputmethod.latin.makedict.ProbabilityInfo;
+import com.android.inputmethod.latin.makedict.WeightedString;
import com.android.inputmethod.latin.makedict.WordProperty;
import java.io.BufferedReader;
diff --git a/tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java b/tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java
index faf00b4a5..a3095da8a 100644
--- a/tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java
+++ b/tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java
@@ -20,9 +20,9 @@ import com.android.inputmethod.latin.makedict.DictDecoder;
import com.android.inputmethod.latin.makedict.DictEncoder;
import com.android.inputmethod.latin.makedict.DictionaryHeader;
import com.android.inputmethod.latin.makedict.FormatSpec;
+import com.android.inputmethod.latin.makedict.FormatSpec.DictionaryOptions;
import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
import com.android.inputmethod.latin.makedict.FusionDictionary;
-import com.android.inputmethod.latin.makedict.FusionDictionary.DictionaryOptions;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
import com.android.inputmethod.latin.makedict.ProbabilityInfo;
import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
diff --git a/tools/dicttool/tests/com/android/inputmethod/latin/makedict/BinaryDictEncoderFlattenTreeTests.java b/tools/dicttool/tests/com/android/inputmethod/latin/makedict/BinaryDictEncoderFlattenTreeTests.java
index 283abcdd1..aa228e72c 100644
--- a/tools/dicttool/tests/com/android/inputmethod/latin/makedict/BinaryDictEncoderFlattenTreeTests.java
+++ b/tools/dicttool/tests/com/android/inputmethod/latin/makedict/BinaryDictEncoderFlattenTreeTests.java
@@ -16,7 +16,7 @@
package com.android.inputmethod.latin.makedict;
-import com.android.inputmethod.latin.makedict.FusionDictionary.DictionaryOptions;
+import com.android.inputmethod.latin.makedict.FormatSpec.DictionaryOptions;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
import junit.framework.TestCase;
diff --git a/tools/dicttool/tests/com/android/inputmethod/latin/makedict/FusionDictionaryTest.java b/tools/dicttool/tests/com/android/inputmethod/latin/makedict/FusionDictionaryTest.java
index d0d47da96..6e81c3f3a 100644
--- a/tools/dicttool/tests/com/android/inputmethod/latin/makedict/FusionDictionaryTest.java
+++ b/tools/dicttool/tests/com/android/inputmethod/latin/makedict/FusionDictionaryTest.java
@@ -16,9 +16,9 @@
package com.android.inputmethod.latin.makedict;
+import com.android.inputmethod.latin.makedict.FormatSpec.DictionaryOptions;
import com.android.inputmethod.latin.makedict.FusionDictionary;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
-import com.android.inputmethod.latin.makedict.FusionDictionary.DictionaryOptions;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
import com.android.inputmethod.latin.makedict.WordProperty;