1/* Copyright 1994 NEC Corporation, Tokyo, Japan. 2 * 3 * Permission to use, copy, modify, distribute and sell this software 4 * and its documentation for any purpose is hereby granted without 5 * fee, provided that the above copyright notice appear in all copies 6 * and that both that copyright notice and this permission notice 7 * appear in supporting documentation, and that the name of NEC 8 * Corporation not be used in advertising or publicity pertaining to 9 * distribution of the software without specific, written prior 10 * permission. NEC Corporation makes no representations about the 11 * suitability of this software for any purpose. It is provided "as 12 * is" without express or implied warranty. 13 * 14 * NEC CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN 16 * NO EVENT SHALL NEC CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 18 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 19 * OTHER TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 */ 22 23#if !defined(lint) && !defined(__CODECENTER__) 24static char rcs_id[] = "$Id: permdic.c 14875 2005-11-12 21:25:31Z bonefish $"; 25#endif 26 27#include <unistd.h> 28#include <string.h> 29#include "RKintern.h" 30#include <fcntl.h> 31 32#define dm_xdm dm_extdata.ptr 33#ifndef WIN 34#define df_fdes df_extdata.var 35#else 36#define df_fdes df_extdata.hnd 37#endif 38 39extern unsigned _RkCalcLVO(); 40 41#ifdef MMAP 42/* If you compile with Visual C++, then please comment out the next 3 lines. */ 43#include <sys/types.h> /* mmap */ 44#include <sys/mman.h> /* mmap */ 45#include <fcntl.h> /* mmap */ 46extern int fd_dic; /* mmap */ 47#endif 48 49static unsigned char *assurep(struct ND *dic, int id); 50static int readThisCache(struct DM *dm, struct ND *xdm, long pgno, unsigned long val, WCHAR_T *key, int cur, int ylen, struct nread *nread, int mc, int nc, int *cf); 51static int SearchInPage(struct DM *dm, struct ND *xdm, long pgno, unsigned char *buf, unsigned long val, WCHAR_T *key, int cur, int ylen, struct nread *nread, int mc, int nc, int *cf); 52static int SearchInDir(struct DM *dm, struct ND *xdm, unsigned char *pos, WCHAR_T *key, int cur, int ylen, struct nread *nread, int mc, int nc, int *cf); 53static void ch_perm(struct DM *qm, unsigned offset, int size, int num); 54 55inline int 56openDF(struct DF *df, char *dfnm, int *w) 57{ 58 struct HD hd; 59 struct ND nd, *xnd; 60 struct DM *dm, *dmh; 61 off_t off; 62 unsigned char ll[4]; 63 int count = 0, err; 64#ifdef WIN 65 HANDLE fd; 66 DWORD readsize; 67 HANDLE errres = INVALID_HANDLE_VALUE; 68#else 69 int fd; 70 int errres = -1; 71#endif 72 73 *w = 0; 74#ifdef WIN 75 fd = CreateFile(dfnm, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 76 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 77 78 if (fd == INVALID_HANDLE_VALUE) { 79 return fd; 80 } 81#else 82 if ((fd = open(dfnm, 0)) == -1) 83 return errres; 84#endif 85 86 for (off = 0, err = 0; !err && _RkReadHeader(fd, &hd, off) >= 0;) { 87 88 if (hd.flag[HD_CODM] > 0) { 89 _RkClearHeader(&hd); 90 break; 91 } 92 nd.time = hd.data[HD_TIME].var; 93 nd.rec = hd.data[HD_REC].var; 94 nd.can = hd.data[HD_CAN].var; 95 nd.doff = off + hd.data[HD_HSZ].var; 96 nd.sz = hd.data[HD_SIZ].var; 97 nd.drsz = hd.data[HD_PGOF].var - hd.data[HD_DROF].var; 98 nd.pgsz = _RkCalcUnlog2(hd.data[HD_L2P].var) + 1; 99 nd.ttlpg = hd.data[HD_PAG].var; 100 nd.fd = fd; 101 nd.buf = (unsigned char *)0; 102 nd.pgs = (struct NP *)0; 103 off += hd.data[HD_SIZ].var; 104 if (!strncmp(".swd", 105 (char *)(hd.data[HD_DMNM].ptr 106 + strlen((char *)hd.data[HD_DMNM].ptr) - 4), 107 4)) { 108#ifndef WIN 109 if (lseek(fd, off, 0) < 0 || read(fd, (char *)ll, 4) != 4) 110 err++; 111#else 112 if (SetFilePointer(fd, off, NULL, FILE_BEGIN) == 0xFFFFFFFF || 113 !ReadFile(fd, (char *)ll, 4, &readsize, NULL) || readsize != 4) { 114 err++; 115 } 116#endif 117 off += bst4_to_l(ll) + 4; 118 } 119 dmh = &df->df_members; 120 for (dm = dmh->dm_next; dm != dmh; dm = dm->dm_next) { 121 if (!strcmp((char *)dm->dm_dicname, (char *)hd.data[HD_DMNM].ptr)) { 122 if (!dm->dm_xdm) { 123 if (!(xnd = (struct ND *)malloc(sizeof(struct ND)))) 124 break; 125 dm->dm_xdm = (pointer)xnd; 126 *xnd = nd; 127 dm->dm_flags |= DM_EXIST; 128 dm->dm_offset = xnd->doff; 129 count++; 130 break; 131 } 132 } 133 } 134 _RkClearHeader(&hd); 135 } 136 _RkClearHeader(&hd); 137 df->df_size = off; 138 if (!count) { 139#ifndef WIN 140 (void)close(fd); 141#else 142 CloseHandle(fd); 143#endif 144 return errres; 145 } 146 return (df->df_fdes = fd); 147} 148 149int 150_Rkpopen(struct DM *dm, char *dfnm, int mode, struct RkKxGram *gram) /* ARGSUSED */ 151{ 152 struct DF *df; 153 struct DD *dd; 154 struct ND *xdm; 155 int writable, i, readsize; 156#ifndef WIN 157 int fd; 158#else 159 HANDLE fd; 160#endif 161 162 if (!(df = dm->dm_file) || !(dd = df->df_direct)) 163 return -1; 164 if (!df->df_rcount) { 165#ifndef WIN 166 if ((df->df_fdes = (long)openDF(df, dfnm, &writable)) < 0) 167 return -1; 168#else 169 if ((df->df_fdes = openDF(df, dfnm, &writable)) == INVALID_HANDLE_VALUE) { 170 return -1; 171 } 172#endif 173 if (writable) 174 df->df_flags |= DF_WRITABLE; 175 else 176 df->df_flags &= ~DF_WRITABLE; 177 df->df_flags |= DF_EXIST; 178 dd->dd_rcount++; 179 } 180 if (!(dm->dm_flags & DM_EXIST)) 181 return -1; 182 df->df_rcount++; 183 xdm = (struct ND *)dm->dm_xdm; 184 fd = df->df_fdes; 185 186 if (!(xdm->buf = (unsigned char *)malloc((size_t)xdm->drsz))) { 187 return(-1); 188 } 189 if (!(xdm->pgs 190 = (struct NP *)malloc((size_t)(sizeof(struct NP) * xdm->ttlpg)))) { 191 free(xdm->buf); 192 xdm->buf = (unsigned char *)0; 193 return(-1); 194 } 195 for (i = 0; i < (int)xdm->ttlpg; i++) { 196 xdm->pgs[i].lnksz = (unsigned) 0; 197 xdm->pgs[i].ndsz = (unsigned) 0; 198 xdm->pgs[i].lvo = (unsigned long) 0; 199 xdm->pgs[i].csn = (unsigned long) 0; 200 xdm->pgs[i].flags = (unsigned) 0; 201 xdm->pgs[i].count = 0; 202 xdm->pgs[i].buf = (unsigned char *) 0; 203 } 204 205#ifndef WIN 206 (void)lseek(fd, xdm->doff, 0); 207 readsize = read(fd, (char *)xdm->buf, (unsigned int) xdm->drsz); 208#else 209 SetFilePointer(fd, xdm->doff, NULL, FILE_BEGIN); 210 if (!ReadFile(fd, (char *)xdm->buf, (unsigned int)xdm->drsz, 211 &readsize, NULL)) { 212 readsize = 0; 213 } 214#endif 215 if (readsize != ((int) xdm->drsz)) { 216 free(xdm->pgs); 217 free(xdm->buf); 218 xdm->buf = (unsigned char *)0; 219 xdm->pgs = (struct NP *)0; 220 return(-1); 221 } 222 if (dm->dm_class == ND_SWD) { 223 struct RkKxGram *gram; 224 225#ifndef WIN 226 lseek(fd, xdm->doff + xdm->drsz + xdm->ttlpg * xdm->pgsz, 0); 227#else 228 SetFilePointer(fd, xdm->doff + xdm->drsz + xdm->ttlpg * xdm->pgsz, NULL, 229 FILE_BEGIN); 230#endif 231 gram = RkReadGram(fd); 232 if (gram) { 233 dm->dm_gram = (struct RkGram *)malloc(sizeof(struct RkGram)); 234 if (dm->dm_gram) { 235 dm->dm_gram->gramdic = gram; 236 dm->dm_gram->P_BB = RkGetGramNum(gram, "BB"); 237 dm->dm_gram->P_NN = RkGetGramNum(gram, "NN"); 238 dm->dm_gram->P_T00 = RkGetGramNum(gram, "T00"); 239 dm->dm_gram->P_T30 = RkGetGramNum(gram, "T30"); 240 dm->dm_gram->P_T35 = RkGetGramNum(gram, "T35"); 241#ifdef FUJIEDA_HACK 242 dm->dm_gram->P_KJ = RkGetGramNum(gram, "KJ"); 243#endif 244 dm->dm_gram->refcount = 1; 245 goto next; 246 } 247 RkCloseGram(gram); 248 } 249 } 250 251 next: 252 if ((mode & DM_WRITABLE) && (df->df_flags & DF_WRITABLE)) { 253 dm->dm_flags |= DM_WRITABLE; 254 } 255 return 0; 256} 257 258int 259_Rkpclose(struct DM *dm, char *dfnm, struct RkKxGram *gram) /* ARGSUSED */ 260{ 261 struct DF *df = dm->dm_file; 262 struct ND *xdm = (struct ND *)dm->dm_xdm; 263 int i; 264 265 _RkKillCache(dm); 266 if (dm->dm_gram) { 267 dm->dm_gram->refcount--; 268 if (dm->dm_gram->refcount == 0) { 269 (void)RkCloseGram(dm->dm_gram->gramdic); 270 free(dm->dm_gram); 271 } 272 } 273 if (xdm) { 274 if (xdm->pgs) { 275 for (i = 0; i < (int)xdm->ttlpg; i++) 276 if (xdm->pgs[i].flags & RK_PG_LOADED) { 277#ifdef MMAP 278 if (((int) (xdm->pgs[i].buf)) != -1) 279 munmap((caddr_t)xdm->pgs[i].buf, xdm->pgsz); 280#else 281 if (xdm->pgs[i].buf) { 282 free(xdm->pgs[i].buf); 283 } 284#endif 285 xdm->pgs[i].flags &= ~RK_PG_LOADED; 286 } 287 free(xdm->pgs); 288 xdm->pgs = (struct NP *)0; 289 } 290 if (xdm->buf) { 291 free( xdm->buf); 292 xdm->buf = (unsigned char *)0; 293 } 294 } 295 296 if (--df->df_rcount == 0) { 297#ifndef WIN 298 int fd; 299#else 300 HANDLE fd; 301#endif 302 struct DM *dmh, *ddm; 303 304 fd = df->df_fdes; 305 306#ifndef WIN 307 (void)close(fd); 308#else 309 CloseHandle(fd); 310#endif 311 dmh = &df->df_members; 312 for (ddm = dmh->dm_next; ddm != dmh; ddm = ddm->dm_next) { 313 xdm = (struct ND *)ddm->dm_xdm; 314 if (xdm) { 315 free(xdm); 316 ddm->dm_xdm = (pointer)0; 317 } 318 } 319 } 320 return 0; 321} 322 323static 324unsigned char * 325assurep(struct ND *dic, int id) 326{ 327 off_t off = dic->doff + dic->drsz + dic->pgsz * id; 328 unsigned size = dic->pgsz; 329 unsigned char *buf; 330 int i; 331#ifndef WIN 332 int fd; 333#else 334 HANDLE fd; 335#endif 336 337 fd = dic->fd; 338 if (!dic->pgs) 339 return((unsigned char *)0); 340 if ((unsigned)id >= dic->ttlpg) 341 return((unsigned char *)0); 342 if (!isLoadedPage(dic->pgs + id)) { 343#ifdef WIN 344 for(i = 0; i < (int)dic->ttlpg; i++) { 345 if (dic->pgs[i].flags & RK_PG_LOADED) { 346 if (_RkDoInvalidateCache((long)dic->pgs[i].buf, dic->pgsz) == 1) { 347 if (dic->pgs[i].buf) { 348 free(dic->pgs[i].buf); 349 } 350 351 dic->pgs[i].buf = (unsigned char *)0; 352 353 dic->pgs[i].lnksz = (unsigned) 0; 354 dic->pgs[i].ndsz = (unsigned) 0; 355 dic->pgs[i].lvo = (unsigned) 0; 356 dic->pgs[i].csn = (unsigned) 0; 357 dic->pgs[i].flags = (unsigned) 0; 358 dic->pgs[i].count = 0; 359 } 360 } 361 } 362#endif 363 364#ifdef MMAP 365 buf = (unsigned char *)mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd_dic, 0); 366 if ((int)buf == -1) 367 return((unsigned char *)0); 368#else 369 if (!(buf = (unsigned char *)malloc(size))) 370 return((unsigned char *)0); 371#endif 372#ifndef WIN 373 (void)lseek(fd, off, 0); 374 if (read(fd, (char *)buf, size) != (int)size) { 375 free(buf); 376 return((unsigned char *)0); 377 } 378#else 379 SetFilePointer(fd, off, NULL, FILE_BEGIN); 380 { 381 DWORD foo; 382 383 if (!ReadFile(fd, (char *)buf, size, &foo, NULL) || 384 foo != size) { 385 free(buf); 386 return (unsigned char *)0; 387 } 388 } 389#endif 390 391 dic->pgs[id].buf = buf; 392 dic->pgs[id].count = 0; 393 dic->pgs[id].flags |= RK_PG_LOADED; 394 dic->pgs[id].ndsz = bst2_to_s(buf + 2); 395 dic->pgs[id].lnksz = bst2_to_s(buf + 4); 396 dic->pgs[id].lvo = bst3_to_l(buf + 7); 397 dic->pgs[id].csn = bst3_to_l(buf + 10); 398 return(buf); 399 } else { 400 return(dic->pgs[id].buf); 401 } 402} 403 404int 405_RkEql(WCHAR_T *a, unsigned char *b, int n) 406{ 407 WCHAR_T c, d; 408 for (; n-- > 0; b += 2) { 409 c = uniqAlnum(*a++); 410 d = (*b << 8) | *(b+1); 411 if (c != d) 412 return(0); 413 } 414 return(1); 415} 416 417static 418int readThisCache(struct DM *dm, struct ND *xdm, long pgno, unsigned long val, WCHAR_T *key, int cur, int ylen, struct nread *nread, int mc, int nc, int *cf) 419{ 420 int remlen; 421 unsigned char *wrec1, *wrec; 422 423 if (xdm->pgs[pgno].buf) { 424 if (*(wrec1 = wrec = xdm->pgs[pgno].buf + val) & 0x80) 425 wrec1 += 2; 426 wrec1 += 2; 427 remlen = (*wrec >> 1) & 0x3f; 428 if (_RkEql(key + cur, (unsigned char *)wrec1, remlen)) { 429 if (remlen + cur > ylen) 430 (*cf)++; 431 else if (nc < mc) { 432 nread[nc].cache = _RkReadCache(dm, (long)wrec); 433 if (nread[nc].cache) { 434 if (_RkGetLink(xdm, pgno, val, &nread[nc].offset, &nread[nc].csn) < 0) { 435 _RkDerefCache(nread[nc].cache); 436 return(0); 437 } 438 nread[nc].nk = cur + remlen; 439 nc++; 440 } else 441 (*cf)++; 442 } else 443 (*cf)++; 444 } 445 } 446 return(nc); 447} 448 449static int 450SearchInPage(struct DM *dm, struct ND *xdm, long pgno, unsigned char *buf, unsigned long val, WCHAR_T *key, int cur, int ylen, struct nread *nread, int mc, int nc, int *cf) 451{ 452 WCHAR_T kv, wc; 453 unsigned char *pos = buf + val; 454 455 if (!*pos && !*(pos + 1)) { 456 val = ((*(pos + 2) & 0x3f) << BIT_UNIT) | *(pos + 3); 457 nc = readThisCache(dm, xdm, pgno, val, key, 458 cur, ylen, nread, mc, nc, cf); 459 if (*(pos + 2) & LAST_NODE) 460 return(nc); 461 pos += 4; 462 } 463 if (cur == ylen) { 464 (*cf)++; 465 return(nc); 466 } 467 kv = uniqAlnum(*(key + cur)); 468 for (wc = bst2_to_s(pos); wc != kv; pos += 4, wc = bst2_to_s(pos)) { 469 if (*(pos + 2) & LAST_NODE) 470 return(nc); 471 } 472 val = ((*(pos + 2) & 0x3f) << BIT_UNIT) | *(pos + 3); 473 cur++; 474 if (*(pos + 2) & WORD_NODE) 475 nc = readThisCache(dm, xdm, pgno, val, key, 476 cur, ylen, nread, mc, nc, cf); 477 else 478 nc = SearchInPage(dm, xdm, pgno, buf, val, key, 479 cur, ylen, nread, mc, nc, cf); 480 return(nc); 481} 482 483static int 484SearchInDir(struct DM *dm, struct ND *xdm, unsigned char *pos, WCHAR_T *key, int cur, int ylen, struct nread *nread, int mc, int nc, int *cf) 485{ 486 WCHAR_T kv, wc, nw; 487 unsigned long val; 488 long next, pgno, iw; 489 unsigned char *p; 490 491 nw = bst2_to_s(pos); 492 pos += 5; 493 if (!*pos && !*(pos + 1)) { 494 val = bst3_to_l(pos + 2); 495 if (val & ~VMASK) { 496 val &= VMASK; 497 pgno = (val - xdm->drsz) / xdm->pgsz; 498 val -= pgno * xdm->pgsz + xdm->drsz; 499 if (assurep(xdm, pgno)) 500 nc = readThisCache(dm, xdm, pgno, val, key, 501 cur, ylen, nread, mc, nc, cf); 502 } 503 } 504 if (cur == ylen) { 505 (*cf)++; 506 return(nc); 507 } 508 kv = uniqAlnum(*(key + cur)); 509 next = (int)(kv % nw); 510 do { 511 p = pos + (((WCHAR_T) next++) % nw) * 5; 512 if ((wc = bst2_to_s(p)) == 0xffff) 513 return(nc); 514 } while (wc != kv); 515 val = bst3_to_l(p + 2); 516 cur++; 517 iw = (val & ~VMASK); 518 val &= VMASK; 519 if (iw) { 520 pgno = (val - xdm->drsz) / xdm->pgsz; 521 val -= pgno * xdm->pgsz + xdm->drsz; 522 if (assurep(xdm, pgno)) 523 nc = readThisCache(dm, xdm, pgno, val, key, 524 cur, ylen, nread, mc, nc, cf); 525 } else { 526 if (val < xdm->drsz) 527 nc = SearchInDir(dm, xdm, xdm->buf + val, key, 528 cur, ylen, nread, mc, nc, cf); 529 else { 530 pgno = (val - xdm->drsz) / xdm->pgsz; 531 val -= pgno * xdm->pgsz + xdm->drsz; 532 p = assurep(xdm, pgno); 533 if (p) 534 nc = SearchInPage(dm, xdm, pgno, p, val, key, 535 cur, ylen, nread, mc, nc, cf); 536 } 537 } 538 return(nc); 539} 540 541int 542_Rkpsearch(struct RkContext *cx, struct DM *dm, WCHAR_T *key, int n, struct nread *nread, int mc, int *cf) 543/* ARGSUSED */ 544{ 545 struct ND *xdm; 546 547 *cf = 0; 548 xdm = (struct ND *)dm->dm_xdm; 549 if (xdm) { 550 if (xdm->buf) 551 return(SearchInDir(dm, xdm, xdm->buf, key, 0, n, nread, mc, 0, cf)); 552 } 553 return(0); 554} 555 556int 557_Rkpio(struct DM *dm, struct ncache *cp, int io) 558/* ARGSUSED */ 559{ 560 if (io == 0) { 561 cp->nc_word = (Wrec *)cp->nc_address; 562 cp->nc_flags |= NC_NHEAP; 563 } 564 return 0; 565} 566 567#if 0 /* »È¤ï¤ì¤Æ¤¤¤Ê¤¤¤Î¤Ç¤È¤ê¤¢¤¨¤º¥³¥á¥ó¥È¤Ë¤¹¤ë */ 568static void 569ch_perm(struct DM *qm, unsigned offset, int size, int num) 570{ 571 unsigned char tmp[8192]; 572 /* I leave this stack located array because of it is not used */ 573 574 if (num > 0) { 575 _RkCopyBits(tmp, 0, size, qm->dm_qbits, offset, num); 576 _RkCopyBits(qm->dm_qbits, offset + 0, size, 577 qm->dm_qbits, offset + num*size, 1); 578 _RkCopyBits(qm->dm_qbits, offset + size, size, tmp, 0, num); 579 } 580} 581#endif 582 583#define PERM_WRECSIZE 2048 584#define PERM_NREADSIZE 128 585 586int 587_Rkpctl(struct DM *dm, struct DM *qm, int what, WCHAR_T *arg, struct RkKxGram *gram) 588{ 589 int nc, cf = 0, ret = -1; 590 struct ND *xdm; 591 unsigned long lucks[2]; 592#ifndef USE_MALLOC_FOR_BIG_ARRAY 593 Wrec wrec[PERM_WRECSIZE]; 594 WCHAR_T key[64]; 595 struct nread nread[PERM_NREADSIZE]; 596 unsigned permutation[RK_CAND_NMAX]; 597#else 598 Wrec *wrec; 599 WCHAR_T *key; 600 struct nread *nread; 601 unsigned *permutation; 602 wrec = (Wrec *)malloc(sizeof(Wrec) * PERM_WRECSIZE); 603 key = (WCHAR_T *)malloc(sizeof(WCHAR_T) * 64); 604 nread = (struct nread *)malloc(sizeof(struct nread) * PERM_NREADSIZE); 605 permutation = (unsigned *)malloc(sizeof(unsigned) * RK_CAND_NMAX); 606 if (!wrec || !key || !nread || !permutation) { 607 if (wrec) free(wrec); 608 if (key) free(key); 609 if (nread) free(nread); 610 if (permutation) free(permutation); 611 return ret; 612 } 613#endif 614 615 if (!dm || !qm || (qm && !qm->dm_qbits)) { 616 goto done; 617 } 618 619 if ((qm->dm_flags & (DM_WRITABLE | DM_WRITEOK)) == 620 (DM_WRITABLE | DM_WRITEOK)) { 621 /* (writable and write ok) */ 622 623 if (RkParseOWrec(gram, arg, wrec, PERM_WRECSIZE, lucks)) { 624 Wrec *p, *q, *kanji; 625 WCHAR_T *wkey; 626 int maxcache = PERM_NREADSIZE; 627 int ylen, klen, cnum, y_off = 2, k_off; 628 629 630 ylen = (wrec[0] >> 1) & 0x3f; 631 if (wrec[0] & 0x80) 632 y_off += 2; 633 p = wrec + y_off; 634 q = p + (ylen * 2); 635 for (wkey = key; p < q ; wkey++) { 636 *wkey = (*p << 8) | *(p + 1); 637 p += 2; 638 } 639 *(key+ylen) = 0; 640 641 /* Éʻ졢´Á»ú¾ðÊó¤Î¼è¤ê½Ð¤· */ 642 k_off = y_off + ylen * 2; 643 klen = (wrec[k_off] >> 1) & 0x7f; 644 cnum = ((wrec[k_off] & 0x01) << 8) | wrec[k_off+1]; 645 kanji = wrec + k_off + 2; 646 647 nc = -1; 648 xdm = (struct ND *)dm->dm_xdm; 649 if (xdm) { 650 if (xdm->buf) 651 nc = SearchInDir(dm, xdm, xdm->buf, key, 0, ylen, nread, 652 maxcache, 0, &cf); 653 } 654 655 if (nc > 0) { 656 struct nread *thisRead; 657 struct ncache *thisCache; 658 unsigned char *wp; 659 int nk, nl, pre; 660 unsigned long offset; 661 int bitSize, fnum = -1, nnum, i; 662 663 for (i = 0 ; i < nc ; i++) { 664 if (nread[i].nk == ylen) { 665 break; 666 } 667 } 668 /* »È¤ï¤Ê¤¤Ã±¸ì¸õÊä¤Ï¤¢¤é¤«¤¸¤á _RkDerefCache ¤¹¤ë */ 669 for (pre = 0 ; pre < nc ; pre++) { 670 if (pre != i) { 671 thisRead = nread + pre; 672 thisCache = thisRead->cache; 673 _RkDerefCache(thisCache); 674 } 675 } 676 677 if (i < nc) { 678 thisRead = nread + i; 679 thisCache = thisRead->cache; 680 wp = thisCache->nc_word; 681 682 nk = _RkCandNumber(wp); 683 nl = (*wp >> 1) & 0x3f; 684 if (*wp & 0x80) 685 wp += 2; 686 wp += 2 + nl *2; 687 688 /* ¤³¤³¤ÎÉôʬ¤Ç¼½ñ¤Î²¿ÈÖÌܤˤǤƤ¯¤ë¤« (fnum) ¤òõ¤¹ */ 689 for (i = 0; i < nk; i++) { 690 unsigned char *kp; 691 692 nl = (*wp >> 1) & 0x7f; /* ¸õÊäĹ */ 693 nnum = ((*wp & 0x01) << 8) | *(wp+1); /* ÉÊ»ìÈÖ¹æ */ 694 if (nl == klen && nnum == cnum) { 695 int lc; 696 697 for (lc = 0, kp = wp + 2; lc < klen*2; lc++) { 698 if (*(kanji+lc) != *(kp+lc)) 699 break; 700 } 701 if (lc == klen*2) { 702 fnum = i; 703 break; 704 } 705 } 706 wp += 2 + nl*2; 707 } 708 709 offset = thisRead->offset; 710 if (fnum >= 0 && fnum < nk && 0 < thisRead->nk && 711 thisRead->nk <= ylen && thisRead->nk <= RK_KEY_WMAX) { 712 int ecount, cval, i, dn = -1, ndel = 0; 713 714 bitSize = _RkCalcLog2(nk + 1) + 1; 715 _RkUnpackBits(permutation, qm->dm_qbits, offset, bitSize, nk); 716 switch (what) { 717 case DST_DoDefine: 718 for (ecount = cval = i = 0; i < nk; i++) { 719 if ((int)permutation[i]/2 > nk) { 720 ecount++; 721 break; 722 }; 723 cval += permutation[i]; 724 if ((unsigned)nk == permutation[i]/2 && dn < 0) 725 dn = i; 726 if ((unsigned)fnum == permutation[i]/2) { 727 ndel = -1; 728 dn = i; 729 } 730 } 731 break; 732 case DST_DoDelete: 733 for (ecount = cval = i = 0; i < nk; i++) { 734 if ((int)permutation[i]/2 > nk) { 735 ecount++; 736 break; 737 }; 738 cval += permutation[i]; 739 if ((unsigned)fnum == permutation[i]/2) 740 dn = i; 741 }; 742 break; 743 } 744 if (ecount || cval < (nk-1)*(nk-2)) { 745 for (i = 0; i < nk; i++) 746 permutation[i] = 2*i; 747 _RkPackBits(qm->dm_qbits, offset, bitSize, permutation, nk); 748 } else { 749 if (dn >= 0) { 750 if (!ndel) { 751 switch (what) { 752 case DST_DoDefine: 753 _RkSetBitNum(qm->dm_qbits, offset, bitSize, dn, fnum*2); 754/* ¤³¤³¤Ïʤӽç¤òÊѹ¹¤¹¤ë´Ø¿ô¤À¤¬¤È¤ê¤¢¤¨¤º¥³¥á¥ó¥È¤Ë¤¹¤ë¡£ 755 ch_perm(qm, offset, bitSize, dn); 756*/ 757 break; 758 case DST_DoDelete: 759 _RkSetBitNum(qm->dm_qbits, offset, bitSize, dn, nk*2); 760 break; 761 } 762 qm->dm_flags |= DM_UPDATED; 763 } 764 _RkDerefCache(thisCache); 765 ret = 0; 766 goto done; 767 } 768 } 769 } 770 _RkDerefCache(thisCache); 771 } 772 } 773 } 774 } 775 done: 776#ifdef USE_MALLOC_FOR_BIG_ARRAY 777 free(wrec); 778 free(key); 779 free(nread); 780 free(permutation); 781#endif 782 return ret; 783} 784 785int 786_Rkpsync(struct RkContext *cx, struct DM *dm, struct DM *qm) 787{ 788 struct DF *df; 789 struct DD *dd; 790#ifdef MMAP 791 struct ND *dic; 792#endif 793 char *file; 794 795 if (qm) { 796 df = qm->dm_file; 797 dd = df->df_direct; 798 file = _RkCreatePath(dd, df->df_link); 799 if (file) { 800 int i; 801#ifdef MMAP 802 int j; 803#endif 804 i = FQsync(cx, dm, qm, file); 805 free(file); 806#ifdef MMAP 807 dic = (struct ND *)dm->dm_xdm; 808 if(dic) 809 for(j=0;j<dic->ttlpg;j++) { 810 if (isLoadedPage(dic->pgs + j)) 811 if (_RkDoInvalidateCache(dic->pgs[j].buf, dic->pgsz) == 1) { 812 if (((int) (dic->pgs[j].buf)) != -1) 813 munmap((caddr_t)dic->pgs[j].buf, dic->pgsz); 814 dic->pgs[j].buf = (unsigned char *)0; 815 dic->pgs[j].lnksz = (unsigned) 0; 816 dic->pgs[j].ndsz = (unsigned) 0; 817 dic->pgs[j].lvo = (unsigned) 0; 818 dic->pgs[j].csn = (unsigned) 0; 819 dic->pgs[j].flags = (unsigned) 0; 820 dic->pgs[j].count = 0; 821 } 822 } 823#endif 824 return (i); 825 } 826 } 827 return (0); 828} 829