Back to index

im-sdk  12.3.91
CikuOper.c
Go to the documentation of this file.
00001 /*
00002 Copyright 1990-2003 Sun Microsystems, Inc. All Rights Reserved.
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a
00005 copy of this software and associated documentation files (the
00006 "Software"), to deal in the Software without restriction, including
00007 without limitation the rights to use, copy, modify, merge, publish,
00008 distribute, sublicense, and/or sell copies of the Software, and to
00009 permit persons to whom the Software is furnished to do so, subject to
00010 the following conditions: The above copyright notice and this
00011 permission notice shall be included in all copies or substantial
00012 portions of the Software.
00013 
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00016 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00017 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00018 IN NO EVENT SHALL THE OPEN GROUP OR SUN MICROSYSTEMS, INC. BE LIABLE
00019 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
00020 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
00021 THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE EVEN IF
00022 ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
00023 
00024 
00025 Except as contained in this notice, the names of The Open Group and/or
00026 Sun Microsystems, Inc. shall not be used in advertising or otherwise to
00027 promote the sale, use or other dealings in this Software without prior
00028 written authorization from The Open Group and/or Sun Microsystems,
00029 Inc., as applicable.
00030 
00031 
00032 X Window System is a trademark of The Open Group
00033 
00034 OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
00035 logo, LBX, X Window System, and Xinerama are trademarks of the Open
00036 Group. All other trademarks and registered trademarks mentioned herein
00037 are the property of their respective owners. No right, title or
00038 interest in or to any trademark, service mark, logo or trade name of
00039 Sun Microsystems, Inc. or its licensors is granted.
00040 
00041 */
00042 
00043 #include "PYIM.h"
00044 #include "UDCOper.h"
00045 
00046 /* Jword.c */
00047 JINT    GbkHz2244ToYjSM(JINT nHzcode);
00048 JINT    GbkHz2244ToYj(JINT nHzcode);
00049 UCHAR*  RecovDyz2244(UCHAR *szDyz2244);
00050 VOID    Jword2Uchar(JWORD* pwJword, UCHAR* szUch, JINT nMaxLen);
00051 VOID    JwordNCpy(JWORD* pwDst, JWORD* pwSrc, JINT nLen);
00052 JINT    JwordValidLen(JWORD* pwJwordArray, JINT nMaxLen);
00053 JINT    JwordHanziLen(JWORD* pwJwordArray, JINT nMaxLen);
00054 JINT    JwordNCmp(JWORD* pwSrc1, JWORD* pwSrc2, JINT nNum);
00055 JINT    IsGbkkkHz(JWORD wHz);
00056 
00057 JINT    GetCikuData(CHAR* szSysCikuName);
00058 JINT    WriteCikuData(CHAR* szSysCikuName, JINT nTimeStamp);
00059 JINT    EnumCandi(JINT* pnOrgYj, JINT nLenYj, SysCandi* psc, UdcCandi* puc, JINT* pnSize, JINT nMatchMode, JINT nMode);
00060 VOID    InitStructSc(SysCandi* psc);
00061 VOID    InitStructUc(UdcCandi* puc);
00062 JINT    LookupCiku(JINT* pnOrgYj, JINT nLenYj, JINT nMatchMode, SysCandi* psc, UdcCandi* puc);
00063 VOID    SortCandi(SysCandi* psc, UdcCandi* puc);
00064 VOID    AdjustFreq(JWORD* pwHz2244, JINT nLenThis);
00065 JINT    IsCizuExist(JWORD* pwHz2244, JINT nLenThis);
00066 JINT    IsGbkkkHz(JWORD wHz);
00067 
00068 VOID    WarpByte(VOID* pv, JINT n);
00069 VOID    WarpIndex(ShIndex* pInt419);
00070 VOID    WarpCikuHeader(CikuHeader* pCh);
00071 
00072 BYTE   *pCkAll = NULL;
00073 extern  UdcMemAll  udcAll;
00074 
00075 extern UDCData *udcGB, *udcGBK;
00076 
00077 /*
00078 **  Warp 4 Bytes or Warp 2 Bytes.
00079 **  Because SPARC and Intel x86 have different byte order.
00080 */
00081 VOID WarpByte(VOID* pv, JINT n)
00082 {
00083        JINT    nInt;
00084        JWORD   wWord;
00085        
00086        nInt = wWord = 0;
00087        if (n == 4)
00088        {
00089               nInt = *((JINT*)pv);
00090               *((JINT*)pv) = ((nInt & 0x000000FF) << 24) + ((nInt & 0x0000FF00) << 8) +
00091                              ((nInt & 0xFF000000) >> 24) + ((nInt & 0x00FF0000) >> 8);
00092        }
00093        else if (n == 2)
00094        {
00095               wWord = *((JWORD*)pv);
00096               *((JWORD*)pv) = (JWORD)( ((wWord & 0x00FF) << 8) + ((wWord & 0xFF00) >> 8) );
00097        }
00098        else
00099               return;
00100 }
00101 
00102 /*
00103 **  Both CikuHeader and UdCikuHeader have same structure.
00104 */
00105 VOID WarpCikuHeader(CikuHeader* pCh)
00106 {
00107        JINT    i;
00108        
00109        for (i = 0; i < 4; i++)
00110        {
00111               WarpByte( (VOID*)((JINT*)pCh + i), 4);
00112        }
00113        
00114        for (i = 24; i < 32; i++)
00115        {
00116               WarpByte( (VOID*)((JINT*)pCh + i), 4);
00117        }
00118 }
00119 
00120 /*
00121 **  All ShIndex, DhIndex, MhIndex, GbkIndex and UdcIndex have same structure.
00122 */
00123 VOID WarpIndex(ShIndex* pInt419)
00124 {
00125        JINT    i;
00126        
00127        for (i = 0; i < 419; i++)
00128        {
00129               WarpByte( (VOID*)((JINT*)pInt419 + i), 4);
00130        }
00131 }
00132 
00133 
00134 /*
00135 **  Read out all those data in System Ciku file to pCkAll.
00136 */
00137 JINT GetCikuData(CHAR* szSysCikuName)
00138 {
00139        FILE*   pfCiku;
00140        JINT    i, k;
00141        JINT    nFileSize;
00142        JINT    nWarpFlag;     /* Flag to indicate whether it is necessary to */
00143        
00144        CikuHeader  *pCkh;
00145        ShIndex     *pShi;
00146        DhIndex     *pDhi;
00147        MhIndex     *pMhi;
00148        GbkIndex    *pGbki;
00149        BYTE        *pShArea;
00150        BYTE        *pDhArea;
00151        BYTE        *pMhArea;
00152        BYTE        *pGbkArea;
00153        
00154        nWarpFlag = FALSE;
00155        
00156        pfCiku = fopen(szSysCikuName, "rb");
00157        if (pfCiku == NULL)
00158        {
00159               return FALSE;
00160        }
00161        
00162        pCkh = (CikuHeader*)malloc(sizeof(CikuHeader));
00163        if (pCkh == NULL)
00164        {
00165               return FALSE;
00166        }
00167        
00168        fseek(pfCiku, 0, SEEK_SET);
00169        if (fread (pCkh, 1, sizeof(CikuHeader), pfCiku) != sizeof(CikuHeader) )
00170        {
00171               return FALSE;
00172        }
00173        
00174        /* Check Magic Word in Header */
00175        if ((pCkh->nMagicDescHi != 0x35303539) || (pCkh->nMagicDescLow != 0x34333442))
00176        {
00177               /* Is SPARC or x86 File? */
00178               if ((pCkh->nMagicDescHi == 0x39353035) && (pCkh->nMagicDescLow == 0x42343334))
00179               {
00180                      nWarpFlag = TRUE;
00181               }
00182               else
00183                      return FALSE;
00184        }
00185        
00186        if (nWarpFlag == TRUE)
00187               WarpCikuHeader(pCkh);
00188        
00189        nFileSize = pCkh->nFileSize;
00190        
00191        fseek(pfCiku, 0, SEEK_END);
00192        if (nFileSize != ftell(pfCiku))
00193        {
00194               return FALSE;
00195        }
00196        
00197        free(pCkh);
00198        pCkh = NULL;
00199        
00200        pCkAll = (BYTE*)malloc(nFileSize);
00201        if (pCkAll == NULL)
00202        {
00203               fprintf(stderr, "Failed to malloc() for pCkAll in GetCikuInfo.\n");
00204               return FALSE;
00205        }
00206        
00207        fseek(pfCiku, 0, SEEK_SET);
00208        if ((JINT)fread (pCkAll, 1, nFileSize, pfCiku) != nFileSize )
00209        {
00210               fprintf(stderr, "Failed to fread() System Ciku File.\n");
00211               return FALSE;
00212        }
00213        fclose(pfCiku);
00214        
00215        pCkh     = (CikuHeader *)pCkAll;
00216        if (nWarpFlag == TRUE)
00217               WarpCikuHeader(pCkh);
00218 
00219        pShi     = (ShIndex  *)(pCkAll + pCkh->nIdxShPos);
00220        pDhi     = (DhIndex  *)(pCkAll + pCkh->nIdxDhPos);
00221        pMhi     = (MhIndex  *)(pCkAll + pCkh->nIdxMhPos);
00222        pGbki    = (GbkIndex *)(pCkAll + pCkh->nIdxGbkPos);
00223        
00224        if (nWarpFlag == TRUE)
00225        {
00226               WarpIndex((ShIndex *)pShi);
00227               WarpIndex((ShIndex *)pDhi);
00228               WarpIndex((ShIndex *)pMhi);
00229               WarpIndex((ShIndex *)pGbki);
00230        }
00231        
00232        pShArea  = (BYTE *)(pCkAll + pShi->nStartPos);
00233        pDhArea  = (BYTE *)(pCkAll + pDhi->nStartPos);
00234        pMhArea  = (BYTE *)(pCkAll + pMhi->nStartPos);
00235        pGbkArea = (BYTE *)(pCkAll + pGbki->nStartPos);
00236        
00237        for(i = 0; i < NUM_YINJIE; i++)
00238               for(k = (pShi->nYjOff[i] & 0x00FFFFFF); k < (pShi->nYjOff[i + 1] & 0x00FFFFFF); k++)
00239                      *(pShArea + k) ^= (BYTE)((i + 56) / 2);
00240 
00241        for(i = 0; i < NUM_YINJIE; i++)
00242               for(k = pDhi->nYjOff[i]; k < pDhi->nYjOff[i + 1]; k++)
00243                      *(pDhArea + k) ^= (BYTE)((i + 56) / 2);
00244 
00245        for(i = 0; i < NUM_YINJIE; i++)
00246               for(k = pMhi->nYjOff[i]; k < pMhi->nYjOff[i + 1]; k++)
00247                      *(pMhArea + k) ^= (BYTE)((i + 56) / 2);
00248 
00249        for(i = 0; i < NUM_YINJIE; i++)
00250               for(k = pGbki->nYjOff[i]; k < pGbki->nYjOff[i + 1]; k++)
00251                      *(pGbkArea + k) ^= (BYTE)((i + 56) / 2);
00252 
00253        return TRUE;
00254 }
00255 
00256 
00257 JINT WriteCikuData(CHAR* szSysCikuName, JINT nTimeStamp)
00258 {
00259        FILE*   pfCiku;
00260        JINT    i, k;
00261        JINT    nFileSize, nTmp;
00262        
00263        CikuHeader  *pCkh;
00264        ShIndex     *pShi;
00265        DhIndex     *pDhi;
00266        MhIndex     *pMhi;
00267        GbkIndex    *pGbki;
00268        BYTE        *pShArea;
00269        BYTE        *pDhArea;
00270        BYTE        *pMhArea;
00271        BYTE        *pGbkArea;
00272 
00273        pCkh     = (CikuHeader *)pCkAll;
00274        pShi     = (ShIndex  *)(pCkAll + pCkh->nIdxShPos);
00275        pDhi     = (DhIndex  *)(pCkAll + pCkh->nIdxDhPos);
00276        pMhi     = (MhIndex  *)(pCkAll + pCkh->nIdxMhPos);
00277        pGbki    = (GbkIndex *)(pCkAll + pCkh->nIdxGbkPos);
00278        
00279        pShArea  = (BYTE *)(pCkAll + pShi->nStartPos);
00280        pDhArea  = (BYTE *)(pCkAll + pDhi->nStartPos);
00281        pMhArea  = (BYTE *)(pCkAll + pMhi->nStartPos);
00282        pGbkArea = (BYTE *)(pCkAll + pGbki->nStartPos);
00283        
00284        pCkh->nLatestTime = nTimeStamp;
00285        
00286        /* Write These data back to file */
00287        pfCiku = fopen(szSysCikuName, "wb");
00288        if (pfCiku == NULL)
00289        {
00290               fprintf(stderr, "Failed to Create System Ciku File: %s\n", szSysCikuName);
00291               return FALSE;
00292        }
00293        
00294        for(i = 0; i < NUM_YINJIE; i++)
00295               for(k = (pShi->nYjOff[i] & 0x00FFFFFF); k < (pShi->nYjOff[i + 1] & 0x00FFFFFF); k++)
00296                      *(pShArea + k) ^= (BYTE)((i + 56) / 2);
00297 
00298        for(i = 0; i < NUM_YINJIE; i++)
00299               for(k = pDhi->nYjOff[i]; k < pDhi->nYjOff[i + 1]; k++)
00300                      *(pDhArea + k) ^= (BYTE)((i + 56) / 2);
00301 
00302        for(i = 0; i < NUM_YINJIE; i++)
00303               for(k = pMhi->nYjOff[i]; k < pMhi->nYjOff[i + 1]; k++)
00304                      *(pMhArea + k) ^= (BYTE)((i + 56) / 2);
00305        
00306        for(i = 0; i < NUM_YINJIE; i++)
00307               for(k = pGbki->nYjOff[i]; k < pGbki->nYjOff[i + 1]; k++)
00308                      *(pGbkArea + k) ^= (BYTE)((i + 56) / 2);
00309 
00310        nFileSize = pCkh->nFileSize;
00311 
00312        fseek(pfCiku, 0, SEEK_SET);
00313        nTmp = (JINT)fwrite (pCkAll, nFileSize, 1, pfCiku);
00314        
00315        for(i = 0; i < NUM_YINJIE; i++)
00316               for(k = (pShi->nYjOff[i] & 0x00FFFFFF); k < (pShi->nYjOff[i + 1] & 0x00FFFFFF); k++)
00317                      *(pShArea + k) ^= (BYTE)((i + 56) / 2);
00318 
00319        for(i = 0; i < NUM_YINJIE; i++)
00320               for(k = pDhi->nYjOff[i]; k < pDhi->nYjOff[i + 1]; k++)
00321                      *(pDhArea + k) ^= (BYTE)((i + 56) / 2);
00322 
00323        for(i = 0; i < NUM_YINJIE; i++)
00324               for(k = pMhi->nYjOff[i]; k < pMhi->nYjOff[i + 1]; k++)
00325                      *(pMhArea + k) ^= (BYTE)((i + 56) / 2);
00326        
00327        for(i = 0; i < NUM_YINJIE; i++)
00328               for(k = pGbki->nYjOff[i]; k < pGbki->nYjOff[i + 1]; k++)
00329                      *(pGbkArea + k) ^= (BYTE)((i + 56) / 2);
00330 
00331        if (nTmp != 1)
00332        {
00333               fprintf(stderr, "Failed to fwrite() System Ciku File.\n");
00334               return FALSE;
00335        }
00336        
00337        fclose (pfCiku);
00338        return TRUE;
00339 }
00340 
00341 
00342 /*
00343 **  Free the memory alloc to pCkAll
00344 */
00345 VOID FreePckAll()
00346 {
00347        free(pCkAll);
00348        pCkAll = NULL;
00349 }
00350 
00351 
00352 /*  
00353 **  pnSize:     If nMode is LU_CANDI_CALC, Calculate the size need totally to contain all those SysCandis,
00354 **              and set nNumShCandi, nNumDhCandi, nNumMhCandi, nSizShCandi, nSizDhCandi, nSizMhCandi of struct psc.
00355 **              [pnSize is in JWORD]
00356 **
00357 **  nMatchMode: LU_MATCH_STRICT   ==> Match Strictly. Used by nLenYj >= 5. Condition: nCzLen == nLenYj  
00358 **              LU_MATCH_WIDELY   ==> Match Widely.   Used by nLenYj >= 5. Condition: nCzLen >= nLenYj
00359 **              Condition for LU_MATCH_WIDLY:
00360 **                        zhong hua ren min gong // zhong hua ren min gong h  // zhong hua ren min gong he
00361 **              Condition for LU_MATCH_STRICT:  => Last YjString is unmatched and meanless.
00362 **                        zhong hua ren min gong [go gon cho chon cua]
00363 **
00364 **  nMode:      LU_CANDI_WRITE ==> Write all those SysCandis to allocated memory for Sh, Dh, Mh Candidates.
00365 **              LU_CANDI_CALC  ==> Calculate the space size which needed to contain all those SysCandis.
00366 **
00367 **  NOTES:      Structure psc was filled after two calling of this function: First in Mode LU_CANDI_CALC,
00368 **              second in Mode LU_CANDI_WRITE.
00369 **
00370 **  CONTENTS OF pwMhCandi + pwDhCandi + pwShCandi + pwGbkCandi + pwSpecCandi + pwUdc28Candi
00371 **             Mh:    fhhhhhh0fhhh0fhhhh0
00372 **             Dh:    fhh0fhh0fhh0fhh0fhh0fhh0fhh0fhh0fhh0fhh0fhh0fhh0
00373 **             Sh:    XX0XX0h0h0h0h0h0h0h0h0h0h0h0 + 0     OR
00374 **                    Q0Q0Q0Q0Q0Q0Q0h0h0h0h0h0h0h0h0 + 0
00375 **             Gbk:   h0h0h0h0h0h0h0h0
00376 **             Spec:  In ucUdcCandi->pwSpecCandi[6]
00377 **             Udc28: fhhhh0fhhhhhh0fhh0
00378 **             Notes:  f  ==> JWORD of Frequence and Length
00379 **                     h  ==> JWORD of a Single Hanzi
00380 **                     XX ==> JWORDs of Xian Form Candi
00381 **                     Q  ==> JWORD of High frequence Hanzi of a Specified Yinjie ShengMu, Ex, Q->7
00382 **                            "可开空口科克看"
00383 **
00384 */
00385 JINT EnumCandi(JINT* pnOrgYj, JINT nLenYj, SysCandi* psc, UdcCandi* puc, JINT* pnSize, JINT nMatchMode, JINT nMode)
00386 {
00387        JINT    nFromOff, nToOff;
00388        JINT    nFromYj, nToYj, nXianNum;         /* For Single Hanzi Area Searching */
00389        UCHAR   chHi, chLow;                      /* For Single Hanzi Area Searching */
00390        JINT    nCzLen, i, m, k, nTmp;
00391        JWORD   wCzHz[10], wMhLenFreq, wDhFreq;
00392        JINT    nEqualFlag;
00393        CHAR    *pszYj1, *pszYj2;                 /* For DhCandi, compare string directly */
00394        CHAR    szYj3[14], szYj4[14];
00395        JINT    nfGbkCizu;
00396 
00397        UDCData       * pudc;
00398 
00399        /* Definition for puc */
00400        JINT    nCurSize;
00401        JINT    nUdc28FreqLen, nUdc28Len;
00402 
00403        CikuHeader  *pCkh;
00404        ShIndex     *pShi;
00405        DhIndex     *pDhi;
00406        MhIndex     *pMhi;
00407        GbkIndex    *pGbki;
00408        BYTE        *pShArea;
00409        BYTE        *pDhArea;
00410        BYTE        *pMhArea;
00411        BYTE        *pGbkArea;
00412 
00413        pCkh     = (CikuHeader *)pCkAll;
00414        pShi     = (ShIndex  *)(pCkAll + pCkh->nIdxShPos);
00415        pDhi     = (DhIndex  *)(pCkAll + pCkh->nIdxDhPos);
00416        pMhi     = (MhIndex  *)(pCkAll + pCkh->nIdxMhPos);
00417        pGbki    = (GbkIndex *)(pCkAll + pCkh->nIdxGbkPos);
00418        
00419        pShArea  = (BYTE *)(pCkAll + pShi->nStartPos);
00420        pDhArea  = (BYTE *)(pCkAll + pDhi->nStartPos);
00421        pMhArea  = (BYTE *)(pCkAll + pMhi->nStartPos);
00422        pGbkArea = (BYTE *)(pCkAll + pGbki->nStartPos);
00423 
00424        *pnSize  = 0;
00425        if (nMode == LU_CANDI_WRITE)
00426        {
00427               psc->nSizMhCandi  = 0;
00428               psc->nSizDhCandi  = 0;
00429               psc->nSizShCandi  = 0;
00430               psc->nSizGbkCandi = 0;
00431                      
00432               psc->nNumMhCandi  = 0;
00433               psc->nNumDhCandi  = 0;
00434               psc->nNumShCandi  = 0;
00435               psc->nNumGbkCandi = 0;
00436 
00437               puc->nNumSpecCandi  = 0;
00438               puc->nNumUdc28Candi = 0;
00439               puc->nSizUdc28Candi = 0;
00440        }
00441 
00442        if (nLenYj >= 3)
00443        {
00444               /*
00445               **  Determine the FromOff and ToOff which to used for searching by the pnOrgYj[0].
00446               */
00447               if ((pnOrgYj[0] >= 0) && (pnOrgYj[0] < NUM_YINJIE))
00448               {
00449                      nFromOff = pMhi->nYjOff[ pnOrgYj[0] ];
00450                      nToOff   = pMhi->nYjOff[ pnOrgYj[0] + 1];
00451               }
00452               else   /* ((pnOrgYj[0] >= 450) && (pnOrgYj[0] <= 475)) */
00453               {
00454                      nFromOff = pMhi->nYjOff[ INDEXSMTOYINJIE[pnOrgYj[0] - 450] ];
00455                      nToOff   = pMhi->nYjOff[ INDEXSMTOYINJIE[pnOrgYj[0] - 450 + 1] ];
00456               }
00457               
00458               /* !! DON'T add k++ in this FOR sentence !! */
00459               for (k = nFromOff; k < nToOff; )
00460               {
00461                      wMhLenFreq = (JWORD)*(pMhArea + k);
00462                      nCzLen     = 2 + ((UCHAR)*(pMhArea + k) & 0x07);
00463                      k++;
00464                      
00465                      for (m = 0; m < 10; m++)
00466                             wCzHz[m]   = 0x0000;
00467                      for (m = 0; m < nCzLen; m++)
00468                      {
00469                             wCzHz[m]   = (JWORD)(*(pMhArea + k + 1) + ((*(pMhArea + k)) << 8));
00470                             k += 2;
00471                      }
00472                      
00473                      /*
00474                      ** DON'T CONVERT wCzItem into YJSTRING and CALL ParsePreedit() HERE, BECAUSE THAT
00475                      ** IS TOO COMPLEX AND UN_LOGICALLY.
00476                      ** For Example, zai xian shi qu ==> zai xi'an shi qu [Four ~ Five !!!!]
00477                      */
00478 
00479                      nEqualFlag = FALSE;
00480                      if (( (nLenYj <= 4) && (nCzLen <= nLenYj) ) || 
00481                          ( (nLenYj >= 5) && (nMatchMode == LU_MATCH_WIDELY) ) || 
00482                          ( (nLenYj >= 5) && (nMatchMode == LU_MATCH_STRICT) && (nCzLen <= nLenYj) )  )
00483                      {
00484                             nEqualFlag = TRUE;
00485                             
00486                             for(m = 0; m < min(nLenYj, nCzLen); m++)
00487                                    if ( ( pnOrgYj[m] != GbkHz2244ToYjSM((JINT)wCzHz[m]) ) &&                    \
00488                                         ( pnOrgYj[m] != GbkHz2244ToYj((JINT)wCzHz[m])   ) )
00489                                    {
00490                                           nEqualFlag = FALSE;
00491                                           break;
00492                                    }
00493                      }
00494                      
00495                      if ((nEqualFlag == TRUE) && (nMode == LU_CANDI_CALC))
00496                      {
00497                             psc->nSizMhCandi += (nCzLen + 2);  /* Add two JWORD Here to contain Freq&Len Word and a ZERO */
00498                             psc->nNumMhCandi += 1;
00499                             *pnSize += (nCzLen + 2);
00500                      }
00501                      else if ((nEqualFlag == TRUE) && (nMode == LU_CANDI_WRITE))
00502                      {
00503                             psc->pwMhCandi[psc->nSizMhCandi] = wMhLenFreq;
00504                             for (m = 0; m < nCzLen; m++)
00505                                    psc->pwMhCandi[psc->nSizMhCandi + m + 1] = wCzHz[m];
00506                             
00507                             psc->nSizMhCandi += (nCzLen + 2);
00508                             psc->nNumMhCandi += 1;
00509                             *pnSize += (nCzLen + 2);
00510                      }
00511               }
00512        }
00513        
00514 
00515        if (nLenYj >= 2)
00516        {
00517               /*
00518               **  Determine the FromOff and ToOff which to used for searching by the pnOrgYj[0].
00519               */
00520               if ((pnOrgYj[0] >= 0) && (pnOrgYj[0] < NUM_YINJIE))
00521               {
00522                      nFromOff = pDhi->nYjOff[ pnOrgYj[0] ];
00523                      nToOff   = pDhi->nYjOff[ pnOrgYj[0] + 1];
00524               }
00525               else /* ((pnOrgYj[0] >= 450) && (pnOrgYj[0] <= 475)) */
00526               {
00527                      nFromOff = pDhi->nYjOff[ INDEXSMTOYINJIE[pnOrgYj[0] - 450] ];
00528                      nToOff   = pDhi->nYjOff[ INDEXSMTOYINJIE[pnOrgYj[0] - 450 + 1] ];
00529               }
00530        
00531               /* !! DON'T add k++ in this FOR sentence !! */
00532               for (k = nFromOff; k < nToOff; )
00533               {
00534                      wDhFreq  = (JWORD)*(pDhArea + k);
00535                      nCzLen   = 2;
00536                      k ++;
00537 
00538                      for (m = 0; m < 10; m++)
00539                             wCzHz[m]   = 0x0000;
00540                      for (m = 0; m < nCzLen; m++)
00541                      {
00542                             wCzHz[m]   = (JWORD)(*(pDhArea + k + 1) + ((*(pDhArea + k)) << 8));
00543                             k += 2;
00544                      }
00545 
00546                      for (m = 0; m < 14; m++)
00547                      {
00548                             szYj3[m]   = '\0';
00549                             szYj4[m]   = '\0';
00550                      }
00551                      
00552                      if ((pnOrgYj[0] >= 450) && (pnOrgYj[0] <= 475))
00553                             pszYj1 = SHENGMUSTR[ pnOrgYj[0] - 450 ];
00554                      else
00555                             /* Rewrite this line to proc [fangan] ==> [fan gan] and [fang an]. Scott Ma 98-05-12 */
00556                             /* pszYj1 = YINJIESTR_CSZ[ pnOrgYj[0] ];  */
00557                             pszYj1 = YINJIESTR_CSZ[ GbkHz2244ToYj((JINT)wCzHz[0]) ];
00558 
00559                      if ((pnOrgYj[1] >= 450) && (pnOrgYj[1] <= 475))
00560                             pszYj2 = SHENGMUSTR[ GbkHz2244ToYjSM((JINT)wCzHz[1]) - 450 ];
00561                      else
00562                             pszYj2 = YINJIESTR_CSZ[ GbkHz2244ToYj((JINT)wCzHz[1]) ];
00563                      strcat(strcat(szYj3, pszYj1), pszYj2);
00564 
00565                      /* Add the following 4 lines to proc [fangan] ==> [fan gan] and [fang an]. Scott Ma 98-05-12 */
00566                      if ((pnOrgYj[0] >= 450) && (pnOrgYj[0] <= 475))
00567                             pszYj1 = SHENGMUSTR[ pnOrgYj[0] - 450 ];
00568                      else
00569                             pszYj1 = YINJIESTR_CSZ[ pnOrgYj[0] ];
00570 
00571                      if ((pnOrgYj[1] >= 450) && (pnOrgYj[1] <= 475))
00572                             pszYj2 = SHENGMUSTR[ pnOrgYj[1] - 450 ];
00573                      else
00574                             pszYj2 = YINJIESTR_CSZ[ pnOrgYj[1] ];
00575                      strcat(strcat(szYj4, pszYj1), pszYj2);
00576 
00577                      nEqualFlag = TRUE;
00578                      if ( strcmp (szYj3, szYj4) != 0)
00579                             nEqualFlag = FALSE;
00580                      
00581                      if ((nEqualFlag == TRUE) && (nMode == LU_CANDI_CALC))
00582                      {
00583                             psc->nSizDhCandi += (nCzLen + 2);  /* Add two JWORD Here to contain Freq Word and a ZERO */
00584                             psc->nNumDhCandi += 1;
00585                             *pnSize += (nCzLen + 2);
00586                      }
00587                      else if ((nEqualFlag == TRUE) && (nMode == LU_CANDI_WRITE))
00588                      {
00589                             psc->pwDhCandi[psc->nSizDhCandi] = wDhFreq;
00590                             for (m = 0; m < nCzLen; m++)
00591                                    psc->pwDhCandi[psc->nSizDhCandi + m + 1] = wCzHz[m];
00592                             
00593                             psc->nSizDhCandi += (nCzLen + 2);
00594                             psc->nNumDhCandi += 1;
00595                             *pnSize += (nCzLen + 2);
00596                      }
00597               }
00598        }
00599 
00600        /* GB Single Hanzi */
00601        if (nLenYj >= 1)
00602        {
00603               /*
00604               **  Order of Single Hanzi Candidates:
00605               **  IF pnOrgYj[0] is a SM, place HIFREQHANZI[?][14] at the head of ShCandi Area
00606               **                         Place Single Hanzi by Frequence and Yinjie Sequence
00607               **  IF pnOrgYj[0] is Normal Yinjie [0 ~ 414], place XianForm candis at the head.
00608               **                         place Single Hanzi by Frequence and Yinjie Sequence
00609               **
00610               **  Determine the Fromyj and ToYj which to used for searching by the pnOrgYj[0].
00611               **  NOTICE: This is different from DhCandi and MhCandi.  
00612               */
00613               if ((pnOrgYj[0] >= 0) && (pnOrgYj[0] < NUM_YINJIE))
00614               {
00615                      nFromYj  = pnOrgYj[0];
00616                      nToYj    = pnOrgYj[0] + 1;
00617               }
00618 
00619               else   /* ((pnOrgYj[0] >= 450) && (pnOrgYj[0] <= 475)) */
00620               {
00621                      nFromYj  = INDEXSMTOYINJIE[ pnOrgYj[0] - 450 ];
00622                      nToYj    = INDEXSMTOYINJIE[ pnOrgYj[0] - 450 + 1 ];
00623 
00624                      for (m = 0; m < 7; m++)         /* There are 7 HIFREQHANZI in each SM Yinjie. See PyBasic.h */
00625                      {
00626                             if (nMode == LU_CANDI_CALC)
00627                             {
00628                                    psc->nSizShCandi += 2;        /* Add one ZERO After this HIFREQHANZI */
00629                                    psc->nNumShCandi += 1;
00630                                    *pnSize += 2;
00631                             }
00632                             else if (nMode == LU_CANDI_WRITE)
00633                             {
00634                                    chHi  = HIFREQHANZI[pnOrgYj[0] - 450][2 * m];
00635                                    chLow = HIFREQHANZI[pnOrgYj[0] - 450][2 * m + 1];
00636                                    psc->pwShCandi[psc->nSizShCandi]     = (JWORD)((chHi << 8) + chLow);
00637                                    
00638                                    psc->nSizShCandi += 2;
00639                                    psc->nNumShCandi += 1;
00640                                    *pnSize += 2;
00641                             }
00642                      }
00643               }
00644 
00645               /* add GB(0xD7FA -- 0xD7FE) user defined characters from udcGB list, if the locale is zh_CN.EUC. */
00646               if(nGBKMode == FALSE) {
00647                      pudc = udcGB;
00648                      while (pudc != NULL)
00649                      {
00650                             if( pnOrgYj[0] != FastMatchYinJieStr(pudc->pinyin) ) {
00651                                    pudc = pudc->next;
00652                                    continue;
00653                             }
00654 
00655                             if (nMode == LU_CANDI_CALC) {
00656                                    psc->nSizShCandi += 2;        /* Add one ZERO After this HIFREQHANZI */
00657                                    psc->nNumShCandi += 1;
00658                                    *pnSize += 2;
00659                             }
00660                             else if (nMode == LU_CANDI_WRITE) {
00661                                    psc->pwShCandi[psc->nSizShCandi]     = (JWORD)pudc->nHzcode;
00662                                    psc->nSizShCandi += 2;
00663                                    psc->nNumShCandi += 1;
00664                                    *pnSize += 2;
00665                             }
00666                             pudc = pudc->next;
00667                      }
00668               }
00669               
00670               /*
00671               **  Because 'Xian' Form is already included in above processing (0 ~ 414), and no necessary
00672               **  for (450 ~ 475), So, not to include then in the following reclycle.
00673               */
00674               for(k = nFromYj; k < nToYj; k++)
00675               {
00676                      nXianNum = (pShi->nYjOff[k + 1] & 0x0F000000) >> 24;
00677                      nFromOff = pShi->nYjOff[ k ] & 0x00FFFFFF;
00678                      nToOff   = (pShi->nYjOff[ k + 1] & 0x00FFFFFF) - (4 * nXianNum);
00679                      
00680                      /* !!Don't add m++ in this FOR sentence!! */
00681                      for(m = nFromOff; m < nToOff;  )
00682                      {
00683                             if (nMode == LU_CANDI_CALC)
00684                             {
00685                                    psc->nSizShCandi += 2;        /* Add one ZERO After each Single Hanzi Candidate */
00686                                    psc->nNumShCandi += 1;
00687                                    *pnSize += 2;
00688                                    m += 2;
00689                             }
00690                             else if (nMode == LU_CANDI_WRITE)
00691                             {
00692                                    chHi  = (UCHAR)*(pShArea + m);
00693                                    chLow = (UCHAR)*(pShArea + m + 1);
00694                                    psc->pwShCandi[psc->nSizShCandi]   = (JWORD)((chHi << 8) + chLow);
00695                                    
00696                                    psc->nSizShCandi += 2;
00697                                    psc->nNumShCandi += 1;
00698                                    *pnSize += 2;
00699                                    m += 2;
00700                             }
00701                      }
00702               }
00703 
00704               if ((pnOrgYj[0] >= 0) && (pnOrgYj[0] < NUM_YINJIE))
00705               {
00706                      nXianNum = (pShi->nYjOff[nToYj] & 0x0F000000) >> 24;
00707                      for (k = 0; k < nXianNum; k++)
00708                      {
00709                             if (nMode == LU_CANDI_CALC)
00710                             {
00711                                    psc->nSizShCandi += 3;        /* Add one ZERO After this Xian Candi */
00712                                    psc->nNumShCandi += 1;
00713                                    *pnSize += 3;
00714                             }
00715                             else if (nMode == LU_CANDI_WRITE)
00716                             {
00717                                    nTmp  = pShi->nYjOff[nToYj] & 0x00FFFFFF;
00718                                    chHi  = (UCHAR)*(pShArea + nTmp - (nXianNum * 4) + (k * 4));
00719                                    chLow = (UCHAR)*(pShArea + nTmp - (nXianNum * 4) + (k * 4) + 1);
00720                                    psc->pwShCandi[psc->nSizShCandi]     = (JWORD)((chHi << 8) + chLow);
00721                                    
00722                                    chHi  = (UCHAR)*(pShArea + nTmp - (nXianNum * 4) + (k * 4) + 2);
00723                                    chLow = (UCHAR)*(pShArea + nTmp - (nXianNum * 4) + (k * 4) + 3);
00724                                    psc->pwShCandi[psc->nSizShCandi + 1] = (JWORD)((chHi << 8) + chLow);
00725                                    
00726                                    psc->pwShCandi[psc->nSizShCandi + 2] = 0x0000;
00727 
00728                                    psc->nSizShCandi += 3;
00729                                    psc->nNumShCandi += 1;
00730                                    *pnSize += 3;
00731                             }
00732                      }
00733               }
00734        }
00735        
00736        /* GBK Single Hanzi */
00737 
00738        if ((nLenYj >= 1) && (nGBKMode == TRUE))
00739        {
00740               nTmp = pnOrgYj[0];
00741 
00742               /* add GBK user defined characters from udcGBK list */
00743               pudc = udcGBK;
00744               while (pudc != NULL) {
00745                      if( pnOrgYj[0] != FastMatchYinJieStr(pudc->pinyin) ) {
00746                             pudc = pudc->next;
00747                             continue;
00748                      }
00749 
00750                      if (nMode == LU_CANDI_CALC) {
00751                             psc->nSizShCandi += 2;        /* Add one ZERO After this HIFREQHANZI */
00752                             psc->nNumShCandi += 1;
00753                             *pnSize += 2;
00754                      }
00755                      else if (nMode == LU_CANDI_WRITE) {
00756                             psc->pwShCandi[psc->nSizShCandi]     = (JWORD)pudc->nHzcode;
00757                             
00758                             psc->nSizShCandi += 2;
00759                             psc->nNumShCandi += 1;
00760                             *pnSize += 2;
00761                      }
00762                      pudc = pudc->next;
00763               }
00764 
00765               /* Process "a", "e", "o", "m", "n" */
00766               if (nTmp == 450)
00767                      nTmp = 0;
00768               else if (nTmp == 455)
00769                      nTmp = 80;
00770               else if (nTmp == 462)
00771                      nTmp = 191;
00772               else if (nTmp == 463)
00773                      nTmp = 211;
00774               else if (nTmp == 464)
00775                      nTmp = 237;
00776 
00777               if ((nTmp >= 0) && (nTmp < NUM_YINJIE))
00778               {
00779                      nFromOff = pGbki->nYjOff[ nTmp ];
00780                      nToOff   = pGbki->nYjOff[ nTmp + 1];
00781               
00782                      /* !!Don't add m++ in this FOR sentence!! */
00783                      for(m = nFromOff; m < nToOff;  )
00784                      {
00785                             if (nMode == LU_CANDI_CALC)
00786                             {
00787                                    psc->nSizGbkCandi += 2;       /* Add one ZERO After each GBK Single Hanzi Candidate */
00788                                    psc->nNumGbkCandi += 1;
00789                                    *pnSize += 2;
00790                                    m += 2;
00791                             }
00792                             else if (nMode == LU_CANDI_WRITE)
00793                             {
00794                                    chHi  = (UCHAR)*(pGbkArea + m);
00795                                    chLow = (UCHAR)*(pGbkArea + m + 1);
00796                                    psc->pwGbkCandi[psc->nSizGbkCandi]   = (JWORD)((chHi << 8) + chLow);
00797                             
00798                                    psc->nSizGbkCandi += 2;
00799                                    psc->nNumGbkCandi += 1;
00800                                    *pnSize += 2;
00801                                    m += 2;
00802                             }
00803                      }
00804               }
00805        }
00806        
00807 
00808        /****************************************************************************************
00809        **************************    Enum Candi in udcAll     **********************************
00810        ****************************************************************************************/
00811        /*
00812        ** Get puc->pwSpecCandi[6]. pwSepcCandi only be given if pnOrgYj[0] is among [0 ~ 414]
00813        */
00814        if ((nLenYj >= 1) && (pnOrgYj[0] >= 0) && (pnOrgYj[0] < NUM_YINJIE))
00815        {
00816               nTmp = 0;
00817               for (i = 0; i < (udcAll.udcfh.nSizeSpecHz / 2); i++)
00818               {
00819                      if (udcAll.pwUdcSh[i] == 0x0000)
00820                             nTmp++;
00821                      
00822                      if (nTmp == (pnOrgYj[0] + 1))
00823                      {
00824                             i++;
00825                             for (m = i; udcAll.pwUdcSh[m] != 0x0000; m++)
00826                             {
00827                                    /* MAX: 6 Special Hanzi for each Yinjie in < UdCiku.dat >!! */
00828                                    if ((m - i) > 5)
00829                                           break;       /* Break out FOR_m */
00830                                    
00831                                    if (nMode == LU_CANDI_WRITE)
00832                                           puc->pwSpecCandi[m - i] = udcAll.pwUdcSh[m];
00833                                    puc->nNumSpecCandi ++;
00834                             }
00835                             break;           /* Break out FOR_i */
00836                      }
00837               }
00838        }
00839        else
00840               puc->nNumSpecCandi = 0;
00841 
00842        /*
00843        **  Get puc->nNumUdc28Candi and puc->nSizUdc28Candi, AND
00844        **  fill puc->pwUdc28Candi[] if nMode == LU_CANDI_WRITE
00845        */
00846        if (nLenYj >= 2)
00847        {
00848               /*
00849               **  Determine the nFromYj and nToYj which to used for searching by the pnOrgYj[0].
00850               */
00851               if ((pnOrgYj[0] >= 0) && (pnOrgYj[0] < NUM_YINJIE))
00852               {
00853                      nFromYj  = pnOrgYj[0];
00854                      nToYj    = pnOrgYj[0] + 1;
00855               }
00856               else   /* ((pnOrgYj[0] >= 450) && (pnOrgYj[0] <= 475)) */
00857               {
00858                      nFromYj  = INDEXSMTOYINJIE[ pnOrgYj[0] - 450 ];
00859                      nToYj    = INDEXSMTOYINJIE[ pnOrgYj[0] - 450 + 1 ];
00860               }
00861 
00862               for(k = nFromYj; k < nToYj; k++)
00863               {
00864                      nCurSize   = udcAll.udci.nYjOff[k + 1] - udcAll.udci.nYjOff[k];      /* In BYTE */
00865 
00866                      /* NO i++ in this FOR sentence */
00867                      for (i = 0; i < nCurSize / 2; )
00868                      {
00869                             nUdc28FreqLen =  udcAll.pwUdc28[k][i] & 0x00FF;
00870                             nUdc28Len     = (udcAll.pwUdc28[k][i] & 0x0007) + 2;
00871                             i++;
00872 
00873                             for (m = 0; m < 10; m++)
00874                                    wCzHz[m]  = 0x0000;
00875                             for (m = 0; m < nUdc28Len; m++)
00876                             {
00877                                    wCzHz[m]  = udcAll.pwUdc28[k][i];
00878                                    i++;
00879                             }
00880                      
00881                             nEqualFlag = FALSE;
00882                             if (( (nLenYj <= 4) && (nUdc28Len  <= nLenYj) ) || 
00883                                 ( (nLenYj >= 5) && (nMatchMode == LU_MATCH_WIDELY) ) || 
00884                                 ( (nLenYj >= 5) && (nMatchMode == LU_MATCH_STRICT) && (nUdc28Len <= nLenYj) )  )
00885                             {
00886                                    nEqualFlag = TRUE;
00887                             
00888                                    for(m = 0; m < min(nLenYj, nUdc28Len); m++)
00889                                           if ( ( pnOrgYj[m] != GbkHz2244ToYjSM((JINT)wCzHz[m]) ) &&                    \
00890                                                ( pnOrgYj[m] != GbkHz2244ToYj  ((JINT)wCzHz[m]) ) )
00891                                           {
00892                                                  nEqualFlag = FALSE;
00893                                                  break;
00894                                           }
00895                             }
00896 
00897                             /* Is there any GBK UdcCizu that to be omitted? */
00898                             if (nEqualFlag == TRUE)
00899                             {
00900                                    nfGbkCizu = FALSE;
00901                                    for (m = 0; m < nUdc28Len; m++)
00902                                    {
00903                                           if (IsGbkkkHz(wCzHz[m]) == TRUE)
00904                                           {
00905                                                  nfGbkCizu = TRUE;
00906                                                  break;
00907                                           }
00908                                    }
00909                                    
00910                                    if ((nfGbkCizu == TRUE) && (nGBKMode == FALSE))
00911 /*
00912                                        ((strstr(szLocale, "GBK") == NULL) &&
00913                                         (strstr(szLocale, "UTF-8") == NULL)
00914                                        ))
00915 */
00916                                           nEqualFlag = FALSE;
00917 #ifdef _DRAW_IM_WIN_H
00918                                    nEqualFlag = TRUE;
00919 #endif                             
00920                             }
00921                             
00922                             if ((nEqualFlag == TRUE) && (nMode == LU_CANDI_CALC))
00923                             {
00924                                    puc->nSizUdc28Candi += (nUdc28Len + 2);   /* Add two JWORD Here to contain Freq&Len Word and a ZERO */
00925                                    puc->nNumUdc28Candi += 1;
00926                                    *pnSize += (nUdc28Len + 2);
00927                             }
00928                             else if ((nEqualFlag == TRUE) && (nMode == LU_CANDI_WRITE))
00929                             {
00930                                    puc->pwUdc28Candi[puc->nSizUdc28Candi] = (JWORD)nUdc28FreqLen;
00931                                    for (m = 0; m < nUdc28Len; m++)
00932                                           puc->pwUdc28Candi[puc->nSizUdc28Candi + m + 1] = wCzHz[m];
00933                             
00934                                    puc->nSizUdc28Candi += (nUdc28Len + 2);
00935                                    puc->nNumUdc28Candi += 1;
00936                                    *pnSize += (nUdc28Len + 2);
00937                             }
00938                      }
00939               }
00940        }
00941        
00942        *pnSize += 1;
00943        return TRUE;
00944 }
00945 
00946 
00947 /*
00948 **  Initialize Structure SysCandi
00949 */
00950 VOID InitStructSc(SysCandi* psc)
00951 {
00952        JINT    i;
00953        
00954        for(i = 0; i < 9; i++)
00955               psc->nOrgYj[i]     = 0x00000000;
00956 
00957        psc->nLenYj       = 0;
00958        psc->nNumShCandi  = 0;
00959        psc->nNumDhCandi  = 0;
00960        psc->nNumMhCandi  = 0;
00961        psc->nNumGbkCandi = 0;
00962        
00963        psc->nSizShCandi  = 0;
00964        psc->nSizDhCandi  = 0;
00965        psc->nSizMhCandi  = 0;
00966        psc->nSizGbkCandi = 0;
00967        
00968        free (psc->pwShCandi);
00969        free (psc->pwDhCandi);
00970        free (psc->pwMhCandi);
00971        free (psc->pwGbkCandi);
00972        psc->pwShCandi   = NULL;
00973        psc->pwDhCandi   = NULL;
00974        psc->pwMhCandi   = NULL;
00975        psc->pwGbkCandi  = NULL;
00976 }
00977 
00978 
00979 /*
00980 **  nLenYj indicates the length of pnOrgYj. 
00981 **  Max Length of nLenYj is 9, even Max Hanzi Length in
00982 **  current PyCiku.dat is 7.
00983 **
00984 **  Notice here: pnOrgYj[i] may be 0x00010000 + [0 ~ 475] to indicates there is 
00985 **               ['] before corressponding yinjie string.
00986 **  return TRUE or FALSE
00987 */
00988 JINT LookupCiku(JINT* pnOrgYj, JINT nLenYj, JINT nMatchMode, SysCandi* psc, UdcCandi* puc)
00989 {
00990        JINT    nSize, i;
00991 
00992        nSize = 0;
00993 
00994        InitStructSc(psc);
00995        InitStructUc(puc);
00996        
00997        /* 
00998        ** Set the content of psc->nOrgYj and pscYj->nLenYj    AND 
00999        ** Filter those Yjcode which start with a [']. 
01000        */
01001        for(i = 0; i < nLenYj; i++)
01002        {
01003               psc->nOrgYj[i]  = pnOrgYj[i];
01004               pnOrgYj[i]     &= 0x0000FFFF;
01005        }
01006        psc->nLenYj  = nLenYj;
01007        
01008        EnumCandi(pnOrgYj, nLenYj, psc, puc, &nSize, nMatchMode, LU_CANDI_CALC);
01009        
01010        psc->pwMhCandi    = (JWORD*)malloc((psc->nSizMhCandi  + MALIGN) * sizeof(JWORD));
01011        psc->pwDhCandi    = (JWORD*)malloc((psc->nSizDhCandi  + MALIGN) * sizeof(JWORD));
01012        psc->pwShCandi    = (JWORD*)malloc((psc->nSizShCandi  + MALIGN) * sizeof(JWORD));
01013        psc->pwGbkCandi   = (JWORD*)malloc((psc->nSizGbkCandi + MALIGN) * sizeof(JWORD));
01014        puc->pwUdc28Candi = (JWORD*)malloc((puc->nSizUdc28Candi + MALIGN) * sizeof(JWORD));
01015 
01016        if ((psc->pwMhCandi == NULL)  || (psc->pwDhCandi == NULL) || (psc->pwShCandi == NULL) || 
01017               (psc->pwGbkCandi == NULL) || (puc->pwUdc28Candi == NULL) )
01018        {
01019               fprintf(stderr, "Error!! Failed to Malloc() in Function LookupCiku().\n");
01020               return FALSE;
01021        }
01022 
01023        memset(psc->pwMhCandi,  '\0', (psc->nSizMhCandi  + MALIGN) * sizeof(JWORD));
01024        memset(psc->pwDhCandi,  '\0', (psc->nSizDhCandi  + MALIGN) * sizeof(JWORD));
01025        memset(psc->pwShCandi,  '\0', (psc->nSizShCandi  + MALIGN) * sizeof(JWORD));
01026        memset(psc->pwGbkCandi, '\0', (psc->nSizGbkCandi + MALIGN) * sizeof(JWORD));
01027        memset(puc->pwUdc28Candi, '\0', (puc->nSizUdc28Candi + MALIGN) * sizeof(JWORD));
01028        
01029        EnumCandi(pnOrgYj, nLenYj, psc, puc, &nSize, nMatchMode, LU_CANDI_WRITE);
01030        
01031        /* Additional Process for Spec Hanzi Candi, MXL 98.01.12 */
01032        if (0 == (psc->nNumMhCandi + psc->nNumDhCandi + puc->nNumUdc28Candi))
01033               puc->nNumSpecCandi = 0;
01034        
01035        /* Sort Candidates in structure SysCandi and UdcCandi by Frequence */
01036        SortCandi(psc, puc);
01037        
01038        return TRUE;
01039 }
01040 
01041 
01042 /*
01043 **  Sort Candidates in Structure SysCandi by Length and Frequence
01044 **  
01045 **  NOT IMPROVED:
01046 **  [** TO IMPROVE: In SortSysCandi(), Rearrange XIAN candies to proper position **] 97.11.28.
01047 **  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
01048 */
01049 VOID SortCandi(SysCandi* psc, UdcCandi* puc)
01050 {
01051        JINT    nNumM, nSizM, nNumD, nSizD, nNumUdc28, nSizUdc28;
01052        JINT    nBuf, nTmp, i, k, m, n, p, nLenM, nFreqM, nLenUdc28, nFreqUdc28;
01053        JWORD   *pwBuf = NULL;
01054        
01055        nNumM   = psc->nNumMhCandi;
01056        nSizM   = psc->nSizMhCandi;
01057        nNumD   = psc->nNumDhCandi;
01058        nSizD   = psc->nSizDhCandi;
01059        nNumUdc28 = puc->nNumUdc28Candi;
01060        nSizUdc28 = puc->nSizUdc28Candi;
01061 
01062        if ((nNumM <= 1) && (nNumD <= 1) && (nNumUdc28 <= 1))
01063               return;
01064        
01065        nBuf = max(nSizM, nSizD);
01066        nBuf = max(nBuf, nSizUdc28);
01067        
01068        pwBuf = (JWORD *)malloc((nBuf + MALIGN) * sizeof(JWORD));
01069        if (pwBuf == NULL)
01070        {
01071               fprintf(stderr, "Failed to alloc Memory in function SortSysCandi().\n");
01072               return;
01073        }
01074        
01075        /*
01076        **  For MultipleHanzi Candidates, by Length First, by Frequence Second.
01077        */
01078        nLenM = nFreqM = 0;
01079        if(nNumM > 1)
01080        {
01081               memset(pwBuf, '\0', (nBuf + MALIGN) * sizeof(JWORD));
01082               
01083               p = m = n = 0;
01084               for(i = 0xFF; (i >= 0x00) && (p < nNumM); i--)
01085               {
01086                      for(k = 0; k < nSizM; )
01087                      {
01088                             /*
01089                             **  Exchange [Freq + Len] to [Len + Freq] (nTmp), because by Length first.
01090                             **  Notice: (nLen + 2) is the really length of this Mh Cizu,
01091                             **          another 2 is (Len+Freq) WORD in front and Zero WORD in End.
01092                             */
01093                             nLenM  = psc->pwMhCandi[k] & 0x07;
01094                             nFreqM = psc->pwMhCandi[k] & 0xF8;
01095                             nTmp   = (nLenM << 5) + (nFreqM >> 3);
01096                             if(nTmp == i)
01097                             {
01098                                    for(m = 0; m < (nLenM + 2 + 2); m++)
01099                                           pwBuf[n++] = psc->pwMhCandi[k + m];
01100                                    p++;
01101                             }
01102                             k += (nLenM + 2 + 2);
01103                      }
01104               }
01105               
01106               for(i = 0; i < nSizM; i++)
01107                      psc->pwMhCandi[i] = pwBuf[i];
01108        }
01109        
01110        /*
01111        **  For DoubleHanzi Candidates, by Frequence only.
01112        */
01113        if(nNumD > 1)
01114        {
01115               memset(pwBuf, '\0', (nBuf + MALIGN) * sizeof(JWORD));
01116               
01117               p = m = n = 0;
01118               for(i = 0xFF; (i >= 0x00) && (p < nNumD); i--)
01119               {
01120                      for(k = 0; k < nSizD; k++)
01121                      {
01122                             nTmp   = psc->pwDhCandi[k];
01123                             if(nTmp == i)
01124                             {
01125                                    for(m = 0; m < (2 + 2); m++)
01126                                           pwBuf[n++] = psc->pwDhCandi[k + m];
01127                                    p++;
01128                             }
01129                      }
01130               }
01131               
01132               for(i = 0; i < nSizD; i++)
01133                      psc->pwDhCandi[i] = pwBuf[i];
01134        }
01135 
01136 
01137        /*
01138        **  For Udc come from <UdCiku.dat>, by Length First, by Frequence Second.
01139        */
01140        nLenUdc28 = nFreqUdc28 = 0;
01141        if(nNumUdc28 > 1)
01142        {
01143               memset(pwBuf, '\0', (nBuf + MALIGN) * sizeof(JWORD));
01144               
01145               p = m = n = 0;
01146               for(i = 0xFF; (i >= 0x00) && (p < nNumUdc28); i--)
01147               {
01148                      for(k = 0; k < nSizUdc28; )
01149                      {
01150                             /*
01151                             **  Exchange [Freq + Len] to [Len + Freq] (nTmp), because by Length first.
01152                             **  Notice: (nLen + 2) is the really length of this Mh Cizu,
01153                             **          another 2 is (Len+Freq) WORD in front and Zero WORD in End.
01154                             */
01155                             nLenUdc28  = puc->pwUdc28Candi[k] & 0x07;
01156                             nFreqUdc28 = puc->pwUdc28Candi[k] & 0xF8;
01157                             nTmp   = (nLenUdc28 << 5) + (nFreqUdc28 >> 3);
01158                             if(nTmp == i)
01159                             {
01160                                    for(m = 0; m < (nLenUdc28 + 2 + 2); m++)
01161                                           pwBuf[n++] = puc->pwUdc28Candi[k + m];
01162                                    p++;
01163                             }
01164                             k += (nLenUdc28 + 2 + 2);
01165                      }
01166               }
01167               
01168               for(i = 0; i < nSizUdc28; i++)
01169                      puc->pwUdc28Candi[i] = pwBuf[i];
01170        }
01171 
01172        free(pwBuf);
01173 }
01174 
01175 
01176 /*
01177 **  Adjust the freqence of a specified Ciku. Length of this cizu is 
01178 **  specified in nLen.
01179 **
01180 **  Increase the frequence of this Dh or Mh, decrease the frequence
01181 **  of other Dh or Mh which have same Yjcode.
01182 **
01183 **  For Sh, move the Hanzi forward to a certain place, move other
01184 **  Hanzies backward.
01185 */
01186 VOID AdjustFreq(JWORD* pwHz2244, JINT nLenThis)
01187 {
01188        JINT    nYjFirst;
01189        JINT    nCzLen, i, k, m, t;
01190        JINT    nFromOff, nToOff;
01191        JWORD   wCzHz, wMhLenFreq, wFreq;
01192        JINT    nEqualFlag;
01193        CHAR    szDhYj1[14], szDhYj2[14];
01194        UCHAR   pchHz2244[20];     /* Max is 9 Hanzi!! */
01195        JINT    nFindFlag;
01196        JINT    nUdc28FreqLen, nUdc28Len;
01197        JINT    nCurSize;
01198        JINT    nXianNum, nPos;
01199        BYTE    *pbAreaBase;
01200 
01201        CikuHeader  *pCkh;
01202        ShIndex     *pShi;
01203        DhIndex     *pDhi;
01204        MhIndex     *pMhi;
01205        GbkIndex    *pGbki;
01206        BYTE        *pShArea;
01207        BYTE        *pDhArea;
01208        BYTE        *pMhArea;
01209        BYTE        *pGbkArea;
01210 
01211        pCkh     = (CikuHeader *)pCkAll;
01212        pShi     = (ShIndex  *)(pCkAll + pCkh->nIdxShPos);
01213        pDhi     = (DhIndex  *)(pCkAll + pCkh->nIdxDhPos);
01214        pMhi     = (MhIndex  *)(pCkAll + pCkh->nIdxMhPos);
01215        pGbki    = (GbkIndex *)(pCkAll + pCkh->nIdxGbkPos);
01216        
01217        pShArea  = (BYTE *)(pCkAll + pShi->nStartPos);
01218        pDhArea  = (BYTE *)(pCkAll + pDhi->nStartPos);
01219        pMhArea  = (BYTE *)(pCkAll + pMhi->nStartPos);
01220        pGbkArea = (BYTE *)(pCkAll + pGbki->nStartPos);
01221 
01222        if (nLenThis > 9) nLenThis = 9;
01223        memset(pchHz2244, '\0', 20);
01224        Jword2Uchar(pwHz2244, pchHz2244, nLenThis);
01225        
01226        nFindFlag = FALSE;
01227        /* nYjFirst must be in range 0~414 */
01228        nYjFirst = GbkHz2244ToYj((JINT)pwHz2244[0]);
01229 
01230        if (nLenThis >= 3)
01231        {
01232               /*
01233               **  Determine the FromOff and ToOff which to used for searching by the pnOrgYj[0].
01234               */
01235               nFromOff = pMhi->nYjOff[ nYjFirst ];
01236               nToOff   = pMhi->nYjOff[ nYjFirst + 1];
01237               
01238               /* !! DON'T add k++ in this FOR sentence !! */
01239               for (k = nFromOff; k < nToOff; )
01240               {
01241                      wMhLenFreq = (JWORD)*(pMhArea + k);
01242                      nCzLen     = 2 + ((UCHAR)*(pMhArea + k) & 0x07);
01243                      k++;
01244 
01245                      /*  It is just this Cizu, Increase its frequence here. */
01246                      if ((nCzLen == nLenThis) &&
01247                             (strncmp((CHAR*)(&pMhArea[k]), (CHAR*)pchHz2244, 2 * nCzLen) == 0) )
01248                      {
01249                             /* Just set Frequence to highest. */
01250                             *(pMhArea + k - 1) = (BYTE)(0xF8 + (nCzLen - 2));
01251                             k += (2 * nCzLen);
01252                             nFindFlag = TRUE;
01253                      }
01254                      /*
01255                      **  Have the same length. Is it also have same Yjcode? If yes, 
01256                      **  reduce the frequence.
01257                      */
01258                      else if ((nCzLen == nLenThis) &&
01259                              (strncmp((CHAR*)(&pMhArea[k]), (CHAR*)pchHz2244, 2 * nCzLen) != 0) )
01260                      {
01261                             nEqualFlag = TRUE;
01262 
01263                             /*
01264                             ** Compare from the second Hanzi, because the first Hanzi must
01265                             ** same Yjcode. So, skip the first by adding t += 2.
01266                             */
01267                             t = k;
01268                             t += 2;
01269                             for (m = 1; m < nCzLen; m++)
01270                             {
01271                                    wCzHz   = (JWORD)(*(pMhArea + t + 1) + ((*(pMhArea + t)) << 8));
01272                                    t += 2;
01273 
01274                                    if ( GbkHz2244ToYj((JINT)pwHz2244[1]) != GbkHz2244ToYj((JINT)wCzHz) )
01275                                    {
01276                                           nEqualFlag = FALSE;
01277                                           break;
01278                                    }
01279                             }
01280 
01281                             /* Have same Yjcodes in every Hanzi, reduce its Frequence Here. */
01282                             if (nEqualFlag == TRUE)
01283                             {
01284                                    wMhLenFreq = (JWORD)*(pMhArea + k - 1);
01285                                    /*
01286                                    ** Length bits have the lowest 3 bits.  -8 means reduce the Frequence
01287                                    ** by ONE level. if its Freq Level is 1, no reduce needed.
01288                                    */
01289                                    if (wMhLenFreq >= 16)
01290                                           *(pMhArea + k - 1) -= 8;
01291                             }
01292 
01293                             k += (2 * nCzLen);
01294                      }
01295                      /* If it doesn't have the same length, just skip this cizu. */
01296                      else
01297                             k += (2 * nCzLen);
01298               }
01299        }
01300        
01301        else if (nLenThis == 2)
01302        {
01303               /*
01304               **  Determine the FromOff and ToOff which to used for searching by the pnOrgYj[0].
01305               */
01306               nFromOff = pDhi->nYjOff[ nYjFirst ];
01307               nToOff   = pDhi->nYjOff[ nYjFirst + 1];
01308               
01309               /* !! DON'T add k++ in this FOR sentence !! */
01310               for (k = nFromOff; k < nToOff; )
01311               {
01312                      wFreq   = (JWORD)*(pDhArea + k);
01313                      nCzLen  = 2;
01314                      k++;
01315 
01316                      /*  It is just this Cizu, Increase its frequence here. */
01317                      if (strncmp((CHAR*)(&pDhArea[k]), (CHAR*)pchHz2244, 4) == 0)
01318                      {
01319                             *(pDhArea + k - 1) = 0xFF;
01320                             k += 4;
01321                             nFindFlag = TRUE;
01322                      }
01323                      /*
01324                      **  Have the same length. Is it also have same Yjcode? If yes, 
01325                      **  reduce the frequence.
01326                      */
01327                      else
01328                      {
01329                             for(i = 0; i < 14; i++)
01330                                    szDhYj1[i] = szDhYj2[i] = '\0';
01331 
01332                             /* Cat total YinjieString into szDhYj1 */
01333                             strcat( strcat(szDhYj1, YINJIESTR_CSZ[nYjFirst]),       
01334                                                     YINJIESTR_CSZ[GbkHz2244ToYj((JINT)pwHz2244[1])] );
01335 
01336                             t = k;
01337                             wCzHz   = (JWORD)(*(pDhArea + t + 1) + ((*(pDhArea + t)) << 8));
01338                             strcat(szDhYj2, YINJIESTR_CSZ[GbkHz2244ToYj((JINT)wCzHz)]);
01339 
01340                             t += 2;
01341                             wCzHz   = (JWORD)(*(pDhArea + t + 1) + ((*(pDhArea + t)) << 8));
01342                             strcat(szDhYj2, YINJIESTR_CSZ[GbkHz2244ToYj((JINT)wCzHz)]);
01343 
01344                             nEqualFlag = TRUE;
01345                             if (strcmp(szDhYj1, szDhYj2) != 0)
01346                                    nEqualFlag = FALSE;
01347 
01348                             /* Have same Yjcodes in every Hanzi, reduce its Frequence Here. */
01349                             if (nEqualFlag == TRUE)
01350                             {
01351                                    wFreq = (JWORD)*(pDhArea + k - 1);
01352                                    /*
01353                                    ** Decrease by ONE Level.
01354                                    */
01355                                    if (wFreq >= 2)
01356                                           *(pDhArea + k - 1) -= 1;
01357                             }
01358                             k += 4;
01359 
01360                      }
01361               }
01362        }
01363 
01364        /* nLenThis == 1, GB and GBK */
01365        else if (nLenThis == 1)
01366        {
01367               if (IsGbkkkHz(pwHz2244[0]) == TRUE)   /* GbKkk */
01368               {
01369                      nFromOff   = pGbki->nYjOff[ nYjFirst ];
01370                      nToOff     = pGbki->nYjOff[ nYjFirst + 1 ];
01371                      pbAreaBase = pGbkArea;
01372               }
01373               else    /* Normal GB */
01374               {
01375                      nXianNum   = (pShi->nYjOff[nYjFirst + 1] & 0x0F000000) >> 24;
01376                      nFromOff   = pShi->nYjOff[nYjFirst] & 0x00FFFFFF;
01377                      nToOff     = (pShi->nYjOff[nYjFirst + 1] & 0x00FFFFFF) - (4 * nXianNum);
01378                      pbAreaBase = pShArea;
01379               }
01380               
01381               nPos = 0;
01382               for (k = nFromOff; k < nToOff; k += 2)
01383               {
01384                      if (strncmp((CHAR*)(&pbAreaBase[k]), (CHAR*)pchHz2244, 2) == 0)
01385                      {
01386                             nPos = (k - nFromOff) / 2;
01387                             break;
01388                      }
01389               }
01390               
01391               /*
01392               **  If NOT the first Hanzi in ShArea[nYj] or GbkArea[nYj], move this Hanzi
01393               **  forward by (nPos / 4  + 1)
01394               */
01395               if (nPos > 0)
01396               {
01397                      m = 0;
01398                      for (k = nFromOff + (2 * nPos); m < (nPos / 4  + 1); )
01399                      {
01400                             pbAreaBase[k + 1] = pbAreaBase[k - 1];
01401                             pbAreaBase[k]     = pbAreaBase[k - 2];
01402                             k -= 2;
01403                             m++;
01404                      }
01405                      pbAreaBase[k + 1] = pchHz2244[1];
01406                      pbAreaBase[k]     = pchHz2244[0];
01407               }
01408        }
01409 
01410        /*
01411        **  Otherwise, this must be an UserDefinedCizu.
01412        */
01413        if ((nLenThis >= 2) && (nFindFlag == FALSE))
01414        {
01415               nCurSize   = udcAll.udci.nYjOff[nYjFirst + 1] - udcAll.udci.nYjOff[nYjFirst];      /* In BYTE */
01416 
01417               /* NO i++ in this FOR sentence */
01418               for (i = 0; i < nCurSize / 2; )
01419               {
01420                      nUdc28FreqLen =  udcAll.pwUdc28[nYjFirst][i] & 0x00FF;
01421                      nUdc28Len     = (udcAll.pwUdc28[nYjFirst][i] & 0x0007) + 2;
01422                      i++;
01423 
01424                      /*  It is just this Cizu, Increase its frequence here. */
01425                      if ((nUdc28Len == nLenThis) &&
01426                             (strncmp((CHAR*)&(udcAll.pwUdc28[nYjFirst][i]), (CHAR*)pchHz2244, 2 * nUdc28Len) == 0) )
01427                      {
01428                             /* Just set Frequence to highest. */
01429                             udcAll.pwUdc28[nYjFirst][i - 1] = (BYTE)(0xF8 + (nUdc28Len - 2));
01430                             i += nUdc28Len;
01431                             nFindFlag = TRUE;
01432                      }
01433                      else
01434                      {
01435                             if (nUdc28FreqLen >= 0x0010)
01436                                    udcAll.pwUdc28[nYjFirst][i - 1] -= 8;
01437                             i += nUdc28Len;
01438                      }
01439               }
01440        }
01441 
01442 }
01443 
01444 
01445 /*
01446 **  Lookup the System Ciku and User Defined Ciku to find out whether pwHz2244 Exist or not.
01447 **  Length of this Cizu is given in nLenThis.  Constant is defined file <CikuOper.h>
01448 **  If NO,                           RETURN 0;  ==>  NON_EXIST_CIZU 
01449 **  If YES && in System Ciku,        RETURN 1;  ==>  SYS_EXIST_CIZU 
01450 **  If YES && in User Defined Ciku,  RETURN 2;  ==>  UDC_EXIST_CIZU 
01451 */
01452 JINT IsCizuExist(JWORD* pwHz2244, JINT nLenThis)
01453 {
01454        JINT    nFindFlag;
01455        
01456        JINT    nYjFirst;
01457        JINT    nCzLen, i, k;
01458        JINT    nFromOff, nToOff;
01459        JWORD   wMhLenFreq, wFreq;
01460        UCHAR   pchHz2244[20];     /* Max is 9 Hanzi!! */
01461        JINT    nCurSize, nUdc28FreqLen, nUdc28Len;
01462 
01463        CikuHeader  *pCkh;
01464        ShIndex     *pShi;
01465        DhIndex     *pDhi;
01466        MhIndex     *pMhi;
01467        GbkIndex    *pGbki;
01468        BYTE        *pShArea;
01469        BYTE        *pDhArea;
01470        BYTE        *pMhArea;
01471        BYTE        *pGbkArea;
01472 
01473        pCkh     = (CikuHeader *)pCkAll;
01474        pShi     = (ShIndex  *)(pCkAll + pCkh->nIdxShPos);
01475        pDhi     = (DhIndex  *)(pCkAll + pCkh->nIdxDhPos);
01476        pMhi     = (MhIndex  *)(pCkAll + pCkh->nIdxMhPos);
01477        pGbki    = (GbkIndex *)(pCkAll + pCkh->nIdxGbkPos);
01478        
01479        pShArea  = (BYTE *)(pCkAll + pShi->nStartPos);
01480        pDhArea  = (BYTE *)(pCkAll + pDhi->nStartPos);
01481        pMhArea  = (BYTE *)(pCkAll + pMhi->nStartPos);
01482        pGbkArea = (BYTE *)(pCkAll + pGbki->nStartPos);
01483 
01484        nFindFlag = NON_EXIST_CIZU;
01485        if (nLenThis > 9) nLenThis = 9;
01486        memset(pchHz2244, '\0', 20);
01487        Jword2Uchar(pwHz2244, pchHz2244, nLenThis);
01488        
01489        /* nYjFirst must be in range 0~414 */
01490        nYjFirst = GbkHz2244ToYj((JINT)pwHz2244[0]);
01491 
01492        if (nLenThis >= 3)
01493        {
01494               /*
01495               **  Determine the FromOff and ToOff which to used for searching by the pnOrgYj[0].
01496               */
01497               nFromOff = pMhi->nYjOff[ nYjFirst ];
01498               nToOff   = pMhi->nYjOff[ nYjFirst + 1];
01499               
01500               /* !! DON'T add k++ in this FOR sentence !! */
01501               for (k = nFromOff; k < nToOff; )
01502               {
01503                      wMhLenFreq = (JWORD)*(pMhArea + k);
01504                      nCzLen     = 2 + ((UCHAR)*(pMhArea + k) & 0x07);
01505                      k++;
01506 
01507                      /*  It is just this Cizu, Set nFindFlag and return */
01508                      if ((nCzLen == nLenThis) &&
01509                             (strncmp((CHAR*)(&pMhArea[k]), (CHAR*)pchHz2244, 2 * nCzLen) == 0) )
01510                      {
01511                             nFindFlag  = SYS_EXIST_CIZU;
01512                             return nFindFlag;
01513                      }
01514                      /* Just Skip this Mh Word */
01515                      else
01516                             k += (2 * nCzLen);
01517               }
01518        }
01519        
01520        else if (nLenThis == 2)
01521        {
01522               /*
01523               **  Determine the FromOff and ToOff which to used for searching by the pnOrgYj[0].
01524               */
01525               nFromOff = pDhi->nYjOff[ nYjFirst ];
01526               nToOff   = pDhi->nYjOff[ nYjFirst + 1];
01527               
01528               /* !! DON'T add k++ in this FOR sentence !! */
01529               for (k = nFromOff; k < nToOff; )
01530               {
01531                      wFreq   = (JWORD)*(pDhArea + k);
01532                      nCzLen  = 2;
01533                      k++;
01534 
01535                      /* It is just this Cizu, Increase its frequence here. */
01536                      if (strncmp((CHAR*)(&pDhArea[k]), (CHAR*)pchHz2244, 4) == 0)
01537                      {
01538                             nFindFlag  = SYS_EXIST_CIZU;
01539                             return nFindFlag;
01540                      }
01541                      /* Just Skip this Dh Cizu */
01542                      else
01543                             k += 2 * nCzLen;
01544               }
01545        }
01546        
01547        else if (nLenThis == 1)
01548        {
01549               nFindFlag = SYS_EXIST_CIZU;
01550               return nFindFlag;
01551        }
01552        
01553        if (nFindFlag == NON_EXIST_CIZU)
01554        {
01555               nCurSize   = udcAll.udci.nYjOff[nYjFirst + 1] - udcAll.udci.nYjOff[nYjFirst];      /* In BYTE */
01556 
01557               /* NO i++ in this FOR sentence */
01558               for (i = 0; i < nCurSize / 2; )
01559               {
01560                      nUdc28FreqLen =  udcAll.pwUdc28[nYjFirst][i] & 0x00FF;
01561                      nUdc28Len     = (udcAll.pwUdc28[nYjFirst][i] & 0x0007) + 2;
01562                      i++;
01563 
01564                      /*  It is just this Cizu, Increase its frequence here. 
01565                      **
01566                      **  A Small & Big BUG was Arrested!! aHa!! 97-12-28!!
01567                      **  This bug appear in INTEL x86 CPU!!
01568                      if ((nUdc28Len == nLenThis) &&
01569                             (strncmp((CHAR*)&(udcAll.pwUdc28[nYjFirst][i]), (CHAR*)pchHz2244, 2 * nUdc28Len) == 0) )
01570                      */
01571                      if ((nUdc28Len == nLenThis) &&
01572                             (JwordNCmp(&(udcAll.pwUdc28[nYjFirst][i]), pwHz2244, nUdc28Len) == 0) )
01573                      {
01574                             nFindFlag  = UDC_EXIST_CIZU;
01575                             return nFindFlag;
01576                      }
01577                      else
01578                             i += nUdc28Len;
01579               }
01580        }
01581        
01582        return nFindFlag;      /* Must be NON_EXIST_CIZU HERE. */
01583 }
01584 
01585 
01586 /*
01587 **  Enumlate all those Mh, Dh and Sh selections in pSge->pwSlctHz
01588 **  AND call AdjustFreq().
01589 **  JWORD     pwSlctHz[512];     Selected Hanzi of Every Step, each seperated by 0009
01590 **  JWORD     pwSlctRawPy[512];  Crossponding Pinyin (include <'> <~>) of above Hz2244, septed by 0009
01591 **  JINT      nSlctSteps;        Step Number of Selection
01592 **
01593 **  This function may only be called after FULL COMMITTED!!!
01594 */
01595 VOID ProcFreq(SesGuiElement* pSge)
01596 {
01597        JINT    i, k, m;
01598        JWORD   wThisSel[9];        /* Contain Hz2244 Cizu Item */
01599        JINT    nLenThis;
01600 
01601        k = 0;
01602        nLenThis = 0;
01603        for(m = 0; m < 9; m++)
01604               wThisSel[m] = 0x0000;
01605 
01606        /* Don't add i++ and k++ in this FOR sentence */
01607        for (i = 0; (i < pSge->nSlctSteps) && (k < UTWO); )
01608        {
01609               if (pSge->pwSlctHz[k] == 0x0009)
01610               {
01611                      k++;
01612                      i++;
01613                      AdjustFreq(wThisSel, nLenThis);
01614                      for(m = 0; m < 9; m++)
01615                             wThisSel[m] = 0x0000;
01616                      nLenThis = 0;
01617               }
01618               else
01619               {
01620                      wThisSel[nLenThis] = pSge->pwSlctHz[k];
01621                      nLenThis++;
01622                      k++;
01623               }
01624        }
01625 }
01626