1 /* 2 * Copyright (C) 2008,2009 OMRON SOFTWARE Co., Ltd. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #include "jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni.h" 17 18 #include "nj_lib.h" 19 #include "nj_err.h" 20 #include "nj_ext.h" 21 #include "nj_dic.h" 22 23 24 #include <stdlib.h> 25 #include <string.h> 26 #include <dlfcn.h> 27 28 #include "OpenWnnJni.h" 29 30 31 #include "predef_table.h" 32 33 /** 34 * functions for internal use 35 */ 36 static void clearDictionaryStructure( NJ_DIC_INFO* dicInfo ) { 37 dicInfo->type = 0; 38 dicInfo->handle = NULL; 39 /* dicInfo->srhCache = NULL; */ 40 41 dicInfo->dic_freq[ NJ_MODE_TYPE_HENKAN ].base = 0; 42 dicInfo->dic_freq[ NJ_MODE_TYPE_HENKAN ].high = 0; 43 } 44 45 static NJ_CHAR convertUTFCharToNjChar( NJ_UINT8* src ) 46 { 47 NJ_CHAR ret; 48 NJ_UINT8* dst; 49 50 /* convert UTF-16BE character to NJ_CHAR format */ 51 dst = ( NJ_UINT8* )&ret; 52 dst[ 0 ] = src[ 0 ]; 53 dst[ 1 ] = src[ 1 ]; 54 55 return ret; 56 } 57 58 static int convertStringToNjChar( JNIEnv *env, NJ_CHAR* dst, jstring srcJ, int maxChars ) 59 { 60 const unsigned char* src; 61 62 src = ( const unsigned char* )( ( *env )->GetStringUTFChars( env, srcJ, NULL ) ); 63 if( src != NULL ) { 64 int i, o; 65 66 /* convert UTF-8 to UTF-16BE */ 67 for( i = o = 0 ; src[ i ] != 0x00 && o < maxChars ; ) { 68 NJ_UINT8* dst_tmp; 69 dst_tmp = ( NJ_UINT8* )&( dst[ o ] ); 70 71 if( ( src[ i ] & 0x80 ) == 0x00 ) { 72 /* U+0000 ... U+007f */ 73 /* 8[0xxxxxxx] -> 16BE[00000000 0xxxxxxx] */ 74 dst_tmp[ 0 ] = 0x00; 75 dst_tmp[ 1 ] = src[ i + 0 ] & 0x7f; 76 i++; 77 o++; 78 } else if( ( src[ i ] & 0xe0 ) == 0xc0 ) { 79 /* U+0080 ... U+07ff */ 80 /* 8[110xxxxx 10yyyyyy] -> 16BE[00000xxx xxyyyyyy] */ 81 if( src[ i + 1 ] == 0x00 ) { 82 break; 83 } 84 dst_tmp[ 0 ] = ( ( src[ i + 0 ] & 0x1f ) >> 2 ); 85 dst_tmp[ 1 ] = ( ( src[ i + 0 ] & 0x1f ) << 6 ) | ( src[ i + 1 ] & 0x3f ); 86 i += 2; 87 o++; 88 } else if( ( src[ i ] & 0xf0 ) == 0xe0 ) { 89 /* U+0800 ... U+ffff */ 90 /* 8[1110xxxx 10yyyyyy 10zzzzzz] -> 16BE[xxxxyyyy yyzzzzzz] */ 91 if( src[ i + 1 ] == 0x00 || src[ i + 2 ] == 0x00 ) { 92 break; 93 } 94 dst_tmp[ 0 ] = ( ( src[ i + 0 ] & 0x0f ) << 4 ) | ( ( src[ i + 1 ] & 0x3f ) >> 2 ); 95 dst_tmp[ 1 ] = ( ( src[ i + 1 ] & 0x3f ) << 6 ) | ( src[ i + 2 ] & 0x3f ); 96 i += 3; 97 o++; 98 } else if( ( src[ i ] & 0xf8 ) == 0xf0 ) { 99 NJ_UINT8 dst1, dst2, dst3; 100 /* U+10000 ... U+10ffff */ 101 /* 8[11110www 10xxxxxx 10yyyyyy 10zzzzzz] -> 32BE[00000000 000wwwxx xxxxyyyy yyzzzzzz] */ 102 /* -> 16BE[110110WW XXxxxxyy 110111yy yyzzzzzz] */ 103 /* -- --====== == -------- */ 104 /* dst1 dst2 dst3 */ 105 /* "wwwxx"(00001-10000) - 1 = "WWXX"(0000-1111) */ 106 if( !( o < maxChars - 1 ) ) { 107 /* output buffer is full */ 108 break; 109 } 110 if( src[ i + 1 ] == 0x00 || src[ i + 2 ] == 0x00 || src[ i + 3 ] == 0x00 ) { 111 break; 112 } 113 dst1 = ( ( ( src[ i + 0 ] & 0x07 ) << 2 ) | ( ( src[ i + 1 ] & 0x3f ) >> 4 ) ) - 1; 114 dst2 = ( ( src[ i + 1 ] & 0x3f ) << 4 ) | ( ( src[ i + 2 ] & 0x3f ) >> 2 ); 115 dst3 = ( ( src[ i + 2 ] & 0x3f ) << 6 ) | ( src[ i + 3 ] & 0x3f ); 116 117 dst_tmp[ 0 ] = 0xd8 | ( ( dst1 & 0x0c ) >> 2 ); 118 dst_tmp[ 1 ] = ( ( dst1 & 0x03 ) << 6 ) | ( ( dst2 & 0xfc ) >> 2 ); 119 dst_tmp[ 2 ] = 0xdc | ( ( dst2 & 0x03 ) ); 120 dst_tmp[ 3 ] = dst3; 121 i += 4; 122 o += 2; 123 } else { /* Broken code */ 124 break; 125 } 126 } 127 dst[ o ] = NJ_CHAR_NUL; 128 129 ( *env )->ReleaseStringUTFChars( env, srcJ, ( const char* )src ); 130 return 0; 131 } 132 /* If retrieveing the string failed, return an error code */ 133 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_CONVERT_STR_TO_NJC, NJ_ERR_JNI_FUNC_FAILED); 134 } 135 136 static int convertNjCharToString( JNIEnv* env, jstring* dstJ, NJ_CHAR* src, int maxChars ) 137 { 138 char dst[ (NJ_MAX_LEN + NJ_MAX_RESULT_LEN + NJ_TERM_LEN ) * 3 + 1 ]; 139 140 int i, o; 141 142 /* convert UTF-16BE to a UTF-8 */ 143 for( i = o = 0 ; src[ i ] != 0x0000 && i < maxChars ; ) { 144 NJ_UINT8* src_tmp; 145 src_tmp = ( NJ_UINT8* )&( src[ i ] ); 146 147 if( src_tmp[ 0 ] == 0x00 && src_tmp[ 1 ] <= 0x7f ) { 148 /* U+0000 ... U+007f */ 149 /* 16BE[00000000 0xxxxxxx] -> 8[0xxxxxxx] */ 150 dst[ o + 0 ] = src_tmp[ 1 ] & 0x007f; 151 i++; 152 o++; 153 } else if ( src_tmp[ 0 ] <= 0x07 ) { 154 /* U+0080 ... U+07ff */ 155 /* 16BE[00000xxx xxyyyyyy] -> 8[110xxxxx 10yyyyyy] */ 156 dst[ o + 0 ] = 0xc0 | ( ( src_tmp[ 0 ] & 0x07 ) << 2 ) | ( ( src_tmp[ 1 ] & 0xc0 ) >> 6 ); 157 dst[ o + 1 ] = 0x80 | ( ( src_tmp[ 1 ] & 0x3f ) ); 158 i++; 159 o += 2; 160 } else if ( src_tmp[ 0 ] >= 0xd8 && src_tmp[ 0 ] <= 0xdb ) { 161 NJ_UINT8 src1, src2, src3; 162 /* U+10000 ... U+10ffff (surrogate pair) */ 163 /* 32BE[00000000 000wwwxx xxxxyyyy yyzzzzzz] -> 8[11110www 10xxxxxx 10yyyyyy 10zzzzzz] */ 164 /* 16BE[110110WW XXxxxxyy 110111yy yyzzzzzz] */ 165 /* -- --====== == -------- */ 166 /* src1 src2 src3 */ 167 /* "WWXX"(0000-1111) + 1 = "wwwxx"(0001-10000) */ 168 if( !( i < maxChars - 1 ) || src_tmp[ 2 ] < 0xdc || src_tmp[ 2 ] > 0xdf ) { 169 /* That is broken code */ 170 break; 171 } 172 src1 = ( ( ( src_tmp[ 0 ] & 0x03 ) << 2 ) | ( ( src_tmp[ 1 ] & 0xc0 ) >> 6 ) ) + 1; 173 src2 = ( ( src_tmp[ 1 ] & 0x3f ) << 2 ) | ( ( src_tmp[ 2 ] & 0x03 ) ); 174 src3 = src_tmp[ 3 ]; 175 176 dst[ o + 0 ] = 0xf0 | ( ( src1 & 0x1c ) >> 2 ); 177 dst[ o + 1 ] = 0x80 | ( ( src1 & 0x03 ) << 4 ) | ( ( src2 & 0xf0 ) >> 4 ); 178 dst[ o + 2 ] = 0x80 | ( ( src2 & 0x0f ) << 2 ) | ( ( src3 & 0xc0 ) >> 6 ); 179 dst[ o + 3 ] = 0x80 | ( src3 & 0x3f ); 180 i += 2; 181 o += 4; 182 } else { 183 /* U+0800 ... U+ffff (except range of surrogate pair) */ 184 /* 16BE[xxxxyyyy yyzzzzzz] -> 8[1110xxxx 10yyyyyy 10zzzzzz] */ 185 dst[ o + 0 ] = 0xe0 | ( ( src_tmp[ 0 ] & 0xf0 ) >> 4 ); 186 dst[ o + 1 ] = 0x80 | ( ( src_tmp[ 0 ] & 0x0f ) << 2 ) | ( ( src_tmp[ 1 ] & 0xc0 ) >> 6 ); 187 dst[ o + 2 ] = 0x80 | ( ( src_tmp[ 1 ] & 0x3f ) ); 188 i++; 189 o += 3; 190 } 191 } 192 dst[ o ] = 0x00; 193 194 *dstJ = ( *env )->NewStringUTF( env, dst ); 195 196 /* If NewString() failed, return an error code */ 197 return ( *dstJ == NULL ) ? NJ_SET_ERR_VAL(NJ_FUNC_JNI_CONVERT_NJC_TO_STR, NJ_ERR_JNI_FUNC_FAILED) : 0; 198 } 199 200 /* 201 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 202 * Method: createWnnWork 203 * Signature: (Ljava/lang/String;)J 204 */ 205 JNIEXPORT jlong JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_createWnnWork 206 (JNIEnv *env, jobject obj, jstring dicLibPathJ) 207 { 208 NJ_JNIWORK* work; 209 210 /* Allocating the internal work area */ 211 work = ( NJ_JNIWORK* )malloc( sizeof( NJ_JNIWORK ) ); 212 if( work != NULL ) { 213 NJ_UINT32* dic_size; 214 NJ_UINT8* dic_type; 215 NJ_UINT8** dic_data; 216 NJ_UINT8** con_data; 217 const char* dicLibPath; 218 NJ_INT16 result; 219 int i; 220 221 /* Initialize the work area */ 222 memset( work, 0x00, sizeof( NJ_JNIWORK ) ); 223 224 /* Load the dictionary library which is specified by dicLibPathJ */ 225 if( dicLibPathJ == NULL || 226 ( dicLibPath = ( *env )->GetStringUTFChars( env, dicLibPathJ, 0 ) ) == NULL ) { 227 free( work ); 228 return 0; 229 } 230 231 work->dicLibHandle = ( void* )dlopen( dicLibPath, RTLD_LAZY ); 232 ( *env )->ReleaseStringUTFChars( env, dicLibPathJ, dicLibPath ); 233 234 if( work->dicLibHandle == NULL ) { 235 free( work ); 236 return 0; 237 } 238 239 /* Retrieve data pointers of dictionary from the dictionary library, and put to internal work area */ 240 dic_size = ( NJ_UINT32* )dlsym( work->dicLibHandle, "dic_size" ); 241 dic_type = ( NJ_UINT8* )dlsym( work->dicLibHandle, "dic_type" ); 242 dic_data = ( NJ_UINT8** )dlsym( work->dicLibHandle, "dic_data" ); 243 if( dic_size == NULL || dic_type == NULL || dic_data == NULL ) { 244 dlclose( work->dicLibHandle ); 245 free( work ); 246 return 0; 247 } 248 249 for( i = 0 ; i < NJ_MAX_DIC ; i++ ) { 250 work->dicHandle[ i ] = dic_data[ i ]; 251 work->dicSize[ i ] = dic_size[ i ]; 252 work->dicType[ i ] = dic_type[ i ]; 253 } 254 255 /* Set the rule dictionary if the rule data exist */ 256 con_data = ( NJ_UINT8** )dlsym( work->dicLibHandle, "con_data" ); 257 if( con_data != NULL ) { 258 work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ] = con_data[ 0 ]; 259 } 260 261 /* Execute the initialize method to initialize the internal work area */ 262 result = njx_init( &( work->wnnClass ) ); 263 264 if( result >= 0 ) { 265 jlong jresult; 266 267 *( NJ_JNIWORK** )&jresult = work; 268 return jresult; 269 } 270 271 /* If allocating a byte array failed, free all resource, and return NULL */ 272 dlclose( work->dicLibHandle ); 273 free( work ); 274 } 275 /* If allocating the internal work area failed, return NULL */ 276 return 0; 277 } 278 279 /* 280 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 281 * Method: freeWnnWork 282 * Signature: (J)I 283 */ 284 JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_freeWnnWork 285 (JNIEnv *env, jobject obj, jlong wnnWork) 286 { 287 NJ_JNIWORK* work; 288 289 work = *( NJ_JNIWORK** )&wnnWork; 290 if( work != NULL ) { 291 /* If the internal work area was not yet released, remove that */ 292 if( work->dicLibHandle != NULL ) { 293 dlclose( work->dicLibHandle ); 294 work->dicLibHandle = NULL; 295 } 296 free( work ); 297 298 return 0; 299 } 300 301 /* freeWnnWork() is always successful even if the internal work area was already released */ 302 return 0; 303 } 304 305 /* 306 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 307 * Method: clearDictionaryParameters 308 * Signature: (J)I 309 */ 310 JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_clearDictionaryParameters 311 (JNIEnv *env, jobject obj, jlong wnnWork) 312 { 313 NJ_JNIWORK* work; 314 315 work = *( NJ_JNIWORK** )&wnnWork; 316 if( work != NULL ) { 317 int index; 318 319 /* Clear all dictionary set information structure and reset search state */ 320 for( index = 0 ; index < NJ_MAX_DIC ; index++ ) { 321 clearDictionaryStructure( &( work->dicSet.dic[ index ] ) ); 322 } 323 work->flag = NJ_JNI_FLAG_NONE; 324 325 /* Clear the cache information */ 326 memset( work->dicSet.keyword, 0x00, sizeof( work->dicSet.keyword ) ); 327 328 return 0; 329 } 330 331 /* If the internal work area was already released, return an error code */ 332 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_CLEAR_DICTIONARY_PARAMETERS, NJ_ERR_NOT_ALLOCATED); 333 } 334 335 /* 336 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 337 * Method: setDictionaryParameter 338 * Signature: (JIII)I 339 */ 340 JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_setDictionaryParameter 341 (JNIEnv *env, jobject obj, jlong wnnWork, jint index, jint base, jint high) 342 { 343 NJ_JNIWORK* work; 344 345 if( ( index < 0 || index > NJ_MAX_DIC-1 ) || 346 ( base < -1 || base > 1000 ) || 347 ( high < -1 || high > 1000 ) ) { 348 /* If a invalid parameter was specified, return an error code */ 349 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_DICTIONARY_PARAMETERS, NJ_ERR_INVALID_PARAM); 350 } 351 352 work = *( NJ_JNIWORK** )&wnnWork; 353 if( work != NULL ) { 354 /* Create the dictionary set information structure */ 355 if( base < 0 || high < 0 || base > high ) { 356 /* If -1 was specified to base or high, clear that dictionary information structure */ 357 /* If base is larger than high, clear that dictionary information structure */ 358 clearDictionaryStructure( &( work->dicSet.dic[ index ] ) ); 359 } else { 360 /* Set the dictionary informatin structure */ 361 work->dicSet.dic[ index ].type = work->dicType[ index ]; 362 work->dicSet.dic[ index ].handle = work->dicHandle[ index ]; 363 work->dicSet.dic[ index ].srhCache = &( work->srhCache[ index ] ); 364 365 work->dicSet.dic[ index ].dic_freq[ NJ_MODE_TYPE_HENKAN ].base = base; 366 work->dicSet.dic[ index ].dic_freq[ NJ_MODE_TYPE_HENKAN ].high = high; 367 } 368 369 /* Reset search state because the dicionary information was changed */ 370 work->flag = NJ_JNI_FLAG_NONE; 371 372 return 0; 373 } 374 375 /* If the internal work area was already released, return an error code */ 376 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_DICTIONARY_PARAMETERS, NJ_ERR_NOT_ALLOCATED); 377 } 378 379 /* 380 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 381 * Method: searchWord 382 * Signature: (JIILjava/lang/String;)I 383 */ 384 JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_searchWord 385 (JNIEnv *env, jobject obj, jlong wnnWork, jint operation, jint order, jstring keyString) 386 { 387 NJ_JNIWORK* work; 388 389 if( !( operation == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_SEARCH_EXACT || 390 operation == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_SEARCH_PREFIX || 391 operation == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_SEARCH_LINK ) || 392 !( order == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_ORDER_BY_FREQUENCY || 393 order == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_ORDER_BY_KEY ) || 394 keyString == NULL ) { 395 /* If a invalid parameter was specified, return an error code */ 396 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SEARCH_WORD, NJ_ERR_INVALID_PARAM); 397 } 398 399 work = *( NJ_JNIWORK** )&wnnWork; 400 if( work != NULL ) { 401 if( ( *env )->GetStringLength( env, keyString ) > NJ_MAX_LEN ) { 402 /* If too long key string was specified, return "No result is found" */ 403 work->flag &= ~NJ_JNI_FLAG_ENABLE_CURSOR; 404 work->flag &= ~NJ_JNI_FLAG_ENABLE_RESULT; 405 return 0; 406 } 407 408 if( convertStringToNjChar( env, work->keyString, keyString, NJ_MAX_LEN ) >= 0 ) { 409 jint result; 410 411 /* Set the structure for search */ 412 memset( &( work->cursor ), 0x00, sizeof( NJ_CURSOR ) ); 413 work->cursor.cond.operation = operation; 414 work->cursor.cond.mode = order; 415 work->cursor.cond.ds = &( work->dicSet ); 416 work->cursor.cond.yomi = work->keyString; 417 work->cursor.cond.charset = &( work->approxSet ); 418 419 /* If the link search feature is specified, set the predict search information to structure */ 420 if( operation == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_SEARCH_LINK ) { 421 work->cursor.cond.yomi = work->previousStroke; 422 work->cursor.cond.kanji = work->previousCandidate; 423 } 424 425 /* Search a specified word */ 426 memcpy( &( work->wnnClass.dic_set ), &( work->dicSet ), sizeof( NJ_DIC_SET ) ); 427 result = ( jint )njx_search_word( &( work->wnnClass ), &( work->cursor ) ); 428 429 /* If a result is found, enable getNextWord method */ 430 if( result == 1 ) { 431 work->flag |= NJ_JNI_FLAG_ENABLE_CURSOR; 432 } else { 433 work->flag &= ~NJ_JNI_FLAG_ENABLE_CURSOR; 434 } 435 work->flag &= ~NJ_JNI_FLAG_ENABLE_RESULT; 436 437 return result; 438 } 439 /* If converting the string failed, return an error code */ 440 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SEARCH_WORD, NJ_ERR_INTERNAL); 441 } 442 443 /* If the internal work area was already released, return an error code */ 444 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SEARCH_WORD, NJ_ERR_NOT_ALLOCATED); 445 } 446 447 /* 448 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 449 * Method: getNextWord 450 * Signature: (JI)I 451 */ 452 JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getNextWord 453 (JNIEnv *env, jclass obj, jlong wnnWork, jint length) 454 { 455 NJ_JNIWORK* work; 456 457 work = *( NJ_JNIWORK** )&wnnWork; 458 if( work != NULL ) { 459 if( work->flag & NJ_JNI_FLAG_ENABLE_CURSOR ) { 460 jint result; 461 462 /* Get a specified word and search a next word */ 463 if( length <= 0 ) { 464 result = ( jint )njx_get_word( &( work->wnnClass ), &( work->cursor ), &( work->result ) ); 465 } else { 466 do { 467 result = ( jint )njx_get_word( &( work->wnnClass ), &( work->cursor ), &( work->result ) ); 468 if( length == ( NJ_GET_YLEN_FROM_STEM( &( work->result.word ) ) + NJ_GET_YLEN_FROM_FZK( &( work->result.word ) ) ) ) { 469 break; 470 } 471 } while( result > 0 ); 472 } 473 474 /* If a result is found, enable getStroke, getCandidate, getFrequency methods */ 475 if( result > 0 ) { 476 work->flag |= NJ_JNI_FLAG_ENABLE_RESULT; 477 } else { 478 work->flag &= ~NJ_JNI_FLAG_ENABLE_RESULT; 479 } 480 return result; 481 } else { 482 /* When njx_search_word() was not yet called, return "No result is found" */ 483 return 0; 484 } 485 } 486 487 /* If the internal work area was already released, return an error code */ 488 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_GET_WORD, NJ_ERR_NOT_ALLOCATED); 489 } 490 491 /* 492 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 493 * Method: getStroke 494 * Signature: (J)Ljava/lang/String; 495 */ 496 JNIEXPORT jstring JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getStroke 497 (JNIEnv *env, jobject obj, jlong wnnWork) 498 { 499 NJ_JNIWORK* work; 500 501 work = *( NJ_JNIWORK** )&wnnWork; 502 if( work != NULL ) { 503 jstring str; 504 505 if( work->flag & NJ_JNI_FLAG_ENABLE_RESULT ) { 506 NJ_CHAR stroke[ NJ_MAX_LEN + NJ_TERM_LEN ]; 507 508 if( njx_get_stroke( &( work->wnnClass ), &( work->result ), stroke, sizeof( NJ_CHAR ) * ( NJ_MAX_LEN + NJ_TERM_LEN ) ) >= 0 && 509 convertNjCharToString( env, &str, stroke, NJ_MAX_LEN ) >= 0 ) { 510 return str; 511 } 512 } else { 513 /* When njx_get_word() was not yet called, return "No result is found" */ 514 if( convertNjCharToString( env, &str, ( NJ_CHAR* )"\x00\x00", NJ_MAX_LEN ) >= 0 ) { 515 return str; 516 } 517 } 518 } 519 520 /* If the internal work area was already released, return an error status */ 521 return NULL; 522 } 523 524 /* 525 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 526 * Method: getCandidate 527 * Signature: (J)Ljava/lang/String; 528 */ 529 JNIEXPORT jstring JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getCandidate 530 (JNIEnv *env, jobject obj, jlong wnnWork) 531 { 532 NJ_JNIWORK* work; 533 534 work = *( NJ_JNIWORK** )&wnnWork; 535 if( work != NULL ) { 536 jstring str; 537 538 if( work->flag & NJ_JNI_FLAG_ENABLE_RESULT ) { 539 NJ_CHAR candidate[ NJ_MAX_LEN + NJ_TERM_LEN ]; 540 541 if( njx_get_candidate( &( work->wnnClass ), &( work->result ), candidate, sizeof( NJ_CHAR ) * ( NJ_MAX_RESULT_LEN + NJ_TERM_LEN ) ) >= 0 && 542 convertNjCharToString( env, &str, candidate, NJ_MAX_RESULT_LEN ) >= 0 ) { 543 return str; 544 } 545 } else { 546 /* When njx_get_word() was not yet called, return "No result is found" */ 547 if( convertNjCharToString( env, &str, ( NJ_CHAR* )"\x00\x00", NJ_MAX_RESULT_LEN ) >= 0 ) { 548 return str; 549 } 550 } 551 } 552 553 /* If the internal work area was already released, return an error status */ 554 return NULL; 555 } 556 557 /* 558 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 559 * Method: getFrequency 560 * Signature: (J)I 561 */ 562 JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getFrequency 563 (JNIEnv *env, jobject obj, jlong wnnWork) 564 { 565 NJ_JNIWORK* work; 566 567 work = *( NJ_JNIWORK** )&wnnWork; 568 if( work != NULL ) { 569 if( work->flag & NJ_JNI_FLAG_ENABLE_RESULT ) { 570 return ( jint )( work->result.word.stem.hindo ); 571 } else { 572 /* When njx_get_word() was not yet called, return "No result is found" */ 573 return 0; 574 } 575 } 576 577 /* If the internal work area was already released, return an error code */ 578 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_GET_FREQUENCY, NJ_ERR_NOT_ALLOCATED); 579 } 580 581 /* 582 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 583 * Method: clearApproxPatterns 584 * Signature: (J)V 585 */ 586 JNIEXPORT void JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_clearApproxPatterns 587 (JNIEnv *env, jobject obj, jlong wnnWork) 588 { 589 NJ_JNIWORK* work; 590 591 work = *( NJ_JNIWORK** )&wnnWork; 592 if( work != NULL ) { 593 int i; 594 595 /* Clear state */ 596 work->flag = NJ_JNI_FLAG_NONE; 597 598 /* Clear approximate patterns */ 599 work->approxSet.charset_count = 0; 600 for( i = 0 ; i < NJ_MAX_CHARSET ; i++ ) { 601 work->approxSet.from[ i ] = NULL; 602 work->approxSet.to[ i ] = NULL; 603 } 604 605 /* Clear the cache information */ 606 memset( work->dicSet.keyword, 0x00, sizeof( work->dicSet.keyword ) ); 607 } 608 } 609 610 /* 611 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 612 * Method: setApproxPattern 613 * Signature: (JLjava/lang/String;Ljava/lang/String;)I 614 */ 615 JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_setApproxPattern__JLjava_lang_String_2Ljava_lang_String_2 616 (JNIEnv *env, jobject obj, jlong wnnWork, jstring srcJ, jstring dstJ) 617 { 618 NJ_JNIWORK* work; 619 620 if( srcJ == NULL || ( *env )->GetStringLength( env, srcJ ) == 0 || ( *env )->GetStringLength( env, srcJ ) > 1 || 621 dstJ == NULL || ( *env )->GetStringLength( env, dstJ ) == 0 || ( *env )->GetStringLength( env, dstJ ) > 3 ) { 622 /* If a invalid parameter was specified, return an error code */ 623 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_APPROX_PATTERN, NJ_ERR_INVALID_PARAM); 624 } 625 626 work = *( NJ_JNIWORK** )&wnnWork; 627 if( work != NULL ) { 628 if( work->approxSet.charset_count < NJ_MAX_CHARSET ) { 629 NJ_CHAR* from; 630 NJ_CHAR* to; 631 632 /* Set pointers of string to store approximate informations */ 633 from = work->approxStr + NJ_APPROXSTORE_SIZE * work->approxSet.charset_count; 634 to = work->approxStr + NJ_APPROXSTORE_SIZE * work->approxSet.charset_count + NJ_MAX_CHARSET_FROM_LEN + NJ_TERM_LEN; 635 work->approxSet.from[ work->approxSet.charset_count ] = from; 636 work->approxSet.to[ work->approxSet.charset_count ] = to; 637 638 /* Convert approximate informations to internal format */ 639 if( convertStringToNjChar( env, from, srcJ, NJ_MAX_CHARSET_FROM_LEN ) >= 0 && 640 convertStringToNjChar( env, to, dstJ, NJ_MAX_CHARSET_TO_LEN ) >= 0 ) { 641 work->approxSet.charset_count++; 642 643 /* Reset search state because the seach condition was changed */ 644 work->flag = NJ_JNI_FLAG_NONE; 645 646 return 0; 647 } 648 649 /* If converting informations failed, reset pointers, and return an error code */ 650 work->approxSet.from[ work->approxSet.charset_count ] = NULL; 651 work->approxSet.to[ work->approxSet.charset_count ] = NULL; 652 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_APPROX_PATTERN, NJ_ERR_INTERNAL); 653 } 654 /* If the approx pattern registration area was full, return an error code */ 655 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_APPROX_PATTERN, NJ_ERR_APPROX_PATTERN_IS_FULL); 656 } 657 658 /* If the internal work area was already released, return an error code */ 659 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_APPROX_PATTERN, NJ_ERR_NOT_ALLOCATED); 660 } 661 662 /* 663 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 664 * Method: setApproxPattern 665 * Signature: (JI)I 666 */ 667 JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_setApproxPattern__JI 668 (JNIEnv *env, jclass obj, jlong wnnWork, jint approxPattern) 669 { 670 NJ_JNIWORK *work; 671 672 if( !( approxPattern == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_APPROX_PATTERN_EN_TOUPPER || 673 approxPattern == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_APPROX_PATTERN_EN_TOLOWER || 674 approxPattern == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_APPROX_PATTERN_EN_QWERTY_NEAR || 675 approxPattern == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_APPROX_PATTERN_EN_QWERTY_NEAR_UPPER || 676 approxPattern == jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_APPROX_PATTERN_JAJP_12KEY_NORMAL ) ) { 677 /* If a invalid parameter was specified, return an error code */ 678 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_APPROX_PATTERN, NJ_ERR_INVALID_PARAM); 679 } 680 681 work = *( NJ_JNIWORK** )&wnnWork; 682 if( work != NULL ) { 683 const PREDEF_APPROX_PATTERN* pattern; 684 685 pattern = predefinedApproxPatterns[ approxPattern ]; 686 if( work->approxSet.charset_count + pattern->size <= NJ_MAX_CHARSET ) { 687 int i; 688 689 for( i = 0 ; i < pattern->size ; i++ ) { 690 NJ_CHAR* from; 691 NJ_CHAR* to; 692 693 /* Set pointers of string to store approximate informations */ 694 from = work->approxStr + NJ_APPROXSTORE_SIZE * ( work->approxSet.charset_count + i ); 695 to = work->approxStr + NJ_APPROXSTORE_SIZE * ( work->approxSet.charset_count + i ) + NJ_MAX_CHARSET_FROM_LEN + NJ_TERM_LEN; 696 work->approxSet.from[ work->approxSet.charset_count + i ] = from; 697 work->approxSet.to[ work->approxSet.charset_count + i ] = to; 698 699 /* Set approximate pattern */ 700 from[ 0 ] = convertUTFCharToNjChar( pattern->from + i * 2 ); /* "2" means the size of UTF-16BE */ 701 from[ 1 ] = 0x0000; 702 703 to[ 0 ] = convertUTFCharToNjChar( pattern->to + i * 2 ); /* "2" means the size of UTF-16BE */ 704 to[ 1 ] = 0x0000; 705 } 706 work->approxSet.charset_count += pattern->size; 707 708 /* Reset search state because the seach condition was changed */ 709 work->flag = NJ_JNI_FLAG_NONE; 710 711 return 0; 712 } 713 /* If the approx pattern registration area was full, return an error code */ 714 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_APPROX_PATTERN, NJ_ERR_APPROX_PATTERN_IS_FULL); 715 } 716 717 /* If the internal work area was already released, return an error code */ 718 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_APPROX_PATTERN, NJ_ERR_NOT_ALLOCATED); 719 } 720 721 /* 722 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 723 * Method: getLeftPartOfSpeech 724 * Signature: (J)I 725 */ 726 JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getLeftPartOfSpeech 727 (JNIEnv *env, jclass obj, jlong wnnWork) 728 { 729 NJ_JNIWORK* work; 730 731 work = *( NJ_JNIWORK** )&wnnWork; 732 if( work != NULL ) { 733 return NJ_GET_FPOS_FROM_STEM( &( work->result.word ) ); 734 } 735 736 /* If the internal work area was already released, return an error code */ 737 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_GET_LEFT_PART_OF_SPEECH, NJ_ERR_NOT_ALLOCATED); 738 } 739 740 /* 741 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 742 * Method: getRightPartOfSpeech 743 * Signature: (J)I 744 */ 745 JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getRightPartOfSpeech 746 (JNIEnv *env, jclass obj, jlong wnnWork) 747 { 748 NJ_JNIWORK* work; 749 750 work = *( NJ_JNIWORK** )&wnnWork; 751 if( work != NULL ) { 752 return NJ_GET_BPOS_FROM_STEM( &( work->result.word ) ); 753 } 754 755 /* If the internal work area was already released, return an error code */ 756 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_GET_RIGHT_PART_OF_SPEECH, NJ_ERR_NOT_ALLOCATED); 757 } 758 759 /* 760 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 761 * Method: clearResult 762 * Signature: (J)V 763 */ 764 JNIEXPORT void JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_clearResult 765 (JNIEnv *env, jclass obj, jlong wnnWork) 766 { 767 NJ_JNIWORK* work; 768 769 work = *( NJ_JNIWORK** )&wnnWork; 770 if( work != NULL ) { 771 /* Clear the current word information */ 772 memset( &( work->result ), 0x00, sizeof( NJ_RESULT ) ); 773 memset( &( work->previousStroke ), 0x00, sizeof( work->previousStroke ) ); 774 memset( &( work->previousCandidate ), 0x00, sizeof( work->previousCandidate ) ); 775 } 776 777 /* In this method, No error reports. */ 778 } 779 780 /* 781 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 782 * Method: setLeftPartOfSpeech 783 * Signature: (JI)I 784 */ 785 JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_setLeftPartOfSpeech 786 (JNIEnv *env, jclass obj, jlong wnnWork, jint leftPartOfSpeech) 787 { 788 NJ_JNIWORK* work; 789 790 work = *( NJ_JNIWORK** )&wnnWork; 791 if( work != NULL ) { 792 NJ_UINT16 lcount = 0, rcount = 0; 793 794 if( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ] == NULL ) { 795 /* No rule dictionary was set */ 796 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_LEFT_PART_OF_SPEECH, NJ_ERR_NO_RULEDIC); 797 } 798 799 njd_r_get_count( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ], &lcount, &rcount ); 800 801 if( leftPartOfSpeech < 1 || leftPartOfSpeech > lcount ) { 802 /* If a invalid parameter was specified, return an error code */ 803 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_LEFT_PART_OF_SPEECH, NJ_ERR_INVALID_PARAM); 804 } 805 806 NJ_SET_FPOS_TO_STEM( &( work->result.word ), leftPartOfSpeech ); 807 return 0; 808 } 809 810 /* If the internal work area was already released, return an error code */ 811 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_LEFT_PART_OF_SPEECH, NJ_ERR_NOT_ALLOCATED); 812 } 813 814 /* 815 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 816 * Method: setRightPartOfSpeech 817 * Signature: (JI)I 818 */ 819 JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_setRightPartOfSpeech 820 (JNIEnv *env, jclass obj, jlong wnnWork, jint rightPartOfSpeech) 821 { 822 NJ_JNIWORK* work; 823 824 work = *( NJ_JNIWORK** )&wnnWork; 825 if( work != NULL ) { 826 NJ_UINT16 lcount = 0, rcount = 0; 827 828 if( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ] == NULL ) { 829 /* No rule dictionary was set */ 830 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_RIGHT_PART_OF_SPEECH, NJ_ERR_NO_RULEDIC); 831 } 832 833 njd_r_get_count( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ], &lcount, &rcount ); 834 835 if( rightPartOfSpeech < 1 || rightPartOfSpeech > rcount ) { 836 /* If a invalid parameter was specified, return an error code */ 837 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_RIGHT_PART_OF_SPEECH, NJ_ERR_INVALID_PARAM); 838 } 839 840 NJ_SET_BPOS_TO_STEM( &( work->result.word ), rightPartOfSpeech ); 841 return 0; 842 } 843 844 /* If the internal work area was already released, return an error code */ 845 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_RIGHT_PART_OF_SPEECH, NJ_ERR_NOT_ALLOCATED); 846 } 847 848 /* 849 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 850 * Method: setStroke 851 * Signature: (JLjava/lang/String;)I 852 */ 853 JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_setStroke 854 (JNIEnv *env, jclass obj, jlong wnnWork, jstring stroke) 855 { 856 NJ_JNIWORK* work; 857 858 if( stroke == NULL ) { 859 /* If a invalid parameter was specified, return an error code */ 860 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_STROKE, NJ_ERR_INVALID_PARAM); 861 } 862 863 work = *( NJ_JNIWORK** )&wnnWork; 864 if( work != NULL ) { 865 if( ( *env )->GetStringLength( env, stroke ) > NJ_MAX_LEN ) { 866 /* If a invalid parameter was specified, return an error code */ 867 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_STROKE, NJ_ERR_YOMI_TOO_LONG); 868 } 869 870 /* Store stroke string */ 871 if( convertStringToNjChar( env, work->previousStroke, stroke, NJ_MAX_LEN ) >= 0 ) { 872 return 0; 873 } 874 875 /* If converting the string failed, return an error code */ 876 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_STROKE, NJ_ERR_INTERNAL); 877 } 878 879 /* If the internal work area was already released, return an error code */ 880 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_STROKE, NJ_ERR_NOT_ALLOCATED); 881 } 882 883 /* 884 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 885 * Method: setCandidate 886 * Signature: (JLjava/lang/String;)I 887 */ 888 JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_setCandidate 889 (JNIEnv *env, jclass obj, jlong wnnWork, jstring candidate) 890 { 891 NJ_JNIWORK* work; 892 893 if( candidate == NULL ) { 894 /* If a invalid parameter was specified, return an error code */ 895 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_CANDIDATE, NJ_ERR_INVALID_PARAM); 896 } 897 898 work = *( NJ_JNIWORK** )&wnnWork; 899 if( work != NULL ) { 900 if( ( *env )->GetStringLength( env, candidate ) > NJ_MAX_RESULT_LEN ) { 901 /* If a invalid parameter was specified, return an error code */ 902 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_CANDIDATE, NJ_ERR_CANDIDATE_TOO_LONG); 903 } 904 905 /* Store candidate string */ 906 if( convertStringToNjChar( env, work->previousCandidate, candidate, NJ_MAX_RESULT_LEN ) >= 0 ) { 907 return 0; 908 } 909 910 /* If converting the string failed, return an error code */ 911 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_CANDIDATE, NJ_ERR_INTERNAL); 912 } 913 914 /* If the internal work area was already released, return an error code */ 915 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SET_CANDIDATE, NJ_ERR_NOT_ALLOCATED); 916 } 917 918 /* 919 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 920 * Method: selectWord 921 * Signature: (J)I 922 */ 923 JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_selectWord 924 (JNIEnv *env, jclass obj, jlong wnnWork) 925 { 926 NJ_JNIWORK* work; 927 928 work = *( NJ_JNIWORK** )&wnnWork; 929 if( work != NULL ) { 930 /* Put the previous word information to engine */ 931 memcpy( &( work->wnnClass.dic_set ), &( work->dicSet ), sizeof( NJ_DIC_SET ) ); 932 return ( jint )njx_select( &( work->wnnClass ), &( work->result ) ); 933 } 934 935 /* If the internal work area was already released, return an error code */ 936 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_SELECT_WORD, NJ_ERR_NOT_ALLOCATED); 937 } 938 939 /* 940 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 941 * Method: getLeftPartOfSpeechSpecifiedType 942 * Signature: (JI)I 943 */ 944 JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getLeftPartOfSpeechSpecifiedType 945 (JNIEnv *env, jclass obj, jlong wnnWork, jint type) 946 { 947 NJ_JNIWORK* work; 948 949 work = *( NJ_JNIWORK** )&wnnWork; 950 if( work != NULL ) { 951 switch( type ) { 952 case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_V1: 953 type = NJ_HINSI_V1_F; 954 break; 955 case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_V2: 956 type = NJ_HINSI_V2_F; 957 break; 958 case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_V3: 959 type = NJ_HINSI_V3_F; 960 break; 961 case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_BUNTOU: 962 /* No part of speech is defined at this type */ 963 return 0; 964 case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_TANKANJI: 965 type = NJ_HINSI_TANKANJI_F; 966 break; 967 case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_SUUJI: 968 /* No part of speech is defined at this type */ 969 return 0; 970 case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_MEISI: 971 type = NJ_HINSI_MEISI_F; 972 break; 973 case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_JINMEI: 974 type = NJ_HINSI_JINMEI_F; 975 break; 976 case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_CHIMEI: 977 type = NJ_HINSI_CHIMEI_F; 978 break; 979 case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_KIGOU: 980 type = NJ_HINSI_KIGOU_F; 981 break; 982 default: 983 /* If a invalid parameter was specified, return an error code */ 984 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_GET_LEFT_PART_OF_SPEECH_SPECIFIED_TYPE, NJ_ERR_INVALID_PARAM); 985 } 986 return ( jint )njd_r_get_hinsi( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ], type ); 987 } 988 989 /* If the internal work area was already released, return an error code */ 990 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_GET_LEFT_PART_OF_SPEECH_SPECIFIED_TYPE, NJ_ERR_NOT_ALLOCATED); 991 } 992 993 /* 994 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 995 * Method: getRightPartOfSpeechSpecifiedType 996 * Signature: (JI)I 997 */ 998 JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getRightPartOfSpeechSpecifiedType 999 (JNIEnv *env, jclass obj, jlong wnnWork, jint type) 1000 { 1001 NJ_JNIWORK* work; 1002 1003 work = *( NJ_JNIWORK** )&wnnWork; 1004 if( work != NULL ) { 1005 switch( type ) { 1006 case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_V1: 1007 /* No part of speech is defined at this type */ 1008 return 0; 1009 case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_V2: 1010 /* No part of speech is defined at this type */ 1011 return 0; 1012 case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_V3: 1013 /* No part of speech is defined at this type */ 1014 return 0; 1015 case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_BUNTOU: 1016 type = NJ_HINSI_BUNTOU_B; 1017 break; 1018 case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_TANKANJI: 1019 type = NJ_HINSI_TANKANJI_B; 1020 break; 1021 case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_SUUJI: 1022 type = NJ_HINSI_SUUJI_B; 1023 break; 1024 case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_MEISI: 1025 type = NJ_HINSI_MEISI_B; 1026 break; 1027 case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_JINMEI: 1028 type = NJ_HINSI_JINMEI_B; 1029 break; 1030 case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_CHIMEI: 1031 type = NJ_HINSI_CHIMEI_B; 1032 break; 1033 case jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_POS_TYPE_KIGOU: 1034 type = NJ_HINSI_KIGOU_B; 1035 break; 1036 default: 1037 /* If a invalid parameter was specified, return an error code */ 1038 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_GET_LEFT_PART_OF_SPEECH_SPECIFIED_TYPE, NJ_ERR_INVALID_PARAM); 1039 } 1040 return ( jint )njd_r_get_hinsi( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ], type ); 1041 } 1042 1043 /* If the internal work area was already released, return an error code */ 1044 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_GET_RIGHT_PART_OF_SPEECH_SPECIFIED_TYPE, NJ_ERR_NOT_ALLOCATED); 1045 } 1046 1047 /* 1048 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 1049 * Method: getConnectArray 1050 * Signature: (JI)[B 1051 */ 1052 JNIEXPORT jbyteArray JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getConnectArray 1053 (JNIEnv *env, jclass obj, jlong wnnWork, jint leftPartOfSpeech) 1054 { 1055 NJ_JNIWORK* work; 1056 1057 work = *( NJ_JNIWORK** )&wnnWork; 1058 if( work != NULL ) { 1059 NJ_UINT16 lcount = 0, rcount = 0; 1060 jbyteArray resultJ; 1061 1062 if( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ] == NULL ) { 1063 /* No rule dictionary was set */ 1064 return NULL; 1065 } 1066 1067 njd_r_get_count( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ], &lcount, &rcount ); 1068 1069 if( leftPartOfSpeech < 0 || leftPartOfSpeech > lcount ) { 1070 /* Invalid POS is specified */ 1071 return NULL; 1072 } 1073 1074 /* 1-origin */ 1075 resultJ = ( *env )->NewByteArray( env, rcount + 1 ); 1076 1077 if( resultJ != NULL ) { 1078 jbyte *result; 1079 result = ( *env )->GetByteArrayElements( env, resultJ, NULL ); 1080 1081 if( result != NULL ) { 1082 int i; 1083 NJ_UINT8* connect; 1084 1085 if( leftPartOfSpeech == 0 ) { 1086 for( i = 0 ; i < rcount + 1 ; i++ ) { 1087 result[ i ] = 0; 1088 } 1089 } else { 1090 /* Get the packed connect array */ 1091 njd_r_get_connect( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ], leftPartOfSpeech, NJ_RULE_TYPE_FTOB, &connect ); 1092 1093 /* Extract connect array from bit field */ 1094 result[ 0 ] = 0; 1095 1096 for( i = 0 ; i < rcount ; i++ ) { 1097 if( connect[ i / 8 ] & (0x80 >> (i % 8))) { 1098 result[ i + 1 ] = 1; 1099 } else { 1100 result[ i + 1 ] = 0; 1101 } 1102 } 1103 } 1104 1105 ( *env )->ReleaseByteArrayElements( env, resultJ, result, 0 ); 1106 return resultJ; 1107 } 1108 } 1109 /* If allocating the return area failed, return an error code */ 1110 return NULL; 1111 } 1112 /* If the internal work area was already released, return an error code */ 1113 return NULL; 1114 } 1115 1116 /* 1117 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 1118 * Method: getNumberOfLeftPOS 1119 * Signature: (J)I 1120 */ 1121 JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getNumberOfLeftPOS 1122 (JNIEnv *env, jclass obj, jlong wnnWork) 1123 { 1124 NJ_JNIWORK* work; 1125 1126 work = *( NJ_JNIWORK** )&wnnWork; 1127 if( work != NULL ) { 1128 if( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ] == NULL ) { 1129 /* No rule dictionary was set */ 1130 return 0; 1131 } else { 1132 NJ_UINT16 lcount = 0, rcount = 0; 1133 1134 njd_r_get_count( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ], &lcount, &rcount ); 1135 return lcount; 1136 } 1137 } 1138 1139 /* If the internal work area was already released, return an error code */ 1140 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_GET_NUMBER_OF_LEFT_POS, NJ_ERR_NOT_ALLOCATED); 1141 } 1142 1143 /* 1144 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 1145 * Method: getNumberOfRightPOS 1146 * Signature: (J)I 1147 */ 1148 JNIEXPORT jint JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getNumberOfRightPOS 1149 (JNIEnv *env, jclass obj, jlong wnnWork) 1150 { 1151 NJ_JNIWORK* work; 1152 1153 work = *( NJ_JNIWORK** )&wnnWork; 1154 if( work != NULL ) { 1155 if( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ] == NULL ) { 1156 /* No rule dictionary was set */ 1157 return 0; 1158 } else { 1159 NJ_UINT16 lcount = 0, rcount = 0; 1160 1161 njd_r_get_count( work->dicSet.rHandle[ NJ_MODE_TYPE_HENKAN ], &lcount, &rcount ); 1162 return rcount; 1163 } 1164 } 1165 1166 /* If the internal work area was already released, return an error code */ 1167 return NJ_SET_ERR_VAL(NJ_FUNC_JNI_GET_NUMBER_OF_RIGHT_POS, NJ_ERR_NOT_ALLOCATED); 1168 } 1169 1170 /* 1171 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 1172 * Method: getApproxPattern 1173 * Signature: (JLjava/lang/String;)[Ljava/lang/String; 1174 */ 1175 JNIEXPORT jobjectArray JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getApproxPattern 1176 (JNIEnv *env, jclass obj, jlong wnnWork, jstring srcJ) 1177 { 1178 NJ_JNIWORK* work; 1179 1180 if( srcJ == NULL || ( *env )->GetStringLength( env, srcJ ) == 0 || ( *env )->GetStringLength( env, srcJ ) > 1 ) { 1181 /* If a invalid parameter was specified, return an error code */ 1182 return NULL; 1183 } 1184 1185 work = *( NJ_JNIWORK** )&wnnWork; 1186 if( work != NULL ) { 1187 int i, outIndex, outCount; 1188 NJ_CHAR from[ NJ_MAX_CHARSET_FROM_LEN + NJ_TERM_LEN ]; 1189 1190 if( convertStringToNjChar( env, from, srcJ, NJ_MAX_CHARSET_FROM_LEN ) >= 0 ) { 1191 outCount = 0; 1192 for( i = 0 ; i < work->approxSet.charset_count ; i++ ) { 1193 if( nj_strcmp( from, work->approxSet.from[ i ] ) == 0 ) { 1194 outCount++; 1195 } 1196 } 1197 1198 jclass strC = ( *env )->FindClass( env, "java/lang/String" ); 1199 1200 if( strC != NULL ) { 1201 jobjectArray retJ = ( *env )->NewObjectArray( env, outCount, strC, NULL ); 1202 1203 if( retJ != NULL ) { 1204 for( i = outIndex = 0 ; i < work->approxSet.charset_count ; i++ ) { 1205 if( nj_strcmp( from, work->approxSet.from[ i ] ) == 0 ) { 1206 jstring dstJ; 1207 1208 if( convertNjCharToString( env, &dstJ, work->approxSet.to[ i ], NJ_MAX_CHARSET_TO_LEN ) < 0 ) { 1209 return NULL; 1210 } 1211 1212 ( *env )->SetObjectArrayElement( env, retJ, outIndex++, dstJ ); 1213 } 1214 1215 } 1216 return retJ; 1217 } 1218 } 1219 } 1220 /* If the internal error occured, return an error code */ 1221 return NULL; 1222 } 1223 1224 /* If the internal work area was already released, return an error code */ 1225 return NULL; 1226 } 1227 1228 /* 1229 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 1230 * Method: createBindArray 1231 * Signature: (JLjava/lang/String;II)[Ljava/lang/String; 1232 */ 1233 JNIEXPORT jobjectArray JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_createBindArray 1234 (JNIEnv *env, jclass obj, jlong wnnWork, jstring keyStringJ, jint maxBindsOfQuery, jint maxPatternOfApprox) 1235 { 1236 NJ_JNIWORK* work; 1237 1238 if( keyStringJ == NULL ) { 1239 /* If a invalid parameter was specified, return an error code */ 1240 return NULL; 1241 } 1242 1243 work = *( NJ_JNIWORK** )&wnnWork; 1244 if( work != NULL ) { 1245 /* create the string array for result */ 1246 jclass strC = ( *env )->FindClass( env, "java/lang/String" ); 1247 1248 if( strC != NULL ) { 1249 jobjectArray retJ = ( *env )->NewObjectArray( env, maxBindsOfQuery * (maxPatternOfApprox+1), strC, NULL ); 1250 1251 if( retJ != NULL ) { 1252 NJ_CHAR keyString[ NJ_MAX_LEN + NJ_TERM_LEN ]; 1253 1254 if( convertStringToNjChar( env, keyString, keyStringJ, NJ_MAX_LEN ) >= 0 ) { 1255 int queryLen, outIndex, approxPattern; 1256 NJ_CHAR baseStr[ NJ_MAX_LEN + NJ_MAX_CHARSET_TO_LEN + NJ_TERM_LEN ]; 1257 1258 outIndex = 0; 1259 baseStr[ 0 ] = NJ_CHAR_NUL; 1260 1261 for( queryLen = 0 ; queryLen < maxBindsOfQuery && keyString[ queryLen ] != NJ_CHAR_NUL ; queryLen++ ) { 1262 int i; 1263 1264 for( i = -1, approxPattern = -1 ; i < work->approxSet.charset_count ; i++ ) { 1265 if( i == -1 || keyString[ queryLen ] == work->approxSet.from[ i ][ 0 ] ) { 1266 int tailOffset = 0; 1267 1268 if( i == -1 ) { 1269 if( *( ( NJ_UINT8* )( &keyString[ queryLen ] ) + 0 ) == 0x00 && 1270 ( *( ( NJ_UINT8* )( &keyString[ queryLen ] ) + 1 ) == 0x25 || /* '%' */ 1271 *( ( NJ_UINT8* )( &keyString[ queryLen ] ) + 1 ) == 0x5c || /* '\' */ 1272 *( ( NJ_UINT8* )( &keyString[ queryLen ] ) + 1 ) == 0x5f ) ) { /* '_' */ 1273 *( ( NJ_UINT8* )( &baseStr[ queryLen + 0 ] ) + 0 ) = 0x00; 1274 *( ( NJ_UINT8* )( &baseStr[ queryLen + 0 ] ) + 1 ) = 0x5c; /* '\' */ 1275 baseStr[ queryLen + 1 ] = keyString[ queryLen ]; 1276 tailOffset = 2; 1277 } else { 1278 baseStr[ queryLen + 0 ] = keyString[ queryLen ]; 1279 tailOffset = 1; 1280 } 1281 } else { 1282 nj_strcpy( &baseStr[ queryLen ], work->approxSet.to[ i ] ); 1283 tailOffset = nj_strlen( work->approxSet.to[ i ] ); 1284 } 1285 1286 *( ( NJ_UINT8* )( &baseStr[ queryLen + tailOffset ] ) + 0 ) = 0x00; 1287 *( ( NJ_UINT8* )( &baseStr[ queryLen + tailOffset ] ) + 1 ) = 0x25; /* '%' */ 1288 baseStr[ queryLen + tailOffset + 1 ] = NJ_CHAR_NUL; 1289 1290 jstring dstJ; 1291 if( convertNjCharToString( env, &dstJ, baseStr, NJ_MAX_LEN ) < 0 ) { 1292 return NULL; 1293 } 1294 1295 ( *env )->SetObjectArrayElement( env, retJ, outIndex++, dstJ ); 1296 approxPattern++; 1297 } 1298 } 1299 for( ; approxPattern < maxPatternOfApprox ; approxPattern++ ) { 1300 jstring dstJ = ( *env )->NewStringUTF( env, "" ); 1301 if( dstJ == NULL ) { 1302 return NULL; 1303 } 1304 ( *env )->SetObjectArrayElement( env, retJ, outIndex++, dstJ ); 1305 } 1306 1307 *( ( NJ_UINT8* )( &baseStr[ queryLen ] ) + 0 ) = 0x00; 1308 *( ( NJ_UINT8* )( &baseStr[ queryLen ] ) + 1 ) = 0x5f; /* '_' */ 1309 baseStr[ queryLen + 1 ] = NJ_CHAR_NUL; 1310 } 1311 1312 for( ; queryLen < maxBindsOfQuery ; queryLen++ ) { 1313 for( approxPattern = -1 ; approxPattern < maxPatternOfApprox ; approxPattern++ ) { 1314 jstring dstJ = ( *env )->NewStringUTF( env, "%" ); 1315 if( dstJ == NULL ) { 1316 return NULL; 1317 } 1318 ( *env )->SetObjectArrayElement( env, retJ, outIndex++, dstJ ); 1319 } 1320 } 1321 1322 return retJ; 1323 } 1324 } 1325 } 1326 /* If the internal error occured, return an error code */ 1327 return NULL; 1328 } 1329 1330 /* If the internal work area was already released, return an error code */ 1331 return NULL; 1332 } 1333 1334 /* 1335 * Class: jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni 1336 * Method: createQueryStringBase 1337 * Signature: (JIILjava/lang/String;)Ljava/lang/String; 1338 */ 1339 JNIEXPORT jstring JNICALL Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_createQueryStringBase 1340 (JNIEnv *env, jclass obj, jlong wnnWork, jint maxBindsOfQuery, jint maxPatternOfApprox, jstring keyColumnNameJ) 1341 { 1342 NJ_JNIWORK* work; 1343 jstring retJ = NULL; 1344 1345 if( keyColumnNameJ == NULL ) { 1346 /* If a invalid parameter was specified, return an error code */ 1347 return NULL; 1348 } 1349 1350 work = *( NJ_JNIWORK** )&wnnWork; 1351 if( work != NULL ) { 1352 const unsigned char* keyName = ( const unsigned char* )( ( *env )->GetStringUTFChars( env, keyColumnNameJ, NULL ) ); 1353 1354 if( keyName != NULL ) { 1355 int keyLength = strlen( ( char* )keyName ); 1356 1357 char *dst = ( char* )malloc( maxBindsOfQuery * ( ( 1 + keyLength + 18 + 1 + 5 ) + 1358 ( ( 4 + keyLength + 18 ) * maxPatternOfApprox ) + 1359 1 ) ); 1360 if( dst != NULL ) { 1361 int queryLen, dstPtr; 1362 1363 for( queryLen = dstPtr = 0 ; queryLen < maxBindsOfQuery ; queryLen++ ) { 1364 int approxPattern; 1365 1366 strcpy( &dst[ dstPtr ], "(" ); 1367 strcpy( &dst[ dstPtr + 1 ], ( char* )keyName ); 1368 strcpy( &dst[ dstPtr + 1 + keyLength ], " like ? escape '\x5c'" ); 1369 dstPtr += 1 + keyLength + 18; 1370 1371 for( approxPattern = 0 ; approxPattern < maxPatternOfApprox ; approxPattern++ ) { 1372 strcpy( &dst[ dstPtr ], " or " ); 1373 strcpy( &dst[ dstPtr + 4 ], ( char* )keyName ); 1374 strcpy( &dst[ dstPtr + 4 + keyLength ], " like ? escape '\x5c'" ); 1375 dstPtr += 4 + keyLength + 18; 1376 } 1377 strcpy( &dst[ dstPtr ], ")" ); 1378 dstPtr++; 1379 1380 if( queryLen != maxBindsOfQuery-1 ) { 1381 strcpy( &dst[ dstPtr ], " and " ); 1382 dstPtr += 5; 1383 } 1384 } 1385 1386 dst[ dstPtr ] = '\0'; 1387 retJ = ( *env )->NewStringUTF( env, dst ); 1388 1389 free( dst ); 1390 } 1391 1392 ( *env )->ReleaseStringUTFChars( env, keyColumnNameJ, ( const char* )keyName ); 1393 } 1394 } 1395 return retJ; 1396 } 1397 1398