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 
17 #include "nj_lib.h"
18 #include "nj_err.h"
19 #include "nj_ext.h"
20 #include "nj_dic.h"
21 #include "njd.h"
22 #ifdef NJ_LEARN_MUHENKAN_DEBUG
23 #include <stdio.h>
24 #include <def_mojicode.h>
25 #endif
26 #ifdef NJ_AWNN22_DEBUG
27 #include <stdio.h>
28 #include <def_mojicode.h>
29 #endif
30 
31 #define QUE_TYPE_EMPTY  0
32 #define QUE_TYPE_NEXT   0
33 #define QUE_TYPE_JIRI   1
34 #define QUE_TYPE_FZK    2
35 #define POS_DATA_OFFSET  0x20
36 #define POS_LEARN_WORD   0x24
37 #define POS_MAX_WORD     0x28
38 #define POS_QUE_SIZE     0x2C
39 #define POS_NEXT_QUE     0x30
40 #define POS_WRITE_FLG    0x34
41 #define POS_INDEX_OFFSET        0x3C
42 #define POS_INDEX_OFFSET2       0x40
43 
44 #define LEARN_INDEX_TOP_ADDR(x) ((x) + (NJ_INT32_READ((x) + POS_INDEX_OFFSET)))
45 #define LEARN_INDEX_TOP_ADDR2(x) ((x) + (NJ_INT32_READ((x) + POS_INDEX_OFFSET2)))
46 #define LEARN_DATA_TOP_ADDR(x)  ((x) + (NJ_INT32_READ((x) + POS_DATA_OFFSET)))
47 
48 #define LEARN_INDEX_BOTTOM_ADDR(x) (LEARN_DATA_TOP_ADDR(x) - 1)
49 
50 #define LEARN_QUE_STRING_OFFSET 5
51 
52 #define ADDRESS_TO_POS(x,adr)   (((adr) - LEARN_DATA_TOP_ADDR(x)) / QUE_SIZE(x))
53 #define POS_TO_ADDRESS(x,pos)   (LEARN_DATA_TOP_ADDR(x) + QUE_SIZE(x) * (pos))
54 
55 #define GET_UINT16(ptr) ((((NJ_UINT16)(*(ptr))) << 8) | (*((ptr) + 1) & 0x00ff))
56 
57 #define GET_FPOS_FROM_DATA(x) ((NJ_UINT16)NJ_INT16_READ((x)+1) >> 7)
58 #define GET_YSIZE_FROM_DATA(x) ((NJ_UINT8)((NJ_UINT16)NJ_INT16_READ((x)+1) & 0x7F))
59 #define GET_BPOS_FROM_DATA(x) ((NJ_UINT16)NJ_INT16_READ((x)+3) >> 7)
60 #define GET_KSIZE_FROM_DATA(x) ((NJ_UINT8)((NJ_UINT16)NJ_INT16_READ((x)+3) & 0x7F))
61 #define GET_BPOS_FROM_EXT_DATA(x) ((NJ_UINT16)NJ_INT16_READ(x) >> 7)
62 #define GET_YSIZE_FROM_EXT_DATA(x) ((NJ_UINT8)((NJ_UINT16)NJ_INT16_READ(x) & 0x7F))
63 
64 #define SET_BPOS_AND_YSIZE(x,bpos,ysize)                                \
65     NJ_INT16_WRITE((x), ((NJ_UINT16)((bpos) << 7) | ((ysize) & 0x7F)))
66 #define SET_FPOS_AND_YSIZE(x,fpos,ysize)                                \
67     NJ_INT16_WRITE(((x)+1), ((NJ_UINT16)((fpos) << 7) | ((ysize) & 0x7F)))
68 #define SET_BPOS_AND_KSIZE(x,bpos,ksize)                                \
69     NJ_INT16_WRITE(((x)+3), ((NJ_UINT16)((bpos) << 7) | ((ksize) & 0x7F)))
70 
71 #define GET_TYPE_FROM_DATA(x) (*(x) & 0x03)
72 #define GET_UFLG_FROM_DATA(x) (*(x) >> 7)
73 #define GET_FFLG_FROM_DATA(x) ((*(x) >> 6) & 0x01)
74 #define GET_MFLG_FROM_DATA(x) (*(x) & 0x10)
75 
76 #define SET_TYPE_UFLG_FFLG(x,type,u,f)                                  \
77     (*(x) = (NJ_UINT8)(((type) & 0x03) |                                \
78                        (((u) & 0x01) << 7) | (((f) & 0x01) << 6)))
79 #define SET_TYPE_ALLFLG(x,type,u,f,m)                                   \
80     (*(x) = (NJ_UINT8)(((type) & 0x03) |                                \
81                        (((u) & 0x01) << 7) | (((f) & 0x01) << 6) | (((m) & 0x01) << 4)))
82 
83 #define RESET_FFLG(x) (*(x) &= 0xbf)
84 
85 #define STATE_COPY(to, from)                                    \
86     { ((NJ_UINT8*)(to))[0] = ((NJ_UINT8*)(from))[0];            \
87         ((NJ_UINT8*)(to))[1] = ((NJ_UINT8*)(from))[1];          \
88         ((NJ_UINT8*)(to))[2] = ((NJ_UINT8*)(from))[2];          \
89         ((NJ_UINT8*)(to))[3] = ((NJ_UINT8*)(from))[3]; }
90 
91 #define USE_QUE_NUM(que_size, str_size)    \
92     ( (((str_size) % ((que_size) - 1)) == 0)                           \
93       ? ((str_size) / ((que_size) - 1))                                \
94       : ((str_size) / ((que_size) - 1) + 1) )
95 
96 #define NEXT_QUE(que, max)  ( ((que) < ((max) - 1)) ? ((que) + 1) : 0 )
97 
98 #define PREV_QUE(que, max)  ( ((que) == 0) ? ((max) - 1) : ((que) - 1) )
99 
100 #define COPY_QUE(handle, src, dst)                                      \
101     nj_memcpy(POS_TO_ADDRESS((handle), (dst)), POS_TO_ADDRESS((handle), (src)), QUE_SIZE(handle))
102 
103 
104 #define INIT_HINDO          (-10000)
105 
106 #define LOC_CURRENT_NO_ENTRY  0xffffffffU
107 
108 
109 
110 static NJ_WQUE *get_que(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id);
111 static NJ_INT16 is_continued(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id);
112 static NJ_UINT16 search_next_que(NJ_DIC_HANDLE handle, NJ_UINT16 que_id);
113 static NJ_INT16 que_strcmp_complete_with_hyouki(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id, NJ_CHAR *yomi, NJ_UINT16 yomi_len, NJ_CHAR *hyouki, NJ_UINT8 multi_flg);
114 static NJ_CHAR  *get_string(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id, NJ_UINT8 *slen);
115 static NJ_CHAR  *get_hyouki(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id, NJ_UINT8 *slen);
116 static NJ_INT16 get_cand_by_sequential(NJ_CLASS *iwnn, NJ_SEARCH_CONDITION *cond, NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT8 search_pattern, NJ_UINT8 comp_flg);
117 static NJ_INT16 get_cand_by_evaluate(NJ_CLASS *iwnn, NJ_SEARCH_CONDITION *cond, NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT8 search_pattern);
118 static NJ_INT16 get_cand_by_evaluate2(NJ_CLASS *iwnn, NJ_SEARCH_CONDITION *cond, NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT8 search_pattern, NJ_UINT16 hIdx);
119 static NJ_INT16 search_range_by_yomi(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT8 op, NJ_CHAR *yomi, NJ_UINT16 ylen, NJ_UINT16 *from, NJ_UINT16 *to, NJ_UINT8 *forward_flag);
120 static NJ_INT16 search_range_by_yomi2(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT8 op, NJ_CHAR *yomi, NJ_UINT16 ylen, NJ_UINT16 sfrom, NJ_UINT16 sto, NJ_UINT16 *from, NJ_UINT16 *to,
121                                       NJ_UINT8 *forward_flag);
122 static NJ_INT16 search_range_by_yomi_multi(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_CHAR *yomi, NJ_UINT16 ylen, NJ_UINT16 *from, NJ_UINT16 *to);
123 static NJ_INT16 str_que_cmp(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_CHAR *yomi, NJ_UINT16 yomiLen, NJ_UINT16 que_id, NJ_UINT8 mode);
124 static NJ_WQUE *get_que_type_and_next(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id);
125 static NJ_WQUE *get_que_allHinsi(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id);
126 static NJ_WQUE *get_que_yomiLen_and_hyoukiLen(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id);
127 static NJ_INT16 continue_cnt(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id);
128 
129 static NJ_UINT8 *get_search_index_address(NJ_DIC_HANDLE handle, NJ_UINT8 search_pattern);
130 
131 static NJ_HINDO get_hindo(NJ_CLASS *iwnn, NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT8 search_pattern);
132 
133 static NJ_HINDO calculate_hindo(NJ_DIC_HANDLE handle, NJ_INT32 freq, NJ_DIC_FREQ *dic_freq, NJ_INT16 freq_max, NJ_INT16 freq_min);
134 static NJ_INT16 que_strcmp_include(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id, NJ_CHAR *yomi);
135 
136 #define GET_LEARN_MAX_WORD_COUNT(h) ((NJ_UINT16)NJ_INT32_READ((h) + POS_MAX_WORD))
137 
138 #define GET_LEARN_WORD_COUNT(h)                         \
139     ((NJ_UINT16)NJ_INT32_READ((h) + POS_LEARN_WORD))
140 #define SET_LEARN_WORD_COUNT(h, n)                      \
141     NJ_INT32_WRITE((h)+POS_LEARN_WORD, (NJ_UINT32)(n))
142 #define GET_LEARN_NEXT_WORD_POS(h)                      \
143     ((NJ_UINT16)NJ_INT32_READ((h) + POS_NEXT_QUE))
144 #define SET_LEARN_NEXT_WORD_POS(h, id)                  \
145     NJ_INT32_WRITE((h)+POS_NEXT_QUE, (NJ_UINT32)(id))
146 #define QUE_SIZE(h)     ((NJ_UINT16)NJ_INT32_READ((h) + POS_QUE_SIZE))
147 
148 #define COPY_UINT16(dst,src)    (*(NJ_UINT16 *)(dst) = *(NJ_UINT16 *)(src))
149 
get_search_index_address(NJ_DIC_HANDLE handle,NJ_UINT8 search_pattern)150 static NJ_UINT8 *get_search_index_address(NJ_DIC_HANDLE handle, NJ_UINT8 search_pattern) {
151 
152 
153 
154     return LEARN_INDEX_TOP_ADDR(handle);
155 }
156 
njd_l_search_word(NJ_CLASS * iwnn,NJ_SEARCH_CONDITION * con,NJ_SEARCH_LOCATION_SET * loctset,NJ_UINT8 comp_flg)157 NJ_INT16 njd_l_search_word(NJ_CLASS *iwnn, NJ_SEARCH_CONDITION *con,
158                            NJ_SEARCH_LOCATION_SET *loctset,
159                            NJ_UINT8 comp_flg) {
160 
161     NJ_UINT16    word_count;
162     NJ_UINT32    type;
163     NJ_DIC_INFO *pdicinfo;
164     NJ_UINT16    hIdx;
165     NJ_INT16     ret;
166 
167 
168     word_count = GET_LEARN_WORD_COUNT(loctset->loct.handle);
169     if (word_count == 0) {
170 
171         loctset->loct.status = NJ_ST_SEARCH_END_EXT;
172         return 0;
173     }
174 
175     type = NJ_GET_DIC_TYPE_EX(loctset->loct.type, loctset->loct.handle);
176 
177     if (type == NJ_DIC_TYPE_CUSTOM_INCOMPRESS) {
178         if ((con->operation == NJ_CUR_OP_COMP) ||
179             (con->operation == NJ_CUR_OP_FORE)){
180 
181             if (con->ylen > NJ_GET_MAX_YLEN(loctset->loct.handle)) {
182                 loctset->loct.status = NJ_ST_SEARCH_END_EXT;
183                 return 0;
184             }
185         }
186     }
187 
188 
189     switch (con->operation) {
190     case NJ_CUR_OP_COMP:
191         if (con->mode != NJ_CUR_MODE_FREQ) {
192 
193             loctset->loct.status = NJ_ST_SEARCH_END_EXT;
194             break;
195         }
196 
197 
198         return get_cand_by_sequential(iwnn, con, loctset, con->operation, comp_flg);
199 
200     case NJ_CUR_OP_FORE:
201 
202         if (con->mode == NJ_CUR_MODE_YOMI) {
203 
204             return get_cand_by_sequential(iwnn, con, loctset, con->operation, 0);
205         } else {
206 
207 
208             pdicinfo = con->ds->dic;
209             for (hIdx = 0; (hIdx < NJ_MAX_DIC) && (pdicinfo->handle != loctset->loct.handle); hIdx++) {
210                 pdicinfo++;
211             }
212 
213             if (hIdx == NJ_MAX_DIC) {
214 
215                 loctset->loct.status = NJ_ST_SEARCH_END;
216                 return 0;
217             }
218 
219 
220 
221             if ((con->ds->dic[hIdx].srhCache == NULL) || (con->ylen == 0) ||
222                 !(con->ds->mode & 0x0001)) {
223                 return get_cand_by_evaluate(iwnn, con, loctset, con->operation);
224             } else {
225                 ret = get_cand_by_evaluate2(iwnn, con, loctset, con->operation, hIdx);
226                 if (ret == NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_CACHE_NOT_ENOUGH)) {
227 
228                     NJ_SET_CACHEOVER_TO_SCACHE(con->ds->dic[hIdx].srhCache);
229                     ret = get_cand_by_evaluate2(iwnn, con, loctset, con->operation, hIdx);
230                 }
231                 return ret;
232             }
233         }
234 
235     case NJ_CUR_OP_LINK:
236 
237         if (NJ_GET_DIC_TYPE_EX(loctset->loct.type, loctset->loct.handle) == NJ_DIC_TYPE_USER) {
238 
239             loctset->loct.status = NJ_ST_SEARCH_END_EXT;
240             break;
241         }
242         if (con->mode != NJ_CUR_MODE_FREQ) {
243 
244             loctset->loct.status = NJ_ST_SEARCH_END_EXT;
245             break;
246         }
247 
248         if (comp_flg == 0) {
249 
250             return get_cand_by_sequential(iwnn, con, loctset, con->operation, 0);
251         } else {
252 
253             return get_cand_by_evaluate(iwnn, con, loctset, con->operation);
254         }
255 
256     default:
257         loctset->loct.status = NJ_ST_SEARCH_END_EXT;
258     }
259 
260     return 0;
261 }
262 
get_que_type_and_next(NJ_CLASS * iwnn,NJ_DIC_HANDLE handle,NJ_UINT16 que_id)263 static NJ_WQUE *get_que_type_and_next(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle,
264                                       NJ_UINT16 que_id) {
265     NJ_UINT8 *ptr;
266     NJ_WQUE *que = &(iwnn->que_tmp);
267 
268 
269     if (que_id >= GET_LEARN_MAX_WORD_COUNT(handle)) {
270         return NULL;
271     }
272 
273     ptr = POS_TO_ADDRESS(handle, que_id);
274 
275     que->type = GET_TYPE_FROM_DATA(ptr);
276     que->next_flag  = GET_FFLG_FROM_DATA(ptr);
277 
278     switch (que->type) {
279     case QUE_TYPE_EMPTY:
280     case QUE_TYPE_JIRI:
281     case QUE_TYPE_FZK:
282         return que;
283     default:
284         break;
285     }
286 #ifdef LEARN_DEBUG
287     printf("FATAL : Illegal que was gotten (que_id=%d)\n", que_id);
288 #endif
289     return NULL;
290 }
291 
get_que_yomiLen_and_hyoukiLen(NJ_CLASS * iwnn,NJ_DIC_HANDLE handle,NJ_UINT16 que_id)292 static NJ_WQUE *get_que_yomiLen_and_hyoukiLen(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle,
293                                               NJ_UINT16 que_id) {
294     NJ_UINT8 *ptr;
295     NJ_WQUE *que = &(iwnn->que_tmp);
296 
297 
298     if (que_id >= GET_LEARN_MAX_WORD_COUNT(handle)) {
299         return NULL;
300     }
301 
302     ptr = POS_TO_ADDRESS(handle, que_id);
303 
304     que->type        = GET_TYPE_FROM_DATA(ptr);
305     que->yomi_byte   = GET_YSIZE_FROM_DATA(ptr);
306     que->yomi_len    = que->yomi_byte / sizeof(NJ_CHAR);
307     que->hyouki_byte = GET_KSIZE_FROM_DATA(ptr);
308     que->hyouki_len  = que->hyouki_byte / sizeof(NJ_CHAR);
309 
310     switch (que->type) {
311     case QUE_TYPE_JIRI:
312     case QUE_TYPE_FZK:
313         return que;
314     default:
315         break;
316     }
317 #ifdef LEARN_DEBUG
318     printf("FATAL : Illegal que was gotten (que_id=%d)\n", que_id);
319 #endif
320     return NULL;
321 }
322 
get_que_allHinsi(NJ_CLASS * iwnn,NJ_DIC_HANDLE handle,NJ_UINT16 que_id)323 static NJ_WQUE *get_que_allHinsi(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle,
324                                  NJ_UINT16 que_id) {
325     NJ_UINT8 *ptr;
326     NJ_WQUE *que = &(iwnn->que_tmp);
327 
328 
329     if (que_id >= GET_LEARN_MAX_WORD_COUNT(handle)) {
330         return NULL;
331     }
332 
333     ptr = POS_TO_ADDRESS(handle, que_id);
334 
335     que->type      = GET_TYPE_FROM_DATA(ptr);
336     que->mae_hinsi = GET_FPOS_FROM_DATA(ptr);
337     que->ato_hinsi = GET_BPOS_FROM_DATA(ptr);
338 
339     switch (que->type) {
340     case QUE_TYPE_JIRI:
341     case QUE_TYPE_FZK:
342         return que;
343     default:
344         break;
345     }
346 #ifdef LEARN_DEBUG
347     printf("FATAL : Illegal que was gotten (que_id=%d)\n", que_id);
348 #endif
349     return NULL;
350 }
351 
get_que(NJ_CLASS * iwnn,NJ_DIC_HANDLE handle,NJ_UINT16 que_id)352 static NJ_WQUE *get_que(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id) {
353     NJ_UINT8 *ptr;
354     NJ_WQUE *que = &(iwnn->que_tmp);
355 
356 
357     if (que_id >= GET_LEARN_MAX_WORD_COUNT(handle)) {
358         return NULL;
359     }
360 
361     ptr = POS_TO_ADDRESS(handle, que_id);
362 
363     que->entry      = que_id;
364     que->type       = GET_TYPE_FROM_DATA(ptr);
365     que->mae_hinsi  = GET_FPOS_FROM_DATA(ptr);
366     que->ato_hinsi  = GET_BPOS_FROM_DATA(ptr);
367     que->yomi_byte  = GET_YSIZE_FROM_DATA(ptr);
368     que->yomi_len   = que->yomi_byte / sizeof(NJ_CHAR);
369     que->hyouki_byte= GET_KSIZE_FROM_DATA(ptr);
370     que->hyouki_len = que->hyouki_byte / sizeof(NJ_CHAR);
371     que->next_flag  = GET_FFLG_FROM_DATA(ptr);
372 
373     switch (que->type) {
374     case QUE_TYPE_JIRI:
375     case QUE_TYPE_FZK:
376         return que;
377     default:
378         break;
379     }
380 #ifdef LEARN_DEBUG
381     printf("FATAL : Illegal que was gotten (que_id=%d)\n", que_id);
382 #endif
383     return NULL;
384 }
385 
is_continued(NJ_CLASS * iwnn,NJ_DIC_HANDLE handle,NJ_UINT16 que_id)386 static NJ_INT16 is_continued(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id) {
387     NJ_WQUE *que;
388     NJ_UINT16 i;
389     NJ_UINT16 max, end;
390 
391 
392     max = GET_LEARN_MAX_WORD_COUNT(handle);
393     end = GET_LEARN_NEXT_WORD_POS(handle);
394 
395     for (i = 0; i < max; i++) {
396         que_id++;
397         if (que_id >= GET_LEARN_MAX_WORD_COUNT(handle)) {
398 
399             que_id = 0;
400         }
401 
402 
403         if (que_id == end) {
404 
405             return 0;
406         }
407 
408         que = get_que_type_and_next(iwnn, handle, que_id);
409 #ifdef IWNN_ERR_CHECK
410         if (iwnn->err_check_flg == 1) {
411             que = NULL;
412         }
413 #endif
414         if (que == NULL) {
415             return NJ_SET_ERR_VAL(NJ_FUNC_IS_CONTINUED, NJ_ERR_DIC_BROKEN);
416         }
417         if (que->type != QUE_TYPE_EMPTY) {
418 
419             if (que->next_flag != 0) {
420 
421                 return 1;
422             } else {
423 
424                 return 0;
425             }
426         }
427     }
428 
429 
430     return 0;
431 }
432 
continue_cnt(NJ_CLASS * iwnn,NJ_DIC_HANDLE handle,NJ_UINT16 que_id)433 static NJ_INT16 continue_cnt(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id) {
434     NJ_WQUE *que;
435     NJ_UINT16 i;
436     NJ_UINT16 max, end;
437     NJ_INT16 cnt = 0;
438 
439 
440     max = GET_LEARN_MAX_WORD_COUNT(handle);
441     end = GET_LEARN_NEXT_WORD_POS(handle);
442 
443     for (i = 0; i < max; i++) {
444         que_id++;
445         if (que_id >= max) {
446 
447             que_id = 0;
448         }
449 
450 
451         if (que_id == end) {
452 
453             return cnt;
454         }
455 
456         que = get_que_type_and_next(iwnn, handle, que_id);
457         if (que == NULL) {
458             return NJ_SET_ERR_VAL(NJ_FUNC_CONTINUE_CNT, NJ_ERR_DIC_BROKEN);
459         }
460         if (que->type != QUE_TYPE_EMPTY) {
461 
462             if (que->next_flag != 0) {
463 
464                 cnt++;
465 
466 
467                 if (cnt >= (NJD_MAX_CONNECT_CNT - 1)) {
468                     return cnt;
469                 }
470             } else {
471 
472                 return cnt;
473             }
474         }
475     }
476 
477 
478     return 0;
479 }
480 
search_next_que(NJ_DIC_HANDLE handle,NJ_UINT16 que_id)481 static NJ_UINT16 search_next_que(NJ_DIC_HANDLE handle, NJ_UINT16 que_id) {
482     NJ_UINT16 max;
483     NJ_UINT16 i;
484 
485 
486     max = GET_LEARN_MAX_WORD_COUNT(handle);
487 
488     for (i = 0; i < max; i++) {
489         que_id++;
490         if (que_id >= max) {
491 
492             que_id = 0;
493         }
494 
495         if (GET_TYPE_FROM_DATA(POS_TO_ADDRESS(handle, que_id)) != QUE_TYPE_EMPTY) {
496 
497             return que_id;
498         }
499     }
500 
501 
502     return 0;
503 }
504 
que_strcmp_complete_with_hyouki(NJ_CLASS * iwnn,NJ_DIC_HANDLE handle,NJ_UINT16 que_id,NJ_CHAR * yomi,NJ_UINT16 yomi_len,NJ_CHAR * hyouki,NJ_UINT8 multi_flg)505 static NJ_INT16 que_strcmp_complete_with_hyouki(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle,
506                                                 NJ_UINT16 que_id, NJ_CHAR *yomi, NJ_UINT16 yomi_len, NJ_CHAR *hyouki,
507                                                 NJ_UINT8 multi_flg) {
508     NJ_CHAR *str;
509     NJ_INT16 ret;
510     NJ_UINT8 slen;
511     NJ_UINT16 hyouki_len;
512     NJ_UINT16 que_yomilen, que_hyoukilen;
513     NJ_INT16 que_count = 1;
514     NJ_INT16 cnt = 0;
515 
516 
517 
518     hyouki_len = nj_strlen(hyouki);
519 
520     if (multi_flg == 0) {
521 
522         cnt = 1;
523     } else {
524 
525 
526         cnt = GET_LEARN_WORD_COUNT(handle);
527     }
528 
529     while (cnt--) {
530         str = get_string(iwnn, handle, que_id, &slen);
531         if (str == NULL) {
532             return NJ_SET_ERR_VAL(NJ_FUNC_QUE_STRCMP_COMPLETE_WITH_HYOUKI,
533                                   NJ_ERR_DIC_BROKEN);
534         }
535         que_yomilen = slen;
536 
537         ret = nj_strncmp(yomi, str, que_yomilen);
538         if (ret != 0) {
539 
540             return 0;
541         }
542 
543         str = get_hyouki(iwnn, handle, que_id, &slen);
544         if (str == NULL) {
545             return NJ_SET_ERR_VAL(NJ_FUNC_QUE_STRCMP_COMPLETE_WITH_HYOUKI,
546                                   NJ_ERR_DIC_BROKEN);
547         }
548         que_hyoukilen = slen;
549 
550         ret = nj_strncmp(hyouki, str, que_hyoukilen);
551         if (ret != 0) {
552 
553             return 0;
554         }
555 
556         if ((yomi_len == que_yomilen) &&
557             (hyouki_len == que_hyoukilen)) {
558 
559             return que_count;
560         }
561 
562         if ((que_yomilen > yomi_len) ||
563             (que_hyoukilen > hyouki_len)) {
564 
565             return 0;
566         }
567 
568         ret = is_continued(iwnn, handle, que_id);
569         if (ret <= 0) {
570 
571             return ret;
572         }
573 
574 
575         if (que_count >= (NJD_MAX_CONNECT_CNT - 1)) {
576 
577             return 0;
578         }
579 
580         yomi_len -= que_yomilen;
581         yomi     += que_yomilen;
582 
583         hyouki_len -= que_hyoukilen;
584         hyouki     += que_hyoukilen;
585 
586 
587         que_id = search_next_que(handle, que_id);
588         que_count++;
589     }
590     return 0;
591 }
592 
que_strcmp_include(NJ_CLASS * iwnn,NJ_DIC_HANDLE handle,NJ_UINT16 que_id,NJ_CHAR * yomi)593 static NJ_INT16 que_strcmp_include(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle,
594                                    NJ_UINT16 que_id, NJ_CHAR *yomi) {
595     NJ_CHAR *str;
596     NJ_UINT16 que_len;
597     NJ_UINT16 yomi_len;
598     NJ_INT16 ret;
599     NJ_INT16 que_count = 1;
600     NJ_UINT16 i = 0;
601     NJ_UINT8 slen;
602 
603 
604 #ifdef LEARN_DEBUG
605     printf("que_strcmp_include(que_id=%d, yomi=[%s])\n", que_id, yomi);
606 #endif
607     yomi_len = nj_strlen(yomi);
608     if (yomi_len == 0) {
609         return que_count;
610     }
611 
612     i = GET_LEARN_WORD_COUNT(handle);
613 
614     while (--i) {
615 
616 
617         ret = is_continued(iwnn, handle, que_id);
618         if (ret < 0) {
619 
620             return ret;
621         } else if (ret == 0) {
622 
623             return que_count;
624         }
625 
626 
627         que_id = search_next_que(handle, que_id);
628 
629         str = get_string(iwnn, handle, que_id, &slen);
630 #ifdef IWNN_ERR_CHECK
631         if (iwnn->err_check_flg == 2) {
632             str = NULL;
633         }
634 #endif
635         if (str == NULL) {
636             return NJ_SET_ERR_VAL(NJ_FUNC_QUE_STRCMP_INCLUDE, NJ_ERR_DIC_BROKEN);
637         }
638         que_len = slen;
639 
640 
641         if (que_len > yomi_len) {
642 #ifdef LEARN_DEBUG
643             printf("  >> mismatch [%s] (que_len > yomi_len)\n", str);
644 #endif
645             return que_count;
646         }
647 
648 
649         ret = nj_strncmp(yomi, str, que_len);
650         if (ret != 0) {
651 #ifdef LEARN_DEBUG
652             printf("  >> mismatch [%s]\n", str);
653 #endif
654 
655             return que_count;
656         }
657 
658 
659         if (que_len == yomi_len) {
660 #ifdef LEARN_DEBUG
661             printf("  >> match! [%s](%d)\n", str, que_count);
662 #endif
663             return (que_count + 1);
664         }
665 
666         que_count++;
667         if (que_count >= NJD_MAX_CONNECT_CNT) {
668 
669             return que_count;
670         }
671 
672 
673         yomi_len -= que_len;
674         yomi     += que_len;
675     }
676 
677     return que_count;
678 }
679 
get_string(NJ_CLASS * iwnn,NJ_DIC_HANDLE handle,NJ_UINT16 que_id,NJ_UINT8 * slen)680 static NJ_CHAR *get_string(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle,
681                            NJ_UINT16 que_id, NJ_UINT8 *slen) {
682     NJ_UINT8 *src, *dst;
683     NJ_UINT8 copy_size, size;
684     NJ_UINT8 i;
685     NJ_UINT8 *top_addr;
686     NJ_UINT8 *bottom_addr;
687     NJ_UINT16 que_size;
688 
689 
690     src = POS_TO_ADDRESS(handle, que_id);
691     switch (GET_TYPE_FROM_DATA(src)) {
692     case QUE_TYPE_JIRI:
693     case QUE_TYPE_FZK:
694         size =  GET_YSIZE_FROM_DATA(src);
695         *slen = (NJ_UINT8)(size / sizeof(NJ_CHAR));
696         break;
697 
698     default:
699 #ifdef LEARN_DEBUG
700         printf("get_string(handle=%p, que_id=%d) : broken que\n", handle, que_id);
701 #endif
702         return NULL;
703     }
704 
705     if (NJ_GET_DIC_TYPE(handle) == NJ_DIC_TYPE_USER) {
706         if (*slen > NJ_MAX_USER_LEN) {
707             return NULL;
708         }
709     } else {
710         if (*slen > NJ_MAX_LEN) {
711             return NULL;
712         }
713     }
714 
715 
716     src += LEARN_QUE_STRING_OFFSET;
717 
718     que_size = QUE_SIZE(handle);
719 
720 
721     copy_size = (NJ_UINT8)que_size - LEARN_QUE_STRING_OFFSET;
722     dst = (NJ_UINT8*)&(iwnn->learn_string_tmp[0]);
723     if (copy_size > size) {
724 
725         copy_size = size;
726     }
727     for (i = 0; i < copy_size; i++) {
728         *dst++ = *src++;
729     }
730 
731 
732     top_addr = LEARN_DATA_TOP_ADDR(handle);
733     bottom_addr = top_addr;
734     bottom_addr += que_size * GET_LEARN_MAX_WORD_COUNT(handle) - 1;
735 
736     while (size -= copy_size) {
737 
738         if (src >= bottom_addr) {
739             src = top_addr;
740         }
741 
742 
743         if (*src != QUE_TYPE_NEXT) {
744 #ifdef LEARN_DEBUG
745             printf("FATAL: src que was broken(not QUE_TYPE_NEXT) [src=%x]\n", src);
746 #endif
747             return NULL;
748         }
749 
750         src++;
751         if (size < que_size) {
752 
753             copy_size = size;
754         } else {
755             copy_size = (NJ_UINT8)(que_size - 1);
756         }
757         for (i = 0; i < copy_size; i++) {
758             *dst++ = *src++;
759         }
760     }
761     iwnn->learn_string_tmp[*slen] = NJ_CHAR_NUL;
762 
763     return &(iwnn->learn_string_tmp[0]);
764 }
765 
get_hyouki(NJ_CLASS * iwnn,NJ_DIC_HANDLE handle,NJ_UINT16 que_id,NJ_UINT8 * slen)766 static NJ_CHAR *get_hyouki(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle,
767                            NJ_UINT16 que_id, NJ_UINT8 *slen) {
768     NJ_UINT8 *src, *dst;
769     NJ_WQUE *que;
770     NJ_UINT8 copy_size, size;
771     NJ_UINT8 i;
772     NJ_UINT8 *top_addr;
773     NJ_UINT8 *bottom_addr;
774     NJ_CHAR  *hira;
775     NJ_UINT16 que_size;
776     NJ_UINT32 dictype;
777 
778 
779     que = get_que_yomiLen_and_hyoukiLen(iwnn, handle, que_id);
780     if (que == NULL) {
781         return NULL;
782     }
783 
784     dictype = NJ_GET_DIC_TYPE(handle);
785     if (dictype == NJ_DIC_TYPE_USER) {
786         if (que->yomi_len > NJ_MAX_USER_LEN) {
787             return NULL;
788         }
789         if (que->hyouki_len > NJ_MAX_USER_KOUHO_LEN) {
790             return NULL;
791         }
792     } else {
793         if (que->yomi_len > NJ_MAX_LEN) {
794             return NULL;
795         }
796         if (que->hyouki_len > NJ_MAX_RESULT_LEN) {
797             return NULL;
798         }
799     }
800 
801     src = POS_TO_ADDRESS(handle, que_id);
802 
803     if (que->hyouki_len == 0) {
804         hira = get_string(iwnn, handle, que_id, slen);
805         if (hira == NULL) {
806             return NULL;
807         }
808 
809         if (GET_MFLG_FROM_DATA(src) != 0) {
810             *slen = (NJ_UINT8)nje_convert_hira_to_kata(hira, &(iwnn->muhenkan_tmp[0]), *slen);
811             return &(iwnn->muhenkan_tmp[0]);
812         } else {
813             return hira;
814         }
815     }
816 
817     src += LEARN_QUE_STRING_OFFSET;
818 
819     que_size = QUE_SIZE(handle);
820 
821 
822     size = que->yomi_byte;
823     copy_size = (NJ_UINT8)que_size - LEARN_QUE_STRING_OFFSET;
824     dst = (NJ_UINT8*)&(iwnn->learn_string_tmp[0]);
825     if (copy_size > size) {
826 
827         copy_size = size;
828     }
829 
830 
831     top_addr = LEARN_DATA_TOP_ADDR(handle);
832     bottom_addr = top_addr;
833     bottom_addr += que_size * GET_LEARN_MAX_WORD_COUNT(handle) - 1;
834 
835     src += copy_size;
836     while (size -= copy_size) {
837 
838 
839         if (src >= bottom_addr) {
840             src = top_addr;
841         }
842 
843 
844         if (*src != QUE_TYPE_NEXT) {
845 #ifdef LEARN_DEBUG
846             printf("FATAL: src que was broken(not QUE_TYPE_NEXT) [src=%x]\n", src);
847 #endif
848             return NULL;
849         }
850 
851         src++;
852         if (size < que_size) {
853 
854             copy_size = size;
855         } else {
856             copy_size = (NJ_UINT8)(que_size - 1);
857         }
858         src += copy_size;
859     }
860 
861 
862 
863     if (((src - top_addr) % que_size) == 0) {
864 
865         if (src >= bottom_addr) {
866             src = top_addr;
867         }
868 
869         if (*src++ != QUE_TYPE_NEXT) {
870 #ifdef LEARN_DEBUG
871             printf("FATAL: src que was broken(QUE_TYPE_NEXT) [src=%x]\n", src - 1);
872 #endif
873             return NULL;
874         }
875     }
876 
877     size = que->hyouki_byte;
878 
879 
880     copy_size = (NJ_UINT8)(que_size);
881     copy_size -= (NJ_UINT8)((src - top_addr) % que_size);
882     if (copy_size > size) {
883 
884         copy_size = size;
885     }
886     for (i = 0; i < copy_size; i++) {
887         *dst++ = *src++;
888     }
889 
890     while (size -= copy_size) {
891 
892 
893         if (src >= bottom_addr) {
894             src = top_addr;
895         }
896 
897 
898         if (*src != QUE_TYPE_NEXT) {
899 #ifdef LEARN_DEBUG
900             printf("FATAL: src que was broken(not QUE_TYPE_NEXT) [src=%x]\n", src);
901 #endif
902             return NULL;
903         }
904 
905         src++;
906         if (size < que_size) {
907 
908             copy_size = size;
909         } else {
910             copy_size = (NJ_UINT8)(que_size - 1);
911         }
912 
913         for (i = 0; i < copy_size; i++) {
914             *dst++ = *src++;
915         }
916     }
917 
918     *slen = que->hyouki_len;
919     iwnn->learn_string_tmp[*slen] = NJ_CHAR_NUL;
920 
921     return &(iwnn->learn_string_tmp[0]);
922 }
923 
get_cand_by_sequential(NJ_CLASS * iwnn,NJ_SEARCH_CONDITION * cond,NJ_SEARCH_LOCATION_SET * loctset,NJ_UINT8 search_pattern,NJ_UINT8 comp_flg)924 static NJ_INT16 get_cand_by_sequential(NJ_CLASS *iwnn, NJ_SEARCH_CONDITION *cond,
925                                        NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT8 search_pattern,
926                                        NJ_UINT8 comp_flg) {
927     NJ_UINT16 current, from, to;
928     NJ_UINT16 que_id;
929     NJ_UINT8  *ptr, *p;
930     NJ_INT16 ret, num_count;
931     NJ_CHAR  *yomi;
932     NJ_WQUE  *que;
933     NJ_UINT8 forward_flag = 0;
934 
935 
936 
937     if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_NO_INIT) {
938 
939         ret = search_range_by_yomi(iwnn, loctset->loct.handle, search_pattern,
940                                    cond->yomi, cond->ylen, &from, &to, &forward_flag);
941         if (ret < 0) {
942             return ret;
943         }
944         if (ret == 0) {
945             if (forward_flag) {
946                 loctset->loct.status = NJ_ST_SEARCH_END;
947             } else {
948                 loctset->loct.status = NJ_ST_SEARCH_END_EXT;
949             }
950             return 0;
951         }
952         loctset->loct.top = from;
953         loctset->loct.bottom = to;
954         current = from;
955     } else if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_READY) {
956 
957         current = (NJ_UINT16)(loctset->loct.current + 1);
958     } else {
959         loctset->loct.status = NJ_ST_SEARCH_END;
960         return 0;
961     }
962 
963 
964     ptr = get_search_index_address(loctset->loct.handle, cond->operation);
965     p = ptr + (current * NJ_INDEX_SIZE);
966 
967     while (current <= loctset->loct.bottom) {
968         que_id = GET_UINT16(p);
969         if (search_pattern == NJ_CUR_OP_COMP) {
970 
971             ret = str_que_cmp(iwnn, loctset->loct.handle, cond->yomi, cond->ylen, que_id, 1);
972 
973 
974             if (ret == 2) {
975                 ret = 0;
976             }
977         } else if (search_pattern == NJ_CUR_OP_FORE) {
978 
979             ret = str_que_cmp(iwnn, loctset->loct.handle, cond->yomi, cond->ylen, que_id, 2);
980 
981 
982             if (ret == 2) {
983                 ret = 0;
984             }
985         } else {
986 
987 
988 
989             ret = que_strcmp_complete_with_hyouki(iwnn, loctset->loct.handle, que_id,
990                                                   cond->yomi, cond->ylen, cond->kanji, 0);
991         }
992 
993         if (ret < 0) {
994             return ret;
995         }
996         if (ret > 0) {
997             if (search_pattern == NJ_CUR_OP_LINK) {
998 
999 
1000                 num_count = continue_cnt(iwnn, loctset->loct.handle, que_id);
1001                 if (num_count < 0) {
1002 
1003                     return num_count;
1004                 }
1005 
1006 
1007                 if (num_count >= ret) {
1008 
1009                     loctset->loct.current_info = (NJ_UINT8)(((num_count + 1) << 4) | ret);
1010                     loctset->loct.current = current;
1011                     loctset->loct.status = NJ_ST_SEARCH_READY;
1012                     loctset->cache_freq = get_hindo(iwnn, loctset, search_pattern);
1013                     return 1;
1014                 }
1015             } else {
1016 
1017 
1018 
1019 
1020 
1021 
1022                 que = get_que_allHinsi(iwnn, loctset->loct.handle, que_id);
1023                 if (njd_connect_test(cond, que->mae_hinsi, que->ato_hinsi)) {
1024 
1025 
1026                     switch (NJ_GET_DIC_TYPE_EX(loctset->loct.type, loctset->loct.handle)) {
1027                     case NJ_DIC_TYPE_CUSTOM_INCOMPRESS:
1028                         if ((search_pattern == NJ_CUR_OP_COMP) && (comp_flg == 1)) {
1029                             yomi = cond->yomi + cond->ylen;
1030                             ret = que_strcmp_include(iwnn, loctset->loct.handle, que_id, yomi);
1031                             if (ret < 0) {
1032                                 return ret;
1033                             }
1034                         }
1035                         break;
1036                     default:
1037                         break;
1038                     }
1039                     loctset->loct.current = current;
1040                     loctset->loct.status = NJ_ST_SEARCH_READY;
1041 
1042                     loctset->loct.current_info = (ret & 0x0f) << 4;
1043                     loctset->cache_freq = get_hindo(iwnn, loctset, search_pattern);
1044                     return 1;
1045                 }
1046             }
1047         }
1048         p += NJ_INDEX_SIZE;
1049         current++;
1050     }
1051 
1052 
1053     loctset->loct.status = NJ_ST_SEARCH_END;
1054     return 0;
1055 }
1056 
get_cand_by_evaluate(NJ_CLASS * iwnn,NJ_SEARCH_CONDITION * cond,NJ_SEARCH_LOCATION_SET * loctset,NJ_UINT8 search_pattern)1057 static NJ_INT16 get_cand_by_evaluate(NJ_CLASS *iwnn, NJ_SEARCH_CONDITION *cond,
1058                                      NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT8 search_pattern) {
1059     NJ_UINT16 from, to, i;
1060     NJ_UINT16 que_id, oldest;
1061     NJ_UINT32 max_value, eval, current;
1062     NJ_UINT8  *ptr, *p;
1063     NJ_WQUE  *que;
1064     NJ_INT16 ret, num_count;
1065     NJ_INT32 found = 0;
1066     NJ_UINT8 forward_flag = 0;
1067     NJ_INT32 is_first_search, is_better_freq;
1068 
1069 
1070 
1071     ptr = get_search_index_address(loctset->loct.handle, cond->operation);
1072 
1073 
1074     oldest = GET_LEARN_NEXT_WORD_POS(loctset->loct.handle);
1075 
1076 
1077     current = 0;
1078     if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_NO_INIT) {
1079         if (search_pattern == NJ_CUR_OP_LINK) {
1080 
1081 
1082 
1083             ret = search_range_by_yomi_multi(iwnn, loctset->loct.handle,
1084                                              cond->yomi, cond->ylen, &from, &to);
1085         } else {
1086 
1087 
1088             ret = search_range_by_yomi(iwnn, loctset->loct.handle, search_pattern,
1089                                        cond->yomi, cond->ylen, &from, &to, &forward_flag);
1090         }
1091         if (ret <= 0) {
1092             loctset->loct.status = NJ_ST_SEARCH_END;
1093             return ret;
1094         }
1095         loctset->loct.top = from;
1096         loctset->loct.bottom = to;
1097         is_first_search = 1;
1098     } else if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_READY) {
1099         current = GET_UINT16(ptr + (loctset->loct.current * NJ_INDEX_SIZE));
1100         if (current < oldest) {
1101             current += GET_LEARN_MAX_WORD_COUNT(loctset->loct.handle);
1102         }
1103         is_first_search = 0;
1104     } else {
1105         loctset->loct.status = NJ_ST_SEARCH_END;
1106         return 0;
1107     }
1108 
1109 
1110     max_value = oldest;
1111 
1112     p = ptr + (loctset->loct.top * NJ_INDEX_SIZE);
1113     eval = current;
1114     for (i = (NJ_UINT16)loctset->loct.top; i <= (NJ_UINT16)loctset->loct.bottom; i++) {
1115         que_id = GET_UINT16(p);
1116         if (que_id < oldest) {
1117             eval = que_id + GET_LEARN_MAX_WORD_COUNT(loctset->loct.handle);
1118         } else {
1119             eval = que_id;
1120         }
1121 #ifdef LEARN_DEBUG
1122         printf("que(%d) : eval = %d\n", que_id, eval);
1123 #endif
1124         is_better_freq = ((eval >= max_value) && ((is_first_search) || (eval < current))) ? 1 : 0;
1125 
1126         if (is_better_freq) {
1127 
1128             if (search_pattern == NJ_CUR_OP_LINK) {
1129 
1130                 ret = que_strcmp_complete_with_hyouki(iwnn, loctset->loct.handle, que_id,
1131                                                       cond->yomi, cond->ylen, cond->kanji, 1);
1132             } else {
1133 
1134                 ret = str_que_cmp(iwnn, loctset->loct.handle, cond->yomi, cond->ylen, que_id, 2);
1135 
1136                 if (ret == 2) {
1137                     ret = 0;
1138                 }
1139             }
1140             if (ret < 0) {
1141                 return ret;
1142             }
1143             if (ret >= 1) {
1144                 if (search_pattern == NJ_CUR_OP_LINK) {
1145 
1146 
1147                     num_count = continue_cnt(iwnn, loctset->loct.handle, que_id);
1148                     if (num_count < 0) {
1149 
1150                         return num_count;
1151                     }
1152 
1153 
1154                     if (num_count >= ret) {
1155 
1156                         loctset->loct.current_info = (NJ_UINT8)(((num_count + 1) << 4) | ret);
1157                         loctset->loct.current = i;
1158                         max_value = eval;
1159                         found = 1;
1160                     }
1161                 } else {
1162 
1163 
1164 
1165 
1166 
1167                     que = get_que_allHinsi(iwnn, loctset->loct.handle, que_id);
1168                     if (njd_connect_test(cond, que->mae_hinsi, que->ato_hinsi)) {
1169 
1170                         loctset->loct.current_info = (NJ_UINT8)0x10;
1171                         loctset->loct.current = i;
1172                         max_value = eval;
1173                         found = 1;
1174 #ifdef LEARN_DEBUG
1175                         printf("---keep.");
1176 #endif
1177                     }
1178                 }
1179             }
1180         }
1181         p += NJ_INDEX_SIZE;
1182     }
1183 
1184 
1185     if (found == 0) {
1186         loctset->loct.status = NJ_ST_SEARCH_END;
1187         return 0;
1188     } else {
1189         loctset->loct.status = NJ_ST_SEARCH_READY;
1190         loctset->cache_freq = get_hindo(iwnn, loctset, search_pattern);
1191         return 1;
1192     }
1193 
1194 }
1195 
search_range_by_yomi(NJ_CLASS * iwnn,NJ_DIC_HANDLE handle,NJ_UINT8 op,NJ_CHAR * yomi,NJ_UINT16 len,NJ_UINT16 * from,NJ_UINT16 * to,NJ_UINT8 * forward_flag)1196 static NJ_INT16 search_range_by_yomi(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT8 op,
1197                                      NJ_CHAR  *yomi, NJ_UINT16 len, NJ_UINT16 *from, NJ_UINT16 *to,
1198                                      NJ_UINT8 *forward_flag) {
1199     NJ_UINT16 right, mid = 0, left, max;
1200     NJ_UINT16 que_id;
1201     NJ_UINT8  *ptr, *p;
1202     NJ_CHAR  *str;
1203     NJ_INT16 ret = 0;
1204     NJ_INT32 found = 0;
1205     NJ_UINT8 slen;
1206     NJ_INT32 cmp;
1207 
1208 
1209 
1210     ptr = get_search_index_address(handle, op);
1211 
1212     max = GET_LEARN_WORD_COUNT(handle);
1213 
1214     right = max - 1;
1215     left = 0;
1216 
1217 #ifdef LEARN_DEBUG
1218     printf("src:[%s]\n", yomi);
1219 #endif
1220 
1221     *forward_flag = 0;
1222 
1223 
1224     switch (op) {
1225     case NJ_CUR_OP_COMP:
1226     case NJ_CUR_OP_LINK:
1227     case NJ_CUR_OP_FORE:
1228 
1229 
1230 
1231         break;
1232     default:
1233         return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_PARAM_OPERATION);
1234     }
1235 
1236     while (left <= right) {
1237         mid = left + ((right - left) / 2);
1238         p = ptr + (mid * NJ_INDEX_SIZE);
1239         que_id = GET_UINT16(p);
1240         str = get_string(iwnn, handle, que_id, &slen);
1241 
1242 #ifdef IWNN_ERR_CHECK
1243         if (iwnn->err_check_flg == 3) {
1244             str = NULL;
1245         }
1246 #endif
1247         if (str == NULL) {
1248             return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_DIC_BROKEN);
1249         }
1250 
1251         ret = nj_strncmp(yomi, str, len);
1252         if (op != NJ_CUR_OP_FORE) {
1253 
1254 
1255             if (ret == 0) {
1256                 if ((*forward_flag == 0) && (len <= (NJ_UINT16)slen)) {
1257 
1258                     *forward_flag = 1;
1259                 }
1260                 if (len > (NJ_UINT16)slen) {
1261                     ret = 1;
1262                 } else if (len < (NJ_UINT16)slen) {
1263                     ret = -1;
1264                 }
1265             }
1266         }
1267 #ifdef LEARN_DEBUG
1268         printf("   [%d][%d][%d]COMPARE:[%s] = %d\n", left, mid, right, str, ret);
1269 #endif
1270         if (ret == 0) {
1271 
1272             found = 1;
1273             break;
1274         } else if (ret < 0) {
1275 
1276             right = mid - 1;
1277             if (mid == 0) {
1278                 break;
1279             }
1280         } else {
1281 
1282             left = mid + 1;
1283         }
1284     }
1285 
1286     if (!found) {
1287         return 0;
1288     }
1289 
1290     if (mid == 0) {
1291         *from = mid;
1292     } else {
1293 
1294         p = ((mid - 1) * NJ_INDEX_SIZE) + ptr;
1295 
1296         for (cmp = mid - 1; cmp >= 0; cmp--) {
1297             que_id = GET_UINT16(p);
1298             str = get_string(iwnn, handle, que_id, &slen);
1299 
1300 #ifdef IWNN_ERR_CHECK
1301             if (iwnn->err_check_flg == 4) {
1302                 str = NULL;
1303             }
1304 #endif
1305             if (str == NULL) {
1306                 return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_DIC_BROKEN);
1307             }
1308 
1309             if (op != NJ_CUR_OP_FORE) {
1310                 ret = nj_strncmp(yomi, str, len);
1311                 if (ret == 0) {
1312                     if (len > (NJ_UINT16)slen) {
1313                         ret = 1;
1314                     } else if (len < (NJ_UINT16)slen) {
1315                         ret = -1;
1316                     }
1317                 }
1318                 if (ret > 0) {
1319 
1320                     break;
1321                 }
1322             } else {
1323 
1324                 if (nj_strncmp(yomi, str, len) != 0) {
1325                     break;
1326                 }
1327             }
1328             p -= NJ_INDEX_SIZE;
1329         }
1330         if (cmp < 0) {
1331             *from = 0;
1332         } else {
1333             *from = (NJ_UINT16)cmp + 1;
1334         }
1335     }
1336 
1337 #ifdef LEARN_DEBUG
1338     printf("  >> from:(%d)\n", *from);
1339 #endif
1340 
1341 #ifdef IWNN_ERR_CHECK
1342     if (iwnn->err_check_flg == 5) {
1343         mid = max - 2;
1344     }
1345 #endif
1346     if ((mid + 1) >= max) {
1347         *to = mid;
1348     } else {
1349 
1350         p = ((mid + 1) * NJ_INDEX_SIZE) + ptr;
1351 
1352         for (right = mid + 1; right < max; right++) {
1353             que_id = GET_UINT16(p);
1354             str = get_string(iwnn, handle, que_id, &slen);
1355 
1356 #ifdef IWNN_ERR_CHECK
1357             if (iwnn->err_check_flg == 5) {
1358                 str = NULL;
1359             }
1360 #endif
1361             if (str == NULL) {
1362                 return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_DIC_BROKEN);
1363             }
1364 
1365             if (op != NJ_CUR_OP_FORE) {
1366                 ret = nj_strncmp(yomi, str, len);
1367                 if (ret == 0) {
1368                     if (len > (NJ_UINT16)slen) {
1369                         ret = 1;
1370                     } else if (len < (NJ_UINT16)slen) {
1371                         ret = -1;
1372                     }
1373                 }
1374                 if (ret < 0) {
1375 
1376                     break;
1377                 }
1378             } else {
1379 
1380                 if (nj_strncmp(yomi, str, len) != 0) {
1381                     break;
1382                 }
1383             }
1384             p += NJ_INDEX_SIZE;
1385         }
1386         *to = right - 1;
1387     }
1388 
1389 #ifdef LEARN_DEBUG
1390     printf("  >> to:(%d)\n", *to);
1391 #endif
1392     return 1;
1393 }
1394 
search_range_by_yomi_multi(NJ_CLASS * iwnn,NJ_DIC_HANDLE handle,NJ_CHAR * yomi,NJ_UINT16 len,NJ_UINT16 * from,NJ_UINT16 * to)1395 static NJ_INT16 search_range_by_yomi_multi(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle,
1396                                            NJ_CHAR *yomi, NJ_UINT16 len, NJ_UINT16 *from, NJ_UINT16 *to) {
1397     NJ_UINT16 right, mid = 0, left, max = 0;
1398     NJ_UINT16 que_id;
1399     NJ_UINT8  *ptr, *p;
1400     NJ_INT16 ret = 0;
1401     NJ_UINT16 comp_len;
1402     NJ_UINT16 i, char_len;
1403     NJ_INT32 found = 0;
1404     NJ_INT32 cmp;
1405     NJ_CHAR  comp_yomi[NJ_MAX_LEN + NJ_TERM_LEN];
1406     NJ_CHAR  *pYomi;
1407 
1408 
1409 
1410 
1411     ptr = LEARN_INDEX_TOP_ADDR(handle);
1412 
1413 
1414     max = GET_LEARN_WORD_COUNT(handle);
1415 
1416 #ifdef LEARN_DEBUG
1417     printf("src:[%s]\n", yomi);
1418 #endif
1419 
1420     comp_len = 0;
1421     pYomi = &yomi[0];
1422     while (comp_len < len) {
1423 
1424 
1425         char_len = NJ_CHAR_LEN(pYomi);
1426         for (i = 0; i < char_len; i++) {
1427             *(comp_yomi + comp_len) = *pYomi;
1428             comp_len++;
1429             pYomi++;
1430         }
1431         *(comp_yomi + comp_len) = NJ_CHAR_NUL;
1432 
1433         right = max - 1;
1434         left = 0;
1435         while (left <= right) {
1436             mid = left + ((right - left) / 2);
1437             p = ptr + (mid * NJ_INDEX_SIZE);
1438             que_id = GET_UINT16(p);
1439 
1440 
1441             ret = str_que_cmp(iwnn, handle, comp_yomi, comp_len, que_id, 1);
1442             if (ret < 0) {
1443                 return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI_MULTI, NJ_ERR_DIC_BROKEN);
1444             }
1445 
1446 #ifdef LEARN_DEBUG
1447             printf("   [%d][%d][%d]COMPARE:[%s] = %d\n", left, mid, right, str, ret);
1448 #endif
1449             if (ret == 1) {
1450 
1451                 found = 1;
1452                 break;
1453             } else if (ret == 0) {
1454 
1455                 right = mid - 1;
1456                 if (mid == 0) {
1457                     break;
1458                 }
1459             } else {
1460 
1461                 left = mid + 1;
1462             }
1463         }
1464 
1465         if (found) {
1466             break;
1467         }
1468     }
1469 
1470     if (!found) {
1471 
1472         return 0;
1473     }
1474 
1475 
1476     if (mid == 0) {
1477         *from = mid;
1478     } else {
1479 
1480         p = ((mid - 1) * NJ_INDEX_SIZE) + ptr;
1481 
1482         for (cmp = mid - 1; cmp >= 0; cmp--) {
1483             que_id = GET_UINT16(p);
1484             ret = str_que_cmp(iwnn, handle, comp_yomi, comp_len, que_id, 1);
1485             if (ret < 0) {
1486                 return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI_MULTI, NJ_ERR_DIC_BROKEN);
1487             }
1488             if (ret == 2) {
1489                 break;
1490             }
1491             p -= NJ_INDEX_SIZE;
1492         }
1493         if (cmp < 0) {
1494             *from = 0;
1495         } else {
1496             *from = (NJ_UINT16)cmp + 1;
1497         }
1498     }
1499 
1500 #ifdef LEARN_DEBUG
1501     printf("  >> from:(%d)\n", *from);
1502 #endif
1503 
1504 
1505     if ((mid + 1) >= max) {
1506         *to = mid;
1507     } else {
1508 
1509         p = ((mid + 1) * NJ_INDEX_SIZE) + ptr;
1510 
1511         for (right = mid + 1; right < max; right++) {
1512             que_id = GET_UINT16(p);
1513             ret = str_que_cmp(iwnn, handle, yomi, len, que_id, 1);
1514             if (ret < 0) {
1515                 return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI_MULTI, NJ_ERR_DIC_BROKEN);
1516             }
1517             if (ret == 0) {
1518                 break;
1519             }
1520             p += NJ_INDEX_SIZE;
1521         }
1522         *to = right - 1;
1523     }
1524 
1525 #ifdef LEARN_DEBUG
1526     printf("  >> to:(%d)\n", *to);
1527 #endif
1528     return 1;
1529 }
1530 
str_que_cmp(NJ_CLASS * iwnn,NJ_DIC_HANDLE handle,NJ_CHAR * yomi,NJ_UINT16 yomiLen,NJ_UINT16 que_id,NJ_UINT8 mode)1531 static NJ_INT16 str_que_cmp(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_CHAR *yomi,
1532                             NJ_UINT16 yomiLen, NJ_UINT16 que_id, NJ_UINT8 mode) {
1533     NJ_UINT8  *queYomi;
1534     NJ_UINT8  *yomiPtr;
1535     NJ_UINT16 yomiByte;
1536     NJ_UINT16 yomiPos;
1537     NJ_UINT8  queYomiByte, queKouhoByte;
1538     NJ_UINT8  queYomiPos, queYomiSearchArea;
1539     NJ_INT16  complete;
1540     NJ_UINT8  *top_addr;
1541     NJ_UINT8  *bottom_addr;
1542     NJ_UINT16 que_size;
1543 
1544 
1545 #ifdef IWNN_ERR_CHECK
1546     if (iwnn->err_check_flg == 6) {
1547         que_id = GET_LEARN_MAX_WORD_COUNT(handle);
1548     }
1549 #endif
1550     if (que_id >= GET_LEARN_MAX_WORD_COUNT(handle)) {
1551 
1552         return NJ_SET_ERR_VAL(NJ_FUNC_STR_QUE_CMP, NJ_ERR_DIC_BROKEN);
1553     }
1554 
1555     queYomi = POS_TO_ADDRESS(handle, que_id);
1556 #ifdef IWNN_ERR_CHECK
1557     if (iwnn->err_check_flg == 7) {
1558         *queYomi = 0x03;
1559     }
1560 #endif
1561     switch (GET_TYPE_FROM_DATA(queYomi)) {
1562     case QUE_TYPE_EMPTY:
1563     case QUE_TYPE_JIRI:
1564     case QUE_TYPE_FZK:
1565         break;
1566     default:
1567 
1568         return NJ_SET_ERR_VAL(NJ_FUNC_STR_QUE_CMP, NJ_ERR_DIC_BROKEN);
1569     }
1570 
1571 
1572     if ((mode == 2) && (yomiLen == 0)) {
1573         return 1;
1574     }
1575 
1576 
1577     queYomiByte = GET_YSIZE_FROM_DATA(queYomi);
1578     queKouhoByte= GET_KSIZE_FROM_DATA(queYomi);
1579 
1580     top_addr = LEARN_DATA_TOP_ADDR(handle);
1581     que_size = QUE_SIZE(handle);
1582 
1583 
1584     queYomi += LEARN_QUE_STRING_OFFSET;
1585     queYomiSearchArea = (NJ_UINT8)(QUE_SIZE(handle) - LEARN_QUE_STRING_OFFSET);
1586 
1587     complete = 0;
1588     yomiPos = 0; queYomiPos = 0;
1589     yomiPtr  = (NJ_UINT8*)yomi;
1590     yomiByte = yomiLen * sizeof(NJ_CHAR);
1591 
1592 
1593     while ((complete = (*yomiPtr - *queYomi)) == 0) {
1594         yomiPos++; queYomiPos++;
1595 
1596         if (queYomiPos >= queYomiByte) {
1597             if (queYomiByte == yomiByte) {
1598 
1599                 return 1;
1600             } else if (mode == 2) {
1601 
1602                 return 2;
1603             } else {
1604 
1605                 return (mode + 1);
1606             }
1607         }
1608         if (yomiPos >= yomiByte) {
1609 
1610             break;
1611         } else {
1612             yomiPtr++; queYomi++;
1613 #ifdef IWNN_ERR_CHECK
1614             if (iwnn->err_check_flg == 8) {
1615                 queYomiPos = queYomiSearchArea;
1616             }
1617 #endif
1618             if (queYomiPos >= queYomiSearchArea) {
1619 
1620                 bottom_addr = top_addr;
1621                 bottom_addr += que_size * GET_LEARN_MAX_WORD_COUNT(handle) - 1;
1622                 if (queYomi >= bottom_addr) {
1623                     queYomi = top_addr;
1624                 }
1625 
1626 
1627                 if (*queYomi++ != QUE_TYPE_NEXT) {
1628 
1629                     return NJ_SET_ERR_VAL(NJ_FUNC_STR_QUE_CMP, NJ_ERR_DIC_BROKEN);
1630                 }
1631                 queYomiSearchArea += (NJ_UINT8)(que_size - 1);
1632             }
1633         }
1634     }
1635     if (complete == 0) {
1636         if (yomiByte < queYomiByte) {
1637 
1638             if (mode == 2) {
1639                 return 1;
1640             }
1641 
1642             return 0;
1643         } else {
1644 
1645             return 2;
1646         }
1647     } else if (complete < 0) {
1648 
1649         return 0;
1650     } else {
1651 
1652         return 2;
1653     }
1654 }
1655 
calculate_hindo(NJ_DIC_HANDLE handle,NJ_INT32 freq,NJ_DIC_FREQ * dic_freq,NJ_INT16 freq_max,NJ_INT16 freq_min)1656 static NJ_HINDO calculate_hindo(NJ_DIC_HANDLE handle, NJ_INT32 freq, NJ_DIC_FREQ *dic_freq, NJ_INT16 freq_max, NJ_INT16 freq_min) {
1657     NJ_UINT16 max;
1658     NJ_HINDO  hindo;
1659 
1660 
1661     max = GET_LEARN_MAX_WORD_COUNT(handle);
1662 
1663 
1664 
1665 
1666     if (NJ_GET_DIC_TYPE(handle) == NJ_DIC_TYPE_USER) {
1667 
1668         hindo = (NJ_INT16)dic_freq->base;
1669     } else {
1670 
1671         if (max > 1) {
1672 
1673             hindo = CALCULATE_HINDO(freq, dic_freq->base, dic_freq->high, (max-1));
1674         } else {
1675 
1676             hindo = (NJ_INT16)dic_freq->high;
1677         }
1678     }
1679     return NORMALIZE_HINDO(hindo, freq_max, freq_min);
1680 }
1681 
get_hindo(NJ_CLASS * iwnn,NJ_SEARCH_LOCATION_SET * loctset,NJ_UINT8 search_pattern)1682 static NJ_HINDO get_hindo(NJ_CLASS *iwnn, NJ_SEARCH_LOCATION_SET *loctset,
1683                           NJ_UINT8 search_pattern) {
1684     NJ_WQUE   *que;
1685     NJ_UINT16 que_id, oldest;
1686     NJ_UINT8  offset;
1687     NJ_INT32  dic_freq;
1688     NJ_UINT16 max;
1689     NJ_UINT8  *learn_index_top_addr;
1690 
1691 
1692 
1693     learn_index_top_addr = get_search_index_address(loctset->loct.handle, search_pattern);
1694 
1695     que_id = (NJ_UINT16)GET_UINT16(learn_index_top_addr +
1696                                    ((loctset->loct.current & 0xffffU) * NJ_INDEX_SIZE));
1697     oldest = GET_LEARN_NEXT_WORD_POS(loctset->loct.handle);
1698 
1699     offset = (loctset->loct.current_info & 0x0f);
1700     while (offset--) {
1701         que_id = search_next_que(loctset->loct.handle, que_id);
1702     }
1703 
1704     que = get_que(iwnn, loctset->loct.handle, que_id);
1705     if (que == NULL) {
1706         return INIT_HINDO;
1707     }
1708 
1709     max = GET_LEARN_MAX_WORD_COUNT(loctset->loct.handle);
1710     if (que_id >= oldest) {
1711         dic_freq = que_id - oldest;
1712     } else {
1713         dic_freq = que_id - oldest + max;
1714     }
1715 
1716 
1717     return calculate_hindo(loctset->loct.handle, dic_freq, &(loctset->dic_freq), 1000, 0);
1718 }
1719 
njd_l_get_word(NJ_CLASS * iwnn,NJ_SEARCH_LOCATION_SET * loctset,NJ_WORD * word)1720 NJ_INT16 njd_l_get_word(NJ_CLASS *iwnn, NJ_SEARCH_LOCATION_SET *loctset, NJ_WORD *word) {
1721     NJ_WQUE *que;
1722     NJ_UINT16 que_id;
1723     NJ_UINT8 offset;
1724     NJ_UINT8 *learn_index_top_addr;
1725 
1726 
1727 
1728     learn_index_top_addr = get_search_index_address(loctset->loct.handle, GET_LOCATION_OPERATION(loctset->loct.status));
1729 
1730     que_id = (NJ_UINT16)GET_UINT16(learn_index_top_addr +
1731                                    ((loctset->loct.current & 0xffff) * NJ_INDEX_SIZE));
1732 
1733     offset = (loctset->loct.current_info & 0x0f);
1734     while (offset--) {
1735         que_id = search_next_que(loctset->loct.handle, que_id);
1736     }
1737 
1738     que = get_que(iwnn, loctset->loct.handle, que_id);
1739     if (que == NULL) {
1740         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_GET_WORD, NJ_ERR_CANNOT_GET_QUE);
1741     }
1742 
1743     word->stem.loc = loctset->loct;
1744 
1745     word->stem.loc.current &= 0x0000ffff;
1746     word->stem.loc.current |= ((NJ_UINT32)que_id << 16);
1747 
1748 
1749     word->stem.hindo = loctset->cache_freq;
1750 
1751     NJ_SET_FPOS_TO_STEM(word, que->mae_hinsi);
1752     NJ_SET_YLEN_TO_STEM(word, que->yomi_len);
1753     if (que->hyouki_len > 0) {
1754         NJ_SET_KLEN_TO_STEM(word, que->hyouki_len);
1755     } else {
1756 
1757         NJ_SET_KLEN_TO_STEM(word, que->yomi_len);
1758     }
1759     NJ_SET_BPOS_TO_STEM(word, que->ato_hinsi);
1760 
1761 
1762     word->stem.type = 0;
1763 
1764     return 1;
1765 }
1766 
njd_l_get_stroke(NJ_CLASS * iwnn,NJ_WORD * word,NJ_CHAR * stroke,NJ_UINT16 size)1767 NJ_INT16 njd_l_get_stroke(NJ_CLASS *iwnn, NJ_WORD *word, NJ_CHAR *stroke, NJ_UINT16 size) {
1768     NJ_UINT16 que_id;
1769     NJ_CHAR   *str;
1770     NJ_UINT8  slen;
1771     NJ_UINT8  ylen;
1772 
1773 
1774     que_id = (NJ_UINT16)(word->stem.loc.current >> 16);
1775 
1776 
1777     ylen = (NJ_UINT8)NJ_GET_YLEN_FROM_STEM(word);
1778 
1779     if ((NJ_UINT16)((ylen+ NJ_TERM_LEN)*sizeof(NJ_CHAR)) > size) {
1780 
1781         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_GET_STROKE, NJ_ERR_BUFFER_NOT_ENOUGH);
1782     }
1783     if (ylen == 0) {
1784         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_GET_STROKE, NJ_ERR_INVALID_RESULT);
1785     }
1786     str = get_string(iwnn, word->stem.loc.handle, que_id, &slen);
1787 
1788 #ifdef IWNN_ERR_CHECK
1789     if (iwnn->err_check_flg == 9) {
1790         str = NULL;
1791     }
1792 #endif
1793 
1794     if (str == NULL) {
1795         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_GET_STROKE, NJ_ERR_DIC_BROKEN);
1796     }
1797 
1798 
1799     nj_strcpy(stroke, str);
1800 
1801     return slen;
1802 }
1803 
njd_l_get_candidate(NJ_CLASS * iwnn,NJ_WORD * word,NJ_CHAR * candidate,NJ_UINT16 size)1804 NJ_INT16 njd_l_get_candidate(NJ_CLASS *iwnn, NJ_WORD *word,
1805                              NJ_CHAR *candidate, NJ_UINT16 size) {
1806     NJ_UINT16 que_id;
1807     NJ_CHAR   *str;
1808     NJ_UINT16 klen;
1809     NJ_UINT8  slen;
1810 
1811 
1812     que_id = (NJ_UINT16)(word->stem.loc.current >> 16);
1813 
1814 
1815     klen = NJ_GET_KLEN_FROM_STEM(word);
1816 
1817     if (size < ((klen+NJ_TERM_LEN)*sizeof(NJ_CHAR))) {
1818 
1819         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_GET_CANDIDATE, NJ_ERR_BUFFER_NOT_ENOUGH);
1820     }
1821     str = get_hyouki(iwnn, word->stem.loc.handle, que_id, &slen);
1822 #ifdef IWNN_ERR_CHECK
1823     if (iwnn->err_check_flg == 10) {
1824         str = NULL;
1825     }
1826 #endif
1827     if (str == NULL) {
1828 
1829         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_GET_CANDIDATE, NJ_ERR_DIC_BROKEN);
1830     }
1831 
1832 
1833     nj_strcpy(candidate, str);
1834 
1835     return klen;
1836 }
1837 
njd_l_check_dic(NJ_CLASS * iwnn,NJ_DIC_HANDLE handle)1838 NJ_INT16 njd_l_check_dic(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle) {
1839     NJ_UINT16 flg;
1840     NJ_UINT16 word_cnt, max;
1841     NJ_UINT8 *ptr;
1842     NJ_UINT16 target_id;
1843     NJ_UINT16 i;
1844     NJ_UINT16 id1 = 0;
1845     NJ_UINT8 slen;
1846 
1847 
1848 
1849     if ((NJ_GET_DIC_TYPE(handle) != NJ_DIC_TYPE_USER)) {
1850 
1851         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_CHECK_DIC, NJ_ERR_DIC_TYPE_INVALID);
1852     }
1853 
1854 
1855     word_cnt = GET_LEARN_WORD_COUNT(handle);
1856     max = GET_LEARN_MAX_WORD_COUNT(handle);
1857     if (word_cnt > max) {
1858 
1859         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_CHECK_DIC,
1860                               NJ_ERR_DIC_BROKEN);
1861     }
1862 
1863     ptr = LEARN_INDEX_TOP_ADDR(handle);
1864     for (i = 0; i < word_cnt; i++) {
1865         id1 = GET_UINT16(ptr);
1866 
1867         if (id1 >= max) {
1868             return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_CHECK_DIC,
1869                                   NJ_ERR_DIC_BROKEN);
1870         }
1871         ptr += NJ_INDEX_SIZE;
1872     }
1873 
1874 
1875     ptr = LEARN_INDEX_TOP_ADDR2(handle);
1876     for (i = 0; i < word_cnt; i++) {
1877         id1 = GET_UINT16(ptr);
1878 
1879         if (id1 >= max) {
1880             return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_CHECK_DIC,
1881                                   NJ_ERR_DIC_BROKEN);
1882         }
1883         ptr += NJ_INDEX_SIZE;
1884     }
1885 
1886 
1887     flg = GET_UINT16(handle + POS_WRITE_FLG);
1888 
1889     target_id = GET_UINT16(handle + POS_WRITE_FLG + 2);
1890 
1891 
1892 
1893     if (((flg != word_cnt) && (flg != (word_cnt + 1)) && (flg != (word_cnt - 1))) ||
1894         (target_id >= max)) {
1895         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_CHECK_DIC,
1896                               NJ_ERR_DIC_BROKEN);
1897     }
1898 
1899 
1900     if (flg == (word_cnt + 1)) {
1901         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_CHECK_DIC, NJ_ERR_DIC_BROKEN);
1902     } else if (flg == (word_cnt - 1)) {
1903         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_CHECK_DIC, NJ_ERR_DIC_BROKEN);
1904     }
1905 
1906     word_cnt = GET_LEARN_WORD_COUNT(handle);
1907 
1908     ptr = LEARN_INDEX_TOP_ADDR(handle);
1909     for (i = 0; i < word_cnt; i++) {
1910         id1 = GET_UINT16(ptr);
1911         if (get_hyouki(iwnn, handle, id1, &slen) == NULL) {
1912             return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_CHECK_DIC,
1913                                   NJ_ERR_DIC_BROKEN);
1914         }
1915         ptr += NJ_INDEX_SIZE;
1916     }
1917 
1918     ptr = LEARN_INDEX_TOP_ADDR2(handle);
1919     for (i = 0; i < word_cnt; i++) {
1920         id1 = GET_UINT16(ptr);
1921 
1922         if (id1 >= max) {
1923             return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_CHECK_DIC,
1924                                   NJ_ERR_DIC_BROKEN);
1925         }
1926         ptr += NJ_INDEX_SIZE;
1927     }
1928 
1929     return 0;
1930 }
1931 
get_cand_by_evaluate2(NJ_CLASS * iwnn,NJ_SEARCH_CONDITION * cond,NJ_SEARCH_LOCATION_SET * loctset,NJ_UINT8 search_pattern,NJ_UINT16 idx)1932 static NJ_INT16 get_cand_by_evaluate2(NJ_CLASS *iwnn, NJ_SEARCH_CONDITION *cond,
1933                                       NJ_SEARCH_LOCATION_SET *loctset,
1934                                       NJ_UINT8 search_pattern,
1935                                       NJ_UINT16 idx) {
1936     NJ_UINT16 from, to, i;
1937     NJ_UINT16 que_id, oldest;
1938     NJ_UINT32 max_value, eval, current;
1939     NJ_UINT8  *ptr, *p;
1940     NJ_WQUE *que;
1941     NJ_INT16 ret = 0;
1942     NJ_INT32 found = 0;
1943     NJ_UINT8 forward_flag = 0;
1944 
1945 
1946     NJ_UINT16               abIdx;
1947     NJ_UINT16               abIdx_old;
1948     NJ_UINT16               tmp_len;
1949     NJ_UINT16               yomi_clen;
1950     NJ_UINT16               j,l,m;
1951     NJ_UINT8                cmpflg;
1952     NJ_UINT8                endflg = 0;
1953     NJ_CHAR                 *str;
1954     NJ_CHAR                 *key;
1955     NJ_CHAR                 char_tmp[NJ_MAX_LEN + NJ_TERM_LEN];
1956     NJ_CHAR                 *pchar_tmp;
1957     NJ_SEARCH_CACHE         *psrhCache = cond->ds->dic[idx].srhCache;
1958     NJ_UINT16               endIdx;
1959     NJ_UINT8                slen;
1960     NJ_UINT16               addcnt = 0;
1961     NJ_CHAR                 *yomi;
1962     NJ_UINT8                aimai_flg = 0x01;
1963     NJ_CHARSET              *pCharset = cond->charset;
1964 
1965 
1966     if (NJ_GET_CACHEOVER_FROM_SCACHE(psrhCache)) {
1967         aimai_flg = 0x00;
1968     }
1969 
1970 
1971     ptr = get_search_index_address(loctset->loct.handle, cond->operation);
1972 
1973 
1974     oldest = GET_LEARN_NEXT_WORD_POS(loctset->loct.handle);
1975     max_value = oldest;
1976 
1977 
1978     current = 0;
1979     if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_NO_INIT) {
1980 
1981 
1982         key       = cond->ds->keyword;
1983         yomi      = cond->yomi;
1984         yomi_clen = cond->yclen;
1985 
1986 
1987         endflg = 0x00;
1988 
1989         if (psrhCache->keyPtr[0] == 0xFFFF) {
1990             cmpflg = 0x01;
1991             psrhCache->keyPtr[0] = 0x0000;
1992         } else {
1993             cmpflg = 0x00;
1994         }
1995 
1996         for (i = 0; i < yomi_clen; i++) {
1997             j = i;
1998 
1999 
2000             if (!cmpflg) {
2001 
2002                 if (((j != 0) && (psrhCache->keyPtr[j] == 0)) || (psrhCache->keyPtr[j+1] == 0)) {
2003 
2004                     cmpflg = 0x01;
2005                 } else {
2006 
2007                 }
2008             }
2009 
2010             if (cmpflg) {
2011 
2012                 if (!j) {
2013 
2014                     abIdx = 0;
2015                     addcnt = 0;
2016                     nj_charncpy(char_tmp, yomi, 1);
2017                     tmp_len = nj_strlen(char_tmp);
2018                     ret = search_range_by_yomi(iwnn, loctset->loct.handle, search_pattern,
2019                                                char_tmp, tmp_len, &from,
2020                                                &to, &forward_flag);
2021                     if (ret < 0) {
2022 
2023 
2024                         psrhCache->keyPtr[j+1] = abIdx;
2025                         loctset->loct.status = NJ_ST_SEARCH_END;
2026                         return ret;
2027                     } else if (ret > 0) {
2028 
2029                         psrhCache->storebuff[abIdx].top    = from;
2030                         psrhCache->storebuff[abIdx].bottom = to;
2031                         psrhCache->storebuff[abIdx].idx_no = (NJ_INT8)tmp_len;
2032                         addcnt++;
2033                         abIdx++;
2034                         psrhCache->keyPtr[j+1] = abIdx;
2035                     } else {
2036                         psrhCache->keyPtr[j+1] = abIdx;
2037                     }
2038 
2039                     if ((!endflg) && (pCharset != NULL) && aimai_flg) {
2040 
2041                         for (l = 0; l < pCharset->charset_count; l++) {
2042 
2043                             if (nj_charncmp(yomi, pCharset->from[l], 1) == 0) {
2044 
2045                                 nj_strcpy(char_tmp, pCharset->to[l]);
2046                                 tmp_len = nj_strlen(char_tmp);
2047                                 ret = search_range_by_yomi(iwnn, loctset->loct.handle, search_pattern,
2048                                                            char_tmp, tmp_len, &from, &to, &forward_flag);
2049                                 if (ret < 0) {
2050 
2051 
2052                                     psrhCache->keyPtr[j+1] = abIdx;
2053                                     loctset->loct.status = NJ_ST_SEARCH_END;
2054                                     return ret;
2055                                 } else if (ret > 0) {
2056 
2057 
2058                                     if (abIdx >= NJ_SEARCH_CACHE_SIZE) {
2059                                         psrhCache->keyPtr[j+1] = 0;
2060                                         return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_CACHE_NOT_ENOUGH);
2061                                     }
2062                                     psrhCache->storebuff[abIdx].top    = from;
2063                                     psrhCache->storebuff[abIdx].bottom = to;
2064                                     psrhCache->storebuff[abIdx].idx_no = (NJ_INT8)tmp_len;
2065                                     if (addcnt == 0) {
2066                                         psrhCache->keyPtr[j] = abIdx;
2067                                     }
2068                                     abIdx++;
2069                                     addcnt++;
2070                                     psrhCache->keyPtr[j+1] = abIdx;
2071                                 } else {
2072                                     psrhCache->keyPtr[j+1] = abIdx;
2073                                 }
2074                             }
2075                         }
2076                     }
2077                 } else {
2078 
2079                     if (psrhCache->keyPtr[j] == psrhCache->keyPtr[j-1]) {
2080 
2081                         psrhCache->keyPtr[j+1] = psrhCache->keyPtr[j-1];
2082                         endflg = 0x01;
2083                     } else {
2084 
2085                         endIdx = psrhCache->keyPtr[j];
2086                         abIdx_old = psrhCache->keyPtr[j-1];
2087 
2088                         if (NJ_GET_CACHEOVER_FROM_SCACHE(psrhCache)) {
2089                             abIdx = psrhCache->keyPtr[j - 1];
2090                             psrhCache->keyPtr[j] = abIdx;
2091                         } else {
2092                             abIdx = psrhCache->keyPtr[j];
2093                         }
2094                         addcnt = 0;
2095 
2096                         if ((abIdx > NJ_SEARCH_CACHE_SIZE) || (abIdx_old >= NJ_SEARCH_CACHE_SIZE) ||
2097                             (endIdx > NJ_SEARCH_CACHE_SIZE)) {
2098 
2099                             return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_CACHE_BROKEN);
2100                         }
2101                         for (m = abIdx_old; m < endIdx; m++) {
2102 
2103                             p = ptr + (psrhCache->storebuff[m].top * NJ_INDEX_SIZE);
2104                             que_id = GET_UINT16(p);
2105 
2106 
2107                             str = get_string(iwnn, loctset->loct.handle, que_id, &slen);
2108 
2109                             if (str == NULL) {
2110                                 return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_DIC_BROKEN);
2111                             }
2112 
2113 
2114                             nj_strncpy(char_tmp, str, psrhCache->storebuff[m].idx_no);
2115                             char_tmp[psrhCache->storebuff[m].idx_no] = NJ_CHAR_NUL;
2116 
2117                             pchar_tmp = &char_tmp[psrhCache->storebuff[m].idx_no];
2118                             nj_charncpy(pchar_tmp, yomi, 1);
2119                             tmp_len = nj_strlen(char_tmp);
2120 
2121 
2122                             ret = search_range_by_yomi2(iwnn, loctset->loct.handle, search_pattern,
2123                                                         char_tmp, tmp_len,
2124                                                         (NJ_UINT16)(psrhCache->storebuff[m].top),
2125                                                         (NJ_UINT16)(psrhCache->storebuff[m].bottom),
2126                                                         &from, &to, &forward_flag);
2127                             if (ret < 0) {
2128 
2129 
2130                                 psrhCache->keyPtr[j+1] = abIdx;
2131                                 loctset->loct.status = NJ_ST_SEARCH_END;
2132                                 return ret;
2133                             } else if (ret > 0) {
2134 
2135 
2136                                 if (abIdx >= NJ_SEARCH_CACHE_SIZE) {
2137                                     psrhCache->keyPtr[j+1] = 0;
2138                                     return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_CACHE_NOT_ENOUGH);
2139                                 }
2140                                 psrhCache->storebuff[abIdx].top    = from;
2141                                 psrhCache->storebuff[abIdx].bottom = to;
2142                                 psrhCache->storebuff[abIdx].idx_no = (NJ_INT8)tmp_len;
2143                                 if (addcnt == 0) {
2144                                     psrhCache->keyPtr[j] = abIdx;
2145                                 }
2146                                 abIdx++;
2147                                 addcnt++;
2148                                 psrhCache->keyPtr[j+1] = abIdx;
2149                             } else {
2150                                 psrhCache->keyPtr[j+1] = abIdx;
2151                             }
2152 
2153                             if ((!endflg) && (pCharset != NULL) && aimai_flg) {
2154 
2155                                 for (l = 0; l < pCharset->charset_count; l++) {
2156 
2157                                     if (nj_charncmp(yomi, pCharset->from[l], 1) == 0) {
2158 
2159                                         tmp_len = nj_strlen(pCharset->to[l]);
2160 
2161                                         nj_strncpy(pchar_tmp, pCharset->to[l], tmp_len);
2162                                         *(pchar_tmp + tmp_len) = NJ_CHAR_NUL;
2163                                         tmp_len = nj_strlen(char_tmp);
2164                                         ret = search_range_by_yomi2(iwnn, loctset->loct.handle, search_pattern,
2165                                                                     char_tmp, tmp_len,
2166                                                                     (NJ_UINT16)(psrhCache->storebuff[m].top),
2167                                                                     (NJ_UINT16)(psrhCache->storebuff[m].bottom),
2168                                                                     &from, &to, &forward_flag);
2169                                         if (ret < 0) {
2170 
2171 
2172                                             psrhCache->keyPtr[j+1] = abIdx;
2173                                             loctset->loct.status = NJ_ST_SEARCH_END;
2174                                             return ret;
2175                                         } else if (ret > 0) {
2176 
2177 
2178                                             if (abIdx >= NJ_SEARCH_CACHE_SIZE) {
2179                                                 psrhCache->keyPtr[j+1] = 0;
2180                                                 return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_CACHE_NOT_ENOUGH);
2181                                             }
2182                                             psrhCache->storebuff[abIdx].top    = from;
2183                                             psrhCache->storebuff[abIdx].bottom = to;
2184                                             psrhCache->storebuff[abIdx].idx_no = (NJ_INT8)tmp_len;
2185                                             abIdx++;
2186                                             addcnt++;
2187                                             psrhCache->keyPtr[j+1] = abIdx;
2188                                         } else {
2189                                             psrhCache->keyPtr[j+1] = abIdx;
2190                                         }
2191                                     }
2192                                 }
2193                             }
2194                         }
2195                     }
2196                 }
2197             }
2198             yomi += UTL_CHAR(yomi);
2199             key  += UTL_CHAR(key);
2200         }
2201 
2202 
2203         if ((addcnt == 0) && (psrhCache->keyPtr[yomi_clen - 1] == psrhCache->keyPtr[yomi_clen])) {
2204             endflg = 0x01;
2205         }
2206 
2207         if (endflg) {
2208             loctset->loct.status = NJ_ST_SEARCH_END;
2209             return 0;
2210         }
2211     } else if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_READY) {
2212         current = GET_UINT16(ptr + (loctset->loct.current * NJ_INDEX_SIZE));
2213         if (current < oldest) {
2214             current += GET_LEARN_MAX_WORD_COUNT(loctset->loct.handle);
2215         }
2216     } else {
2217         loctset->loct.status = NJ_ST_SEARCH_END;
2218         return 0;
2219     }
2220 
2221 
2222     j = cond->yclen - 1;
2223 
2224     abIdx = psrhCache->keyPtr[j];
2225     abIdx_old = psrhCache->keyPtr[j+1];
2226 
2227     endIdx = abIdx_old;
2228     if ((abIdx >= NJ_SEARCH_CACHE_SIZE) || (abIdx_old > NJ_SEARCH_CACHE_SIZE)) {
2229 
2230         return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_CACHE_BROKEN);
2231     }
2232     p = ptr + (psrhCache->storebuff[abIdx].top * NJ_INDEX_SIZE);
2233     que_id = GET_UINT16(p);
2234     eval = current;
2235 
2236 
2237 
2238     if (psrhCache->keyPtr[j] < psrhCache->keyPtr[j + 1]) {
2239         if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_NO_INIT) {
2240             endIdx = abIdx + 1;
2241             NJ_SET_AIMAI_TO_SCACHE(psrhCache);
2242         }
2243 
2244         for (m = abIdx; m < endIdx; m++) {
2245             p = ptr + (psrhCache->storebuff[m].top * NJ_INDEX_SIZE);
2246             que_id = GET_UINT16(p);
2247             eval = current;
2248 
2249             for (i = (NJ_UINT16)psrhCache->storebuff[m].top; i <= (NJ_UINT16)psrhCache->storebuff[m].bottom; i++) {
2250                 que_id = GET_UINT16(p);
2251                 if (que_id < oldest) {
2252                     eval = que_id + GET_LEARN_MAX_WORD_COUNT(loctset->loct.handle);
2253                 } else {
2254                     eval = que_id;
2255                 }
2256 #ifdef LEARN_DEBUG
2257                 printf("que(%d) : eval = %d : %d\n", que_id, eval, i);
2258 #endif
2259                 if (eval >= max_value) {
2260                     if ((GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_NO_INIT)
2261                         || ((GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_READY)
2262                             && (NJ_GET_AIMAI_FROM_SCACHE(psrhCache)))
2263                         || (eval < current)) {
2264 
2265 
2266 
2267                         str = get_string(iwnn, loctset->loct.handle, que_id, &slen);
2268                         if (str == NULL) {
2269                             return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_DIC_BROKEN);
2270                         }
2271 
2272 
2273 
2274                         que = get_que_allHinsi(iwnn, loctset->loct.handle, que_id);
2275                         if (njd_connect_test(cond, que->mae_hinsi, que->ato_hinsi)) {
2276 
2277                             loctset->loct.current_info = (NJ_UINT8)0x10;
2278                             loctset->loct.current = i;
2279                             max_value = eval;
2280                             found = 1;
2281 #ifdef LEARN_DEBUG
2282                             printf("---keep.");
2283 #endif
2284                         }
2285                     }
2286                 }
2287                 p += NJ_INDEX_SIZE;
2288             }
2289         }
2290     }
2291 
2292     if (GET_LOCATION_STATUS(loctset->loct.status) != NJ_ST_SEARCH_NO_INIT) {
2293         NJ_UNSET_AIMAI_TO_SCACHE(psrhCache);
2294     }
2295 
2296 
2297     if (found == 0) {
2298         loctset->loct.status = NJ_ST_SEARCH_END;
2299         return 0;
2300     } else {
2301         loctset->loct.status = NJ_ST_SEARCH_READY;
2302         loctset->cache_freq = get_hindo(iwnn, loctset, search_pattern);
2303         return 1;
2304     }
2305 }
2306 
search_range_by_yomi2(NJ_CLASS * iwnn,NJ_DIC_HANDLE handle,NJ_UINT8 op,NJ_CHAR * yomi,NJ_UINT16 len,NJ_UINT16 sfrom,NJ_UINT16 sto,NJ_UINT16 * from,NJ_UINT16 * to,NJ_UINT8 * forward_flag)2307 static NJ_INT16 search_range_by_yomi2(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT8 op,
2308                                       NJ_CHAR  *yomi, NJ_UINT16 len,
2309                                       NJ_UINT16 sfrom, NJ_UINT16 sto,
2310                                       NJ_UINT16 *from, NJ_UINT16 *to,
2311                                       NJ_UINT8 *forward_flag) {
2312     NJ_UINT16 right, mid = 0, left, max;
2313     NJ_UINT16 que_id;
2314     NJ_UINT8  *ptr, *p;
2315     NJ_CHAR  *str;
2316     NJ_INT16 ret = 0;
2317     NJ_INT32 found = 0;
2318     NJ_UINT8 slen;
2319     NJ_INT32 cmp;
2320 
2321 
2322 
2323     ptr = get_search_index_address(handle, op);
2324 
2325     max = GET_LEARN_WORD_COUNT(handle);
2326 
2327     right = sto;
2328     left = sfrom;
2329 
2330 #ifdef LEARN_DEBUG
2331     printf("src:[%s]\n", yomi);
2332 #endif
2333 
2334     *forward_flag = 0;
2335 
2336     while (left <= right) {
2337         mid = left + ((right - left) / 2);
2338         p = ptr + (mid * NJ_INDEX_SIZE);
2339         que_id = GET_UINT16(p);
2340         str = get_string(iwnn, handle, que_id, &slen);
2341         if (str == NULL) {
2342             return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_DIC_BROKEN);
2343         }
2344 
2345 
2346         ret = nj_strncmp(yomi, str, len);
2347 
2348 #ifdef LEARN_DEBUG
2349         printf("   [%d][%d][%d]COMPARE:[%s] = %d\n", left, mid, right, str, ret);
2350 #endif
2351         if (ret == 0) {
2352 
2353             found = 1;
2354             break;
2355         } else if (ret < 0) {
2356 
2357             right = mid - 1;
2358             if (mid == 0) {
2359                 break;
2360             }
2361         } else {
2362 
2363             left = mid + 1;
2364         }
2365     }
2366 
2367     if (!found) {
2368         return 0;
2369     }
2370 
2371     if (mid == 0) {
2372         *from = mid;
2373     } else {
2374 
2375         p = ((mid - 1) * NJ_INDEX_SIZE) + ptr;
2376 
2377         for (cmp = mid - 1; cmp >= 0; cmp--) {
2378             que_id = GET_UINT16(p);
2379             str = get_string(iwnn, handle, que_id, &slen);
2380             if (str == NULL) {
2381                 return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_DIC_BROKEN);
2382             }
2383 
2384 
2385             if (nj_strncmp(yomi, str, len) != 0) {
2386                 break;
2387             }
2388             p -= NJ_INDEX_SIZE;
2389         }
2390         if (cmp < 0) {
2391             *from = 0;
2392         } else {
2393             *from = (NJ_UINT16)cmp + 1;
2394         }
2395     }
2396 
2397 #ifdef LEARN_DEBUG
2398     printf("  >> from:(%d)\n", *from);
2399 #endif
2400 
2401     if ((mid + 1) >= max) {
2402         *to = mid;
2403     } else {
2404 
2405         p = ((mid + 1) * NJ_INDEX_SIZE) + ptr;
2406 
2407         for (right = mid + 1; right < max; right++) {
2408             que_id = GET_UINT16(p);
2409             str = get_string(iwnn, handle, que_id, &slen);
2410             if (str == NULL) {
2411                 return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_DIC_BROKEN);
2412             }
2413 
2414 
2415             if (nj_strncmp(yomi, str, len) != 0) {
2416                 break;
2417             }
2418             p += NJ_INDEX_SIZE;
2419         }
2420         *to = right - 1;
2421     }
2422 
2423 #ifdef LEARN_DEBUG
2424     printf("  >> to:(%d)\n", *to);
2425 #endif
2426     return 1;
2427 }
2428 
2429