| /* |
| * Copyright (C) 2008,2009 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" |
| #ifdef NJ_LEARN_MUHENKAN_DEBUG |
| #include <stdio.h> |
| #include <def_mojicode.h> |
| #endif |
| #ifdef NJ_AWNN22_DEBUG |
| #include <stdio.h> |
| #include <def_mojicode.h> |
| #endif |
| |
| #define QUE_TYPE_EMPTY 0 |
| #define QUE_TYPE_NEXT 0 |
| #define QUE_TYPE_JIRI 1 |
| #define QUE_TYPE_FZK 2 |
| #define POS_DATA_OFFSET 0x20 |
| #define POS_LEARN_WORD 0x24 |
| #define POS_MAX_WORD 0x28 |
| #define POS_QUE_SIZE 0x2C |
| #define POS_NEXT_QUE 0x30 |
| #define POS_WRITE_FLG 0x34 |
| #define POS_INDEX_OFFSET 0x3C |
| #define POS_INDEX_OFFSET2 0x40 |
| |
| #define LEARN_INDEX_TOP_ADDR(x) ((x) + (NJ_INT32_READ((x) + POS_INDEX_OFFSET))) |
| #define LEARN_INDEX_TOP_ADDR2(x) ((x) + (NJ_INT32_READ((x) + POS_INDEX_OFFSET2))) |
| #define LEARN_DATA_TOP_ADDR(x) ((x) + (NJ_INT32_READ((x) + POS_DATA_OFFSET))) |
| |
| #define LEARN_INDEX_BOTTOM_ADDR(x) (LEARN_DATA_TOP_ADDR(x) - 1) |
| |
| #define LEARN_QUE_STRING_OFFSET 5 |
| |
| #define ADDRESS_TO_POS(x,adr) (((adr) - LEARN_DATA_TOP_ADDR(x)) / QUE_SIZE(x)) |
| #define POS_TO_ADDRESS(x,pos) (LEARN_DATA_TOP_ADDR(x) + QUE_SIZE(x) * (pos)) |
| |
| #define GET_UINT16(ptr) ((((NJ_UINT16)(*(ptr))) << 8) | (*((ptr) + 1) & 0x00ff)) |
| |
| #define GET_FPOS_FROM_DATA(x) ((NJ_UINT16)NJ_INT16_READ((x)+1) >> 7) |
| #define GET_YSIZE_FROM_DATA(x) ((NJ_UINT8)((NJ_UINT16)NJ_INT16_READ((x)+1) & 0x7F)) |
| #define GET_BPOS_FROM_DATA(x) ((NJ_UINT16)NJ_INT16_READ((x)+3) >> 7) |
| #define GET_KSIZE_FROM_DATA(x) ((NJ_UINT8)((NJ_UINT16)NJ_INT16_READ((x)+3) & 0x7F)) |
| #define GET_BPOS_FROM_EXT_DATA(x) ((NJ_UINT16)NJ_INT16_READ(x) >> 7) |
| #define GET_YSIZE_FROM_EXT_DATA(x) ((NJ_UINT8)((NJ_UINT16)NJ_INT16_READ(x) & 0x7F)) |
| |
| #define SET_BPOS_AND_YSIZE(x,bpos,ysize) \ |
| NJ_INT16_WRITE((x), ((NJ_UINT16)((bpos) << 7) | ((ysize) & 0x7F))) |
| #define SET_FPOS_AND_YSIZE(x,fpos,ysize) \ |
| NJ_INT16_WRITE(((x)+1), ((NJ_UINT16)((fpos) << 7) | ((ysize) & 0x7F))) |
| #define SET_BPOS_AND_KSIZE(x,bpos,ksize) \ |
| NJ_INT16_WRITE(((x)+3), ((NJ_UINT16)((bpos) << 7) | ((ksize) & 0x7F))) |
| |
| #define GET_TYPE_FROM_DATA(x) (*(x) & 0x03) |
| #define GET_UFLG_FROM_DATA(x) (*(x) >> 7) |
| #define GET_FFLG_FROM_DATA(x) ((*(x) >> 6) & 0x01) |
| #define GET_MFLG_FROM_DATA(x) (*(x) & 0x10) |
| |
| #define SET_TYPE_UFLG_FFLG(x,type,u,f) \ |
| (*(x) = (NJ_UINT8)(((type) & 0x03) | \ |
| (((u) & 0x01) << 7) | (((f) & 0x01) << 6))) |
| #define SET_TYPE_ALLFLG(x,type,u,f,m) \ |
| (*(x) = (NJ_UINT8)(((type) & 0x03) | \ |
| (((u) & 0x01) << 7) | (((f) & 0x01) << 6) | (((m) & 0x01) << 4))) |
| |
| #define RESET_FFLG(x) (*(x) &= 0xbf) |
| |
| #define STATE_COPY(to, from) \ |
| { ((NJ_UINT8*)(to))[0] = ((NJ_UINT8*)(from))[0]; \ |
| ((NJ_UINT8*)(to))[1] = ((NJ_UINT8*)(from))[1]; \ |
| ((NJ_UINT8*)(to))[2] = ((NJ_UINT8*)(from))[2]; \ |
| ((NJ_UINT8*)(to))[3] = ((NJ_UINT8*)(from))[3]; } |
| |
| #define USE_QUE_NUM(que_size, str_size) \ |
| ( (((str_size) % ((que_size) - 1)) == 0) \ |
| ? ((str_size) / ((que_size) - 1)) \ |
| : ((str_size) / ((que_size) - 1) + 1) ) |
| |
| #define NEXT_QUE(que, max) ( ((que) < ((max) - 1)) ? ((que) + 1) : 0 ) |
| |
| #define PREV_QUE(que, max) ( ((que) == 0) ? ((max) - 1) : ((que) - 1) ) |
| |
| #define COPY_QUE(handle, src, dst) \ |
| nj_memcpy(POS_TO_ADDRESS((handle), (dst)), POS_TO_ADDRESS((handle), (src)), QUE_SIZE(handle)) |
| |
| |
| #define INIT_HINDO (-10000) |
| |
| #define LOC_CURRENT_NO_ENTRY 0xffffffffU |
| |
| |
| |
| static NJ_WQUE *get_que(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id); |
| static NJ_INT16 is_continued(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id); |
| static NJ_UINT16 search_next_que(NJ_DIC_HANDLE handle, NJ_UINT16 que_id); |
| static NJ_INT16 que_strcmp_complete_with_hyouki(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id, NJ_CHAR *yomi, NJ_UINT16 yomi_len, NJ_CHAR *hyouki, NJ_UINT8 multi_flg); |
| static NJ_CHAR *get_string(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id, NJ_UINT8 *slen); |
| static NJ_CHAR *get_hyouki(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id, NJ_UINT8 *slen); |
| static NJ_INT16 get_cand_by_sequential(NJ_CLASS *iwnn, NJ_SEARCH_CONDITION *cond, NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT8 search_pattern, NJ_UINT8 comp_flg); |
| static NJ_INT16 get_cand_by_evaluate(NJ_CLASS *iwnn, NJ_SEARCH_CONDITION *cond, NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT8 search_pattern); |
| static NJ_INT16 get_cand_by_evaluate2(NJ_CLASS *iwnn, NJ_SEARCH_CONDITION *cond, NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT8 search_pattern, NJ_UINT16 hIdx); |
| static NJ_INT16 search_range_by_yomi(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT8 op, NJ_CHAR *yomi, NJ_UINT16 ylen, NJ_UINT16 *from, NJ_UINT16 *to, NJ_UINT8 *forward_flag); |
| static NJ_INT16 search_range_by_yomi2(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT8 op, NJ_CHAR *yomi, NJ_UINT16 ylen, NJ_UINT16 sfrom, NJ_UINT16 sto, NJ_UINT16 *from, NJ_UINT16 *to, |
| NJ_UINT8 *forward_flag); |
| static NJ_INT16 search_range_by_yomi_multi(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_CHAR *yomi, NJ_UINT16 ylen, NJ_UINT16 *from, NJ_UINT16 *to); |
| static NJ_INT16 str_que_cmp(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_CHAR *yomi, NJ_UINT16 yomiLen, NJ_UINT16 que_id, NJ_UINT8 mode); |
| static NJ_WQUE *get_que_type_and_next(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id); |
| static NJ_WQUE *get_que_allHinsi(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id); |
| static NJ_WQUE *get_que_yomiLen_and_hyoukiLen(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id); |
| static NJ_INT16 continue_cnt(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id); |
| |
| static NJ_UINT8 *get_search_index_address(NJ_DIC_HANDLE handle, NJ_UINT8 search_pattern); |
| |
| static NJ_HINDO get_hindo(NJ_CLASS *iwnn, NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT8 search_pattern); |
| |
| static NJ_HINDO calculate_hindo(NJ_DIC_HANDLE handle, NJ_INT32 freq, NJ_DIC_FREQ *dic_freq, NJ_INT16 freq_max, NJ_INT16 freq_min); |
| static NJ_INT16 que_strcmp_include(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id, NJ_CHAR *yomi); |
| |
| #define GET_LEARN_MAX_WORD_COUNT(h) ((NJ_UINT16)NJ_INT32_READ((h) + POS_MAX_WORD)) |
| |
| #define GET_LEARN_WORD_COUNT(h) \ |
| ((NJ_UINT16)NJ_INT32_READ((h) + POS_LEARN_WORD)) |
| #define SET_LEARN_WORD_COUNT(h, n) \ |
| NJ_INT32_WRITE((h)+POS_LEARN_WORD, (NJ_UINT32)(n)) |
| #define GET_LEARN_NEXT_WORD_POS(h) \ |
| ((NJ_UINT16)NJ_INT32_READ((h) + POS_NEXT_QUE)) |
| #define SET_LEARN_NEXT_WORD_POS(h, id) \ |
| NJ_INT32_WRITE((h)+POS_NEXT_QUE, (NJ_UINT32)(id)) |
| #define QUE_SIZE(h) ((NJ_UINT16)NJ_INT32_READ((h) + POS_QUE_SIZE)) |
| |
| #define COPY_UINT16(dst,src) (*(NJ_UINT16 *)(dst) = *(NJ_UINT16 *)(src)) |
| |
| static NJ_UINT8 *get_search_index_address(NJ_DIC_HANDLE handle, NJ_UINT8 search_pattern) { |
| |
| |
| |
| return LEARN_INDEX_TOP_ADDR(handle); |
| } |
| |
| NJ_INT16 njd_l_search_word(NJ_CLASS *iwnn, NJ_SEARCH_CONDITION *con, |
| NJ_SEARCH_LOCATION_SET *loctset, |
| NJ_UINT8 comp_flg) { |
| |
| NJ_UINT16 word_count; |
| NJ_UINT32 type; |
| NJ_DIC_INFO *pdicinfo; |
| NJ_UINT16 hIdx; |
| NJ_INT16 ret; |
| |
| |
| word_count = GET_LEARN_WORD_COUNT(loctset->loct.handle); |
| if (word_count == 0) { |
| |
| loctset->loct.status = NJ_ST_SEARCH_END_EXT; |
| return 0; |
| } |
| |
| type = NJ_GET_DIC_TYPE_EX(loctset->loct.type, loctset->loct.handle); |
| |
| if (type == NJ_DIC_TYPE_CUSTOM_INCOMPRESS) { |
| if ((con->operation == NJ_CUR_OP_COMP) || |
| (con->operation == NJ_CUR_OP_FORE)){ |
| |
| if (con->ylen > NJ_GET_MAX_YLEN(loctset->loct.handle)) { |
| loctset->loct.status = NJ_ST_SEARCH_END_EXT; |
| return 0; |
| } |
| } |
| } |
| |
| |
| switch (con->operation) { |
| case NJ_CUR_OP_COMP: |
| if (con->mode != NJ_CUR_MODE_FREQ) { |
| |
| loctset->loct.status = NJ_ST_SEARCH_END_EXT; |
| break; |
| } |
| |
| |
| return get_cand_by_sequential(iwnn, con, loctset, con->operation, comp_flg); |
| |
| case NJ_CUR_OP_FORE: |
| |
| if (con->mode == NJ_CUR_MODE_YOMI) { |
| |
| return get_cand_by_sequential(iwnn, con, loctset, con->operation, 0); |
| } else { |
| |
| |
| 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)) { |
| return get_cand_by_evaluate(iwnn, con, loctset, con->operation); |
| } else { |
| ret = get_cand_by_evaluate2(iwnn, con, loctset, con->operation, hIdx); |
| if (ret == NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_CACHE_NOT_ENOUGH)) { |
| |
| NJ_SET_CACHEOVER_TO_SCACHE(con->ds->dic[hIdx].srhCache); |
| ret = get_cand_by_evaluate2(iwnn, con, loctset, con->operation, hIdx); |
| } |
| return ret; |
| } |
| } |
| |
| case NJ_CUR_OP_LINK: |
| |
| if (NJ_GET_DIC_TYPE_EX(loctset->loct.type, loctset->loct.handle) == NJ_DIC_TYPE_USER) { |
| |
| loctset->loct.status = NJ_ST_SEARCH_END_EXT; |
| break; |
| } |
| if (con->mode != NJ_CUR_MODE_FREQ) { |
| |
| loctset->loct.status = NJ_ST_SEARCH_END_EXT; |
| break; |
| } |
| |
| if (comp_flg == 0) { |
| |
| return get_cand_by_sequential(iwnn, con, loctset, con->operation, 0); |
| } else { |
| |
| return get_cand_by_evaluate(iwnn, con, loctset, con->operation); |
| } |
| |
| default: |
| loctset->loct.status = NJ_ST_SEARCH_END_EXT; |
| } |
| |
| return 0; |
| } |
| |
| static NJ_WQUE *get_que_type_and_next(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, |
| NJ_UINT16 que_id) { |
| NJ_UINT8 *ptr; |
| NJ_WQUE *que = &(iwnn->que_tmp); |
| |
| |
| if (que_id >= GET_LEARN_MAX_WORD_COUNT(handle)) { |
| return NULL; |
| } |
| |
| ptr = POS_TO_ADDRESS(handle, que_id); |
| |
| que->type = GET_TYPE_FROM_DATA(ptr); |
| que->next_flag = GET_FFLG_FROM_DATA(ptr); |
| |
| switch (que->type) { |
| case QUE_TYPE_EMPTY: |
| case QUE_TYPE_JIRI: |
| case QUE_TYPE_FZK: |
| return que; |
| default: |
| break; |
| } |
| #ifdef LEARN_DEBUG |
| printf("FATAL : Illegal que was gotten (que_id=%d)\n", que_id); |
| #endif |
| return NULL; |
| } |
| |
| static NJ_WQUE *get_que_yomiLen_and_hyoukiLen(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, |
| NJ_UINT16 que_id) { |
| NJ_UINT8 *ptr; |
| NJ_WQUE *que = &(iwnn->que_tmp); |
| |
| |
| if (que_id >= GET_LEARN_MAX_WORD_COUNT(handle)) { |
| return NULL; |
| } |
| |
| ptr = POS_TO_ADDRESS(handle, que_id); |
| |
| que->type = GET_TYPE_FROM_DATA(ptr); |
| que->yomi_byte = GET_YSIZE_FROM_DATA(ptr); |
| que->yomi_len = que->yomi_byte / sizeof(NJ_CHAR); |
| que->hyouki_byte = GET_KSIZE_FROM_DATA(ptr); |
| que->hyouki_len = que->hyouki_byte / sizeof(NJ_CHAR); |
| |
| switch (que->type) { |
| case QUE_TYPE_JIRI: |
| case QUE_TYPE_FZK: |
| return que; |
| default: |
| break; |
| } |
| #ifdef LEARN_DEBUG |
| printf("FATAL : Illegal que was gotten (que_id=%d)\n", que_id); |
| #endif |
| return NULL; |
| } |
| |
| static NJ_WQUE *get_que_allHinsi(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, |
| NJ_UINT16 que_id) { |
| NJ_UINT8 *ptr; |
| NJ_WQUE *que = &(iwnn->que_tmp); |
| |
| |
| if (que_id >= GET_LEARN_MAX_WORD_COUNT(handle)) { |
| return NULL; |
| } |
| |
| ptr = POS_TO_ADDRESS(handle, que_id); |
| |
| que->type = GET_TYPE_FROM_DATA(ptr); |
| que->mae_hinsi = GET_FPOS_FROM_DATA(ptr); |
| que->ato_hinsi = GET_BPOS_FROM_DATA(ptr); |
| |
| switch (que->type) { |
| case QUE_TYPE_JIRI: |
| case QUE_TYPE_FZK: |
| return que; |
| default: |
| break; |
| } |
| #ifdef LEARN_DEBUG |
| printf("FATAL : Illegal que was gotten (que_id=%d)\n", que_id); |
| #endif |
| return NULL; |
| } |
| |
| static NJ_WQUE *get_que(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id) { |
| NJ_UINT8 *ptr; |
| NJ_WQUE *que = &(iwnn->que_tmp); |
| |
| |
| if (que_id >= GET_LEARN_MAX_WORD_COUNT(handle)) { |
| return NULL; |
| } |
| |
| ptr = POS_TO_ADDRESS(handle, que_id); |
| |
| que->entry = que_id; |
| que->type = GET_TYPE_FROM_DATA(ptr); |
| que->mae_hinsi = GET_FPOS_FROM_DATA(ptr); |
| que->ato_hinsi = GET_BPOS_FROM_DATA(ptr); |
| que->yomi_byte = GET_YSIZE_FROM_DATA(ptr); |
| que->yomi_len = que->yomi_byte / sizeof(NJ_CHAR); |
| que->hyouki_byte= GET_KSIZE_FROM_DATA(ptr); |
| que->hyouki_len = que->hyouki_byte / sizeof(NJ_CHAR); |
| que->next_flag = GET_FFLG_FROM_DATA(ptr); |
| |
| switch (que->type) { |
| case QUE_TYPE_JIRI: |
| case QUE_TYPE_FZK: |
| return que; |
| default: |
| break; |
| } |
| #ifdef LEARN_DEBUG |
| printf("FATAL : Illegal que was gotten (que_id=%d)\n", que_id); |
| #endif |
| return NULL; |
| } |
| |
| static NJ_INT16 is_continued(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id) { |
| NJ_WQUE *que; |
| NJ_UINT16 i; |
| NJ_UINT16 max, end; |
| |
| |
| max = GET_LEARN_MAX_WORD_COUNT(handle); |
| end = GET_LEARN_NEXT_WORD_POS(handle); |
| |
| for (i = 0; i < max; i++) { |
| que_id++; |
| if (que_id >= GET_LEARN_MAX_WORD_COUNT(handle)) { |
| |
| que_id = 0; |
| } |
| |
| |
| if (que_id == end) { |
| |
| return 0; |
| } |
| |
| que = get_que_type_and_next(iwnn, handle, que_id); |
| #ifdef IWNN_ERR_CHECK |
| if (iwnn->err_check_flg == 1) { |
| que = NULL; |
| } |
| #endif |
| if (que == NULL) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_IS_CONTINUED, NJ_ERR_DIC_BROKEN); |
| } |
| if (que->type != QUE_TYPE_EMPTY) { |
| |
| if (que->next_flag != 0) { |
| |
| return 1; |
| } else { |
| |
| return 0; |
| } |
| } |
| } |
| |
| |
| return 0; |
| } |
| |
| static NJ_INT16 continue_cnt(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT16 que_id) { |
| NJ_WQUE *que; |
| NJ_UINT16 i; |
| NJ_UINT16 max, end; |
| NJ_INT16 cnt = 0; |
| |
| |
| max = GET_LEARN_MAX_WORD_COUNT(handle); |
| end = GET_LEARN_NEXT_WORD_POS(handle); |
| |
| for (i = 0; i < max; i++) { |
| que_id++; |
| if (que_id >= max) { |
| |
| que_id = 0; |
| } |
| |
| |
| if (que_id == end) { |
| |
| return cnt; |
| } |
| |
| que = get_que_type_and_next(iwnn, handle, que_id); |
| if (que == NULL) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_CONTINUE_CNT, NJ_ERR_DIC_BROKEN); |
| } |
| if (que->type != QUE_TYPE_EMPTY) { |
| |
| if (que->next_flag != 0) { |
| |
| cnt++; |
| |
| |
| if (cnt >= (NJD_MAX_CONNECT_CNT - 1)) { |
| return cnt; |
| } |
| } else { |
| |
| return cnt; |
| } |
| } |
| } |
| |
| |
| return 0; |
| } |
| |
| static NJ_UINT16 search_next_que(NJ_DIC_HANDLE handle, NJ_UINT16 que_id) { |
| NJ_UINT16 max; |
| NJ_UINT16 i; |
| |
| |
| max = GET_LEARN_MAX_WORD_COUNT(handle); |
| |
| for (i = 0; i < max; i++) { |
| que_id++; |
| if (que_id >= max) { |
| |
| que_id = 0; |
| } |
| |
| if (GET_TYPE_FROM_DATA(POS_TO_ADDRESS(handle, que_id)) != QUE_TYPE_EMPTY) { |
| |
| return que_id; |
| } |
| } |
| |
| |
| return 0; |
| } |
| |
| static NJ_INT16 que_strcmp_complete_with_hyouki(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, |
| NJ_UINT16 que_id, NJ_CHAR *yomi, NJ_UINT16 yomi_len, NJ_CHAR *hyouki, |
| NJ_UINT8 multi_flg) { |
| NJ_CHAR *str; |
| NJ_INT16 ret; |
| NJ_UINT8 slen; |
| NJ_UINT16 hyouki_len; |
| NJ_UINT16 que_yomilen, que_hyoukilen; |
| NJ_INT16 que_count = 1; |
| NJ_INT16 cnt = 0; |
| |
| |
| |
| hyouki_len = nj_strlen(hyouki); |
| |
| if (multi_flg == 0) { |
| |
| cnt = 1; |
| } else { |
| |
| |
| cnt = GET_LEARN_WORD_COUNT(handle); |
| } |
| |
| while (cnt--) { |
| str = get_string(iwnn, handle, que_id, &slen); |
| if (str == NULL) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_QUE_STRCMP_COMPLETE_WITH_HYOUKI, |
| NJ_ERR_DIC_BROKEN); |
| } |
| que_yomilen = slen; |
| |
| ret = nj_strncmp(yomi, str, que_yomilen); |
| if (ret != 0) { |
| |
| return 0; |
| } |
| |
| str = get_hyouki(iwnn, handle, que_id, &slen); |
| if (str == NULL) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_QUE_STRCMP_COMPLETE_WITH_HYOUKI, |
| NJ_ERR_DIC_BROKEN); |
| } |
| que_hyoukilen = slen; |
| |
| ret = nj_strncmp(hyouki, str, que_hyoukilen); |
| if (ret != 0) { |
| |
| return 0; |
| } |
| |
| if ((yomi_len == que_yomilen) && |
| (hyouki_len == que_hyoukilen)) { |
| |
| return que_count; |
| } |
| |
| if ((que_yomilen > yomi_len) || |
| (que_hyoukilen > hyouki_len)) { |
| |
| return 0; |
| } |
| |
| ret = is_continued(iwnn, handle, que_id); |
| if (ret <= 0) { |
| |
| return ret; |
| } |
| |
| |
| if (que_count >= (NJD_MAX_CONNECT_CNT - 1)) { |
| |
| return 0; |
| } |
| |
| yomi_len -= que_yomilen; |
| yomi += que_yomilen; |
| |
| hyouki_len -= que_hyoukilen; |
| hyouki += que_hyoukilen; |
| |
| |
| que_id = search_next_que(handle, que_id); |
| que_count++; |
| } |
| return 0; |
| } |
| |
| static NJ_INT16 que_strcmp_include(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, |
| NJ_UINT16 que_id, NJ_CHAR *yomi) { |
| NJ_CHAR *str; |
| NJ_UINT16 que_len; |
| NJ_UINT16 yomi_len; |
| NJ_INT16 ret; |
| NJ_INT16 que_count = 1; |
| NJ_UINT16 i = 0; |
| NJ_UINT8 slen; |
| |
| |
| #ifdef LEARN_DEBUG |
| printf("que_strcmp_include(que_id=%d, yomi=[%s])\n", que_id, yomi); |
| #endif |
| yomi_len = nj_strlen(yomi); |
| if (yomi_len == 0) { |
| return que_count; |
| } |
| |
| i = GET_LEARN_WORD_COUNT(handle); |
| |
| while (--i) { |
| |
| |
| ret = is_continued(iwnn, handle, que_id); |
| if (ret < 0) { |
| |
| return ret; |
| } else if (ret == 0) { |
| |
| return que_count; |
| } |
| |
| |
| que_id = search_next_que(handle, que_id); |
| |
| str = get_string(iwnn, handle, que_id, &slen); |
| #ifdef IWNN_ERR_CHECK |
| if (iwnn->err_check_flg == 2) { |
| str = NULL; |
| } |
| #endif |
| if (str == NULL) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_QUE_STRCMP_INCLUDE, NJ_ERR_DIC_BROKEN); |
| } |
| que_len = slen; |
| |
| |
| if (que_len > yomi_len) { |
| #ifdef LEARN_DEBUG |
| printf(" >> mismatch [%s] (que_len > yomi_len)\n", str); |
| #endif |
| return que_count; |
| } |
| |
| |
| ret = nj_strncmp(yomi, str, que_len); |
| if (ret != 0) { |
| #ifdef LEARN_DEBUG |
| printf(" >> mismatch [%s]\n", str); |
| #endif |
| |
| return que_count; |
| } |
| |
| |
| if (que_len == yomi_len) { |
| #ifdef LEARN_DEBUG |
| printf(" >> match! [%s](%d)\n", str, que_count); |
| #endif |
| return (que_count + 1); |
| } |
| |
| que_count++; |
| if (que_count >= NJD_MAX_CONNECT_CNT) { |
| |
| return que_count; |
| } |
| |
| |
| yomi_len -= que_len; |
| yomi += que_len; |
| } |
| |
| return que_count; |
| } |
| |
| static NJ_CHAR *get_string(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, |
| NJ_UINT16 que_id, NJ_UINT8 *slen) { |
| NJ_UINT8 *src, *dst; |
| NJ_UINT8 copy_size, size; |
| NJ_UINT8 i; |
| NJ_UINT8 *top_addr; |
| NJ_UINT8 *bottom_addr; |
| NJ_UINT16 que_size; |
| |
| |
| src = POS_TO_ADDRESS(handle, que_id); |
| switch (GET_TYPE_FROM_DATA(src)) { |
| case QUE_TYPE_JIRI: |
| case QUE_TYPE_FZK: |
| size = GET_YSIZE_FROM_DATA(src); |
| *slen = (NJ_UINT8)(size / sizeof(NJ_CHAR)); |
| break; |
| |
| default: |
| #ifdef LEARN_DEBUG |
| printf("get_string(handle=%p, que_id=%d) : broken que\n", handle, que_id); |
| #endif |
| return NULL; |
| } |
| |
| if (NJ_GET_DIC_TYPE(handle) == NJ_DIC_TYPE_USER) { |
| if (*slen > NJ_MAX_USER_LEN) { |
| return NULL; |
| } |
| } else { |
| if (*slen > NJ_MAX_LEN) { |
| return NULL; |
| } |
| } |
| |
| |
| src += LEARN_QUE_STRING_OFFSET; |
| |
| que_size = QUE_SIZE(handle); |
| |
| |
| copy_size = (NJ_UINT8)que_size - LEARN_QUE_STRING_OFFSET; |
| dst = (NJ_UINT8*)&(iwnn->learn_string_tmp[0]); |
| if (copy_size > size) { |
| |
| copy_size = size; |
| } |
| for (i = 0; i < copy_size; i++) { |
| *dst++ = *src++; |
| } |
| |
| |
| top_addr = LEARN_DATA_TOP_ADDR(handle); |
| bottom_addr = top_addr; |
| bottom_addr += que_size * GET_LEARN_MAX_WORD_COUNT(handle) - 1; |
| |
| while (size -= copy_size) { |
| |
| if (src >= bottom_addr) { |
| src = top_addr; |
| } |
| |
| |
| if (*src != QUE_TYPE_NEXT) { |
| #ifdef LEARN_DEBUG |
| printf("FATAL: src que was broken(not QUE_TYPE_NEXT) [src=%x]\n", src); |
| #endif |
| return NULL; |
| } |
| |
| src++; |
| if (size < que_size) { |
| |
| copy_size = size; |
| } else { |
| copy_size = (NJ_UINT8)(que_size - 1); |
| } |
| for (i = 0; i < copy_size; i++) { |
| *dst++ = *src++; |
| } |
| } |
| iwnn->learn_string_tmp[*slen] = NJ_CHAR_NUL; |
| |
| return &(iwnn->learn_string_tmp[0]); |
| } |
| |
| static NJ_CHAR *get_hyouki(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, |
| NJ_UINT16 que_id, NJ_UINT8 *slen) { |
| NJ_UINT8 *src, *dst; |
| NJ_WQUE *que; |
| NJ_UINT8 copy_size, size; |
| NJ_UINT8 i; |
| NJ_UINT8 *top_addr; |
| NJ_UINT8 *bottom_addr; |
| NJ_CHAR *hira; |
| NJ_UINT16 que_size; |
| NJ_UINT32 dictype; |
| |
| |
| que = get_que_yomiLen_and_hyoukiLen(iwnn, handle, que_id); |
| if (que == NULL) { |
| return NULL; |
| } |
| |
| dictype = NJ_GET_DIC_TYPE(handle); |
| if (dictype == NJ_DIC_TYPE_USER) { |
| if (que->yomi_len > NJ_MAX_USER_LEN) { |
| return NULL; |
| } |
| if (que->hyouki_len > NJ_MAX_USER_KOUHO_LEN) { |
| return NULL; |
| } |
| } else { |
| if (que->yomi_len > NJ_MAX_LEN) { |
| return NULL; |
| } |
| if (que->hyouki_len > NJ_MAX_RESULT_LEN) { |
| return NULL; |
| } |
| } |
| |
| src = POS_TO_ADDRESS(handle, que_id); |
| |
| if (que->hyouki_len == 0) { |
| hira = get_string(iwnn, handle, que_id, slen); |
| if (hira == NULL) { |
| return NULL; |
| } |
| |
| if (GET_MFLG_FROM_DATA(src) != 0) { |
| *slen = (NJ_UINT8)nje_convert_hira_to_kata(hira, &(iwnn->muhenkan_tmp[0]), *slen); |
| return &(iwnn->muhenkan_tmp[0]); |
| } else { |
| return hira; |
| } |
| } |
| |
| src += LEARN_QUE_STRING_OFFSET; |
| |
| que_size = QUE_SIZE(handle); |
| |
| |
| size = que->yomi_byte; |
| copy_size = (NJ_UINT8)que_size - LEARN_QUE_STRING_OFFSET; |
| dst = (NJ_UINT8*)&(iwnn->learn_string_tmp[0]); |
| if (copy_size > size) { |
| |
| copy_size = size; |
| } |
| |
| |
| top_addr = LEARN_DATA_TOP_ADDR(handle); |
| bottom_addr = top_addr; |
| bottom_addr += que_size * GET_LEARN_MAX_WORD_COUNT(handle) - 1; |
| |
| src += copy_size; |
| while (size -= copy_size) { |
| |
| |
| if (src >= bottom_addr) { |
| src = top_addr; |
| } |
| |
| |
| if (*src != QUE_TYPE_NEXT) { |
| #ifdef LEARN_DEBUG |
| printf("FATAL: src que was broken(not QUE_TYPE_NEXT) [src=%x]\n", src); |
| #endif |
| return NULL; |
| } |
| |
| src++; |
| if (size < que_size) { |
| |
| copy_size = size; |
| } else { |
| copy_size = (NJ_UINT8)(que_size - 1); |
| } |
| src += copy_size; |
| } |
| |
| |
| |
| if (((src - top_addr) % que_size) == 0) { |
| |
| if (src >= bottom_addr) { |
| src = top_addr; |
| } |
| |
| if (*src++ != QUE_TYPE_NEXT) { |
| #ifdef LEARN_DEBUG |
| printf("FATAL: src que was broken(QUE_TYPE_NEXT) [src=%x]\n", src - 1); |
| #endif |
| return NULL; |
| } |
| } |
| |
| size = que->hyouki_byte; |
| |
| |
| copy_size = (NJ_UINT8)(que_size); |
| copy_size -= (NJ_UINT8)((src - top_addr) % que_size); |
| if (copy_size > size) { |
| |
| copy_size = size; |
| } |
| for (i = 0; i < copy_size; i++) { |
| *dst++ = *src++; |
| } |
| |
| while (size -= copy_size) { |
| |
| |
| if (src >= bottom_addr) { |
| src = top_addr; |
| } |
| |
| |
| if (*src != QUE_TYPE_NEXT) { |
| #ifdef LEARN_DEBUG |
| printf("FATAL: src que was broken(not QUE_TYPE_NEXT) [src=%x]\n", src); |
| #endif |
| return NULL; |
| } |
| |
| src++; |
| if (size < que_size) { |
| |
| copy_size = size; |
| } else { |
| copy_size = (NJ_UINT8)(que_size - 1); |
| } |
| |
| for (i = 0; i < copy_size; i++) { |
| *dst++ = *src++; |
| } |
| } |
| |
| *slen = que->hyouki_len; |
| iwnn->learn_string_tmp[*slen] = NJ_CHAR_NUL; |
| |
| return &(iwnn->learn_string_tmp[0]); |
| } |
| |
| static NJ_INT16 get_cand_by_sequential(NJ_CLASS *iwnn, NJ_SEARCH_CONDITION *cond, |
| NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT8 search_pattern, |
| NJ_UINT8 comp_flg) { |
| NJ_UINT16 current, from, to; |
| NJ_UINT16 que_id; |
| NJ_UINT8 *ptr, *p; |
| NJ_INT16 ret, num_count; |
| NJ_CHAR *yomi; |
| NJ_WQUE *que; |
| NJ_UINT8 forward_flag = 0; |
| |
| |
| |
| if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_NO_INIT) { |
| |
| ret = search_range_by_yomi(iwnn, loctset->loct.handle, search_pattern, |
| cond->yomi, cond->ylen, &from, &to, &forward_flag); |
| if (ret < 0) { |
| return ret; |
| } |
| if (ret == 0) { |
| if (forward_flag) { |
| loctset->loct.status = NJ_ST_SEARCH_END; |
| } else { |
| loctset->loct.status = NJ_ST_SEARCH_END_EXT; |
| } |
| return 0; |
| } |
| loctset->loct.top = from; |
| loctset->loct.bottom = to; |
| current = from; |
| } else if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_READY) { |
| |
| current = (NJ_UINT16)(loctset->loct.current + 1); |
| } else { |
| loctset->loct.status = NJ_ST_SEARCH_END; |
| return 0; |
| } |
| |
| |
| ptr = get_search_index_address(loctset->loct.handle, cond->operation); |
| p = ptr + (current * NJ_INDEX_SIZE); |
| |
| while (current <= loctset->loct.bottom) { |
| que_id = GET_UINT16(p); |
| if (search_pattern == NJ_CUR_OP_COMP) { |
| |
| ret = str_que_cmp(iwnn, loctset->loct.handle, cond->yomi, cond->ylen, que_id, 1); |
| |
| |
| if (ret == 2) { |
| ret = 0; |
| } |
| } else if (search_pattern == NJ_CUR_OP_FORE) { |
| |
| ret = str_que_cmp(iwnn, loctset->loct.handle, cond->yomi, cond->ylen, que_id, 2); |
| |
| |
| if (ret == 2) { |
| ret = 0; |
| } |
| } else { |
| |
| |
| |
| ret = que_strcmp_complete_with_hyouki(iwnn, loctset->loct.handle, que_id, |
| cond->yomi, cond->ylen, cond->kanji, 0); |
| } |
| |
| if (ret < 0) { |
| return ret; |
| } |
| if (ret > 0) { |
| if (search_pattern == NJ_CUR_OP_LINK) { |
| |
| |
| num_count = continue_cnt(iwnn, loctset->loct.handle, que_id); |
| if (num_count < 0) { |
| |
| return num_count; |
| } |
| |
| |
| if (num_count >= ret) { |
| |
| loctset->loct.current_info = (NJ_UINT8)(((num_count + 1) << 4) | ret); |
| loctset->loct.current = current; |
| loctset->loct.status = NJ_ST_SEARCH_READY; |
| loctset->cache_freq = get_hindo(iwnn, loctset, search_pattern); |
| return 1; |
| } |
| } else { |
| |
| |
| |
| |
| |
| |
| que = get_que_allHinsi(iwnn, loctset->loct.handle, que_id); |
| if (njd_connect_test(cond, que->mae_hinsi, que->ato_hinsi)) { |
| |
| |
| switch (NJ_GET_DIC_TYPE_EX(loctset->loct.type, loctset->loct.handle)) { |
| case NJ_DIC_TYPE_CUSTOM_INCOMPRESS: |
| if ((search_pattern == NJ_CUR_OP_COMP) && (comp_flg == 1)) { |
| yomi = cond->yomi + cond->ylen; |
| ret = que_strcmp_include(iwnn, loctset->loct.handle, que_id, yomi); |
| if (ret < 0) { |
| return ret; |
| } |
| } |
| break; |
| default: |
| break; |
| } |
| loctset->loct.current = current; |
| loctset->loct.status = NJ_ST_SEARCH_READY; |
| |
| loctset->loct.current_info = (ret & 0x0f) << 4; |
| loctset->cache_freq = get_hindo(iwnn, loctset, search_pattern); |
| return 1; |
| } |
| } |
| } |
| p += NJ_INDEX_SIZE; |
| current++; |
| } |
| |
| |
| loctset->loct.status = NJ_ST_SEARCH_END; |
| return 0; |
| } |
| |
| static NJ_INT16 get_cand_by_evaluate(NJ_CLASS *iwnn, NJ_SEARCH_CONDITION *cond, |
| NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT8 search_pattern) { |
| NJ_UINT16 from, to, i; |
| NJ_UINT16 que_id, oldest; |
| NJ_UINT32 max_value, eval, current; |
| NJ_UINT8 *ptr, *p; |
| NJ_WQUE *que; |
| NJ_INT16 ret, num_count; |
| NJ_INT32 found = 0; |
| NJ_UINT8 forward_flag = 0; |
| NJ_INT32 is_first_search, is_better_freq; |
| |
| |
| |
| ptr = get_search_index_address(loctset->loct.handle, cond->operation); |
| |
| |
| oldest = GET_LEARN_NEXT_WORD_POS(loctset->loct.handle); |
| |
| |
| current = 0; |
| if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_NO_INIT) { |
| if (search_pattern == NJ_CUR_OP_LINK) { |
| |
| |
| |
| ret = search_range_by_yomi_multi(iwnn, loctset->loct.handle, |
| cond->yomi, cond->ylen, &from, &to); |
| } else { |
| |
| |
| ret = search_range_by_yomi(iwnn, loctset->loct.handle, search_pattern, |
| cond->yomi, cond->ylen, &from, &to, &forward_flag); |
| } |
| if (ret <= 0) { |
| loctset->loct.status = NJ_ST_SEARCH_END; |
| return ret; |
| } |
| loctset->loct.top = from; |
| loctset->loct.bottom = to; |
| is_first_search = 1; |
| } else if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_READY) { |
| current = GET_UINT16(ptr + (loctset->loct.current * NJ_INDEX_SIZE)); |
| if (current < oldest) { |
| current += GET_LEARN_MAX_WORD_COUNT(loctset->loct.handle); |
| } |
| is_first_search = 0; |
| } else { |
| loctset->loct.status = NJ_ST_SEARCH_END; |
| return 0; |
| } |
| |
| |
| max_value = oldest; |
| |
| p = ptr + (loctset->loct.top * NJ_INDEX_SIZE); |
| eval = current; |
| for (i = (NJ_UINT16)loctset->loct.top; i <= (NJ_UINT16)loctset->loct.bottom; i++) { |
| que_id = GET_UINT16(p); |
| if (que_id < oldest) { |
| eval = que_id + GET_LEARN_MAX_WORD_COUNT(loctset->loct.handle); |
| } else { |
| eval = que_id; |
| } |
| #ifdef LEARN_DEBUG |
| printf("que(%d) : eval = %d\n", que_id, eval); |
| #endif |
| is_better_freq = ((eval >= max_value) && ((is_first_search) || (eval < current))) ? 1 : 0; |
| |
| if (is_better_freq) { |
| |
| if (search_pattern == NJ_CUR_OP_LINK) { |
| |
| ret = que_strcmp_complete_with_hyouki(iwnn, loctset->loct.handle, que_id, |
| cond->yomi, cond->ylen, cond->kanji, 1); |
| } else { |
| |
| ret = str_que_cmp(iwnn, loctset->loct.handle, cond->yomi, cond->ylen, que_id, 2); |
| |
| if (ret == 2) { |
| ret = 0; |
| } |
| } |
| if (ret < 0) { |
| return ret; |
| } |
| if (ret >= 1) { |
| if (search_pattern == NJ_CUR_OP_LINK) { |
| |
| |
| num_count = continue_cnt(iwnn, loctset->loct.handle, que_id); |
| if (num_count < 0) { |
| |
| return num_count; |
| } |
| |
| |
| if (num_count >= ret) { |
| |
| loctset->loct.current_info = (NJ_UINT8)(((num_count + 1) << 4) | ret); |
| loctset->loct.current = i; |
| max_value = eval; |
| found = 1; |
| } |
| } else { |
| |
| |
| |
| |
| |
| que = get_que_allHinsi(iwnn, loctset->loct.handle, que_id); |
| if (njd_connect_test(cond, que->mae_hinsi, que->ato_hinsi)) { |
| |
| loctset->loct.current_info = (NJ_UINT8)0x10; |
| loctset->loct.current = i; |
| max_value = eval; |
| found = 1; |
| #ifdef LEARN_DEBUG |
| printf("---keep."); |
| #endif |
| } |
| } |
| } |
| } |
| p += NJ_INDEX_SIZE; |
| } |
| |
| |
| if (found == 0) { |
| loctset->loct.status = NJ_ST_SEARCH_END; |
| return 0; |
| } else { |
| loctset->loct.status = NJ_ST_SEARCH_READY; |
| loctset->cache_freq = get_hindo(iwnn, loctset, search_pattern); |
| return 1; |
| } |
| |
| } |
| |
| static NJ_INT16 search_range_by_yomi(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT8 op, |
| NJ_CHAR *yomi, NJ_UINT16 len, NJ_UINT16 *from, NJ_UINT16 *to, |
| NJ_UINT8 *forward_flag) { |
| NJ_UINT16 right, mid = 0, left, max; |
| NJ_UINT16 que_id; |
| NJ_UINT8 *ptr, *p; |
| NJ_CHAR *str; |
| NJ_INT16 ret = 0; |
| NJ_INT32 found = 0; |
| NJ_UINT8 slen; |
| NJ_INT32 cmp; |
| |
| |
| |
| ptr = get_search_index_address(handle, op); |
| |
| max = GET_LEARN_WORD_COUNT(handle); |
| |
| right = max - 1; |
| left = 0; |
| |
| #ifdef LEARN_DEBUG |
| printf("src:[%s]\n", yomi); |
| #endif |
| |
| *forward_flag = 0; |
| |
| |
| switch (op) { |
| case NJ_CUR_OP_COMP: |
| case NJ_CUR_OP_LINK: |
| case NJ_CUR_OP_FORE: |
| |
| |
| |
| break; |
| default: |
| return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_PARAM_OPERATION); |
| } |
| |
| while (left <= right) { |
| mid = left + ((right - left) / 2); |
| p = ptr + (mid * NJ_INDEX_SIZE); |
| que_id = GET_UINT16(p); |
| str = get_string(iwnn, handle, que_id, &slen); |
| |
| #ifdef IWNN_ERR_CHECK |
| if (iwnn->err_check_flg == 3) { |
| str = NULL; |
| } |
| #endif |
| if (str == NULL) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_DIC_BROKEN); |
| } |
| |
| ret = nj_strncmp(yomi, str, len); |
| if (op != NJ_CUR_OP_FORE) { |
| |
| |
| if (ret == 0) { |
| if ((*forward_flag == 0) && (len <= (NJ_UINT16)slen)) { |
| |
| *forward_flag = 1; |
| } |
| if (len > (NJ_UINT16)slen) { |
| ret = 1; |
| } else if (len < (NJ_UINT16)slen) { |
| ret = -1; |
| } |
| } |
| } |
| #ifdef LEARN_DEBUG |
| printf(" [%d][%d][%d]COMPARE:[%s] = %d\n", left, mid, right, str, ret); |
| #endif |
| if (ret == 0) { |
| |
| found = 1; |
| break; |
| } else if (ret < 0) { |
| |
| right = mid - 1; |
| if (mid == 0) { |
| break; |
| } |
| } else { |
| |
| left = mid + 1; |
| } |
| } |
| |
| if (!found) { |
| return 0; |
| } |
| |
| if (mid == 0) { |
| *from = mid; |
| } else { |
| |
| p = ((mid - 1) * NJ_INDEX_SIZE) + ptr; |
| |
| for (cmp = mid - 1; cmp >= 0; cmp--) { |
| que_id = GET_UINT16(p); |
| str = get_string(iwnn, handle, que_id, &slen); |
| |
| #ifdef IWNN_ERR_CHECK |
| if (iwnn->err_check_flg == 4) { |
| str = NULL; |
| } |
| #endif |
| if (str == NULL) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_DIC_BROKEN); |
| } |
| |
| if (op != NJ_CUR_OP_FORE) { |
| ret = nj_strncmp(yomi, str, len); |
| if (ret == 0) { |
| if (len > (NJ_UINT16)slen) { |
| ret = 1; |
| } else if (len < (NJ_UINT16)slen) { |
| ret = -1; |
| } |
| } |
| if (ret > 0) { |
| |
| break; |
| } |
| } else { |
| |
| if (nj_strncmp(yomi, str, len) != 0) { |
| break; |
| } |
| } |
| p -= NJ_INDEX_SIZE; |
| } |
| if (cmp < 0) { |
| *from = 0; |
| } else { |
| *from = (NJ_UINT16)cmp + 1; |
| } |
| } |
| |
| #ifdef LEARN_DEBUG |
| printf(" >> from:(%d)\n", *from); |
| #endif |
| |
| #ifdef IWNN_ERR_CHECK |
| if (iwnn->err_check_flg == 5) { |
| mid = max - 2; |
| } |
| #endif |
| if ((mid + 1) >= max) { |
| *to = mid; |
| } else { |
| |
| p = ((mid + 1) * NJ_INDEX_SIZE) + ptr; |
| |
| for (right = mid + 1; right < max; right++) { |
| que_id = GET_UINT16(p); |
| str = get_string(iwnn, handle, que_id, &slen); |
| |
| #ifdef IWNN_ERR_CHECK |
| if (iwnn->err_check_flg == 5) { |
| str = NULL; |
| } |
| #endif |
| if (str == NULL) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_DIC_BROKEN); |
| } |
| |
| if (op != NJ_CUR_OP_FORE) { |
| ret = nj_strncmp(yomi, str, len); |
| if (ret == 0) { |
| if (len > (NJ_UINT16)slen) { |
| ret = 1; |
| } else if (len < (NJ_UINT16)slen) { |
| ret = -1; |
| } |
| } |
| if (ret < 0) { |
| |
| break; |
| } |
| } else { |
| |
| if (nj_strncmp(yomi, str, len) != 0) { |
| break; |
| } |
| } |
| p += NJ_INDEX_SIZE; |
| } |
| *to = right - 1; |
| } |
| |
| #ifdef LEARN_DEBUG |
| printf(" >> to:(%d)\n", *to); |
| #endif |
| return 1; |
| } |
| |
| static NJ_INT16 search_range_by_yomi_multi(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, |
| NJ_CHAR *yomi, NJ_UINT16 len, NJ_UINT16 *from, NJ_UINT16 *to) { |
| NJ_UINT16 right, mid = 0, left, max = 0; |
| NJ_UINT16 que_id; |
| NJ_UINT8 *ptr, *p; |
| NJ_INT16 ret = 0; |
| NJ_UINT16 comp_len; |
| NJ_UINT16 i, char_len; |
| NJ_INT32 found = 0; |
| NJ_INT32 cmp; |
| NJ_CHAR comp_yomi[NJ_MAX_LEN + NJ_TERM_LEN]; |
| NJ_CHAR *pYomi; |
| |
| |
| |
| |
| ptr = LEARN_INDEX_TOP_ADDR(handle); |
| |
| |
| max = GET_LEARN_WORD_COUNT(handle); |
| |
| #ifdef LEARN_DEBUG |
| printf("src:[%s]\n", yomi); |
| #endif |
| |
| comp_len = 0; |
| pYomi = &yomi[0]; |
| while (comp_len < len) { |
| |
| |
| char_len = NJ_CHAR_LEN(pYomi); |
| for (i = 0; i < char_len; i++) { |
| *(comp_yomi + comp_len) = *pYomi; |
| comp_len++; |
| pYomi++; |
| } |
| *(comp_yomi + comp_len) = NJ_CHAR_NUL; |
| |
| right = max - 1; |
| left = 0; |
| while (left <= right) { |
| mid = left + ((right - left) / 2); |
| p = ptr + (mid * NJ_INDEX_SIZE); |
| que_id = GET_UINT16(p); |
| |
| |
| ret = str_que_cmp(iwnn, handle, comp_yomi, comp_len, que_id, 1); |
| if (ret < 0) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI_MULTI, NJ_ERR_DIC_BROKEN); |
| } |
| |
| #ifdef LEARN_DEBUG |
| printf(" [%d][%d][%d]COMPARE:[%s] = %d\n", left, mid, right, str, ret); |
| #endif |
| if (ret == 1) { |
| |
| found = 1; |
| break; |
| } else if (ret == 0) { |
| |
| right = mid - 1; |
| if (mid == 0) { |
| break; |
| } |
| } else { |
| |
| left = mid + 1; |
| } |
| } |
| |
| if (found) { |
| break; |
| } |
| } |
| |
| if (!found) { |
| |
| return 0; |
| } |
| |
| |
| if (mid == 0) { |
| *from = mid; |
| } else { |
| |
| p = ((mid - 1) * NJ_INDEX_SIZE) + ptr; |
| |
| for (cmp = mid - 1; cmp >= 0; cmp--) { |
| que_id = GET_UINT16(p); |
| ret = str_que_cmp(iwnn, handle, comp_yomi, comp_len, que_id, 1); |
| if (ret < 0) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI_MULTI, NJ_ERR_DIC_BROKEN); |
| } |
| if (ret == 2) { |
| break; |
| } |
| p -= NJ_INDEX_SIZE; |
| } |
| if (cmp < 0) { |
| *from = 0; |
| } else { |
| *from = (NJ_UINT16)cmp + 1; |
| } |
| } |
| |
| #ifdef LEARN_DEBUG |
| printf(" >> from:(%d)\n", *from); |
| #endif |
| |
| |
| if ((mid + 1) >= max) { |
| *to = mid; |
| } else { |
| |
| p = ((mid + 1) * NJ_INDEX_SIZE) + ptr; |
| |
| for (right = mid + 1; right < max; right++) { |
| que_id = GET_UINT16(p); |
| ret = str_que_cmp(iwnn, handle, yomi, len, que_id, 1); |
| if (ret < 0) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI_MULTI, NJ_ERR_DIC_BROKEN); |
| } |
| if (ret == 0) { |
| break; |
| } |
| p += NJ_INDEX_SIZE; |
| } |
| *to = right - 1; |
| } |
| |
| #ifdef LEARN_DEBUG |
| printf(" >> to:(%d)\n", *to); |
| #endif |
| return 1; |
| } |
| |
| static NJ_INT16 str_que_cmp(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_CHAR *yomi, |
| NJ_UINT16 yomiLen, NJ_UINT16 que_id, NJ_UINT8 mode) { |
| NJ_UINT8 *queYomi; |
| NJ_UINT8 *yomiPtr; |
| NJ_UINT16 yomiByte; |
| NJ_UINT16 yomiPos; |
| NJ_UINT8 queYomiByte, queKouhoByte; |
| NJ_UINT8 queYomiPos, queYomiSearchArea; |
| NJ_INT16 complete; |
| NJ_UINT8 *top_addr; |
| NJ_UINT8 *bottom_addr; |
| NJ_UINT16 que_size; |
| |
| |
| #ifdef IWNN_ERR_CHECK |
| if (iwnn->err_check_flg == 6) { |
| que_id = GET_LEARN_MAX_WORD_COUNT(handle); |
| } |
| #endif |
| if (que_id >= GET_LEARN_MAX_WORD_COUNT(handle)) { |
| |
| return NJ_SET_ERR_VAL(NJ_FUNC_STR_QUE_CMP, NJ_ERR_DIC_BROKEN); |
| } |
| |
| queYomi = POS_TO_ADDRESS(handle, que_id); |
| #ifdef IWNN_ERR_CHECK |
| if (iwnn->err_check_flg == 7) { |
| *queYomi = 0x03; |
| } |
| #endif |
| switch (GET_TYPE_FROM_DATA(queYomi)) { |
| case QUE_TYPE_EMPTY: |
| case QUE_TYPE_JIRI: |
| case QUE_TYPE_FZK: |
| break; |
| default: |
| |
| return NJ_SET_ERR_VAL(NJ_FUNC_STR_QUE_CMP, NJ_ERR_DIC_BROKEN); |
| } |
| |
| |
| if ((mode == 2) && (yomiLen == 0)) { |
| return 1; |
| } |
| |
| |
| queYomiByte = GET_YSIZE_FROM_DATA(queYomi); |
| queKouhoByte= GET_KSIZE_FROM_DATA(queYomi); |
| |
| top_addr = LEARN_DATA_TOP_ADDR(handle); |
| que_size = QUE_SIZE(handle); |
| |
| |
| queYomi += LEARN_QUE_STRING_OFFSET; |
| queYomiSearchArea = (NJ_UINT8)(QUE_SIZE(handle) - LEARN_QUE_STRING_OFFSET); |
| |
| complete = 0; |
| yomiPos = 0; queYomiPos = 0; |
| yomiPtr = (NJ_UINT8*)yomi; |
| yomiByte = yomiLen * sizeof(NJ_CHAR); |
| |
| |
| while ((complete = (*yomiPtr - *queYomi)) == 0) { |
| yomiPos++; queYomiPos++; |
| |
| if (queYomiPos >= queYomiByte) { |
| if (queYomiByte == yomiByte) { |
| |
| return 1; |
| } else if (mode == 2) { |
| |
| return 2; |
| } else { |
| |
| return (mode + 1); |
| } |
| } |
| if (yomiPos >= yomiByte) { |
| |
| break; |
| } else { |
| yomiPtr++; queYomi++; |
| #ifdef IWNN_ERR_CHECK |
| if (iwnn->err_check_flg == 8) { |
| queYomiPos = queYomiSearchArea; |
| } |
| #endif |
| if (queYomiPos >= queYomiSearchArea) { |
| |
| bottom_addr = top_addr; |
| bottom_addr += que_size * GET_LEARN_MAX_WORD_COUNT(handle) - 1; |
| if (queYomi >= bottom_addr) { |
| queYomi = top_addr; |
| } |
| |
| |
| if (*queYomi++ != QUE_TYPE_NEXT) { |
| |
| return NJ_SET_ERR_VAL(NJ_FUNC_STR_QUE_CMP, NJ_ERR_DIC_BROKEN); |
| } |
| queYomiSearchArea += (NJ_UINT8)(que_size - 1); |
| } |
| } |
| } |
| if (complete == 0) { |
| if (yomiByte < queYomiByte) { |
| |
| if (mode == 2) { |
| return 1; |
| } |
| |
| return 0; |
| } else { |
| |
| return 2; |
| } |
| } else if (complete < 0) { |
| |
| return 0; |
| } else { |
| |
| return 2; |
| } |
| } |
| |
| static NJ_HINDO calculate_hindo(NJ_DIC_HANDLE handle, NJ_INT32 freq, NJ_DIC_FREQ *dic_freq, NJ_INT16 freq_max, NJ_INT16 freq_min) { |
| NJ_UINT16 max; |
| NJ_HINDO hindo; |
| |
| |
| max = GET_LEARN_MAX_WORD_COUNT(handle); |
| |
| |
| |
| |
| if (NJ_GET_DIC_TYPE(handle) == NJ_DIC_TYPE_USER) { |
| |
| hindo = (NJ_INT16)dic_freq->base; |
| } else { |
| |
| if (max > 1) { |
| |
| hindo = CALCULATE_HINDO(freq, dic_freq->base, dic_freq->high, (max-1)); |
| } else { |
| |
| hindo = (NJ_INT16)dic_freq->high; |
| } |
| } |
| return NORMALIZE_HINDO(hindo, freq_max, freq_min); |
| } |
| |
| static NJ_HINDO get_hindo(NJ_CLASS *iwnn, NJ_SEARCH_LOCATION_SET *loctset, |
| NJ_UINT8 search_pattern) { |
| NJ_WQUE *que; |
| NJ_UINT16 que_id, oldest; |
| NJ_UINT8 offset; |
| NJ_INT32 dic_freq; |
| NJ_UINT16 max; |
| NJ_UINT8 *learn_index_top_addr; |
| |
| |
| |
| learn_index_top_addr = get_search_index_address(loctset->loct.handle, search_pattern); |
| |
| que_id = (NJ_UINT16)GET_UINT16(learn_index_top_addr + |
| ((loctset->loct.current & 0xffffU) * NJ_INDEX_SIZE)); |
| oldest = GET_LEARN_NEXT_WORD_POS(loctset->loct.handle); |
| |
| offset = (loctset->loct.current_info & 0x0f); |
| while (offset--) { |
| que_id = search_next_que(loctset->loct.handle, que_id); |
| } |
| |
| que = get_que(iwnn, loctset->loct.handle, que_id); |
| if (que == NULL) { |
| return INIT_HINDO; |
| } |
| |
| max = GET_LEARN_MAX_WORD_COUNT(loctset->loct.handle); |
| if (que_id >= oldest) { |
| dic_freq = que_id - oldest; |
| } else { |
| dic_freq = que_id - oldest + max; |
| } |
| |
| |
| return calculate_hindo(loctset->loct.handle, dic_freq, &(loctset->dic_freq), loctset->dic_freq_max, loctset->dic_freq_min); |
| } |
| |
| NJ_INT16 njd_l_get_word(NJ_CLASS *iwnn, NJ_SEARCH_LOCATION_SET *loctset, NJ_WORD *word) { |
| NJ_WQUE *que; |
| NJ_UINT16 que_id; |
| NJ_UINT8 offset; |
| NJ_UINT8 *learn_index_top_addr; |
| |
| |
| |
| learn_index_top_addr = get_search_index_address(loctset->loct.handle, GET_LOCATION_OPERATION(loctset->loct.status)); |
| |
| que_id = (NJ_UINT16)GET_UINT16(learn_index_top_addr + |
| ((loctset->loct.current & 0xffff) * NJ_INDEX_SIZE)); |
| |
| offset = (loctset->loct.current_info & 0x0f); |
| while (offset--) { |
| que_id = search_next_que(loctset->loct.handle, que_id); |
| } |
| |
| que = get_que(iwnn, loctset->loct.handle, que_id); |
| if (que == NULL) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_GET_WORD, NJ_ERR_CANNOT_GET_QUE); |
| } |
| |
| word->stem.loc = loctset->loct; |
| |
| word->stem.loc.current &= 0x0000ffff; |
| word->stem.loc.current |= ((NJ_UINT32)que_id << 16); |
| |
| |
| word->stem.hindo = loctset->cache_freq; |
| |
| NJ_SET_FPOS_TO_STEM(word, que->mae_hinsi); |
| NJ_SET_YLEN_TO_STEM(word, que->yomi_len); |
| if (que->hyouki_len > 0) { |
| NJ_SET_KLEN_TO_STEM(word, que->hyouki_len); |
| } else { |
| |
| NJ_SET_KLEN_TO_STEM(word, que->yomi_len); |
| } |
| NJ_SET_BPOS_TO_STEM(word, que->ato_hinsi); |
| |
| |
| word->stem.type = 0; |
| |
| return 1; |
| } |
| |
| NJ_INT16 njd_l_get_stroke(NJ_CLASS *iwnn, NJ_WORD *word, NJ_CHAR *stroke, NJ_UINT16 size) { |
| NJ_UINT16 que_id; |
| NJ_CHAR *str; |
| NJ_UINT8 slen; |
| NJ_UINT8 ylen; |
| |
| |
| que_id = (NJ_UINT16)(word->stem.loc.current >> 16); |
| |
| |
| ylen = (NJ_UINT8)NJ_GET_YLEN_FROM_STEM(word); |
| |
| if ((NJ_UINT16)((ylen+ NJ_TERM_LEN)*sizeof(NJ_CHAR)) > size) { |
| |
| return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_GET_STROKE, NJ_ERR_BUFFER_NOT_ENOUGH); |
| } |
| if (ylen == 0) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_GET_STROKE, NJ_ERR_INVALID_RESULT); |
| } |
| str = get_string(iwnn, word->stem.loc.handle, que_id, &slen); |
| |
| #ifdef IWNN_ERR_CHECK |
| if (iwnn->err_check_flg == 9) { |
| str = NULL; |
| } |
| #endif |
| |
| if (str == NULL) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_GET_STROKE, NJ_ERR_DIC_BROKEN); |
| } |
| |
| |
| nj_strcpy(stroke, str); |
| |
| return slen; |
| } |
| |
| NJ_INT16 njd_l_get_candidate(NJ_CLASS *iwnn, NJ_WORD *word, |
| NJ_CHAR *candidate, NJ_UINT16 size) { |
| NJ_UINT16 que_id; |
| NJ_CHAR *str; |
| NJ_UINT16 klen; |
| NJ_UINT8 slen; |
| |
| |
| que_id = (NJ_UINT16)(word->stem.loc.current >> 16); |
| |
| |
| klen = NJ_GET_KLEN_FROM_STEM(word); |
| |
| if (size < ((klen+NJ_TERM_LEN)*sizeof(NJ_CHAR))) { |
| |
| return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_GET_CANDIDATE, NJ_ERR_BUFFER_NOT_ENOUGH); |
| } |
| str = get_hyouki(iwnn, word->stem.loc.handle, que_id, &slen); |
| #ifdef IWNN_ERR_CHECK |
| if (iwnn->err_check_flg == 10) { |
| str = NULL; |
| } |
| #endif |
| if (str == NULL) { |
| |
| return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_GET_CANDIDATE, NJ_ERR_DIC_BROKEN); |
| } |
| |
| |
| nj_strcpy(candidate, str); |
| |
| return klen; |
| } |
| |
| NJ_INT16 njd_l_check_dic(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle) { |
| NJ_UINT16 flg; |
| NJ_UINT16 word_cnt, max; |
| NJ_UINT8 *ptr; |
| NJ_UINT16 target_id; |
| NJ_UINT16 i; |
| NJ_UINT16 id1 = 0; |
| NJ_UINT8 slen; |
| |
| |
| |
| if ((NJ_GET_DIC_TYPE(handle) != NJ_DIC_TYPE_USER)) { |
| |
| return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_CHECK_DIC, NJ_ERR_DIC_TYPE_INVALID); |
| } |
| |
| |
| word_cnt = GET_LEARN_WORD_COUNT(handle); |
| max = GET_LEARN_MAX_WORD_COUNT(handle); |
| if (word_cnt > max) { |
| |
| return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_CHECK_DIC, |
| NJ_ERR_DIC_BROKEN); |
| } |
| |
| ptr = LEARN_INDEX_TOP_ADDR(handle); |
| for (i = 0; i < word_cnt; i++) { |
| id1 = GET_UINT16(ptr); |
| |
| if (id1 >= max) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_CHECK_DIC, |
| NJ_ERR_DIC_BROKEN); |
| } |
| ptr += NJ_INDEX_SIZE; |
| } |
| |
| |
| ptr = LEARN_INDEX_TOP_ADDR2(handle); |
| for (i = 0; i < word_cnt; i++) { |
| id1 = GET_UINT16(ptr); |
| |
| if (id1 >= max) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_CHECK_DIC, |
| NJ_ERR_DIC_BROKEN); |
| } |
| ptr += NJ_INDEX_SIZE; |
| } |
| |
| |
| flg = GET_UINT16(handle + POS_WRITE_FLG); |
| |
| target_id = GET_UINT16(handle + POS_WRITE_FLG + 2); |
| |
| |
| |
| if (((flg != word_cnt) && (flg != (word_cnt + 1)) && (flg != (word_cnt - 1))) || |
| (target_id >= max)) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_CHECK_DIC, |
| NJ_ERR_DIC_BROKEN); |
| } |
| |
| |
| if (flg == (word_cnt + 1)) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_CHECK_DIC, NJ_ERR_DIC_BROKEN); |
| } else if (flg == (word_cnt - 1)) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_CHECK_DIC, NJ_ERR_DIC_BROKEN); |
| } |
| |
| word_cnt = GET_LEARN_WORD_COUNT(handle); |
| |
| ptr = LEARN_INDEX_TOP_ADDR(handle); |
| for (i = 0; i < word_cnt; i++) { |
| id1 = GET_UINT16(ptr); |
| if (get_hyouki(iwnn, handle, id1, &slen) == NULL) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_CHECK_DIC, |
| NJ_ERR_DIC_BROKEN); |
| } |
| ptr += NJ_INDEX_SIZE; |
| } |
| |
| ptr = LEARN_INDEX_TOP_ADDR2(handle); |
| for (i = 0; i < word_cnt; i++) { |
| id1 = GET_UINT16(ptr); |
| |
| if (id1 >= max) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_NJD_L_CHECK_DIC, |
| NJ_ERR_DIC_BROKEN); |
| } |
| ptr += NJ_INDEX_SIZE; |
| } |
| |
| return 0; |
| } |
| |
| static NJ_INT16 get_cand_by_evaluate2(NJ_CLASS *iwnn, NJ_SEARCH_CONDITION *cond, |
| NJ_SEARCH_LOCATION_SET *loctset, |
| NJ_UINT8 search_pattern, |
| NJ_UINT16 idx) { |
| NJ_UINT16 from, to, i; |
| NJ_UINT16 que_id, oldest; |
| NJ_UINT32 max_value, eval, current; |
| NJ_UINT8 *ptr, *p; |
| NJ_WQUE *que; |
| NJ_INT16 ret = 0; |
| NJ_INT32 found = 0; |
| NJ_UINT8 forward_flag = 0; |
| |
| |
| NJ_UINT16 abIdx; |
| NJ_UINT16 abIdx_old; |
| NJ_UINT16 tmp_len; |
| NJ_UINT16 yomi_clen; |
| NJ_UINT16 j,l,m; |
| NJ_UINT8 cmpflg; |
| NJ_UINT8 endflg = 0; |
| NJ_CHAR *str; |
| NJ_CHAR *key; |
| NJ_CHAR char_tmp[NJ_MAX_LEN + NJ_TERM_LEN]; |
| NJ_CHAR *pchar_tmp; |
| NJ_SEARCH_CACHE *psrhCache = cond->ds->dic[idx].srhCache; |
| NJ_UINT16 endIdx; |
| NJ_UINT8 slen; |
| NJ_UINT16 addcnt = 0; |
| NJ_CHAR *yomi; |
| NJ_UINT8 aimai_flg = 0x01; |
| NJ_CHARSET *pCharset = cond->charset; |
| |
| |
| if (NJ_GET_CACHEOVER_FROM_SCACHE(psrhCache)) { |
| aimai_flg = 0x00; |
| } |
| |
| |
| ptr = get_search_index_address(loctset->loct.handle, cond->operation); |
| |
| |
| oldest = GET_LEARN_NEXT_WORD_POS(loctset->loct.handle); |
| max_value = oldest; |
| |
| |
| current = 0; |
| if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_NO_INIT) { |
| |
| |
| key = cond->ds->keyword; |
| yomi = cond->yomi; |
| yomi_clen = cond->yclen; |
| |
| |
| endflg = 0x00; |
| |
| if (psrhCache->keyPtr[0] == 0xFFFF) { |
| cmpflg = 0x01; |
| psrhCache->keyPtr[0] = 0x0000; |
| } else { |
| cmpflg = 0x00; |
| } |
| |
| for (i = 0; i < yomi_clen; i++) { |
| j = i; |
| |
| |
| if (!cmpflg) { |
| |
| if (((j != 0) && (psrhCache->keyPtr[j] == 0)) || (psrhCache->keyPtr[j+1] == 0)) { |
| |
| cmpflg = 0x01; |
| } else { |
| |
| } |
| } |
| |
| if (cmpflg) { |
| |
| if (!j) { |
| |
| abIdx = 0; |
| addcnt = 0; |
| nj_charncpy(char_tmp, yomi, 1); |
| tmp_len = nj_strlen(char_tmp); |
| ret = search_range_by_yomi(iwnn, loctset->loct.handle, search_pattern, |
| char_tmp, tmp_len, &from, |
| &to, &forward_flag); |
| if (ret < 0) { |
| |
| |
| psrhCache->keyPtr[j+1] = abIdx; |
| loctset->loct.status = NJ_ST_SEARCH_END; |
| return ret; |
| } else if (ret > 0) { |
| |
| psrhCache->storebuff[abIdx].top = from; |
| psrhCache->storebuff[abIdx].bottom = to; |
| psrhCache->storebuff[abIdx].idx_no = (NJ_INT8)tmp_len; |
| addcnt++; |
| abIdx++; |
| psrhCache->keyPtr[j+1] = abIdx; |
| } else { |
| psrhCache->keyPtr[j+1] = abIdx; |
| } |
| |
| if ((!endflg) && (pCharset != NULL) && aimai_flg) { |
| |
| for (l = 0; l < pCharset->charset_count; l++) { |
| |
| if (nj_charncmp(yomi, pCharset->from[l], 1) == 0) { |
| |
| nj_strcpy(char_tmp, pCharset->to[l]); |
| tmp_len = nj_strlen(char_tmp); |
| ret = search_range_by_yomi(iwnn, loctset->loct.handle, search_pattern, |
| char_tmp, tmp_len, &from, &to, &forward_flag); |
| if (ret < 0) { |
| |
| |
| psrhCache->keyPtr[j+1] = abIdx; |
| loctset->loct.status = NJ_ST_SEARCH_END; |
| return ret; |
| } else if (ret > 0) { |
| |
| |
| if (abIdx >= NJ_SEARCH_CACHE_SIZE) { |
| psrhCache->keyPtr[j+1] = 0; |
| return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_CACHE_NOT_ENOUGH); |
| } |
| psrhCache->storebuff[abIdx].top = from; |
| psrhCache->storebuff[abIdx].bottom = to; |
| psrhCache->storebuff[abIdx].idx_no = (NJ_INT8)tmp_len; |
| if (addcnt == 0) { |
| psrhCache->keyPtr[j] = abIdx; |
| } |
| abIdx++; |
| addcnt++; |
| psrhCache->keyPtr[j+1] = abIdx; |
| } else { |
| psrhCache->keyPtr[j+1] = abIdx; |
| } |
| } |
| } |
| } |
| } else { |
| |
| if (psrhCache->keyPtr[j] == psrhCache->keyPtr[j-1]) { |
| |
| psrhCache->keyPtr[j+1] = psrhCache->keyPtr[j-1]; |
| endflg = 0x01; |
| } else { |
| |
| endIdx = psrhCache->keyPtr[j]; |
| abIdx_old = psrhCache->keyPtr[j-1]; |
| |
| if (NJ_GET_CACHEOVER_FROM_SCACHE(psrhCache)) { |
| abIdx = psrhCache->keyPtr[j - 1]; |
| psrhCache->keyPtr[j] = abIdx; |
| } else { |
| abIdx = psrhCache->keyPtr[j]; |
| } |
| addcnt = 0; |
| |
| if ((abIdx > NJ_SEARCH_CACHE_SIZE) || (abIdx_old >= NJ_SEARCH_CACHE_SIZE) || |
| (endIdx > NJ_SEARCH_CACHE_SIZE)) { |
| |
| return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_CACHE_BROKEN); |
| } |
| for (m = abIdx_old; m < endIdx; m++) { |
| |
| p = ptr + (psrhCache->storebuff[m].top * NJ_INDEX_SIZE); |
| que_id = GET_UINT16(p); |
| |
| |
| str = get_string(iwnn, loctset->loct.handle, que_id, &slen); |
| |
| if (str == NULL) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_DIC_BROKEN); |
| } |
| |
| |
| nj_strncpy(char_tmp, str, psrhCache->storebuff[m].idx_no); |
| char_tmp[psrhCache->storebuff[m].idx_no] = NJ_CHAR_NUL; |
| |
| pchar_tmp = &char_tmp[psrhCache->storebuff[m].idx_no]; |
| nj_charncpy(pchar_tmp, yomi, 1); |
| tmp_len = nj_strlen(char_tmp); |
| |
| |
| ret = search_range_by_yomi2(iwnn, loctset->loct.handle, search_pattern, |
| char_tmp, tmp_len, |
| (NJ_UINT16)(psrhCache->storebuff[m].top), |
| (NJ_UINT16)(psrhCache->storebuff[m].bottom), |
| &from, &to, &forward_flag); |
| if (ret < 0) { |
| |
| |
| psrhCache->keyPtr[j+1] = abIdx; |
| loctset->loct.status = NJ_ST_SEARCH_END; |
| return ret; |
| } else if (ret > 0) { |
| |
| |
| if (abIdx >= NJ_SEARCH_CACHE_SIZE) { |
| psrhCache->keyPtr[j+1] = 0; |
| return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_CACHE_NOT_ENOUGH); |
| } |
| psrhCache->storebuff[abIdx].top = from; |
| psrhCache->storebuff[abIdx].bottom = to; |
| psrhCache->storebuff[abIdx].idx_no = (NJ_INT8)tmp_len; |
| if (addcnt == 0) { |
| psrhCache->keyPtr[j] = abIdx; |
| } |
| abIdx++; |
| addcnt++; |
| psrhCache->keyPtr[j+1] = abIdx; |
| } else { |
| psrhCache->keyPtr[j+1] = abIdx; |
| } |
| |
| if ((!endflg) && (pCharset != NULL) && aimai_flg) { |
| |
| for (l = 0; l < pCharset->charset_count; l++) { |
| |
| if (nj_charncmp(yomi, pCharset->from[l], 1) == 0) { |
| |
| tmp_len = nj_strlen(pCharset->to[l]); |
| |
| nj_strncpy(pchar_tmp, pCharset->to[l], tmp_len); |
| *(pchar_tmp + tmp_len) = NJ_CHAR_NUL; |
| tmp_len = nj_strlen(char_tmp); |
| ret = search_range_by_yomi2(iwnn, loctset->loct.handle, search_pattern, |
| char_tmp, tmp_len, |
| (NJ_UINT16)(psrhCache->storebuff[m].top), |
| (NJ_UINT16)(psrhCache->storebuff[m].bottom), |
| &from, &to, &forward_flag); |
| if (ret < 0) { |
| |
| |
| psrhCache->keyPtr[j+1] = abIdx; |
| loctset->loct.status = NJ_ST_SEARCH_END; |
| return ret; |
| } else if (ret > 0) { |
| |
| |
| if (abIdx >= NJ_SEARCH_CACHE_SIZE) { |
| psrhCache->keyPtr[j+1] = 0; |
| return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_CACHE_NOT_ENOUGH); |
| } |
| psrhCache->storebuff[abIdx].top = from; |
| psrhCache->storebuff[abIdx].bottom = to; |
| psrhCache->storebuff[abIdx].idx_no = (NJ_INT8)tmp_len; |
| abIdx++; |
| addcnt++; |
| psrhCache->keyPtr[j+1] = abIdx; |
| } else { |
| psrhCache->keyPtr[j+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; |
| } |
| } else if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_READY) { |
| current = GET_UINT16(ptr + (loctset->loct.current * NJ_INDEX_SIZE)); |
| if (current < oldest) { |
| current += GET_LEARN_MAX_WORD_COUNT(loctset->loct.handle); |
| } |
| } else { |
| loctset->loct.status = NJ_ST_SEARCH_END; |
| return 0; |
| } |
| |
| |
| j = cond->yclen - 1; |
| |
| abIdx = psrhCache->keyPtr[j]; |
| abIdx_old = psrhCache->keyPtr[j+1]; |
| |
| endIdx = abIdx_old; |
| if ((abIdx >= NJ_SEARCH_CACHE_SIZE) || (abIdx_old > NJ_SEARCH_CACHE_SIZE)) { |
| |
| return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_CACHE_BROKEN); |
| } |
| p = ptr + (psrhCache->storebuff[abIdx].top * NJ_INDEX_SIZE); |
| que_id = GET_UINT16(p); |
| eval = current; |
| |
| |
| |
| if (psrhCache->keyPtr[j] < psrhCache->keyPtr[j + 1]) { |
| if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_NO_INIT) { |
| endIdx = abIdx + 1; |
| NJ_SET_AIMAI_TO_SCACHE(psrhCache); |
| } |
| |
| for (m = abIdx; m < endIdx; m++) { |
| p = ptr + (psrhCache->storebuff[m].top * NJ_INDEX_SIZE); |
| que_id = GET_UINT16(p); |
| eval = current; |
| |
| for (i = (NJ_UINT16)psrhCache->storebuff[m].top; i <= (NJ_UINT16)psrhCache->storebuff[m].bottom; i++) { |
| que_id = GET_UINT16(p); |
| if (que_id < oldest) { |
| eval = que_id + GET_LEARN_MAX_WORD_COUNT(loctset->loct.handle); |
| } else { |
| eval = que_id; |
| } |
| #ifdef LEARN_DEBUG |
| printf("que(%d) : eval = %d : %d\n", que_id, eval, i); |
| #endif |
| if (eval >= max_value) { |
| if ((GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_NO_INIT) |
| || ((GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_READY) |
| && (NJ_GET_AIMAI_FROM_SCACHE(psrhCache))) |
| || (eval < current)) { |
| |
| |
| |
| str = get_string(iwnn, loctset->loct.handle, que_id, &slen); |
| if (str == NULL) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_DIC_BROKEN); |
| } |
| |
| |
| |
| que = get_que_allHinsi(iwnn, loctset->loct.handle, que_id); |
| if (njd_connect_test(cond, que->mae_hinsi, que->ato_hinsi)) { |
| |
| loctset->loct.current_info = (NJ_UINT8)0x10; |
| loctset->loct.current = i; |
| max_value = eval; |
| found = 1; |
| #ifdef LEARN_DEBUG |
| printf("---keep."); |
| #endif |
| } |
| } |
| } |
| p += NJ_INDEX_SIZE; |
| } |
| } |
| } |
| |
| if (GET_LOCATION_STATUS(loctset->loct.status) != NJ_ST_SEARCH_NO_INIT) { |
| NJ_UNSET_AIMAI_TO_SCACHE(psrhCache); |
| } |
| |
| |
| if (found == 0) { |
| loctset->loct.status = NJ_ST_SEARCH_END; |
| return 0; |
| } else { |
| loctset->loct.status = NJ_ST_SEARCH_READY; |
| loctset->cache_freq = get_hindo(iwnn, loctset, search_pattern); |
| return 1; |
| } |
| } |
| |
| static NJ_INT16 search_range_by_yomi2(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT8 op, |
| NJ_CHAR *yomi, NJ_UINT16 len, |
| NJ_UINT16 sfrom, NJ_UINT16 sto, |
| NJ_UINT16 *from, NJ_UINT16 *to, |
| NJ_UINT8 *forward_flag) { |
| NJ_UINT16 right, mid = 0, left, max; |
| NJ_UINT16 que_id; |
| NJ_UINT8 *ptr, *p; |
| NJ_CHAR *str; |
| NJ_INT16 ret = 0; |
| NJ_INT32 found = 0; |
| NJ_UINT8 slen; |
| NJ_INT32 cmp; |
| |
| |
| |
| ptr = get_search_index_address(handle, op); |
| |
| max = GET_LEARN_WORD_COUNT(handle); |
| |
| right = sto; |
| left = sfrom; |
| |
| #ifdef LEARN_DEBUG |
| printf("src:[%s]\n", yomi); |
| #endif |
| |
| *forward_flag = 0; |
| |
| while (left <= right) { |
| mid = left + ((right - left) / 2); |
| p = ptr + (mid * NJ_INDEX_SIZE); |
| que_id = GET_UINT16(p); |
| str = get_string(iwnn, handle, que_id, &slen); |
| if (str == NULL) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_DIC_BROKEN); |
| } |
| |
| |
| ret = nj_strncmp(yomi, str, len); |
| |
| #ifdef LEARN_DEBUG |
| printf(" [%d][%d][%d]COMPARE:[%s] = %d\n", left, mid, right, str, ret); |
| #endif |
| if (ret == 0) { |
| |
| found = 1; |
| break; |
| } else if (ret < 0) { |
| |
| right = mid - 1; |
| if (mid == 0) { |
| break; |
| } |
| } else { |
| |
| left = mid + 1; |
| } |
| } |
| |
| if (!found) { |
| return 0; |
| } |
| |
| if (mid == 0) { |
| *from = mid; |
| } else { |
| |
| p = ((mid - 1) * NJ_INDEX_SIZE) + ptr; |
| |
| for (cmp = mid - 1; cmp >= 0; cmp--) { |
| que_id = GET_UINT16(p); |
| str = get_string(iwnn, handle, que_id, &slen); |
| if (str == NULL) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_DIC_BROKEN); |
| } |
| |
| |
| if (nj_strncmp(yomi, str, len) != 0) { |
| break; |
| } |
| p -= NJ_INDEX_SIZE; |
| } |
| if (cmp < 0) { |
| *from = 0; |
| } else { |
| *from = (NJ_UINT16)cmp + 1; |
| } |
| } |
| |
| #ifdef LEARN_DEBUG |
| printf(" >> from:(%d)\n", *from); |
| #endif |
| |
| if ((mid + 1) >= max) { |
| *to = mid; |
| } else { |
| |
| p = ((mid + 1) * NJ_INDEX_SIZE) + ptr; |
| |
| for (right = mid + 1; right < max; right++) { |
| que_id = GET_UINT16(p); |
| str = get_string(iwnn, handle, que_id, &slen); |
| if (str == NULL) { |
| return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_RANGE_BY_YOMI, NJ_ERR_DIC_BROKEN); |
| } |
| |
| |
| if (nj_strncmp(yomi, str, len) != 0) { |
| break; |
| } |
| p += NJ_INDEX_SIZE; |
| } |
| *to = right - 1; |
| } |
| |
| #ifdef LEARN_DEBUG |
| printf(" >> to:(%d)\n", *to); |
| #endif |
| return 1; |
| } |
| |