| /* |
| * 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 previous word information exist, set the predict search information to structure */ |
| if( operation == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_SEARCH_LINK && |
| ( work->previousStroke[ 0 ] != NJ_CHAR_NUL && work->previousCandidate[ 0 ] != NJ_CHAR_NUL ) ) { |
| 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 ) ); |
| |
| /* Reset previous word information */ |
| work->previousStroke[ 0 ] = NJ_CHAR_NUL; |
| work->previousCandidate[ 0 ] = NJ_CHAR_NUL; |
| |
| /* 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; |
| } |
| |