/* * Copyright (C) 2008,2009 OMRON SOFTWARE Co., Ltd. * * 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 "jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni.h" #include "nj_lib.h" #include "nj_err.h" #include "nj_ext.h" #include "nj_dic.h" #include <stdlib.h> #include <string.h> #include <dlfcn.h> #include "OpenWnnJni.h" #include "predef_table.h" /** * functions for internal use */ static void clearDictionaryStructure( NJ_DIC_INFO* dicInfo ) { dicInfo->type = 0; dicInfo->handle = NULL; /* dicInfo->srhCache = NULL; */ dicInfo->dic_freq[ NJ_MODE_TYPE_HENKAN ].base = 0; dicInfo->dic_freq[ NJ_MODE_TYPE_HENKAN ].high = 0; } static NJ_CHAR convertUTFCharToNjChar( NJ_UINT8* src ) { NJ_CHAR ret; NJ_UINT8* dst; /* convert UTF-16BE character to NJ_CHAR format */ dst = ( NJ_UINT8* )&ret; dst[ 0 ] = src[ 0 ]; dst[ 1 ] = src[ 1 ]; return ret; } static int convertStringToNjChar( JNIEnv *env, NJ_CHAR* dst, jstring srcJ, int maxChars ) { const unsigned char* src; src = ( const unsigned char* )( ( *env )->GetStringUTFChars( env, srcJ, NULL ) ); if( src != NULL ) { int i, o; /* convert UTF-8 to UTF-16BE */ for( i = o = 0 ; src[ i ] != 0x00 && o < maxChars ; ) { NJ_UINT8* dst_tmp; dst_tmp = ( NJ_UINT8* )&( dst[ o ] ); if( ( src[ i ] & 0x80 ) == 0x00 ) { /* U+0000 ... U+007f */ /* 8[0xxxxxxx] -> 16BE[00000000 0xxxxxxx] */ dst_tmp[ 0 ] = 0x00; dst_tmp[ 1 ] = src[ i + 0 ] & 0x7f; i++; o++; } else if( ( src[ i ] & 0xe0 ) == 0xc0 ) { /* U+0080 ... U+07ff */ /* 8[110xxxxx 10yyyyyy] -> 16BE[00000xxx xxyyyyyy] */ if( src[ i + 1 ] == 0x00 ) { break; } dst_tmp[ 0 ] = ( ( src[ i + 0 ] & 0x1f ) >> 2 ); dst_tmp[ 1 ] = ( ( src[ i + 0 ] & 0x1f ) << 6 ) | ( src[ i + 1 ] & 0x3f ); i += 2; o++; } else if( ( src[ i ] & 0xf0 ) == 0xe0 ) { /* U+0800 ... U+ffff */ /* 8[1110xxxx 10yyyyyy 10zzzzzz] -> 16BE[xxxxyyyy yyzzzzzz] */ if( src[ i + 1 ] == 0x00 || src[ i + 2 ] == 0x00 ) { break; } dst_tmp[ 0 ] = ( ( src[ i + 0 ] & 0x0f ) << 4 ) | ( ( src[ i + 1 ] & 0x3f ) >> 2 ); dst_tmp[ 1 ] = ( ( src[ i + 1 ] & 0x3f ) << 6 ) | ( src[ i + 2 ] & 0x3f ); i += 3; o++; } else if( ( src[ i ] & 0xf8 ) == 0xf0 ) { NJ_UINT8 dst1, dst2, dst3; /* U+10000 ... U+10ffff */ /* 8[11110www 10xxxxxx 10yyyyyy 10zzzzzz] -> 32BE[00000000 000wwwxx xxxxyyyy yyzzzzzz] */ /* -> 16BE[110110WW XXxxxxyy 110111yy yyzzzzzz] */ /* -- --====== == -------- */ /* dst1 dst2 dst3 */ /* "wwwxx"(00001-10000) - 1 = "WWXX"(0000-1111) */ if( !( o < maxChars - 1 ) ) { /* output buffer is full */ break; } if( src[ i + 1 ] == 0x00 || src[ i + 2 ] == 0x00 || src[ i + 3 ] == 0x00 ) { break; } dst1 = ( ( ( src[ i + 0 ] & 0x07 ) << 2 ) | ( ( src[ i + 1 ] & 0x3f ) >> 4 ) ) - 1; dst2 = ( ( src[ i + 1 ] & 0x3f ) << 4 ) | ( ( src[ i + 2 ] & 0x3f ) >> 2 ); dst3 = ( ( src[ i + 2 ] & 0x3f ) << 6 ) | ( src[ i + 3 ] & 0x3f ); dst_tmp[ 0 ] = 0xd8 | ( ( dst1 & 0x0c ) >> 2 ); dst_tmp[ 1 ] = ( ( dst1 & 0x03 ) << 6 ) | ( ( dst2 & 0xfc ) >> 2 ); dst_tmp[ 2 ] = 0xdc | ( ( dst2 & 0x03 ) ); dst_tmp[ 3 ] = dst3; i += 4; o += 2; } else { /* Broken code */ break; } } dst[ o ] = NJ_CHAR_NUL; ( *env )->ReleaseStringUTFChars( env, srcJ, ( const char* )src ); return 0; } /* If retrieveing the string failed, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_CONVERT_STR_TO_NJC, NJ_ERR_JNI_FUNC_FAILED); } static int convertNjCharToString( JNIEnv* env, jstring* dstJ, NJ_CHAR* src, int maxChars ) { char dst[ (NJ_MAX_LEN + NJ_MAX_RESULT_LEN + NJ_TERM_LEN ) * 3 + 1 ]; int i, o; /* convert UTF-16BE to a UTF-8 */ for( i = o = 0 ; src[ i ] != 0x0000 && i < maxChars ; ) { NJ_UINT8* src_tmp; src_tmp = ( NJ_UINT8* )&( src[ i ] ); if( src_tmp[ 0 ] == 0x00 && src_tmp[ 1 ] <= 0x7f ) { /* U+0000 ... U+007f */ /* 16BE[00000000 0xxxxxxx] -> 8[0xxxxxxx] */ dst[ o + 0 ] = src_tmp[ 1 ] & 0x007f; i++; o++; } else if ( src_tmp[ 0 ] <= 0x07 ) { /* U+0080 ... U+07ff */ /* 16BE[00000xxx xxyyyyyy] -> 8[110xxxxx 10yyyyyy] */ dst[ o + 0 ] = 0xc0 | ( ( src_tmp[ 0 ] & 0x07 ) << 2 ) | ( ( src_tmp[ 1 ] & 0xc0 ) >> 6 ); dst[ o + 1 ] = 0x80 | ( ( src_tmp[ 1 ] & 0x3f ) ); i++; o += 2; } else if ( src_tmp[ 0 ] >= 0xd8 && src_tmp[ 0 ] <= 0xdb ) { NJ_UINT8 src1, src2, src3; /* U+10000 ... U+10ffff (surrogate pair) */ /* 32BE[00000000 000wwwxx xxxxyyyy yyzzzzzz] -> 8[11110www 10xxxxxx 10yyyyyy 10zzzzzz] */ /* 16BE[110110WW XXxxxxyy 110111yy yyzzzzzz] */ /* -- --====== == -------- */ /* src1 src2 src3 */ /* "WWXX"(0000-1111) + 1 = "wwwxx"(0001-10000) */ if( !( i < maxChars - 1 ) || src_tmp[ 2 ] < 0xdc || src_tmp[ 2 ] > 0xdf ) { /* That is broken code */ break; } src1 = ( ( ( src_tmp[ 0 ] & 0x03 ) << 2 ) | ( ( src_tmp[ 1 ] & 0xc0 ) >> 6 ) ) + 1; src2 = ( ( src_tmp[ 1 ] & 0x3f ) << 2 ) | ( ( src_tmp[ 2 ] & 0x03 ) ); src3 = src_tmp[ 3 ]; dst[ o + 0 ] = 0xf0 | ( ( src1 & 0x1c ) >> 2 ); dst[ o + 1 ] = 0x80 | ( ( src1 & 0x03 ) << 4 ) | ( ( src2 & 0xf0 ) >> 4 ); dst[ o + 2 ] = 0x80 | ( ( src2 & 0x0f ) << 2 ) | ( ( src3 & 0xc0 ) >> 6 ); dst[ o + 3 ] = 0x80 | ( src3 & 0x3f ); i += 2; o += 4; } else { /* U+0800 ... U+ffff (except range of surrogate pair) */ /* 16BE[xxxxyyyy yyzzzzzz] -> 8[1110xxxx 10yyyyyy 10zzzzzz] */ dst[ o + 0 ] = 0xe0 | ( ( src_tmp[ 0 ] & 0xf0 ) >> 4 ); dst[ o + 1 ] = 0x80 | ( ( src_tmp[ 0 ] & 0x0f ) << 2 ) | ( ( src_tmp[ 1 ] & 0xc0 ) >> 6 ); dst[ o + 2 ] = 0x80 | ( ( src_tmp[ 1 ] & 0x3f ) ); i++; o += 3; } } dst[ o ] = 0x00; *dstJ = ( *env )->NewStringUTF( env, dst ); /* If NewString() failed, return an error code */ return ( *dstJ == NULL ) ? NJ_SET_ERR_VAL(NJ_FUNC_JNI_CONVERT_NJC_TO_STR, NJ_ERR_JNI_FUNC_FAILED) : 0; } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: createWnnWork * Signature: (Ljava/lang/String;)J */ JNIEXPORT jlong JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_createWnnWork (JNIEnv *env, jobject obj, jstring dicLibPathJ) { NJ_JNIWORK* work; /* Allocating the internal work area */ work = ( NJ_JNIWORK* )malloc( sizeof( NJ_JNIWORK ) ); if( work != NULL ) { NJ_UINT32* dic_size; NJ_UINT8* dic_type; NJ_UINT8** dic_data; NJ_UINT8** con_data; const char* dicLibPath; NJ_INT16 result; int i; /* Initialize the work area */ memset( work, 0x00, sizeof( NJ_JNIWORK ) ); /* Load the dictionary library which is specified by dicLibPathJ */ if( dicLibPathJ == NULL || ( dicLibPath = ( *env )->GetStringUTFChars( env, dicLibPathJ, 0 ) ) == NULL ) { free( work ); return 0; } work->dicLibHandle = ( void* )dlopen( dicLibPath, RTLD_LAZY ); ( *env )->ReleaseStringUTFChars( env, dicLibPathJ, dicLibPath ); if( work->dicLibHandle == NULL ) { free( work ); return 0; } /* Retrieve data pointers of dictionary from the dictionary library, and put to internal work area */ dic_size = ( NJ_UINT32* )dlsym( work->dicLibHandle, "dic_size" ); dic_type = ( NJ_UINT8* )dlsym( work->dicLibHandle, "dic_type" ); dic_data = ( NJ_UINT8** )dlsym( work->dicLibHandle, "dic_data" ); if( dic_size == NULL || dic_type == NULL || dic_data == NULL ) { dlclose( work->dicLibHandle ); free( work ); return 0; } for( i = 0 ; i < NJ_MAX_DIC ; i++ ) { work->dicHandle[ i ] = dic_data[ i ]; work->dicSize[ i ] = dic_size[ i ]; work->dicType[ i ] = dic_type[ i ]; } /* Set the rule dictionary if the rule data exist */ con_data = ( NJ_UINT8** )dlsym( work->dicLibHandle, "con_data" ); if( con_data != NULL ) { work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ] = con_data[ 0 ]; } /* Execute the initialize method to initialize the internal work area */ result = njx_init( &( work->wnnClass ) ); if( result >= 0 ) { jlong jresult; *( NJ_JNIWORK** )&jresult = work; return jresult; } /* If allocating a byte array failed, free all resource, and return NULL */ dlclose( work->dicLibHandle ); free( work ); } /* If allocating the internal work area failed, return NULL */ return 0; } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: freeWnnWork * Signature: (J)I */ JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_freeWnnWork (JNIEnv *env, jobject obj, jlong wnnWork) { NJ_JNIWORK* work; work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { /* If the internal work area was not yet released, remove that */ if( work->dicLibHandle != NULL ) { dlclose( work->dicLibHandle ); work->dicLibHandle = NULL; } free( work ); return 0; } /* freeWnnWork() is always successful even if the internal work area was already released */ return 0; } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: clearDictionaryParameters * Signature: (J)I */ JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_clearDictionaryParameters (JNIEnv *env, jobject obj, jlong wnnWork) { NJ_JNIWORK* work; work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { int index; /* Clear all dictionary set information structure and reset search state */ for( index = 0 ; index < NJ_MAX_DIC ; index++ ) { clearDictionaryStructure( &( work->dicSet.dic[ index ] ) ); } work->flag = NJ_JNI_FLAG_NONE; /* Clear the cache information */ memset( work->dicSet.keyword, 0x00, sizeof( work->dicSet.keyword ) ); return 0; } /* If the internal work area was already released, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_CLEAR_DICTIONARY_PARAMETERS, NJ_ERR_NOT_ALLOCATED); } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: setDictionaryParameter * Signature: (JIII)I */ JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_setDictionaryParameter (JNIEnv *env, jobject obj, jlong wnnWork, jint index, jint base, jint high) { NJ_JNIWORK* work; if( ( index < 0 || index > NJ_MAX_DIC-1 ) || ( base < -1 || base > 1000 ) || ( high < -1 || high > 1000 ) ) { /* If a invalid parameter was specified, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_DICTIONARY_PARAMETERS, NJ_ERR_INVALID_PARAM); } work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { /* Create the dictionary set information structure */ if( base < 0 || high < 0 || base > high ) { /* If -1 was specified to base or high, clear that dictionary information structure */ /* If base is larger than high, clear that dictionary information structure */ clearDictionaryStructure( &( work->dicSet.dic[ index ] ) ); } else { /* Set the dictionary informatin structure */ work->dicSet.dic[ index ].type = work->dicType[ index ]; work->dicSet.dic[ index ].handle = work->dicHandle[ index ]; work->dicSet.dic[ index ].srhCache = &( work->srhCache[ index ] ); work->dicSet.dic[ index ].dic_freq[ NJ_MODE_TYPE_HENKAN ].base = base; work->dicSet.dic[ index ].dic_freq[ NJ_MODE_TYPE_HENKAN ].high = high; } /* Reset search state because the dicionary information was changed */ work->flag = NJ_JNI_FLAG_NONE; return 0; } /* If the internal work area was already released, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_DICTIONARY_PARAMETERS, NJ_ERR_NOT_ALLOCATED); } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: searchWord * Signature: (JIILjava/lang/String;)I */ JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_searchWord (JNIEnv *env, jobject obj, jlong wnnWork, jint operation, jint order, jstring keyString) { NJ_JNIWORK* work; if( !( operation == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_SEARCH_EXACT || operation == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_SEARCH_PREFIX || operation == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_SEARCH_LINK ) || !( order == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_ORDER_BY_FREQUENCY || order == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_ORDER_BY_KEY ) || keyString == NULL ) { /* If a invalid parameter was specified, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SEARCH_WORD, NJ_ERR_INVALID_PARAM); } work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { if( ( *env )->GetStringLength( env, keyString ) > NJ_MAX_LEN ) { /* If too long key string was specified, return "No result is found" */ work->flag &= ~NJ_JNI_FLAG_ENABLE_CURSOR; work->flag &= ~NJ_JNI_FLAG_ENABLE_RESULT; return 0; } if( convertStringToNjChar( env, work->keyString, keyString, NJ_MAX_LEN ) >= 0 ) { jint result; /* Set the structure for search */ memset( &( work->cursor ), 0x00, sizeof( NJ_CURSOR ) ); work->cursor.cond.operation = operation; work->cursor.cond.mode = order; work->cursor.cond.ds = &( work->dicSet ); work->cursor.cond.yomi = work->keyString; work->cursor.cond.charset = &( work->approxSet ); /* If the link search feature is specified, set the predict search information to structure */ if( operation == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_SEARCH_LINK ) { work->cursor.cond.yomi = work->previousStroke; work->cursor.cond.kanji = work->previousCandidate; } /* Search a specified word */ memcpy( &( work->wnnClass.dic_set ), &( work->dicSet ), sizeof( NJ_DIC_SET ) ); result = ( jint )njx_search_word( &( work->wnnClass ), &( work->cursor ) ); /* If a result is found, enable getNextWord method */ if( result == 1 ) { work->flag |= NJ_JNI_FLAG_ENABLE_CURSOR; } else { work->flag &= ~NJ_JNI_FLAG_ENABLE_CURSOR; } work->flag &= ~NJ_JNI_FLAG_ENABLE_RESULT; return result; } /* If converting the string failed, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SEARCH_WORD, NJ_ERR_INTERNAL); } /* If the internal work area was already released, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SEARCH_WORD, NJ_ERR_NOT_ALLOCATED); } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: getNextWord * Signature: (JI)I */ JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getNextWord (JNIEnv *env, jclass obj, jlong wnnWork, jint length) { NJ_JNIWORK* work; work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { if( work->flag & NJ_JNI_FLAG_ENABLE_CURSOR ) { jint result; /* Get a specified word and search a next word */ if( length <= 0 ) { result = ( jint )njx_get_word( &( work->wnnClass ), &( work->cursor ), &( work->result ) ); } else { do { result = ( jint )njx_get_word( &( work->wnnClass ), &( work->cursor ), &( work->result ) ); if( length == ( NJ_GET_YLEN_FROM_STEM( &( work->result.word ) ) + NJ_GET_YLEN_FROM_FZK( &( work->result.word ) ) ) ) { break; } } while( result > 0 ); } /* If a result is found, enable getStroke, getCandidate, getFrequency methods */ if( result > 0 ) { work->flag |= NJ_JNI_FLAG_ENABLE_RESULT; } else { work->flag &= ~NJ_JNI_FLAG_ENABLE_RESULT; } return result; } else { /* When njx_search_word() was not yet called, return "No result is found" */ return 0; } } /* If the internal work area was already released, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_GET_WORD, NJ_ERR_NOT_ALLOCATED); } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: getStroke * Signature: (J)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getStroke (JNIEnv *env, jobject obj, jlong wnnWork) { NJ_JNIWORK* work; work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { jstring str; if( work->flag & NJ_JNI_FLAG_ENABLE_RESULT ) { NJ_CHAR stroke[ NJ_MAX_LEN + NJ_TERM_LEN ]; if( njx_get_stroke( &( work->wnnClass ), &( work->result ), stroke, sizeof( NJ_CHAR ) * ( NJ_MAX_LEN + NJ_TERM_LEN ) ) >= 0 && convertNjCharToString( env, &str, stroke, NJ_MAX_LEN ) >= 0 ) { return str; } } else { /* When njx_get_word() was not yet called, return "No result is found" */ if( convertNjCharToString( env, &str, ( NJ_CHAR* )"\x00\x00", NJ_MAX_LEN ) >= 0 ) { return str; } } } /* If the internal work area was already released, return an error status */ return NULL; } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: getCandidate * Signature: (J)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getCandidate (JNIEnv *env, jobject obj, jlong wnnWork) { NJ_JNIWORK* work; work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { jstring str; if( work->flag & NJ_JNI_FLAG_ENABLE_RESULT ) { NJ_CHAR candidate[ NJ_MAX_LEN + NJ_TERM_LEN ]; if( njx_get_candidate( &( work->wnnClass ), &( work->result ), candidate, sizeof( NJ_CHAR ) * ( NJ_MAX_RESULT_LEN + NJ_TERM_LEN ) ) >= 0 && convertNjCharToString( env, &str, candidate, NJ_MAX_RESULT_LEN ) >= 0 ) { return str; } } else { /* When njx_get_word() was not yet called, return "No result is found" */ if( convertNjCharToString( env, &str, ( NJ_CHAR* )"\x00\x00", NJ_MAX_RESULT_LEN ) >= 0 ) { return str; } } } /* If the internal work area was already released, return an error status */ return NULL; } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: getFrequency * Signature: (J)I */ JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getFrequency (JNIEnv *env, jobject obj, jlong wnnWork) { NJ_JNIWORK* work; work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { if( work->flag & NJ_JNI_FLAG_ENABLE_RESULT ) { return ( jint )( work->result.word.stem.hindo ); } else { /* When njx_get_word() was not yet called, return "No result is found" */ return 0; } } /* If the internal work area was already released, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_GET_FREQUENCY, NJ_ERR_NOT_ALLOCATED); } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: clearApproxPatterns * Signature: (J)V */ JNIEXPORT void JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_clearApproxPatterns (JNIEnv *env, jobject obj, jlong wnnWork) { NJ_JNIWORK* work; work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { int i; /* Clear state */ work->flag = NJ_JNI_FLAG_NONE; /* Clear approximate patterns */ work->approxSet.charset_count = 0; for( i = 0 ; i < NJ_MAX_CHARSET ; i++ ) { work->approxSet.from[ i ] = NULL; work->approxSet.to[ i ] = NULL; } /* Clear the cache information */ memset( work->dicSet.keyword, 0x00, sizeof( work->dicSet.keyword ) ); } } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: setApproxPattern * Signature: (JLjava/lang/String;Ljava/lang/String;)I */ JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_setApproxPattern__JLjava_lang_String_2Ljava_lang_String_2 (JNIEnv *env, jobject obj, jlong wnnWork, jstring srcJ, jstring dstJ) { NJ_JNIWORK* work; if( srcJ == NULL || ( *env )->GetStringLength( env, srcJ ) == 0 || ( *env )->GetStringLength( env, srcJ ) > 1 || dstJ == NULL || ( *env )->GetStringLength( env, dstJ ) == 0 || ( *env )->GetStringLength( env, dstJ ) > 3 ) { /* If a invalid parameter was specified, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_APPROX_PATTERN, NJ_ERR_INVALID_PARAM); } work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { if( work->approxSet.charset_count < NJ_MAX_CHARSET ) { NJ_CHAR* from; NJ_CHAR* to; /* Set pointers of string to store approximate informations */ from = work->approxStr + NJ_APPROXSTORE_SIZE * work->approxSet.charset_count; to = work->approxStr + NJ_APPROXSTORE_SIZE * work->approxSet.charset_count + NJ_MAX_CHARSET_FROM_LEN + NJ_TERM_LEN; work->approxSet.from[ work->approxSet.charset_count ] = from; work->approxSet.to[ work->approxSet.charset_count ] = to; /* Convert approximate informations to internal format */ if( convertStringToNjChar( env, from, srcJ, NJ_MAX_CHARSET_FROM_LEN ) >= 0 && convertStringToNjChar( env, to, dstJ, NJ_MAX_CHARSET_TO_LEN ) >= 0 ) { work->approxSet.charset_count++; /* Reset search state because the seach condition was changed */ work->flag = NJ_JNI_FLAG_NONE; return 0; } /* If converting informations failed, reset pointers, and return an error code */ work->approxSet.from[ work->approxSet.charset_count ] = NULL; work->approxSet.to[ work->approxSet.charset_count ] = NULL; return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_APPROX_PATTERN, NJ_ERR_INTERNAL); } /* If the approx pattern registration area was full, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_APPROX_PATTERN, NJ_ERR_APPROX_PATTERN_IS_FULL); } /* If the internal work area was already released, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_APPROX_PATTERN, NJ_ERR_NOT_ALLOCATED); } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: setApproxPattern * Signature: (JI)I */ JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_setApproxPattern__JI (JNIEnv *env, jclass obj, jlong wnnWork, jint approxPattern) { NJ_JNIWORK *work; if( !( approxPattern == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_APPROX_PATTERN_EN_TOUPPER || approxPattern == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_APPROX_PATTERN_EN_TOLOWER || approxPattern == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_APPROX_PATTERN_EN_QWERTY_NEAR || approxPattern == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_APPROX_PATTERN_EN_QWERTY_NEAR_UPPER || approxPattern == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_APPROX_PATTERN_JAJP_12KEY_NORMAL ) ) { /* If a invalid parameter was specified, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_APPROX_PATTERN, NJ_ERR_INVALID_PARAM); } work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { const PREDEF_APPROX_PATTERN* pattern; pattern = predefinedApproxPatterns[ approxPattern ]; if( work->approxSet.charset_count + pattern->size <= NJ_MAX_CHARSET ) { int i; for( i = 0 ; i < pattern->size ; i++ ) { NJ_CHAR* from; NJ_CHAR* to; /* Set pointers of string to store approximate informations */ from = work->approxStr + NJ_APPROXSTORE_SIZE * ( work->approxSet.charset_count + i ); to = work->approxStr + NJ_APPROXSTORE_SIZE * ( work->approxSet.charset_count + i ) + NJ_MAX_CHARSET_FROM_LEN + NJ_TERM_LEN; work->approxSet.from[ work->approxSet.charset_count + i ] = from; work->approxSet.to[ work->approxSet.charset_count + i ] = to; /* Set approximate pattern */ from[ 0 ] = convertUTFCharToNjChar( pattern->from + i * 2 ); /* "2" means the size of UTF-16BE */ from[ 1 ] = 0x0000; to[ 0 ] = convertUTFCharToNjChar( pattern->to + i * 2 ); /* "2" means the size of UTF-16BE */ to[ 1 ] = 0x0000; } work->approxSet.charset_count += pattern->size; /* Reset search state because the seach condition was changed */ work->flag = NJ_JNI_FLAG_NONE; return 0; } /* If the approx pattern registration area was full, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_APPROX_PATTERN, NJ_ERR_APPROX_PATTERN_IS_FULL); } /* If the internal work area was already released, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_APPROX_PATTERN, NJ_ERR_NOT_ALLOCATED); } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: getLeftPartOfSpeech * Signature: (J)I */ JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getLeftPartOfSpeech (JNIEnv *env, jclass obj, jlong wnnWork) { NJ_JNIWORK* work; work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { return NJ_GET_FPOS_FROM_STEM( &( work->result.word ) ); } /* If the internal work area was already released, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_GET_LEFT_PART_OF_SPEECH, NJ_ERR_NOT_ALLOCATED); } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: getRightPartOfSpeech * Signature: (J)I */ JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getRightPartOfSpeech (JNIEnv *env, jclass obj, jlong wnnWork) { NJ_JNIWORK* work; work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { return NJ_GET_BPOS_FROM_STEM( &( work->result.word ) ); } /* If the internal work area was already released, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_GET_RIGHT_PART_OF_SPEECH, NJ_ERR_NOT_ALLOCATED); } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: clearResult * Signature: (J)V */ JNIEXPORT void JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_clearResult (JNIEnv *env, jclass obj, jlong wnnWork) { NJ_JNIWORK* work; work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { /* Clear the current word information */ memset( &( work->result ), 0x00, sizeof( NJ_RESULT ) ); memset( &( work->previousStroke ), 0x00, sizeof( work->previousStroke ) ); memset( &( work->previousCandidate ), 0x00, sizeof( work->previousCandidate ) ); } /* In this method, No error reports. */ } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: setLeftPartOfSpeech * Signature: (JI)I */ JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_setLeftPartOfSpeech (JNIEnv *env, jclass obj, jlong wnnWork, jint leftPartOfSpeech) { NJ_JNIWORK* work; work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { NJ_UINT16 lcount = 0, rcount = 0; if( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ] == NULL ) { /* No rule dictionary was set */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_LEFT_PART_OF_SPEECH, NJ_ERR_NO_RULEDIC); } njd_r_get_count( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ], &lcount, &rcount ); if( leftPartOfSpeech < 1 || leftPartOfSpeech > lcount ) { /* If a invalid parameter was specified, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_LEFT_PART_OF_SPEECH, NJ_ERR_INVALID_PARAM); } NJ_SET_FPOS_TO_STEM( &( work->result.word ), leftPartOfSpeech ); return 0; } /* If the internal work area was already released, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_LEFT_PART_OF_SPEECH, NJ_ERR_NOT_ALLOCATED); } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: setRightPartOfSpeech * Signature: (JI)I */ JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_setRightPartOfSpeech (JNIEnv *env, jclass obj, jlong wnnWork, jint rightPartOfSpeech) { NJ_JNIWORK* work; work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { NJ_UINT16 lcount = 0, rcount = 0; if( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ] == NULL ) { /* No rule dictionary was set */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_RIGHT_PART_OF_SPEECH, NJ_ERR_NO_RULEDIC); } njd_r_get_count( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ], &lcount, &rcount ); if( rightPartOfSpeech < 1 || rightPartOfSpeech > rcount ) { /* If a invalid parameter was specified, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_RIGHT_PART_OF_SPEECH, NJ_ERR_INVALID_PARAM); } NJ_SET_BPOS_TO_STEM( &( work->result.word ), rightPartOfSpeech ); return 0; } /* If the internal work area was already released, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_RIGHT_PART_OF_SPEECH, NJ_ERR_NOT_ALLOCATED); } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: setStroke * Signature: (JLjava/lang/String;)I */ JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_setStroke (JNIEnv *env, jclass obj, jlong wnnWork, jstring stroke) { NJ_JNIWORK* work; if( stroke == NULL ) { /* If a invalid parameter was specified, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_STROKE, NJ_ERR_INVALID_PARAM); } work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { if( ( *env )->GetStringLength( env, stroke ) > NJ_MAX_LEN ) { /* If a invalid parameter was specified, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_STROKE, NJ_ERR_YOMI_TOO_LONG); } /* Store stroke string */ if( convertStringToNjChar( env, work->previousStroke, stroke, NJ_MAX_LEN ) >= 0 ) { return 0; } /* If converting the string failed, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_STROKE, NJ_ERR_INTERNAL); } /* If the internal work area was already released, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_STROKE, NJ_ERR_NOT_ALLOCATED); } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: setCandidate * Signature: (JLjava/lang/String;)I */ JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_setCandidate (JNIEnv *env, jclass obj, jlong wnnWork, jstring candidate) { NJ_JNIWORK* work; if( candidate == NULL ) { /* If a invalid parameter was specified, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_CANDIDATE, NJ_ERR_INVALID_PARAM); } work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { if( ( *env )->GetStringLength( env, candidate ) > NJ_MAX_RESULT_LEN ) { /* If a invalid parameter was specified, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_CANDIDATE, NJ_ERR_CANDIDATE_TOO_LONG); } /* Store candidate string */ if( convertStringToNjChar( env, work->previousCandidate, candidate, NJ_MAX_RESULT_LEN ) >= 0 ) { return 0; } /* If converting the string failed, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_CANDIDATE, NJ_ERR_INTERNAL); } /* If the internal work area was already released, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_CANDIDATE, NJ_ERR_NOT_ALLOCATED); } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: selectWord * Signature: (J)I */ JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_selectWord (JNIEnv *env, jclass obj, jlong wnnWork) { NJ_JNIWORK* work; work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { /* Put the previous word information to engine */ memcpy( &( work->wnnClass.dic_set ), &( work->dicSet ), sizeof( NJ_DIC_SET ) ); return ( jint )njx_select( &( work->wnnClass ), &( work->result ) ); } /* If the internal work area was already released, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SELECT_WORD, NJ_ERR_NOT_ALLOCATED); } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: getLeftPartOfSpeechSpecifiedType * Signature: (JI)I */ JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getLeftPartOfSpeechSpecifiedType (JNIEnv *env, jclass obj, jlong wnnWork, jint type) { NJ_JNIWORK* work; work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { switch( type ) { case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_V1: type = NJ_HINSI_V1_F; break; case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_V2: type = NJ_HINSI_V2_F; break; case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_V3: type = NJ_HINSI_V3_F; break; case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_BUNTOU: /* No part of speech is defined at this type */ return 0; case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_TANKANJI: type = NJ_HINSI_TANKANJI_F; break; case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_SUUJI: /* No part of speech is defined at this type */ return 0; case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_MEISI: type = NJ_HINSI_MEISI_F; break; case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_JINMEI: type = NJ_HINSI_JINMEI_F; break; case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_CHIMEI: type = NJ_HINSI_CHIMEI_F; break; case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_KIGOU: type = NJ_HINSI_KIGOU_F; break; default: /* If a invalid parameter was specified, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_GET_LEFT_PART_OF_SPEECH_SPECIFIED_TYPE, NJ_ERR_INVALID_PARAM); } return ( jint )njd_r_get_hinsi( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ], type ); } /* If the internal work area was already released, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_GET_LEFT_PART_OF_SPEECH_SPECIFIED_TYPE, NJ_ERR_NOT_ALLOCATED); } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: getRightPartOfSpeechSpecifiedType * Signature: (JI)I */ JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getRightPartOfSpeechSpecifiedType (JNIEnv *env, jclass obj, jlong wnnWork, jint type) { NJ_JNIWORK* work; work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { switch( type ) { case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_V1: /* No part of speech is defined at this type */ return 0; case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_V2: /* No part of speech is defined at this type */ return 0; case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_V3: /* No part of speech is defined at this type */ return 0; case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_BUNTOU: type = NJ_HINSI_BUNTOU_B; break; case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_TANKANJI: type = NJ_HINSI_TANKANJI_B; break; case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_SUUJI: type = NJ_HINSI_SUUJI_B; break; case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_MEISI: type = NJ_HINSI_MEISI_B; break; case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_JINMEI: type = NJ_HINSI_JINMEI_B; break; case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_CHIMEI: type = NJ_HINSI_CHIMEI_B; break; case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_KIGOU: type = NJ_HINSI_KIGOU_B; break; default: /* If a invalid parameter was specified, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_GET_LEFT_PART_OF_SPEECH_SPECIFIED_TYPE, NJ_ERR_INVALID_PARAM); } return ( jint )njd_r_get_hinsi( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ], type ); } /* If the internal work area was already released, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_GET_RIGHT_PART_OF_SPEECH_SPECIFIED_TYPE, NJ_ERR_NOT_ALLOCATED); } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: getConnectArray * Signature: (JI)[B */ JNIEXPORT jbyteArray JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getConnectArray (JNIEnv *env, jclass obj, jlong wnnWork, jint leftPartOfSpeech) { NJ_JNIWORK* work; work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { NJ_UINT16 lcount = 0, rcount = 0; jbyteArray resultJ; if( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ] == NULL ) { /* No rule dictionary was set */ return NULL; } njd_r_get_count( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ], &lcount, &rcount ); if( leftPartOfSpeech < 0 || leftPartOfSpeech > lcount ) { /* Invalid POS is specified */ return NULL; } /* 1-origin */ resultJ = ( *env )->NewByteArray( env, rcount + 1 ); if( resultJ != NULL ) { jbyte *result; result = ( *env )->GetByteArrayElements( env, resultJ, NULL ); if( result != NULL ) { int i; NJ_UINT8* connect; if( leftPartOfSpeech == 0 ) { for( i = 0 ; i < rcount + 1 ; i++ ) { result[ i ] = 0; } } else { /* Get the packed connect array */ njd_r_get_connect( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ], leftPartOfSpeech, NJ_RULE_TYPE_FTOB, &connect ); /* Extract connect array from bit field */ result[ 0 ] = 0; for( i = 0 ; i < rcount ; i++ ) { if( connect[ i / 8 ] & (0x80 >> (i % 8))) { result[ i + 1 ] = 1; } else { result[ i + 1 ] = 0; } } } ( *env )->ReleaseByteArrayElements( env, resultJ, result, 0 ); return resultJ; } } /* If allocating the return area failed, return an error code */ return NULL; } /* If the internal work area was already released, return an error code */ return NULL; } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: getNumberOfLeftPOS * Signature: (J)I */ JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getNumberOfLeftPOS (JNIEnv *env, jclass obj, jlong wnnWork) { NJ_JNIWORK* work; work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { if( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ] == NULL ) { /* No rule dictionary was set */ return 0; } else { NJ_UINT16 lcount = 0, rcount = 0; njd_r_get_count( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ], &lcount, &rcount ); return lcount; } } /* If the internal work area was already released, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_GET_NUMBER_OF_LEFT_POS, NJ_ERR_NOT_ALLOCATED); } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: getNumberOfRightPOS * Signature: (J)I */ JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getNumberOfRightPOS (JNIEnv *env, jclass obj, jlong wnnWork) { NJ_JNIWORK* work; work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { if( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ] == NULL ) { /* No rule dictionary was set */ return 0; } else { NJ_UINT16 lcount = 0, rcount = 0; njd_r_get_count( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ], &lcount, &rcount ); return rcount; } } /* If the internal work area was already released, return an error code */ return NJ_SET_ERR_VAL(NJ_FUNC_JNI_GET_NUMBER_OF_RIGHT_POS, NJ_ERR_NOT_ALLOCATED); } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: getApproxPattern * Signature: (JLjava/lang/String;)[Ljava/lang/String; */ JNIEXPORT jobjectArray JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getApproxPattern (JNIEnv *env, jclass obj, jlong wnnWork, jstring srcJ) { NJ_JNIWORK* work; if( srcJ == NULL || ( *env )->GetStringLength( env, srcJ ) == 0 || ( *env )->GetStringLength( env, srcJ ) > 1 ) { /* If a invalid parameter was specified, return an error code */ return NULL; } work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { int i, outIndex, outCount; NJ_CHAR from[ NJ_MAX_CHARSET_FROM_LEN + NJ_TERM_LEN ]; if( convertStringToNjChar( env, from, srcJ, NJ_MAX_CHARSET_FROM_LEN ) >= 0 ) { outCount = 0; for( i = 0 ; i < work->approxSet.charset_count ; i++ ) { if( nj_strcmp( from, work->approxSet.from[ i ] ) == 0 ) { outCount++; } } jclass strC = ( *env )->FindClass( env, "java/lang/String" ); if( strC != NULL ) { jobjectArray retJ = ( *env )->NewObjectArray( env, outCount, strC, NULL ); if( retJ != NULL ) { for( i = outIndex = 0 ; i < work->approxSet.charset_count ; i++ ) { if( nj_strcmp( from, work->approxSet.from[ i ] ) == 0 ) { jstring dstJ; if( convertNjCharToString( env, &dstJ, work->approxSet.to[ i ], NJ_MAX_CHARSET_TO_LEN ) < 0 ) { return NULL; } ( *env )->SetObjectArrayElement( env, retJ, outIndex++, dstJ ); } } return retJ; } } } /* If the internal error occured, return an error code */ return NULL; } /* If the internal work area was already released, return an error code */ return NULL; } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: createBindArray * Signature: (JLjava/lang/String;II)[Ljava/lang/String; */ JNIEXPORT jobjectArray JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_createBindArray (JNIEnv *env, jclass obj, jlong wnnWork, jstring keyStringJ, jint maxBindsOfQuery, jint maxPatternOfApprox) { NJ_JNIWORK* work; if( keyStringJ == NULL ) { /* If a invalid parameter was specified, return an error code */ return NULL; } work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { /* create the string array for result */ jclass strC = ( *env )->FindClass( env, "java/lang/String" ); if( strC != NULL ) { jobjectArray retJ = ( *env )->NewObjectArray( env, maxBindsOfQuery * (maxPatternOfApprox+1), strC, NULL ); if( retJ != NULL ) { NJ_CHAR keyString[ NJ_MAX_LEN + NJ_TERM_LEN ]; if( convertStringToNjChar( env, keyString, keyStringJ, NJ_MAX_LEN ) >= 0 ) { int queryLen, outIndex, approxPattern; NJ_CHAR baseStr[ NJ_MAX_LEN + NJ_MAX_CHARSET_TO_LEN + NJ_TERM_LEN ]; outIndex = 0; baseStr[ 0 ] = NJ_CHAR_NUL; for( queryLen = 0 ; queryLen < maxBindsOfQuery && keyString[ queryLen ] != NJ_CHAR_NUL ; queryLen++ ) { int i; for( i = -1, approxPattern = -1 ; i < work->approxSet.charset_count ; i++ ) { if( i == -1 || keyString[ queryLen ] == work->approxSet.from[ i ][ 0 ] ) { int tailOffset = 0; if( i == -1 ) { if( *( ( NJ_UINT8* )( &keyString[ queryLen ] ) + 0 ) == 0x00 && ( *( ( NJ_UINT8* )( &keyString[ queryLen ] ) + 1 ) == 0x25 || /* '%' */ *( ( NJ_UINT8* )( &keyString[ queryLen ] ) + 1 ) == 0x5c || /* '\' */ *( ( NJ_UINT8* )( &keyString[ queryLen ] ) + 1 ) == 0x5f ) ) { /* '_' */ *( ( NJ_UINT8* )( &baseStr[ queryLen + 0 ] ) + 0 ) = 0x00; *( ( NJ_UINT8* )( &baseStr[ queryLen + 0 ] ) + 1 ) = 0x5c; /* '\' */ baseStr[ queryLen + 1 ] = keyString[ queryLen ]; tailOffset = 2; } else { baseStr[ queryLen + 0 ] = keyString[ queryLen ]; tailOffset = 1; } } else { nj_strcpy( &baseStr[ queryLen ], work->approxSet.to[ i ] ); tailOffset = nj_strlen( work->approxSet.to[ i ] ); } *( ( NJ_UINT8* )( &baseStr[ queryLen + tailOffset ] ) + 0 ) = 0x00; *( ( NJ_UINT8* )( &baseStr[ queryLen + tailOffset ] ) + 1 ) = 0x25; /* '%' */ baseStr[ queryLen + tailOffset + 1 ] = NJ_CHAR_NUL; jstring dstJ; if( convertNjCharToString( env, &dstJ, baseStr, NJ_MAX_LEN ) < 0 ) { return NULL; } ( *env )->SetObjectArrayElement( env, retJ, outIndex++, dstJ ); approxPattern++; } } for( ; approxPattern < maxPatternOfApprox ; approxPattern++ ) { jstring dstJ = ( *env )->NewStringUTF( env, "" ); if( dstJ == NULL ) { return NULL; } ( *env )->SetObjectArrayElement( env, retJ, outIndex++, dstJ ); } *( ( NJ_UINT8* )( &baseStr[ queryLen ] ) + 0 ) = 0x00; *( ( NJ_UINT8* )( &baseStr[ queryLen ] ) + 1 ) = 0x5f; /* '_' */ baseStr[ queryLen + 1 ] = NJ_CHAR_NUL; } for( ; queryLen < maxBindsOfQuery ; queryLen++ ) { for( approxPattern = -1 ; approxPattern < maxPatternOfApprox ; approxPattern++ ) { jstring dstJ = ( *env )->NewStringUTF( env, "%" ); if( dstJ == NULL ) { return NULL; } ( *env )->SetObjectArrayElement( env, retJ, outIndex++, dstJ ); } } return retJ; } } } /* If the internal error occured, return an error code */ return NULL; } /* If the internal work area was already released, return an error code */ return NULL; } /* * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni * Method: createQueryStringBase * Signature: (JIILjava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_createQueryStringBase (JNIEnv *env, jclass obj, jlong wnnWork, jint maxBindsOfQuery, jint maxPatternOfApprox, jstring keyColumnNameJ) { NJ_JNIWORK* work; jstring retJ = NULL; if( keyColumnNameJ == NULL ) { /* If a invalid parameter was specified, return an error code */ return NULL; } work = *( NJ_JNIWORK** )&wnnWork; if( work != NULL ) { const unsigned char* keyName = ( const unsigned char* )( ( *env )->GetStringUTFChars( env, keyColumnNameJ, NULL ) ); if( keyName != NULL ) { int keyLength = strlen( ( char* )keyName ); char *dst = ( char* )malloc( maxBindsOfQuery * ( ( 1 + keyLength + 18 + 1 + 5 ) + ( ( 4 + keyLength + 18 ) * maxPatternOfApprox ) + 1 ) ); if( dst != NULL ) { int queryLen, dstPtr; for( queryLen = dstPtr = 0 ; queryLen < maxBindsOfQuery ; queryLen++ ) { int approxPattern; strcpy( &dst[ dstPtr ], "(" ); strcpy( &dst[ dstPtr + 1 ], ( char* )keyName ); strcpy( &dst[ dstPtr + 1 + keyLength ], " like ? escape '\x5c'" ); dstPtr += 1 + keyLength + 18; for( approxPattern = 0 ; approxPattern < maxPatternOfApprox ; approxPattern++ ) { strcpy( &dst[ dstPtr ], " or " ); strcpy( &dst[ dstPtr + 4 ], ( char* )keyName ); strcpy( &dst[ dstPtr + 4 + keyLength ], " like ? escape '\x5c'" ); dstPtr += 4 + keyLength + 18; } strcpy( &dst[ dstPtr ], ")" ); dstPtr++; if( queryLen != maxBindsOfQuery-1 ) { strcpy( &dst[ dstPtr ], " and " ); dstPtr += 5; } } dst[ dstPtr ] = '\0'; retJ = ( *env )->NewStringUTF( env, dst ); free( dst ); } ( *env )->ReleaseStringUTFChars( env, keyColumnNameJ, ( const char* )keyName ); } } return retJ; }