/* * Copyright (C) 2008-2012 OMRON SOFTWARE Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "nj_lib.h" #include "nj_err.h" #include "nj_ext.h" #include "nj_dic.h" #include "njd.h" #define NODE_TERM(x) ((NJ_UINT8)(0x80 & (*(x)))) #define NODE_LEFT_EXIST(x) ((NJ_UINT8)(0x40 & (*(x)))) #define NODE_DATA_EXIST(x) ((NJ_UINT8)(0x20 & (*(x)))) #define NODE_IDX_EXIST(x) ((NJ_UINT8)(0x10 & (*(x)))) #define NODE_IDX_CNT(x) ((NJ_UINT8)((0x0f & (*(x))) + 2)) #define STEM_TERMINETER(x) ((NJ_UINT8)(0x80 & (*(x)))) #define STEM_NO_CONV_FLG(x) ((NJ_UINT8)(0x40 & (*(x)))) #define TERM_BIT (1) #define INDEX_BIT (8) #define APPEND_YOMI_FLG(h) ((NJ_UINT8)(0x80 & (*((h) + 0x1C)))) #define HINSI_NO_TOP_ADDR(h) ((NJ_UINT8*)((h) + NJ_INT32_READ((h) + 0x1D))) #define FHINSI_NO_CNT(h) ((NJ_INT16)(NJ_INT16_READ((h) + 0x21))) #define BHINSI_NO_CNT(h) ((NJ_INT16)(NJ_INT16_READ((h) + 0x23))) #define HINSI_NO_BYTE(h) ((NJ_UINT8)(*((h) + 0x25))) #define HINDO_NO_TOP_ADDR(h) ((NJ_UINT8*)((h) + NJ_INT32_READ((h) + 0x26))) #define HINDO_NO_CNT(h) ((NJ_UINT8)(*((h) + 0x2A))) #define STEM_AREA_TOP_ADDR(h) ((NJ_UINT8*)((h) + NJ_INT32_READ((h) + 0x2B))) #define BIT_CANDIDATE_LEN(h) ((NJ_UINT8)(*((h) + 0x2F))) #define BIT_FHINSI(h) ((NJ_UINT8)(*((h) + 0x30))) #define BIT_BHINSI(h) ((NJ_UINT8)(*((h) + 0x31))) #define BIT_HINDO_LEN(h) ((NJ_UINT8)(*((h) + 0x32))) #define BIT_MUHENKAN_LEN(h) ((NJ_UINT8)(*((h) + 0x33))) #define BIT_YOMI_LEN(h) ((NJ_UINT8)(*((h) + 0x35))) #define YOMI_INDX_TOP_ADDR(h) ((NJ_UINT8*)((h) + NJ_INT32_READ((h) + 0x42))) #define YOMI_INDX_CNT(h) ((NJ_INT16)(*((h) + 0x46))) #define YOMI_INDX_SIZE(h) ((NJ_INT8)(*((h) + 0x47))) #define NODE_AREA_TOP_ADDR(h) ((NJ_UINT8*)((h) + NJ_INT32_READ((h) + 0x48))) #define BIT_NODE_AREA_DATA_LEN(h) ((NJ_UINT8)(*((h) + 0x4C))) #define BIT_NODE_AREA_LEFT_LEN(h) ((NJ_UINT8)(*((h) + 0x4D))) #define NODE_AREA_MID_ADDR(h) ((NJ_UINT32)(NJ_INT32_READ((h) + 0x4E))) #define CAND_IDX_AREA_TOP_ADDR(h) ((NJ_UINT8*)((h) + NJ_INT32_READ((h) + 0x52))) #define CAND_IDX_AREA_CNT(h) ((NJ_UINT32)(((NJ_INT32_READ((h) + 0x56)) >> 8) & 0x00FFFFFF)) #define CAND_IDX_AREA_SIZE(h) ((NJ_UINT8)(*((h) + 0x59))) #define WORD_LEN(x) ((NJ_UINT16)(0x007F & (x))) #define CURRENT_INFO_SET ((NJ_UINT8)(0x10)) #define COMP_DIC_FREQ_DIV 63 #define LOC_CURRENT_NO_ENTRY 0xffffffffU typedef struct { NJ_UINT16 stem_size; NJ_UINT16 term; NJ_UINT16 no_conv_flg; NJ_HINDO hindo; NJ_UINT16 hindo_jitu; NJ_UINT16 candidate_size; NJ_UINT16 yomi_size; NJ_UINT16 fhinsi; NJ_UINT16 bhinsi; NJ_UINT16 fhinsi_jitu; NJ_UINT16 bhinsi_jitu; } STEM_DATA_SET; static NJ_INT16 get_stem_next(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data); static void get_stem_word(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data, STEM_DATA_SET *stem_set, NJ_UINT8 check); static void get_stem_cand_data(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data, STEM_DATA_SET *stem_set); static NJ_UINT16 get_stem_yomi_data(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data,STEM_DATA_SET *stem_set); static NJ_UINT16 get_stem_yomi_size(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data, NJ_UINT16 yomi_size); 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); static NJ_INT16 search_node(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset); static NJ_INT16 bdic_search_data(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset); static NJ_INT16 bdic_search_fore_data(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset); static NJ_HINDO get_stem_hindo(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data); static NJ_INT16 search_node2(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT16 hidx); static NJ_INT16 bdic_search_fore_data2(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT16 hidx); static NJ_INT16 search_yomi_node(NJ_UINT8 operation, NJ_UINT8 *node, NJ_UINT8 *now, NJ_UINT16 idx_no, NJ_CHAR *yomi, NJ_UINT16 yomilen, NJ_UINT8 *root, NJ_UINT8 *node_mid, NJ_UINT16 bit_left, NJ_UINT16 bit_data, NJ_UINT8 *data_top, NJ_INT16 ytbl_cnt, NJ_UINT16 y, NJ_UINT8 *ytbl_top, NJ_CACHE_INFO *storebuf, NJ_UINT8 **con_node, NJ_UINT32 *data_offset); static NJ_INT16 get_node_bottom(NJ_CHAR *yomi, NJ_UINT8 *now, NJ_UINT8 *node_mid, NJ_UINT8 *data_top, NJ_UINT16 bit_left, NJ_UINT16 bit_data, NJ_UINT32 top, NJ_DIC_HANDLE handle, NJ_UINT32 *ret_bottom); static NJ_INT16 bdic_get_next_data(NJ_UINT8 *data_top, NJ_UINT8 *data_end, NJ_SEARCH_LOCATION_SET *loctset, NJ_SEARCH_CACHE *psrhCache, NJ_UINT16 abIdx); static NJ_INT16 bdic_get_word_freq(NJ_UINT8 *data_top, NJ_SEARCH_LOCATION_SET *loctset, NJ_SEARCH_CACHE *psrhCache, NJ_UINT16 abIdx); static NJ_HINDO get_stem_hindo(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data) { NJ_UINT8 flg_bit; NJ_UINT16 data; NJ_UINT16 pos, j, bit_all; flg_bit = BIT_MUHENKAN_LEN(hdl); if (NJ_GET_DIC_FMT(hdl) != NJ_DIC_FMT_KANAKAN) { flg_bit++; } if (BIT_HINDO_LEN(hdl)) { bit_all = (NJ_UINT16)(TERM_BIT + flg_bit); pos = (NJ_UINT16)(bit_all >> 3); data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos)); j = (NJ_UINT16)(bit_all & 0x0007); return GET_BITFIELD_16(data, j, BIT_HINDO_LEN(hdl)); } else { return 0; } } static NJ_INT16 get_stem_next(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data) { NJ_UINT8 flg_bit; NJ_UINT16 data; NJ_UINT16 pos, j, bit_all; NJ_UINT16 stem_size, cand_bit, yomi_bit; NJ_UINT16 candidate_size, yomi_size; flg_bit = BIT_MUHENKAN_LEN(hdl); if (NJ_GET_DIC_FMT(hdl) != NJ_DIC_FMT_KANAKAN) { flg_bit++; } bit_all = (NJ_UINT16)(TERM_BIT + flg_bit + BIT_HINDO_LEN(hdl) + BIT_FHINSI(hdl) + BIT_BHINSI(hdl)); pos = (NJ_UINT16)(bit_all >> 3); data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos)); j = (NJ_UINT16)(bit_all & 0x0007); cand_bit = BIT_CANDIDATE_LEN(hdl); candidate_size = GET_BITFIELD_16(data, j, cand_bit); bit_all += cand_bit; if (APPEND_YOMI_FLG(hdl) && STEM_TERMINETER(stem_data)) { pos = (NJ_UINT16)(bit_all >> 3); data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos)); j = (NJ_UINT16)(bit_all & 0x0007); yomi_bit = BIT_YOMI_LEN(hdl); yomi_size = GET_BITFIELD_16(data, j, yomi_bit); bit_all += yomi_bit; } else { yomi_size = 0; } stem_size = GET_BIT_TO_BYTE(bit_all); stem_size += candidate_size; stem_size += yomi_size; return stem_size; } static void get_stem_word(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data, STEM_DATA_SET *stem_set, NJ_UINT8 check) { NJ_UINT8 flg_bit; NJ_UINT16 data; NJ_UINT16 pos, j, bit_all = 0; NJ_UINT16 bit; NJ_UINT16 dpos = 0; NJ_INT16 next; NJ_UINT8 b; NJ_UINT8 *wkc; flg_bit = BIT_MUHENKAN_LEN(hdl); if (NJ_GET_DIC_FMT(hdl) != NJ_DIC_FMT_KANAKAN) { flg_bit++; } if (BIT_HINDO_LEN(hdl)) { bit_all = (NJ_UINT16)(TERM_BIT + flg_bit); pos = (NJ_UINT16)(bit_all >> 3); data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos)); j = (NJ_UINT16)(bit_all & 0x0007); stem_set->hindo = GET_BITFIELD_16(data, j, BIT_HINDO_LEN(hdl)); } else { stem_set->hindo = 0; } stem_set->hindo_jitu = (NJ_UINT16)(*(HINDO_NO_TOP_ADDR(hdl) + stem_set->hindo)); if (BIT_FHINSI(hdl)) { bit_all = (NJ_UINT16)(TERM_BIT + flg_bit + BIT_HINDO_LEN(hdl)); pos = (NJ_UINT16)(bit_all >> 3); data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos)); j = (NJ_UINT16)(bit_all & 0x0007); stem_set->fhinsi = GET_BITFIELD_16(data, j, BIT_FHINSI(hdl)); } else { stem_set->fhinsi = 0; } b = HINSI_NO_BYTE(hdl); wkc = (NJ_UINT8*)(HINSI_NO_TOP_ADDR(hdl) + (b * (NJ_UINT16)(stem_set->fhinsi))); if (b == 2) { stem_set->fhinsi_jitu = (NJ_UINT16)(NJ_INT16_READ(wkc)); } else { stem_set->fhinsi_jitu = (NJ_UINT16)*wkc; } if (BIT_BHINSI(hdl)) { bit_all = (NJ_UINT16)(TERM_BIT + flg_bit + BIT_HINDO_LEN(hdl) + BIT_FHINSI(hdl)); pos = (NJ_UINT16)(bit_all >> 3); data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos)); j = (NJ_UINT16)(bit_all & 0x0007); stem_set->bhinsi = GET_BITFIELD_16(data, j, BIT_BHINSI(hdl)); } else { stem_set->bhinsi = 0; } wkc = (NJ_UINT8*)(HINSI_NO_TOP_ADDR(hdl) + (b * (FHINSI_NO_CNT(hdl) + (NJ_UINT16)(stem_set->bhinsi)))); if (b == 2) { stem_set->bhinsi_jitu = (NJ_UINT16)(NJ_INT16_READ(wkc)); } else { stem_set->bhinsi_jitu = (NJ_UINT16)*wkc; } if (check != 1) { bit_all = (NJ_UINT16)(TERM_BIT + flg_bit + BIT_HINDO_LEN(hdl) + BIT_FHINSI(hdl) + BIT_BHINSI(hdl)); pos = (NJ_UINT16)(bit_all >> 3); data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos)); j = (NJ_UINT16)(bit_all & 0x0007); bit = BIT_CANDIDATE_LEN(hdl); stem_set->candidate_size = GET_BITFIELD_16(data, j, bit); bit_all += bit; } if (check == 0) { stem_set->yomi_size = 0; if (APPEND_YOMI_FLG(hdl) && STEM_TERMINETER(stem_data)) { pos = (NJ_UINT16)(bit_all >> 3); data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos)); j = (NJ_UINT16)(bit_all & 0x0007); bit = BIT_YOMI_LEN(hdl); stem_set->yomi_size = GET_BITFIELD_16(data, j, bit); bit_all += bit; dpos = GET_BIT_TO_BYTE(bit_all); dpos += stem_set->candidate_size; } else if (APPEND_YOMI_FLG(hdl)) { while (!(STEM_TERMINETER(stem_data))) { next = get_stem_next(hdl, stem_data); stem_data += next; } dpos = get_stem_yomi_data(hdl, stem_data, stem_set); } if (stem_set->yomi_size) { stem_set->yomi_size = get_stem_yomi_size(hdl, stem_data + dpos, stem_set->yomi_size); } } } static void get_stem_cand_data(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data, STEM_DATA_SET *stem_set) { NJ_UINT8 flg_bit; NJ_UINT16 data; NJ_UINT16 pos, j, bit_all; NJ_UINT16 cand_bit, yomi_bit; flg_bit = BIT_MUHENKAN_LEN(hdl); if (NJ_GET_DIC_FMT(hdl) != NJ_DIC_FMT_KANAKAN) { flg_bit++; } bit_all = (NJ_UINT16)(TERM_BIT + flg_bit + BIT_HINDO_LEN(hdl) + BIT_FHINSI(hdl) + BIT_BHINSI(hdl)); pos = (NJ_UINT16)(bit_all >> 3); data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos)); cand_bit = BIT_CANDIDATE_LEN(hdl); j = (NJ_UINT16)(bit_all & 0x0007); stem_set->candidate_size = GET_BITFIELD_16(data, j, cand_bit); bit_all += cand_bit; if (APPEND_YOMI_FLG(hdl) && STEM_TERMINETER(stem_data)) { yomi_bit = BIT_YOMI_LEN(hdl); bit_all += yomi_bit; } stem_set->stem_size = GET_BIT_TO_BYTE(bit_all); } static NJ_UINT16 get_stem_yomi_data(NJ_DIC_HANDLE hdl, NJ_UINT8 *stem_data,STEM_DATA_SET *stem_set) { NJ_UINT16 flg_bit; NJ_UINT16 data; NJ_UINT16 cand_bit, yomi_bit; NJ_UINT16 pos, j, bit_all; NJ_UINT16 yomi_pos; NJ_UINT16 candidate_size; flg_bit = BIT_MUHENKAN_LEN(hdl); if (NJ_GET_DIC_FMT(hdl) != NJ_DIC_FMT_KANAKAN) { flg_bit++; } bit_all = (NJ_UINT16)(TERM_BIT + flg_bit + BIT_HINDO_LEN(hdl) + BIT_FHINSI(hdl) + BIT_BHINSI(hdl)); pos = (NJ_UINT16)(bit_all >> 3); data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos)); j = (NJ_UINT16)(bit_all & 0x0007); cand_bit = BIT_CANDIDATE_LEN(hdl); candidate_size = GET_BITFIELD_16(data, j, cand_bit); bit_all += cand_bit; if (APPEND_YOMI_FLG(hdl) && STEM_TERMINETER(stem_data)) { pos = (NJ_UINT16)(bit_all >> 3); data = (NJ_UINT16)(NJ_INT16_READ(stem_data + pos)); j = (NJ_UINT16)(bit_all & 0x0007); yomi_bit = BIT_YOMI_LEN(hdl); stem_set->yomi_size = GET_BITFIELD_16(data, j, yomi_bit); bit_all += yomi_bit; } else { stem_set->yomi_size = 0; } yomi_pos = GET_BIT_TO_BYTE(bit_all); yomi_pos += candidate_size; return yomi_pos; } static NJ_UINT16 get_stem_yomi_size(NJ_DIC_HANDLE hdl, NJ_UINT8 *ydata, NJ_UINT16 yomi_size) { NJ_INT16 ytbl_cnt; NJ_INT8 ysize; NJ_UINT8 *ytbl_top; NJ_UINT8 *ytbl; NJ_UINT8 yidx; NJ_UINT16 i; NJ_UINT16 len; ytbl_cnt = YOMI_INDX_CNT(hdl); if (ytbl_cnt) { ysize = YOMI_INDX_SIZE(hdl); ytbl_top = YOMI_INDX_TOP_ADDR(hdl); len = 0; for (i = 0; i < yomi_size; i++) { if (ysize == 2) { yidx = *(ydata+i); ytbl = ytbl_top + ((yidx-1) * ysize); len += UTL_CHAR(ytbl); } else { len++; } } return len * sizeof(NJ_CHAR); } else { return yomi_size; } } 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) { NJ_INT16 ytbl_cnt; NJ_INT8 ysize; NJ_UINT8 *ytbl_top, *ytbl; NJ_UINT8 *ydata; NJ_UINT8 yidx; NJ_UINT16 i; NJ_UINT16 copy_len; NJ_UINT16 char_len; ytbl_cnt = YOMI_INDX_CNT(hdl); ysize = YOMI_INDX_SIZE(hdl); ytbl_top = YOMI_INDX_TOP_ADDR(hdl); ydata = stem_data + yomi_pos; if (ytbl_cnt) { copy_len = 0; for (i = 0; i < yomi_size; i++) { yidx = *(ydata + i); ytbl = ytbl_top + ((yidx - 1) * ysize); if (ysize == 2) { char_len = UTL_CHAR(ytbl); if (((copy_len + char_len + NJ_TERM_LEN) * sizeof(NJ_CHAR)) > size) { return size; } while (char_len > 0) { NJ_CHAR_COPY(yomi + copy_len, ytbl); copy_len++; char_len--; ytbl += sizeof(NJ_CHAR); } } else { if (((copy_len + 1 + NJ_TERM_LEN) * sizeof(NJ_CHAR)) > size) { return size; } *(yomi + copy_len) = (NJ_CHAR)(*ytbl); copy_len++; } } } else { if ((yomi_size + (NJ_TERM_LEN * sizeof(NJ_CHAR))) > size) { return size; } nj_memcpy((NJ_UINT8*)yomi, ydata, yomi_size); copy_len = yomi_size / sizeof(NJ_CHAR); } *(yomi + copy_len) = NJ_CHAR_NUL; return copy_len; } static NJ_INT16 search_node(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset) { NJ_UINT8 *root, *now, *node, *node_mid; NJ_UINT8 index; NJ_UINT8 *byomi; NJ_UINT8 *wkc; NJ_UINT8 idx_no; NJ_INT16 idx; NJ_INT16 char_size; NJ_INT16 left, right, mid; NJ_INT16 ytbl_cnt; NJ_UINT16 c, d; NJ_UINT8 c1 = 0, c2 = 0; NJ_UINT16 y; NJ_UINT16 ysize = (condition->ylen * sizeof(NJ_CHAR)); NJ_UINT8 *ytbl_top; NJ_UINT16 idx_cnt; NJ_UINT16 nd_index; NJ_UINT16 bit_left, bit_data; NJ_UINT32 data_offset; NJ_UINT16 data; NJ_UINT16 pos, j, bit_all, bit_tmp, bit_idx; NJ_UINT32 data_l; NJ_UINT8 restart_flg = 0; NJ_UINT8 bottom_flg = 0; NJ_UINT8 *data_top, *stem_data; NJ_UINT16 hindo, hindo_max; NJ_UINT32 current,hindo_max_data, bottom, next; node = NULL; byomi = (NJ_UINT8*)(condition->yomi); root = NODE_AREA_TOP_ADDR(loctset->loct.handle); node_mid = root + NODE_AREA_MID_ADDR(loctset->loct.handle); now = node_mid; idx_no = 0; idx_cnt = 1; bit_left = BIT_NODE_AREA_LEFT_LEN(loctset->loct.handle); bit_data = BIT_NODE_AREA_DATA_LEN(loctset->loct.handle); ytbl_cnt = YOMI_INDX_CNT(loctset->loct.handle); y = YOMI_INDX_SIZE(loctset->loct.handle); ytbl_top = YOMI_INDX_TOP_ADDR(loctset->loct.handle); data_top = STEM_AREA_TOP_ADDR(loctset->loct.handle); if ((condition->operation == NJ_CUR_OP_FORE) && NJ_CHAR_STRLEN_IS_0(condition->yomi)) { ysize = 0; node = root; } while (ysize > 0) { if (ytbl_cnt != 0) { char_size = UTL_CHAR(byomi) * sizeof(NJ_CHAR); if (char_size > 2) { loctset->loct.status = NJ_ST_SEARCH_END_EXT; return 0; } if (char_size == 2) { if (y == 1) { return 0; } c1 = *byomi; c2 = *(byomi + 1); c = (NJ_UINT16)((c1 << 8) | c2); } else { c1 = *byomi; c2 = 0x00; c = (NJ_UINT16)(*byomi); } idx = -1; left = 0; right = ytbl_cnt; if (y == 2) { while (left <= right) { mid = (left + right) >> 1; wkc = ytbl_top + (mid << 1); if (c1 == *wkc) { if (c2 == *(wkc + 1)) { idx = (NJ_UINT16)(mid + 1); break; } if (c2 < *(wkc + 1)) { right = mid - 1; } else { left = mid + 1; } } else if (c1 < *wkc) { right = mid - 1; } else { left = mid + 1; } } } else { while (left <= right) { mid = (left + right) >> 1; wkc = ytbl_top + (mid * y); d = (NJ_UINT16)(*wkc); if (c == d) { idx = (NJ_UINT16)(mid + 1); break; } if (c < d) { right = mid - 1; } else { left = mid + 1; } } } if (idx < 0) { loctset->loct.status = NJ_ST_SEARCH_END_EXT; return 0; } index = (NJ_UINT8)idx; } else { index = *byomi; char_size = 1; } byomi += char_size; ysize -= char_size; while (now < data_top) { if (NODE_IDX_EXIST(now)) { bit_idx = 8; idx_cnt = NODE_IDX_CNT(now); } else { bit_idx = 4; idx_cnt = 1; } bit_all = bit_idx; if (NODE_LEFT_EXIST(now)) { bit_all += bit_left; } if (NODE_DATA_EXIST(now)) { bit_all += bit_data; } bit_tmp = bit_all; bit_all += (NJ_UINT16)(idx_no << 3); pos = (NJ_UINT16)(bit_all >> 3); data = (NJ_UINT16)(NJ_INT16_READ(now + pos)); j = (NJ_UINT16)(bit_all & 0x0007); nd_index = GET_BITFIELD_16(data, j, INDEX_BIT); if (index == (NJ_UINT8)nd_index) { break; } else { if ((!NODE_TERM(now)) && (index > (NJ_UINT8)nd_index) && (idx_no == 0)) { now += GET_BIT_TO_BYTE(bit_tmp + (idx_cnt * 8)); if (now == node_mid) { loctset->loct.status = NJ_ST_SEARCH_END_EXT; return 0; } continue; } else { if ((now == node_mid) && (restart_flg == 0) && (index < (NJ_UINT8)nd_index) && (idx_no == 0) && (root != node_mid)) { now = root; idx_no = 0; restart_flg = 1; continue; } loctset->loct.status = NJ_ST_SEARCH_END_EXT; return 0; } } } if ( (idx_cnt > (NJ_UINT16)(idx_no + 1))) { if (ysize == 0) { if (condition->operation == NJ_CUR_OP_FORE) { node = now; break; } loctset->loct.status = NJ_ST_SEARCH_END; return 0; } idx_no++; continue; } node = now; idx_no = 0; if (ysize == 0) { break; } else { if (!(NODE_LEFT_EXIST(now))) { loctset->loct.status = NJ_ST_SEARCH_END_EXT; return 0; } } if (NODE_IDX_EXIST(now)) { bit_idx = 8; } else { bit_idx = 4; } pos = (NJ_UINT16)(bit_idx >> 3); data_l = (NJ_UINT32)(NJ_INT32_READ(now + pos)); j = (NJ_UINT16)(bit_idx & 0x0007); now += GET_BITFIELD_32(data_l, j, bit_left); } now = node; if ((node == NULL) || !(NODE_DATA_EXIST(node))) { if ((condition->operation == NJ_CUR_OP_FORE) && (node != NULL)) { while (!NODE_DATA_EXIST(node)) { if (!(NODE_LEFT_EXIST(node))) { loctset->loct.status = NJ_ST_SEARCH_END; return 0; } if (NODE_IDX_EXIST(node)) { bit_idx = 8; } else { bit_idx = 4; } pos = (NJ_UINT16)(bit_idx >> 3); data_l = (NJ_UINT32)(NJ_INT32_READ(node + pos)); j = (NJ_UINT16)(bit_idx & 0x0007); node += GET_BITFIELD_32(data_l, j, bit_left); } } else { loctset->loct.status = NJ_ST_SEARCH_END; return 0; } } if (NODE_IDX_EXIST(node)) { bit_idx = 8; } else { bit_idx = 4; } if (NODE_LEFT_EXIST(node)) { bit_all = bit_idx + bit_left; } else { bit_all = bit_idx; } pos = (NJ_UINT16)(bit_all >> 3); data_l = (NJ_UINT32)(NJ_INT32_READ(node + pos)); j = (NJ_UINT16)(bit_all & 0x0007); data_offset = GET_BITFIELD_32(data_l, j, bit_data); loctset->loct.top = data_offset; loctset->loct.current = 0; if (condition->operation == NJ_CUR_OP_FORE) { bottom = loctset->loct.top; if (NJ_CHAR_STRLEN_IS_0(condition->yomi)) { node = node_mid; } else { node = now; if (NODE_LEFT_EXIST(node)) { if (NODE_IDX_EXIST(node)) { bit_all = 8; } else { bit_all = 4; } pos = (NJ_UINT16)(bit_all >> 3); data_l = (NJ_UINT32)(NJ_INT32_READ(node + pos)); j = (NJ_UINT16)(bit_all & 0x0007); node += GET_BITFIELD_32(data_l, j, bit_left); } else { bottom_flg = 1; } } if (!bottom_flg) { while (node < data_top) { if (!NODE_TERM(node)) { if (NODE_IDX_EXIST(node)) { bit_all = 8; idx_cnt = NODE_IDX_CNT(node); } else { bit_all = 4; idx_cnt = 1; } if (NODE_LEFT_EXIST(node)) { bit_all += bit_left; } if (NODE_DATA_EXIST(node)) { bit_all += bit_data; } node += GET_BIT_TO_BYTE(bit_all + (idx_cnt * 8)); } else { if (!NODE_LEFT_EXIST(node)) { if (NODE_DATA_EXIST(node)) { if (NODE_IDX_EXIST(node)) { bit_all = 8; } else { bit_all = 4; } pos = (NJ_UINT16)(bit_all >> 3); data_l = (NJ_UINT32)(NJ_INT32_READ(node + pos)); j = (NJ_UINT16)(bit_all & 0x0007); data_offset = GET_BITFIELD_32(data_l, j, bit_data); bottom = data_offset; break; } else { return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_DIC_BROKEN); } } else { if (NODE_IDX_EXIST(node)) { bit_all = 8; } else { bit_all = 4; } pos = (NJ_UINT16)(bit_all >> 3); data_l = (NJ_UINT32)(NJ_INT32_READ(node + pos)); j = (NJ_UINT16)(bit_all & 0x0007); node += GET_BITFIELD_32(data_l, j, bit_left); } } } } stem_data = data_top + bottom; while (!(STEM_TERMINETER(stem_data))) { next = get_stem_next(loctset->loct.handle, stem_data); stem_data += next; } loctset->loct.bottom = (NJ_UINT32)(stem_data - data_top); stem_data = data_top + loctset->loct.top; hindo = (NJ_UINT16) *((NJ_UINT8*)(HINDO_NO_TOP_ADDR(loctset->loct.handle) + get_stem_hindo(loctset->loct.handle, stem_data))); hindo_max = hindo; hindo_max_data = 0; if (condition->mode == NJ_CUR_MODE_FREQ) { j = get_stem_next(loctset->loct.handle, stem_data); current = j; stem_data += j; while (stem_data <= (data_top + loctset->loct.bottom)) { hindo = (NJ_UINT16) *((NJ_UINT8*)(HINDO_NO_TOP_ADDR(loctset->loct.handle) + get_stem_hindo(loctset->loct.handle, stem_data))); if (hindo > hindo_max) { hindo_max = hindo; hindo_max_data = current; } j = get_stem_next(loctset->loct.handle, stem_data); current += j; stem_data += j; } } loctset->cache_freq = CALCULATE_HINDO(hindo_max, loctset->dic_freq.base, loctset->dic_freq.high, COMP_DIC_FREQ_DIV); loctset->loct.current = hindo_max_data; } return 1; } static NJ_INT16 bdic_search_data(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset) { NJ_UINT8 *data, *data_end; NJ_INT16 i, current = 0; NJ_UINT16 hindo; data = STEM_AREA_TOP_ADDR(loctset->loct.handle); data += loctset->loct.top + loctset->loct.current; if (GET_LOCATION_STATUS(loctset->loct.status) != NJ_ST_SEARCH_NO_INIT) { if (STEM_TERMINETER(data)) { loctset->loct.status = NJ_ST_SEARCH_END; return 0; } i = get_stem_next(loctset->loct.handle, data); data += i; current += i; } if (NJ_GET_DIC_FMT(loctset->loct.handle) == NJ_DIC_FMT_KANAKAN) { data_end = loctset->loct.handle + NJ_DIC_COMMON_HEADER_SIZE + NJ_INT32_READ(loctset->loct.handle + NJ_DIC_POS_DATA_SIZE) + NJ_INT32_READ(loctset->loct.handle + NJ_DIC_POS_EXT_SIZE) - NJ_DIC_ID_LEN; } else { data_end = CAND_IDX_AREA_TOP_ADDR(loctset->loct.handle); } if (data < data_end) { loctset->loct.status = NJ_ST_SEARCH_READY; loctset->loct.current += current; hindo = (NJ_UINT16) *((NJ_UINT8*)(HINDO_NO_TOP_ADDR(loctset->loct.handle) + get_stem_hindo(loctset->loct.handle, data))); loctset->cache_freq = CALCULATE_HINDO(hindo, loctset->dic_freq.base, loctset->dic_freq.high, COMP_DIC_FREQ_DIV); return 1; } loctset->loct.status = NJ_ST_SEARCH_END; return 0; } static NJ_INT16 bdic_search_fore_data(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset) { NJ_UINT8 *data, *data_top, *bottom, *data_end; NJ_INT16 i = 0; NJ_INT16 hindo = 0; NJ_INT16 hindo_max = -1; NJ_UINT8 no_hit = 0; NJ_UINT32 current = loctset->loct.current; NJ_UINT8 *current_org; NJ_UINT32 hindo_data = 0; if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_NO_INIT) { loctset->loct.status = NJ_ST_SEARCH_READY; loctset->loct.current_info = CURRENT_INFO_SET; return 1; } data_top = STEM_AREA_TOP_ADDR(loctset->loct.handle); data = data_top + loctset->loct.top + loctset->loct.current; current_org = data; bottom = data_top + loctset->loct.bottom; if (NJ_GET_DIC_FMT(loctset->loct.handle) == NJ_DIC_FMT_KANAKAN) { data_end = loctset->loct.handle + NJ_DIC_COMMON_HEADER_SIZE + NJ_INT32_READ(loctset->loct.handle + NJ_DIC_POS_DATA_SIZE) + NJ_INT32_READ(loctset->loct.handle + NJ_DIC_POS_EXT_SIZE) - NJ_DIC_ID_LEN; } else { data_end = CAND_IDX_AREA_TOP_ADDR(loctset->loct.handle); } if (condition->mode == NJ_CUR_MODE_FREQ) { while (data < data_end) { i = get_stem_next(loctset->loct.handle, data); data += i; current += i; if (data > bottom) { if (loctset->cache_freq == 0) { loctset->loct.status = NJ_ST_SEARCH_END; return 0; } else if (no_hit == 1) { loctset->loct.status = NJ_ST_SEARCH_END; return 0; } loctset->cache_freq -= 1; data = data_top + loctset->loct.top; current = 0; no_hit = 1; } if ((hindo_max != -1) && (data == current_org)) { loctset->loct.status = NJ_ST_SEARCH_READY; loctset->loct.current_info = CURRENT_INFO_SET; loctset->loct.current = hindo_data; loctset->cache_freq = hindo_max; return 1; } hindo = (NJ_INT16) *((NJ_UINT8*)(HINDO_NO_TOP_ADDR(loctset->loct.handle) + get_stem_hindo(loctset->loct.handle, data))); hindo = CALCULATE_HINDO(hindo, loctset->dic_freq.base, loctset->dic_freq.high, COMP_DIC_FREQ_DIV); if (hindo == loctset->cache_freq) { loctset->loct.status = NJ_ST_SEARCH_READY; loctset->loct.current_info = CURRENT_INFO_SET; loctset->loct.current = current; return 1; } if (hindo < loctset->cache_freq) { if (((hindo == hindo_max) && (current < hindo_data)) || (hindo > hindo_max)) { hindo_max = hindo; hindo_data = current; } } } } else { i = get_stem_next(loctset->loct.handle, data); data += i; current += i; if (data > bottom) { loctset->loct.status = NJ_ST_SEARCH_END; return 0; } hindo = (NJ_INT16) *((NJ_UINT8*)(HINDO_NO_TOP_ADDR(loctset->loct.handle) + get_stem_hindo(loctset->loct.handle, data))); loctset->cache_freq = CALCULATE_HINDO(hindo, loctset->dic_freq.base, loctset->dic_freq.high, COMP_DIC_FREQ_DIV); loctset->loct.status = NJ_ST_SEARCH_READY; loctset->loct.current_info = CURRENT_INFO_SET; loctset->loct.current = current; return 1; } loctset->loct.status = NJ_ST_SEARCH_END; return 0; } NJ_INT16 njd_b_search_word(NJ_SEARCH_CONDITION *con, NJ_SEARCH_LOCATION_SET *loctset) { NJ_INT16 ret; NJ_DIC_INFO *pdicinfo; NJ_UINT16 hIdx; switch (con->operation) { case NJ_CUR_OP_COMP: if (con->mode != NJ_CUR_MODE_FREQ) { loctset->loct.status = NJ_ST_SEARCH_END_EXT; return 0; } break; case NJ_CUR_OP_FORE: if (APPEND_YOMI_FLG(loctset->loct.handle) == 0) { loctset->loct.status = NJ_ST_SEARCH_END_EXT; return 0; } if ((NJ_GET_DIC_TYPE_EX(loctset->loct.type, loctset->loct.handle) != NJ_DIC_TYPE_CUSTOM_COMPRESS) && NJ_CHAR_STRLEN_IS_0(con->yomi)) { loctset->loct.status = NJ_ST_SEARCH_END_EXT; return 0; } break; default: loctset->loct.status = NJ_ST_SEARCH_END_EXT; return 0; } if (con->ylen > NJ_GET_MAX_YLEN(loctset->loct.handle)) { loctset->loct.status = NJ_ST_SEARCH_END_EXT; return 0; } if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_NO_INIT) { switch (con->operation) { case NJ_CUR_OP_COMP: ret = search_node(con, loctset); if (ret < 1) { return ret; } ret = bdic_search_data(con, loctset); if (ret < 1) { loctset->loct.status = NJ_ST_SEARCH_END; } break; case NJ_CUR_OP_FORE: pdicinfo = con->ds->dic; for (hIdx = 0; (hIdx < NJ_MAX_DIC) && (pdicinfo->handle != loctset->loct.handle); hIdx++) { pdicinfo++; } if (hIdx == NJ_MAX_DIC) { loctset->loct.status = NJ_ST_SEARCH_END; return 0; } if ((con->ds->dic[hIdx].srhCache == NULL) || (con->ylen == 0) || !(con->ds->mode & 0x0001)) { ret = search_node(con, loctset); if (ret < 1) { return ret; } ret = bdic_search_fore_data(con, loctset); } else { ret = search_node2(con, loctset, hIdx); if (ret == NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_NOT_ENOUGH)) { NJ_SET_CACHEOVER_TO_SCACHE(con->ds->dic[hIdx].srhCache); ret = search_node2(con, loctset, hIdx); } if (ret < 1) { return ret; } ret = bdic_search_fore_data2(con, loctset, hIdx); } if (ret < 1) { loctset->loct.status = NJ_ST_SEARCH_END; } break; default: loctset->loct.status = NJ_ST_SEARCH_END_EXT; return 0; } } else if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_READY) { switch (con->operation) { case NJ_CUR_OP_COMP: ret = bdic_search_data(con, loctset); if (ret < 1) { loctset->loct.status = NJ_ST_SEARCH_END; } break; case NJ_CUR_OP_FORE: pdicinfo = con->ds->dic; for (hIdx = 0; (hIdx < NJ_MAX_DIC) && (pdicinfo->handle != loctset->loct.handle); hIdx++) { pdicinfo++; } if (hIdx == NJ_MAX_DIC) { loctset->loct.status = NJ_ST_SEARCH_END; return 0; } if ((con->ds->dic[hIdx].srhCache == NULL) || (con->ylen == 0) || !(con->ds->mode & 0x0001)) { ret = bdic_search_fore_data(con, loctset); } else { ret = bdic_search_fore_data2(con, loctset, hIdx); } if (ret < 1) { loctset->loct.status = NJ_ST_SEARCH_END; } break; default: loctset->loct.status = NJ_ST_SEARCH_END; return 0; } } else { loctset->loct.status = NJ_ST_SEARCH_END; return 0; } return ret; } NJ_INT16 njd_b_get_word(NJ_SEARCH_LOCATION_SET *loctset, NJ_WORD *word) { NJ_UINT8 *data; STEM_DATA_SET stem_set; NJ_UINT8 check; if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_END) { return 0; } if (GET_LOCATION_OPERATION(loctset->loct.status) == NJ_CUR_OP_FORE) { data = STEM_AREA_TOP_ADDR(loctset->loct.handle); data += loctset->loct.top + loctset->loct.current; check = 0; } else { data = STEM_AREA_TOP_ADDR(loctset->loct.handle); data += loctset->loct.top + loctset->loct.current; check = 2; } get_stem_word(loctset->loct.handle, data, &stem_set, check); if (GET_LOCATION_OPERATION(loctset->loct.status) == NJ_CUR_OP_FORE) { word->stem.info1 = (NJ_UINT16)(stem_set.yomi_size / sizeof(NJ_CHAR)); } word->stem.info1 = WORD_LEN(word->stem.info1); word->stem.info1 |= (NJ_UINT16)(stem_set.fhinsi_jitu << 7); if (check != 1) { if (stem_set.candidate_size == 0) { if (GET_LOCATION_OPERATION(loctset->loct.status) == NJ_CUR_OP_FORE) { word->stem.info2 = (NJ_UINT16)(stem_set.yomi_size / sizeof(NJ_CHAR)); } else { word->stem.info2 = (NJ_UINT16)NJ_GET_YLEN_FROM_STEM(word); } } else { word->stem.info2 = (NJ_UINT16)(stem_set.candidate_size / sizeof(NJ_CHAR)); } } else { word->stem.info2 = (NJ_UINT16)NJ_GET_YLEN_FROM_STEM(word); } word->stem.info2 = WORD_LEN(word->stem.info2); word->stem.info2 |= (NJ_UINT16)(stem_set.bhinsi_jitu << 7); word->stem.hindo = CALCULATE_HINDO(stem_set.hindo_jitu, loctset->dic_freq.base, loctset->dic_freq.high, COMP_DIC_FREQ_DIV); word->stem.loc = loctset->loct; return 1; } NJ_INT16 njd_b_get_candidate(NJ_WORD *word, NJ_CHAR *candidate, NJ_UINT16 size) { NJ_SEARCH_LOCATION *loc; NJ_CHAR *wkc, *cand; NJ_UINT8 *wkd; NJ_UINT8 *data; NJ_UINT8 *data_org; NJ_UINT16 len, j; STEM_DATA_SET stem_set; NJ_INT16 next; NJ_UINT16 yomi_pos; NJ_CHAR ybuf[NJ_MAX_LEN + NJ_TERM_LEN]; if ((GET_LOCATION_OPERATION(word->stem.loc.status) == NJ_CUR_OP_COMP) || (GET_LOCATION_OPERATION(word->stem.loc.status) == NJ_CUR_OP_FORE)) { loc = &word->stem.loc; data = STEM_AREA_TOP_ADDR(loc->handle); data += loc->top + loc->current; get_stem_cand_data(loc->handle, data, &stem_set); len = stem_set.candidate_size / sizeof(NJ_CHAR); } else { return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_CANDIDATE, NJ_ERR_INVALID_RESULT); } if (len == 0) { data_org = data; if (GET_LOCATION_OPERATION(word->stem.loc.status) == NJ_CUR_OP_COMP) { len = WORD_LEN(word->stem.info1); if (size < ((len + NJ_TERM_LEN) * sizeof(NJ_CHAR))) { return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_CANDIDATE, NJ_ERR_BUFFER_NOT_ENOUGH); } wkc = word->yomi; } else { while (!(STEM_TERMINETER(data))) { next = get_stem_next(loc->handle, data); data += next; } yomi_pos = get_stem_yomi_data(loc->handle, data, &stem_set); wkc = ybuf; len = get_stem_yomi_string(loc->handle, data, wkc, yomi_pos, stem_set.yomi_size, size); if (size < ((len + NJ_TERM_LEN) * sizeof(NJ_CHAR))) { return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_CANDIDATE, NJ_ERR_BUFFER_NOT_ENOUGH); } } if (STEM_NO_CONV_FLG(data_org) == 0) { cand = candidate; for (j = 0; j < len; j++) { *cand++ = *wkc++; } *cand = NJ_CHAR_NUL; } else { nje_convert_hira_to_kata(wkc, candidate, len); } } else { if (size < (stem_set.candidate_size + (NJ_TERM_LEN*sizeof(NJ_CHAR)))) { return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_CANDIDATE, NJ_ERR_BUFFER_NOT_ENOUGH); } wkc = candidate; wkd = data + stem_set.stem_size; for (j = 0; j < len; j++) { NJ_CHAR_COPY(wkc, wkd); wkd += sizeof(NJ_CHAR); wkc++; } *wkc = NJ_CHAR_NUL; } return len; } NJ_INT16 njd_b_get_stroke(NJ_WORD *word, NJ_CHAR *stroke, NJ_UINT16 size) { NJ_SEARCH_LOCATION *loc; NJ_UINT8 *data; NJ_INT16 len; NJ_INT16 next; NJ_UINT16 yomi_pos; STEM_DATA_SET stem_set; if (GET_LOCATION_OPERATION(word->stem.loc.status) == NJ_CUR_OP_FORE) { if (NJ_GET_YLEN_FROM_STEM(word) == 0) { return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_STROKE, NJ_ERR_INVALID_RESULT); } loc = &word->stem.loc; data = STEM_AREA_TOP_ADDR(loc->handle); data += loc->top + loc->current; } else { return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_STROKE, NJ_ERR_INVALID_RESULT); } while (!(STEM_TERMINETER(data))) { next = get_stem_next(loc->handle, data); data += next; } yomi_pos = get_stem_yomi_data(loc->handle, data, &stem_set); if (stem_set.yomi_size == 0) { return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_STROKE, NJ_ERR_INVALID_RESULT); } len = get_stem_yomi_string(loc->handle, data, stroke, yomi_pos, stem_set.yomi_size, size); if (size < (NJ_UINT16)((len+NJ_TERM_LEN)*sizeof(NJ_CHAR))) { return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_GET_STROKE, NJ_ERR_BUFFER_NOT_ENOUGH); } *(stroke + len) = NJ_CHAR_NUL; return len; } static NJ_INT16 search_node2(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT16 hidx) { NJ_UINT8 *root, *now, *node, *node_mid; NJ_CHAR *yomi; NJ_INT16 ytbl_cnt; NJ_UINT16 y; NJ_UINT8 *ytbl_top; NJ_UINT16 bit_left, bit_data; NJ_UINT32 data_offset; NJ_UINT16 j; NJ_UINT8 *data_top, *stem_data; NJ_UINT16 hindo, hindo_max, hindo_tmp; NJ_UINT32 current, hindo_max_data, hindo_tmp_data; NJ_SEARCH_CACHE *psrhCache = condition->ds->dic[hidx].srhCache; NJ_CHAR *key; NJ_UINT8 cmpflg; NJ_UINT8 endflg; NJ_UINT16 abPtrIdx; NJ_UINT16 key_len; NJ_UINT16 i, l, m; NJ_UINT16 abIdx; NJ_UINT16 abIdx_current; NJ_UINT16 abIdx_old; NJ_UINT16 addcnt = 0; NJ_CHAR char_tmp[NJ_MAX_LEN + NJ_TERM_LEN]; NJ_UINT16 tmp_len; NJ_UINT16 endIdx; NJ_INT16 ret; NJ_UINT8 *con_node; NJ_UINT16 yomi_clen; NJ_UINT8 aimai_flg = 0x01; NJ_CHAR key_tmp[NJ_MAX_CHAR_LEN + NJ_TERM_LEN]; NJ_CACHE_INFO tmpbuff; if (NJ_GET_CACHEOVER_FROM_SCACHE(psrhCache)) { aimai_flg = 0x00; } node = NULL; yomi = condition->yomi; root = NODE_AREA_TOP_ADDR(loctset->loct.handle); node_mid = root + NODE_AREA_MID_ADDR(loctset->loct.handle); now = node_mid; bit_left = BIT_NODE_AREA_LEFT_LEN(loctset->loct.handle); bit_data = BIT_NODE_AREA_DATA_LEN(loctset->loct.handle); ytbl_cnt = YOMI_INDX_CNT(loctset->loct.handle); y = YOMI_INDX_SIZE(loctset->loct.handle); ytbl_top = YOMI_INDX_TOP_ADDR(loctset->loct.handle); data_top = STEM_AREA_TOP_ADDR(loctset->loct.handle); endflg = 0x00; cmpflg = 0x00; abPtrIdx = 0; key = condition->ds->keyword; yomi_clen = condition->yclen; for (i = 0; i < yomi_clen; i++) { abPtrIdx = i; if (!cmpflg) { if (((abPtrIdx != 0) && (psrhCache->keyPtr[abPtrIdx] == 0)) || (psrhCache->keyPtr[abPtrIdx + 1] == 0)) { cmpflg = 0x01; } else { } } addcnt = 0; if (cmpflg) { if (abPtrIdx == 0) { abIdx = 0; nj_charncpy(key_tmp, yomi, 1); key_len = nj_strlen(key_tmp); node = NULL; now = node_mid; psrhCache->keyPtr[0] = 0; ret = search_yomi_node(condition->operation, node, now, 0, key_tmp, key_len, root, node_mid, bit_left, bit_data, data_top, ytbl_cnt, y, ytbl_top, &tmpbuff, &con_node, &data_offset); if (ret < 0) { } else { psrhCache->storebuff[abIdx] = tmpbuff; now = con_node; psrhCache->storebuff[abIdx].top = data_offset; if (condition->operation == NJ_CUR_OP_FORE) { ret = get_node_bottom(key_tmp, now, node_mid, data_top, bit_left, bit_data, psrhCache->storebuff[abIdx].top, loctset->loct.handle, &(psrhCache->storebuff[abIdx].bottom)); if (ret < 0) { return ret; } } addcnt++; abIdx++; } if ((condition->charset != NULL) && aimai_flg) { for (l = 0; l < condition->charset->charset_count; l++) { if (nj_charncmp(key, condition->charset->from[l], 1) == 0) { nj_strcpy(char_tmp, condition->charset->to[l]); tmp_len = nj_strlen(char_tmp); node = NULL; now = node_mid; ret = search_yomi_node(condition->operation, node, now, 0, char_tmp, tmp_len, root, node_mid, bit_left, bit_data, data_top, ytbl_cnt, y, ytbl_top, &tmpbuff, &con_node, &data_offset); if (ret < 0) { } else { if (abIdx >= NJ_SEARCH_CACHE_SIZE) { psrhCache->keyPtr[abPtrIdx+1] = 0; return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_NOT_ENOUGH); } psrhCache->storebuff[abIdx] = tmpbuff; now = con_node; psrhCache->storebuff[abIdx].top = data_offset; if (condition->operation == NJ_CUR_OP_FORE) { ret = get_node_bottom(key_tmp, now, node_mid, data_top, bit_left, bit_data, psrhCache->storebuff[abIdx].top, loctset->loct.handle, &(psrhCache->storebuff[abIdx].bottom)); if (ret < 0) { return ret; } } addcnt++; abIdx++; } } } } psrhCache->keyPtr[abPtrIdx + 1] = abIdx; } else { nj_charncpy(key_tmp, yomi, 1); key_len = nj_strlen(key_tmp); if (psrhCache->keyPtr[abPtrIdx] == psrhCache->keyPtr[abPtrIdx - 1]) { psrhCache->keyPtr[abPtrIdx+1] = psrhCache->keyPtr[abPtrIdx-1]; endflg = 0x01; } else { endIdx = psrhCache->keyPtr[abPtrIdx]; abIdx_old = psrhCache->keyPtr[abPtrIdx - 1]; if (NJ_GET_CACHEOVER_FROM_SCACHE(psrhCache)) { abIdx = psrhCache->keyPtr[abPtrIdx - 1]; psrhCache->keyPtr[abPtrIdx] = abIdx; } else { abIdx = psrhCache->keyPtr[abPtrIdx]; } if ((abIdx > NJ_SEARCH_CACHE_SIZE) || (abIdx_old >= NJ_SEARCH_CACHE_SIZE) || (endIdx > NJ_SEARCH_CACHE_SIZE)) { return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_BROKEN); } for (m = abIdx_old; m < endIdx; m++) { node = psrhCache->storebuff[m].node; now = psrhCache->storebuff[m].now; if ((node == now) && (psrhCache->storebuff[m].idx_no == 0)) { continue; } ret = search_yomi_node(condition->operation, node, now, psrhCache->storebuff[m].idx_no, key_tmp, key_len, root, node_mid, bit_left, bit_data, data_top, ytbl_cnt, y, ytbl_top, &tmpbuff, &con_node, &data_offset); if (ret < 0) { } else { if (abIdx >= NJ_SEARCH_CACHE_SIZE) { psrhCache->keyPtr[abPtrIdx+1] = 0; return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_NOT_ENOUGH); } psrhCache->storebuff[abIdx] = tmpbuff; now = con_node; psrhCache->storebuff[abIdx].top = data_offset; if (condition->operation == NJ_CUR_OP_FORE) { ret = get_node_bottom(key_tmp, now, node_mid, data_top, bit_left, bit_data, psrhCache->storebuff[abIdx].top, loctset->loct.handle, &(psrhCache->storebuff[abIdx].bottom)); if (ret < 0) { return ret; } } addcnt++; abIdx++; } if ((condition->charset != NULL) && aimai_flg) { for (l = 0; l < condition->charset->charset_count; l++) { if (nj_charncmp(key, condition->charset->from[l], 1) == 0) { nj_strcpy(char_tmp, condition->charset->to[l]); tmp_len = nj_strlen(char_tmp); node = psrhCache->storebuff[m].node; now = psrhCache->storebuff[m].now; ret = search_yomi_node(condition->operation, node, now, psrhCache->storebuff[m].idx_no, char_tmp, tmp_len, root, node_mid, bit_left, bit_data, data_top, ytbl_cnt, y, ytbl_top, &tmpbuff, &con_node, &data_offset); if (ret < 0) { } else { if (abIdx >= NJ_SEARCH_CACHE_SIZE) { psrhCache->keyPtr[abPtrIdx+1] = 0; return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_NOT_ENOUGH); } psrhCache->storebuff[abIdx] = tmpbuff; now = con_node; psrhCache->storebuff[abIdx].top = data_offset; if (condition->operation == NJ_CUR_OP_FORE) { ret = get_node_bottom(key_tmp, now, node_mid, data_top, bit_left, bit_data, psrhCache->storebuff[abIdx].top, loctset->loct.handle, &(psrhCache->storebuff[abIdx].bottom)); if (ret < 0) { return ret; } } addcnt++; abIdx++; } } } } } psrhCache->keyPtr[abPtrIdx + 1] = abIdx; } } } yomi += UTL_CHAR(yomi); key += UTL_CHAR(key); } if ((addcnt == 0) && (psrhCache->keyPtr[yomi_clen - 1] == psrhCache->keyPtr[yomi_clen])) { endflg = 0x01; } if (endflg) { loctset->loct.status = NJ_ST_SEARCH_END; return 0; } loctset->loct.current = 0; abPtrIdx = condition->yclen; abIdx = psrhCache->keyPtr[abPtrIdx]; abIdx_old = psrhCache->keyPtr[abPtrIdx - 1]; if ((abIdx > NJ_SEARCH_CACHE_SIZE) || (abIdx_old >= NJ_SEARCH_CACHE_SIZE)) { return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_BROKEN); } if (condition->mode == NJ_CUR_MODE_FREQ) { hindo_max = 0; hindo_max_data = 0; abIdx_current = abIdx_old; stem_data = data_top + psrhCache->storebuff[abIdx_current].top; hindo = (NJ_UINT16) *((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle) + get_stem_hindo(loctset->loct.handle, stem_data))); hindo_tmp = 0; hindo_tmp_data = 0; current = 0; while (stem_data <= (data_top + psrhCache->storebuff[abIdx_current].bottom)) { if (hindo > hindo_tmp) { hindo_tmp = hindo; hindo_tmp_data = current; } j = get_stem_next(loctset->loct.handle, stem_data); current += j; stem_data += j; hindo = (NJ_UINT16) *((NJ_UINT8 *) (HINDO_NO_TOP_ADDR(loctset->loct.handle) + get_stem_hindo(loctset->loct.handle, stem_data))); } psrhCache->storebuff[abIdx_current].current = hindo_tmp_data; if (hindo_tmp > hindo_max) { hindo_max = hindo_tmp; hindo_max_data = hindo_tmp_data; } } else { abIdx_current = abIdx_old; stem_data = data_top + psrhCache->storebuff[abIdx_current].top; hindo = (NJ_UINT16) *((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle) + get_stem_hindo(loctset->loct.handle, stem_data))); hindo_max = hindo; hindo_max_data = 0; } loctset->loct.top = psrhCache->storebuff[abIdx_current].top; loctset->loct.bottom = psrhCache->storebuff[abIdx_current].bottom; loctset->cache_freq = CALCULATE_HINDO(hindo_max, loctset->dic_freq.base, loctset->dic_freq.high, COMP_DIC_FREQ_DIV); loctset->loct.current = hindo_max_data; loctset->loct.current_cache = (NJ_UINT8)abIdx_current; psrhCache->viewCnt = 1; NJ_SET_AIMAI_TO_SCACHE(psrhCache); return 1; } static NJ_INT16 search_yomi_node(NJ_UINT8 operation, NJ_UINT8 *node, NJ_UINT8 *now, NJ_UINT16 idx_no, NJ_CHAR *yomi, NJ_UINT16 yomilen, NJ_UINT8 * root, NJ_UINT8 * node_mid, NJ_UINT16 bit_left, NJ_UINT16 bit_data, NJ_UINT8 * data_top, NJ_INT16 ytbl_cnt, NJ_UINT16 y, NJ_UINT8 * ytbl_top, NJ_CACHE_INFO * storebuf, NJ_UINT8 ** con_node, NJ_UINT32 * data_offset) { NJ_UINT8 index; NJ_UINT8 *wkc; NJ_UINT8 *byomi; NJ_INT16 idx; NJ_INT16 char_size; NJ_INT16 left, right, mid; NJ_UINT16 c, d; NJ_UINT8 c1 = 0, c2 = 0; NJ_UINT16 ysize = yomilen * sizeof(NJ_CHAR); NJ_UINT16 idx_cnt; NJ_UINT16 nd_index; NJ_UINT16 data; NJ_UINT16 pos, j, bit_all, bit_tmp, bit_idx; NJ_UINT32 data_l; NJ_UINT8 restart_flg = 0; *con_node = NULL; idx_cnt = 1; storebuf->idx_no = 0; byomi = (NJ_UINT8*)yomi; while (ysize > 0) { if (ytbl_cnt != 0) { char_size = UTL_CHAR(byomi) * sizeof(NJ_CHAR); if (char_size > 2) { return -1; } if (char_size == 2) { if (y == 1) { return -1; } c1 = *byomi; c2 = *(byomi + 1); c = (NJ_UINT16)((c1 << 8) | c2); } else { c1 = *byomi; c2 = 0x00; c = (NJ_UINT16)(*byomi); } idx = -1; left = 0; right = ytbl_cnt; if (y == 2) { while (left <= right) { mid = (left + right) >> 1; wkc = ytbl_top + (mid << 1); if (c1 == *wkc) { if (c2 == *(wkc + 1)) { idx = (NJ_UINT16) (mid + 1); break; } if (c2 < *(wkc + 1)) { right = mid - 1; } else { left = mid + 1; } } else if (c1 < *wkc) { right = mid - 1; } else { left = mid + 1; } } } else { while (left <= right) { mid = (left + right) >> 1; wkc = ytbl_top + (mid * y); d = (NJ_UINT16) (*wkc); if (c == d) { idx = (NJ_UINT16) (mid + 1); break; } if (c < d) { right = mid - 1; } else { left = mid + 1; } } } if (idx < 0) { return -1; } index = (NJ_UINT8) idx; } else { index = *byomi; char_size = 1; } byomi += char_size; ysize -= char_size; while (now < data_top) { if (NODE_IDX_EXIST(now)) { bit_idx = 8; idx_cnt = NODE_IDX_CNT(now); } else { bit_idx = 4; idx_cnt = 1; } bit_all = bit_idx; if (NODE_LEFT_EXIST(now)) { bit_all += bit_left; } if (NODE_DATA_EXIST(now)) { bit_all += bit_data; } bit_tmp = bit_all; bit_all += (NJ_UINT16) (idx_no << 3); pos = (NJ_UINT16) (bit_all >> 3); data = (NJ_UINT16) (NJ_INT16_READ(now + pos)); j = (NJ_UINT16) (bit_all & 0x0007); nd_index = GET_BITFIELD_16(data, j, INDEX_BIT); if (index == (NJ_UINT8) nd_index) { break; } else { if ((!NODE_TERM(now)) && (index > (NJ_UINT8) nd_index) && (idx_no == 0)) { now += GET_BIT_TO_BYTE(bit_tmp + (idx_cnt * 8)); if (now == node_mid) { return -1; } continue; } else { if ((now == node_mid) && (restart_flg == 0) && (index < (NJ_UINT8) nd_index) && (idx_no == 0) && (root != node_mid)) { now = root; idx_no = 0; restart_flg = 1; continue; } return -1; } } } if ( (idx_cnt > (NJ_UINT16) (idx_no + 1))) { if (ysize == 0) { if (operation == NJ_CUR_OP_FORE) { storebuf->node = now; storebuf->now = now; storebuf->idx_no = idx_no + 1; node = now; break; } return -2; } idx_no++; continue; } node = now; storebuf->node = now; idx_no = 0; if (ysize == 0) { *con_node = now; } else { if (!(NODE_LEFT_EXIST(now))) { return -1; } } if (NODE_LEFT_EXIST(now)) { if (NODE_IDX_EXIST(now)) { bit_idx = 8; } else { bit_idx = 4; } pos = (NJ_UINT16) (bit_idx >> 3); data_l = (NJ_UINT32) (NJ_INT32_READ(now + pos)); j = (NJ_UINT16) (bit_idx & 0x0007); now += GET_BITFIELD_32(data_l, j, bit_left); storebuf->now = now; } else { storebuf->now = now; } } if (*con_node == NULL) { *con_node = now; } if ((node == NULL) || !(NODE_DATA_EXIST(node))) { if ((operation == NJ_CUR_OP_FORE) && (node != NULL)) { while (!NODE_DATA_EXIST(node)) { if (!(NODE_LEFT_EXIST(node))) { return -2; } if (NODE_IDX_EXIST(node)) { bit_idx = 8; } else { bit_idx = 4; } pos = (NJ_UINT16) (bit_idx >> 3); data_l = (NJ_UINT32) (NJ_INT32_READ(node + pos)); j = (NJ_UINT16) (bit_idx & 0x0007); node += GET_BITFIELD_32(data_l, j, bit_left); } } else { return -2; } } if (NODE_IDX_EXIST(node)) { bit_idx = 8; } else { bit_idx = 4; } if (NODE_LEFT_EXIST(node)) { bit_all = bit_idx + bit_left; } else { bit_all = bit_idx; } pos = (NJ_UINT16) (bit_all >> 3); data_l = (NJ_UINT32) (NJ_INT32_READ(node + pos)); j = (NJ_UINT16) (bit_all & 0x0007); *data_offset = GET_BITFIELD_32(data_l, j, bit_data); return 1; } static NJ_INT16 get_node_bottom(NJ_CHAR * yomi, NJ_UINT8 * now, NJ_UINT8 * node_mid, NJ_UINT8 * data_top, NJ_UINT16 bit_left, NJ_UINT16 bit_data, NJ_UINT32 top, NJ_DIC_HANDLE handle, NJ_UINT32 * ret_bottom) { NJ_UINT8 *node; NJ_UINT16 idx_cnt; NJ_UINT32 data_offset; NJ_UINT16 pos, j, bit_all; NJ_UINT32 data_l; NJ_UINT8 bottom_flg = 0; NJ_UINT8 *stem_data; NJ_UINT32 bottom, next; bottom = top; if (NJ_CHAR_STRLEN_IS_0(yomi)) { node = node_mid; } else { node = now; if (NODE_LEFT_EXIST(node)) { if (NODE_IDX_EXIST(node)) { bit_all = 8; } else { bit_all = 4; } pos = (NJ_UINT16) (bit_all >> 3); data_l = (NJ_UINT32) (NJ_INT32_READ(node + pos)); j = (NJ_UINT16) (bit_all & 0x0007); node += GET_BITFIELD_32(data_l, j, bit_left); } else { bottom_flg = 1; } } if (!bottom_flg) { while (node < data_top) { if (!NODE_TERM(node)) { if (NODE_IDX_EXIST(node)) { bit_all = 8; idx_cnt = NODE_IDX_CNT(node); } else { bit_all = 4; idx_cnt = 1; } if (NODE_LEFT_EXIST(node)) { bit_all += bit_left; } if (NODE_DATA_EXIST(node)) { bit_all += bit_data; } node += GET_BIT_TO_BYTE(bit_all + (idx_cnt * 8)); } else { if (!NODE_LEFT_EXIST(node)) { if (NODE_DATA_EXIST(node)) { if (NODE_IDX_EXIST(node)) { bit_all = 8; } else { bit_all = 4; } pos = (NJ_UINT16) (bit_all >> 3); data_l = (NJ_UINT32) (NJ_INT32_READ(node + pos)); j = (NJ_UINT16) (bit_all & 0x0007); data_offset = GET_BITFIELD_32(data_l, j, bit_data); bottom = data_offset; break; } else { return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_DIC_BROKEN); } } else { if (NODE_IDX_EXIST(node)) { bit_all = 8; } else { bit_all = 4; } pos = (NJ_UINT16) (bit_all >> 3); data_l = (NJ_UINT32) (NJ_INT32_READ(node + pos)); j = (NJ_UINT16) (bit_all & 0x0007); node += GET_BITFIELD_32(data_l, j, bit_left); } } } } stem_data = data_top + bottom; while (!(STEM_TERMINETER(stem_data))) { next = get_stem_next(handle, stem_data); stem_data += next; } *ret_bottom = (NJ_UINT32) (stem_data - data_top); return 1; } static NJ_INT16 bdic_search_fore_data2(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT16 hidx) { NJ_UINT8 *data, *data_top, *bottom, *data_end; NJ_INT16 i = 0; NJ_INT16 hindo = 0; NJ_UINT32 current = loctset->loct.current; NJ_SEARCH_CACHE *psrhCache = condition->ds->dic[hidx].srhCache; NJ_UINT16 top_abIdx; NJ_UINT16 bottom_abIdx; NJ_UINT16 count_abIdx; NJ_UINT16 current_abIdx; NJ_UINT16 old_abIdx; NJ_UINT8 freq_flag = 0; NJ_INT16 save_hindo = 0; NJ_UINT16 save_abIdx = 0; NJ_UINT16 abPtrIdx; NJ_UINT16 m; NJ_INT16 ret; NJ_INT16 loop_check; NJ_UINT16 abIdx; NJ_UINT16 abIdx_old; NJ_UINT16 hindo_max, hindo_tmp; NJ_UINT32 hindo_max_data, hindo_tmp_data; NJ_UINT16 abIdx_current; if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_NO_INIT) { loctset->loct.status = NJ_ST_SEARCH_READY; loctset->loct.current_info = CURRENT_INFO_SET; return 1; } if (NJ_GET_AIMAI_FROM_SCACHE(psrhCache)) { NJ_UNSET_AIMAI_TO_SCACHE(psrhCache); data_top = STEM_AREA_TOP_ADDR(loctset->loct.handle); if (condition->operation == NJ_CUR_OP_FORE) { if (condition->ylen) { abPtrIdx = condition->yclen; abIdx = psrhCache->keyPtr[abPtrIdx]; abIdx_old = psrhCache->keyPtr[abPtrIdx - 1]; if ((abIdx > NJ_SEARCH_CACHE_SIZE) || (abIdx_old >= NJ_SEARCH_CACHE_SIZE)) { return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_BROKEN); } if (condition->mode == NJ_CUR_MODE_FREQ) { hindo_max = 0; hindo_max_data = 0; abIdx_current = abIdx_old; for (m = abIdx_old; m < abIdx; m++) { data = data_top + psrhCache->storebuff[m].top; hindo = (NJ_UINT16) *((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle) + get_stem_hindo(loctset->loct.handle, data))); hindo_tmp = 0; hindo_tmp_data = 0; current = 0; while (data <= (data_top + psrhCache->storebuff[m].bottom)) { if (hindo > hindo_tmp) { hindo_tmp = hindo; hindo_tmp_data = current; } i = get_stem_next(loctset->loct.handle, data); current += i; data += i; hindo = (NJ_UINT16) *((NJ_UINT8 *) (HINDO_NO_TOP_ADDR(loctset->loct.handle) + get_stem_hindo(loctset->loct.handle, data))); } psrhCache->storebuff[m].current = hindo_tmp_data; if (hindo_tmp > hindo_max) { hindo_max = hindo_tmp; hindo_max_data = hindo_tmp_data; abIdx_current = m; } } } else { abIdx_current = abIdx_old; data = data_top + psrhCache->storebuff[abIdx_current].top; hindo = (NJ_UINT16) *((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle) + get_stem_hindo(loctset->loct.handle, data))); hindo_max = hindo; hindo_max_data = 0; } loctset->loct.top = psrhCache->storebuff[abIdx_current].top; loctset->loct.bottom = psrhCache->storebuff[abIdx_current].bottom; loctset->cache_freq = CALCULATE_HINDO(hindo_max, loctset->dic_freq.base, loctset->dic_freq.high, COMP_DIC_FREQ_DIV); loctset->loct.current = hindo_max_data; loctset->loct.current_cache = (NJ_UINT8)abIdx_current; psrhCache->viewCnt = 1; } else { data = data_top + loctset->loct.top; hindo = (NJ_UINT16) *((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle) + get_stem_hindo(loctset->loct.handle, data))); hindo_max = hindo; hindo_max_data = 0; if (condition->mode == NJ_CUR_MODE_FREQ) { i = get_stem_next(loctset->loct.handle, data); current = i; data += i; while (data <= (data_top + loctset->loct.bottom)) { hindo = (NJ_UINT16)*((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle) + get_stem_hindo(loctset->loct.handle, data))); if (hindo > hindo_max) { hindo_max = hindo; hindo_max_data = current; } i = get_stem_next(loctset->loct.handle, data); current += i; data += i; } } loctset->cache_freq = CALCULATE_HINDO(hindo_max, loctset->dic_freq.base, loctset->dic_freq.high, COMP_DIC_FREQ_DIV); loctset->loct.current = hindo_max_data; } } return 1; } data_top = STEM_AREA_TOP_ADDR(loctset->loct.handle); data = data_top + loctset->loct.top + loctset->loct.current; bottom = data_top + loctset->loct.bottom; if (NJ_GET_DIC_FMT(loctset->loct.handle) == NJ_DIC_FMT_KANAKAN) { data_end = loctset->loct.handle + NJ_DIC_COMMON_HEADER_SIZE + NJ_INT32_READ(loctset->loct.handle + NJ_DIC_POS_DATA_SIZE) + NJ_INT32_READ(loctset->loct.handle + NJ_DIC_POS_EXT_SIZE) - NJ_DIC_ID_LEN; } else { data_end = CAND_IDX_AREA_TOP_ADDR(loctset->loct.handle); } if (condition->mode == NJ_CUR_MODE_FREQ) { abPtrIdx = condition->yclen; bottom_abIdx = psrhCache->keyPtr[abPtrIdx]; top_abIdx = psrhCache->keyPtr[abPtrIdx - 1]; if ((bottom_abIdx > NJ_SEARCH_CACHE_SIZE) || (top_abIdx >= NJ_SEARCH_CACHE_SIZE)) { return NJ_SET_ERR_VAL(NJ_FUNC_NJD_B_SEARCH_WORD, NJ_ERR_CACHE_BROKEN); } count_abIdx = bottom_abIdx - top_abIdx; if (!count_abIdx) { loctset->loct.status = NJ_ST_SEARCH_END; return 0; } old_abIdx = loctset->loct.current_cache; loop_check = 0; ret = bdic_get_next_data(data_top, data_end, loctset, psrhCache, old_abIdx); if (ret == loctset->cache_freq) { psrhCache->viewCnt++; if (psrhCache->viewCnt <= NJ_CACHE_VIEW_CNT) { loctset->loct.status = NJ_ST_SEARCH_READY; loctset->loct.current_info = CURRENT_INFO_SET; loctset->loct.current = psrhCache->storebuff[old_abIdx].current; loctset->loct.current_cache = (NJ_UINT8)old_abIdx; return 1; } else { freq_flag = 1; psrhCache->viewCnt = 0; } } else { if (ret == -1) { loop_check++; } save_hindo = ret; save_abIdx = old_abIdx; } current_abIdx = old_abIdx + 1; if (current_abIdx >= bottom_abIdx) { current_abIdx = top_abIdx; } while (loop_check != count_abIdx) { ret = bdic_get_word_freq(data_top, loctset, psrhCache, current_abIdx); if ((ret == loctset->cache_freq) && (loctset->loct.top == psrhCache->storebuff[current_abIdx].top) && (loctset->loct.current == psrhCache->storebuff[current_abIdx].current)) { ret = bdic_get_next_data(data_top, data_end, loctset, psrhCache, current_abIdx); } if (ret == loctset->cache_freq) { loctset->loct.status = NJ_ST_SEARCH_READY; loctset->loct.current_info = CURRENT_INFO_SET; loctset->loct.top = psrhCache->storebuff[current_abIdx].top; loctset->loct.bottom = psrhCache->storebuff[current_abIdx].bottom; loctset->loct.current = psrhCache->storebuff[current_abIdx].current; loctset->loct.current_cache = (NJ_UINT8)current_abIdx; psrhCache->viewCnt = 1; return 1; } else { if (ret == -1) { loop_check++; } if (save_hindo < ret) { save_hindo = ret; save_abIdx = current_abIdx; } } current_abIdx++; if (current_abIdx >= bottom_abIdx) { current_abIdx = top_abIdx; } if (current_abIdx == old_abIdx) { if (freq_flag == 1) { loctset->loct.status = NJ_ST_SEARCH_READY; loctset->loct.current_info = CURRENT_INFO_SET; loctset->loct.top = psrhCache->storebuff[current_abIdx].top; loctset->loct.bottom = psrhCache->storebuff[current_abIdx].bottom; loctset->loct.current = psrhCache->storebuff[current_abIdx].current; loctset->loct.current_cache = (NJ_UINT8)current_abIdx; psrhCache->viewCnt = 1; return 1; } else if (save_hindo != -1) { loctset->cache_freq = save_hindo; loctset->loct.status = NJ_ST_SEARCH_READY; loctset->loct.current_info = CURRENT_INFO_SET; loctset->loct.top = psrhCache->storebuff[save_abIdx].top; loctset->loct.bottom = psrhCache->storebuff[save_abIdx].bottom; loctset->loct.current = psrhCache->storebuff[save_abIdx].current; loctset->loct.current_cache = (NJ_UINT8)save_abIdx; psrhCache->viewCnt = 1; return 1; } } } } else { i = get_stem_next(loctset->loct.handle, data); data += i; current += i; if (data > bottom) { loctset->loct.status = NJ_ST_SEARCH_END; return 0; } hindo = (NJ_INT16)*((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle) + get_stem_hindo(loctset->loct.handle, data))); loctset->cache_freq = CALCULATE_HINDO(hindo, loctset->dic_freq.base, loctset->dic_freq.high, COMP_DIC_FREQ_DIV); loctset->loct.status = NJ_ST_SEARCH_READY; loctset->loct.current_info = CURRENT_INFO_SET; loctset->loct.current = current; return 1; } loctset->loct.status = NJ_ST_SEARCH_END; return 0; } static NJ_INT16 bdic_get_next_data(NJ_UINT8 *data_top, NJ_UINT8 *data_end, NJ_SEARCH_LOCATION_SET *loctset, NJ_SEARCH_CACHE *psrhCache, NJ_UINT16 abIdx) { NJ_UINT8 *data, *bottom; NJ_INT16 i = 0; NJ_INT16 hindo = 0; NJ_INT16 hindo_max = -1; NJ_UINT8 no_hit = 0; NJ_UINT32 current = psrhCache->storebuff[abIdx].current; NJ_UINT8 *current_org; NJ_UINT32 hindo_data = 0; NJ_INT16 freq_org = loctset->cache_freq; if (psrhCache->storebuff[abIdx].current == LOC_CURRENT_NO_ENTRY) { return (-1); } data = data_top + psrhCache->storebuff[abIdx].top + psrhCache->storebuff[abIdx].current; current_org = data; bottom = data_top + psrhCache->storebuff[abIdx].bottom; while (data < data_end) { i = get_stem_next(loctset->loct.handle, data); data += i; current += i; if (data > bottom) { if ((freq_org == 0) || (no_hit == 1)) { psrhCache->storebuff[abIdx].current = LOC_CURRENT_NO_ENTRY; return -1; } freq_org -= 1; data = data_top + psrhCache->storebuff[abIdx].top; current = 0; no_hit = 1; } if ((hindo_max != -1) && (data == current_org)) { psrhCache->storebuff[abIdx].current = hindo_data; return hindo_max; } hindo = (NJ_INT16)*((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle) + get_stem_hindo(loctset->loct.handle, data))); hindo = CALCULATE_HINDO(hindo, loctset->dic_freq.base, loctset->dic_freq.high, COMP_DIC_FREQ_DIV); if (hindo == freq_org) { psrhCache->storebuff[abIdx].current = current; return hindo; } if (hindo < freq_org) { if ((hindo > hindo_max) || ((hindo == hindo_max) && (current < hindo_data))) { hindo_max = hindo; hindo_data = current; } } } psrhCache->storebuff[abIdx].current = LOC_CURRENT_NO_ENTRY; return -1; } static NJ_INT16 bdic_get_word_freq(NJ_UINT8 * data_top, NJ_SEARCH_LOCATION_SET * loctset, NJ_SEARCH_CACHE * psrhCache, NJ_UINT16 abIdx) { NJ_UINT8 *data; NJ_INT16 hindo = 0; if (psrhCache->storebuff[abIdx].current != LOC_CURRENT_NO_ENTRY) { data = data_top + psrhCache->storebuff[abIdx].top + psrhCache->storebuff[abIdx].current; hindo = (NJ_INT16)*((NJ_UINT8 *)(HINDO_NO_TOP_ADDR(loctset->loct.handle) + get_stem_hindo(loctset->loct.handle, data))); hindo = CALCULATE_HINDO(hindo, loctset->dic_freq.base, loctset->dic_freq.high, COMP_DIC_FREQ_DIV); } else { hindo = -1; } return hindo; }