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