Home | History | Annotate | Download | only in engine
      1 /*
      2  * Copyright (C) 2008,2009  OMRON SOFTWARE Co., Ltd.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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