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 
     23 
     24 #define NODE_TERM(x) ((NJ_UINT8)(0x80 & (*(x))))
     25 #define NODE_LEFT_EXIST(x) ((NJ_UINT8)(0x40 & (*(x))))
     26 #define NODE_DATA_EXIST(x) ((NJ_UINT8)(0x20 & (*(x))))
     27 #define NODE_IDX_EXIST(x) ((NJ_UINT8)(0x10 & (*(x))))
     28 #define NODE_IDX_CNT(x) ((NJ_UINT8)((0x0f & (*(x))) + 2))
     29 
     30 #define STEM_TERMINETER(x) ((NJ_UINT8)(0x80 & (*(x))))
     31 
     32 #define STEM_NO_CONV_FLG(x) ((NJ_UINT8)(0x40 & (*(x))))
     33 
     34 #define TERM_BIT (1)
     35 #define INDEX_BIT (8)
     36 
     37 #define APPEND_YOMI_FLG(h) ((NJ_UINT8)(0x80 & (*((h) + 0x1C))))
     38 #define HINSI_NO_TOP_ADDR(h) ((NJ_UINT8*)((h) + NJ_INT32_READ((h) + 0x1D)))
     39 #define FHINSI_NO_CNT(h) ((NJ_INT16)(NJ_INT16_READ((h) + 0x21)))
     40 #define BHINSI_NO_CNT(h) ((NJ_INT16)(NJ_INT16_READ((h) + 0x23)))
     41 #define HINSI_NO_BYTE(h) ((NJ_UINT8)(*((h) + 0x25)))
     42 #define HINDO_NO_TOP_ADDR(h) ((NJ_UINT8*)((h) + NJ_INT32_READ((h) + 0x26)))
     43 #define HINDO_NO_CNT(h) ((NJ_UINT8)(*((h) + 0x2A)))
     44 #define STEM_AREA_TOP_ADDR(h) ((NJ_UINT8*)((h) + NJ_INT32_READ((h) + 0x2B)))
     45 #define BIT_CANDIDATE_LEN(h) ((NJ_UINT8)(*((h) + 0x2F)))
     46 #define BIT_FHINSI(h) ((NJ_UINT8)(*((h) + 0x30)))
     47 #define BIT_BHINSI(h) ((NJ_UINT8)(*((h) + 0x31)))
     48 #define BIT_HINDO_LEN(h) ((NJ_UINT8)(*((h) + 0x32)))
     49 #define BIT_MUHENKAN_LEN(h) ((NJ_UINT8)(*((h) + 0x33)))
     50 #define BIT_YOMI_LEN(h) ((NJ_UINT8)(*((h) + 0x35)))
     51 #define YOMI_INDX_TOP_ADDR(h) ((NJ_UINT8*)((h) + NJ_INT32_READ((h) + 0x42)))
     52 #define YOMI_INDX_CNT(h) ((NJ_INT16)(*((h) + 0x46)))
     53 #define YOMI_INDX_SIZE(h) ((NJ_INT8)(*((h) + 0x47)))
     54 #define NODE_AREA_TOP_ADDR(h) ((NJ_UINT8*)((h) + NJ_INT32_READ((h) + 0x48)))
     55 #define BIT_NODE_AREA_DATA_LEN(h) ((NJ_UINT8)(*((h) + 0x4C)))
     56 #define BIT_NODE_AREA_LEFT_LEN(h) ((NJ_UINT8)(*((h) + 0x4D)))
     57 #define NODE_AREA_MID_ADDR(h) ((NJ_UINT32)(NJ_INT32_READ((h) + 0x4E)))
     58 #define CAND_IDX_AREA_TOP_ADDR(h) ((NJ_UINT8*)((h) + NJ_INT32_READ((h) + 0x52)))
     59 #define CAND_IDX_AREA_CNT(h) ((NJ_UINT32)(((NJ_INT32_READ((h) + 0x56)) >> 8) & 0x00FFFFFF))
     60 #define CAND_IDX_AREA_SIZE(h) ((NJ_UINT8)(*((h) + 0x59)))
     61 
     62 #define WORD_LEN(x) ((NJ_UINT16)(0x007F & (x)))
     63 
     64 #define CURRENT_INFO_SET ((NJ_UINT8)(0x10))
     65 
     66 #define COMP_DIC_FREQ_DIV 63
     67 
     68 #define LOC_CURRENT_NO_ENTRY  0xffffffffU
     69 
     70 typedef struct {
     71     NJ_UINT16 stem_size;
     72     NJ_UINT16 term;
     73     NJ_UINT16 no_conv_flg;
     74     NJ_HINDO hindo;
     75     NJ_UINT16 hindo_jitu;
     76     NJ_UINT16 candidate_size;
     77     NJ_UINT16 yomi_size;
     78     NJ_UINT16 fhinsi;
     79     NJ_UINT16 bhinsi;
     80     NJ_UINT16 fhinsi_jitu;
     81     NJ_UINT16 bhinsi_jitu;
     82 } STEM_DATA_SET;
     83 
     84 static NJ_INT16 get_stem_next(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data);
     85 static void get_stem_word(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data, STEM_DATA_SET *stem_set, NJ_UINT8 check);
     86 static void get_stem_cand_data(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data, STEM_DATA_SET *stem_set);
     87 static NJ_UINT16 get_stem_yomi_data(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data,STEM_DATA_SET *stem_set);
     88 static NJ_UINT16 get_stem_yomi_size(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data, NJ_UINT16 yomi_size);
     89 static NJ_UINT16 get_stem_yomi_string(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data, NJ_CHAR *yomi, NJ_UINT16 yomi_pos, NJ_UINT16 yomi_size, NJ_UINT16 size);
     90 static NJ_INT16 search_node(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset);
     91 static NJ_INT16 bdic_search_data(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset);
     92 static NJ_INT16 bdic_search_fore_data(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset);
     93 
     94 static NJ_HINDO get_stem_hindo(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data);
     95 
     96 static NJ_INT16 search_node2(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset,
     97                              NJ_UINT16 hidx);
     98 static NJ_INT16 bdic_search_fore_data2(NJ_SEARCH_CONDITION *condition,
     99                                        NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT16 hidx);
    100 static NJ_INT16 search_yomi_node(NJ_UINT8 operation, NJ_UINT8 *node,
    101                                  NJ_UINT8 *now, NJ_UINT16 idx_no,
    102                                  NJ_CHAR  *yomi, NJ_UINT16 yomilen,
    103                                  NJ_UINT8 *root, NJ_UINT8 *node_mid,
    104                                  NJ_UINT16 bit_left, NJ_UINT16 bit_data,
    105                                  NJ_UINT8 *data_top,
    106                                  NJ_INT16 ytbl_cnt, NJ_UINT16 y,
    107                                  NJ_UINT8 *ytbl_top, NJ_CACHE_INFO *storebuf,
    108                                  NJ_UINT8 **con_node, NJ_UINT32 *data_offset);
    109 static NJ_INT16 get_node_bottom(NJ_CHAR *yomi, NJ_UINT8 *now, NJ_UINT8 *node_mid,
    110                                 NJ_UINT8 *data_top, NJ_UINT16 bit_left,
    111                                 NJ_UINT16 bit_data, NJ_UINT32 top,
    112                                 NJ_DIC_HANDLE handle, NJ_UINT32 *ret_bottom);
    113 static NJ_INT16 bdic_get_next_data(NJ_UINT8 *data_top, NJ_UINT8 *data_end,
    114                                    NJ_SEARCH_LOCATION_SET *loctset,
    115                                    NJ_SEARCH_CACHE *psrhCache, NJ_UINT16 abIdx);
    116 static NJ_INT16 bdic_get_word_freq(NJ_UINT8 *data_top, NJ_SEARCH_LOCATION_SET *loctset,
    117                                    NJ_SEARCH_CACHE *psrhCache, NJ_UINT16 abIdx);
    118 
    119 static NJ_HINDO get_stem_hindo(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data)
    120 {
    121     NJ_UINT8 flg_bit;
    122     NJ_UINT16 data;
    123     NJ_UINT16 pos, j, bit_all;
    124 
    125 
    126 
    127     flg_bit = BIT_MUHENKAN_LEN(hdl);
    128     if (NJ_GET_DIC_FMT(hdl) != NJ_DIC_FMT_KANAKAN) {
    129         flg_bit++;
    130     }
    131 
    132     if (BIT_HINDO_LEN(hdl)) {
    133 
    134         bit_all = (NJ_UINT16)(TERM_BIT + flg_bit);
    135         pos = (NJ_UINT16)(bit_all >> 3);
    136         data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos));
    137 
    138 
    139         j = (NJ_UINT16)(bit_all & 0x0007);
    140 
    141         return GET_BITFIELD_16(data, j, BIT_HINDO_LEN(hdl));
    142     } else {
    143 
    144         return 0;
    145     }
    146 }
    147 
    148 static NJ_INT16 get_stem_next(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data)
    149 {
    150     NJ_UINT8 flg_bit;
    151     NJ_UINT16 data;
    152     NJ_UINT16 pos, j, bit_all;
    153     NJ_UINT16 stem_size, cand_bit, yomi_bit;
    154     NJ_UINT16 candidate_size, yomi_size;
    155 
    156 
    157 
    158     flg_bit = BIT_MUHENKAN_LEN(hdl);
    159     if (NJ_GET_DIC_FMT(hdl) != NJ_DIC_FMT_KANAKAN) {
    160         flg_bit++;
    161     }
    162 
    163 
    164 
    165     bit_all = (NJ_UINT16)(TERM_BIT + flg_bit +
    166                           BIT_HINDO_LEN(hdl) +
    167                           BIT_FHINSI(hdl) +
    168                           BIT_BHINSI(hdl));
    169     pos = (NJ_UINT16)(bit_all >> 3);
    170     data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos));
    171 
    172 
    173     j = (NJ_UINT16)(bit_all & 0x0007);
    174     cand_bit = BIT_CANDIDATE_LEN(hdl);
    175 
    176     candidate_size = GET_BITFIELD_16(data, j, cand_bit);
    177     bit_all += cand_bit;
    178 
    179 
    180     if (APPEND_YOMI_FLG(hdl) && STEM_TERMINETER(stem_data)) {
    181 
    182 
    183         pos = (NJ_UINT16)(bit_all >> 3);
    184         data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos));
    185 
    186 
    187         j = (NJ_UINT16)(bit_all & 0x0007);
    188         yomi_bit = BIT_YOMI_LEN(hdl);
    189 
    190         yomi_size = GET_BITFIELD_16(data, j, yomi_bit);
    191         bit_all += yomi_bit;
    192     } else {
    193         yomi_size = 0;
    194     }
    195 
    196 
    197     stem_size = GET_BIT_TO_BYTE(bit_all);
    198 
    199 
    200     stem_size += candidate_size;
    201 
    202 
    203     stem_size += yomi_size;
    204 
    205 
    206     return stem_size;
    207 }
    208 
    209 static void get_stem_word(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data, STEM_DATA_SET *stem_set, NJ_UINT8 check)
    210 {
    211     NJ_UINT8 flg_bit;
    212     NJ_UINT16 data;
    213     NJ_UINT16 pos, j, bit_all = 0;
    214     NJ_UINT16 bit;
    215     NJ_UINT16 dpos = 0;
    216     NJ_INT16 next;
    217     NJ_UINT8 b;
    218     NJ_UINT8 *wkc;
    219 
    220 
    221 
    222     flg_bit = BIT_MUHENKAN_LEN(hdl);
    223     if (NJ_GET_DIC_FMT(hdl) != NJ_DIC_FMT_KANAKAN) {
    224         flg_bit++;
    225     }
    226 
    227     if (BIT_HINDO_LEN(hdl)) {
    228 
    229         bit_all = (NJ_UINT16)(TERM_BIT + flg_bit);
    230         pos = (NJ_UINT16)(bit_all >> 3);
    231         data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos));
    232 
    233 
    234         j = (NJ_UINT16)(bit_all & 0x0007);
    235 
    236         stem_set->hindo = GET_BITFIELD_16(data, j, BIT_HINDO_LEN(hdl));
    237     } else {
    238 
    239         stem_set->hindo = 0;
    240     }
    241 
    242     stem_set->hindo_jitu = (NJ_UINT16)(*(HINDO_NO_TOP_ADDR(hdl) + stem_set->hindo));
    243 
    244     if (BIT_FHINSI(hdl)) {
    245 
    246 
    247         bit_all = (NJ_UINT16)(TERM_BIT + flg_bit + BIT_HINDO_LEN(hdl));
    248         pos = (NJ_UINT16)(bit_all >> 3);
    249         data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos));
    250 
    251 
    252         j = (NJ_UINT16)(bit_all & 0x0007);
    253 
    254         stem_set->fhinsi = GET_BITFIELD_16(data, j, BIT_FHINSI(hdl));
    255     } else {
    256         stem_set->fhinsi = 0;
    257     }
    258 
    259 
    260     b = HINSI_NO_BYTE(hdl);
    261     wkc = (NJ_UINT8*)(HINSI_NO_TOP_ADDR(hdl) + (b * (NJ_UINT16)(stem_set->fhinsi)));
    262 
    263 
    264     if (b == 2) {
    265         stem_set->fhinsi_jitu = (NJ_UINT16)(NJ_INT16_READ(wkc));
    266     } else {
    267         stem_set->fhinsi_jitu = (NJ_UINT16)*wkc;
    268     }
    269 
    270     if (BIT_BHINSI(hdl)) {
    271 
    272 
    273         bit_all = (NJ_UINT16)(TERM_BIT + flg_bit + BIT_HINDO_LEN(hdl) + BIT_FHINSI(hdl));
    274         pos = (NJ_UINT16)(bit_all >> 3);
    275         data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos));
    276 
    277 
    278         j = (NJ_UINT16)(bit_all & 0x0007);
    279 
    280         stem_set->bhinsi = GET_BITFIELD_16(data, j, BIT_BHINSI(hdl));
    281     } else {
    282         stem_set->bhinsi = 0;
    283     }
    284 
    285     wkc = (NJ_UINT8*)(HINSI_NO_TOP_ADDR(hdl)
    286                       + (b * (FHINSI_NO_CNT(hdl) + (NJ_UINT16)(stem_set->bhinsi))));
    287 
    288     if (b == 2) {
    289         stem_set->bhinsi_jitu = (NJ_UINT16)(NJ_INT16_READ(wkc));
    290     } else {
    291         stem_set->bhinsi_jitu = (NJ_UINT16)*wkc;
    292     }
    293 
    294 
    295     if (check != 1) {
    296 
    297 
    298         bit_all = (NJ_UINT16)(TERM_BIT + flg_bit +
    299                               BIT_HINDO_LEN(hdl) +
    300                               BIT_FHINSI(hdl) +
    301                               BIT_BHINSI(hdl));
    302         pos = (NJ_UINT16)(bit_all >> 3);
    303         data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos));
    304 
    305 
    306         j = (NJ_UINT16)(bit_all & 0x0007);
    307         bit = BIT_CANDIDATE_LEN(hdl);
    308 
    309         stem_set->candidate_size = GET_BITFIELD_16(data, j, bit);
    310         bit_all += bit;
    311     }
    312 
    313     if (check == 0) {
    314         stem_set->yomi_size = 0;
    315 
    316 
    317         if (APPEND_YOMI_FLG(hdl) && STEM_TERMINETER(stem_data)) {
    318             pos = (NJ_UINT16)(bit_all >> 3);
    319             data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos));
    320 
    321 
    322             j = (NJ_UINT16)(bit_all & 0x0007);
    323             bit = BIT_YOMI_LEN(hdl);
    324 
    325             stem_set->yomi_size = GET_BITFIELD_16(data, j, bit);
    326             bit_all += bit;
    327 
    328 
    329 
    330             dpos = GET_BIT_TO_BYTE(bit_all);
    331             dpos += stem_set->candidate_size;
    332 
    333         } else if (APPEND_YOMI_FLG(hdl)) {
    334             while (!(STEM_TERMINETER(stem_data))) {
    335                 next = get_stem_next(hdl, stem_data);
    336                 stem_data += next;
    337             }
    338 
    339             dpos = get_stem_yomi_data(hdl, stem_data, stem_set);
    340         }
    341 
    342         if (stem_set->yomi_size) {
    343 
    344             stem_set->yomi_size = get_stem_yomi_size(hdl, stem_data + dpos, stem_set->yomi_size);
    345         }
    346     }
    347 }
    348 
    349 static void get_stem_cand_data(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data, STEM_DATA_SET *stem_set)
    350 {
    351     NJ_UINT8 flg_bit;
    352     NJ_UINT16 data;
    353     NJ_UINT16 pos, j, bit_all;
    354     NJ_UINT16 cand_bit, yomi_bit;
    355 
    356 
    357 
    358     flg_bit = BIT_MUHENKAN_LEN(hdl);
    359     if (NJ_GET_DIC_FMT(hdl) != NJ_DIC_FMT_KANAKAN) {
    360         flg_bit++;
    361     }
    362 
    363 
    364 
    365     bit_all = (NJ_UINT16)(TERM_BIT + flg_bit +
    366                           BIT_HINDO_LEN(hdl) +
    367                           BIT_FHINSI(hdl) +
    368                           BIT_BHINSI(hdl));
    369     pos = (NJ_UINT16)(bit_all >> 3);
    370     data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos));
    371 
    372 
    373     cand_bit = BIT_CANDIDATE_LEN(hdl);
    374     j = (NJ_UINT16)(bit_all & 0x0007);
    375 
    376     stem_set->candidate_size = GET_BITFIELD_16(data, j, cand_bit);
    377     bit_all += cand_bit;
    378 
    379 
    380     if (APPEND_YOMI_FLG(hdl) && STEM_TERMINETER(stem_data)) {
    381 
    382         yomi_bit = BIT_YOMI_LEN(hdl);
    383         bit_all += yomi_bit;
    384     }
    385 
    386 
    387     stem_set->stem_size = GET_BIT_TO_BYTE(bit_all);
    388 }
    389 
    390 static NJ_UINT16 get_stem_yomi_data(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data,STEM_DATA_SET *stem_set)
    391 {
    392     NJ_UINT16 flg_bit;
    393     NJ_UINT16 data;
    394     NJ_UINT16 cand_bit, yomi_bit;
    395     NJ_UINT16 pos, j, bit_all;
    396     NJ_UINT16 yomi_pos;
    397     NJ_UINT16 candidate_size;
    398 
    399 
    400 
    401     flg_bit = BIT_MUHENKAN_LEN(hdl);
    402     if (NJ_GET_DIC_FMT(hdl) != NJ_DIC_FMT_KANAKAN) {
    403         flg_bit++;
    404     }
    405 
    406 
    407 
    408     bit_all = (NJ_UINT16)(TERM_BIT + flg_bit + BIT_HINDO_LEN(hdl) +
    409                           BIT_FHINSI(hdl) + BIT_BHINSI(hdl));
    410     pos = (NJ_UINT16)(bit_all >> 3);
    411     data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos));
    412 
    413 
    414     j = (NJ_UINT16)(bit_all & 0x0007);
    415 
    416     cand_bit = BIT_CANDIDATE_LEN(hdl);
    417     candidate_size = GET_BITFIELD_16(data, j, cand_bit);
    418 
    419 
    420     bit_all += cand_bit;
    421 
    422 
    423     if (APPEND_YOMI_FLG(hdl) && STEM_TERMINETER(stem_data)) {
    424 
    425 
    426         pos = (NJ_UINT16)(bit_all >> 3);
    427         data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos));
    428 
    429 
    430         j = (NJ_UINT16)(bit_all & 0x0007);
    431         yomi_bit = BIT_YOMI_LEN(hdl);
    432 
    433         stem_set->yomi_size = GET_BITFIELD_16(data, j, yomi_bit);
    434         bit_all += yomi_bit;
    435     } else {
    436         stem_set->yomi_size = 0;
    437     }
    438 
    439 
    440 
    441     yomi_pos = GET_BIT_TO_BYTE(bit_all);
    442     yomi_pos += candidate_size;
    443 
    444     return yomi_pos;
    445 }
    446 
    447 static NJ_UINT16 get_stem_yomi_size(NJ_DIC_HANDLE hdl, NJ_UINT8 *ydata, NJ_UINT16 yomi_size)
    448 {
    449     NJ_INT16 ytbl_cnt;
    450     NJ_INT8 ysize;
    451     NJ_UINT8 *ytbl_top;
    452     NJ_UINT8 *ytbl;
    453     NJ_UINT8 yidx;
    454     NJ_UINT16 i;
    455     NJ_UINT16 len;
    456 
    457 
    458 
    459     ytbl_cnt = YOMI_INDX_CNT(hdl);
    460 
    461     if (ytbl_cnt) {
    462     ysize = YOMI_INDX_SIZE(hdl);
    463     ytbl_top = YOMI_INDX_TOP_ADDR(hdl);
    464 
    465         len = 0;
    466         for (i = 0; i < yomi_size; i++) {
    467             if (ysize == 2) {
    468 
    469                 yidx = *(ydata+i);
    470                 ytbl = ytbl_top + ((yidx-1) * ysize);
    471                 len += UTL_CHAR(ytbl);
    472 
    473             } else {
    474 
    475                 len++;
    476             }
    477         }
    478 
    479         return len * sizeof(NJ_CHAR);
    480     } else {
    481 
    482         return yomi_size;
    483     }
    484 }
    485 
    486 static NJ_UINT16 get_stem_yomi_string(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data, NJ_CHAR *yomi, NJ_UINT16 yomi_pos, NJ_UINT16 yomi_size, NJ_UINT16 size)
    487 {
    488     NJ_INT16 ytbl_cnt;
    489     NJ_INT8 ysize;
    490     NJ_UINT8 *ytbl_top, *ytbl;
    491     NJ_UINT8 *ydata;
    492     NJ_UINT8 yidx;
    493     NJ_UINT16 i;
    494     NJ_UINT16 copy_len;
    495     NJ_UINT16 char_len;
    496 
    497 
    498 
    499     ytbl_cnt = YOMI_INDX_CNT(hdl);
    500     ysize    = YOMI_INDX_SIZE(hdl);
    501     ytbl_top = YOMI_INDX_TOP_ADDR(hdl);
    502 
    503 
    504     ydata = stem_data + yomi_pos;
    505 
    506     if (ytbl_cnt) {
    507         copy_len = 0;
    508         for (i = 0; i < yomi_size; i++) {
    509 
    510             yidx = *(ydata + i);
    511             ytbl = ytbl_top + ((yidx - 1) * ysize);
    512             if (ysize == 2) {
    513 
    514                 char_len = UTL_CHAR(ytbl);
    515                 if (((copy_len + char_len + NJ_TERM_LEN) * sizeof(NJ_CHAR)) > size) {
    516                     return size;
    517                 }
    518                 while (char_len > 0) {
    519                     NJ_CHAR_COPY(yomi + copy_len, ytbl);
    520                     copy_len++;
    521                     char_len--;
    522                     ytbl += sizeof(NJ_CHAR);
    523                 }
    524             } else {
    525 
    526                 if (((copy_len + 1 + NJ_TERM_LEN) * sizeof(NJ_CHAR)) > size) {
    527                     return size;
    528                 }
    529 
    530                 *(yomi + copy_len) = (NJ_CHAR)(*ytbl);
    531                 copy_len++;
    532             }
    533         }
    534     } else {
    535         if ((yomi_size + (NJ_TERM_LEN * sizeof(NJ_CHAR))) > size) {
    536             return size;
    537         }
    538 
    539         nj_memcpy((NJ_UINT8*)yomi, ydata, yomi_size);
    540         copy_len = yomi_size / sizeof(NJ_CHAR);
    541     }
    542 
    543 
    544     *(yomi + copy_len) = NJ_CHAR_NUL;
    545 
    546 
    547     return copy_len;
    548 }
    549 
    550 static NJ_INT16 search_node(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset)
    551 {
    552     NJ_UINT8 *root, *now, *node, *node_mid;
    553     NJ_UINT8 index;
    554     NJ_UINT8 *byomi;
    555     NJ_UINT8 *wkc;
    556     NJ_UINT8 idx_no;
    557     NJ_INT16 idx;
    558     NJ_INT16 char_size;
    559     NJ_INT16 left, right, mid;
    560     NJ_INT16 ytbl_cnt;
    561     NJ_UINT16 c, d;
    562     NJ_UINT8  c1 = 0, c2 = 0;
    563     NJ_UINT16 y;
    564     NJ_UINT16 ysize = (condition->ylen * sizeof(NJ_CHAR));
    565     NJ_UINT8 *ytbl_top;
    566     NJ_UINT16 idx_cnt;
    567     NJ_UINT16 nd_index;
    568     NJ_UINT16 bit_left, bit_data;
    569     NJ_UINT32 data_offset;
    570     NJ_UINT16 data;
    571     NJ_UINT16 pos, j, bit_all, bit_tmp, bit_idx;
    572     NJ_UINT32 data_l;
    573     NJ_UINT8 restart_flg = 0;
    574     NJ_UINT8 bottom_flg = 0;
    575     NJ_UINT8 *data_top, *stem_data;
    576     NJ_UINT16 hindo, hindo_max;
    577     NJ_UINT32 current,hindo_max_data, bottom, next;
    578 
    579 
    580     node = NULL;
    581 
    582     byomi = (NJ_UINT8*)(condition->yomi);
    583 
    584 
    585     root = NODE_AREA_TOP_ADDR(loctset->loct.handle);
    586 
    587 
    588     node_mid = root + NODE_AREA_MID_ADDR(loctset->loct.handle);
    589     now = node_mid;
    590 
    591 
    592     idx_no = 0;
    593     idx_cnt = 1;
    594 
    595     bit_left = BIT_NODE_AREA_LEFT_LEN(loctset->loct.handle);
    596     bit_data = BIT_NODE_AREA_DATA_LEN(loctset->loct.handle);
    597 
    598     ytbl_cnt = YOMI_INDX_CNT(loctset->loct.handle);
    599     y = YOMI_INDX_SIZE(loctset->loct.handle);
    600     ytbl_top = YOMI_INDX_TOP_ADDR(loctset->loct.handle);
    601 
    602     data_top = STEM_AREA_TOP_ADDR(loctset->loct.handle);
    603 
    604 
    605     if ((condition->operation == NJ_CUR_OP_FORE) &&
    606         NJ_CHAR_STRLEN_IS_0(condition->yomi)) {
    607 
    608         ysize = 0;
    609 
    610 
    611         node = root;
    612     }
    613 
    614 
    615     while (ysize > 0) {
    616         if (ytbl_cnt != 0) {
    617             char_size = UTL_CHAR(byomi) * sizeof(NJ_CHAR);
    618             if (char_size > 2) {
    619                 loctset->loct.status = NJ_ST_SEARCH_END_EXT;
    620                 return 0;
    621             }
    622 
    623             if (char_size == 2) {
    624                 if (y == 1) {
    625                     return 0;
    626                 }
    627                 c1 = *byomi;
    628                 c2 = *(byomi + 1);
    629                 c = (NJ_UINT16)((c1 << 8) | c2);
    630             } else {
    631 
    632                 c1 = *byomi;
    633                 c2 = 0x00;
    634                 c = (NJ_UINT16)(*byomi);
    635             }
    636 
    637             idx = -1;
    638             left = 0;
    639             right = ytbl_cnt;
    640 
    641             if (y == 2) {
    642                 while (left <= right) {
    643                     mid = (left + right) >> 1;
    644                     wkc = ytbl_top + (mid << 1);
    645 
    646                     if (c1 == *wkc) {
    647                         if (c2 == *(wkc + 1)) {
    648                             idx = (NJ_UINT16)(mid + 1);
    649                             break;
    650                         }
    651                         if (c2 < *(wkc + 1)) {
    652                             right = mid - 1;
    653                         } else {
    654                             left = mid + 1;
    655                         }
    656                     } else if (c1 < *wkc) {
    657                         right = mid - 1;
    658                     } else {
    659                         left = mid + 1;
    660                     }
    661                 }
    662             } else {
    663                 while (left <= right) {
    664                     mid = (left + right) >> 1;
    665                     wkc = ytbl_top + (mid * y);
    666                     d = (NJ_UINT16)(*wkc);
    667                     if (c == d) {
    668                         idx = (NJ_UINT16)(mid + 1);
    669                         break;
    670                     }
    671                     if (c < d) {
    672                         right = mid - 1;
    673                     } else {
    674                         left = mid + 1;
    675                     }
    676                 }
    677             }
    678 
    679             if (idx < 0) {
    680                 loctset->loct.status = NJ_ST_SEARCH_END_EXT;
    681                 return 0;
    682             }
    683             index = (NJ_UINT8)idx;
    684         } else {
    685             index = *byomi;
    686             char_size = 1;
    687         }
    688 
    689         byomi += char_size;
    690         ysize -= char_size;
    691 
    692         while (now < data_top) {
    693             if (NODE_IDX_EXIST(now)) {
    694                 bit_idx = 8;
    695                 idx_cnt = NODE_IDX_CNT(now);
    696             } else {
    697                 bit_idx = 4;
    698                 idx_cnt = 1;
    699             }
    700             bit_all = bit_idx;
    701 
    702 
    703             if (NODE_LEFT_EXIST(now)) {
    704                 bit_all += bit_left;
    705             }
    706 
    707 
    708             if (NODE_DATA_EXIST(now)) {
    709                 bit_all += bit_data;
    710             }
    711 
    712             bit_tmp = bit_all;
    713 
    714 
    715             bit_all += (NJ_UINT16)(idx_no << 3);
    716 
    717 
    718             pos = (NJ_UINT16)(bit_all >> 3);
    719 
    720             data = (NJ_UINT16)(NJ_INT16_READ(now + pos));
    721 
    722 
    723             j = (NJ_UINT16)(bit_all & 0x0007);
    724 
    725             nd_index = GET_BITFIELD_16(data, j, INDEX_BIT);
    726             if (index == (NJ_UINT8)nd_index) {
    727 
    728                 break;
    729             } else {
    730                 if ((!NODE_TERM(now)) && (index > (NJ_UINT8)nd_index) && (idx_no == 0)) {
    731 
    732                     now += GET_BIT_TO_BYTE(bit_tmp + (idx_cnt * 8));
    733                     if (now == node_mid) {
    734                         loctset->loct.status = NJ_ST_SEARCH_END_EXT;
    735                         return 0;
    736                     }
    737                     continue;
    738                 } else {
    739                     if ((now == node_mid) && (restart_flg == 0) &&
    740                         (index < (NJ_UINT8)nd_index) && (idx_no == 0) &&
    741                         (root != node_mid)) {
    742                         now = root;
    743                         idx_no = 0;
    744                         restart_flg = 1;
    745                         continue;
    746                     }
    747                     loctset->loct.status = NJ_ST_SEARCH_END_EXT;
    748                     return 0;
    749                 }
    750             }
    751         }
    752 
    753         if ( (idx_cnt > (NJ_UINT16)(idx_no + 1))) {
    754             if (ysize == 0) {
    755                 if (condition->operation == NJ_CUR_OP_FORE) {
    756 
    757                     node = now;
    758                     break;
    759                 }
    760                 loctset->loct.status = NJ_ST_SEARCH_END;
    761                 return 0;
    762             }
    763             idx_no++;
    764             continue;
    765         }
    766         node = now;
    767         idx_no = 0;
    768 
    769         if (ysize == 0) {
    770             break;
    771         } else {
    772             if (!(NODE_LEFT_EXIST(now))) {
    773                 loctset->loct.status = NJ_ST_SEARCH_END_EXT;
    774                 return 0;
    775             }
    776         }
    777 
    778         if (NODE_IDX_EXIST(now)) {
    779             bit_idx = 8;
    780         } else {
    781             bit_idx = 4;
    782         }
    783         pos = (NJ_UINT16)(bit_idx >> 3);
    784         data_l = (NJ_UINT32)(NJ_INT32_READ(now + pos));
    785 
    786 
    787         j = (NJ_UINT16)(bit_idx & 0x0007);
    788 
    789         now += GET_BITFIELD_32(data_l, j, bit_left);
    790     }
    791 
    792 
    793     now = node;
    794 
    795 
    796     if ((node == NULL) || !(NODE_DATA_EXIST(node))) {
    797 
    798         if ((condition->operation == NJ_CUR_OP_FORE) &&
    799             (node != NULL)) {
    800             while (!NODE_DATA_EXIST(node)) {
    801                 if (!(NODE_LEFT_EXIST(node))) {
    802                     loctset->loct.status = NJ_ST_SEARCH_END;
    803                     return 0;
    804                 }
    805 
    806                 if (NODE_IDX_EXIST(node)) {
    807                     bit_idx = 8;
    808                 } else {
    809                     bit_idx = 4;
    810                 }
    811                 pos = (NJ_UINT16)(bit_idx >> 3);
    812                 data_l = (NJ_UINT32)(NJ_INT32_READ(node + pos));
    813 
    814 
    815                 j = (NJ_UINT16)(bit_idx & 0x0007);
    816                 node += GET_BITFIELD_32(data_l, j, bit_left);
    817             }
    818         } else {
    819             loctset->loct.status = NJ_ST_SEARCH_END;
    820             return 0;
    821         }
    822     }
    823 
    824     if (NODE_IDX_EXIST(node)) {
    825         bit_idx = 8;
    826     } else {
    827         bit_idx = 4;
    828     }
    829 
    830 
    831     if (NODE_LEFT_EXIST(node)) {
    832         bit_all = bit_idx + bit_left;
    833     } else {
    834         bit_all = bit_idx;
    835     }
    836 
    837     pos = (NJ_UINT16)(bit_all >> 3);
    838     data_l = (NJ_UINT32)(NJ_INT32_READ(node + pos));
    839 
    840 
    841     j = (NJ_UINT16)(bit_all & 0x0007);
    842     data_offset = GET_BITFIELD_32(data_l, j, bit_data);
    843 
    844     loctset->loct.top = data_offset;
    845     loctset->loct.current = 0;
    846 
    847     if (condition->operation == NJ_CUR_OP_FORE) {
    848 
    849         bottom = loctset->loct.top;
    850 
    851         if (NJ_CHAR_STRLEN_IS_0(condition->yomi)) {
    852             node = node_mid;
    853 
    854         } else {
    855 
    856             node = now;
    857             if (NODE_LEFT_EXIST(node)) {
    858                 if (NODE_IDX_EXIST(node)) {
    859                     bit_all = 8;
    860                 } else {
    861                     bit_all = 4;
    862                 }
    863 
    864                 pos = (NJ_UINT16)(bit_all >> 3);
    865                 data_l = (NJ_UINT32)(NJ_INT32_READ(node + pos));
    866 
    867 
    868                 j = (NJ_UINT16)(bit_all & 0x0007);
    869                 node += GET_BITFIELD_32(data_l, j, bit_left);
    870 
    871             } else {
    872                 bottom_flg = 1;
    873             }
    874         }
    875 
    876         if (!bottom_flg) {
    877             while (node < data_top) {
    878 
    879                 if (!NODE_TERM(node)) {
    880 
    881                     if (NODE_IDX_EXIST(node)) {
    882                         bit_all = 8;
    883                         idx_cnt = NODE_IDX_CNT(node);
    884                     } else {
    885                         bit_all = 4;
    886                         idx_cnt = 1;
    887                     }
    888 
    889 
    890                     if (NODE_LEFT_EXIST(node)) {
    891                         bit_all += bit_left;
    892                     }
    893 
    894 
    895                     if (NODE_DATA_EXIST(node)) {
    896                         bit_all += bit_data;
    897                     }
    898 
    899 
    900                     node += GET_BIT_TO_BYTE(bit_all + (idx_cnt * 8));
    901                 } else {
    902 
    903                     if (!NODE_LEFT_EXIST(node)) {
    904 
    905                         if (NODE_DATA_EXIST(node)) {
    906 
    907                             if (NODE_IDX_EXIST(node)) {
    908                                 bit_all = 8;
    909                             } else {
    910                                 bit_all = 4;
    911                             }
    912 
    913                             pos = (NJ_UINT16)(bit_all >> 3);
    914                             data_l = (NJ_UINT32)(NJ_INT32_READ(node + pos));
    915 
    916 
    917                             j = (NJ_UINT16)(bit_all & 0x0007);
    918                             data_offset = GET_BITFIELD_32(data_l, j, bit_data);
    919 
    920                             bottom = data_offset;
    921                             break;
    922                         } else {
    923                             return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_DIC_BROKEN);
    924                         }
    925 
    926                     } else {
    927 
    928                         if (NODE_IDX_EXIST(node)) {
    929                             bit_all = 8;
    930                         } else {
    931                             bit_all = 4;
    932                         }
    933 
    934                         pos = (NJ_UINT16)(bit_all >> 3);
    935                         data_l = (NJ_UINT32)(NJ_INT32_READ(node + pos));
    936 
    937 
    938                         j = (NJ_UINT16)(bit_all & 0x0007);
    939 
    940 
    941                         node += GET_BITFIELD_32(data_l, j, bit_left);
    942                     }
    943                 }
    944             }
    945         }
    946 
    947         stem_data = data_top + bottom;
    948 
    949         while (!(STEM_TERMINETER(stem_data))) {
    950             next = get_stem_next(loctset->loct.handle, stem_data);
    951             stem_data += next;
    952         }
    953         loctset->loct.bottom = (NJ_UINT32)(stem_data - data_top);
    954 
    955 
    956         stem_data = data_top + loctset->loct.top;
    957 
    958         hindo = (NJ_UINT16) *((NJ_UINT8*)(HINDO_NO_TOP_ADDR(loctset->loct.handle)
    959                                           + get_stem_hindo(loctset->loct.handle, stem_data)));
    960 
    961         hindo_max = hindo;
    962         hindo_max_data = 0;
    963 
    964         if (condition->mode == NJ_CUR_MODE_FREQ) {
    965 
    966 
    967             j = get_stem_next(loctset->loct.handle, stem_data);
    968             current = j;
    969             stem_data += j;
    970 
    971             while (stem_data <= (data_top + loctset->loct.bottom)) {
    972 
    973 
    974                 hindo = (NJ_UINT16) *((NJ_UINT8*)(HINDO_NO_TOP_ADDR(loctset->loct.handle)
    975                                                   + get_stem_hindo(loctset->loct.handle, stem_data)));
    976 
    977 
    978                 if (hindo > hindo_max) {
    979                     hindo_max = hindo;
    980                     hindo_max_data = current;
    981                 }
    982 
    983 
    984                 j = get_stem_next(loctset->loct.handle, stem_data);
    985                 current += j;
    986                 stem_data += j;
    987             }
    988         }
    989         loctset->cache_freq = CALCULATE_HINDO(hindo_max, loctset->dic_freq.base,
    990                                               loctset->dic_freq.high, COMP_DIC_FREQ_DIV);
    991         loctset->loct.current = hindo_max_data;
    992 
    993     }
    994 
    995     return 1;
    996 }
    997 
    998 static NJ_INT16 bdic_search_data(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset)
    999 {
   1000     NJ_UINT8 *data, *data_end;
   1001     NJ_INT16 i, current = 0;
   1002     NJ_UINT16 hindo;
   1003 
   1004 
   1005     data = STEM_AREA_TOP_ADDR(loctset->loct.handle);
   1006     data += loctset->loct.top + loctset->loct.current;
   1007 
   1008     if (GET_LOCATION_STATUS(loctset->loct.status) != NJ_ST_SEARCH_NO_INIT) {
   1009 
   1010         if (STEM_TERMINETER(data)) {
   1011 
   1012             loctset->loct.status = NJ_ST_SEARCH_END;
   1013             return 0;
   1014         }
   1015 
   1016 
   1017         i = get_stem_next(loctset->loct.handle, data);
   1018 
   1019         data += i;
   1020         current += i;
   1021     }
   1022 
   1023     if (NJ_GET_DIC_FMT(loctset->loct.handle) == NJ_DIC_FMT_KANAKAN) {
   1024         data_end = loctset->loct.handle
   1025             + NJ_DIC_COMMON_HEADER_SIZE
   1026             + NJ_INT32_READ(loctset->loct.handle + NJ_DIC_POS_DATA_SIZE)
   1027             + NJ_INT32_READ(loctset->loct.handle + NJ_DIC_POS_EXT_SIZE)
   1028             - NJ_DIC_ID_LEN;
   1029     } else {
   1030         data_end = CAND_IDX_AREA_TOP_ADDR(loctset->loct.handle);
   1031     }
   1032 
   1033     if (data < data_end) {
   1034 
   1035         loctset->loct.status = NJ_ST_SEARCH_READY;
   1036         loctset->loct.current += current;
   1037         hindo = (NJ_UINT16) *((NJ_UINT8*)(HINDO_NO_TOP_ADDR(loctset->loct.handle) +
   1038                                           get_stem_hindo(loctset->loct.handle, data)));
   1039         loctset->cache_freq = CALCULATE_HINDO(hindo, loctset->dic_freq.base,
   1040                                               loctset->dic_freq.high, COMP_DIC_FREQ_DIV);
   1041         return 1;
   1042     }
   1043 
   1044     loctset->loct.status = NJ_ST_SEARCH_END;
   1045     return 0;
   1046 }
   1047 
   1048 static NJ_INT16 bdic_search_fore_data(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset)
   1049 {
   1050     NJ_UINT8 *data, *data_top, *bottom, *data_end;
   1051     NJ_INT16 i = 0;
   1052     NJ_INT16 hindo = 0;
   1053     NJ_INT16 hindo_max = -1;
   1054     NJ_UINT8 no_hit = 0;
   1055     NJ_UINT32 current = loctset->loct.current;
   1056     NJ_UINT8 *current_org;
   1057     NJ_UINT32 hindo_data = 0;
   1058 
   1059 
   1060 
   1061     if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_NO_INIT) {
   1062         loctset->loct.status = NJ_ST_SEARCH_READY;
   1063         loctset->loct.current_info = CURRENT_INFO_SET;
   1064         return 1;
   1065     }
   1066 
   1067 
   1068     data_top = STEM_AREA_TOP_ADDR(loctset->loct.handle);
   1069 
   1070 
   1071     data = data_top + loctset->loct.top + loctset->loct.current;
   1072 
   1073 
   1074     current_org = data;
   1075 
   1076 
   1077     bottom = data_top + loctset->loct.bottom;
   1078 
   1079     if (NJ_GET_DIC_FMT(loctset->loct.handle) == NJ_DIC_FMT_KANAKAN) {
   1080         data_end = loctset->loct.handle
   1081             + NJ_DIC_COMMON_HEADER_SIZE
   1082             + NJ_INT32_READ(loctset->loct.handle + NJ_DIC_POS_DATA_SIZE)
   1083             + NJ_INT32_READ(loctset->loct.handle + NJ_DIC_POS_EXT_SIZE)
   1084             - NJ_DIC_ID_LEN;
   1085     } else {
   1086         data_end = CAND_IDX_AREA_TOP_ADDR(loctset->loct.handle);
   1087     }
   1088 
   1089     if (condition->mode == NJ_CUR_MODE_FREQ) {
   1090 
   1091 
   1092 
   1093         while (data < data_end) {
   1094 
   1095             i = get_stem_next(loctset->loct.handle, data);
   1096             data += i;
   1097             current += i;
   1098 
   1099 
   1100             if (data > bottom) {
   1101                 if (loctset->cache_freq == 0) {
   1102 
   1103                     loctset->loct.status = NJ_ST_SEARCH_END;
   1104                     return 0;
   1105                 } else if (no_hit == 1) {
   1106 
   1107                     loctset->loct.status = NJ_ST_SEARCH_END;
   1108                     return 0;
   1109                 }
   1110 
   1111                 loctset->cache_freq -= 1;
   1112 
   1113 
   1114                 data = data_top + loctset->loct.top;
   1115                 current = 0;
   1116 
   1117                 no_hit = 1;
   1118             }
   1119 
   1120 
   1121             if ((hindo_max != -1) && (data == current_org)) {
   1122                 loctset->loct.status = NJ_ST_SEARCH_READY;
   1123                 loctset->loct.current_info = CURRENT_INFO_SET;
   1124                 loctset->loct.current = hindo_data;
   1125                 loctset->cache_freq = hindo_max;
   1126                 return 1;
   1127             }
   1128 
   1129 
   1130             hindo = (NJ_INT16) *((NJ_UINT8*)(HINDO_NO_TOP_ADDR(loctset->loct.handle) + get_stem_hindo(loctset->loct.handle, data)));
   1131 
   1132             hindo = CALCULATE_HINDO(hindo, loctset->dic_freq.base,
   1133                                     loctset->dic_freq.high, COMP_DIC_FREQ_DIV);
   1134 
   1135 
   1136             if (hindo == loctset->cache_freq) {
   1137                 loctset->loct.status = NJ_ST_SEARCH_READY;
   1138                 loctset->loct.current_info = CURRENT_INFO_SET;
   1139                 loctset->loct.current = current;
   1140                 return 1;
   1141             }
   1142 
   1143             if (hindo < loctset->cache_freq) {
   1144                 if (((hindo == hindo_max) && (current < hindo_data)) ||
   1145                     (hindo > hindo_max)) {
   1146                     hindo_max = hindo;
   1147                     hindo_data = current;
   1148                 }
   1149             }
   1150         }
   1151     } else {
   1152 
   1153 
   1154 
   1155         i = get_stem_next(loctset->loct.handle, data);
   1156         data += i;
   1157         current += i;
   1158 
   1159 
   1160         if (data > bottom) {
   1161 
   1162             loctset->loct.status = NJ_ST_SEARCH_END;
   1163             return 0;
   1164         }
   1165 
   1166 
   1167         hindo = (NJ_INT16) *((NJ_UINT8*)(HINDO_NO_TOP_ADDR(loctset->loct.handle)
   1168                                          + get_stem_hindo(loctset->loct.handle, data)));
   1169         loctset->cache_freq = CALCULATE_HINDO(hindo, loctset->dic_freq.base,
   1170                                               loctset->dic_freq.high, COMP_DIC_FREQ_DIV);
   1171         loctset->loct.status = NJ_ST_SEARCH_READY;
   1172         loctset->loct.current_info = CURRENT_INFO_SET;
   1173         loctset->loct.current = current;
   1174         return 1;
   1175     }
   1176 
   1177     loctset->loct.status = NJ_ST_SEARCH_END;
   1178     return 0;
   1179 }
   1180 
   1181 NJ_INT16 njd_b_search_word(NJ_SEARCH_CONDITION *con, NJ_SEARCH_LOCATION_SET *loctset)
   1182 {
   1183     NJ_INT16 ret;
   1184     NJ_DIC_INFO *pdicinfo;
   1185     NJ_UINT16 hIdx;
   1186 
   1187 
   1188 
   1189 
   1190     switch (con->operation) {
   1191     case NJ_CUR_OP_COMP:
   1192 
   1193         if (con->mode != NJ_CUR_MODE_FREQ) {
   1194 
   1195             loctset->loct.status = NJ_ST_SEARCH_END_EXT;
   1196             return 0;
   1197         }
   1198         break;
   1199     case NJ_CUR_OP_FORE:
   1200 
   1201         if (APPEND_YOMI_FLG(loctset->loct.handle) == 0) {
   1202             loctset->loct.status = NJ_ST_SEARCH_END_EXT;
   1203             return 0;
   1204         }
   1205 
   1206         if ((NJ_GET_DIC_TYPE_EX(loctset->loct.type, loctset->loct.handle) != NJ_DIC_TYPE_CUSTOM_COMPRESS)
   1207             && NJ_CHAR_STRLEN_IS_0(con->yomi)) {
   1208             loctset->loct.status = NJ_ST_SEARCH_END_EXT;
   1209             return 0;
   1210         }
   1211         break;
   1212     default:
   1213 
   1214         loctset->loct.status = NJ_ST_SEARCH_END_EXT;
   1215         return 0;
   1216     }
   1217 
   1218     if (con->ylen > NJ_GET_MAX_YLEN(loctset->loct.handle)) {
   1219         loctset->loct.status = NJ_ST_SEARCH_END_EXT;
   1220         return 0;
   1221     }
   1222 
   1223     if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_NO_INIT) {
   1224 
   1225 
   1226         switch (con->operation) {
   1227         case NJ_CUR_OP_COMP:
   1228             ret = search_node(con, loctset);
   1229             if (ret < 1) {
   1230                 return ret;
   1231             }
   1232             ret = bdic_search_data(con, loctset);
   1233             if (ret < 1) {
   1234 
   1235                 loctset->loct.status = NJ_ST_SEARCH_END;
   1236             }
   1237             break;
   1238         case NJ_CUR_OP_FORE:
   1239             pdicinfo = con->ds->dic;
   1240             for (hIdx = 0; (hIdx < NJ_MAX_DIC) && (pdicinfo->handle != loctset->loct.handle); hIdx++) {
   1241                 pdicinfo++;
   1242             }
   1243 
   1244             if (hIdx == NJ_MAX_DIC) {
   1245 
   1246                 loctset->loct.status = NJ_ST_SEARCH_END;
   1247                 return 0;
   1248             }
   1249 
   1250             if ((con->ds->dic[hIdx].srhCache == NULL) || (con->ylen == 0) ||
   1251                 !(con->ds->mode & 0x0001)) {
   1252                 ret = search_node(con, loctset);
   1253                 if (ret < 1) {
   1254                     return ret;
   1255                 }
   1256                 ret = bdic_search_fore_data(con, loctset);
   1257             } else {
   1258                 ret = search_node2(con, loctset, hIdx);
   1259                 if (ret == NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_NOT_ENOUGH)) {
   1260 
   1261                     NJ_SET_CACHEOVER_TO_SCACHE(con->ds->dic[hIdx].srhCache);
   1262                     ret = search_node2(con, loctset, hIdx);
   1263                 }
   1264                 if (ret < 1) {
   1265                     return ret;
   1266                 }
   1267                 ret = bdic_search_fore_data2(con, loctset, hIdx);
   1268             }
   1269             if (ret < 1) {
   1270 
   1271                 loctset->loct.status = NJ_ST_SEARCH_END;
   1272             }
   1273             break;
   1274         default:
   1275             loctset->loct.status = NJ_ST_SEARCH_END_EXT;
   1276             return 0;
   1277         }
   1278     } else if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_READY) {
   1279 
   1280         switch (con->operation) {
   1281         case NJ_CUR_OP_COMP:
   1282             ret = bdic_search_data(con, loctset);
   1283             if (ret < 1) {
   1284 
   1285                 loctset->loct.status = NJ_ST_SEARCH_END;
   1286             }
   1287             break;
   1288         case NJ_CUR_OP_FORE:
   1289             pdicinfo = con->ds->dic;
   1290             for (hIdx = 0; (hIdx < NJ_MAX_DIC) && (pdicinfo->handle != loctset->loct.handle); hIdx++) {
   1291                 pdicinfo++;
   1292             }
   1293 
   1294             if (hIdx == NJ_MAX_DIC) {
   1295 
   1296                 loctset->loct.status = NJ_ST_SEARCH_END;
   1297                 return 0;
   1298             }
   1299 
   1300             if ((con->ds->dic[hIdx].srhCache == NULL) || (con->ylen == 0) ||
   1301                 !(con->ds->mode & 0x0001)) {
   1302                 ret = bdic_search_fore_data(con, loctset);
   1303             } else {
   1304                 ret = bdic_search_fore_data2(con, loctset, hIdx);
   1305             }
   1306             if (ret < 1) {
   1307 
   1308                 loctset->loct.status = NJ_ST_SEARCH_END;
   1309             }
   1310             break;
   1311         default:
   1312             loctset->loct.status = NJ_ST_SEARCH_END;
   1313             return 0;
   1314         }
   1315     } else {
   1316         loctset->loct.status = NJ_ST_SEARCH_END;
   1317         return 0;
   1318     }
   1319     return ret;
   1320 }
   1321 
   1322 NJ_INT16 njd_b_get_word(NJ_SEARCH_LOCATION_SET *loctset, NJ_WORD *word)
   1323 {
   1324     NJ_UINT8 *data;
   1325     STEM_DATA_SET stem_set;
   1326     NJ_UINT8 check;
   1327 
   1328 
   1329 
   1330 
   1331     if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_END) {
   1332         return 0;
   1333     }
   1334 
   1335 	if (GET_LOCATION_OPERATION(loctset->loct.status) == NJ_CUR_OP_FORE) {
   1336         data = STEM_AREA_TOP_ADDR(loctset->loct.handle);
   1337         data += loctset->loct.top + loctset->loct.current;
   1338 
   1339 
   1340         check = 0;
   1341     } else {
   1342 
   1343 
   1344 
   1345         data = STEM_AREA_TOP_ADDR(loctset->loct.handle);
   1346         data += loctset->loct.top + loctset->loct.current;
   1347 
   1348 
   1349         check = 2;
   1350     }
   1351 
   1352 
   1353     get_stem_word(loctset->loct.handle, data, &stem_set, check);
   1354 
   1355     if (GET_LOCATION_OPERATION(loctset->loct.status) == NJ_CUR_OP_FORE) {
   1356         word->stem.info1 = (NJ_UINT16)(stem_set.yomi_size / sizeof(NJ_CHAR));
   1357     }
   1358     word->stem.info1 = WORD_LEN(word->stem.info1);
   1359     word->stem.info1 |= (NJ_UINT16)(stem_set.fhinsi_jitu << 7);
   1360 
   1361     if (check != 1) {
   1362         if (stem_set.candidate_size == 0) {
   1363 
   1364             if (GET_LOCATION_OPERATION(loctset->loct.status) == NJ_CUR_OP_FORE) {
   1365                 word->stem.info2 = (NJ_UINT16)(stem_set.yomi_size / sizeof(NJ_CHAR));
   1366             } else {
   1367 
   1368                 word->stem.info2 = (NJ_UINT16)NJ_GET_YLEN_FROM_STEM(word);
   1369             }
   1370         } else {
   1371 
   1372             word->stem.info2 = (NJ_UINT16)(stem_set.candidate_size / sizeof(NJ_CHAR));
   1373         }
   1374     } else {
   1375 
   1376         word->stem.info2 = (NJ_UINT16)NJ_GET_YLEN_FROM_STEM(word);
   1377     }
   1378 
   1379     word->stem.info2 = WORD_LEN(word->stem.info2);
   1380     word->stem.info2 |= (NJ_UINT16)(stem_set.bhinsi_jitu << 7);
   1381     word->stem.hindo = CALCULATE_HINDO(stem_set.hindo_jitu, loctset->dic_freq.base,
   1382                                        loctset->dic_freq.high, COMP_DIC_FREQ_DIV);
   1383     word->stem.loc = loctset->loct;
   1384 
   1385     return 1;
   1386 }
   1387 
   1388 NJ_INT16 njd_b_get_candidate(NJ_WORD *word, NJ_CHAR *candidate, NJ_UINT16 size)
   1389 {
   1390     NJ_SEARCH_LOCATION *loc;
   1391     NJ_CHAR  *wkc, *cand;
   1392     NJ_UINT8  *wkd;
   1393     NJ_UINT8 *data;
   1394     NJ_UINT8 *data_org;
   1395     NJ_UINT16 len, j;
   1396     STEM_DATA_SET stem_set;
   1397     NJ_INT16  next;
   1398     NJ_UINT16 yomi_pos;
   1399     NJ_CHAR   ybuf[NJ_MAX_LEN + NJ_TERM_LEN];
   1400 
   1401 
   1402 
   1403 
   1404     if ((GET_LOCATION_OPERATION(word->stem.loc.status) == NJ_CUR_OP_COMP) ||
   1405         (GET_LOCATION_OPERATION(word->stem.loc.status) == NJ_CUR_OP_FORE)) {
   1406 
   1407 
   1408         loc = &word->stem.loc;
   1409         data = STEM_AREA_TOP_ADDR(loc->handle);
   1410         data += loc->top + loc->current;
   1411 
   1412 
   1413         get_stem_cand_data(loc->handle, data, &stem_set);
   1414         len = stem_set.candidate_size / sizeof(NJ_CHAR);
   1415 
   1416     } else {
   1417 
   1418         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_CANDIDATE, NJ_ERR_INVALID_RESULT);
   1419     }
   1420 
   1421     if (len == 0) {
   1422         data_org = data;
   1423 
   1424         if (GET_LOCATION_OPERATION(word->stem.loc.status) == NJ_CUR_OP_COMP) {
   1425 
   1426             len = WORD_LEN(word->stem.info1);
   1427             if (size < ((len + NJ_TERM_LEN) * sizeof(NJ_CHAR))) {
   1428                 return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_CANDIDATE, NJ_ERR_BUFFER_NOT_ENOUGH);
   1429             }
   1430             wkc = word->yomi;
   1431         } else {
   1432 
   1433 
   1434 
   1435             while (!(STEM_TERMINETER(data))) {
   1436                 next = get_stem_next(loc->handle, data);
   1437                 data += next;
   1438             }
   1439 
   1440 
   1441             yomi_pos = get_stem_yomi_data(loc->handle, data, &stem_set);
   1442 
   1443 
   1444             wkc = ybuf;
   1445             len = get_stem_yomi_string(loc->handle, data, wkc,
   1446                                        yomi_pos, stem_set.yomi_size,
   1447                                        size);
   1448 
   1449 
   1450             if (size < ((len + NJ_TERM_LEN) * sizeof(NJ_CHAR))) {
   1451                 return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_CANDIDATE, NJ_ERR_BUFFER_NOT_ENOUGH);
   1452             }
   1453         }
   1454 
   1455         if (STEM_NO_CONV_FLG(data_org) == 0) {
   1456             cand = candidate;
   1457             for (j = 0; j < len; j++) {
   1458                 *cand++ = *wkc++;
   1459             }
   1460             *cand = NJ_CHAR_NUL;
   1461         } else {
   1462             nje_convert_hira_to_kata(wkc, candidate, len);
   1463         }
   1464 
   1465     } else {
   1466 
   1467         if (size < (stem_set.candidate_size + (NJ_TERM_LEN*sizeof(NJ_CHAR)))) {
   1468             return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_CANDIDATE, NJ_ERR_BUFFER_NOT_ENOUGH);
   1469         }
   1470         wkc = candidate;
   1471         wkd = data + stem_set.stem_size;
   1472         for (j = 0; j < len; j++) {
   1473             NJ_CHAR_COPY(wkc, wkd);
   1474             wkd += sizeof(NJ_CHAR);
   1475             wkc++;
   1476         }
   1477         *wkc = NJ_CHAR_NUL;
   1478     }
   1479 
   1480     return len;
   1481 }
   1482 
   1483 NJ_INT16 njd_b_get_stroke(NJ_WORD *word, NJ_CHAR *stroke, NJ_UINT16 size)
   1484 {
   1485     NJ_SEARCH_LOCATION *loc;
   1486     NJ_UINT8 *data;
   1487     NJ_INT16 len;
   1488     NJ_INT16 next;
   1489     NJ_UINT16 yomi_pos;
   1490     STEM_DATA_SET stem_set;
   1491 
   1492 
   1493 
   1494 
   1495     if (GET_LOCATION_OPERATION(word->stem.loc.status) == NJ_CUR_OP_FORE) {
   1496         if (NJ_GET_YLEN_FROM_STEM(word) == 0) {
   1497 
   1498             return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_STROKE, NJ_ERR_INVALID_RESULT);
   1499         }
   1500 
   1501 
   1502         loc = &word->stem.loc;
   1503 
   1504         data = STEM_AREA_TOP_ADDR(loc->handle);
   1505         data += loc->top + loc->current;
   1506 
   1507     } else {
   1508 
   1509         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_STROKE, NJ_ERR_INVALID_RESULT);
   1510     }
   1511 
   1512 
   1513     while (!(STEM_TERMINETER(data))) {
   1514         next = get_stem_next(loc->handle, data);
   1515         data += next;
   1516     }
   1517 
   1518 
   1519     yomi_pos = get_stem_yomi_data(loc->handle, data, &stem_set);
   1520     if (stem_set.yomi_size == 0) {
   1521 
   1522         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_STROKE, NJ_ERR_INVALID_RESULT);
   1523     }
   1524 
   1525 
   1526     len = get_stem_yomi_string(loc->handle, data, stroke,
   1527                                yomi_pos, stem_set.yomi_size,
   1528                                size);
   1529 
   1530 
   1531     if (size < (NJ_UINT16)((len+NJ_TERM_LEN)*sizeof(NJ_CHAR))) {
   1532         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_STROKE, NJ_ERR_BUFFER_NOT_ENOUGH);
   1533     }
   1534 
   1535     *(stroke + len) = NJ_CHAR_NUL;
   1536     return len;
   1537 }
   1538 
   1539 static NJ_INT16 search_node2(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT16 hidx)
   1540 {
   1541     NJ_UINT8 *root, *now, *node, *node_mid;
   1542     NJ_CHAR  *yomi;
   1543 
   1544     NJ_INT16 ytbl_cnt;
   1545     NJ_UINT16 y;
   1546     NJ_UINT8 *ytbl_top;
   1547 
   1548     NJ_UINT16 bit_left, bit_data;
   1549     NJ_UINT32 data_offset;
   1550     NJ_UINT16 j;
   1551     NJ_UINT8 *data_top, *stem_data;
   1552     NJ_UINT16 hindo, hindo_max, hindo_tmp;
   1553     NJ_UINT32 current, hindo_max_data, hindo_tmp_data;
   1554 
   1555 
   1556     NJ_SEARCH_CACHE *psrhCache = condition->ds->dic[hidx].srhCache;
   1557     NJ_CHAR  *key;
   1558     NJ_UINT8 cmpflg;
   1559     NJ_UINT8 endflg;
   1560     NJ_UINT16 abPtrIdx;
   1561     NJ_UINT16 key_len;
   1562     NJ_UINT16 i, l, m;
   1563     NJ_UINT16 abIdx;
   1564     NJ_UINT16 abIdx_current;
   1565     NJ_UINT16 abIdx_old;
   1566     NJ_UINT16 addcnt = 0;
   1567     NJ_CHAR   char_tmp[NJ_MAX_LEN + NJ_TERM_LEN];
   1568     NJ_UINT16 tmp_len;
   1569     NJ_UINT16 endIdx;
   1570     NJ_INT16 ret;
   1571     NJ_UINT8 *con_node;
   1572     NJ_UINT16 yomi_clen;
   1573     NJ_UINT8 aimai_flg = 0x01;
   1574     NJ_CHAR  key_tmp[NJ_MAX_CHAR_LEN + NJ_TERM_LEN];
   1575     NJ_CACHE_INFO tmpbuff;
   1576 
   1577 
   1578     if (NJ_GET_CACHEOVER_FROM_SCACHE(psrhCache)) {
   1579         aimai_flg = 0x00;
   1580     }
   1581 
   1582     node = NULL;
   1583 
   1584     yomi = condition->yomi;
   1585 
   1586 
   1587     root = NODE_AREA_TOP_ADDR(loctset->loct.handle);
   1588 
   1589 
   1590     node_mid = root + NODE_AREA_MID_ADDR(loctset->loct.handle);
   1591     now = node_mid;
   1592 
   1593     bit_left = BIT_NODE_AREA_LEFT_LEN(loctset->loct.handle);
   1594     bit_data = BIT_NODE_AREA_DATA_LEN(loctset->loct.handle);
   1595 
   1596     ytbl_cnt = YOMI_INDX_CNT(loctset->loct.handle);
   1597     y = YOMI_INDX_SIZE(loctset->loct.handle);
   1598     ytbl_top = YOMI_INDX_TOP_ADDR(loctset->loct.handle);
   1599 
   1600     data_top = STEM_AREA_TOP_ADDR(loctset->loct.handle);
   1601 
   1602 
   1603     endflg = 0x00;
   1604     cmpflg = 0x00;
   1605     abPtrIdx = 0;
   1606     key = condition->ds->keyword;
   1607 
   1608 
   1609     yomi_clen = condition->yclen;
   1610     for (i = 0; i < yomi_clen; i++) {
   1611 
   1612         abPtrIdx = i;
   1613 
   1614 
   1615         if (!cmpflg) {
   1616 
   1617             if (((abPtrIdx != 0) && (psrhCache->keyPtr[abPtrIdx] == 0))
   1618                 || (psrhCache->keyPtr[abPtrIdx + 1] == 0)) {
   1619 
   1620                 cmpflg = 0x01;
   1621             } else {
   1622 
   1623             }
   1624         }
   1625 
   1626         addcnt = 0;
   1627         if (cmpflg) {
   1628 
   1629             if (abPtrIdx == 0) {
   1630 
   1631                 abIdx = 0;
   1632 
   1633                 nj_charncpy(key_tmp, yomi, 1);
   1634                 key_len = nj_strlen(key_tmp);
   1635 
   1636                 node = NULL;
   1637                 now = node_mid;
   1638                 psrhCache->keyPtr[0] = 0;
   1639 
   1640 
   1641                 ret = search_yomi_node(condition->operation,
   1642                                        node, now, 0, key_tmp, key_len,
   1643                                        root, node_mid, bit_left, bit_data,
   1644                                        data_top, ytbl_cnt, y, ytbl_top,
   1645                                        &tmpbuff,
   1646                                        &con_node, &data_offset);
   1647 
   1648                 if (ret < 0) {
   1649 
   1650                 } else {
   1651 
   1652 
   1653 
   1654                     psrhCache->storebuff[abIdx] = tmpbuff;
   1655 
   1656 
   1657                     now = con_node;
   1658 
   1659                     psrhCache->storebuff[abIdx].top = data_offset;
   1660 
   1661                     if (condition->operation == NJ_CUR_OP_FORE) {
   1662                         ret = get_node_bottom(key_tmp, now, node_mid, data_top,
   1663                                               bit_left, bit_data,
   1664                                               psrhCache->storebuff[abIdx].top,
   1665                                               loctset->loct.handle,
   1666                                               &(psrhCache->storebuff[abIdx].bottom));
   1667                         if (ret < 0) {
   1668 
   1669                             return ret;
   1670                         }
   1671                     }
   1672                     addcnt++;
   1673                     abIdx++;
   1674                 }
   1675 
   1676                 if ((condition->charset != NULL) && aimai_flg) {
   1677 
   1678                     for (l = 0; l < condition->charset->charset_count; l++) {
   1679 
   1680                         if (nj_charncmp(key, condition->charset->from[l], 1) == 0) {
   1681 
   1682                             nj_strcpy(char_tmp, condition->charset->to[l]);
   1683                             tmp_len = nj_strlen(char_tmp);
   1684 
   1685                             node = NULL;
   1686                             now = node_mid;
   1687 
   1688 
   1689                             ret = search_yomi_node(condition->operation,
   1690                                                    node, now, 0, char_tmp, tmp_len,
   1691                                                    root, node_mid, bit_left, bit_data,
   1692                                                    data_top, ytbl_cnt, y, ytbl_top,
   1693                                                    &tmpbuff,
   1694                                                    &con_node, &data_offset);
   1695 
   1696                             if (ret < 0) {
   1697 
   1698                             } else {
   1699 
   1700 
   1701 
   1702                                 if (abIdx >= NJ_SEARCH_CACHE_SIZE) {
   1703                                     psrhCache->keyPtr[abPtrIdx+1] = 0;
   1704                                     return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_NOT_ENOUGH);
   1705                                 }
   1706 
   1707 
   1708                                 psrhCache->storebuff[abIdx] = tmpbuff;
   1709 
   1710 
   1711                                 now = con_node;
   1712 
   1713                                 psrhCache->storebuff[abIdx].top = data_offset;
   1714 
   1715                                 if (condition->operation == NJ_CUR_OP_FORE) {
   1716                                     ret = get_node_bottom(key_tmp, now,
   1717                                                           node_mid, data_top,
   1718                                                           bit_left, bit_data,
   1719                                                           psrhCache->storebuff[abIdx].top,
   1720                                                           loctset->loct.handle,
   1721                                                           &(psrhCache->storebuff[abIdx].bottom));
   1722                                     if (ret < 0) {
   1723 
   1724                                         return ret;
   1725                                     }
   1726                                 }
   1727                                 addcnt++;
   1728                                 abIdx++;
   1729                             }
   1730                         }
   1731                     }
   1732                 }
   1733                 psrhCache->keyPtr[abPtrIdx + 1] = abIdx;
   1734             } else {
   1735                 nj_charncpy(key_tmp, yomi, 1);
   1736                 key_len = nj_strlen(key_tmp);
   1737 
   1738                 if (psrhCache->keyPtr[abPtrIdx] == psrhCache->keyPtr[abPtrIdx - 1]) {
   1739 
   1740                     psrhCache->keyPtr[abPtrIdx+1] = psrhCache->keyPtr[abPtrIdx-1];
   1741                     endflg = 0x01;
   1742                 } else {
   1743                     endIdx = psrhCache->keyPtr[abPtrIdx];
   1744                     abIdx_old = psrhCache->keyPtr[abPtrIdx - 1];
   1745 
   1746                     if (NJ_GET_CACHEOVER_FROM_SCACHE(psrhCache)) {
   1747                         abIdx = psrhCache->keyPtr[abPtrIdx - 1];
   1748                         psrhCache->keyPtr[abPtrIdx] = abIdx;
   1749                     } else {
   1750                         abIdx = psrhCache->keyPtr[abPtrIdx];
   1751                     }
   1752 
   1753                     if ((abIdx > NJ_SEARCH_CACHE_SIZE) || (abIdx_old >= NJ_SEARCH_CACHE_SIZE)
   1754                         || (endIdx > NJ_SEARCH_CACHE_SIZE)) {
   1755 
   1756                         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_BROKEN);
   1757                     }
   1758 
   1759                     for (m = abIdx_old; m < endIdx; m++) {
   1760                         node = psrhCache->storebuff[m].node;
   1761                         now = psrhCache->storebuff[m].now;
   1762 
   1763                         if ((node == now) && (psrhCache->storebuff[m].idx_no == 0)) {
   1764                             continue;
   1765                         }
   1766 
   1767 
   1768                         ret = search_yomi_node(condition->operation,
   1769                                                node, now, psrhCache->storebuff[m].idx_no,
   1770                                                key_tmp, key_len, root,
   1771                                                node_mid, bit_left, bit_data,
   1772                                                data_top, ytbl_cnt, y, ytbl_top,
   1773                                                &tmpbuff,
   1774                                                &con_node, &data_offset);
   1775 
   1776                         if (ret < 0) {
   1777 
   1778                         } else {
   1779 
   1780 
   1781 
   1782                             if (abIdx >= NJ_SEARCH_CACHE_SIZE) {
   1783                                 psrhCache->keyPtr[abPtrIdx+1] = 0;
   1784                                 return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_NOT_ENOUGH);
   1785                             }
   1786 
   1787 
   1788                             psrhCache->storebuff[abIdx] = tmpbuff;
   1789 
   1790 
   1791                             now = con_node;
   1792 
   1793                             psrhCache->storebuff[abIdx].top = data_offset;
   1794 
   1795                             if (condition->operation == NJ_CUR_OP_FORE) {
   1796                                 ret = get_node_bottom(key_tmp, now, node_mid, data_top,
   1797                                                       bit_left, bit_data,
   1798                                                       psrhCache->storebuff[abIdx].top,
   1799                                                       loctset->loct.handle,
   1800                                                       &(psrhCache->storebuff[abIdx].bottom));
   1801 
   1802                                 if (ret < 0) {
   1803 
   1804                                     return ret;
   1805                                 }
   1806                             }
   1807                             addcnt++;
   1808                             abIdx++;
   1809                         }
   1810 
   1811                         if ((condition->charset != NULL) && aimai_flg) {
   1812 
   1813                             for (l = 0; l < condition->charset->charset_count; l++) {
   1814 
   1815                                 if (nj_charncmp(key, condition->charset->from[l], 1) == 0) {
   1816 
   1817                                     nj_strcpy(char_tmp, condition->charset->to[l]);
   1818 
   1819                                     tmp_len = nj_strlen(char_tmp);
   1820 
   1821                                     node = psrhCache->storebuff[m].node;
   1822                                     now = psrhCache->storebuff[m].now;
   1823 
   1824 
   1825                                     ret = search_yomi_node(condition->operation,
   1826                                                            node, now,
   1827                                                            psrhCache->storebuff[m].idx_no,
   1828                                                            char_tmp, tmp_len,
   1829                                                            root, node_mid,
   1830                                                            bit_left, bit_data, data_top,
   1831                                                            ytbl_cnt, y, ytbl_top,
   1832                                                            &tmpbuff,
   1833                                                            &con_node, &data_offset);
   1834 
   1835                                     if (ret < 0) {
   1836 
   1837                                     } else {
   1838 
   1839 
   1840 
   1841                                         if (abIdx >= NJ_SEARCH_CACHE_SIZE) {
   1842                                             psrhCache->keyPtr[abPtrIdx+1] = 0;
   1843                                             return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_NOT_ENOUGH);
   1844                                         }
   1845 
   1846 
   1847                                         psrhCache->storebuff[abIdx] = tmpbuff;
   1848 
   1849 
   1850                                         now = con_node;
   1851 
   1852                                         psrhCache->storebuff[abIdx].top = data_offset;
   1853 
   1854                                         if (condition->operation == NJ_CUR_OP_FORE) {
   1855                                             ret = get_node_bottom(key_tmp, now, node_mid,
   1856                                                                   data_top, bit_left, bit_data,
   1857                                                                   psrhCache->storebuff[abIdx].top,
   1858                                                                   loctset->loct.handle,
   1859                                                                   &(psrhCache->storebuff[abIdx].bottom));
   1860                                             if (ret < 0) {
   1861 
   1862                                                 return ret;
   1863                                             }
   1864                                         }
   1865                                         addcnt++;
   1866                                         abIdx++;
   1867                                     }
   1868                                 }
   1869                             }
   1870                         }
   1871                     }
   1872                     psrhCache->keyPtr[abPtrIdx + 1] = abIdx;
   1873                 }
   1874             }
   1875         }
   1876         yomi += UTL_CHAR(yomi);
   1877         key  += UTL_CHAR(key);
   1878     }
   1879 
   1880     if ((addcnt == 0) && (psrhCache->keyPtr[yomi_clen - 1] == psrhCache->keyPtr[yomi_clen])) {
   1881         endflg = 0x01;
   1882     }
   1883 
   1884     if (endflg) {
   1885         loctset->loct.status = NJ_ST_SEARCH_END;
   1886         return 0;
   1887     }
   1888 
   1889     loctset->loct.current = 0;
   1890 
   1891 
   1892 
   1893     abPtrIdx = condition->yclen;
   1894 
   1895 
   1896     abIdx = psrhCache->keyPtr[abPtrIdx];
   1897     abIdx_old = psrhCache->keyPtr[abPtrIdx - 1];
   1898     if ((abIdx > NJ_SEARCH_CACHE_SIZE) || (abIdx_old >= NJ_SEARCH_CACHE_SIZE)) {
   1899 
   1900         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_BROKEN);
   1901     }
   1902 
   1903     if (condition->mode == NJ_CUR_MODE_FREQ) {
   1904         hindo_max = 0;
   1905         hindo_max_data = 0;
   1906         abIdx_current = abIdx_old;
   1907 
   1908 
   1909         stem_data = data_top + psrhCache->storebuff[abIdx_current].top;
   1910 
   1911         hindo = (NJ_UINT16) *((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle) +
   1912                                            get_stem_hindo(loctset->loct.handle, stem_data)));
   1913 
   1914         hindo_tmp = 0;
   1915         hindo_tmp_data = 0;
   1916         current = 0;
   1917 
   1918 
   1919         while (stem_data <= (data_top + psrhCache->storebuff[abIdx_current].bottom)) {
   1920 
   1921             if (hindo > hindo_tmp) {
   1922                 hindo_tmp = hindo;
   1923                 hindo_tmp_data = current;
   1924             }
   1925 
   1926 
   1927             j = get_stem_next(loctset->loct.handle, stem_data);
   1928             current += j;
   1929             stem_data += j;
   1930 
   1931 
   1932             hindo = (NJ_UINT16) *((NJ_UINT8 *) (HINDO_NO_TOP_ADDR(loctset->loct.handle) +
   1933                                                 get_stem_hindo(loctset->loct.handle, stem_data)));
   1934 
   1935         }
   1936 
   1937 
   1938         psrhCache->storebuff[abIdx_current].current = hindo_tmp_data;
   1939 
   1940 
   1941         if (hindo_tmp > hindo_max) {
   1942             hindo_max = hindo_tmp;
   1943             hindo_max_data = hindo_tmp_data;
   1944         }
   1945     } else {
   1946 
   1947         abIdx_current = abIdx_old;
   1948 
   1949 
   1950         stem_data = data_top + psrhCache->storebuff[abIdx_current].top;
   1951 
   1952         hindo = (NJ_UINT16) *((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle)
   1953                                            + get_stem_hindo(loctset->loct.handle, stem_data)));
   1954 
   1955         hindo_max = hindo;
   1956         hindo_max_data = 0;
   1957     }
   1958 
   1959 
   1960     loctset->loct.top = psrhCache->storebuff[abIdx_current].top;
   1961     loctset->loct.bottom = psrhCache->storebuff[abIdx_current].bottom;
   1962 
   1963     loctset->cache_freq = CALCULATE_HINDO(hindo_max, loctset->dic_freq.base,
   1964                                           loctset->dic_freq.high, COMP_DIC_FREQ_DIV);
   1965     loctset->loct.current = hindo_max_data;
   1966     loctset->loct.current_cache = (NJ_UINT8)abIdx_current;
   1967 
   1968 
   1969     psrhCache->viewCnt = 1;
   1970     NJ_SET_AIMAI_TO_SCACHE(psrhCache);
   1971 
   1972     return 1;
   1973 }
   1974 
   1975 static NJ_INT16 search_yomi_node(NJ_UINT8 operation, NJ_UINT8 *node, NJ_UINT8 *now,
   1976                                  NJ_UINT16 idx_no, NJ_CHAR  *yomi, NJ_UINT16 yomilen,
   1977                                  NJ_UINT8 * root, NJ_UINT8 * node_mid,
   1978                                  NJ_UINT16 bit_left, NJ_UINT16 bit_data,
   1979                                  NJ_UINT8 * data_top,
   1980                                  NJ_INT16 ytbl_cnt, NJ_UINT16 y, NJ_UINT8 * ytbl_top,
   1981                                  NJ_CACHE_INFO * storebuf,
   1982                                  NJ_UINT8 ** con_node,
   1983                                  NJ_UINT32 * data_offset)
   1984 {
   1985 
   1986     NJ_UINT8 index;
   1987     NJ_UINT8 *wkc;
   1988     NJ_UINT8 *byomi;
   1989     NJ_INT16 idx;
   1990     NJ_INT16 char_size;
   1991     NJ_INT16 left, right, mid;
   1992     NJ_UINT16 c, d;
   1993     NJ_UINT8 c1 = 0, c2 = 0;
   1994     NJ_UINT16 ysize = yomilen * sizeof(NJ_CHAR);
   1995     NJ_UINT16 idx_cnt;
   1996     NJ_UINT16 nd_index;
   1997     NJ_UINT16 data;
   1998     NJ_UINT16 pos, j, bit_all, bit_tmp, bit_idx;
   1999     NJ_UINT32 data_l;
   2000     NJ_UINT8 restart_flg = 0;
   2001 
   2002 
   2003     *con_node = NULL;
   2004 
   2005 
   2006     idx_cnt = 1;
   2007     storebuf->idx_no = 0;
   2008 
   2009     byomi = (NJ_UINT8*)yomi;
   2010 
   2011 
   2012     while (ysize > 0) {
   2013         if (ytbl_cnt != 0) {
   2014             char_size = UTL_CHAR(byomi) * sizeof(NJ_CHAR);
   2015             if (char_size > 2) {
   2016                 return -1;
   2017             }
   2018 
   2019 
   2020 
   2021             if (char_size == 2) {
   2022                 if (y == 1) {
   2023                     return -1;
   2024                 }
   2025                 c1 = *byomi;
   2026                 c2 = *(byomi + 1);
   2027                 c = (NJ_UINT16)((c1 << 8) | c2);
   2028             } else {
   2029 
   2030                 c1 = *byomi;
   2031                 c2 = 0x00;
   2032                 c = (NJ_UINT16)(*byomi);
   2033             }
   2034 
   2035             idx = -1;
   2036             left = 0;
   2037             right = ytbl_cnt;
   2038 
   2039             if (y == 2) {
   2040                 while (left <= right) {
   2041                     mid = (left + right) >> 1;
   2042                     wkc = ytbl_top + (mid << 1);
   2043 
   2044                     if (c1 == *wkc) {
   2045                         if (c2 == *(wkc + 1)) {
   2046                             idx = (NJ_UINT16) (mid + 1);
   2047                             break;
   2048                         }
   2049                         if (c2 < *(wkc + 1)) {
   2050                             right = mid - 1;
   2051                         } else {
   2052                             left = mid + 1;
   2053                         }
   2054                     } else if (c1 < *wkc) {
   2055                         right = mid - 1;
   2056                     } else {
   2057                         left = mid + 1;
   2058                     }
   2059                 }
   2060             } else {
   2061                 while (left <= right) {
   2062                     mid = (left + right) >> 1;
   2063                     wkc = ytbl_top + (mid * y);
   2064                     d = (NJ_UINT16) (*wkc);
   2065                     if (c == d) {
   2066                         idx = (NJ_UINT16) (mid + 1);
   2067                         break;
   2068                     }
   2069                     if (c < d) {
   2070                         right = mid - 1;
   2071                     } else {
   2072                         left = mid + 1;
   2073                     }
   2074                 }
   2075             }
   2076 
   2077             if (idx < 0) {
   2078                 return -1;
   2079             }
   2080             index = (NJ_UINT8) idx;
   2081         } else {
   2082             index = *byomi;
   2083             char_size = 1;
   2084         }
   2085 
   2086         byomi += char_size;
   2087         ysize -= char_size;
   2088 
   2089         while (now < data_top) {
   2090             if (NODE_IDX_EXIST(now)) {
   2091                 bit_idx = 8;
   2092                 idx_cnt = NODE_IDX_CNT(now);
   2093             } else {
   2094                 bit_idx = 4;
   2095                 idx_cnt = 1;
   2096             }
   2097             bit_all = bit_idx;
   2098 
   2099 
   2100             if (NODE_LEFT_EXIST(now)) {
   2101                 bit_all += bit_left;
   2102             }
   2103 
   2104 
   2105             if (NODE_DATA_EXIST(now)) {
   2106                 bit_all += bit_data;
   2107             }
   2108 
   2109             bit_tmp = bit_all;
   2110 
   2111 
   2112             bit_all += (NJ_UINT16) (idx_no << 3);
   2113 
   2114             pos = (NJ_UINT16) (bit_all >> 3);
   2115 
   2116             data = (NJ_UINT16) (NJ_INT16_READ(now + pos));
   2117 
   2118             j = (NJ_UINT16) (bit_all & 0x0007);
   2119 
   2120             nd_index = GET_BITFIELD_16(data, j, INDEX_BIT);
   2121             if (index == (NJ_UINT8) nd_index) {
   2122 
   2123                 break;
   2124             } else {
   2125                 if ((!NODE_TERM(now)) && (index > (NJ_UINT8) nd_index) && (idx_no == 0)) {
   2126 
   2127                     now += GET_BIT_TO_BYTE(bit_tmp + (idx_cnt * 8));
   2128                     if (now == node_mid) {
   2129 
   2130                         return -1;
   2131                     }
   2132                     continue;
   2133                 } else {
   2134                     if ((now == node_mid) && (restart_flg == 0)
   2135                         && (index < (NJ_UINT8) nd_index) && (idx_no == 0)
   2136                         && (root != node_mid)) {
   2137                         now = root;
   2138                         idx_no = 0;
   2139                         restart_flg = 1;
   2140                         continue;
   2141                     }
   2142                     return -1;
   2143                 }
   2144             }
   2145         }
   2146 
   2147         if ( (idx_cnt > (NJ_UINT16) (idx_no + 1))) {
   2148             if (ysize == 0) {
   2149                 if (operation == NJ_CUR_OP_FORE) {
   2150 
   2151                     storebuf->node = now;
   2152                     storebuf->now = now;
   2153                     storebuf->idx_no = idx_no + 1;
   2154                     node = now;
   2155                     break;
   2156                 }
   2157                 return -2;
   2158             }
   2159             idx_no++;
   2160             continue;
   2161         }
   2162 
   2163         node = now;
   2164         storebuf->node = now;
   2165         idx_no = 0;
   2166 
   2167         if (ysize == 0) {
   2168             *con_node = now;
   2169         } else {
   2170             if (!(NODE_LEFT_EXIST(now))) {
   2171                 return -1;
   2172             }
   2173         }
   2174 
   2175         if (NODE_LEFT_EXIST(now)) {
   2176             if (NODE_IDX_EXIST(now)) {
   2177                 bit_idx = 8;
   2178             } else {
   2179                 bit_idx = 4;
   2180             }
   2181             pos = (NJ_UINT16) (bit_idx >> 3);
   2182             data_l = (NJ_UINT32) (NJ_INT32_READ(now + pos));
   2183 
   2184 
   2185             j = (NJ_UINT16) (bit_idx & 0x0007);
   2186 
   2187             now += GET_BITFIELD_32(data_l, j, bit_left);
   2188             storebuf->now = now;
   2189         } else {
   2190             storebuf->now = now;
   2191         }
   2192     }
   2193 
   2194 
   2195 
   2196     if (*con_node == NULL) {
   2197         *con_node = now;
   2198     }
   2199 
   2200 
   2201     if ((node == NULL) || !(NODE_DATA_EXIST(node))) {
   2202 
   2203         if ((operation == NJ_CUR_OP_FORE) && (node != NULL)) {
   2204             while (!NODE_DATA_EXIST(node)) {
   2205                 if (!(NODE_LEFT_EXIST(node))) {
   2206 
   2207                     return -2;
   2208                 }
   2209 
   2210                 if (NODE_IDX_EXIST(node)) {
   2211                     bit_idx = 8;
   2212                 } else {
   2213                     bit_idx = 4;
   2214                 }
   2215                 pos = (NJ_UINT16) (bit_idx >> 3);
   2216                 data_l = (NJ_UINT32) (NJ_INT32_READ(node + pos));
   2217 
   2218 
   2219                 j = (NJ_UINT16) (bit_idx & 0x0007);
   2220                 node += GET_BITFIELD_32(data_l, j, bit_left);
   2221             }
   2222         } else {
   2223             return -2;
   2224         }
   2225     }
   2226 
   2227     if (NODE_IDX_EXIST(node)) {
   2228         bit_idx = 8;
   2229     } else {
   2230         bit_idx = 4;
   2231     }
   2232 
   2233 
   2234     if (NODE_LEFT_EXIST(node)) {
   2235         bit_all = bit_idx + bit_left;
   2236     } else {
   2237         bit_all = bit_idx;
   2238     }
   2239 
   2240     pos = (NJ_UINT16) (bit_all >> 3);
   2241     data_l = (NJ_UINT32) (NJ_INT32_READ(node + pos));
   2242 
   2243 
   2244     j = (NJ_UINT16) (bit_all & 0x0007);
   2245     *data_offset = GET_BITFIELD_32(data_l, j, bit_data);
   2246 
   2247     return 1;
   2248 }
   2249 
   2250 static NJ_INT16 get_node_bottom(NJ_CHAR * yomi, NJ_UINT8 * now, NJ_UINT8 * node_mid,
   2251                                 NJ_UINT8 * data_top, NJ_UINT16 bit_left, NJ_UINT16 bit_data,
   2252                                 NJ_UINT32 top, NJ_DIC_HANDLE handle,
   2253                                 NJ_UINT32 * ret_bottom)
   2254 {
   2255     NJ_UINT8 *node;
   2256     NJ_UINT16 idx_cnt;
   2257     NJ_UINT32 data_offset;
   2258     NJ_UINT16 pos, j, bit_all;
   2259     NJ_UINT32 data_l;
   2260     NJ_UINT8 bottom_flg = 0;
   2261     NJ_UINT8 *stem_data;
   2262     NJ_UINT32 bottom, next;
   2263 
   2264 
   2265 
   2266     bottom = top;
   2267 
   2268     if (NJ_CHAR_STRLEN_IS_0(yomi)) {
   2269         node = node_mid;
   2270 
   2271     } else {
   2272 
   2273         node = now;
   2274         if (NODE_LEFT_EXIST(node)) {
   2275 
   2276             if (NODE_IDX_EXIST(node)) {
   2277                 bit_all = 8;
   2278             } else {
   2279                 bit_all = 4;
   2280             }
   2281 
   2282             pos = (NJ_UINT16) (bit_all >> 3);
   2283             data_l = (NJ_UINT32) (NJ_INT32_READ(node + pos));
   2284 
   2285 
   2286             j = (NJ_UINT16) (bit_all & 0x0007);
   2287             node += GET_BITFIELD_32(data_l, j, bit_left);
   2288 
   2289         } else {
   2290             bottom_flg = 1;
   2291         }
   2292     }
   2293 
   2294 
   2295     if (!bottom_flg) {
   2296         while (node < data_top) {
   2297 
   2298             if (!NODE_TERM(node)) {
   2299 
   2300                 if (NODE_IDX_EXIST(node)) {
   2301                     bit_all = 8;
   2302                     idx_cnt = NODE_IDX_CNT(node);
   2303                 } else {
   2304                     bit_all = 4;
   2305                     idx_cnt = 1;
   2306                 }
   2307 
   2308 
   2309                 if (NODE_LEFT_EXIST(node)) {
   2310                     bit_all += bit_left;
   2311                 }
   2312 
   2313 
   2314                 if (NODE_DATA_EXIST(node)) {
   2315                     bit_all += bit_data;
   2316                 }
   2317 
   2318 
   2319                 node += GET_BIT_TO_BYTE(bit_all + (idx_cnt * 8));
   2320             } else {
   2321 
   2322                 if (!NODE_LEFT_EXIST(node)) {
   2323 
   2324                     if (NODE_DATA_EXIST(node)) {
   2325 
   2326                         if (NODE_IDX_EXIST(node)) {
   2327                             bit_all = 8;
   2328                         } else {
   2329                             bit_all = 4;
   2330                         }
   2331 
   2332                         pos = (NJ_UINT16) (bit_all >> 3);
   2333                         data_l = (NJ_UINT32) (NJ_INT32_READ(node + pos));
   2334 
   2335 
   2336                         j = (NJ_UINT16) (bit_all & 0x0007);
   2337                         data_offset = GET_BITFIELD_32(data_l, j, bit_data);
   2338 
   2339                         bottom = data_offset;
   2340                         break;
   2341                     } else {
   2342                         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_DIC_BROKEN);
   2343                     }
   2344 
   2345                 } else {
   2346 
   2347                     if (NODE_IDX_EXIST(node)) {
   2348                         bit_all = 8;
   2349                     } else {
   2350                         bit_all = 4;
   2351                     }
   2352 
   2353                     pos = (NJ_UINT16) (bit_all >> 3);
   2354                     data_l = (NJ_UINT32) (NJ_INT32_READ(node + pos));
   2355 
   2356 
   2357                     j = (NJ_UINT16) (bit_all & 0x0007);
   2358 
   2359 
   2360                     node += GET_BITFIELD_32(data_l, j, bit_left);
   2361                 }
   2362             }
   2363         }
   2364     }
   2365 
   2366     stem_data = data_top + bottom;
   2367 
   2368     while (!(STEM_TERMINETER(stem_data))) {
   2369         next = get_stem_next(handle, stem_data);
   2370         stem_data += next;
   2371     }
   2372     *ret_bottom = (NJ_UINT32) (stem_data - data_top);
   2373 
   2374     return 1;
   2375 }
   2376 
   2377 static NJ_INT16 bdic_search_fore_data2(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT16 hidx)
   2378 {
   2379     NJ_UINT8 *data, *data_top, *bottom, *data_end;
   2380     NJ_INT16 i = 0;
   2381     NJ_INT16 hindo = 0;
   2382     NJ_UINT32 current = loctset->loct.current;
   2383 
   2384 
   2385     NJ_SEARCH_CACHE *psrhCache = condition->ds->dic[hidx].srhCache;
   2386 
   2387     NJ_UINT16 top_abIdx;
   2388     NJ_UINT16 bottom_abIdx;
   2389     NJ_UINT16 count_abIdx;
   2390     NJ_UINT16 current_abIdx;
   2391     NJ_UINT16 old_abIdx;
   2392     NJ_UINT8 freq_flag = 0;
   2393     NJ_INT16 save_hindo = 0;
   2394     NJ_UINT16 save_abIdx = 0;
   2395     NJ_UINT16 abPtrIdx;
   2396     NJ_UINT16 m;
   2397     NJ_INT16 ret;
   2398     NJ_INT16 loop_check;
   2399 
   2400     NJ_UINT16 abIdx;
   2401     NJ_UINT16 abIdx_old;
   2402     NJ_UINT16 hindo_max, hindo_tmp;
   2403     NJ_UINT32 hindo_max_data, hindo_tmp_data;
   2404     NJ_UINT16 abIdx_current;
   2405 
   2406 
   2407 
   2408 
   2409     if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_NO_INIT) {
   2410         loctset->loct.status = NJ_ST_SEARCH_READY;
   2411         loctset->loct.current_info = CURRENT_INFO_SET;
   2412         return 1;
   2413     }
   2414 
   2415     if (NJ_GET_AIMAI_FROM_SCACHE(psrhCache)) {
   2416         NJ_UNSET_AIMAI_TO_SCACHE(psrhCache);
   2417 
   2418         data_top = STEM_AREA_TOP_ADDR(loctset->loct.handle);
   2419         if (condition->operation == NJ_CUR_OP_FORE) {
   2420             if (condition->ylen) {
   2421 
   2422                 abPtrIdx = condition->yclen;
   2423 
   2424 
   2425                 abIdx = psrhCache->keyPtr[abPtrIdx];
   2426                 abIdx_old = psrhCache->keyPtr[abPtrIdx - 1];
   2427                 if ((abIdx > NJ_SEARCH_CACHE_SIZE) || (abIdx_old >= NJ_SEARCH_CACHE_SIZE)) {
   2428 
   2429                     return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_BROKEN);
   2430                 }
   2431 
   2432                 if (condition->mode == NJ_CUR_MODE_FREQ) {
   2433                     hindo_max = 0;
   2434                     hindo_max_data = 0;
   2435                     abIdx_current = abIdx_old;
   2436 
   2437                     for (m = abIdx_old; m < abIdx; m++) {
   2438 
   2439                         data = data_top + psrhCache->storebuff[m].top;
   2440 
   2441                         hindo = (NJ_UINT16) *((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle) +
   2442                                                            get_stem_hindo(loctset->loct.handle, data)));
   2443 
   2444                         hindo_tmp = 0;
   2445                         hindo_tmp_data = 0;
   2446                         current = 0;
   2447 
   2448 
   2449                         while (data <= (data_top + psrhCache->storebuff[m].bottom)) {
   2450 
   2451                             if (hindo > hindo_tmp) {
   2452                                 hindo_tmp = hindo;
   2453                                 hindo_tmp_data = current;
   2454                             }
   2455 
   2456 
   2457                             i = get_stem_next(loctset->loct.handle, data);
   2458                             current += i;
   2459                             data += i;
   2460 
   2461 
   2462                             hindo = (NJ_UINT16) *((NJ_UINT8 *) (HINDO_NO_TOP_ADDR(loctset->loct.handle) +
   2463                                                                 get_stem_hindo(loctset->loct.handle, data)));
   2464 
   2465                         }
   2466 
   2467 
   2468                         psrhCache->storebuff[m].current = hindo_tmp_data;
   2469 
   2470 
   2471                         if (hindo_tmp > hindo_max) {
   2472                             hindo_max = hindo_tmp;
   2473                             hindo_max_data = hindo_tmp_data;
   2474                             abIdx_current = m;
   2475                         }
   2476                     }
   2477                 } else {
   2478 
   2479                     abIdx_current = abIdx_old;
   2480 
   2481 
   2482                     data = data_top + psrhCache->storebuff[abIdx_current].top;
   2483 
   2484                     hindo = (NJ_UINT16) *((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle)
   2485                                                        + get_stem_hindo(loctset->loct.handle, data)));
   2486 
   2487                     hindo_max = hindo;
   2488                     hindo_max_data = 0;
   2489                 }
   2490 
   2491 
   2492                 loctset->loct.top = psrhCache->storebuff[abIdx_current].top;
   2493                 loctset->loct.bottom = psrhCache->storebuff[abIdx_current].bottom;
   2494 
   2495                 loctset->cache_freq = CALCULATE_HINDO(hindo_max, loctset->dic_freq.base,
   2496                                                       loctset->dic_freq.high, COMP_DIC_FREQ_DIV);
   2497                 loctset->loct.current = hindo_max_data;
   2498                 loctset->loct.current_cache = (NJ_UINT8)abIdx_current;
   2499 
   2500 
   2501                 psrhCache->viewCnt = 1;
   2502             } else {
   2503 
   2504                 data = data_top + loctset->loct.top;
   2505 
   2506                 hindo = (NJ_UINT16) *((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle) +
   2507                                                    get_stem_hindo(loctset->loct.handle, data)));
   2508 
   2509                 hindo_max = hindo;
   2510                 hindo_max_data = 0;
   2511 
   2512                 if (condition->mode == NJ_CUR_MODE_FREQ) {
   2513 
   2514 
   2515                     i = get_stem_next(loctset->loct.handle, data);
   2516                     current = i;
   2517                     data += i;
   2518 
   2519 
   2520                     while (data <= (data_top + loctset->loct.bottom)) {
   2521 
   2522 
   2523                         hindo = (NJ_UINT16)*((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle) +
   2524                                                           get_stem_hindo(loctset->loct.handle, data)));
   2525 
   2526 
   2527                         if (hindo > hindo_max) {
   2528                             hindo_max = hindo;
   2529                             hindo_max_data = current;
   2530                         }
   2531 
   2532 
   2533                         i = get_stem_next(loctset->loct.handle, data);
   2534                         current += i;
   2535                         data += i;
   2536                     }
   2537                 }
   2538                 loctset->cache_freq = CALCULATE_HINDO(hindo_max,
   2539                                                       loctset->dic_freq.base,
   2540                                                       loctset->dic_freq.high, COMP_DIC_FREQ_DIV);
   2541                 loctset->loct.current = hindo_max_data;
   2542             }
   2543         }
   2544         return 1;
   2545     }
   2546 
   2547 
   2548     data_top = STEM_AREA_TOP_ADDR(loctset->loct.handle);
   2549 
   2550 
   2551     data = data_top + loctset->loct.top + loctset->loct.current;
   2552 
   2553 
   2554 
   2555     bottom = data_top + loctset->loct.bottom;
   2556 
   2557     if (NJ_GET_DIC_FMT(loctset->loct.handle) == NJ_DIC_FMT_KANAKAN) {
   2558         data_end = loctset->loct.handle
   2559             + NJ_DIC_COMMON_HEADER_SIZE
   2560             + NJ_INT32_READ(loctset->loct.handle + NJ_DIC_POS_DATA_SIZE)
   2561             + NJ_INT32_READ(loctset->loct.handle + NJ_DIC_POS_EXT_SIZE)
   2562             - NJ_DIC_ID_LEN;
   2563     } else {
   2564         data_end = CAND_IDX_AREA_TOP_ADDR(loctset->loct.handle);
   2565     }
   2566 
   2567     if (condition->mode == NJ_CUR_MODE_FREQ) {
   2568 
   2569 
   2570         abPtrIdx = condition->yclen;
   2571 
   2572 
   2573         bottom_abIdx = psrhCache->keyPtr[abPtrIdx];
   2574         top_abIdx = psrhCache->keyPtr[abPtrIdx - 1];
   2575         if ((bottom_abIdx > NJ_SEARCH_CACHE_SIZE) || (top_abIdx >= NJ_SEARCH_CACHE_SIZE)) {
   2576 
   2577             return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_BROKEN);
   2578         }
   2579 
   2580 
   2581         count_abIdx = bottom_abIdx - top_abIdx;
   2582         if (!count_abIdx) {
   2583             loctset->loct.status = NJ_ST_SEARCH_END;
   2584             return 0;
   2585         }
   2586 
   2587         old_abIdx = loctset->loct.current_cache;
   2588 
   2589         loop_check = 0;
   2590 
   2591 
   2592         ret = bdic_get_next_data(data_top, data_end, loctset, psrhCache, old_abIdx);
   2593 
   2594         if (ret == loctset->cache_freq) {
   2595 
   2596             psrhCache->viewCnt++;
   2597             if (psrhCache->viewCnt <= NJ_CACHE_VIEW_CNT) {
   2598 
   2599                 loctset->loct.status = NJ_ST_SEARCH_READY;
   2600                 loctset->loct.current_info = CURRENT_INFO_SET;
   2601                 loctset->loct.current = psrhCache->storebuff[old_abIdx].current;
   2602                 loctset->loct.current_cache = (NJ_UINT8)old_abIdx;
   2603                 return 1;
   2604             } else {
   2605 
   2606                 freq_flag = 1;
   2607                 psrhCache->viewCnt = 0;
   2608             }
   2609         } else {
   2610             if (ret == -1) {
   2611 
   2612                 loop_check++;
   2613             }
   2614             save_hindo = ret;
   2615             save_abIdx = old_abIdx;
   2616         }
   2617 
   2618 
   2619         current_abIdx = old_abIdx + 1;
   2620         if (current_abIdx >= bottom_abIdx) {
   2621 
   2622             current_abIdx = top_abIdx;
   2623         }
   2624 
   2625         while (loop_check != count_abIdx) {
   2626 
   2627 
   2628             ret = bdic_get_word_freq(data_top, loctset, psrhCache, current_abIdx);
   2629 
   2630             if ((ret == loctset->cache_freq) &&
   2631                 (loctset->loct.top == psrhCache->storebuff[current_abIdx].top) &&
   2632                 (loctset->loct.current == psrhCache->storebuff[current_abIdx].current)) {
   2633                 ret = bdic_get_next_data(data_top, data_end, loctset, psrhCache, current_abIdx);
   2634             }
   2635 
   2636             if (ret == loctset->cache_freq) {
   2637 
   2638                 loctset->loct.status = NJ_ST_SEARCH_READY;
   2639                 loctset->loct.current_info = CURRENT_INFO_SET;
   2640                 loctset->loct.top = psrhCache->storebuff[current_abIdx].top;
   2641                 loctset->loct.bottom = psrhCache->storebuff[current_abIdx].bottom;
   2642                 loctset->loct.current = psrhCache->storebuff[current_abIdx].current;
   2643                 loctset->loct.current_cache = (NJ_UINT8)current_abIdx;
   2644                 psrhCache->viewCnt = 1;
   2645                 return 1;
   2646 
   2647             } else {
   2648                 if (ret == -1) {
   2649 
   2650                     loop_check++;
   2651                 }
   2652                 if (save_hindo < ret) {
   2653 
   2654                     save_hindo = ret;
   2655                     save_abIdx = current_abIdx;
   2656                 }
   2657             }
   2658 
   2659 
   2660             current_abIdx++;
   2661             if (current_abIdx >= bottom_abIdx) {
   2662 
   2663                 current_abIdx = top_abIdx;
   2664             }
   2665 
   2666 
   2667             if (current_abIdx == old_abIdx) {
   2668                 if (freq_flag == 1) {
   2669 
   2670                     loctset->loct.status = NJ_ST_SEARCH_READY;
   2671                     loctset->loct.current_info = CURRENT_INFO_SET;
   2672                     loctset->loct.top = psrhCache->storebuff[current_abIdx].top;
   2673                     loctset->loct.bottom = psrhCache->storebuff[current_abIdx].bottom;
   2674                     loctset->loct.current = psrhCache->storebuff[current_abIdx].current;
   2675                     loctset->loct.current_cache = (NJ_UINT8)current_abIdx;
   2676                     psrhCache->viewCnt = 1;
   2677                     return 1;
   2678                 } else if (save_hindo != -1) {
   2679 
   2680                     loctset->cache_freq = save_hindo;
   2681                     loctset->loct.status = NJ_ST_SEARCH_READY;
   2682                     loctset->loct.current_info = CURRENT_INFO_SET;
   2683                     loctset->loct.top = psrhCache->storebuff[save_abIdx].top;
   2684                     loctset->loct.bottom = psrhCache->storebuff[save_abIdx].bottom;
   2685                     loctset->loct.current = psrhCache->storebuff[save_abIdx].current;
   2686                     loctset->loct.current_cache = (NJ_UINT8)save_abIdx;
   2687                     psrhCache->viewCnt = 1;
   2688                     return 1;
   2689                 }
   2690             }
   2691         }
   2692     } else {
   2693 
   2694 
   2695 
   2696         i = get_stem_next(loctset->loct.handle, data);
   2697         data += i;
   2698         current += i;
   2699 
   2700 
   2701         if (data > bottom) {
   2702 
   2703             loctset->loct.status = NJ_ST_SEARCH_END;
   2704             return 0;
   2705         }
   2706 
   2707 
   2708         hindo = (NJ_INT16)*((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle)
   2709                                          + get_stem_hindo(loctset->loct.handle, data)));
   2710         loctset->cache_freq = CALCULATE_HINDO(hindo, loctset->dic_freq.base,
   2711                                               loctset->dic_freq.high, COMP_DIC_FREQ_DIV);
   2712         loctset->loct.status = NJ_ST_SEARCH_READY;
   2713         loctset->loct.current_info = CURRENT_INFO_SET;
   2714         loctset->loct.current = current;
   2715         return 1;
   2716     }
   2717 
   2718     loctset->loct.status = NJ_ST_SEARCH_END;
   2719     return 0;
   2720 }
   2721 
   2722 static NJ_INT16 bdic_get_next_data(NJ_UINT8 *data_top, NJ_UINT8 *data_end,
   2723                                    NJ_SEARCH_LOCATION_SET *loctset,
   2724                                    NJ_SEARCH_CACHE *psrhCache,
   2725                                    NJ_UINT16 abIdx)
   2726 {
   2727     NJ_UINT8 *data, *bottom;
   2728     NJ_INT16 i = 0;
   2729     NJ_INT16 hindo = 0;
   2730     NJ_INT16 hindo_max = -1;
   2731     NJ_UINT8 no_hit = 0;
   2732     NJ_UINT32 current = psrhCache->storebuff[abIdx].current;
   2733     NJ_UINT8 *current_org;
   2734     NJ_UINT32 hindo_data = 0;
   2735     NJ_INT16 freq_org = loctset->cache_freq;
   2736 
   2737 
   2738     if (psrhCache->storebuff[abIdx].current == LOC_CURRENT_NO_ENTRY) {
   2739         return (-1);
   2740     }
   2741 
   2742 
   2743     data = data_top + psrhCache->storebuff[abIdx].top + psrhCache->storebuff[abIdx].current;
   2744 
   2745 
   2746     current_org = data;
   2747 
   2748 
   2749     bottom = data_top + psrhCache->storebuff[abIdx].bottom;
   2750 
   2751 
   2752 
   2753 
   2754     while (data < data_end) {
   2755 
   2756         i = get_stem_next(loctset->loct.handle, data);
   2757         data += i;
   2758         current += i;
   2759 
   2760 
   2761         if (data > bottom) {
   2762             if ((freq_org == 0) || (no_hit == 1)) {
   2763 
   2764                 psrhCache->storebuff[abIdx].current = LOC_CURRENT_NO_ENTRY;
   2765                 return -1;
   2766             }
   2767 
   2768             freq_org -= 1;
   2769 
   2770 
   2771             data = data_top + psrhCache->storebuff[abIdx].top;
   2772             current = 0;
   2773 
   2774             no_hit = 1;
   2775         }
   2776 
   2777 
   2778         if ((hindo_max != -1) && (data == current_org)) {
   2779             psrhCache->storebuff[abIdx].current = hindo_data;
   2780             return hindo_max;
   2781         }
   2782 
   2783 
   2784         hindo = (NJ_INT16)*((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle)
   2785                                          + get_stem_hindo(loctset->loct.handle, data)));
   2786 
   2787         hindo = CALCULATE_HINDO(hindo, loctset->dic_freq.base, loctset->dic_freq.high, COMP_DIC_FREQ_DIV);
   2788 
   2789 
   2790         if (hindo == freq_org) {
   2791             psrhCache->storebuff[abIdx].current = current;
   2792             return hindo;
   2793         }
   2794 
   2795         if (hindo < freq_org) {
   2796             if ((hindo > hindo_max) || ((hindo == hindo_max) && (current < hindo_data))) {
   2797                 hindo_max = hindo;
   2798                 hindo_data = current;
   2799             }
   2800         }
   2801     }
   2802 
   2803 
   2804     psrhCache->storebuff[abIdx].current = LOC_CURRENT_NO_ENTRY;
   2805     return -1;
   2806 }
   2807 
   2808 static NJ_INT16 bdic_get_word_freq(NJ_UINT8 * data_top, NJ_SEARCH_LOCATION_SET * loctset,
   2809                                    NJ_SEARCH_CACHE * psrhCache, NJ_UINT16 abIdx)
   2810 {
   2811     NJ_UINT8 *data;
   2812     NJ_INT16 hindo = 0;
   2813 
   2814 
   2815     if (psrhCache->storebuff[abIdx].current != LOC_CURRENT_NO_ENTRY) {
   2816 
   2817         data = data_top + psrhCache->storebuff[abIdx].top + psrhCache->storebuff[abIdx].current;
   2818 
   2819 
   2820         hindo = (NJ_INT16)*((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle)
   2821                                          + get_stem_hindo(loctset->loct.handle, data)));
   2822 
   2823         hindo = CALCULATE_HINDO(hindo, loctset->dic_freq.base, loctset->dic_freq.high, COMP_DIC_FREQ_DIV);
   2824 
   2825     } else {
   2826 
   2827         hindo = -1;
   2828     }
   2829 
   2830     return hindo;
   2831 }
   2832