Back to index

im-sdk  12.3.91
PyBasic.c
Go to the documentation of this file.
00001 #include  <stdio.h>
00002 #include  <string.h>
00003 #include  <stdlib.h>
00004 #include  "GeneType.h"
00005 #include  "PyBasic.h"
00006 
00007 JINT   GbkHzcodeToYjcode(JINT nHzcode);
00008 JINT   HzcodeToYjcode(JINT nHzcode);
00009 JINT   Hzcode2244ToYjcode(JINT nHzcode);
00010 JINT   Hzcode2244ToYjSMcode(JINT nHzcode);
00011 JINT   GetDyzInfo(JINT nHzcode, JINT* pnDyzYjCode);
00012 JINT   EncodeDyzTo2244(JINT nHzcode, JINT nYjcode);
00013 JINT   FastMatchYinJieStr(CHAR* szPystr);
00014 UCHAR* RecovDyz2244(UCHAR *szDyz2244);
00015 
00016 CHAR   LastChar (JINT nYinjieCode);
00017 CHAR   FirstChar(JINT nYinjieCode);
00018 JINT   ValidButLastChar (JINT nYinjieCode);
00019 JINT   ValidButFirstChar(JINT nYinjieCode);
00020 JINT   ValidAddChar(CHAR ch, JINT nYinjieCode);
00021 
00022 /*
00023 **  nHzcode range: [0xB0A1 ~ 0xF7FE] || [0x2001 ~ 0x2244]
00024 **               [0x2001 ~ 0x2244] contains 580 DuoYinZi.
00025 **  Lookup table GBHZCODETOYJ[] and DYZCODETOYJ[] to return
00026 **  a integer Yinjie code 0~414.
00027 */
00028 JINT HzcodeToYjcode(JINT nHzcode)
00029 {
00030        JINT   hi, low;
00031        JINT   res;
00032        JINT   t1, t2, t3, t4;
00033 
00034        hi  = (nHzcode >> 8) & 0x00FF;
00035        low = nHzcode & 0x00FF;
00036        t1  = t2 = t3 = t4 = 0;
00037 
00038        res = 0xFFFF;
00039 
00040        if ((hi == 0xD7) && (low >= 0xFA) && (low <= 0xFE))
00041               res = 0xFFFF;
00042        else if ((hi >= 0xB0) && (hi <= 0xF7) && (low >= 0xA1) && (low <= 0xFE))
00043        {
00044               t1 = (hi - 0xB0) * 94 + (low - 0xA1) + 1;
00045               t2 = (t1 * 9 - 1) / 32;
00046               t3 = ((t1 - 1) * 9 - 1) / 32;
00047               t4 = (t1 * 9) % 32;
00048 
00049               if (t2 > t3)
00050                      res = (JINT)( (GBHZCODETOYJ[t2] >> (32 - t4)) & 0x01FF ) +
00051                            (JINT)( (GBHZCODETOYJ[t3] << t4) & 0x01FF );
00052               else if (t2 == t3)
00053                      res = (JINT)( GBHZCODETOYJ[t2] >> (32 - t4) ) & 0x01FF;
00054        }
00055        else if ((nHzcode >= 0x2001) && (nHzcode <= 0x2244))
00056        {
00057               t1 = nHzcode - 0x2000;
00058               t2 = (t1 * 9 - 1) / 32;
00059               t3 = ((t1 - 1) * 9 - 1) / 32;
00060               t4 = (t1 * 9) % 32;
00061 
00062               if (t2 > t3)
00063                      res = (JINT)( (DYZCODETOYJ[t2] >> (32 - t4)) & 0x01FF ) +
00064                            (JINT)( (DYZCODETOYJ[t3] << t4) & 0x01FF );
00065               else if (t2 == t3)
00066                      res = (JINT)( DYZCODETOYJ[t2] >> (32 - t4) ) & 0x01FF;
00067        }
00068        else
00069               res = 0xFFFF;
00070 
00071        return (res);
00072 }
00073 
00074 
00075 /*
00076 **  nHzcode range: [0x8140 ~ 0xA0FE] || [0xAA40 ~ 0xFEFE] || [0x2001 ~ 0x2244]
00077 **               [0x2001 ~ 0x2244] contains 580 DuoYinZi.
00078 **  Lookup table GBHZCODETOYJ[] and DYZCODETOYJ[] to return
00079 **  a integer Yinjie code 0~414.
00080 */
00081 JINT GbkHzcodeToYjcode(JINT nHzcode)
00082 {
00083        JINT   hi, low;
00084        JINT   res;
00085        JINT   t1, t2, t3, t4;
00086 
00087        hi  = (nHzcode >> 8) & 0x00FF;
00088        low = nHzcode & 0x00FF;
00089        t1  = t2 = t3 = t4 = 0;
00090 
00091        res = 0xFFFF;
00092        if ((hi >= 0x81) && (hi <= 0xA0) && (low >= 0x40) && (low <= 0xFE))
00093        {
00094               t1 = (hi - 0x81) * 191 + (low - 0x40) + 1;
00095               t2 = (t1 * 9 - 1) / 32;
00096               t3 = ((t1 - 1) * 9 - 1) / 32;
00097               t4 = (t1 * 9) % 32;
00098 
00099               if (t2 > t3)
00100                      res = (JINT)( (GBKHZCODETOYJ[t2] >> (32 - t4)) & 0x01FF ) +
00101                            (JINT)( (GBKHZCODETOYJ[t3] << t4) & 0x01FF );
00102               else if (t2 == t3)
00103                      res = (JINT)( GBKHZCODETOYJ[t2] >> (32 - t4) ) & 0x01FF;
00104        }
00105        else if ((hi >= 0xAA) && (hi <= 0xFE) && (low >= 0x40) && (low <= 0xFE))
00106        {
00107               t1 = (hi - 0xAA) * 191 + (low - 0x40) + 1;
00108               t2 = (t1 * 9 - 1) / 32;
00109               t3 = ((t1 - 1) * 9 - 1) / 32;
00110               t4 = (t1 * 9) % 32;
00111 
00112               if (t2 > t3)
00113                      res = (JINT)( (GBKHZCODETOYJ[t2 + (9 * 191)] >> (32 - t4)) & 0x01FF ) +
00114                            (JINT)( (GBKHZCODETOYJ[t3 + (9 * 191)] << t4) & 0x01FF );
00115               else if (t2 == t3)
00116                      res = (JINT)( GBKHZCODETOYJ[t2 + (9 * 191)] >> (32 - t4) ) & 0x01FF;
00117        }
00118        else if ((nHzcode >= 0x2001) && (nHzcode <= 0x2244))
00119        {
00120               t1 = nHzcode - 0x2000;
00121               t2 = (t1 * 9 - 1) / 32;
00122               t3 = ((t1 - 1) * 9 - 1) / 32;
00123               t4 = (t1 * 9) % 32;
00124 
00125               if (t2 > t3)
00126                      res = (JINT)( (DYZCODETOYJ[t2] >> (32 - t4)) & 0x01FF ) +
00127                            (JINT)( (DYZCODETOYJ[t3] << t4) & 0x01FF );
00128               else if (t2 == t3)
00129                      res = (JINT)( DYZCODETOYJ[t2] >> (32 - t4) ) & 0x01FF;
00130        }
00131        else
00132               res = 0xFFFF;
00133 
00134        if (res == 0x01FF)
00135               res = 0xFFFF;
00136 
00137        return (res);
00138 }
00139 
00140 
00141 /*
00142 **  Lookup the DYZLIST[580] to see if this nHzcode is a DuoYinZi.
00143 **  index of DYZLIST by High Byte is placed in INDEXOFDYZLIST
00144 **  return: JINT        number of DuoYin, for example: 1, 2, 3  else, 0
00145 **         pnDyzYjCode         yinjiecode include yinjie code
00146 */
00147 JINT GetDyzInfo(JINT nHzcode, JINT* pnDyzYjCode)
00148 {
00149        JINT   nHiHzPos, nLowHz;
00150        JINT   i, j;
00151 
00152        nHiHzPos = ((nHzcode & 0xFF00) >> 8) - 0xB0;
00153        nLowHz = nHzcode & 0x00FF;
00154 
00155        j = 0;
00156        for (i = INDEXOFDYZLIST[nHiHzPos]; i < INDEXOFDYZLIST[nHiHzPos + 1]; i++)
00157        {
00158               if( (DYZLIST[i] & 0x00FF) == nLowHz )
00159               {
00160                      pnDyzYjCode[j] = DYZYJCODE[i];
00161                      j++;
00162               }
00163        }
00164 
00165        return (j);
00166 }
00167 
00168 
00169 /*
00170 **  nHzcode is Normal Hanzi Code defined in GB or GBK.
00171 **  If nHzcode indicates a DYZ, return 0x2001 ~ (TOTAL_DYZYINJIE - 1 + 0x2001) [0x2001 + 0x2244]
00172 **  Else, return 0xFFFF.
00173 */
00174 JINT EncodeDyzTo2244(JINT nHzcode, JINT nYjcode)
00175 {
00176        JINT   nHiHzPos, nLowHz;
00177        JINT   i;
00178 
00179        nHiHzPos = ((nHzcode & 0xFF00) >> 8) - 0xB0;
00180        if (nHiHzPos < 0)
00181               return (0xFFFF);
00182        nLowHz = nHzcode & 0x00FF;
00183 
00184        for (i = INDEXOFDYZLIST[nHiHzPos]; i < INDEXOFDYZLIST[nHiHzPos + 1]; i++)
00185        {
00186               if ( ((DYZLIST[i] & 0x00FF) == nLowHz) && (DYZYJCODE[i] == nYjcode) )
00187                      return (i + 0x2001);
00188        }
00189 
00190        return (0xFFFF);
00191 }
00192 
00193 
00194 /*
00195 **  Lookup the equal string of szPystr in YINJIESTR_CSZ[415].
00196 **  If successfully, return 0~414; otherwise, return -1.
00197 **  If chFirst is 'i' 'u' or 'v', return -1 directly.
00198 */
00199 JINT FastMatchYinJieStr(CHAR* szPystr)
00200 {
00201        JINT   i, j, nLen;
00202        CHAR   chFirst;
00203        JINT   nFromYJStr, nToYJStr, nShengmuIndex;
00204 
00205        i = 0;
00206        nLen = (JINT)strlen(szPystr);
00207 
00208        j = 0;
00209        if (nLen > 0)
00210        {
00211               chFirst = szPystr[0];
00212 
00213               if ((chFirst == 'i') || (chFirst == 'u') || (chFirst == 'v'))
00214                      return (-1);
00215 
00216               nFromYJStr = INDEXSMTOYINJIE[ INDEXMAGIC[(JINT)(chFirst - 'a')] ];
00217               nToYJStr = INDEXSMTOYINJIE[ INDEXMAGIC[(JINT)(chFirst - 'a')] + 1];
00218               nShengmuIndex = INDEXMAGIC[(JINT)(chFirst - 'a')];
00219 
00220               if ((chFirst == 'c') && (nLen > 1) && (szPystr[1] == 'h'))
00221               {
00222                      nFromYJStr = INDEXSMTOYINJIE[3];
00223                      nToYJStr = INDEXSMTOYINJIE[4];
00224                      nShengmuIndex = 3;
00225               }
00226               else if ((chFirst == 's') && (nLen > 1) && (szPystr[1] == 'h'))
00227               {
00228                      nFromYJStr = INDEXSMTOYINJIE[19];
00229                      nToYJStr = INDEXSMTOYINJIE[20];
00230                      nShengmuIndex = 19;
00231               }
00232               else if ((chFirst == 'z') && (nLen > 1) && (szPystr[1] == 'h'))
00233               {
00234                      nFromYJStr = INDEXSMTOYINJIE[25];
00235                      nToYJStr = INDEXSMTOYINJIE[26];
00236                      nShengmuIndex = 25;
00237               }
00238 
00239               i = nFromYJStr;
00240               do {
00241                      j = strcmp (YINJIESTR_CSZ[i], szPystr);
00242                      i++;
00243               } while ((i < nToYJStr) && (j != 0));
00244        }
00245 
00246        if (j == 0)
00247               return (i - 1);
00248        else
00249               return (-1);
00250 }
00251 
00252 
00253 /*
00254 **  nYinjieCode Valid from 0 to 414. Return the last
00255 **  character of this YinJie String.
00256 */
00257 CHAR LastChar(JINT nYinjieCode)
00258 {
00259        CHAR   res = ' ';           /* SPACE */
00260        JINT   i = 0;
00261 
00262        if ((nYinjieCode >= 0) && (nYinjieCode <= 414))
00263        {
00264               while (YINJIESTR_CSZ[nYinjieCode][i] != '\0')
00265                      i++;
00266               res = YINJIESTR_CSZ[nYinjieCode][i-1];
00267        }
00268        return res;
00269 }
00270 
00271 /*
00272 **  nYinjieCode Valid from 0 to 414
00273 */
00274 CHAR FirstChar(JINT nYinjieCode)
00275 {
00276        CHAR   res = ' ';           /* SPACE */
00277 
00278        if ((nYinjieCode >= 0) && (nYinjieCode <= 414))
00279               res = YINJIESTR_CSZ[nYinjieCode][0];
00280        return res;
00281 }
00282 
00283 /*
00284 **  Valid but the end CHARacter?
00285 **  return 0~414 if valid, else return 0xFFFF
00286 */
00287 JINT ValidButLastChar(JINT nYinjieCode)
00288 {
00289        JINT   i, nTmpRes;
00290        CHAR   szStr[7];
00291 
00292        for (i = 0; i < 7; i++)
00293               szStr[i] = '\0';
00294 
00295        if ((nYinjieCode >= 0) && (nYinjieCode <= 414))
00296        {
00297               i = 0;
00298               while (YINJIESTR_CSZ[nYinjieCode][i+1])
00299               {
00300                      szStr[i] = YINJIESTR_CSZ[nYinjieCode][i];
00301                      i++;
00302               }
00303 
00304               nTmpRes = FastMatchYinJieStr(szStr);
00305               if(nTmpRes != -1)
00306                      return nTmpRes;
00307        }
00308        return 0xFFFF;
00309 }
00310 
00311 
00312 /*
00313 ** Valid add a new CHARacter before it?
00314 ** return 0~414 if valid, else return 0xFFFF
00315 */
00316 JINT ValidAddChar(CHAR ch, JINT nYinjieCode)
00317 {
00318        JINT   i, nTmpRes;
00319        CHAR   szStr[7];
00320 
00321        for (i = 0; i < 7; i++)
00322               szStr[i] = '\0';
00323 
00324        szStr[0] = ch;
00325        if ((nYinjieCode >= 0) && (nYinjieCode <= 414))
00326        {
00327               i = 0;
00328               while (YINJIESTR_CSZ[nYinjieCode][i])
00329               {
00330                      szStr[i + 1] = YINJIESTR_CSZ[nYinjieCode][i];
00331                      i++;
00332               }
00333 
00334               nTmpRes = FastMatchYinJieStr(szStr);
00335               if(nTmpRes != -1)
00336                      return nTmpRes;
00337        }
00338 
00339        return 0xFFFF;
00340 }
00341 
00342 
00343 /*
00344 **  Valid but first CHARacter ?
00345 **  return 0~414 if valid, else return 0xFFFF
00346 */
00347 JINT ValidButFirstChar(JINT nYinjieCode)
00348 {
00349        JINT   i, nTmpRes;
00350        CHAR   szStr[7];
00351 
00352        for (i = 0; i < 7; i++)
00353               szStr[i] = '\0';
00354 
00355        if ((nYinjieCode >= 0) && (nYinjieCode <= 414))
00356        {
00357               i = 0;
00358               while (YINJIESTR_CSZ[nYinjieCode][i+1])
00359               {
00360                      szStr[i] = YINJIESTR_CSZ[nYinjieCode][i+1];
00361                      i++;
00362               }
00363 
00364               nTmpRes = FastMatchYinJieStr(szStr);
00365               if(nTmpRes != -1)
00366                      return nTmpRes;
00367        }
00368 
00369        return 0xFFFF;
00370 }
00371 
00372 
00373 /*
00374 **  Recover these Hanzi String which encode by GB&Dyz2244 to normal GB
00375 **  Length of returned string is determined by the length of szDyz2244
00376 **
00377 **  This function must be rewritten to process failure of malloc()!!!
00378 */
00379 UCHAR* RecovDyz2244(UCHAR *szDyz2244)
00380 {
00381        JINT   i, j, nLen, nHlfLen;
00382        JINT   nDyzCode, nNormCode;
00383        static UCHAR* szNorm;                     /* Used by function RecovDyz2244() */
00384 
00385        nLen = strlen((CHAR*)szDyz2244);
00386        nHlfLen = nLen / 2;
00387 
00388        if(szNorm != NULL)
00389               free(szNorm);
00390 
00391        szNorm = (UCHAR*)malloc(nLen + 2);
00392        if (szNorm == NULL)
00393        {
00394               fprintf(stderr, "Failed to alloc Memory in function ReconDyz2244\n");
00395               return szDyz2244;
00396        }
00397 
00398        for (i = 0; i < (nLen + 2); i++)
00399               szNorm[i] = '\0';
00400 
00401        j = 0;
00402        for (i = 0; i < nHlfLen; i++)
00403        {
00404               nDyzCode = szDyz2244[(2 * i) + 1] + ((JINT)szDyz2244[2 * i] << 8);
00405               if ((nDyzCode >= 0x2001) && (nDyzCode <= 0x2244))
00406               {
00407                      nNormCode       = DYZLIST[nDyzCode - 0x2001];
00408                      szNorm[2 * i]   = (UCHAR)((nNormCode & 0xFF00) >> 8);
00409                      szNorm[2 * i + 1] = (UCHAR)(nNormCode & 0x00FF);
00410               }
00411               else
00412               {
00413                      szNorm[2 * i]    = szDyz2244[2 * i];
00414                      szNorm[2 * i + 1]  = szDyz2244[2 * i + 1];
00415               }
00416        }
00417 
00418        return (szNorm);
00419 }
00420 
00421 
00422 /*
00423 **  nHzcode range: [0xB0A1 ~ 0xF7FE] || [0x2001 ~ 0x2244]
00424 **  [0x2001 ~ 0x2244] contains 580 DuoYinZi.
00425 **  Lookup table GBHZCODETOYJ[] and DYZCODETOYJ[] to return
00426 **  a integer Yinjie code 0~414.
00427 */
00428 JINT Hzcode2244ToYjcode(JINT nHzcode)
00429 {
00430        JINT   hi, low;
00431        JINT   res;
00432        JINT   t1, t2, t3, t4;
00433 
00434        hi = (nHzcode >> 8) & 0x00FF;
00435        low = nHzcode & 0x00FF;
00436        t1 = t2 = t3 = t4 = 0;
00437        res = 0xFFFF;
00438 
00439        if ((hi >= 0xB0) && (hi <= 0xF7) && (low >= 0xA1) && (low <= 0xFE))
00440        {
00441               t1 = (hi - 0xB0) * 94 + (low - 0xA1) + 1;
00442               t2 = (t1 * 9 - 1) / 32;
00443               t3 = ((t1 - 1) * 9 - 1) / 32;
00444               t4 = (t1 * 9) % 32;
00445 
00446               if (t2 > t3)
00447                      res = (int)( (GBHZCODETOYJ[t2] >> (32 - t4)) & 0x01FF ) +
00448                            (int)( (GBHZCODETOYJ[t3] << t4) & 0x01FF );
00449               else if (t2 == t3)
00450                      res = (int)( GBHZCODETOYJ[t2] >> (32 - t4) ) & 0x01FF;
00451        }
00452        else if ((nHzcode >= 0x2001) && (nHzcode <= 0x2244))
00453        {
00454               t1 = nHzcode - 0x2000;
00455               t2 = (t1 * 9 - 1) / 32;
00456               t3 = ((t1 - 1) * 9 - 1) / 32;
00457               t4 = (t1 * 9) % 32;
00458 
00459               if (t2 > t3)
00460                      res = (int)( (DYZCODETOYJ[t2] >> (32 - t4)) & 0x01FF ) +
00461                            (int)( (DYZCODETOYJ[t3] << t4) & 0x01FF );
00462               else if (t2 == t3)
00463                      res = (int)( DYZCODETOYJ[t2] >> (32 - t4) ) & 0x01FF;
00464        }
00465        else
00466               res = 0xFFFF;
00467 
00468        return (res);
00469 }
00470 
00471 
00472 /*
00473 **  nHzcode range: [0xB0A1 ~ 0xF7FE] || [0x2001 ~ 0x2244]
00474 **  [0x2001 ~ 0x2244] contains 580 DuoYinZi.
00475 **
00476 **  Return ShengMu YinjieCode(450~475) of this Hanzi. If unNormal, return 0xFFFF
00477 */
00478 JINT Hzcode2244ToYjSMcode(JINT nHzcode)
00479 {
00480        JINT   nTmpRes;
00481        JINT   nRet;
00482 
00483        nTmpRes = Hzcode2244ToYjcode(nHzcode);
00484 
00485        if (nTmpRes != 0xFFFF)
00486        {
00487               if ((nTmpRes >= 38) && (nTmpRes < 57 ))          /* "ch" */
00488                      nRet = 3 + 450;
00489               else if ((nTmpRes >= 301) && (nTmpRes < 320))    /* "sh" */
00490                      nRet = 19 + 450;
00491               else if ((nTmpRes >= 395) && (nTmpRes < 415))    /* "zh" */
00492                      nRet = 25 + 450;
00493               else
00494                      nRet = INDEXMAGIC[(JINT)(YINJIESTR_CSZ[nTmpRes][0] - 'a')] + 450;
00495 
00496               return nRet;
00497        }
00498 
00499        return 0xFFFF;
00500 }
00501