1 /*
2 * Copyright (C) 2008-2012 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 */
clearDictionaryStructure(NJ_DIC_INFO * dicInfo)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
convertUTFCharToNjChar(NJ_UINT8 * src)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
convertStringToNjChar(JNIEnv * env,NJ_CHAR * dst,jstring srcJ,int maxChars)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
convertNjCharToString(JNIEnv * env,jstring * dstJ,NJ_CHAR * src,int maxChars)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_createWnnWork(JNIEnv * env,jobject obj,jstring dicLibPathJ)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_freeWnnWork(JNIEnv * env,jobject obj,jlong wnnWork)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_clearDictionaryParameters(JNIEnv * env,jobject obj,jlong wnnWork)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_setDictionaryParameter(JNIEnv * env,jobject obj,jlong wnnWork,jint index,jint base,jint high)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_searchWord(JNIEnv * env,jobject obj,jlong wnnWork,jint operation,jint order,jstring keyString)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getNextWord(JNIEnv * env,jclass obj,jlong wnnWork,jint length)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getStroke(JNIEnv * env,jobject obj,jlong wnnWork)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getCandidate(JNIEnv * env,jobject obj,jlong wnnWork)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getFrequency(JNIEnv * env,jobject obj,jlong wnnWork)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_clearApproxPatterns(JNIEnv * env,jobject obj,jlong wnnWork)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_setApproxPattern__JLjava_lang_String_2Ljava_lang_String_2(JNIEnv * env,jobject obj,jlong wnnWork,jstring srcJ,jstring dstJ)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_setApproxPattern__JI(JNIEnv * env,jclass obj,jlong wnnWork,jint approxPattern)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getLeftPartOfSpeech(JNIEnv * env,jclass obj,jlong wnnWork)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getRightPartOfSpeech(JNIEnv * env,jclass obj,jlong wnnWork)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_clearResult(JNIEnv * env,jclass obj,jlong wnnWork)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_setLeftPartOfSpeech(JNIEnv * env,jclass obj,jlong wnnWork,jint leftPartOfSpeech)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_setRightPartOfSpeech(JNIEnv * env,jclass obj,jlong wnnWork,jint rightPartOfSpeech)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_setStroke(JNIEnv * env,jclass obj,jlong wnnWork,jstring stroke)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_setCandidate(JNIEnv * env,jclass obj,jlong wnnWork,jstring candidate)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_selectWord(JNIEnv * env,jclass obj,jlong wnnWork)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getLeftPartOfSpeechSpecifiedType(JNIEnv * env,jclass obj,jlong wnnWork,jint type)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getRightPartOfSpeechSpecifiedType(JNIEnv * env,jclass obj,jlong wnnWork,jint type)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getConnectArray(JNIEnv * env,jclass obj,jlong wnnWork,jint leftPartOfSpeech)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getNumberOfLeftPOS(JNIEnv * env,jclass obj,jlong wnnWork)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getNumberOfRightPOS(JNIEnv * env,jclass obj,jlong wnnWork)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_getApproxPattern(JNIEnv * env,jclass obj,jlong wnnWork,jstring srcJ)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_createBindArray(JNIEnv * env,jclass obj,jlong wnnWork,jstring keyStringJ,jint maxBindsOfQuery,jint maxPatternOfApprox)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 */
Java_jp_co_omronsoft_openwnn_OpenWnnDictionaryImplJni_createQueryStringBase(JNIEnv * env,jclass obj,jlong wnnWork,jint maxBindsOfQuery,jint maxPatternOfApprox,jstring keyColumnNameJ)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