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