Back to index

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