Back to index

im-sdk  12.3.91
UdCikuOper.c
Go to the documentation of this file.
00001 /*
00002 Copyright 1990-2001 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 #include "PYIM.h"
00043 
00044 /* Jword.c */
00045 JINT    GbkHz2244ToYjSM(JINT nHzcode);
00046 JINT    GbkHz2244ToYj(JINT nHzcode);
00047 UCHAR*  RecovDyz2244(UCHAR *szDyz2244);
00048 VOID    Jword2Uchar(JWORD* pwJword, UCHAR* szUch, JINT nMaxLen);
00049 VOID    JwordNCpy(JWORD* pwDst, JWORD* pwSrc, JINT nLen);
00050 JINT    JwordNCmp(JWORD* pwSrc1, JWORD* pwSrc2, JINT nNum);
00051 JINT    JwordValidLen(JWORD* pwJwordArray, JINT nMaxLen);
00052 JINT    JwordHanziLen(JWORD* pwJwordArray, JINT nMaxLen);
00053 
00054 VOID    ProcUdCizu(SesGuiElement* pSge);
00055 VOID    UniformSlctHz(SesGuiElement* pSge);
00056 JINT    GetNSelect(JINT nXrd, JINT nTotalStep, JWORD* pwSlctHz, JWORD* pwUdcUnit);
00057 VOID    AdjustFreq(JWORD* pwHz2244, JINT nLenThis);
00058 JINT    IsCizuExist(JWORD* pwHz2244, JINT nLenThis);
00059 VOID    JwordInfo(JWORD* pwJwordArray, JINT nMaxLen);
00060 
00061 VOID    WarpByte(VOID* pv, JINT n);
00062 VOID    WarpIndex(ShIndex* pInt419);
00063 VOID    WarpCikuHeader(CikuHeader* pCh);
00064 
00065 JINT    ReadUdcData(CHAR* szUdcName);
00066 JINT    WriteUdcData(CHAR* szUdcName, JINT nTimeStamp);
00067 JINT    AddUdc(JWORD* pwHz2244, JINT nLen);
00068 JINT    DelUdc(JWORD* pwHz2244, JINT nLen);
00069 JINT    PureUdc(VOID);
00070 VOID    FreeUdcData();
00071 VOID    InitStructUc(UdcCandi* puc);
00072 
00073 JINT    HasNonLinkHz(JWORD* pwSlctHz, JINT nTotalSteps);
00074 JINT    IsXrdNonLinkHz(JINT nXrd, JWORD* pwSlctHz, JINT nTotalSteps);
00075 JINT    IsXrdPreLinkHz(JINT nXrd, JWORD* pwSlctHz, JINT nTotalSteps);
00076 JINT    IsXrdSufLinkHz(JINT nXrd, JWORD* pwSlctHz, JINT nTotalSteps);
00077 JINT    TypeOfNSelect (JINT nXrd, JWORD* pwSlctHz, JINT nTotalSteps);
00078 
00079 /* Type Value of function TypeOfNSelect() return */
00080 #define SLCT_TYPE_INVALID     0        /* Invalid Selection */
00081 #define SLCT_TYPE_NONLINK     1        /* One of Non Link Hanzi */
00082 #define SLCT_TYPE_PRELINK     2        /* One of Pre Link Hanzi */
00083 #define SLCT_TYPE_SUFLINK     3        /* One of Suf Link Hanzi */
00084 #define SLCT_TYPE_NORMHZ      4        /* Normal Single Hanzi */
00085 #define SLCT_TYPE_TWOHZ       5        /* Two Hanzi */
00086 #define SLCT_TYPE_THREEHZ     6        /* Three Hanzi */
00087 #define SLCT_TYPE_MFOURHZ     7        /* >= 4 Hanzi */
00088 
00089 UdcMemAll  udcAll;
00090 
00091 /***************************************************************************************
00092        
00093 NONLINKHZ[2 * NUM_NONLINKHZ + 2] =  <以下单字为: 前后均不可联的字, 在分词时作用类同标点符号>
00094 "是的了不也而你我他与它她其就和或";
00095   1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
00096 
00097 PRELINKHZ[2 * NUM_PRELINKHZ + 2] = <以下单字为: 只可与前联, 不可与后联>
00098 "们性员子上下中内外化者家儿年月日时分秒街路村";
00099   1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
00100 
00101 SUFLINKHZ[2 * NUM_SUFLINKHZ + 2] = <以下单字为: 只可与后联, 不可与前联>
00102 "不在这从到那哪第各每某本总当由如以为被使更且指于但将可应会该此全很都近约";
00103   1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
00104   
00105 ***************************************************************************************/
00106 
00107 /*
00108 **  Uniform pwSlctHz first, find these User Defined Cizu, and add them to UdCizu.dat.
00109 **  Call AddUdCizu(JWORD* pwHz2244, JINT nLen) to add this Cizu.
00110 */
00111 VOID ProcUdCizu(SesGuiElement* pSge)
00112 {
00113        JINT    i, j, k, m, w;
00114        JINT    nOrgStep, nUnifStep;
00115        JWORD   wTmp[10], wTmpBak[20];
00116        JINT    nTmpLen, nHzNum;
00117        JINT    nTypeSlct[8];              /* Max Length of User defined Cizu is 8 */
00118 
00119        nOrgStep   = pSge->nSlctSteps;
00120        /* Uniform pwSlctHz */
00121        UniformSlctHz(pSge);
00122        nUnifStep  = pSge->nSlctSteps;
00123        
00124        /* NOT JwordValidLen() Here. Don't count 0x0009 */
00125        nHzNum     = JwordHanziLen(pSge->pwSlctHz, UTWO);
00126        
00127        assert(nUnifStep != 0);
00128        
00129        /*
00130        **  以下 IF...ELSE... 逻辑中有重叠的情况, 为清晰起见, 分别列出. 
00131        **  如果归一为一个选择, 则立即返回.
00132        */
00133        if (nUnifStep <= 1)
00134               return;
00135        
00136        if ((nOrgStep == nHzNum) && (nHzNum <= 8) && (nUnifStep > 1))
00137        {
00138               memset (wTmp, '\0', 10 * sizeof(JWORD));
00139               nTmpLen  = 0;
00140               for (i = 0; i < nUnifStep; i++)
00141                      nTmpLen += GetNSelect(i, nUnifStep, pSge->pwSlctHz, &(wTmp[nTmpLen]));
00142 
00143               AddUdc (wTmp, nHzNum);
00144               return;
00145        }
00146        
00147        /*
00148        **  All condition OF  nHzNum <= 4, except that ((nHzNum == 4) && (HasNonLinkHz))
00149        **                AND nHzNum > 5, except nUnifStep is not two small.
00150        **  在不被归一为单个词组的情况下=> 双字和三字一定构成词,
00151        **                                 没有NONLINKHZ的四字也一定被定义为词.
00152        **                                 5 ~ 8字时,如果其中最多只有一个双字词, 即, 没有三字的情况, 
00153        **                                           其他均为单字, 且不是NONLINKHZ, 也被定义为词. 
00154        **  否则, 进入后面的处理过程.
00155        */
00156        if ( (nHzNum <= 3)                                                           || 
00157             ((nHzNum == 4)  && (!HasNonLinkHz(pSge->pwSlctHz, pSge->nSlctSteps)))   || 
00158             (((nHzNum >= 5) && (nHzNum <= 8))&& (nOrgStep >= (nHzNum - 1)) && 
00159             (nUnifStep >= (nHzNum - 1)) && (!HasNonLinkHz(pSge->pwSlctHz, pSge->nSlctSteps)))
00160           )
00161        {
00162               memset (wTmp, '\0', 10 * sizeof(JWORD));
00163               nTmpLen  = 0;
00164               for (i = 0; i < nUnifStep; i++)
00165                      nTmpLen += GetNSelect(i, nUnifStep, pSge->pwSlctHz, &(wTmp[nTmpLen]));
00166        
00167               AddUdc (wTmp, nHzNum);
00168               return;
00169        }
00170 
00171        /*
00172        **  此处处理包括: 四字中有NONLINKHZ的情况,
00173        **                5 ~ 8字中有多个双字词, 或有三字词的情况, 或有NONLINKHZ的情况, 
00174        **                以及在更长的其他所有情况.
00175        **
00176        **  NONLINKHZ  PRELINKHZ  SUFLINKHZ  NORMLINKHZ
00177        **  HZ2CIZU    HZ3CIZU    HZ48CIZU
00178        **  处理办法:     STEP1: 首先取最长8个字, 或者以NONLINKHZ分开, 或者以大于等于四字的已有词分开.
00179        **                       规定: PRELINKHZ不可与前面的四字以上已有词联结, SUFLINKHZ不可与后面的
00180        **                             四字以上已有词联结, 即, 划分出的任何单元中, 任何单字的前后四字
00181        **                             以上已有词或NONLINKHZ.
00182        **                       如果第一个为PRELINK, 则继续跳过, 如果第一个为SUFLINK, 则一定取下一个,
00183        **                             除非下一个为四字以上已有词, 否则双双跳过.
00184        **                STEP2: 从前往后进行处理, 如果第一个是单字, 第二个为双字或三字已有词, 则
00185        **  #define NUM_NONLINKHZ   16
00186        **  #define NUM_PRELINKHZ   22
00187        **  #define NUM_SUFLINKHZ   36
00188        */
00189        for (i = 0; i < nUnifStep;  )
00190        {
00191               /* Get maximum 8 types of the following selections */
00192               for (j = 0; j < 8; j++)
00193                      nTypeSlct[j] = TypeOfNSelect (i + j, pSge->pwSlctHz, nUnifStep);
00194                      
00195               /* >= 4 Phrase or NonLinkHz */
00196               if ((nTypeSlct[0] == SLCT_TYPE_MFOURHZ) || (nTypeSlct[0] == SLCT_TYPE_NONLINK))
00197               {
00198                      i++;
00199                      continue;
00200               }
00201               
00202               else if ((nTypeSlct[0] == SLCT_TYPE_PRELINK) || (nTypeSlct[0] == SLCT_TYPE_SUFLINK) 
00203                      || (nTypeSlct[0] == SLCT_TYPE_NORMHZ))
00204               {
00205                      m = k = 1;      /* Count for single Hanzi */
00206                      for (j = 1; j < 8; j++)
00207                      {
00208                             if ((nTypeSlct[j] == SLCT_TYPE_PRELINK) || (nTypeSlct[j] == SLCT_TYPE_SUFLINK) 
00209                                    || (nTypeSlct[j] == SLCT_TYPE_NORMHZ))
00210                             {
00211                                    m++;
00212                                    k++;
00213                             }
00214                             else
00215                             {
00216                                    if (nTypeSlct[j - 1] == SLCT_TYPE_SUFLINK)
00217                                    {
00218                                           if (k > 0)
00219                                                  k--;
00220                                    }
00221                                    break;
00222                             }
00223                      }
00224               
00225                      /* Only a single Hanzi before other */
00226                      if (m == 1)      /* Both (k == 0) || (k == 1) */
00227                      {
00228                             if ((nTypeSlct[1] == SLCT_TYPE_TWOHZ) || (nTypeSlct[1] == SLCT_TYPE_THREEHZ))
00229                             {
00230                                    memset (wTmp, '\0', 10 * sizeof(JWORD));
00231                                    nTmpLen  = 0;
00232                                    nTmpLen += GetNSelect(i, nUnifStep, pSge->pwSlctHz, &(wTmp[nTmpLen]));
00233                                    nTmpLen += GetNSelect(i + 1, nUnifStep, pSge->pwSlctHz, &(wTmp[nTmpLen]));
00234                                    
00235                                    AddUdc (wTmp, nTmpLen);
00236                             }
00237                             
00238                             i++;
00239                             continue;
00240                      }
00241                      
00242                      /* Multiple Single Hanzi Connected!! Concentrated them into a single Phrase */
00243                      memset (wTmp, '\0', 10 * sizeof(JWORD));
00244                      nTmpLen  = 0;
00245                      for (j = i; j < (i + k); j++)
00246                             nTmpLen += GetNSelect(j, nUnifStep, pSge->pwSlctHz, &(wTmp[nTmpLen]));
00247                      
00248                      AddUdc (wTmp, nTmpLen);
00249                      i += k;
00250                      continue;
00251               }
00252               else if ((nTypeSlct[0] == SLCT_TYPE_TWOHZ) || (nTypeSlct[0] == SLCT_TYPE_THREEHZ))
00253               {
00254                      if (nTypeSlct[1] == SLCT_TYPE_PRELINK)
00255                      {
00256                             memset (wTmp, '\0', 10 * sizeof(JWORD));
00257                             nTmpLen  = 0;
00258                             nTmpLen += GetNSelect(i, nUnifStep, pSge->pwSlctHz, &(wTmp[nTmpLen]));
00259                             nTmpLen += GetNSelect(i + 1, nUnifStep, pSge->pwSlctHz, &(wTmp[nTmpLen]));
00260 
00261                             AddUdc (wTmp, nTmpLen);
00262 
00263                             i += 2;
00264                             continue;
00265                      }
00266                      else if (nTypeSlct[1] == SLCT_TYPE_NORMHZ)
00267                      {
00268                             memset (wTmp, '\0', 10 * sizeof(JWORD));
00269                             nTmpLen  = 0;
00270                             nTmpLen += GetNSelect(i, nUnifStep, pSge->pwSlctHz, &(wTmp[nTmpLen]));
00271                             nTmpLen += GetNSelect(i + 1, nUnifStep, pSge->pwSlctHz, &(wTmp[nTmpLen]));
00272 
00273                             AddUdc (wTmp, nTmpLen);
00274 
00275                             i++;
00276                             continue;
00277                      }
00278                      else
00279                      {
00280                             i++;
00281                             continue;
00282                      }
00283               }
00284               else
00285               {
00286                      i++;
00287                      continue;
00288               }
00289        }
00290        
00291        return;
00292 }
00293 
00294 
00295 /*
00296 **  Adjust pSge->pwSlctHz and pSge->nSlctSteps to make seperated selected Hanzi
00297 **  to be a single Hanzi. For example, "中", "国", "人" was uniformed as "中国人".
00298 **  Atfer this uniformation, CALL AdjustFreq("中国人") also.
00299 **  pSge->nSlctSteps was adjusted also.
00300 **  pSge->pwSlctHz was seperated by 0x0009 still.
00301 **         ________
00302 **        /  <-----\
00303 **                   ______  _____
00304 **                  / <----\/ <---\
00305 **        OO O OOO OOOO O O OOO OO O  ( Random pwSlctHz )
00306 **
00307 */
00308 VOID UniformSlctHz(SesGuiElement* pSge)
00309 {
00310        JINT    nOrgStep;
00311        JWORD   wTmpAllSlct[UTWO];
00312        JINT    nUnifPos, nUnifStep;
00313        JWORD   wCombCizu[20], wThisCizu[10];
00314        JINT    nTmpLen;
00315        JINT    nEndPos;
00316        JINT    i, j, k;
00317        
00318        memset (wTmpAllSlct,  '\0', UTWO * sizeof(JWORD));
00319        memset (wCombCizu,    '\0', 20 * sizeof(JWORD));
00320        memset (wThisCizu,    '\0', 10 * sizeof(JWORD));
00321        
00322        nOrgStep   = pSge->nSlctSteps;
00323        nUnifPos   = 0;
00324        nUnifStep  = 0;
00325        
00326        /* No i++ in this FOR sentence */
00327        for (i = 0; i < nOrgStep;  )
00328        {
00329               memset (wCombCizu,    '\0', 20 * sizeof(JWORD));
00330               memset (wThisCizu,    '\0', 10 * sizeof(JWORD));
00331 
00332               /* Calculate the end position which make the full length large than 8 */
00333               nTmpLen  = 0;
00334               for (j = i; (j < nOrgStep) && (nTmpLen <= 8); j++)
00335                      nTmpLen += GetNSelect(j, nOrgStep, pSge->pwSlctHz, wThisCizu);
00336               nEndPos = j - 1;
00337               
00338               for (k = nEndPos; k >= i; k--)       /* To be BROKEN */
00339               {
00340                      memset (wCombCizu, '\0', 20 * sizeof(JWORD));
00341                      nTmpLen = 0;
00342                      for(j = i; j <= k; j++)
00343                             nTmpLen += GetNSelect (j, nOrgStep, pSge->pwSlctHz, &(wCombCizu[nTmpLen]));
00344                      
00345                      if ( IsCizuExist(wCombCizu, nTmpLen) != NON_EXIST_CIZU )
00346                      {
00347                             /* 
00348                             **  Adjust Frequence ALSO!! Single Hanzi is already adjusted, 
00349                             **  No more adjustment again.
00350                             */
00351                             if (nTmpLen > 1)
00352                                    AdjustFreq(wCombCizu, nTmpLen);
00353                             
00354                             i = k + 1;
00355                             JwordNCpy( &(wTmpAllSlct[nUnifPos]), wCombCizu, nTmpLen);
00356 #ifdef _DEBUG                      
00357                             JwordInfo( &(wTmpAllSlct[nUnifPos]), 40);
00358 #endif
00359                             /*
00360                             **  Append a 0x0009 after Each Uniformed Cizu Also. (Like in pSge->pwSlctHz(). )
00361                             */
00362                             wTmpAllSlct[nUnifPos + nTmpLen] = 0x0009;
00363                             nUnifPos  += (nTmpLen + 1);
00364                             nUnifStep ++;
00365                             break;                /* break the FOR(k) recycle */
00366                      }
00367               }
00368        }
00369        
00370        memset(pSge->pwSlctHz, '\0', UTWO * sizeof(JWORD));
00371        JwordNCpy (pSge->pwSlctHz, wTmpAllSlct, UTWO);
00372        pSge->nSlctSteps = nUnifStep;
00373 }
00374 
00375 
00376 /*
00377 **  Get the Specified Selection Hz2244 in pwSlctHz to pwUdcUnit.
00378 **  0x0009 NO LONGER EXISTING!!
00379 */
00380 JINT GetNSelect(JINT nXrd, JINT nTotalStep, JWORD* pwSlctHz, JWORD* pwUdcUnit)
00381 {
00382        JINT    i, j, k, nUnitLen;
00383        
00384        assert((nXrd >= 0) && (nXrd < nTotalStep));
00385        
00386        j = k = nUnitLen = 0;
00387        for (i = 0; i < nTotalStep; )
00388        {
00389               if (i == nXrd)
00390               {
00391                      while (pwSlctHz[j] != 0x0009)
00392                      {
00393                             pwUdcUnit[k++] = pwSlctHz[j++];
00394                             nUnitLen++;
00395                      }
00396                      i++;
00397                      break;    /* BREAK the FOR sentence */
00398               }
00399               else    /* i != nXrd */
00400               {
00401                      if (pwSlctHz[j] == 0x0009)
00402                             i++;
00403                      j++;
00404               }
00405        }
00406        
00407        return nUnitLen;
00408 }
00409 
00410 /*
00411 **  Determine the type of this selection.
00412 **  One of following defined type.
00413 **  
00414        #define SLCT_TYPE_INVALID     0
00415        #define SLCT_TYPE_NONLINK     1
00416        #define SLCT_TYPE_PRELINK     2
00417        #define SLCT_TYPE_SUFLINK     3
00418        #define SLCT_TYPE_NORMHZ      4
00419        #define SLCT_TYPE_TWOHZ       5
00420        #define SLCT_TYPE_THREEHZ     6
00421        #define SLCT_TYPE_MFOURHZ     7
00422 */
00423 JINT TypeOfNSelect (JINT nXrd, JWORD* pwSlctHz, JINT nTotalSteps)
00424 {
00425        JWORD    wTmp[10];
00426        JINT     nLen;
00427        
00428        if ((nXrd >= nTotalSteps) || (nXrd < 0))
00429               return SLCT_TYPE_INVALID;
00430        
00431        memset (wTmp, '\0', 10 * sizeof(JWORD));
00432        nLen  = GetNSelect (nXrd, nTotalSteps, pwSlctHz, wTmp);
00433        
00434        if (nLen >= 4)
00435               return SLCT_TYPE_MFOURHZ;
00436        if (nLen == 3)
00437               return SLCT_TYPE_THREEHZ;
00438        if (nLen == 2)
00439               return SLCT_TYPE_TWOHZ;
00440        if (nLen == 1)
00441        {
00442               if (IsXrdNonLinkHz(nXrd, pwSlctHz, nTotalSteps) == TRUE)
00443                      return SLCT_TYPE_NONLINK;
00444               if (IsXrdPreLinkHz(nXrd, pwSlctHz, nTotalSteps) == TRUE)
00445                      return SLCT_TYPE_PRELINK;
00446               if (IsXrdSufLinkHz(nXrd, pwSlctHz, nTotalSteps) == TRUE)
00447                      return SLCT_TYPE_SUFLINK;
00448               return SLCT_TYPE_NORMHZ;
00449        }
00450        
00451        return SLCT_TYPE_INVALID;
00452 }
00453 
00454 
00455 /*
00456 **  Check to see whether there is at least one NONLINKHZ selection among nSteps Selection.
00457 **  If there IS,    return TRUE
00458 **  else (IS NOT),  return FALSE
00459 **  NONLINKHZ was defined in file <PyBasic.h>, 
00460 */
00461 JINT HasNonLinkHz(JWORD* pwSlctHz, JINT nTotalSteps)
00462 {
00463        JINT    i;
00464        JINT    nRet;
00465        
00466        nRet = FALSE;
00467        for (i = 0; i < nTotalSteps; i++)
00468        {
00469               nRet = IsXrdNonLinkHz (i, pwSlctHz, nTotalSteps);
00470               if (nRet == TRUE)
00471                      break;
00472        }
00473        
00474        return nRet;
00475 }
00476 
00477 
00478 /*
00479 **  Determine if this Seletion is NONLINKHZ.
00480 **  If yes, return TRUE, else, return FALSE.
00481 **  NONLINKHZ was defined in file <PyBasic.h>
00482 */
00483 JINT IsXrdNonLinkHz(JINT nXrd, JWORD* pwSlctHz, JINT nTotalSteps)
00484 {
00485        JWORD    wTmp[10], wHz;
00486        JINT     nLen;
00487        JINT     nRet;
00488        JINT     i;
00489        
00490        nRet  = FALSE;
00491        memset (wTmp, '\0', 10 * sizeof(JWORD));
00492        nLen  = GetNSelect (nXrd, nTotalSteps, pwSlctHz, wTmp);
00493        if (nLen == 1)
00494        {
00495               for (i = 0; i < NUM_NONLINKHZ; i++)
00496               {
00497                      wHz = (JWORD)((NONLINKHZ[2 * i] << 8) + NONLINKHZ[2 * i + 1]);
00498                      if (wTmp[0] == wHz)
00499                      {
00500                             nRet = TRUE;
00501                             return nRet;
00502                      }
00503               }
00504        }
00505        
00506        return nRet;
00507 }
00508 
00509 /*
00510 **  Is this PRELINKHZ ? Same as IsXrdNonLinkHz
00511 */
00512 JINT IsXrdPreLinkHz(JINT nXrd, JWORD* pwSlctHz, JINT nTotalSteps)
00513 {
00514        JWORD    wTmp[10], wHz;
00515        JINT     nLen;
00516        JINT     nRet;
00517        JINT     i;
00518        
00519        nRet  = FALSE;
00520        memset (wTmp, '\0', 10 * sizeof(JWORD));
00521        nLen  = GetNSelect (nXrd, nTotalSteps, pwSlctHz, wTmp);
00522        if (nLen == 1)
00523        {
00524               for (i = 0; i < NUM_PRELINKHZ; i++)
00525               {
00526                      wHz = (JWORD)((PRELINKHZ[2 * i] << 8) + PRELINKHZ[2 * i + 1]);
00527                      if (wTmp[0] == wHz)
00528                      {
00529                             nRet = TRUE;
00530                             return nRet;
00531                      }
00532               }
00533        }
00534        
00535        return nRet;
00536 }
00537 
00538 
00539 /*
00540 **  Is this SUFLINKHZ ? Same as IsXrdNonLinkHz
00541 */
00542 JINT IsXrdSufLinkHz(JINT nXrd, JWORD* pwSlctHz, JINT nTotalSteps)
00543 {
00544        JWORD    wTmp[10], wHz;
00545        JINT     nLen;
00546        JINT     nRet;
00547        JINT     i;
00548        
00549        nRet  = FALSE;
00550        memset (wTmp, '\0', 10 * sizeof(JWORD));
00551        nLen  = GetNSelect (nXrd, nTotalSteps, pwSlctHz, wTmp);
00552        if (nLen == 1)
00553        {
00554               for (i = 0; i < NUM_SUFLINKHZ; i++)
00555               {
00556                      wHz = (JWORD)((SUFLINKHZ[2 * i] << 8) + SUFLINKHZ[2 * i + 1]);
00557                      if (wTmp[0] == wHz)
00558                      {
00559                             nRet = TRUE;
00560                             return nRet;
00561                      }
00562               }
00563        }
00564        
00565        return nRet;
00566 }
00567 
00568 
00569 /*
00570 **  Read out all those data in System Ciku file to pCkAll.
00571 */
00572 JINT ReadUdcData(CHAR* szUdcName)
00573 {
00574        FILE*   pfUdc;
00575        JINT    i, k, nTmp;
00576        JINT    nFileSize;
00577        JINT    nWarpFlag;     /* Flag to indicate whether it is necessary to */
00578        
00579        nWarpFlag = FALSE;
00580 
00581        pfUdc = fopen(szUdcName, "rb");
00582        if (pfUdc == NULL)
00583        {
00584               return FALSE;
00585        }
00586        
00587        fseek(pfUdc, 0, SEEK_SET);
00588        if ((JINT)fread (&(udcAll.udcfh), 1, sizeof(UdCikuHeader), pfUdc) != sizeof(UdCikuHeader) )
00589        {
00590               fclose(pfUdc);
00591               return FALSE;
00592        }
00593        
00594        /* Check Magic Word in Header */
00595        if ((udcAll.udcfh.nMagicDescHi != 0x35303539) || (udcAll.udcfh.nMagicDescLow != 0x34333442))
00596        {
00597               /* Is SPARC or x86 File? */
00598               if ((udcAll.udcfh.nMagicDescHi == 0x39353035) && (udcAll.udcfh.nMagicDescLow == 0x42343334))
00599               {
00600                      nWarpFlag = TRUE;
00601               }
00602               else
00603               {
00604                      fclose(pfUdc);
00605                      return FALSE;
00606               }
00607        }
00608 
00609        if (nWarpFlag == TRUE)
00610               WarpCikuHeader((CikuHeader *)&(udcAll.udcfh));
00611 
00612        nFileSize = udcAll.udcfh.nFileSize;
00613        
00614        fseek(pfUdc, 0, SEEK_END);
00615        if (nFileSize != ftell(pfUdc))
00616        {
00617               fclose(pfUdc);
00618               return FALSE;
00619        }
00620        
00621        /* Read in UdcIndex Data */
00622        nTmp = udcAll.udcfh.nIdxUdcPos;
00623        fseek(pfUdc, nTmp, SEEK_SET);
00624        if ((JINT)fread (&(udcAll.udci), 1, sizeof(UdcIndex), pfUdc) != sizeof(UdcIndex))
00625        {
00626               fclose(pfUdc);
00627               return FALSE;
00628        }
00629        
00630        if (nWarpFlag == TRUE)
00631               WarpIndex( (ShIndex *)(&(udcAll.udci)) );
00632 
00633        /* Alloc Memory for SpecHz, and fill these data to it */
00634        nTmp = udcAll.udcfh.nSizeSpecHz;   /* In BYTE */
00635        udcAll.pwUdcSh = (JWORD*)malloc(nTmp);
00636        if (udcAll.pwUdcSh == NULL)
00637        {
00638               fclose(pfUdc);
00639               return FALSE;
00640        }
00641        
00642        nTmp = (udcAll.udcfh.nSizeSpecHz) / sizeof(JWORD);   /* In JWORD */
00643        fseek(pfUdc, udcAll.udcfh.nSpecHzStartPos, SEEK_SET);
00644        if ((JINT)fread (udcAll.pwUdcSh, sizeof(JWORD), nTmp, pfUdc) != nTmp )
00645        {
00646               fclose(pfUdc);
00647               return FALSE;
00648        }
00649        
00650        /* Warp pwUdcSh if necessary */
00651        if (nWarpFlag == TRUE)
00652        {
00653               for (i = 0; i < nTmp; i++)
00654                      WarpByte ( (VOID*)((JWORD*)(udcAll.pwUdcSh) + i), 2);
00655        }
00656 
00657        /* Alloc Memory for pwUdc28[NUM_YINJIE], align each with UDCMEM_ALIGN BYTE (64 JWORD) */
00658        for (i = 0; i < NUM_YINJIE; i++)
00659        {
00660               /* Get the Actual Size to nTmp and upper align it to UDCMEM_ALIGN */
00661               nTmp = udcAll.udci.nYjOff[i + 1] - udcAll.udci.nYjOff[i];
00662               nTmp = ((nTmp + UDCMEM_ALIGN) / UDCMEM_ALIGN) * UDCMEM_ALIGN;
00663               udcAll.pwUdc28[i] = (JWORD*)malloc(nTmp);
00664        }
00665 
00666        /* Is there any failure in Memory Allocation? If no, Init it to 0x0000 */
00667        for (i = 0; i < NUM_YINJIE; i++)
00668        {
00669               if (udcAll.pwUdc28[i] == NULL)
00670               {
00671                      for(k = 0; k < NUM_YINJIE; k++)
00672                      {
00673                             free (udcAll.pwUdc28[i]);
00674                             udcAll.pwUdc28[i] = NULL;
00675                      }
00676                      fprintf(stderr, "Failed in Alloc Mem for pwUdc28. %d\n", i);
00677                      return FALSE;
00678               }
00679 
00680               nTmp = udcAll.udci.nYjOff[i + 1] - udcAll.udci.nYjOff[i];
00681               nTmp = ((nTmp + UDCMEM_ALIGN) / UDCMEM_ALIGN) * UDCMEM_ALIGN;
00682               for (k = 0; k < (nTmp / 2); k++)
00683                      udcAll.pwUdc28[i][k] = 0x0000;
00684        }
00685 
00686        /* Read in pwUdc28 data */
00687        nTmp = udcAll.udci.nStartPos;
00688        fseek(pfUdc, nTmp, SEEK_SET);
00689 
00690        for(i = 0; i < NUM_YINJIE; i++)
00691        {
00692               nTmp = (udcAll.udci.nYjOff[i + 1] - udcAll.udci.nYjOff[i]) / sizeof(JWORD);
00693               if ((JINT)fread (udcAll.pwUdc28[i], sizeof(JWORD), nTmp, pfUdc) != nTmp)
00694               {
00695                      fclose(pfUdc);
00696                      return FALSE;
00697               }
00698               
00699               if (nWarpFlag == TRUE)
00700               {
00701                      for (k = 0; k < nTmp; k++)
00702                             WarpByte ( (VOID*)((JWORD*)(udcAll.pwUdc28[i]) + k), 2);
00703               }
00704        }
00705        
00706        fclose(pfUdc);
00707        return TRUE;
00708 }
00709 
00710 
00711 JINT WriteUdcData(CHAR* szUdcName, JINT nTimeStamp)
00712 {
00713        FILE*   pfUdc;
00714        JINT    i, nTmp;
00715        JINT    nFileSize;
00716 
00717        udcAll.udcfh.nLatestTime  = nTimeStamp;
00718 
00719        nFileSize = sizeof(UdCikuHeader) + sizeof(UdcIndex) + 
00720                    udcAll.udcfh.nSizeSpecHz + udcAll.udci.nYjOff[NUM_YINJIE];
00721        udcAll.udcfh.nFileSize    = nFileSize;
00722        udcAll.udci.nStartPos     = sizeof(UdCikuHeader) + sizeof(UdcIndex) + udcAll.udcfh.nSizeSpecHz;
00723        udcAll.udci.nEndPos       = sizeof(UdCikuHeader) + sizeof(UdcIndex) + 
00724                    udcAll.udcfh.nSizeSpecHz + udcAll.udci.nYjOff[NUM_YINJIE];
00725 
00726        /* Write These data back to file */
00727        pfUdc = fopen(szUdcName, "wb");
00728        if (pfUdc == NULL)
00729        {
00730               fprintf(stderr, "Failed to Open UdCiku File to Write.\n");
00731               return FALSE;
00732        }
00733        
00734        if ((JINT)fwrite (&(udcAll.udcfh), 1, sizeof(UdCikuHeader), pfUdc) != sizeof(UdCikuHeader) )
00735        {
00736               fprintf(stderr, "Failed to fwrite() Ud Ciku File11.\n");
00737               return FALSE;
00738        }
00739 
00740        if ((JINT)fwrite (&(udcAll.udci),  1, sizeof(UdcIndex), pfUdc) != sizeof(UdcIndex) )
00741        {
00742               fprintf(stderr, "Failed to fwrite() Ud Ciku File22.\n");
00743               return FALSE;
00744        }
00745 
00746        nTmp = (udcAll.udcfh.nSizeSpecHz) / sizeof(JWORD);
00747        if ((JINT)fwrite (udcAll.pwUdcSh, sizeof(JWORD), nTmp, pfUdc) != nTmp )
00748        {
00749               fprintf(stderr, "Failed to fwrite() Ud Ciku File33.\n");
00750               return FALSE;
00751        }
00752        
00753        for(i = 0; i < NUM_YINJIE; i++)
00754        {
00755               nTmp = (udcAll.udci.nYjOff[i + 1] - udcAll.udci.nYjOff[i]) / sizeof(JWORD);
00756               if ((JINT)fwrite (udcAll.pwUdc28[i], sizeof(JWORD), nTmp, pfUdc) != nTmp )
00757               {
00758                      fprintf(stderr, "Failed to fwrite() Ud Ciku File44.\n");
00759                      return FALSE;
00760               }
00761        }
00762        
00763        fclose(pfUdc);
00764        return TRUE;
00765 }
00766 
00767 
00768 /*
00769 **  Free Memory which was allocated for udcAll.pwUdcSh and udcAll.pwUdc28[NUM_YINJIE].
00770 **  This function can only be called After QUIT this Input Method.
00771 */
00772 VOID FreeUdcData()
00773 {
00774        JINT    i;
00775 
00776        free (udcAll.pwUdcSh);
00777        udcAll.pwUdcSh = NULL;
00778 
00779        for (i = 0; i < NUM_YINJIE; i++)
00780        {
00781               free (udcAll.pwUdc28[i]);
00782               udcAll.pwUdc28[i] = NULL;
00783        }
00784 }
00785 
00786 
00787 /*
00788 **  Add an User Defined Cizu to structure udcAll.pwUdc28[i] AND
00789 **  realloc the related size of udcAll.udci.nYjOff[]
00790 **  nLen is in JWORD.
00791 */
00792 JINT AddUdc(JWORD* pwHz2244, JINT nLen)
00793 {
00794        JINT    i, nTmp1, nTmp2;
00795        JINT    nCurSize;
00796        JINT    nFreqLen, nTmpLen;
00797        JINT    nFirstYj;
00798 
00799        if (nLen <= 1)
00800               return FALSE;
00801 
00802        nFirstYj = GbkHz2244ToYj(pwHz2244[0]);
00803        if (nFirstYj == 0xFFFF)
00804        {
00805               fprintf(stderr, "Error in AddUdc.\n");
00806               return FALSE;
00807        }
00808 
00809        /* 
00810        **  STEP1: Is it necessary to realloc() for this Yinjie's space? 
00811        */
00812        nCurSize = udcAll.udci.nYjOff[nFirstYj + 1] - udcAll.udci.nYjOff[nFirstYj];    /* In BYTE */
00813        nTmp1    = ((nCurSize + UDCMEM_ALIGN) / UDCMEM_ALIGN) * UDCMEM_ALIGN;
00814        nTmp2    = ((nCurSize + ((nLen + 1) * sizeof(JWORD)) + UDCMEM_ALIGN) / UDCMEM_ALIGN) * UDCMEM_ALIGN;
00815        if (nTmp2 > nTmp1)
00816        {
00817               udcAll.pwUdc28[nFirstYj] = (JWORD*)realloc(udcAll.pwUdc28[nFirstYj], nTmp2);
00818               if (udcAll.pwUdc28[nFirstYj] == NULL)
00819               {
00820                      fprintf(stderr, "Failed to realloc() in AddUdc().\n");
00821                      return FALSE;
00822               }
00823               for(i = 0; i < (UDCMEM_ALIGN) / 2; i++)
00824                      udcAll.pwUdc28[nFirstYj][nTmp1 + i] = 0x0000;
00825        }
00826 
00827        /*
00828        ** STEP2:  Reduce the Frequence of other Udc for FUTURE FUNCTION: DiscardUdc().
00829        ** Notice: Cannot DiscardUdc() here, that will make the LOGIC confusion.
00830        */
00831        /* NO i++ in this FOR sentence */
00832        for (i = 0; i < nCurSize / 2; )
00833        {
00834               nFreqLen = (JINT)udcAll.pwUdc28[nFirstYj][i];
00835               nTmpLen  = (nFreqLen & 0x0007) + 2;
00836               if (nFreqLen >= 0x0010)
00837                      udcAll.pwUdc28[nFirstYj][i] -= 8;
00838               i += (nTmpLen + 1);
00839        }
00840 
00841        /*
00842        ** STEP3:  Append this pwHz2244 just after pwUdc28[nFirstYj][nCurSize / 2]
00843        ** Set the Frequence of this pwHz2244 to the Highest: 11111xxx.
00844        ** xxx from 000 to 111, indicates length from 2 to 9
00845        */
00846        nFreqLen = 0x00F8 + (nLen - 2);
00847        udcAll.pwUdc28[nFirstYj][nCurSize / 2] = (JWORD)nFreqLen;
00848        for (i = 0; i < nLen; i++)
00849               udcAll.pwUdc28[nFirstYj][(nCurSize / 2) + 1 + i] = pwHz2244[i];
00850 
00851        /*
00852        ** STEP4:  Adjust udcAll.udci.nYjOff[nFirstYj + 1] to nYjOff[NUM_YINJIE]
00853        */
00854        for (i = nFirstYj; i < NUM_YINJIE; i++)
00855               udcAll.udci.nYjOff[i + 1] += 2 * (nLen + 1);
00856 
00857        return TRUE;
00858 }
00859 
00860 
00861 /*
00862 **  Del an User Defined Cizu to structure udcAll.pwUdc28[i] AND
00863 **  realloc the related size of udcAll.udci.nYjOff[]
00864 **  If cannot find this Udc, just return FALSE.
00865 */
00866 JINT DelUdc(JWORD* pwHz2244, JINT nLen)
00867 {
00868        JINT    i, k, nTmp1, nTmp2;
00869        JINT    nCurSize;
00870        JINT    nFreqLen, nTmpLen;
00871        JINT    nFirstYj;
00872        JINT    nFindFlag;
00873 
00874        if (nLen <= 1)
00875        {
00876 #ifdef _DRAW_IM_WIN_H
00877               XBell (pDspIme, 100);
00878 #endif
00879               return FALSE;
00880        }
00881 
00882        nFirstYj = GbkHz2244ToYj(pwHz2244[0]);
00883        if (nFirstYj == 0xFFFF)
00884        {
00885               fprintf(stderr, "Error in DelUdc.\n");
00886               return FALSE;
00887        }
00888 
00889        /*
00890        **  STEP1: Find this pwHz2244, Forward other Udcdata to (nLen + 1) JWORD.
00891        */
00892        nFindFlag = FALSE;
00893        nCurSize  = udcAll.udci.nYjOff[nFirstYj + 1] - udcAll.udci.nYjOff[nFirstYj];    /* In BYTE */
00894 
00895        /* NO i++ in this FOR sentence */
00896        for (i = 0; i < nCurSize / 2; )
00897        {
00898               nFreqLen = (JINT)udcAll.pwUdc28[nFirstYj][i];
00899               nTmpLen  = (nFreqLen & 0x0007) + 2;
00900               /* DON'T exchange the sequence of two judgement in the following IF sentence */
00901               if ((nTmpLen == nLen) && (JwordNCmp(pwHz2244, &(udcAll.pwUdc28[nFirstYj][i + 1]), nTmpLen) == 0))
00902               {
00903                      nFindFlag = TRUE;
00904                      for (k = i; k < (nCurSize / 2) - (nTmpLen + 1); k++)
00905                             udcAll.pwUdc28[nFirstYj][k] = udcAll.pwUdc28[nFirstYj][k + nTmpLen + 1];
00906                      for (k = (nCurSize / 2) - (nTmpLen + 1); k < nCurSize / 2; k++)
00907                             udcAll.pwUdc28[nFirstYj][k] = 0x0000;
00908 
00909                      break;        /* BREAK OUT FOR_i sentence */
00910               }
00911               i += (nTmpLen + 1);
00912        }
00913 
00914        if (nFindFlag == FALSE)
00915        {
00916 #ifdef _DRAW_IM_WIN_H
00917               XBell (pDspIme, 100);
00918 #endif
00919               return FALSE;
00920        }
00921 
00922        /* 
00923        **  STEP2: Is it necessary to realloc() for this Yinjie's space? 
00924        */
00925        nTmp1     = ((nCurSize + UDCMEM_ALIGN) / UDCMEM_ALIGN) * UDCMEM_ALIGN;
00926        nTmp2     = ((nCurSize - ((nLen + 1) * sizeof(JWORD)) + UDCMEM_ALIGN) / UDCMEM_ALIGN) * UDCMEM_ALIGN;
00927        if (nTmp2 < nTmp1)
00928        {
00929               udcAll.pwUdc28[nFirstYj] = (JWORD*)realloc(udcAll.pwUdc28[nFirstYj], nTmp2);
00930               if (udcAll.pwUdc28[nFirstYj] == NULL)
00931               {
00932                      fprintf(stderr, "Failed to realloc() in DelUdc().\n");
00933                      return FALSE;
00934               }
00935        }
00936 
00937        /*
00938        ** STEP3:  Adjust udcAll.udci.nYjOff[nFirstYj + 1] to nYjOff[NUM_YINJIE]
00939        */
00940        for (i = nFirstYj; i < NUM_YINJIE; i++)
00941               udcAll.udci.nYjOff[i + 1] -= 2 * (nLen + 1);
00942 
00943        return TRUE;
00944 }
00945 
00946 
00947 /*
00948 **  Pure (Discard or Clean) these rarely used Udc in UdCiku. 
00949 **  BEST WAY to use:
00950 **           CALL this function just before the SAVING UDC operation!!!
00951 */
00952 JINT PureUdc(VOID)
00953 {
00954        JINT    i, k, nYj, nTmp1, nTmp2;
00955        JINT    nCurSize;
00956        JINT    nTmpFreq, nTmpLen;
00957        JINT    nPuredSize;
00958 
00959        JINT    nPureNum;
00960        nPureNum = 0;
00961 
00962        for (nYj = 0; nYj < NUM_YINJIE; nYj++)
00963        {
00964               nCurSize   = udcAll.udci.nYjOff[nYj + 1] - udcAll.udci.nYjOff[nYj];      /* In BYTE */
00965               nTmp1      = ((nCurSize + UDCMEM_ALIGN) / UDCMEM_ALIGN) * UDCMEM_ALIGN;  /* Old Buf Size */
00966               
00967               nPuredSize = 0;
00968               /* NO i++ in this FOR sentence */
00969               for (i = 0; i < nCurSize / 2; )
00970               {
00971                      nTmpFreq = (JUINT)udcAll.pwUdc28[nYj][i] & 0x00F8;
00972                      nTmpLen  = (udcAll.pwUdc28[nYj][i] & 0x0007) + 2;
00973 
00974                      if (nTmpFreq == 0x0008)     /* Lowest Frequence */
00975                      {
00976                             for (k = i; k < (nCurSize / 2) - (nTmpLen + 1); k++)
00977                                    udcAll.pwUdc28[nYj][k] = udcAll.pwUdc28[nYj][k + nTmpLen + 1];
00978                             for (k = (nCurSize / 2) - (nTmpLen + 1); k < nCurSize / 2; k++)
00979                                    udcAll.pwUdc28[nYj][k] = 0x0000;
00980 
00981                             nPureNum   += 1;
00982                             nCurSize   -= 2 * (nTmpLen + 1);
00983                             nPuredSize += 2 * (nTmpLen + 1);
00984                      }
00985                      else    /* If an Udcizu is already deleted, DON'T CHANGE i HERE!! MXL */
00986                             i += (nTmpLen + 1);
00987               }
00988 
00989               /* Adjust udcAll.udci.nYjOff[nFirstYj + 1] to nYjOff[NUM_YINJIE] */
00990               for (k = nYj; k < NUM_YINJIE; k++)
00991                      udcAll.udci.nYjOff[k + 1] -= nPuredSize;
00992 
00993               /* Is it necessary to resize the buffer allocated for udcAll.pwUdc28[nYj] ? */
00994               nTmp2     = ((nCurSize + UDCMEM_ALIGN) / UDCMEM_ALIGN) * UDCMEM_ALIGN;  /* New Buf Size */
00995               if (nTmp2 < nTmp1)
00996               {
00997                      udcAll.pwUdc28[nYj] = (JWORD*)realloc(udcAll.pwUdc28[nYj], nTmp2);
00998                      if (udcAll.pwUdc28[nYj] == NULL)
00999                      {
01000                             fprintf(stderr, "Failed to realloc() in PureUdc().\n");
01001                             return FALSE;
01002                      }
01003               }
01004        }
01005 
01006 #ifdef _DEBUG
01007        fprintf (stderr, "PureNum is %d\n", nPureNum);
01008 #endif
01009 
01010        return TRUE;
01011 }
01012 
01013 /*
01014 **  Init Structure UdcCandi. UdcCandi is an element of struct SesElement.
01015 **  This function is called in InitSge().
01016 */
01017 VOID InitStructUc(UdcCandi* puc)
01018 {
01019        JINT    i;
01020 
01021        puc->nNumSpecCandi   = 0;
01022        puc->nNumUdc28Candi  = 0;
01023        puc->nSizUdc28Candi  = 0;
01024 
01025        for (i = 0; i < 6; i++)
01026               puc->pwSpecCandi[i] = 0x0000;
01027 
01028        free (puc->pwUdc28Candi);
01029        puc->pwUdc28Candi    = NULL;
01030 }
01031