Home | History | Annotate | Download | only in engine
      1 /*
      2  * Copyright (C) 2008-2012  OMRON SOFTWARE Co., Ltd.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "nj_lib.h"
     18 #include "nj_err.h"
     19 #include "nj_ext.h"
     20 #include "nj_dic.h"
     21 #include "njd.h"
     22 
     23 #define NJ_DIC_UNCOMP_EXT_HEADER_SIZE   0x002C
     24 #define CREATE_DIC_TYPE_USER            0
     25 
     26 #define GET_HYOKI_INDEX_OFFSET(cnt)                             \
     27     (NJ_LEARN_DIC_HEADER_SIZE + NJ_INDEX_SIZE * ((cnt)+1))
     28 
     29 #define GET_DATA_AREA_OFFSET(cnt)                               \
     30     (NJ_LEARN_DIC_HEADER_SIZE + NJ_INDEX_SIZE * ((cnt)+1) * 2)
     31 #define GET_EXT_DATA_AREA_OFFSET(cnt)                                   \
     32     (NJ_LEARN_DIC_HEADER_SIZE + NJ_INDEX_SIZE * ((cnt)+1) * 2 + LEARN_DIC_QUE_SIZE * (cnt))
     33 
     34 #define MIN_SIZE_OF_USER_DIC                                            \
     35     (NJ_LEARN_DIC_HEADER_SIZE + NJ_USER_QUE_SIZE + 2 * (NJ_INDEX_SIZE * (1+1)) + 4)
     36 #define GET_MAX_WORD_NUM_IN_USER_DIC(size)                              \
     37     (((size) - NJ_LEARN_DIC_HEADER_SIZE - (2 * NJ_INDEX_SIZE) - 4)      \
     38      / (NJ_USER_QUE_SIZE + 2 * NJ_INDEX_SIZE))
     39 
     40 
     41 static NJ_INT16 check_search_cursor(NJ_CLASS *iwnn, NJ_CURSOR *cursor);
     42 static NJ_INT16 search_word(NJ_CLASS *iwnn, NJ_CURSOR *cursor, NJ_UINT8 comp_flg, NJ_UINT8 *exit_flag);
     43 static void set_operation_id(NJ_SEARCH_LOCATION *dicinfo, NJ_UINT8 reverse, NJ_RESULT *result);
     44 static NJ_INT16 get_word_and_search_next_word(NJ_CLASS *iwnn, NJ_CURSOR *cursor, NJ_RESULT *result, NJ_UINT8 comp_flg);
     45 
     46 static NJ_INT16 njd_check_dic(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle);
     47 
     48 static NJ_INT16 check_search_cursor(NJ_CLASS *iwnn, NJ_CURSOR *cursor) {
     49     NJ_UINT16 i;
     50     NJ_DIC_INFO *dicinfo;
     51     NJ_SEARCH_LOCATION_SET *loctset;
     52 
     53 
     54     if (cursor->cond.ds == NULL) {
     55         return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_PARAM_DIC_NULL);
     56     }
     57 
     58 
     59     for (i = 0; i < NJ_MAX_DIC; i++) {
     60         loctset = &(cursor->loctset[i]);
     61         dicinfo = &(cursor->cond.ds->dic[i]);
     62 
     63 
     64         njd_init_search_location_set(loctset);
     65 
     66         if (dicinfo->handle != NULL) {
     67 
     68 
     69 
     70             if (
     71                 (dicinfo->dic_freq[NJ_MODE_TYPE_HENKAN].high > DIC_FREQ_HIGH) ) {
     72                 return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_DIC_FREQ_INVALID);
     73             }
     74 
     75 
     76             loctset->loct.handle        = dicinfo->handle;
     77             loctset->loct.type          = dicinfo->type;
     78             loctset->loct.current_info  = 0x10;
     79             loctset->loct.status        = NJ_ST_SEARCH_NO_INIT;
     80             loctset->dic_freq           = dicinfo->dic_freq[NJ_MODE_TYPE_HENKAN];
     81         }
     82     }
     83 
     84     if (cursor->cond.yomi == NULL) {
     85 
     86         return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_PARAM_YOMI_NULL);
     87     }
     88 
     89     if (cursor->cond.ylen > NJ_MAX_LEN) {
     90 
     91         return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_YOMI_TOO_LONG);
     92     }
     93 
     94     if (cursor->cond.operation == NJ_CUR_OP_LINK) {
     95 
     96     } else if (cursor->cond.kanji != NULL) {
     97 
     98         if (nj_strlen(cursor->cond.kanji) > NJ_MAX_RESULT_LEN) {
     99             return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_CANDIDATE_TOO_LONG);
    100         }
    101     }
    102 
    103     switch (cursor->cond.operation) {
    104     case NJ_CUR_OP_COMP:
    105     case NJ_CUR_OP_FORE:
    106     case NJ_CUR_OP_LINK:
    107         break;
    108     default:
    109         return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_PARAM_OPERATION);
    110     }
    111 
    112     switch (cursor->cond.mode) {
    113     case NJ_CUR_MODE_FREQ:
    114     case NJ_CUR_MODE_YOMI:
    115         break;
    116     default:
    117         return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_PARAM_MODE);
    118     }
    119 
    120     return 0;
    121 }
    122 
    123 static NJ_INT16 search_word(NJ_CLASS *iwnn, NJ_CURSOR *cursor, NJ_UINT8 comp_flg,
    124                             NJ_UINT8 *exit_flag) {
    125     NJ_UINT32 dic_type;
    126     NJ_INT16 i;
    127     NJ_INT16 ret = 0;
    128     NJ_INT16 flag = 0;
    129     NJ_SEARCH_LOCATION_SET *loctset;
    130 
    131 
    132     *exit_flag = 1;
    133     for (i = 0; i < NJ_MAX_DIC; i++) {
    134         loctset = &(cursor->loctset[i]);
    135 
    136         if (loctset->loct.handle == NULL) {
    137             continue;
    138         }
    139 
    140         dic_type = NJ_GET_DIC_TYPE_EX(loctset->loct.type, loctset->loct.handle);
    141 #ifdef IWNN_ERR_CHECK
    142         if (iwnn->err_check_flg == 12) {
    143             dic_type = 0x11111111;
    144         }
    145 #endif
    146         switch (dic_type) {
    147         case NJ_DIC_TYPE_JIRITSU:
    148         case NJ_DIC_TYPE_FZK:
    149         case NJ_DIC_TYPE_TANKANJI:
    150         case NJ_DIC_TYPE_STDFORE:
    151         case NJ_DIC_TYPE_CUSTOM_COMPRESS:
    152         case NJ_DIC_TYPE_FORECONV:
    153             ret = njd_b_search_word(&cursor->cond, loctset);
    154             break;
    155         case NJ_DIC_TYPE_USER:
    156         case NJ_DIC_TYPE_CUSTOM_INCOMPRESS:
    157             ret = njd_l_search_word(iwnn, &cursor->cond, loctset, comp_flg);
    158             break;
    159 
    160         case NJ_DIC_TYPE_YOMINASHI:
    161             ret = njd_f_search_word(&cursor->cond, loctset);
    162             break;
    163 
    164         default:
    165             return NJ_SET_ERR_VAL(NJ_FUNC_SEARCH_WORD, NJ_ERR_DIC_TYPE_INVALID);
    166         }
    167         if (ret < 0) {
    168             return ret;
    169         }
    170         if (ret == 0) {
    171             if ((GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_END)
    172                 && (*exit_flag == 1)) {
    173                 *exit_flag = 0;
    174             }
    175 
    176             loctset->loct.status = NJ_ST_SEARCH_END;
    177 
    178         } else {
    179             flag = 1;
    180             *exit_flag = 0;
    181         }
    182     }
    183     return flag;
    184 }
    185 
    186 static NJ_INT16 get_word_and_search_next_word(NJ_CLASS *iwnn, NJ_CURSOR *cursor, NJ_RESULT *result,
    187                                               NJ_UINT8 comp_flg) {
    188     NJ_INT16  ret = -1;
    189     NJ_INT32  i, next, first;
    190     NJ_WORD   tmp_word;
    191     NJ_RESULT tmp_result;
    192     NJ_CHAR   tmp_stroke[NJ_MAX_LEN + NJ_TERM_LEN];
    193     NJ_CHAR   result_stroke[NJ_MAX_LEN + NJ_TERM_LEN];
    194     NJ_INT32  j, max_len = 0;
    195     NJ_UINT32 dic_type;
    196     NJ_SEARCH_LOCATION_SET *loctset;
    197 
    198 
    199     next = -1;
    200     first= 0;
    201 
    202     njd_init_word(&tmp_word);
    203 
    204     result->word = tmp_word;
    205     tmp_result.word = tmp_word;
    206 
    207     for (i = 0; i < NJ_MAX_DIC; i++) {
    208         loctset = &(cursor->loctset[i]);
    209         if ((loctset->loct.handle == NULL) ||
    210             (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_END) ||
    211             (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_END_EXT)) {
    212             continue;
    213         }
    214 
    215         dic_type = NJ_GET_DIC_TYPE_EX(loctset->loct.type, loctset->loct.handle);
    216 
    217         switch (dic_type) {
    218         case NJ_DIC_TYPE_JIRITSU:
    219         case NJ_DIC_TYPE_FZK:
    220         case NJ_DIC_TYPE_TANKANJI:
    221         case NJ_DIC_TYPE_STDFORE:
    222         case NJ_DIC_TYPE_CUSTOM_COMPRESS:
    223         case NJ_DIC_TYPE_FORECONV:
    224             tmp_word.yomi = cursor->cond.yomi;
    225             tmp_word.stem.info1 = cursor->cond.ylen;
    226             tmp_result.word.yomi = cursor->cond.yomi;
    227             tmp_result.word.stem.info1 = cursor->cond.ylen;
    228             break;
    229         default:
    230             break;
    231         }
    232 
    233         loctset->loct.status |= SET_LOCATION_OPERATION(cursor->cond.operation);
    234         if (cursor->cond.mode == NJ_CUR_MODE_FREQ) {
    235             if ((cursor->cond.ds->mode & (NJ_CACHE_MODE_VALID)) &&
    236                 (cursor->cond.ds->dic[i].srhCache != NULL) &&
    237                 (NJ_GET_AIMAI_FROM_SCACHE(cursor->cond.ds->dic[i].srhCache)) &&
    238                 (cursor->cond.operation == NJ_CUR_OP_FORE)) {
    239                 first = 1;
    240 
    241                 ret = njd_get_word_data(iwnn, cursor->cond.ds, loctset, (NJ_UINT16)i, &tmp_result.word);
    242                 if (ret < 0) {
    243                     return ret;
    244                 }
    245 
    246                 ret = njd_get_stroke(iwnn, &tmp_result, tmp_stroke, sizeof(tmp_stroke));
    247                 if (ret <= 0) {
    248                     if ((ret == 0) || (NJ_GET_ERR_CODE(ret) == NJ_ERR_BUFFER_NOT_ENOUGH)) {
    249                         return NJ_SET_ERR_VAL(NJ_FUNC_GET_WORD_AND_SEARCH_NEXT_WORD, NJ_ERR_INVALID_RESULT);
    250                     } else {
    251                         return ret;
    252                     }
    253                 }
    254                 for (j = 0; j < cursor->cond.ylen; j++) {
    255                     if (cursor->cond.yomi[j] != tmp_stroke[j]) {
    256                         break;
    257                     }
    258                 }
    259 
    260                 switch (dic_type) {
    261                 case NJ_DIC_TYPE_JIRITSU:
    262                 case NJ_DIC_TYPE_FZK:
    263                 case NJ_DIC_TYPE_TANKANJI:
    264                 case NJ_DIC_TYPE_STDFORE:
    265                 case NJ_DIC_TYPE_CUSTOM_COMPRESS:
    266                 case NJ_DIC_TYPE_FORECONV:
    267                     ret = njd_b_search_word(&cursor->cond, loctset);
    268                     break;
    269 
    270                 case NJ_DIC_TYPE_USER:
    271                 case NJ_DIC_TYPE_CUSTOM_INCOMPRESS:
    272                     ret = njd_l_search_word(iwnn, &cursor->cond, loctset, comp_flg);
    273                     break;
    274 
    275                 default:
    276                     return NJ_SET_ERR_VAL(NJ_FUNC_GET_WORD_AND_SEARCH_NEXT_WORD, NJ_ERR_DIC_TYPE_INVALID);
    277                 }
    278 
    279                 if (ret < 0) {
    280                     return ret;
    281                 }
    282             } else {
    283                 ret = njd_get_word_data(iwnn, cursor->cond.ds, loctset, (NJ_UINT16)i, &tmp_result.word);
    284                 if (ret < 0) {
    285                     return ret;
    286                 }
    287                 j = cursor->cond.ylen;
    288             }
    289 
    290             if ((j > max_len) ||
    291                 ((j == max_len) && (loctset->cache_freq > result->word.stem.hindo)) ||
    292                 (next == -1)) {
    293 
    294                 set_operation_id(&(loctset->loct), 0, result);
    295 
    296                 result->word = tmp_result.word;
    297 
    298                 next = i;
    299                 max_len = j;
    300             }
    301 
    302         } else {
    303 
    304             ret = njd_get_word_data(iwnn, cursor->cond.ds, loctset, (NJ_UINT16)i, &(tmp_result.word));
    305             if (ret < 0) {
    306                 return ret;
    307             }
    308 
    309 
    310             ret = njd_get_stroke(iwnn, &tmp_result, tmp_stroke, sizeof(tmp_stroke));
    311             if (ret <= 0) {
    312                 if ((ret == 0) || (NJ_GET_ERR_CODE(ret) == NJ_ERR_BUFFER_NOT_ENOUGH)) {
    313                     return NJ_SET_ERR_VAL(NJ_FUNC_GET_WORD_AND_SEARCH_NEXT_WORD, NJ_ERR_INVALID_RESULT);
    314                 } else {
    315                     return ret;
    316                 }
    317             }
    318             if ((next == -1) || (nj_strcmp(result_stroke, tmp_stroke) > 0)) {
    319 
    320                 set_operation_id(&(loctset->loct), 0, result);
    321 
    322                 result->word = tmp_result.word;
    323 
    324                 next = i;
    325                 nj_strcpy(result_stroke, tmp_stroke);
    326             }
    327         }
    328     }
    329 
    330 
    331     if (next == -1) {
    332         return 0;
    333     }
    334 
    335     loctset = &(cursor->loctset[next]);
    336     if ((!first) ||
    337         ((loctset->loct.handle != NULL) &&
    338          (cursor->cond.ds->dic[next].srhCache == NULL))) {
    339         dic_type = NJ_GET_DIC_TYPE_EX(loctset->loct.type, loctset->loct.handle);
    340 
    341 
    342         switch (dic_type) {
    343         case NJ_DIC_TYPE_JIRITSU:
    344         case NJ_DIC_TYPE_FZK:
    345         case NJ_DIC_TYPE_TANKANJI:
    346         case NJ_DIC_TYPE_STDFORE:
    347         case NJ_DIC_TYPE_CUSTOM_COMPRESS:
    348         case NJ_DIC_TYPE_FORECONV:
    349             ret = njd_b_search_word(&cursor->cond, loctset);
    350             break;
    351 
    352         case NJ_DIC_TYPE_USER:
    353         case NJ_DIC_TYPE_CUSTOM_INCOMPRESS:
    354             ret = njd_l_search_word(iwnn, &cursor->cond, loctset, comp_flg);
    355             break;
    356 
    357         case NJ_DIC_TYPE_YOMINASHI:
    358             ret = njd_f_search_word(&cursor->cond, loctset);
    359             break;
    360 
    361         default:
    362             return NJ_SET_ERR_VAL(NJ_FUNC_GET_WORD_AND_SEARCH_NEXT_WORD, NJ_ERR_DIC_TYPE_INVALID);
    363         }
    364     }
    365 
    366     if (ret < 0) {
    367         return ret;
    368     }
    369     return 1;
    370 }
    371 
    372 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) {
    373     NJ_INT16 ret = 0;
    374     NJ_UINT32 dic_type;
    375 
    376 
    377 
    378     if (GET_LOCATION_STATUS(loctset->loct.status) == NJ_ST_SEARCH_END) {
    379         return 0;
    380     }
    381 
    382     if (loctset->loct.handle == NULL) {
    383         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_GET_WORD_DATA, NJ_ERR_DIC_TYPE_INVALID);
    384     }
    385 
    386     dic_type = NJ_GET_DIC_TYPE_EX(loctset->loct.type, loctset->loct.handle);
    387 
    388     switch (dic_type) {
    389     case NJ_DIC_TYPE_JIRITSU:
    390     case NJ_DIC_TYPE_FZK:
    391     case NJ_DIC_TYPE_TANKANJI:
    392     case NJ_DIC_TYPE_STDFORE:
    393     case NJ_DIC_TYPE_CUSTOM_COMPRESS:
    394     case NJ_DIC_TYPE_FORECONV:
    395         ret = njd_b_get_word(loctset, word);
    396         break;
    397 
    398     case NJ_DIC_TYPE_USER:
    399     case NJ_DIC_TYPE_CUSTOM_INCOMPRESS:
    400         ret = njd_l_get_word(iwnn, loctset, word);
    401         break;
    402 
    403     case NJ_DIC_TYPE_YOMINASHI:
    404         ret = njd_f_get_word(loctset, word);
    405         break;
    406 
    407     default:
    408         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_GET_WORD_DATA, NJ_ERR_DIC_TYPE_INVALID);
    409     }
    410     return ret;
    411 }
    412 
    413 static void set_operation_id(NJ_SEARCH_LOCATION *dicinfo, NJ_UINT8 reverse, NJ_RESULT *result) {
    414     NJ_UINT16 dictype;
    415     NJ_UINT32 type;
    416 
    417     if (dicinfo->handle == NULL) {
    418 
    419         dictype = NJ_DIC_STATIC;
    420         return;
    421     }
    422 
    423     type = NJ_GET_DIC_TYPE_EX(NJ_GET_DIC_INFO(dicinfo), dicinfo->handle);
    424 
    425 
    426     switch (type) {
    427     case NJ_DIC_TYPE_JIRITSU:
    428     case NJ_DIC_TYPE_FZK:
    429     case NJ_DIC_TYPE_TANKANJI:
    430     case NJ_DIC_TYPE_STDFORE:
    431     case NJ_DIC_TYPE_YOMINASHI:
    432 
    433     case NJ_DIC_TYPE_FORECONV:
    434         dictype = NJ_DIC_STATIC;
    435         break;
    436 
    437     case NJ_DIC_TYPE_CUSTOM_INCOMPRESS:
    438     case NJ_DIC_TYPE_CUSTOM_COMPRESS:
    439         dictype = NJ_DIC_CUSTOMIZE;
    440         break;
    441 
    442     case NJ_DIC_TYPE_USER:
    443         dictype = NJ_DIC_USER;
    444         break;
    445 
    446     default:
    447 
    448         dictype = NJ_DIC_STATIC;
    449     }
    450 
    451 
    452     result->operation_id =
    453         (NJ_UINT16)((NJ_UINT16)NJ_OP_SEARCH | (NJ_UINT16)NJ_FUNC_SEARCH | dictype);
    454 }
    455 
    456 static NJ_INT16 njd_search_word(NJ_CLASS *iwnn, NJ_CURSOR *cursor, NJ_UINT8 comp_flg,
    457                          NJ_UINT8 *exit_flag) {
    458     NJ_INT16 ret;
    459 
    460 
    461     ret = check_search_cursor(iwnn, cursor);
    462     if (ret != 0) {
    463         return ret;
    464     }
    465 
    466     return search_word(iwnn, cursor, comp_flg, exit_flag);
    467 }
    468 
    469 static NJ_INT16 njd_get_word(NJ_CLASS *iwnn, NJ_CURSOR *cursor, NJ_RESULT *result,
    470                       NJ_UINT8 comp_flg) {
    471 
    472     NJ_INT16    ret;
    473 
    474 
    475     ret = get_word_and_search_next_word(iwnn, cursor, result, comp_flg);
    476 
    477     return ret;
    478 }
    479 
    480 NJ_INT16 njd_get_stroke(NJ_CLASS *iwnn, NJ_RESULT *result, NJ_CHAR *stroke, NJ_UINT16 size) {
    481     NJ_INT16 ret = 0;
    482     NJ_UINT16 len;
    483     NJ_UINT32 dictype;
    484 
    485 
    486     if (result->word.stem.loc.handle == NULL) {
    487         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_GET_STROKE, NJ_ERR_INVALID_RESULT);
    488     }
    489 
    490     dictype = NJ_GET_DIC_TYPE_EX(result->word.stem.loc.type, result->word.stem.loc.handle);
    491 
    492     switch (dictype) {
    493     case NJ_DIC_TYPE_JIRITSU:
    494     case NJ_DIC_TYPE_FZK:
    495     case NJ_DIC_TYPE_TANKANJI:
    496     case NJ_DIC_TYPE_STDFORE:
    497     case NJ_DIC_TYPE_CUSTOM_COMPRESS:
    498     case NJ_DIC_TYPE_FORECONV:
    499         if (GET_LOCATION_OPERATION(result->word.stem.loc.status) != NJ_CUR_OP_COMP) {
    500             ret = njd_b_get_stroke(&result->word, stroke, size);
    501         } else {
    502             len = NJ_GET_YLEN_FROM_STEM(&result->word);
    503 
    504             if (size < ((len + NJ_TERM_LEN) * sizeof(NJ_CHAR))) {
    505                 return NJ_SET_ERR_VAL(NJ_FUNC_NJD_GET_STROKE,
    506                                       NJ_ERR_BUFFER_NOT_ENOUGH);
    507             }
    508             if (len == 0) {
    509                 return NJ_SET_ERR_VAL(NJ_FUNC_NJD_GET_STROKE,
    510                                       NJ_ERR_INVALID_RESULT);
    511             }
    512             nj_strncpy(stroke, result->word.yomi, len);
    513             *(stroke + len) = NJ_CHAR_NUL;
    514             return len;
    515         }
    516         break;
    517 
    518     case NJ_DIC_TYPE_USER:
    519     case NJ_DIC_TYPE_CUSTOM_INCOMPRESS:
    520         ret = njd_l_get_stroke(iwnn, &result->word, stroke, size);
    521         break;
    522 
    523     case NJ_DIC_TYPE_YOMINASHI:
    524         ret = njd_f_get_stroke(&result->word, stroke, size);
    525         break;
    526 
    527     default:
    528         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_GET_STROKE, NJ_ERR_DIC_TYPE_INVALID);
    529     }
    530 
    531     if (ret == 0) {
    532         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_GET_STROKE, NJ_ERR_INVALID_RESULT);
    533     }
    534     return ret;
    535 }
    536 
    537 
    538 NJ_INT16 njd_get_candidate(NJ_CLASS *iwnn, NJ_RESULT *result,
    539                            NJ_CHAR *candidate, NJ_UINT16 size) {
    540     NJ_INT16 ret = 0;
    541     NJ_UINT32 dictype;
    542 
    543 
    544     if (result->word.stem.loc.handle == NULL) {
    545         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_GET_CANDIDATE, NJ_ERR_INVALID_RESULT);
    546     }
    547 
    548     dictype = NJ_GET_DIC_TYPE_EX(result->word.stem.loc.type, result->word.stem.loc.handle);
    549 
    550     switch (dictype) {
    551     case NJ_DIC_TYPE_JIRITSU:
    552     case NJ_DIC_TYPE_FZK:
    553     case NJ_DIC_TYPE_TANKANJI:
    554     case NJ_DIC_TYPE_STDFORE:
    555     case NJ_DIC_TYPE_CUSTOM_COMPRESS:
    556     case NJ_DIC_TYPE_FORECONV:
    557         ret = njd_b_get_candidate(&result->word, candidate, size);
    558         break;
    559 
    560     case NJ_DIC_TYPE_USER:
    561     case NJ_DIC_TYPE_CUSTOM_INCOMPRESS:
    562         ret = njd_l_get_candidate(iwnn, &result->word, candidate, size);
    563         break;
    564 
    565     case NJ_DIC_TYPE_YOMINASHI:
    566         ret = njd_f_get_candidate(&result->word, candidate, size);
    567         break;
    568 
    569     default:
    570         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_GET_CANDIDATE, NJ_ERR_DIC_TYPE_INVALID);
    571     }
    572 
    573     if (ret == 0) {
    574         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_GET_CANDIDATE, NJ_ERR_INVALID_RESULT);
    575     }
    576     return ret;
    577 }
    578 
    579 
    580 static NJ_INT16 njd_check_dic(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle) {
    581     NJ_UINT8 *addr;
    582     NJ_UINT32 datasize, extsize;
    583     NJ_UINT32 version;
    584     NJ_UINT32 type;
    585 
    586 
    587     addr = handle;
    588 
    589 
    590     if (NJ_INT32_READ(addr) != NJ_DIC_IDENTIFIER) {
    591         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_CHECK_DIC, NJ_ERR_FORMAT_INVALID);
    592     }
    593     addr += sizeof(NJ_UINT32);
    594 
    595 
    596     version = NJ_INT32_READ(addr);
    597     if ((version != NJ_DIC_VERSION1) && (version != NJ_DIC_VERSION2) &&
    598         (version != NJ_DIC_VERSION2_1) && (version != NJ_DIC_VERSION3)) {
    599         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_CHECK_DIC, NJ_ERR_FORMAT_INVALID);
    600     }
    601     addr += sizeof(NJ_UINT32);
    602 
    603 
    604     type = NJ_INT32_READ(addr);
    605     addr += sizeof(NJ_UINT32);
    606 
    607 
    608     datasize = NJ_INT32_READ(addr);
    609     addr += sizeof(NJ_UINT32);
    610 
    611 
    612     extsize = NJ_INT32_READ(addr);
    613     addr += sizeof(NJ_UINT32);
    614 
    615 
    616     if (NJ_INT32_READ(addr) > (NJ_MAX_LEN * sizeof(NJ_CHAR))) {
    617         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_CHECK_DIC, NJ_ERR_FORMAT_INVALID);
    618     }
    619     addr += sizeof(NJ_UINT32);
    620 
    621 
    622     if (NJ_INT32_READ(addr) > (NJ_MAX_RESULT_LEN * sizeof(NJ_CHAR))) {
    623         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_CHECK_DIC, NJ_ERR_FORMAT_INVALID);
    624     }
    625 
    626 
    627     addr += (extsize + datasize);
    628     if (NJ_INT32_READ(addr) != NJ_DIC_IDENTIFIER) {
    629         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_CHECK_DIC, NJ_ERR_FORMAT_INVALID);
    630     }
    631 
    632 
    633     switch (type) {
    634 
    635     case NJ_DIC_TYPE_JIRITSU:
    636     case NJ_DIC_TYPE_FZK:
    637     case NJ_DIC_TYPE_TANKANJI:
    638     case NJ_DIC_TYPE_CUSTOM_COMPRESS:
    639     case NJ_DIC_TYPE_STDFORE:
    640 
    641         if (version != (NJ_UINT32)NJ_DIC_VERSION2) {
    642             return NJ_SET_ERR_VAL(NJ_FUNC_NJD_CHECK_DIC, NJ_ERR_FORMAT_INVALID);
    643         }
    644         break;
    645 
    646     case NJ_DIC_TYPE_RULE:
    647 
    648         if (version != (NJ_UINT32)NJ_DIC_VERSION2_1) {
    649             return NJ_SET_ERR_VAL(NJ_FUNC_NJD_CHECK_DIC, NJ_ERR_FORMAT_INVALID);
    650         }
    651         break;
    652 
    653     case NJ_DIC_TYPE_YOMINASHI:
    654 
    655         if (version != (NJ_UINT32)NJ_DIC_VERSION1) {
    656             return NJ_SET_ERR_VAL(NJ_FUNC_NJD_CHECK_DIC, NJ_ERR_FORMAT_INVALID);
    657         }
    658         break;
    659 
    660     case NJ_DIC_TYPE_USER:
    661 
    662         if (version != (NJ_UINT32)NJ_DIC_VERSION2) {
    663             return NJ_SET_ERR_VAL(NJ_FUNC_NJD_CHECK_DIC, NJ_ERR_FORMAT_INVALID);
    664         }
    665         return njd_l_check_dic(iwnn, handle);
    666 
    667     default:
    668         return NJ_SET_ERR_VAL(NJ_FUNC_NJD_CHECK_DIC, NJ_ERR_DIC_TYPE_INVALID);
    669     }
    670     return 0;
    671 }
    672 
    673 
    674 NJ_EXTERN NJ_INT16 njx_search_word(NJ_CLASS *iwnn, NJ_CURSOR *cursor) {
    675 
    676     NJ_SEARCH_CACHE     *pCache;
    677     NJ_CHAR             *p_yomi, *p_key;
    678     NJ_UINT16           initst, inited;
    679     NJ_UINT16           clrcnt, diccnt;
    680     NJ_UINT16           kw_len;
    681     NJ_UINT16           cacheOverKeyPtr;
    682 
    683     NJ_UINT8 exit_flag;
    684     NJ_UINT8 cnt;
    685     NJ_DIC_HANDLE dhdl;
    686     NJ_PREVIOUS_SELECTION_INFO *prev_info = &(iwnn->previous_selection);
    687 
    688 
    689     if (iwnn == NULL) {
    690         return NJ_SET_ERR_VAL(NJ_FUNC_NJ_SEARCH_WORD, NJ_ERR_PARAM_ENV_NULL);
    691     }
    692     if (cursor == NULL) {
    693         return NJ_SET_ERR_VAL(NJ_FUNC_NJ_SEARCH_WORD, NJ_ERR_PARAM_CURSOR_NULL);
    694     }
    695 
    696 
    697     cursor->cond.hinsi.fore = NULL;
    698     cursor->cond.hinsi.foreSize = 0;
    699     cursor->cond.hinsi.foreFlag = 0;
    700     cursor->cond.hinsi.rear = NULL;
    701     cursor->cond.hinsi.rearSize = 0;
    702     cursor->cond.hinsi.rearFlag = 0;
    703 
    704 
    705     if (cursor->cond.yomi == NULL) {
    706         return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_PARAM_YOMI_NULL);
    707     }
    708     cursor->cond.ylen = nj_strlen(cursor->cond.yomi);
    709     cursor->cond.yclen = nj_charlen(cursor->cond.yomi);
    710 
    711 
    712     if (cursor->cond.ds == NULL) {
    713         return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_PARAM_DIC_NULL);
    714     }
    715 
    716 
    717     cursor->cond.ds->mode = NJ_CACHE_MODE_VALID;
    718 
    719     p_yomi = cursor->cond.yomi;
    720     p_key  = cursor->cond.ds->keyword;
    721 
    722     for (clrcnt = 0; clrcnt < cursor->cond.yclen; clrcnt++) {
    723         if (nj_charncmp(p_yomi, p_key, 1) != 0) {
    724             break;
    725         }
    726         p_yomi += NJ_CHAR_LEN(p_yomi);
    727         p_key  += NJ_CHAR_LEN(p_key);
    728     }
    729     if (clrcnt != 0) {
    730         initst = clrcnt + 1;
    731     } else {
    732         initst = 0;
    733     }
    734 
    735     kw_len = nj_charlen(cursor->cond.ds->keyword);
    736     if (kw_len >= cursor->cond.yclen) {
    737       inited = kw_len + 1;
    738     } else {
    739       inited = cursor->cond.yclen + 1;
    740     }
    741 
    742     for (diccnt = 0; diccnt < NJ_MAX_DIC; diccnt++) {
    743         pCache = cursor->cond.ds->dic[diccnt].srhCache;
    744         if (pCache != NULL) {
    745 
    746             if (NJ_GET_CACHEOVER_FROM_SCACHE(pCache)) {
    747 
    748                 for (cacheOverKeyPtr = 0; cacheOverKeyPtr < kw_len; cacheOverKeyPtr++) {
    749                     if (pCache->keyPtr[cacheOverKeyPtr] == pCache->keyPtr[cacheOverKeyPtr + 1] ) {
    750                         break;
    751                     }
    752                 }
    753                 cacheOverKeyPtr++;
    754 
    755 
    756                 if (cacheOverKeyPtr < initst) {
    757                     clrcnt = cacheOverKeyPtr;
    758                 } else {
    759                     clrcnt = initst;
    760                 }
    761                 for (; clrcnt < inited; clrcnt++) {
    762                     pCache->keyPtr[clrcnt] = 0x0000;
    763                 }
    764 
    765                 for (clrcnt = 1; clrcnt < inited; clrcnt++ ) {
    766                     if ((pCache->keyPtr[clrcnt - 1] > pCache->keyPtr[clrcnt]) &&
    767                         (pCache->keyPtr[clrcnt] != 0)) {
    768                         return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_CACHE_BROKEN);
    769                     }
    770                 }
    771                 NJ_UNSET_CACHEOVER_TO_SCACHE(pCache);
    772             } else {
    773                 for (clrcnt = initst; clrcnt < inited; clrcnt++) {
    774                     pCache->keyPtr[clrcnt] = 0x0000;
    775                 }
    776 
    777                 for (clrcnt = 1; clrcnt < inited; clrcnt++ ) {
    778                     if ((pCache->keyPtr[clrcnt - 1] > pCache->keyPtr[clrcnt]) &&
    779                         (pCache->keyPtr[clrcnt] != 0)) {
    780                         return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_CACHE_BROKEN);
    781                     }
    782                 }
    783             }
    784         }
    785     }
    786 
    787 
    788     nj_strcpy(cursor->cond.ds->keyword, cursor->cond.yomi);
    789 
    790     for (cnt = 0; cnt < NJ_MAX_DIC; cnt++) {
    791         dhdl = cursor->cond.ds->dic[cnt].handle;
    792 
    793         if (dhdl != NULL) {
    794             if ((cursor->cond.ds->dic[cnt].dic_freq[NJ_MODE_TYPE_HENKAN].base
    795                  > cursor->cond.ds->dic[cnt].dic_freq[NJ_MODE_TYPE_HENKAN].high)) {
    796                     return NJ_SET_ERR_VAL(NJ_FUNC_CHECK_SEARCH_CURSOR, NJ_ERR_DIC_FREQ_INVALID);
    797                 }
    798         }
    799     }
    800 
    801     if( prev_info->count == 0 ) {
    802         cursor->cond.hinsi.yominasi_fore = NULL;
    803     } else {
    804         int prev_hinsi = prev_info->selection_data.b_hinsi;
    805 
    806 
    807         njd_r_get_connect(cursor->cond.ds->rHandle[NJ_MODE_TYPE_HENKAN], prev_hinsi,
    808                           0, &(cursor->cond.hinsi.yominasi_fore));
    809         njd_r_get_count(cursor->cond.ds->rHandle[NJ_MODE_TYPE_HENKAN],
    810                         &(cursor->cond.hinsi.foreSize), &(cursor->cond.hinsi.rearSize));
    811     }
    812 
    813     return njd_search_word(iwnn, cursor, 0, &exit_flag);
    814 }
    815 
    816 
    817 NJ_EXTERN NJ_INT16 njx_get_word(NJ_CLASS *iwnn, NJ_CURSOR *cursor, NJ_RESULT *result) {
    818     NJ_INT16  ret;
    819 
    820 
    821 
    822     if (iwnn == NULL) {
    823         return NJ_SET_ERR_VAL(NJ_FUNC_NJ_GET_WORD, NJ_ERR_PARAM_ENV_NULL);
    824     }
    825     if (cursor == NULL) {
    826         return NJ_SET_ERR_VAL(NJ_FUNC_NJ_GET_WORD, NJ_ERR_PARAM_CURSOR_NULL);
    827     }
    828     if (result == NULL) {
    829         return NJ_SET_ERR_VAL(NJ_FUNC_NJ_GET_WORD, NJ_ERR_PARAM_RESULT_NULL);
    830     }
    831 
    832     ret = njd_get_word(iwnn, cursor, result, 0);
    833 
    834     return ret;
    835 }
    836 
    837 
    838 
    839 NJ_EXTERN NJ_INT16 njx_check_dic(NJ_CLASS *iwnn, NJ_DIC_HANDLE handle, NJ_UINT8 restore, NJ_UINT32 size) {
    840 
    841 
    842     if (iwnn == NULL) {
    843         return NJ_SET_ERR_VAL(NJ_FUNC_NJ_CHECK_DIC, NJ_ERR_PARAM_ENV_NULL);
    844     }
    845 
    846     if (handle == NULL) {
    847         return NJ_SET_ERR_VAL(NJ_FUNC_NJ_CHECK_DIC, NJ_ERR_DIC_HANDLE_NULL);
    848     }
    849 
    850 
    851 
    852     if (size <= NJ_DIC_COMMON_HEADER_SIZE) {
    853         return NJ_SET_ERR_VAL(NJ_FUNC_NJ_CHECK_DIC, NJ_ERR_AREASIZE_INVALID);
    854     }
    855 
    856 
    857 
    858     if (size != (NJ_DIC_COMMON_HEADER_SIZE
    859                  + NJ_INT32_READ(handle + NJ_DIC_POS_DATA_SIZE)
    860                  + NJ_INT32_READ(handle + NJ_DIC_POS_EXT_SIZE))) {
    861         return NJ_SET_ERR_VAL(NJ_FUNC_NJ_CHECK_DIC, NJ_ERR_AREASIZE_INVALID);
    862     }
    863 
    864     return njd_check_dic(iwnn, handle);
    865 }
    866 
    867 NJ_INT16 njd_init_search_location_set(NJ_SEARCH_LOCATION_SET* loctset)
    868 {
    869 
    870     loctset->cache_freq         = 0;
    871     loctset->dic_freq.base      = 0;
    872     loctset->dic_freq.high      = 0;
    873     loctset->loct.type          = NJ_DIC_H_TYPE_NORMAL;
    874     loctset->loct.handle        = NULL;
    875     loctset->loct.current_info  = 0x10;
    876     loctset->loct.current       = 0;
    877     loctset->loct.top           = 0;
    878     loctset->loct.bottom        = 0;
    879     loctset->loct.current_cache = 0;
    880     loctset->loct.status        = NJ_ST_SEARCH_NO_INIT;
    881 
    882     return 1;
    883 }
    884 
    885 NJ_INT16 njd_init_word(NJ_WORD* word)
    886 {
    887 
    888     word->yomi                  = NULL;
    889     word->stem.info1            = 0;
    890     word->stem.info2            = 0;
    891     word->stem.hindo            = 0;
    892     word->fzk.info1             = 0;
    893     word->fzk.info2             = 0;
    894     word->fzk.hindo             = 0;
    895 
    896     word->stem.loc.handle       = NULL;
    897     word->stem.loc.type         = NJ_DIC_H_TYPE_NORMAL;
    898     word->stem.loc.current      = 0;
    899     word->stem.loc.top          = 0;
    900     word->stem.loc.bottom       = 0;
    901     word->stem.loc.current_cache= 0;
    902     word->stem.loc.current_info = 0x10;
    903     word->stem.loc.status       = NJ_ST_SEARCH_NO_INIT;
    904 
    905     return 1;
    906 }
    907