diff options
Diffstat (limited to 'src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine')
9 files changed, 7267 insertions, 0 deletions
diff --git a/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/ndapi.c b/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/ndapi.c new file mode 100644 index 00000000..55971c69 --- /dev/null +++ b/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/ndapi.c @@ -0,0 +1,906 @@ +/* + * 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 NJ_DIC_UNCOMP_EXT_HEADER_SIZE 0x002C +#define CREATE_DIC_TYPE_USER 0 + +#define GET_HYOKI_INDEX_OFFSET(cnt) \ + (NJ_LEARN_DIC_HEADER_SIZE + NJ_INDEX_SIZE * ((cnt)+1)) + +#define GET_DATA_AREA_OFFSET(cnt) \ + (NJ_LEARN_DIC_HEADER_SIZE + NJ_INDEX_SIZE * ((cnt)+1) * 2) +#define GET_EXT_DATA_AREA_OFFSET(cnt) \ + (NJ_LEARN_DIC_HEADER_SIZE + NJ_INDEX_SIZE * ((cnt)+1) * 2 + LEARN_DIC_QUE_SIZE * (cnt)) + +#define MIN_SIZE_OF_USER_DIC \ + (NJ_LEARN_DIC_HEADER_SIZE + NJ_USER_QUE_SIZE + 2 * (NJ_INDEX_SIZE * (1+1)) + 4) +#define GET_MAX_WORD_NUM_IN_USER_DIC(size) \ + (((size) - NJ_LEARN_DIC_HEADER_SIZE - (2 * NJ_INDEX_SIZE) - 4) \ + / (NJ_USER_QUE_SIZE + 2 * NJ_INDEX_SIZE)) + + +static NJ_INT16 check_search_cursor(NJ_CLASS *iwnn, NJ_CURSOR *cursor); +static NJ_INT16 search_word(NJ_CLASS *iwnn, NJ_CURSOR *cursor, NJ_UINT8 comp_flg, NJ_UINT8 *exit_flag); +static void set_operation_id(NJ_SEARCH_LOCATION *dicinfo, NJ_UINT8 reverse, NJ_RESULT *result); +static NJ_INT16 get_word_and_search_next_word(NJ_CLASS *iwnn, NJ_CURSOR *cursor, NJ_RESULT *result, NJ_UINT8 comp_flg); + +static NJ_INT16 njd_check_dic(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle); + +static NJ_INT16 check_search_cursor(NJ_CLASS *iwnn, NJ_CURSOR *cursor) { + NJ_UINT16 i; + NJ_DIC_INFO *dicinfo; + NJ_SEARCH_LOCATION_SET *loctset; + + + if (cursor->cond.ds == NULL) { + return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_PARAM_DIC_NULL); + } + + + for (i = 0; i < NJ_MAX_DIC; i++) { + loctset = &(cursor->loctset[i]); + dicinfo = &(cursor->cond.ds->dic[i]); + + + njd_init_search_location_set(loctset); + + if (dicinfo->handle != NULL) { + + + + if ( + (dicinfo->dic_freq[NJ_MODE_TYPE_HENKAN].high > DIC_FREQ_HIGH) ) { + return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_DIC_FREQ_INVALID); + } + + + loctset->loct.handle = dicinfo->handle; + loctset->loct.type = dicinfo->type; + loctset->loct.current_info = 0x10; + loctset->loct.status = NJ_ST_SEARCH_NO_INIT; + loctset->dic_freq = dicinfo->dic_freq[NJ_MODE_TYPE_HENKAN]; + } + } + + if (cursor->cond.yomi == NULL) { + + return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_PARAM_YOMI_NULL); + } + + if (cursor->cond.ylen > NJ_MAX_LEN) { + + return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_YOMI_TOO_LONG); + } + + if (cursor->cond.operation == NJ_CUR_OP_LINK) { + + } else if (cursor->cond.kanji != NULL) { + + if (nj_strlen(cursor->cond.kanji) > NJ_MAX_RESULT_LEN) { + return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_CANDIDATE_TOO_LONG); + } + } + + switch (cursor->cond.operation) { + case NJ_CUR_OP_COMP: + case NJ_CUR_OP_FORE: + case NJ_CUR_OP_LINK: + break; + default: + return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_PARAM_OPERATION); + } + + switch (cursor->cond.mode) { + case NJ_CUR_MODE_FREQ: + case NJ_CUR_MODE_YOMI: + break; + default: + return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_PARAM_MODE); + } + + return 0; +} + +static NJ_INT16 search_word(NJ_CLASS *iwnn, NJ_CURSOR *cursor, NJ_UINT8 comp_flg, + NJ_UINT8 *exit_flag) { + NJ_UINT32 dic_type; + NJ_INT16 i; + NJ_INT16 ret = 0; + NJ_INT16 flag = 0; + NJ_SEARCH_LOCATION_SET *loctset; + + + *exit_flag = 1; + for (i = 0; i < NJ_MAX_DIC; i++) { + loctset = &(cursor->loctset[i]); + + if (loctset->loct.handle == NULL) { + continue; + } + + dic_type = NJ_GET_DIC_TYPE_EX(loctset->loct.type, loctset->loct.handle); +#ifdef IWNN_ERR_CHECK + if (iwnn->err_check_flg == 12) { + dic_type = 0x11111111; + } +#endif + switch (dic_type) { + case NJ_DIC_TYPE_JIRITSU: + case NJ_DIC_TYPE_FZK: + case NJ_DIC_TYPE_TANKANJI: + case NJ_DIC_TYPE_STDFORE: + case NJ_DIC_TYPE_CUSTOM_COMPRESS: + case NJ_DIC_TYPE_FORECONV: + ret = njd_b_search_word(&cursor->cond, loctset); + break; + case NJ_DIC_TYPE_USER: + case NJ_DIC_TYPE_CUSTOM_INCOMPRESS: + ret = njd_l_search_word(iwnn, &cursor->cond, loctset, comp_flg); + break; + + case NJ_DIC_TYPE_YOMINASHI: + ret = njd_f_search_word(&cursor->cond, loctset); + break; + + default: + return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_WORD, NJ_ERR_DIC_TYPE_INVALID); + } + if (ret < 0) { + return ret; + } + if (ret == 0) { + if ((GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_END) + && (*exit_flag == 1)) { + *exit_flag = 0; + } + + loctset->loct.status = NJ_ST_SEARCH_END; + + } else { + flag = 1; + *exit_flag = 0; + } + } + return flag; +} + +static NJ_INT16 get_word_and_search_next_word(NJ_CLASS *iwnn, NJ_CURSOR *cursor, NJ_RESULT *result, + NJ_UINT8 comp_flg) { + NJ_INT16 ret = -1; + NJ_INT32 i, next, first; + NJ_WORD tmp_word; + NJ_RESULT tmp_result; + NJ_CHAR tmp_stroke[NJ_MAX_LEN + NJ_TERM_LEN]; + NJ_CHAR result_stroke[NJ_MAX_LEN + NJ_TERM_LEN]; + NJ_INT32 j, max_len = 0; + NJ_UINT32 dic_type; + NJ_SEARCH_LOCATION_SET *loctset; + + + next = -1; + first= 0; + + njd_init_word(&tmp_word); + + result->word = tmp_word; + tmp_result.word = tmp_word; + + for (i = 0; i < NJ_MAX_DIC; i++) { + loctset = &(cursor->loctset[i]); + if ((loctset->loct.handle == NULL) || + (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_END) || + (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_END_EXT)) { + continue; + } + + dic_type = NJ_GET_DIC_TYPE_EX(loctset->loct.type, loctset->loct.handle); + + switch (dic_type) { + case NJ_DIC_TYPE_JIRITSU: + case NJ_DIC_TYPE_FZK: + case NJ_DIC_TYPE_TANKANJI: + case NJ_DIC_TYPE_STDFORE: + case NJ_DIC_TYPE_CUSTOM_COMPRESS: + case NJ_DIC_TYPE_FORECONV: + tmp_word.yomi = cursor->cond.yomi; + tmp_word.stem.info1 = cursor->cond.ylen; + tmp_result.word.yomi = cursor->cond.yomi; + tmp_result.word.stem.info1 = cursor->cond.ylen; + break; + default: + break; + } + + loctset->loct.status |= SET_LOCATION_OPERATION(cursor->cond.operation); + if (cursor->cond.mode == NJ_CUR_MODE_FREQ) { + if ((cursor->cond.ds->mode & (NJ_CACHE_MODE_VALID)) && + (cursor->cond.ds->dic[i].srhCache != NULL) && + (NJ_GET_AIMAI_FROM_SCACHE(cursor->cond.ds->dic[i].srhCache)) && + (cursor->cond.operation == NJ_CUR_OP_FORE)) { + first = 1; + + ret = njd_get_word_data(iwnn, cursor->cond.ds, loctset, (NJ_UINT16)i, &tmp_result.word); + if (ret < 0) { + return ret; + } + + ret = njd_get_stroke(iwnn, &tmp_result, tmp_stroke, sizeof(tmp_stroke)); + if (ret <= 0) { + if ((ret == 0) || (NJ_GET_ERR_CODE(ret) == NJ_ERR_BUFFER_NOT_ENOUGH)) { + return NJ_SET_ERR_VAL(NJ_FUNC_GET_WORD_AND_SEARCH_NEXT_WORD, NJ_ERR_INVALID_RESULT); + } else { + return ret; + } + } + for (j = 0; j < cursor->cond.ylen; j++) { + if (cursor->cond.yomi[j] != tmp_stroke[j]) { + break; + } + } + + switch (dic_type) { + case NJ_DIC_TYPE_JIRITSU: + case NJ_DIC_TYPE_FZK: + case NJ_DIC_TYPE_TANKANJI: + case NJ_DIC_TYPE_STDFORE: + case NJ_DIC_TYPE_CUSTOM_COMPRESS: + case NJ_DIC_TYPE_FORECONV: + ret = njd_b_search_word(&cursor->cond, loctset); + break; + + case NJ_DIC_TYPE_USER: + case NJ_DIC_TYPE_CUSTOM_INCOMPRESS: + ret = njd_l_search_word(iwnn, &cursor->cond, loctset, comp_flg); + break; + + default: + return NJ_SET_ERR_VAL(NJ_FUNC_GET_WORD_AND_SEARCH_NEXT_WORD, NJ_ERR_DIC_TYPE_INVALID); + } + + if (ret < 0) { + return ret; + } + } else { + ret = njd_get_word_data(iwnn, cursor->cond.ds, loctset, (NJ_UINT16)i, &tmp_result.word); + if (ret < 0) { + return ret; + } + j = cursor->cond.ylen; + } + + if ((j > max_len) || + ((j == max_len) && (loctset->cache_freq > result->word.stem.hindo)) || + (next == -1)) { + + set_operation_id(&(loctset->loct), 0, result); + + result->word = tmp_result.word; + + next = i; + max_len = j; + } + + } else { + + ret = njd_get_word_data(iwnn, cursor->cond.ds, loctset, (NJ_UINT16)i, &(tmp_result.word)); + if (ret < 0) { + return ret; + } + + + ret = njd_get_stroke(iwnn, &tmp_result, tmp_stroke, sizeof(tmp_stroke)); + if (ret <= 0) { + if ((ret == 0) || (NJ_GET_ERR_CODE(ret) == NJ_ERR_BUFFER_NOT_ENOUGH)) { + return NJ_SET_ERR_VAL(NJ_FUNC_GET_WORD_AND_SEARCH_NEXT_WORD, NJ_ERR_INVALID_RESULT); + } else { + return ret; + } + } + if ((next == -1) || (nj_strcmp(result_stroke, tmp_stroke) > 0)) { + + set_operation_id(&(loctset->loct), 0, result); + + result->word = tmp_result.word; + + next = i; + nj_strcpy(result_stroke, tmp_stroke); + } + } + } + + + if (next == -1) { + return 0; + } + + loctset = &(cursor->loctset[next]); + if ((!first) || + ((loctset->loct.handle != NULL) && + (cursor->cond.ds->dic[next].srhCache == NULL))) { + dic_type = NJ_GET_DIC_TYPE_EX(loctset->loct.type, loctset->loct.handle); + + + switch (dic_type) { + case NJ_DIC_TYPE_JIRITSU: + case NJ_DIC_TYPE_FZK: + case NJ_DIC_TYPE_TANKANJI: + case NJ_DIC_TYPE_STDFORE: + case NJ_DIC_TYPE_CUSTOM_COMPRESS: + case NJ_DIC_TYPE_FORECONV: + ret = njd_b_search_word(&cursor->cond, loctset); + break; + + case NJ_DIC_TYPE_USER: + case NJ_DIC_TYPE_CUSTOM_INCOMPRESS: + ret = njd_l_search_word(iwnn, &cursor->cond, loctset, comp_flg); + break; + + case NJ_DIC_TYPE_YOMINASHI: + ret = njd_f_search_word(&cursor->cond, loctset); + break; + + default: + return NJ_SET_ERR_VAL(NJ_FUNC_GET_WORD_AND_SEARCH_NEXT_WORD, NJ_ERR_DIC_TYPE_INVALID); + } + } + + if (ret < 0) { + return ret; + } + return 1; +} + +NJ_INT16 njd_get_word_data(NJ_CLASS *iwnn, NJ_DIC_SET *dicset, NJ_SEARCH_LOCATION_SET *loctset, NJ_UINT16 dic_idx, NJ_WORD *word) { + NJ_INT16 ret = 0; + NJ_UINT32 dic_type; + + + + if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_END) { + return 0; + } + + if (loctset->loct.handle == NULL) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_GET_WORD_DATA, NJ_ERR_DIC_TYPE_INVALID); + } + + dic_type = NJ_GET_DIC_TYPE_EX(loctset->loct.type, loctset->loct.handle); + + switch (dic_type) { + case NJ_DIC_TYPE_JIRITSU: + case NJ_DIC_TYPE_FZK: + case NJ_DIC_TYPE_TANKANJI: + case NJ_DIC_TYPE_STDFORE: + case NJ_DIC_TYPE_CUSTOM_COMPRESS: + case NJ_DIC_TYPE_FORECONV: + ret = njd_b_get_word(loctset, word); + break; + + case NJ_DIC_TYPE_USER: + case NJ_DIC_TYPE_CUSTOM_INCOMPRESS: + ret = njd_l_get_word(iwnn, loctset, word); + break; + + case NJ_DIC_TYPE_YOMINASHI: + ret = njd_f_get_word(loctset, word); + break; + + default: + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_GET_WORD_DATA, NJ_ERR_DIC_TYPE_INVALID); + } + return ret; +} + +static void set_operation_id(NJ_SEARCH_LOCATION *dicinfo, NJ_UINT8 reverse, NJ_RESULT *result) { + NJ_UINT16 dictype; + NJ_UINT32 type; + + if (dicinfo->handle == NULL) { + + dictype = NJ_DIC_STATIC; + return; + } + + type = NJ_GET_DIC_TYPE_EX(NJ_GET_DIC_INFO(dicinfo), dicinfo->handle); + + + switch (type) { + case NJ_DIC_TYPE_JIRITSU: + case NJ_DIC_TYPE_FZK: + case NJ_DIC_TYPE_TANKANJI: + case NJ_DIC_TYPE_STDFORE: + case NJ_DIC_TYPE_YOMINASHI: + + case NJ_DIC_TYPE_FORECONV: + dictype = NJ_DIC_STATIC; + break; + + case NJ_DIC_TYPE_CUSTOM_INCOMPRESS: + case NJ_DIC_TYPE_CUSTOM_COMPRESS: + dictype = NJ_DIC_CUSTOMIZE; + break; + + case NJ_DIC_TYPE_USER: + dictype = NJ_DIC_USER; + break; + + default: + + dictype = NJ_DIC_STATIC; + } + + + result->operation_id = + (NJ_UINT16)((NJ_UINT16)NJ_OP_SEARCH | (NJ_UINT16)NJ_FUNC_SEARCH | dictype); +} + +static NJ_INT16 njd_search_word(NJ_CLASS *iwnn, NJ_CURSOR *cursor, NJ_UINT8 comp_flg, + NJ_UINT8 *exit_flag) { + NJ_INT16 ret; + + + ret = check_search_cursor(iwnn, cursor); + if (ret != 0) { + return ret; + } + + return search_word(iwnn, cursor, comp_flg, exit_flag); +} + +static NJ_INT16 njd_get_word(NJ_CLASS *iwnn, NJ_CURSOR *cursor, NJ_RESULT *result, + NJ_UINT8 comp_flg) { + + NJ_INT16 ret; + + + ret = get_word_and_search_next_word(iwnn, cursor, result, comp_flg); + + return ret; +} + +NJ_INT16 njd_get_stroke(NJ_CLASS *iwnn, NJ_RESULT *result, NJ_CHAR *stroke, NJ_UINT16 size) { + NJ_INT16 ret = 0; + NJ_UINT16 len; + NJ_UINT32 dictype; + + + if (result->word.stem.loc.handle == NULL) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_GET_STROKE, NJ_ERR_INVALID_RESULT); + } + + dictype = NJ_GET_DIC_TYPE_EX(result->word.stem.loc.type, result->word.stem.loc.handle); + + switch (dictype) { + case NJ_DIC_TYPE_JIRITSU: + case NJ_DIC_TYPE_FZK: + case NJ_DIC_TYPE_TANKANJI: + case NJ_DIC_TYPE_STDFORE: + case NJ_DIC_TYPE_CUSTOM_COMPRESS: + case NJ_DIC_TYPE_FORECONV: + if (GET_LOCATION_OPERATION(result->word.stem.loc.status) != NJ_CUR_OP_COMP) { + ret = njd_b_get_stroke(&result->word, stroke, size); + } else { + len = NJ_GET_YLEN_FROM_STEM(&result->word); + + if (size < ((len + NJ_TERM_LEN) * sizeof(NJ_CHAR))) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_GET_STROKE, + NJ_ERR_BUFFER_NOT_ENOUGH); + } + if (len == 0) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_GET_STROKE, + NJ_ERR_INVALID_RESULT); + } + nj_strncpy(stroke, result->word.yomi, len); + *(stroke + len) = NJ_CHAR_NUL; + return len; + } + break; + + case NJ_DIC_TYPE_USER: + case NJ_DIC_TYPE_CUSTOM_INCOMPRESS: + ret = njd_l_get_stroke(iwnn, &result->word, stroke, size); + break; + + case NJ_DIC_TYPE_YOMINASHI: + ret = njd_f_get_stroke(&result->word, stroke, size); + break; + + default: + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_GET_STROKE, NJ_ERR_DIC_TYPE_INVALID); + } + + if (ret == 0) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_GET_STROKE, NJ_ERR_INVALID_RESULT); + } + return ret; +} + + +NJ_INT16 njd_get_candidate(NJ_CLASS *iwnn, NJ_RESULT *result, + NJ_CHAR *candidate, NJ_UINT16 size) { + NJ_INT16 ret = 0; + NJ_UINT32 dictype; + + + if (result->word.stem.loc.handle == NULL) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_GET_CANDIDATE, NJ_ERR_INVALID_RESULT); + } + + dictype = NJ_GET_DIC_TYPE_EX(result->word.stem.loc.type, result->word.stem.loc.handle); + + switch (dictype) { + case NJ_DIC_TYPE_JIRITSU: + case NJ_DIC_TYPE_FZK: + case NJ_DIC_TYPE_TANKANJI: + case NJ_DIC_TYPE_STDFORE: + case NJ_DIC_TYPE_CUSTOM_COMPRESS: + case NJ_DIC_TYPE_FORECONV: + ret = njd_b_get_candidate(&result->word, candidate, size); + break; + + case NJ_DIC_TYPE_USER: + case NJ_DIC_TYPE_CUSTOM_INCOMPRESS: + ret = njd_l_get_candidate(iwnn, &result->word, candidate, size); + break; + + case NJ_DIC_TYPE_YOMINASHI: + ret = njd_f_get_candidate(&result->word, candidate, size); + break; + + default: + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_GET_CANDIDATE, NJ_ERR_DIC_TYPE_INVALID); + } + + if (ret == 0) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_GET_CANDIDATE, NJ_ERR_INVALID_RESULT); + } + return ret; +} + + +static NJ_INT16 njd_check_dic(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle) { + NJ_UINT8 *addr; + NJ_UINT32 datasize, extsize; + NJ_UINT32 version; + NJ_UINT32 type; + + + addr = handle; + + + if (NJ_INT32_READ(addr) != NJ_DIC_IDENTIFIER) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_CHECK_DIC, NJ_ERR_FORMAT_INVALID); + } + addr += sizeof(NJ_UINT32); + + + version = NJ_INT32_READ(addr); + if ((version != NJ_DIC_VERSION1) && (version != NJ_DIC_VERSION2) && + (version != NJ_DIC_VERSION2_1) && (version != NJ_DIC_VERSION3)) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_CHECK_DIC, NJ_ERR_FORMAT_INVALID); + } + addr += sizeof(NJ_UINT32); + + + type = NJ_INT32_READ(addr); + addr += sizeof(NJ_UINT32); + + + datasize = NJ_INT32_READ(addr); + addr += sizeof(NJ_UINT32); + + + extsize = NJ_INT32_READ(addr); + addr += sizeof(NJ_UINT32); + + + if (NJ_INT32_READ(addr) > (NJ_MAX_LEN * sizeof(NJ_CHAR))) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_CHECK_DIC, NJ_ERR_FORMAT_INVALID); + } + addr += sizeof(NJ_UINT32); + + + if (NJ_INT32_READ(addr) > (NJ_MAX_RESULT_LEN * sizeof(NJ_CHAR))) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_CHECK_DIC, NJ_ERR_FORMAT_INVALID); + } + + + addr += (extsize + datasize); + if (NJ_INT32_READ(addr) != NJ_DIC_IDENTIFIER) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_CHECK_DIC, NJ_ERR_FORMAT_INVALID); + } + + + switch (type) { + + case NJ_DIC_TYPE_JIRITSU: + case NJ_DIC_TYPE_FZK: + case NJ_DIC_TYPE_TANKANJI: + case NJ_DIC_TYPE_CUSTOM_COMPRESS: + case NJ_DIC_TYPE_STDFORE: + + if (version != (NJ_UINT32)NJ_DIC_VERSION2) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_CHECK_DIC, NJ_ERR_FORMAT_INVALID); + } + break; + + case NJ_DIC_TYPE_RULE: + + if (version != (NJ_UINT32)NJ_DIC_VERSION2_1) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_CHECK_DIC, NJ_ERR_FORMAT_INVALID); + } + break; + + case NJ_DIC_TYPE_YOMINASHI: + + if (version != (NJ_UINT32)NJ_DIC_VERSION1) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_CHECK_DIC, NJ_ERR_FORMAT_INVALID); + } + break; + + case NJ_DIC_TYPE_USER: + + if (version != (NJ_UINT32)NJ_DIC_VERSION2) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_CHECK_DIC, NJ_ERR_FORMAT_INVALID); + } + return njd_l_check_dic(iwnn, handle); + + default: + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_CHECK_DIC, NJ_ERR_DIC_TYPE_INVALID); + } + return 0; +} + + +NJ_EXTERN NJ_INT16 njx_search_word(NJ_CLASS *iwnn, NJ_CURSOR *cursor) { + + NJ_SEARCH_CACHE *pCache; + NJ_CHAR *p_yomi, *p_key; + NJ_UINT16 initst, inited; + NJ_UINT16 clrcnt, diccnt; + NJ_UINT16 kw_len; + NJ_UINT16 cacheOverKeyPtr; + + NJ_UINT8 exit_flag; + NJ_UINT8 cnt; + NJ_DIC_HANDLE dhdl; + NJ_PREVIOUS_SELECTION_INFO *prev_info = &(iwnn->previous_selection); + + + if (iwnn == NULL) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJ_SEARCH_WORD, NJ_ERR_PARAM_ENV_NULL); + } + if (cursor == NULL) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJ_SEARCH_WORD, NJ_ERR_PARAM_CURSOR_NULL); + } + + + cursor->cond.hinsi.fore = NULL; + cursor->cond.hinsi.foreSize = 0; + cursor->cond.hinsi.foreFlag = 0; + cursor->cond.hinsi.rear = NULL; + cursor->cond.hinsi.rearSize = 0; + cursor->cond.hinsi.rearFlag = 0; + + + if (cursor->cond.yomi == NULL) { + return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_PARAM_YOMI_NULL); + } + cursor->cond.ylen = nj_strlen(cursor->cond.yomi); + cursor->cond.yclen = nj_charlen(cursor->cond.yomi); + + + if (cursor->cond.ds == NULL) { + return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_PARAM_DIC_NULL); + } + + + cursor->cond.ds->mode = NJ_CACHE_MODE_VALID; + + p_yomi = cursor->cond.yomi; + p_key = cursor->cond.ds->keyword; + + for (clrcnt = 0; clrcnt < cursor->cond.yclen; clrcnt++) { + if (nj_charncmp(p_yomi, p_key, 1) != 0) { + break; + } + p_yomi += NJ_CHAR_LEN(p_yomi); + p_key += NJ_CHAR_LEN(p_key); + } + if (clrcnt != 0) { + initst = clrcnt + 1; + } else { + initst = 0; + } + + kw_len = nj_charlen(cursor->cond.ds->keyword); + if (kw_len >= cursor->cond.yclen) { + inited = kw_len + 1; + } else { + inited = cursor->cond.yclen + 1; + } + + for (diccnt = 0; diccnt < NJ_MAX_DIC; diccnt++) { + pCache = cursor->cond.ds->dic[diccnt].srhCache; + if (pCache != NULL) { + + if (NJ_GET_CACHEOVER_FROM_SCACHE(pCache)) { + + for (cacheOverKeyPtr = 0; cacheOverKeyPtr < kw_len; cacheOverKeyPtr++) { + if (pCache->keyPtr[cacheOverKeyPtr] == pCache->keyPtr[cacheOverKeyPtr + 1] ) { + break; + } + } + cacheOverKeyPtr++; + + + if (cacheOverKeyPtr < initst) { + clrcnt = cacheOverKeyPtr; + } else { + clrcnt = initst; + } + for (; clrcnt < inited; clrcnt++) { + pCache->keyPtr[clrcnt] = 0x0000; + } + + for (clrcnt = 1; clrcnt < inited; clrcnt++ ) { + if ((pCache->keyPtr[clrcnt - 1] > pCache->keyPtr[clrcnt]) && + (pCache->keyPtr[clrcnt] != 0)) { + return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_CACHE_BROKEN); + } + } + NJ_UNSET_CACHEOVER_TO_SCACHE(pCache); + } else { + for (clrcnt = initst; clrcnt < inited; clrcnt++) { + pCache->keyPtr[clrcnt] = 0x0000; + } + + for (clrcnt = 1; clrcnt < inited; clrcnt++ ) { + if ((pCache->keyPtr[clrcnt - 1] > pCache->keyPtr[clrcnt]) && + (pCache->keyPtr[clrcnt] != 0)) { + return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_CACHE_BROKEN); + } + } + } + } + } + + + nj_strcpy(cursor->cond.ds->keyword, cursor->cond.yomi); + + for (cnt = 0; cnt < NJ_MAX_DIC; cnt++) { + dhdl = cursor->cond.ds->dic[cnt].handle; + + if (dhdl != NULL) { + if ((cursor->cond.ds->dic[cnt].dic_freq[NJ_MODE_TYPE_HENKAN].base + > cursor->cond.ds->dic[cnt].dic_freq[NJ_MODE_TYPE_HENKAN].high)) { + return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_DIC_FREQ_INVALID); + } + } + } + + if( prev_info->count == 0 ) { + cursor->cond.hinsi.yominasi_fore = NULL; + } else { + int prev_hinsi = prev_info->selection_data.b_hinsi; + + + njd_r_get_connect(cursor->cond.ds->rHandle[NJ_MODE_TYPE_HENKAN], prev_hinsi, + 0, &(cursor->cond.hinsi.yominasi_fore)); + njd_r_get_count(cursor->cond.ds->rHandle[NJ_MODE_TYPE_HENKAN], + &(cursor->cond.hinsi.foreSize), &(cursor->cond.hinsi.rearSize)); + } + + return njd_search_word(iwnn, cursor, 0, &exit_flag); +} + + +NJ_EXTERN NJ_INT16 njx_get_word(NJ_CLASS *iwnn, NJ_CURSOR *cursor, NJ_RESULT *result) { + NJ_INT16 ret; + + + + if (iwnn == NULL) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJ_GET_WORD, NJ_ERR_PARAM_ENV_NULL); + } + if (cursor == NULL) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJ_GET_WORD, NJ_ERR_PARAM_CURSOR_NULL); + } + if (result == NULL) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJ_GET_WORD, NJ_ERR_PARAM_RESULT_NULL); + } + + ret = njd_get_word(iwnn, cursor, result, 0); + + return ret; +} + + + +NJ_EXTERN NJ_INT16 njx_check_dic(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT8 restore, NJ_UINT32 size) { + + + if (iwnn == NULL) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJ_CHECK_DIC, NJ_ERR_PARAM_ENV_NULL); + } + + if (handle == NULL) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJ_CHECK_DIC, NJ_ERR_DIC_HANDLE_NULL); + } + + + + if (size <= NJ_DIC_COMMON_HEADER_SIZE) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJ_CHECK_DIC, NJ_ERR_AREASIZE_INVALID); + } + + + + if (size != (NJ_DIC_COMMON_HEADER_SIZE + + NJ_INT32_READ(handle + NJ_DIC_POS_DATA_SIZE) + + NJ_INT32_READ(handle + NJ_DIC_POS_EXT_SIZE))) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJ_CHECK_DIC, NJ_ERR_AREASIZE_INVALID); + } + + return njd_check_dic(iwnn, handle); +} + +NJ_INT16 njd_init_search_location_set(NJ_SEARCH_LOCATION_SET* loctset) +{ + + loctset->cache_freq = 0; + loctset->dic_freq.base = 0; + loctset->dic_freq.high = 0; + loctset->loct.type = NJ_DIC_H_TYPE_NORMAL; + loctset->loct.handle = NULL; + loctset->loct.current_info = 0x10; + loctset->loct.current = 0; + loctset->loct.top = 0; + loctset->loct.bottom = 0; + loctset->loct.current_cache = 0; + loctset->loct.status = NJ_ST_SEARCH_NO_INIT; + + return 1; +} + +NJ_INT16 njd_init_word(NJ_WORD* word) +{ + + word->yomi = NULL; + word->stem.info1 = 0; + word->stem.info2 = 0; + word->stem.hindo = 0; + word->fzk.info1 = 0; + word->fzk.info2 = 0; + word->fzk.hindo = 0; + + word->stem.loc.handle = NULL; + word->stem.loc.type = NJ_DIC_H_TYPE_NORMAL; + word->stem.loc.current = 0; + word->stem.loc.top = 0; + word->stem.loc.bottom = 0; + word->stem.loc.current_cache= 0; + word->stem.loc.current_info = 0x10; + word->stem.loc.status = NJ_ST_SEARCH_NO_INIT; + + return 1; +} diff --git a/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/ndbdic.c b/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/ndbdic.c new file mode 100644 index 00000000..6cf73da7 --- /dev/null +++ b/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/ndbdic.c @@ -0,0 +1,2831 @@ +/* + * 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; +} diff --git a/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/ndcommon.c b/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/ndcommon.c new file mode 100644 index 00000000..fc1c25a6 --- /dev/null +++ b/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/ndcommon.c @@ -0,0 +1,80 @@ +/* + * 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" + + + + + +NJ_INT16 njd_connect_test(NJ_SEARCH_CONDITION *con, NJ_UINT16 hinsiF, NJ_UINT16 hinsiR) +{ + + + if (con->hinsi.fore != NULL) { + if (hinsiF == 0) { + return 0; + } + + hinsiF--; + if (hinsiF >= con->hinsi.foreSize) { + return 0; + } + if (*(con->hinsi.fore + (hinsiF / 8)) & (0x80 >> (hinsiF % 8))) { + + if (con->hinsi.foreFlag != 0) { + + return 0; + } + } else { + + if (con->hinsi.foreFlag == 0) { + + return 0; + } + } + } + + + if (con->hinsi.rear != NULL) { + if (hinsiR == 0) { + return 0; + } + + hinsiR--; + if (hinsiR >= con->hinsi.rearSize) { + return 0; + } + if (*(con->hinsi.rear + (hinsiR / 8)) & (0x80 >> (hinsiR % 8))) { + + if (con->hinsi.rearFlag != 0) { + + return 0; + } + } else { + + if (con->hinsi.rearFlag == 0) { + + return 0; + } + } + } + + return 1; +} diff --git a/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/ndfdic.c b/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/ndfdic.c new file mode 100644 index 00000000..1a7c37e2 --- /dev/null +++ b/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/ndfdic.c @@ -0,0 +1,467 @@ +/* + * 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 DATA_SIZE (10) +#define DATA_OFFSET_FHINSI (0) +#define DATA_OFFSET_BHINSI (1) +#define DATA_OFFSET_HINDO (2) +#define DATA_OFFSET_CANDIDATE (3) +#define DATA_OFFSET_CANDIDATE_LEN (5) +#define DATA_OFFSET_YOMI (6) +#define DATA_OFFSET_YOMI_LEN (9) + +#define YOMINASI_DIC_FREQ_DIV 63 + +#define DATA_FHINSI(x) \ + ( (NJ_UINT16)(0x01FF & \ + (((NJ_UINT16)*((x)+DATA_OFFSET_FHINSI ) << 1) | \ + ( *((x)+DATA_OFFSET_FHINSI+1) >> 7))) ) +#define DATA_BHINSI(x) \ + ( (NJ_UINT16)(0x01FF & \ + (((NJ_UINT16)*((x)+DATA_OFFSET_BHINSI ) << 2) | \ + ( *((x)+DATA_OFFSET_BHINSI+1) >> 6))) ) +#define DATA_HINDO(x) \ + ((NJ_HINDO)(0x003F & ((NJ_UINT16)*((x)+DATA_OFFSET_HINDO)))) +#define DATA_CANDIDATE(x) \ + ((NJ_UINT32)(0x000FFFFF & \ + (((NJ_UINT32)*((x)+DATA_OFFSET_CANDIDATE) << 12) | \ + ((NJ_UINT32)*((x)+DATA_OFFSET_CANDIDATE+1) << 4) | \ + ( *((x)+DATA_OFFSET_CANDIDATE+2) >> 4)))) +#define DATA_CANDIDATE_SIZE(x) \ + ((NJ_UINT8)((*((x)+DATA_OFFSET_CANDIDATE_LEN) << 4) | \ + (*((x)+DATA_OFFSET_CANDIDATE_LEN+1) >> 4))) +#define DATA_YOMI(x) \ + ((NJ_UINT32)(0x000FFFFF & \ + (((NJ_UINT32)*((x)+DATA_OFFSET_YOMI) << 16) | \ + ((NJ_UINT32)*((x)+DATA_OFFSET_YOMI+1) << 8) | \ + ( *((x)+DATA_OFFSET_YOMI+2) )))) +#define DATA_YOMI_SIZE(x) \ + ((NJ_UINT8)((*((x)+DATA_OFFSET_YOMI_LEN)))) + +#define YOMI_INDX_TOP_ADDR(h) ((NJ_UINT8*)((h)+NJ_INT32_READ((h)+0x1C))) +#define YOMI_INDX_CNT(h) ((NJ_UINT16)(NJ_INT16_READ((h)+0x20))) +#define YOMI_INDX_BYTE(h) ((NJ_UINT16)(NJ_INT16_READ((h)+0x22))) +#define STEM_AREA_TOP_ADDR(h) ((NJ_UINT8*)((h)+NJ_INT32_READ((h)+0x24))) +#define STRS_AREA_TOP_ADDR(h) ((NJ_UINT8*)((h)+NJ_INT32_READ((h)+0x28))) +#define YOMI_AREA_TOP_ADDR(h) ((NJ_UINT8*)((h)+NJ_INT32_READ((h)+0x2C))) + +#define NO_CONV_FLG ((NJ_UINT32) 0x00080000L) + +#define HINSI_OFFSET (7) + +#define CURRENT_INFO_SET (NJ_UINT8)(0x10) + +static NJ_UINT16 search_data(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset); +static NJ_UINT16 convert_to_yomi(NJ_DIC_HANDLE hdl, NJ_UINT8 *index, NJ_UINT16 len, NJ_CHAR *yomi, NJ_UINT16 size); +static NJ_UINT16 yomi_strcmp_forward(NJ_DIC_HANDLE hdl, NJ_UINT8 *data, NJ_CHAR *yomi); + +static NJ_UINT16 search_data(NJ_SEARCH_CONDITION *condition, NJ_SEARCH_LOCATION_SET *loctset) +{ + NJ_UINT32 offset; + NJ_UINT8 *data; + NJ_UINT16 i, j; + NJ_UINT16 hindo; + NJ_UINT8 hit_flg; + NJ_UINT8 *tmp_hinsi = NULL; + + + offset = loctset->loct.current; + data = STEM_AREA_TOP_ADDR(loctset->loct.handle) + offset; + + if (GET_LOCATION_STATUS(loctset->loct.status) != NJ_ST_SEARCH_NO_INIT) { + data += DATA_SIZE; + offset += DATA_SIZE; + + + if (data >= STRS_AREA_TOP_ADDR(loctset->loct.handle)) { + + loctset->loct.status = NJ_ST_SEARCH_END; + return 0; + } + } + + + tmp_hinsi = condition->hinsi.fore; + condition->hinsi.fore = condition->hinsi.yominasi_fore; + + i = (NJ_UINT16)((STRS_AREA_TOP_ADDR(loctset->loct.handle) - data) / DATA_SIZE); + for (j = 0; j < i; j++) { + + if (njd_connect_test(condition, DATA_FHINSI(data), DATA_BHINSI(data))) { + + hit_flg = 0; + + if (condition->operation == NJ_CUR_OP_LINK) { + + hit_flg = 1; + } else { + + + + if (yomi_strcmp_forward(loctset->loct.handle, data, condition->yomi)) { + + hit_flg = 1; + } + } + + if (hit_flg) { + + loctset->loct.current_info = CURRENT_INFO_SET; + loctset->loct.current = offset; + loctset->loct.status = NJ_ST_SEARCH_READY; + hindo = DATA_HINDO(STEM_AREA_TOP_ADDR(loctset->loct.handle) + loctset->loct.current); + loctset->cache_freq = CALCULATE_HINDO(hindo, loctset->dic_freq.base, + loctset->dic_freq.high, YOMINASI_DIC_FREQ_DIV); + + + condition->hinsi.fore = tmp_hinsi; + return 1; + } + } + + data += DATA_SIZE; + offset += DATA_SIZE; + } + + loctset->loct.status = NJ_ST_SEARCH_END; + + condition->hinsi.fore = tmp_hinsi; + return 0; +} + +static NJ_UINT16 convert_to_yomi(NJ_DIC_HANDLE hdl, NJ_UINT8 *index, NJ_UINT16 len, NJ_CHAR *yomi, NJ_UINT16 size) +{ + NJ_UINT8 *wkc; + NJ_CHAR *wky; + NJ_UINT16 i, idx, yib, ret; + NJ_UINT16 j, char_len; + + + + wkc = YOMI_INDX_TOP_ADDR(hdl); + + + yib = YOMI_INDX_BYTE(hdl); + + + if (NJ_CHAR_ILLEGAL_DIC_YINDEX(yib)) { + + return 0; + } + + + ret = 0; + wky = yomi; + for (i = 0; i < len; i++) { + idx = (NJ_UINT16)((*index - 1) * yib); + if (yib == 2) { + char_len = UTL_CHAR(wkc + idx); + + if (((ret + char_len + NJ_TERM_LEN) * sizeof(NJ_CHAR)) > size) { + return (size / sizeof(NJ_CHAR)); + } + for (j = 0; j < char_len; j++) { + NJ_CHAR_COPY(wky, wkc + idx + j); + wky++; + ret++; + } + } else { + + if (((ret + 1 + NJ_TERM_LEN) * sizeof(NJ_CHAR)) > size) { + return (size / sizeof(NJ_CHAR)); + } + *wky++ = (NJ_CHAR)(*(wkc + idx)); + ret++; + } + index++; + } + *wky = NJ_CHAR_NUL; + return ret; +} + +static NJ_UINT16 yomi_strcmp_forward(NJ_DIC_HANDLE hdl, NJ_UINT8 *data, NJ_CHAR *yomi) +{ + NJ_UINT8 *area; + NJ_CHAR *stroke; + NJ_CHAR buf[NJ_MAX_LEN + NJ_TERM_LEN]; + NJ_UINT16 ylen, dic_ylen, j, size; + + + + size = sizeof(buf); + stroke = buf; + + + area = YOMI_AREA_TOP_ADDR(hdl) + DATA_YOMI(data); + + if (YOMI_INDX_CNT(hdl) == 0) { + + dic_ylen = DATA_YOMI_SIZE(data) / sizeof(NJ_CHAR); + + + if (size < ((dic_ylen + NJ_TERM_LEN) * sizeof(NJ_CHAR))) { + return 0; + } + for (j = 0; j < dic_ylen; j++) { + NJ_CHAR_COPY(stroke, area); + stroke++; + area += sizeof(NJ_CHAR); + } + *stroke = NJ_CHAR_NUL; + } else { + + dic_ylen = convert_to_yomi(hdl, area, DATA_YOMI_SIZE(data), stroke, size); + + + if (size < ((dic_ylen + NJ_TERM_LEN) * sizeof(NJ_CHAR))) { + return 0; + } + } + + + ylen = nj_strlen(yomi); + + + if (dic_ylen < ylen) { + + return 0; + } + + + if (nj_strncmp(yomi, buf, ylen) == 0) { + + return 1; + } + return 0; +} + +NJ_INT16 njd_f_search_word(NJ_SEARCH_CONDITION *con, NJ_SEARCH_LOCATION_SET *loctset) +{ + NJ_UINT16 ret; + + switch (con->operation) { + case NJ_CUR_OP_LINK: + + + if ((con->hinsi.yominasi_fore == NULL) || + (con->hinsi.foreSize == 0)) { + loctset->loct.status = NJ_ST_SEARCH_END; + return 0; + } + break; + case NJ_CUR_OP_FORE: + + + if (NJ_CHAR_STRLEN_IS_0(con->yomi)) { + loctset->loct.status = NJ_ST_SEARCH_END; + return 0; + } + + + if ((con->hinsi.yominasi_fore == NULL) || + (con->hinsi.foreSize == 0)) { + loctset->loct.status = NJ_ST_SEARCH_END; + return 0; + } + break; + default: + + loctset->loct.status = NJ_ST_SEARCH_END; + return 0; + } + + + if (con->mode != NJ_CUR_MODE_FREQ) { + + loctset->loct.status = NJ_ST_SEARCH_END; + return 0; + } + + + if ((GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_NO_INIT) + || (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_READY)) { + + ret = search_data(con, loctset); + if (ret < 1) { + + loctset->loct.status = NJ_ST_SEARCH_END; + } + return ret; + } else { + + loctset->loct.status = NJ_ST_SEARCH_END; + return 0; + } +} + +NJ_INT16 njd_f_get_word(NJ_SEARCH_LOCATION_SET *loctset, NJ_WORD *word) +{ + NJ_UINT8 *data; + NJ_CHAR stroke[NJ_MAX_LEN + NJ_TERM_LEN]; + NJ_INT16 yomilen, kouholen; + + + + if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_END) { + return 0; + } + + + data = STEM_AREA_TOP_ADDR(loctset->loct.handle) + loctset->loct.current; + + NJ_SET_YLEN_TO_STEM(word, 1); + + + word->stem.loc = loctset->loct; + yomilen = njd_f_get_stroke(word, stroke, sizeof(stroke)); + if (yomilen <= 0) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_F_GET_WORD, NJ_ERR_INVALID_RESULT); + } + word->stem.info1 = yomilen; + word->stem.info1 |= (NJ_UINT16)(DATA_FHINSI(data) << HINSI_OFFSET); + word->stem.info2 = (NJ_UINT16)(DATA_BHINSI(data) << HINSI_OFFSET); + kouholen = (NJ_UINT16)DATA_CANDIDATE_SIZE(data)/sizeof(NJ_CHAR); + if (kouholen == 0) { + + kouholen = yomilen; + } + word->stem.info2 |= kouholen; + word->stem.hindo = CALCULATE_HINDO(DATA_HINDO(data), loctset->dic_freq.base, + loctset->dic_freq.high, YOMINASI_DIC_FREQ_DIV); + + + word->stem.type = 0; + + return 1; +} + +NJ_INT16 njd_f_get_stroke(NJ_WORD *word, NJ_CHAR *stroke, NJ_UINT16 size) { + NJ_SEARCH_LOCATION *loc; + NJ_UINT8 *area, *data; + NJ_UINT16 len; + NJ_UINT32 j; + + if (NJ_GET_YLEN_FROM_STEM(word) == 0) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_F_GET_STROKE, NJ_ERR_INVALID_RESULT); + } + + + + loc = &word->stem.loc; + data = STEM_AREA_TOP_ADDR(loc->handle) + loc->current; + + + area = YOMI_AREA_TOP_ADDR(loc->handle) + DATA_YOMI(data); + + if (YOMI_INDX_CNT(loc->handle) == 0) { + + len = DATA_YOMI_SIZE(data)/sizeof(NJ_CHAR); + + + if (size < ((len + NJ_TERM_LEN) * sizeof(NJ_CHAR))) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_F_GET_STROKE, NJ_ERR_BUFFER_NOT_ENOUGH); + } + + for (j = 0; j < len; j++) { + NJ_CHAR_COPY(stroke, area); + stroke++; + area += sizeof(NJ_CHAR); + } + *stroke = NJ_CHAR_NUL; + } else { + + len = convert_to_yomi(loc->handle, area, DATA_YOMI_SIZE(data), stroke, size); + + + if (size < ((len + NJ_TERM_LEN) * sizeof(NJ_CHAR))) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_F_GET_STROKE, NJ_ERR_BUFFER_NOT_ENOUGH); + } + } + return len; +} + +NJ_INT16 njd_f_get_candidate(NJ_WORD *word, NJ_CHAR *candidate, NJ_UINT16 size) +{ + NJ_SEARCH_LOCATION *loc; + NJ_UINT8 *data, *area; + NJ_CHAR work[NJ_MAX_LEN + NJ_TERM_LEN]; + NJ_UINT16 len, j; + + + + + loc = &word->stem.loc; + data = STEM_AREA_TOP_ADDR(loc->handle) + loc->current; + + + len = DATA_CANDIDATE_SIZE(data)/sizeof(NJ_CHAR); + if (size < ((len + NJ_TERM_LEN) * sizeof(NJ_CHAR))) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_F_GET_CANDIDATE, NJ_ERR_BUFFER_NOT_ENOUGH); + } + + + if (len == 0) { + + area = YOMI_AREA_TOP_ADDR(loc->handle) + DATA_YOMI(data); + if (YOMI_INDX_CNT(loc->handle) == 0) { + + len = DATA_YOMI_SIZE(data)/sizeof(NJ_CHAR); + + + if (size < ((len + NJ_TERM_LEN) * sizeof(NJ_CHAR))) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_F_GET_STROKE, NJ_ERR_BUFFER_NOT_ENOUGH); + } + for (j = 0; j < len; j++) { + NJ_CHAR_COPY(candidate + j, area); + area += sizeof(NJ_CHAR); + } + candidate[len] = NJ_CHAR_NUL; + return len; + } else { + + len = convert_to_yomi(loc->handle, area, DATA_YOMI_SIZE(data), work, size); + + + if (size < ((len + NJ_TERM_LEN) * sizeof(NJ_CHAR))) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJD_F_GET_CANDIDATE, NJ_ERR_BUFFER_NOT_ENOUGH); + } + } + + if (DATA_CANDIDATE(data) & NO_CONV_FLG) { + nje_convert_hira_to_kata(work, candidate, len); + } else { + for (j = 0; j < len; j++) { + candidate[j] = work[j]; + } + } + } else { + + area = STRS_AREA_TOP_ADDR(loc->handle) + DATA_CANDIDATE(data); + for (j = 0; j < len; j++) { + NJ_CHAR_COPY(candidate + j, area); + area += sizeof(NJ_CHAR); + } + } + + candidate[len] = NJ_CHAR_NUL; + return len; +} diff --git a/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/ndldic.c b/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/ndldic.c new file mode 100644 index 00000000..d140ea22 --- /dev/null +++ b/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/ndldic.c @@ -0,0 +1,2428 @@ +/* + * 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" +#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), 1000, 0); +} + +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; +} + diff --git a/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/ndrdic.c b/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/ndrdic.c new file mode 100644 index 00000000..b8fe6347 --- /dev/null +++ b/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/ndrdic.c @@ -0,0 +1,122 @@ +/* + * 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 F_HINSI_TOP_ADDR(h) ((NJ_UINT8*)((h)+NJ_INT32_READ((h)+0x20))) +#define B_HINSI_TOP_ADDR(h) ((NJ_UINT8*)((h)+NJ_INT32_READ((h)+0x24))) +#define V2_F_HINSI(h) ((NJ_UINT16)(NJ_INT16_READ((h)+0x28))) +#define BUN_B_HINSI(h) ((NJ_UINT16)(NJ_INT16_READ((h)+0x2A))) +#define TAN_F_HINSI(h) ((NJ_UINT16)(NJ_INT16_READ((h)+0x30))) +#define TAN_B_HINSI(h) ((NJ_UINT16)(NJ_INT16_READ((h)+0x32))) +#define SUUJI_B_HINSI(h) ((NJ_UINT16)(NJ_INT16_READ((h)+0x34))) +#define MEISI_F_HINSI(h) ((NJ_UINT16)(NJ_INT16_READ((h)+0x36))) +#define MEISI_B_HINSI(h) ((NJ_UINT16)(NJ_INT16_READ((h)+0x38))) +#define JINMEI_F_HINSI(h) ((NJ_UINT16)(NJ_INT16_READ((h)+0x3A))) +#define JINMEI_B_HINSI(h) ((NJ_UINT16)(NJ_INT16_READ((h)+0x3C))) +#define CHIMEI_F_HINSI(h) ((NJ_UINT16)(NJ_INT16_READ((h)+0x3E))) +#define CHIMEI_B_HINSI(h) ((NJ_UINT16)(NJ_INT16_READ((h)+0x40))) +#define KIGOU_F_HINSI(h) ((NJ_UINT16)(NJ_INT16_READ((h)+0x42))) +#define KIGOU_B_HINSI(h) ((NJ_UINT16)(NJ_INT16_READ((h)+0x44))) +#define V1_F_HINSI(h) ((NJ_UINT16)(NJ_INT16_READ((h)+0x52))) +#define V3_F_HINSI(h) ((NJ_UINT16)(NJ_INT16_READ((h)+0x54))) + +NJ_INT16 njd_r_get_hinsi(NJ_DIC_HANDLE rule, NJ_UINT8 type) { + + + if (rule == NULL) { + return 0; + } + + switch (type) { + case NJ_HINSI_V2_F : + return V2_F_HINSI(rule); + case NJ_HINSI_BUNTOU_B : + return BUN_B_HINSI(rule); + case NJ_HINSI_TANKANJI_F : + return TAN_F_HINSI(rule); + case NJ_HINSI_TANKANJI_B : + return TAN_B_HINSI(rule); + case NJ_HINSI_SUUJI_B: + return SUUJI_B_HINSI(rule); + case NJ_HINSI_MEISI_F : + return MEISI_F_HINSI(rule); + case NJ_HINSI_MEISI_B : + return MEISI_B_HINSI(rule); + case NJ_HINSI_JINMEI_F : + return JINMEI_F_HINSI(rule); + case NJ_HINSI_JINMEI_B : + return JINMEI_B_HINSI(rule); + case NJ_HINSI_CHIMEI_F : + return CHIMEI_F_HINSI(rule); + case NJ_HINSI_CHIMEI_B : + return CHIMEI_B_HINSI(rule); + case NJ_HINSI_KIGOU_F : + return KIGOU_F_HINSI(rule); + case NJ_HINSI_KIGOU_B : + return KIGOU_B_HINSI(rule); + case NJ_HINSI_V1_F : + return V1_F_HINSI(rule); + case NJ_HINSI_V3_F : + return V3_F_HINSI(rule); default: + + return 0; + } +} + +NJ_INT16 njd_r_get_connect(NJ_DIC_HANDLE rule, NJ_UINT16 hinsi, NJ_UINT8 type, NJ_UINT8 **connect) { + NJ_UINT16 i, rec_len; + + + if (rule == NULL) { + return 0; + } + if (hinsi < 1) { + return 0; + } + + if (type == NJ_RULE_TYPE_BTOF) { + i = F_HINSI_SET_CNT(rule); + rec_len = (NJ_UINT16)((i + 7) / 8); + + *connect = (NJ_UINT8*)(F_HINSI_TOP_ADDR(rule) + ((hinsi - 1) * rec_len)); + } else { + i = B_HINSI_SET_CNT(rule); + rec_len = (NJ_UINT16)((i + 7) / 8); + + *connect = (NJ_UINT8*)(B_HINSI_TOP_ADDR(rule) + ((hinsi - 1) * rec_len)); + } + return 0; +} + +NJ_INT16 njd_r_get_count(NJ_DIC_HANDLE rule, NJ_UINT16 *fcount, NJ_UINT16 *rcount) { + + + if (rule == NULL) { + return 0; + } + + *fcount = F_HINSI_SET_CNT(rule); + *rcount = B_HINSI_SET_CNT(rule); + + return 0; +} diff --git a/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/neapi.c b/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/neapi.c new file mode 100644 index 00000000..4b59aac7 --- /dev/null +++ b/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/neapi.c @@ -0,0 +1,210 @@ +/* + * 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" + + + +static NJ_INT16 set_previous_selection(NJ_CLASS *iwnn, NJ_RESULT *result); +static NJ_INT16 set_learn_word_info(NJ_CLASS *iwnn, NJ_LEARN_WORD_INFO *lword, NJ_RESULT *result); + + + +NJ_EXTERN NJ_INT16 njx_select(NJ_CLASS *iwnn, NJ_RESULT *r_result) { + NJ_INT16 ret; + NJ_DIC_SET *dics; + + + if (iwnn == NULL) { + + return NJ_SET_ERR_VAL(NJ_FUNC_NJ_SELECT, NJ_ERR_PARAM_ENV_NULL); + } + dics = &(iwnn->dic_set); + + if (dics->rHandle[NJ_MODE_TYPE_HENKAN] == NULL) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJ_SELECT, NJ_ERR_NO_RULEDIC); + } + + + if ( r_result != NULL ) { + + ret = set_previous_selection(iwnn, r_result); + if (ret < 0) { + return ret; + } + } else { + + set_previous_selection(iwnn, NULL); + } + return 0; +} + +NJ_EXTERN NJ_INT16 njx_init(NJ_CLASS *iwnn) { + + if (iwnn == NULL) { + + return NJ_SET_ERR_VAL(NJ_FUNC_NJ_INIT, NJ_ERR_PARAM_ENV_NULL); + } + + + set_previous_selection(iwnn, NULL); + return 0; +} + +NJ_EXTERN NJ_INT16 njx_get_candidate(NJ_CLASS *iwnn, NJ_RESULT *result, NJ_CHAR *buf, NJ_UINT16 buf_size) { + NJ_INT16 ret; + + + if (iwnn == NULL) { + + return NJ_SET_ERR_VAL(NJ_FUNC_NJ_GET_CANDIDATE, NJ_ERR_PARAM_ENV_NULL); + } + if (result == NULL) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJ_GET_CANDIDATE, NJ_ERR_PARAM_RESULT_NULL); + } + + if ((buf == NULL) || (buf_size == 0)) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJ_GET_CANDIDATE, NJ_ERR_BUFFER_NOT_ENOUGH); + } + + switch (NJ_GET_RESULT_OP(result->operation_id)) { + case NJ_OP_SEARCH: + ret = njd_get_candidate(iwnn, result, buf, buf_size); + break; + + default: + + ret = NJ_SET_ERR_VAL(NJ_FUNC_NJ_GET_CANDIDATE, NJ_ERR_INVALID_RESULT); + break; + } + + return ret; +} + +NJ_EXTERN NJ_INT16 njx_get_stroke(NJ_CLASS *iwnn, NJ_RESULT *result, NJ_CHAR *buf, NJ_UINT16 buf_size) { + NJ_INT16 ret; + + + if (iwnn == NULL) { + + return NJ_SET_ERR_VAL(NJ_FUNC_NJ_GET_STROKE, NJ_ERR_PARAM_ENV_NULL); + } + if (result == NULL) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJ_GET_STROKE, NJ_ERR_PARAM_RESULT_NULL); + } + + if ((buf == NULL) || (buf_size == 0)) { + return NJ_SET_ERR_VAL(NJ_FUNC_NJ_GET_STROKE, NJ_ERR_BUFFER_NOT_ENOUGH); + } + + switch (NJ_GET_RESULT_OP(result->operation_id)) { + case NJ_OP_SEARCH: + ret = njd_get_stroke(iwnn, result, buf, buf_size); + break; + + default: + + ret = NJ_SET_ERR_VAL(NJ_FUNC_NJ_GET_STROKE, NJ_ERR_INVALID_RESULT); + break; + } + return ret; +} + + +static NJ_INT16 set_previous_selection(NJ_CLASS *iwnn, NJ_RESULT *result) { + NJ_INT16 ret; + NJ_PREVIOUS_SELECTION_INFO *prev_info = &(iwnn->previous_selection); + + + if (result == NULL) { + prev_info->count = 0; + } else { + ret = set_learn_word_info(iwnn, &(prev_info->selection_data), result); + if (ret < 0) { + + return ret; + } + + prev_info->count = 1; + } + + return 0; +} + +static NJ_INT16 set_learn_word_info(NJ_CLASS *iwnn, NJ_LEARN_WORD_INFO *lword, NJ_RESULT *result) +{ + NJ_INT16 ret; + NJ_DIC_SET *dics = &(iwnn->dic_set); + + + +#if 0 + + ret = njx_get_stroke(iwnn, result, lword->yomi, sizeof(lword->yomi)); + if (ret < 0) { + return ret; + } + lword->yomi_len = (NJ_UINT8)ret; + ret = njx_get_candidate(iwnn, result, lword->hyouki, sizeof(lword->hyouki)); + if (ret < 0) { + return ret; + } + lword->hyouki_len = (NJ_UINT8)ret; +#else + lword->yomi[0] = 0x0000; + lword->yomi_len = 0; + lword->hyouki[0] = 0x0000; + lword->hyouki_len = 0; +#endif + + + lword->f_hinsi = NJ_GET_FPOS_FROM_STEM(&(result->word)); + lword->stem_b_hinsi = NJ_GET_BPOS_FROM_STEM(&(result->word)); + lword->b_hinsi = NJ_GET_BPOS_FROM_STEM(&(result->word)); + + + ret = njd_r_get_hinsi(dics->rHandle[NJ_MODE_TYPE_HENKAN], NJ_HINSI_TANKANJI_F); + if ((ret != 0) && (lword->f_hinsi == (NJ_UINT16)ret)) { + ret = njd_r_get_hinsi(dics->rHandle[NJ_MODE_TYPE_HENKAN], NJ_HINSI_CHIMEI_F); + if (ret != 0) { + lword->f_hinsi = (NJ_UINT16)ret; + } + } + + + ret = njd_r_get_hinsi(dics->rHandle[NJ_MODE_TYPE_HENKAN], NJ_HINSI_TANKANJI_B); + if ((ret != 0) && (lword->b_hinsi == (NJ_UINT16)ret)) { + ret = njd_r_get_hinsi(dics->rHandle[NJ_MODE_TYPE_HENKAN], NJ_HINSI_CHIMEI_B); + if (ret != 0) { + lword->b_hinsi = (NJ_UINT16)ret; + } + } + + + ret = njd_r_get_hinsi(dics->rHandle[NJ_MODE_TYPE_HENKAN], NJ_HINSI_TANKANJI_B); + if ((ret != 0) && (lword->stem_b_hinsi == (NJ_UINT16)ret)) { + ret = njd_r_get_hinsi(dics->rHandle[NJ_MODE_TYPE_HENKAN], NJ_HINSI_CHIMEI_B); + if (ret != 0) { + lword->stem_b_hinsi = (NJ_UINT16)ret; + } + } + + return 0; + +} diff --git a/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/necode.c b/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/necode.c new file mode 100644 index 00000000..ca331861 --- /dev/null +++ b/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/necode.c @@ -0,0 +1,70 @@ +/* + * 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_ext.h" + + +#define HIRA_KATA_OFFSET (0x0060) + +#define ZEN_CHAR_LEN 1 + +#define CHAR_TO_WCHAR(s) \ + ((NJ_UINT16)( (((NJ_UINT8*)(s))[0] << 8) | ((NJ_UINT8*)(s))[1] )) + +#define SET_WCHAR_TO_CHAR(s, c) \ + { \ + ((NJ_UINT8*)(s))[0] = (NJ_UINT8)(((c) >> 8) & 0x00ff); \ + ((NJ_UINT8*)(s))[1] = (NJ_UINT8)(((c)) & 0x00ff); \ + } + +#define IS_HIRAGANA_WCHAR(c) ( ((c) >= 0x3041) && ((c) <= 0x3093) ) + + + + +NJ_INT16 nje_convert_hira_to_kata(NJ_CHAR *hira, NJ_CHAR *kata, NJ_UINT16 len) +{ + NJ_UINT16 pnt; + NJ_UINT16 wchar; + + + pnt = 0; + while (pnt < len) { + if (*hira == NJ_CHAR_NUL) { + + return pnt; + } + + + wchar = CHAR_TO_WCHAR(hira); + hira++; + pnt++; + + if (IS_HIRAGANA_WCHAR(wchar)) { + + SET_WCHAR_TO_CHAR(kata, wchar + HIRA_KATA_OFFSET); + kata += ZEN_CHAR_LEN; + } else { + SET_WCHAR_TO_CHAR(kata, wchar); + kata += ZEN_CHAR_LEN; + } + } + + + *kata = NJ_CHAR_NUL; + return pnt; +} diff --git a/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/nj_str.c b/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/nj_str.c new file mode 100644 index 00000000..1892458b --- /dev/null +++ b/src/plugins/openwnn/3rdparty/openwnn/wnnDictionary/engine/nj_str.c @@ -0,0 +1,153 @@ +/* + * 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_ext.h" + + +NJ_CHAR *nj_strcpy(NJ_CHAR *dst, NJ_CHAR *src) { + + NJ_CHAR *ret = dst; + + + while (*src != NJ_CHAR_NUL) { + *dst++ = *src++; + } + *dst = *src; + return ret; +} + +NJ_CHAR *nj_strncpy(NJ_CHAR *dst, NJ_CHAR *src, NJ_UINT16 n) { + + NJ_CHAR *d = dst; + + + while (n != 0) { + if (*src == NJ_CHAR_NUL) { + while (n != 0) { + *d++ = NJ_CHAR_NUL; + n--; + } + break; + } else { + *d++ = *src++; + } + n--; + } + return dst; +} + +NJ_UINT16 nj_strlen(NJ_CHAR *c) { + + NJ_UINT16 count = 0; + + + while (*c++ != NJ_CHAR_NUL) { + count++; + } + return count; +} + +NJ_INT16 nj_strcmp(NJ_CHAR *s1, NJ_CHAR *s2) { + + while (*s1 == *s2) { + if (*s1 == NJ_CHAR_NUL) { + return (0); + } + s1++; + s2++; + } + return NJ_CHAR_DIFF(s1, s2); +} + +NJ_INT16 nj_strncmp(NJ_CHAR *s1, NJ_CHAR *s2, NJ_UINT16 n) { + + while (n != 0) { + if (*s1 != *s2++) { + return NJ_CHAR_DIFF(s1, (s2 - 1)); + } + if (*s1++ == NJ_CHAR_NUL) { + break; + } + n--; + } + return (0); +} + +NJ_UINT16 nj_charlen(NJ_CHAR *c) { + + NJ_UINT16 count = 0; + + + while (*c != NJ_CHAR_NUL) { + count++; + c += NJ_CHAR_LEN(c); + } + return count; +} + +NJ_INT16 nj_charncmp(NJ_CHAR *s1, NJ_CHAR *s2, NJ_UINT16 n) { + NJ_UINT16 i; + + + while (n != 0) { + for (i = NJ_CHAR_LEN(s1); i != 0; i--) { + if (*s1 != *s2) { + return NJ_CHAR_DIFF(s1, s2); + } + if (*s1 == NJ_CHAR_NUL) { + break; + } + s1++; + s2++; + } + n--; + } + return (0); +} + +NJ_CHAR *nj_charncpy(NJ_CHAR *dst, NJ_CHAR *src, NJ_UINT16 n) { + + NJ_CHAR *d = dst; + NJ_UINT16 i; + + + while (n != 0) { + for (i = NJ_CHAR_LEN(src); i != 0; i--) { + *d = *src; + if (*src == NJ_CHAR_NUL) { + return dst; + } + d++; + src++; + } + n--; + } + *d = NJ_CHAR_NUL; + return dst; +} + +NJ_UINT8 *nj_memcpy(NJ_UINT8 *dst, NJ_UINT8 *src, NJ_UINT16 n) { + + NJ_UINT8 *d = dst; + + + while (n != 0) { + *d++ = *src++; + n--; + } + return dst; +} |