/* * 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 "utils/jni_data_utils.h" #include "utils/int_array_view.h" namespace latinime { const int JniDataUtils::CODE_POINT_REPLACEMENT_CHARACTER = 0xFFFD; const int JniDataUtils::CODE_POINT_NULL = 0; /* static */ void JniDataUtils::outputWordProperty(JNIEnv *const env, const WordProperty &wordProperty, jintArray outCodePoints, jbooleanArray outFlags, jintArray outProbabilityInfo, jobject outNgramPrevWordsArray, jobject outNgramPrevWordIsBeginningOfSentenceArray, jobject outNgramTargets, jobject outNgramProbabilities, jobject outShortcutTargets, jobject outShortcutProbabilities) { const CodePointArrayView codePoints = wordProperty.getCodePoints(); JniDataUtils::outputCodePoints(env, outCodePoints, 0 /* start */, MAX_WORD_LENGTH /* maxLength */, codePoints.data(), codePoints.size(), false /* needsNullTermination */); const UnigramProperty &unigramProperty = wordProperty.getUnigramProperty(); const std::vector<NgramProperty> &ngrams = wordProperty.getNgramProperties(); jboolean flags[] = {unigramProperty.isNotAWord(), unigramProperty.isPossiblyOffensive(), !ngrams.empty(), unigramProperty.hasShortcuts(), unigramProperty.representsBeginningOfSentence()}; env->SetBooleanArrayRegion(outFlags, 0 /* start */, NELEMS(flags), flags); const HistoricalInfo &historicalInfo = unigramProperty.getHistoricalInfo(); int probabilityInfo[] = {unigramProperty.getProbability(), historicalInfo.getTimestamp(), historicalInfo.getLevel(), historicalInfo.getCount()}; env->SetIntArrayRegion(outProbabilityInfo, 0 /* start */, NELEMS(probabilityInfo), probabilityInfo); jclass integerClass = env->FindClass("java/lang/Integer"); jmethodID intToIntegerConstructorId = env->GetMethodID(integerClass, "<init>", "(I)V"); jclass arrayListClass = env->FindClass("java/util/ArrayList"); jmethodID addMethodId = env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z"); // Output ngrams. jclass intArrayClass = env->FindClass("[I"); for (const auto &ngramProperty : ngrams) { const NgramContext *const ngramContext = ngramProperty.getNgramContext(); jobjectArray prevWordWordCodePointsArray = env->NewObjectArray( ngramContext->getPrevWordCount(), intArrayClass, nullptr); jbooleanArray prevWordIsBeginningOfSentenceArray = env->NewBooleanArray(ngramContext->getPrevWordCount()); for (size_t i = 0; i < ngramContext->getPrevWordCount(); ++i) { const CodePointArrayView codePoints = ngramContext->getNthPrevWordCodePoints(i + 1); jintArray prevWordCodePoints = env->NewIntArray(codePoints.size()); JniDataUtils::outputCodePoints(env, prevWordCodePoints, 0 /* start */, codePoints.size(), codePoints.data(), codePoints.size(), false /* needsNullTermination */); env->SetObjectArrayElement(prevWordWordCodePointsArray, i, prevWordCodePoints); env->DeleteLocalRef(prevWordCodePoints); JniDataUtils::putBooleanToArray(env, prevWordIsBeginningOfSentenceArray, i, ngramContext->isNthPrevWordBeginningOfSentence(i + 1)); } env->CallBooleanMethod(outNgramPrevWordsArray, addMethodId, prevWordWordCodePointsArray); env->CallBooleanMethod(outNgramPrevWordIsBeginningOfSentenceArray, addMethodId, prevWordIsBeginningOfSentenceArray); env->DeleteLocalRef(prevWordWordCodePointsArray); env->DeleteLocalRef(prevWordIsBeginningOfSentenceArray); const std::vector<int> *const targetWordCodePoints = ngramProperty.getTargetCodePoints(); jintArray targetWordCodePointArray = env->NewIntArray(targetWordCodePoints->size()); JniDataUtils::outputCodePoints(env, targetWordCodePointArray, 0 /* start */, targetWordCodePoints->size(), targetWordCodePoints->data(), targetWordCodePoints->size(), false /* needsNullTermination */); env->CallBooleanMethod(outNgramTargets, addMethodId, targetWordCodePointArray); env->DeleteLocalRef(targetWordCodePointArray); const HistoricalInfo &ngramHistoricalInfo = ngramProperty.getHistoricalInfo(); int bigramProbabilityInfo[] = {ngramProperty.getProbability(), ngramHistoricalInfo.getTimestamp(), ngramHistoricalInfo.getLevel(), ngramHistoricalInfo.getCount()}; jintArray bigramProbabilityInfoArray = env->NewIntArray(NELEMS(bigramProbabilityInfo)); env->SetIntArrayRegion(bigramProbabilityInfoArray, 0 /* start */, NELEMS(bigramProbabilityInfo), bigramProbabilityInfo); env->CallBooleanMethod(outNgramProbabilities, addMethodId, bigramProbabilityInfoArray); env->DeleteLocalRef(bigramProbabilityInfoArray); } // Output shortcuts. for (const auto &shortcut : unigramProperty.getShortcuts()) { const std::vector<int> *const targetCodePoints = shortcut.getTargetCodePoints(); jintArray shortcutTargetCodePointArray = env->NewIntArray(targetCodePoints->size()); JniDataUtils::outputCodePoints(env, shortcutTargetCodePointArray, 0 /* start */, targetCodePoints->size(), targetCodePoints->data(), targetCodePoints->size(), false /* needsNullTermination */); env->CallBooleanMethod(outShortcutTargets, addMethodId, shortcutTargetCodePointArray); env->DeleteLocalRef(shortcutTargetCodePointArray); jobject integerProbability = env->NewObject(integerClass, intToIntegerConstructorId, shortcut.getProbability()); env->CallBooleanMethod(outShortcutProbabilities, addMethodId, integerProbability); env->DeleteLocalRef(integerProbability); } env->DeleteLocalRef(integerClass); env->DeleteLocalRef(arrayListClass); } } // namespace latinime