Back to index

im-sdk  12.3.91
TestCk.c
Go to the documentation of this file.
00001 #include  <stdio.h>
00002 #include  <string.h>
00003 #include  <stdlib.h>
00004 
00005 #include  <sys/types.h>
00006 #include  <sys/stat.h>
00007 #include  <fcntl.h>
00008 
00009 #include  "GeneType.h"
00010 #include  "PyBasic.h"
00011 #include  "ciku.h"
00012 
00013 JINT    Hzcode2244ToYjSMcode(JINT nHzcode);
00014 JINT    Hzcode2244ToYjcode(JINT nHzcode);
00015 UCHAR*  RecovDyz2244(UCHAR *szDyz2244);
00016 VOID    InitStructSc(SysCandi* psc);
00017 JINT    EnumSysCandi(JINT* pnOrgYj, JINT nLenYj, SysCandi* psc, JINT* pnSize, JWORD* pwCandiBuf, JINT nMatchMode, JINT nMode);
00018 SysCandi* LookupSysCiku(JINT *pnOrgYj, JINT nLenYj, JINT nMatchMode);
00019 VOID    SortSysCandi(SysCandi* psc);
00020 
00021 static  BYTE   *pCkAll;
00022 
00023 /*
00024 **  Read out all those data in System Ciku file to pCkAll.
00025 */
00026 JINT GetCikuData(CHAR* szSysCikuName)
00027 {
00028        FILE*   pfCiku;
00029        JINT    i, k;
00030        JINT    nFileSize;
00031        
00032        CikuHeader  *pCkh;
00033        ShIndex     *pShi;
00034        DhIndex     *pDhi;
00035        MhIndex     *pMhi;
00036        GbkIndex    *pGbki;
00037        BYTE        *pShArea;
00038        BYTE        *pDhArea;
00039        BYTE        *pMhArea;
00040        BYTE        *pGbkArea;
00041        
00042        pfCiku = fopen(szSysCikuName, "rb");
00043        if (pfCiku == NULL)
00044        {
00045               fprintf(stderr, "Failed to fopen() System Ciku File: %s\n", szSysCikuName);
00046               return FALSE;
00047        }
00048        
00049        pCkh = (CikuHeader*)malloc(sizeof(CikuHeader));
00050        if (pCkh == NULL)
00051        {
00052               fprintf(stderr, "Failed to malloc() for pCkh in GetCikuInfo.\n");     
00053               return FALSE;
00054        }
00055        
00056        fseek(pfCiku, 0, SEEK_SET);
00057        if (fread (pCkh, 1, sizeof(CikuHeader), pfCiku) != sizeof(CikuHeader) )
00058        {
00059               fprintf(stderr, "Failed to fread() System Ciku Header.\n");
00060               return FALSE;
00061        }
00062        
00063        /* Check Magic Word in Header */
00064        if ((pCkh->nMagicDescHi != 0x35303539) || (pCkh->nMagicDescLow != 0x34333442))
00065        {
00066               fprintf(stderr, "This is not the valid System Ciku Data File.\n");
00067               return FALSE;
00068        }
00069        nFileSize = pCkh->nFileSize;
00070        
00071        fseek(pfCiku, 0, SEEK_END);
00072        if (nFileSize != ftell(pfCiku))
00073        {
00074               fprintf(stderr, "System Ciku File was demaged.\n");
00075               return FALSE;
00076        }
00077        
00078        free(pCkh);
00079        pCkh = NULL;
00080        
00081        pCkAll = (BYTE*)malloc(nFileSize);
00082        if (pCkAll == NULL)
00083        {
00084               fprintf(stderr, "Failed to malloc() for pCkAll in GetCikuInfo.\n");
00085               return FALSE;
00086        }
00087        
00088        fseek(pfCiku, 0, SEEK_SET);
00089        if ((JINT)fread (pCkAll, 1, nFileSize, pfCiku) != nFileSize )
00090        {
00091               fprintf(stderr, "Failed to fread() System Ciku File.\n");
00092               return FALSE;
00093        }
00094        fclose(pfCiku);
00095        
00096        pCkh     = (CikuHeader *)pCkAll;
00097        pShi     = (ShIndex  *)(pCkAll + pCkh->nIdxShPos);
00098        pDhi     = (DhIndex  *)(pCkAll + pCkh->nIdxDhPos);
00099        pMhi     = (MhIndex  *)(pCkAll + pCkh->nIdxMhPos);
00100        pGbki    = (GbkIndex *)(pCkAll + pCkh->nIdxGbkPos);
00101        
00102        pShArea  = (BYTE *)(pCkAll + pShi->nStartPos);
00103        pDhArea  = (BYTE *)(pCkAll + pDhi->nStartPos);
00104        pMhArea  = (BYTE *)(pCkAll + pMhi->nStartPos);
00105        pGbkArea = (BYTE *)(pCkAll + pGbki->nStartPos);
00106        
00107        for(i = 0; i < NUM_YINJIE; i++)
00108               for(k = (pShi->nYjOff[i] & 0x00FFFFFF); k < (pShi->nYjOff[i + 1] & 0x00FFFFFF); k++)
00109                      *(pShArea + k) ^= (BYTE)((i + 56) / 2);
00110 
00111        for(i = 0; i < NUM_YINJIE; i++)
00112               for(k = pDhi->nYjOff[i]; k < pDhi->nYjOff[i + 1]; k++)
00113                      *(pDhArea + k) ^= (BYTE)((i + 56) / 2);
00114 
00115        for(i = 0; i < NUM_YINJIE; i++)
00116               for(k = pMhi->nYjOff[i]; k < pMhi->nYjOff[i + 1]; k++)
00117                      *(pMhArea + k) ^= (BYTE)((i + 56) / 2);
00118 
00119        for(i = 0; i < NUM_YINJIE; i++)
00120               for(k = pGbki->nYjOff[i]; k < pGbki->nYjOff[i + 1]; k++)
00121                      *(pGbkArea + k) ^= (BYTE)((i + 56) / 2);
00122 
00123        return TRUE;
00124 }
00125 
00126 
00127 JINT WriteCikuData(CHAR* szSysCikuName, JINT nTimeStamp)
00128 {
00129        FILE*   pfCiku;
00130        JINT    i, k;
00131        JINT    nFileSize;
00132        
00133        CikuHeader  *pCkh;
00134        ShIndex     *pShi;
00135        DhIndex     *pDhi;
00136        MhIndex     *pMhi;
00137        GbkIndex    *pGbki;
00138        BYTE        *pShArea;
00139        BYTE        *pDhArea;
00140        BYTE        *pMhArea;
00141        BYTE        *pGbkArea;
00142 
00143        pCkh     = (CikuHeader *)pCkAll;
00144        pShi     = (ShIndex  *)(pCkAll + pCkh->nIdxShPos);
00145        pDhi     = (DhIndex  *)(pCkAll + pCkh->nIdxDhPos);
00146        pMhi     = (MhIndex  *)(pCkAll + pCkh->nIdxMhPos);
00147        pGbki    = (GbkIndex *)(pCkAll + pCkh->nIdxGbkPos);
00148        
00149        pShArea  = (BYTE *)(pCkAll + pShi->nStartPos);
00150        pDhArea  = (BYTE *)(pCkAll + pDhi->nStartPos);
00151        pMhArea  = (BYTE *)(pCkAll + pMhi->nStartPos);
00152        pGbkArea = (BYTE *)(pCkAll + pGbki->nStartPos);
00153        
00154        pCkh->nLatestTime = nTimeStamp;
00155        
00156        for(i = 0; i < NUM_YINJIE; i++)
00157               for(k = (pShi->nYjOff[i] & 0x00FFFFFF); k < (pShi->nYjOff[i + 1] & 0x00FFFFFF); k++)
00158                      *(pShArea + k) ^= (BYTE)((i + 56) / 2);
00159 
00160        for(i = 0; i < NUM_YINJIE; i++)
00161               for(k = pDhi->nYjOff[i]; k < pDhi->nYjOff[i + 1]; k++)
00162                      *(pDhArea + k) ^= (BYTE)((i + 56) / 2);
00163 
00164        for(i = 0; i < NUM_YINJIE; i++)
00165               for(k = pMhi->nYjOff[i]; k < pMhi->nYjOff[i + 1]; k++)
00166                      *(pMhArea + k) ^= (BYTE)((i + 56) / 2);
00167        
00168        for(i = 0; i < NUM_YINJIE; i++)
00169               for(k = pGbki->nYjOff[i]; k < pGbki->nYjOff[i + 1]; k++)
00170                      *(pGbkArea + k) ^= (BYTE)((i + 56) / 2);
00171 
00172        /* Write These data back to file */
00173        pfCiku = fopen(szSysCikuName, "wb");
00174        if (pfCiku == NULL)
00175        {
00176               fprintf(stderr, "Failed to Create System Ciku File: %s\n", szSysCikuName);
00177               return FALSE;
00178        }
00179        
00180        nFileSize = pCkh->nFileSize;
00181        if ((JINT)fwrite (pCkAll, 1, nFileSize, pfCiku) != nFileSize )
00182        {
00183               fprintf(stderr, "Failed to fwrite() System Ciku File.\n");
00184               return FALSE;
00185        }
00186        
00187        return TRUE;
00188 }
00189 
00190 
00191 /*  
00192 **  pnSize:     If nMode is LU_SYSCANDI_CALC, Calculate the size need totally to contain all those SysCandis,
00193 **              and set nNumShCandi, nNumDhCandi, nNumMhCandi, nSizShCandi, nSizDhCandi, nSizMhCandi of struct psc.
00194 **              [pnSize is in JWORD]
00195 **
00196 **  nMatchMode: LU_MATCH_STRICT   ==> Match Strictly. Used by nLenYj >= 5. Condition: nCzLen == nLenYj  
00197 **              LU_MATCH_WIDELY   ==> Match Widely.   Used by nLenYj >= 5. Condition: nCzLen >= nLenYj
00198 **              Condition for LU_MATCH_WIDLY:
00199 **                        zhong hua ren min gong // zhong hua ren min gong h  // zhong hua ren min gong he
00200 **              Condition for LU_MATCH_STRICT:  => Last YjString is unmatched and meanless.
00201 **                        zhong hua ren min gong [go gon cho chon cua]
00202 **
00203 **  nMode:      LU_SYSCANDI_WRITE ==> Write all those SysCandis to allocated memory for Sh, Dh, Mh Candidates.
00204 **                                    [Certainly, make *pwShCandi, *pwDhCandi, *pwMhCandi point to *(pwCandiBuf + ?) first.]
00205 **              LU_SYSCANDI_CALC  ==> Calculate the space size which needed to contain all those SysCandis.
00206 **
00207 **  NOTES:      Structure psc was filled after two calling of this function: First in Mode LU_SYSCANDI_CALC,
00208 **              second in Mode LU_SYSCANDI_WRITE.
00209 **
00210 **  Content of pwCandiBuf == pwMhCandi + pwDhCandi + pwShCandi + 0x0000
00211 **             Mh: fhhhhhh0fhhh0fhhhh0
00212 **             Dh: fhh0fhh0fhh0fhh0fhh0fhh0fhh0fhh0fhh0fhh0fhh0fhh0
00213 **             Sh: XX0XX0h0h0h0h0h0h0h0h0h0h0h0 + 0     OR
00214 **                 Q0Q0Q0Q0Q0Q0Q0h0h0h0h0h0h0h0h0 + 0
00215 */
00216 JINT EnumSysCandi(JINT* pnOrgYj, JINT nLenYj, SysCandi* psc, JINT* pnSize, JWORD* pwCandiBuf, JINT nMatchMode, JINT nMode)
00217 {
00218        JINT    nFromOff, nToOff;
00219        JINT    nFromYj, nToYj, nTmp, nXianNum;     /* For Single Hanzi Area Searching */
00220        UCHAR   chHi, chLow;                      /* For Single Hanzi Area Searching */
00221        JINT    nCzLen, m, k;
00222        JWORD   wCzHz[10], wMhLenFreq, wDhFreq;
00223        JINT    nEqualFlag;
00224        CHAR    *pszYj1, *pszYj2;                 /* For DhCandi, compare string directly */
00225        CHAR    szYj3[12], szYj4[12];
00226        
00227        CikuHeader  *pCkh;
00228        ShIndex     *pShi;
00229        DhIndex     *pDhi;
00230        MhIndex     *pMhi;
00231        BYTE        *pShArea;
00232        BYTE        *pDhArea;
00233        BYTE        *pMhArea;
00234        
00235        pCkh    = (CikuHeader *)pCkAll;
00236        pShi    = (ShIndex *)(pCkAll + pCkh->nIdxShPos);
00237        pDhi    = (DhIndex *)(pCkAll + pCkh->nIdxDhPos);
00238        pMhi    = (MhIndex *)(pCkAll + pCkh->nIdxMhPos);
00239        
00240        pShArea = (BYTE *)(pCkAll + pShi->nStartPos);
00241        pDhArea = (BYTE *)(pCkAll + pDhi->nStartPos);
00242        pMhArea = (BYTE *)(pCkAll + pMhi->nStartPos);
00243 
00244        if (nMode == LU_SYSCANDI_CALC)
00245               *pnSize  = 0;
00246        else if (nMode == LU_SYSCANDI_WRITE)
00247        {
00248               psc->pwMhCandi   = pwCandiBuf;
00249               psc->pwDhCandi   = pwCandiBuf + psc->nSizMhCandi;
00250               psc->pwShCandi   = pwCandiBuf + psc->nSizMhCandi + psc->nSizDhCandi;
00251                      
00252               psc->nSizMhCandi = 0;
00253               psc->nSizDhCandi = 0;
00254               psc->nSizShCandi = 0;
00255                      
00256               psc->nNumMhCandi = 0;
00257               psc->nNumDhCandi = 0;
00258               psc->nNumShCandi = 0;
00259        }
00260 
00261        if (nLenYj >= 3)
00262        {
00263               /*
00264               **  Determine the FromOff and ToOff which to used for searching by the pnOrgYj[0].
00265               */
00266               if ((pnOrgYj[0] >= 0) && (pnOrgYj[0] < NUM_YINJIE))
00267               {
00268                      nFromOff = pMhi->nYjOff[ pnOrgYj[0] ];
00269                      nToOff   = pMhi->nYjOff[ pnOrgYj[0] + 1];
00270               }
00271               else   /* ((pnOrgYj[0] >= 450) && (pnOrgYj[0] <= 475)) */
00272               {
00273                      nFromOff = pMhi->nYjOff[ INDEXSMTOYINJIE[pnOrgYj[0] - 450] ];
00274                      nToOff   = pMhi->nYjOff[ INDEXSMTOYINJIE[pnOrgYj[0] - 450 + 1] ];
00275               }
00276        
00277               /* !! DON'T add k++ in this FOR sentence !! */
00278               for (k = nFromOff; k < nToOff; )
00279               {
00280                      wMhLenFreq = (JWORD)*(pMhArea + k);
00281                      nCzLen     = 2 + ((UCHAR)*(pMhArea + k) & 0x07);
00282                      k++;
00283                      
00284                      for (m = 0; m < 10; m++)
00285                             wCzHz[m]   = 0x0000;
00286                      for (m = 0; m < nCzLen; m++)
00287                      {
00288                             wCzHz[m]   = (JWORD)(*(pMhArea + k + 1) + ((*(pMhArea + k)) << 8));
00289                             k += 2;
00290                      }
00291                      
00292                      /*
00293                      ** DON'T CONVERT wCzItem into YJSTRING and CALL ParsePreedit() HERE, BECAUSE THAT
00294                      ** IS TOO COMPLEX AND UN_LOGICALLY.
00295                      ** For Example, zai xian shi qu ==> zai xi'an shi qu [Four ~ Five !!!!]
00296                      */
00297                      nEqualFlag = FALSE;
00298                      if ( ((nCzLen == nLenYj) && ((nLenYj == 3) || (nLenYj == 4))) || 
00299                           ((nCzLen >= nLenYj) && (nLenYj >= 5)  && (nMatchMode == LU_MATCH_WIDELY)) ||
00300                           ((nCzLen == nLenYj) && (nLenYj >= 5)  && (nMatchMode == LU_MATCH_STRICT)) )
00301                      {
00302                             nEqualFlag = TRUE;
00303                             
00304                             for(m = 1; m < nLenYj; m++)
00305                                    if ( ( pnOrgYj[m] != Hzcode2244ToYjSMcode((JINT)wCzHz[m]) ) &&                      \
00306                                         ( pnOrgYj[m] != Hzcode2244ToYjcode((JINT)wCzHz[m])   ) )
00307                                    {
00308                                           nEqualFlag = FALSE;
00309                                           break;
00310                                    }
00311                      }
00312                      
00313                      if ((nEqualFlag == TRUE) && (nMode == LU_SYSCANDI_CALC))
00314                      {
00315                             psc->nSizMhCandi += (nCzLen + 2);  /* Add two JWORD Here to contain Freq&Len Word and a ZERO */
00316                             psc->nNumMhCandi += 1;
00317                             *pnSize += (nCzLen + 2);
00318                      }
00319                      else if ((nEqualFlag == TRUE) && (nMode == LU_SYSCANDI_WRITE))
00320                      {
00321                             psc->pwMhCandi[psc->nSizMhCandi] = wMhLenFreq;
00322                             for (m = 0; m < nCzLen; m++)
00323                                    psc->pwMhCandi[psc->nSizMhCandi + m + 1] = wCzHz[m];
00324                             
00325                             psc->nSizMhCandi += (nCzLen + 2);
00326                             psc->nNumMhCandi += 1;
00327                             *pnSize += (nCzLen + 2);
00328                      }
00329               }
00330        }
00331        
00332 
00333        if (nLenYj >= 2)
00334        {
00335               /*
00336               **  Determine the FromOff and ToOff which to used for searching by the pnOrgYj[0].
00337               */
00338               if ((pnOrgYj[0] >= 0) && (pnOrgYj[0] < NUM_YINJIE))
00339               {
00340                      nFromOff = pDhi->nYjOff[ pnOrgYj[0] ];
00341                      nToOff   = pDhi->nYjOff[ pnOrgYj[0] + 1];
00342               }
00343               else /* ((pnOrgYj[0] >= 450) && (pnOrgYj[0] <= 475)) */
00344               {
00345                      nFromOff = pDhi->nYjOff[ INDEXSMTOYINJIE[pnOrgYj[0] - 450] ];
00346                      nToOff   = pDhi->nYjOff[ INDEXSMTOYINJIE[pnOrgYj[0] - 450 + 1] ];
00347               }
00348        
00349               /* !! DON'T add k++ in this FOR sentence !! */
00350               for (k = nFromOff; k < nToOff; )
00351               {
00352                      wDhFreq  = (JWORD)*(pDhArea + k);
00353                      nCzLen   = 2;
00354                      k ++;
00355 
00356                      for (m = 0; m < 10; m++)
00357                             wCzHz[m]   = 0x0000;
00358                      for (m = 0; m < nCzLen; m++)
00359                      {
00360                             wCzHz[m]   = (JWORD)(*(pDhArea + k + 1) + ((*(pDhArea + k)) << 8));
00361                             k += 2;
00362                      }
00363 
00364                      for (m = 0; m < 12; m++)
00365                      {
00366                             szYj3[m]   = '\0';
00367                             szYj4[m]   = '\0';
00368                      }
00369                      
00370                      if ((pnOrgYj[0] >= 450) && (pnOrgYj[0] <= 475))
00371                             pszYj1 = SHENGMUSTR[ pnOrgYj[0] - 450 ];
00372                      else      /* ((pnOrgYj[0] >= 0) && (pnOrgYj[0] < 415)) */
00373                             pszYj1 = YINJIESTR_CSZ[ pnOrgYj[0] ];
00374 
00375                      if ((pnOrgYj[1] >= 450) && (pnOrgYj[1] <= 475))
00376                             pszYj2 = SHENGMUSTR[ Hzcode2244ToYjSMcode((JINT)wCzHz[1]) - 450];
00377                      else      /*  ((pnOrgYj[1] >= 0) && (pnOrgYj[1] < 415))  */
00378                             pszYj2 = YINJIESTR_CSZ[Hzcode2244ToYjcode( (JINT)wCzHz[1] )];
00379                      strcat(strcat(szYj3, pszYj1), pszYj2);
00380                      
00381                      if ((pnOrgYj[1] >= 450) && (pnOrgYj[1] <= 475))
00382                             pszYj2 = SHENGMUSTR[ pnOrgYj[1] - 450 ];
00383                      else if ((pnOrgYj[1] >= 0) && (pnOrgYj[1] < 415))
00384                             pszYj2 = YINJIESTR_CSZ[ pnOrgYj[1] ];
00385                      strcat(strcat(szYj4, pszYj1), pszYj2);
00386 
00387                      nEqualFlag = TRUE;
00388                      if ( strcmp (szYj3, szYj4) != 0)
00389                             nEqualFlag = FALSE;
00390                      
00391                      if ((nEqualFlag == TRUE) && (nMode == LU_SYSCANDI_CALC))
00392                      {
00393                             psc->nSizDhCandi += (nCzLen + 2);  /* Add two JWORD Here to contain Freq Word and a ZERO */
00394                             psc->nNumDhCandi += 1;
00395                             *pnSize += (nCzLen + 2);
00396                      }
00397                      else if ((nEqualFlag == TRUE) && (nMode == LU_SYSCANDI_WRITE))
00398                      {
00399                             psc->pwDhCandi[psc->nSizDhCandi] = wDhFreq;
00400                             for (m = 0; m < nCzLen; m++)
00401                                    psc->pwDhCandi[psc->nSizDhCandi + m + 1] = wCzHz[m];
00402                             
00403                             psc->nSizDhCandi += (nCzLen + 2);
00404                             psc->nNumDhCandi += 1;
00405                             *pnSize += (nCzLen + 2);
00406                      }
00407               }
00408        }
00409 
00410        if (nLenYj >= 1)
00411        {
00412               /*
00413               **  Order of Single Hanzi Candidates:
00414               **  IF pnOrgYj[0] is a SM, place HIFREQHANZI[?][14] at the head of ShCandi Area
00415               **                         Place Single Hanzi by Frequence and Yinjie Sequence
00416               **  IF pnOrgYj[0] is Normal Yinjie [0 ~ 414], place XianForm candis at the head.
00417               **                         place Single Hanzi by Frequence and Yinjie Sequence
00418               **
00419               **  Determine the Fromyj and ToYj which to used for searching by the pnOrgYj[0].
00420               **  NOTICE: This is different from DhCandi and MhCandi.  
00421               */
00422               if ((pnOrgYj[0] >= 0) && (pnOrgYj[0] < NUM_YINJIE))
00423               {
00424                      nFromYj  = pnOrgYj[0];
00425                      nToYj    = pnOrgYj[0] + 1;
00426 
00427                      nXianNum = (pShi->nYjOff[nToYj] & 0x0F000000) >> 24;
00428                      for (k = 0; k < nXianNum; k++)
00429                      {
00430                             if (nMode == LU_SYSCANDI_CALC)
00431                             {
00432                                    psc->nSizShCandi += 3;        /* Add one ZERO After this Xian Candi */
00433                                    psc->nNumShCandi += 1;
00434                                    *pnSize += 3;
00435                             }
00436                             else if (nMode == LU_SYSCANDI_WRITE)
00437                             {
00438                                    nTmp  = pShi->nYjOff[nToYj] & 0x00FFFFFF;
00439                                    chHi  = (UCHAR)*(pShArea + nTmp - (nXianNum * 4) + (k * 4));
00440                                    chLow = (UCHAR)*(pShArea + nTmp - (nXianNum * 4) + (k * 4) + 1);
00441                                    psc->pwShCandi[psc->nSizShCandi]     = (JWORD)((chHi << 8) + chLow);
00442                                    
00443                                    chHi  = (UCHAR)*(pShArea + nTmp - (nXianNum * 4) + (k * 4) + 2);
00444                                    chLow = (UCHAR)*(pShArea + nTmp - (nXianNum * 4) + (k * 4) + 3);
00445                                    psc->pwShCandi[psc->nSizShCandi + 1] = (JWORD)((chHi << 8) + chLow);
00446                                    
00447                                    psc->pwShCandi[psc->nSizShCandi + 2] = 0x0000;
00448 
00449                                    psc->nSizShCandi += 3;
00450                                    psc->nNumShCandi += 1;
00451                                    *pnSize += 3;
00452                             }
00453                      }
00454               }
00455               else   /* ((pnOrgYj[0] >= 450) && (pnOrgYj[0] <= 475)) */
00456               {
00457                      nFromYj  = INDEXSMTOYINJIE[ pnOrgYj[0] - 450 ];
00458                      nToYj    = INDEXSMTOYINJIE[ pnOrgYj[0] - 450 + 1 ];
00459 
00460                      for (m = 0; m < 7; m++)         /* There are 7 HIFREQHANZI in each SM Yinjie. See PyBasic.h */
00461                      {
00462                             if (nMode == LU_SYSCANDI_CALC)
00463                             {
00464                                    psc->nSizShCandi += 2;        /* Add one ZERO After this HIFREQHANZI */
00465                                    psc->nNumShCandi += 1;
00466                                    *pnSize += 2;
00467                             }
00468                             else if (nMode == LU_SYSCANDI_WRITE)
00469                             {
00470                                    chHi  = HIFREQHANZI[pnOrgYj[0] - 450][2 * m];
00471                                    chLow = HIFREQHANZI[pnOrgYj[0] - 450][2 * m + 1];
00472                                    psc->pwShCandi[psc->nSizShCandi]     = (JWORD)((chHi << 8) + chLow);
00473                                    
00474                                    psc->nSizShCandi += 2;
00475                                    psc->nNumShCandi += 1;
00476                                    *pnSize += 2;
00477                             }
00478                      }
00479               }
00480               
00481               /*
00482               **  Because 'Xian' Form is already included in above processing (0 ~ 414), and no necessary
00483               **  for (450 ~ 475), So, not to include then in the following reclycle.
00484               */
00485               for(k = nFromYj; k < nToYj; k++)
00486               {
00487                      nXianNum = (pShi->nYjOff[k + 1] & 0x0F000000) >> 24;
00488                      nFromOff = pShi->nYjOff[ k ] & 0x00FFFFFF;
00489                      nToOff   = (pShi->nYjOff[ k + 1] & 0x00FFFFFF) - (4 * nXianNum);
00490                      
00491                      /* !!Don't add m++ in this FOR sentence!! */
00492                      for(m = nFromOff; m < nToOff;  )
00493                      {
00494                             if (nMode == LU_SYSCANDI_CALC)
00495                             {
00496                                    psc->nSizShCandi += 2;        /* Add one ZERO After each Single Hanzi Candidate */
00497                                    psc->nNumShCandi += 1;
00498                                    *pnSize += 2;
00499                                    m += 2;
00500                             }
00501                             else if (nMode == LU_SYSCANDI_WRITE)
00502                             {
00503                                    chHi  = (UCHAR)*(pShArea + m);
00504                                    chLow = (UCHAR)*(pShArea + m + 1);
00505                                    psc->pwShCandi[psc->nSizShCandi]   = (JWORD)((chHi << 8) + chLow);
00506                                    
00507                                    psc->nSizShCandi += 2;
00508                                    psc->nNumShCandi += 1;
00509                                    *pnSize += 2;
00510                                    m += 2;
00511                             }
00512                      }
00513               }
00514        }
00515        
00516        *pnSize += 1;
00517        
00518        return TRUE;
00519 }
00520 
00521 
00522 VOID InitStructSc(SysCandi* psc)
00523 {
00524        JINT    i;
00525        
00526        for(i = 0; i < 9; i++)
00527               psc->nOrgYj[i]     = 0xFFFF;
00528 
00529        psc->nLenYj      = 0;
00530 
00531        psc->nNumShCandi = 0;
00532        psc->pwShCandi   = NULL;
00533        
00534        psc->nNumDhCandi = 0;
00535        psc->pwDhCandi   = 0;
00536        
00537        psc->nNumMhCandi = 0;
00538        psc->pwMhCandi   = NULL;
00539        
00540        psc->nSizShCandi = 0;
00541        psc->nSizDhCandi = 0;
00542        psc->nSizMhCandi = 0;
00543 }
00544 
00545 
00546 /*
00547 **  nLenYj indicates the length of pnOrgYj. 
00548 **  Max Length of nLenYj is 9, even Max Hanzi Length in
00549 **  current PyCiku.dat is 7.
00550 */
00551 SysCandi* LookupSysCiku(JINT* pnOrgYj, JINT nLenYj, JINT nMatchMode)
00552 {
00553        JINT      nSize, i;
00554        SysCandi  *pscSC;
00555        static  JWORD  *pwCandiBuf;
00556 
00557        pscSC = (SysCandi*)malloc(sizeof(SysCandi));
00558        if(pscSC == NULL)
00559        {
00560               fprintf(stderr, "Failed to alloc memory for struct pscSC in LookupSysCiku().\n");
00561               exit(FALSE);
00562        }
00563 
00564        nSize = 0;
00565        InitStructSc(pscSC);
00566        if (pwCandiBuf != NULL)
00567               free(pwCandiBuf);
00568        
00569        EnumSysCandi(pnOrgYj, nLenYj, pscSC, &nSize, pwCandiBuf, nMatchMode, LU_SYSCANDI_CALC);
00570        
00571        pwCandiBuf = (JWORD *)malloc(nSize * sizeof(JWORD));
00572        if (pwCandiBuf == NULL)
00573        {
00574               fprintf(stderr, "Error!! Failed to Malloc() in Function LookupSysCiku().\n");
00575               exit(FALSE);
00576        }
00577        for(i = 0; i < nSize; i++)
00578               *(pwCandiBuf + i) = 0x0000;
00579        
00580        printf("MhCandi[%d]  DhCandi[%d]  ShCandi[%d]. TotalSize in JWORD[%d]\n", 
00581               pscSC->nNumMhCandi, pscSC->nNumDhCandi, pscSC->nNumShCandi, nSize);
00582        
00583        EnumSysCandi(pnOrgYj, nLenYj, pscSC, &nSize, pwCandiBuf, nMatchMode, LU_SYSCANDI_WRITE);
00584        
00585        /* Sort Candidates in struct SysCandi by Frequence */
00586        SortSysCandi(pscSC);
00587        
00588        return (pscSC);
00589 }
00590 
00591 
00592 /*
00593 **  Sort Candidates in Structure SysCandi by Length and Frequence
00594 */
00595 VOID SortSysCandi(SysCandi* psc)
00596 {
00597        JINT    nNumM, nSizM, nNumD, nSizD;
00598        JWORD   *pwBuf;
00599        JINT    nBuf, nTmp, i, k, m, n, p, nLenM, nFreqM;
00600        
00601        nNumM   = psc->nNumMhCandi;
00602        nSizM   = psc->nSizMhCandi;
00603        nNumD   = psc->nNumDhCandi;
00604        nSizD   = psc->nSizDhCandi;
00605 
00606        if ((nNumM <= 1) && (nNumD <= 1))
00607               return;
00608        
00609        if(nSizM > nSizD)
00610               nBuf = nSizM;
00611        else
00612               nBuf = nSizD;
00613        
00614        pwBuf = (JWORD *)malloc(nBuf * sizeof(JWORD));
00615        if (pwBuf == NULL)
00616        {
00617               fprintf(stderr, "Failed to alloc Memory in function SortSysCandi().\n");
00618               exit(FALSE);
00619        }
00620        
00621        /*
00622        **  For MultipleHanzi Candidates, by Length First, by Frequence Second.
00623        */
00624        nLenM = nFreqM = 0;
00625        if(nNumM > 1)
00626        {
00627               for(i = 0; i < nBuf; i++)
00628                      pwBuf[i]  = 0x0000;
00629                      
00630               p = m = n = 0;
00631               for(i = 0xFF; (i >= 0x00) && (p < nNumM); i--)
00632               {
00633                      for(k = 0; k < nSizM; k++)
00634                      {
00635                             /*
00636                             **  Exchange [Freq + Len] to [Len + Freq] (nTmp)
00637                             */
00638                             nLenM  = psc->pwMhCandi[k] & 0x07;
00639                             nFreqM = psc->pwMhCandi[k] & 0xF8;
00640                             nTmp   = (nLenM << 5) + (nFreqM >> 3);
00641                             if(nTmp == i)
00642                             {
00643                                    for(m = 0; m < (nLenM + 4); m++)
00644                                           pwBuf[n++] = psc->pwMhCandi[k + m];
00645                                    p++;
00646                             }
00647                      }
00648               }
00649               
00650               for(i = 0; i < nSizM; i++)
00651                      psc->pwMhCandi[i] = pwBuf[i];
00652        }
00653        
00654        /*
00655        **  For DoubleHanzi Candidates, by Frequence only.
00656        */
00657        if(nNumD > 1)
00658        {
00659               for(i = 0; i < nBuf; i++)
00660                      pwBuf[i]  = 0x0000;
00661        
00662               p = m = n = 0;
00663               for(i = 0xFF; (i >= 0x00) && (p < nNumD); i--)
00664               {
00665                      for(k = 0; k < nSizD; k++)
00666                      {
00667                             nTmp   = psc->pwDhCandi[k];
00668                             if(nTmp == i)
00669                             {
00670                                    for(m = 0; m < 4; m++)
00671                                           pwBuf[n++] = psc->pwDhCandi[k + m];
00672                                    p++;
00673                             }
00674                      }
00675               }
00676               
00677               for(i = 0; i < nSizD; i++)
00678                      psc->pwDhCandi[i] = pwBuf[i];
00679        }
00680 }
00681 
00682 
00683 /*
00684 **  Adjust the freqence of a specified Ciku. Length of this cizu is 
00685 **  specified in nLen.
00686 **
00687 **  Increase the frequence of this Dh or Mh, decrease the frequence
00688 **  of other Dh or Mh which have same Yjcode.
00689 **
00690 **  For Sh, move the Hanzi forward to a certain place, move other
00691 **  Hanzies backward.
00692 */
00693 VOID AdjustFreq(JWORD* pwHz2244, JINT nLenThis)
00694 {
00695        JINT    nYjFirst;
00696        JINT    nCzLen, i, k, m, t;
00697        JINT    nFromOff, nToOff;
00698        JWORD   wCzHz, wMhLenFreq, wFreq;
00699        JINT    nEqualFlag;
00700        CHAR    szDhYj1[12], szDhYj2[12];
00701 
00702        CikuHeader  *pCkh;
00703        ShIndex     *pShi;
00704        DhIndex     *pDhi;
00705        MhIndex     *pMhi;
00706        BYTE        *pShArea;
00707        BYTE        *pDhArea;
00708        BYTE        *pMhArea;
00709        
00710        pCkh    = (CikuHeader *)pCkAll;
00711        pShi    = (ShIndex *)(pCkAll + pCkh->nIdxShPos);
00712        pDhi    = (DhIndex *)(pCkAll + pCkh->nIdxDhPos);
00713        pMhi    = (MhIndex *)(pCkAll + pCkh->nIdxMhPos);
00714        pShArea = (BYTE *)(pCkAll + pShi->nStartPos);
00715        pDhArea = (BYTE *)(pCkAll + pDhi->nStartPos);
00716        pMhArea = (BYTE *)(pCkAll + pMhi->nStartPos);
00717 
00718        /* nYjFirst must be in range 0~414 */
00719        nYjFirst = Hzcode2244ToYjcode((JINT)pwHz2244[0]);
00720 
00721        if (nLenThis >= 3)
00722        {
00723               /*
00724               **  Determine the FromOff and ToOff which to used for searching by the pnOrgYj[0].
00725               */
00726               nFromOff = pMhi->nYjOff[ nYjFirst ];
00727               nToOff   = pMhi->nYjOff[ nYjFirst + 1];
00728               
00729               /* !! DON'T add k++ in this FOR sentence !! */
00730               for (k = nFromOff; k < nToOff; )
00731               {
00732                      wMhLenFreq = (JWORD)*(pMhArea + k);
00733                      nCzLen     = 2 + ((UCHAR)*(pMhArea + k) & 0x07);
00734                      k++;
00735 
00736                      /*  It is just this Cizu, Increase its frequence here. */
00737                      if ((nCzLen == nLenThis) &&
00738                             (strncmp((CHAR*)(&pMhArea[k]), (CHAR*)pwHz2244, 2 * nCzLen) == 0) )
00739                      {
00740                             /* Just set Frequence to highest. */
00741                             *(pMhArea + k - 1) = (BYTE)(0xF8 + (nCzLen - 2));
00742                             k += (2 * nCzLen);
00743                      }
00744                      /*
00745                      **  Have the same length. Is it also have same Yjcode? If yes, 
00746                      **  reduce the frequence.
00747                      */
00748                      else if ((nCzLen == nLenThis) &&
00749                             (strncmp((CHAR*)(&pMhArea[k]), (CHAR*)pwHz2244, 2 * nCzLen) != 0) )
00750                      {
00751                             nEqualFlag = TRUE;
00752 
00753                             /*
00754                             ** Compare from the second Hanzi, because the first Hanzi must
00755                             ** same Yjcode. So, skip the first by adding t += 2.
00756                             */
00757                             t = k;
00758                             t += 2;
00759                             for (m = 1; m < nCzLen; m++)
00760                             {
00761                                    wCzHz   = (JWORD)(*(pMhArea + t + 1) + ((*(pMhArea + t)) << 8));
00762                                    t += 2;
00763 
00764                                    if ( Hzcode2244ToYjcode((JINT)pwHz2244[1]) != Hzcode2244ToYjcode((JINT)wCzHz) )
00765                                    {
00766                                           nEqualFlag = FALSE;
00767                                           break;
00768                                    }
00769                             }
00770 
00771                             /* Have same Yjcodes in every Hanzi, reduce its Frequence Here. */
00772                             if (nEqualFlag == TRUE)
00773                             {
00774                                    wMhLenFreq = (JWORD)*(pMhArea + k - 1);
00775                                    /*
00776                                    ** Length bits have the lowest 3 bits.  -8 means reduce the Frequence
00777                                    ** by ONE level. if its Freq Level is 1, no reduce needed.
00778                                    */
00779                                    if (wMhLenFreq >= 16)
00780                                           *(pMhArea + k - 1) -= 8;
00781                             }
00782 
00783                             k += (2 * nCzLen);
00784                      }
00785                      /* If it doesn't have the same length, just skip this cizu. */
00786                      else
00787                             k += (2 * nCzLen);
00788               }
00789        }
00790        
00791        else if (nLenThis == 2)
00792        {
00793               /*
00794               **  Determine the FromOff and ToOff which to used for searching by the pnOrgYj[0].
00795               */
00796               nFromOff = pDhi->nYjOff[ nYjFirst ];
00797               nToOff   = pDhi->nYjOff[ nYjFirst + 1];
00798               
00799               /* !! DON'T add k++ in this FOR sentence !! */
00800               for (k = nFromOff; k < nToOff; )
00801               {
00802                      wFreq   = (JWORD)*(pDhArea + k);
00803                      nCzLen  = 2;
00804                      k++;
00805 
00806                      /*  It is just this Cizu, Increase its frequence here. */
00807                      if (strncmp((CHAR*)(&pDhArea[k]), (CHAR*)pwHz2244, 4) == 0)
00808                      {
00809                             /* Just set Frequence to highest. */
00810                             *(pDhArea + k - 1) = 0xFF;
00811                             k += 4;
00812                             printf("YES. Increase Freq Just This.\n");
00813                      }
00814                      /*
00815                      **  Have the same length. Is it also have same Yjcode? If yes, 
00816                      **  reduce the frequence.
00817                      */
00818                      else
00819                      {
00820                             for(i = 0; i < 12; i++)
00821                                    szDhYj1[i] = szDhYj2[i] = '\0';
00822 
00823                             /* Cat total YinjieString into szDhYj1 */
00824                             strcat( strcat(szDhYj1, YINJIESTR_CSZ[nYjFirst]),       
00825                                                     YINJIESTR_CSZ[Hzcode2244ToYjcode((JINT)pwHz2244[1])] );
00826 
00827                             t = k;
00828                             wCzHz   = (JWORD)(*(pMhArea + t + 1) + ((*(pMhArea + t)) << 8));
00829                             strcat(szDhYj2, YINJIESTR_CSZ[Hzcode2244ToYjcode((JINT)wCzHz)]);
00830 
00831                             t += 2;
00832                             wCzHz   = (JWORD)(*(pMhArea + t + 1) + ((*(pMhArea + t)) << 8));
00833                             strcat(szDhYj2, YINJIESTR_CSZ[Hzcode2244ToYjcode((JINT)wCzHz)]);
00834 
00835                             nEqualFlag = TRUE;
00836                             if (strcmp(szDhYj1, szDhYj2) != 0)
00837                                    nEqualFlag = FALSE;
00838 
00839                             /* Have same Yjcodes in every Hanzi, reduce its Frequence Here. */
00840                             if (nEqualFlag == TRUE)
00841                             {
00842                                    wFreq = (JWORD)*(pDhArea + k - 1);
00843                                    /*
00844                                    ** Decrease by ONE Level.
00845                                    */
00846                                    if (wFreq >= 2)
00847                                           *(pDhArea + k - 1) -= 1;
00848                                    
00849                                    printf("YES. Decrease Freq Here!!!!\n");
00850                             }
00851                             k += 4;
00852 
00853                      }
00854               }
00855        }
00856 
00857 }
00858 
00859