aboutsummaryrefslogtreecommitdiffstats
path: root/native
diff options
context:
space:
mode:
Diffstat (limited to 'native')
-rw-r--r--native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp33
-rw-r--r--native/src/binary_format.h13
2 files changed, 40 insertions, 6 deletions
diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
index ce874d8d4..18c972444 100644
--- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
+++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "LatinIME: jni: BinaryDictionary"
+#include "binary_format.h"
#include "com_android_inputmethod_latin_BinaryDictionary.h"
#include "dictionary.h"
#include "jni.h"
@@ -38,6 +39,8 @@
namespace latinime {
+void releaseDictBuf(void* dictBuf, const size_t length, int fd);
+
static jint latinime_BinaryDictionary_open(JNIEnv *env, jobject object,
jstring sourceDir, jlong dictOffset, jlong dictSize,
jint typedLetterMultiplier, jint fullWordMultiplier, jint maxWordLength, jint maxWords,
@@ -104,8 +107,18 @@ static jint latinime_BinaryDictionary_open(JNIEnv *env, jobject object,
LOGE("DICT: dictBuf is null");
return 0;
}
- Dictionary *dictionary = new Dictionary(dictBuf, dictSize, fd, adjust, typedLetterMultiplier,
- fullWordMultiplier, maxWordLength, maxWords, maxAlternatives);
+ Dictionary *dictionary = NULL;
+ if (BinaryFormat::UNKNOWN_FORMAT == BinaryFormat::detectFormat((uint8_t*)dictBuf)) {
+ LOGE("DICT: dictionary format is unknown, bad magic number");
+#ifdef USE_MMAP_FOR_DICTIONARY
+ releaseDictBuf(((char*)dictBuf) - adjust, adjDictSize, fd);
+#else // USE_MMAP_FOR_DICTIONARY
+ releaseDictBuf(dictBuf, 0, 0);
+#endif // USE_MMAP_FOR_DICTIONARY
+ } else {
+ dictionary = new Dictionary(dictBuf, dictSize, fd, adjust, typedLetterMultiplier,
+ fullWordMultiplier, maxWordLength, maxWords, maxAlternatives);
+ }
PROF_END(66);
PROF_CLOSE;
return (jint)dictionary;
@@ -180,19 +193,27 @@ static void latinime_BinaryDictionary_close(JNIEnv *env, jobject object, jint di
void *dictBuf = dictionary->getDict();
if (!dictBuf) return;
#ifdef USE_MMAP_FOR_DICTIONARY
- int ret = munmap((void *)((char *)dictBuf - dictionary->getDictBufAdjust()),
- dictionary->getDictSize() + dictionary->getDictBufAdjust());
+ releaseDictBuf((void *)((char *)dictBuf - dictionary->getDictBufAdjust()),
+ dictionary->getDictSize() + dictionary->getDictBufAdjust(), dictionary->getMmapFd());
+#else // USE_MMAP_FOR_DICTIONARY
+ releaseDictBuf(dictBuf, 0, 0);
+#endif // USE_MMAP_FOR_DICTIONARY
+ delete dictionary;
+}
+
+void releaseDictBuf(void* dictBuf, const size_t length, int fd) {
+#ifdef USE_MMAP_FOR_DICTIONARY
+ int ret = munmap(dictBuf, length);
if (ret != 0) {
LOGE("DICT: Failure in munmap. ret=%d errno=%d", ret, errno);
}
- ret = close(dictionary->getMmapFd());
+ ret = close(fd);
if (ret != 0) {
LOGE("DICT: Failure in close. ret=%d errno=%d", ret, errno);
}
#else // USE_MMAP_FOR_DICTIONARY
free(dictBuf);
#endif // USE_MMAP_FOR_DICTIONARY
- delete dictionary;
}
static JNINativeMethod sMethods[] = {
diff --git a/native/src/binary_format.h b/native/src/binary_format.h
index e9f108e25..7deec27d3 100644
--- a/native/src/binary_format.h
+++ b/native/src/binary_format.h
@@ -17,6 +17,8 @@
#ifndef LATINIME_BINARY_FORMAT_H
#define LATINIME_BINARY_FORMAT_H
+#include "unigram_dictionary.h"
+
namespace latinime {
class BinaryFormat {
@@ -26,6 +28,11 @@ private:
const static int MULTIPLE_BYTE_CHARACTER_ADDITIONAL_SIZE = 2;
public:
+ const static int UNKNOWN_FORMAT = -1;
+ const static int FORMAT_VERSION_1 = 1;
+ const static uint16_t FORMAT_VERSION_1_MAGIC_NUMBER = 0x78B1;
+
+ static int detectFormat(const uint8_t* const dict);
static int getGroupCountAndForwardPointer(const uint8_t* const dict, int* pos);
static uint8_t getFlagsAndForwardPointer(const uint8_t* const dict, int* pos);
static int32_t getCharCodeAndForwardPointer(const uint8_t* const dict, int* pos);
@@ -43,6 +50,12 @@ public:
int *pos);
};
+inline int BinaryFormat::detectFormat(const uint8_t* const dict) {
+ const uint16_t magicNumber = (dict[0] << 8) + dict[1]; // big endian
+ if (FORMAT_VERSION_1_MAGIC_NUMBER == magicNumber) return FORMAT_VERSION_1;
+ return UNKNOWN_FORMAT;
+}
+
inline int BinaryFormat::getGroupCountAndForwardPointer(const uint8_t* const dict, int* pos) {
return dict[(*pos)++];
}