iso2022_cnext.h
Upload User: yingmei828
Upload Date: 2007-01-01
Package Size: 1646k
Code Size: 12k
Development Platform:

Unix_Linux

  1. /*
  2.  * ISO-2022-CN-EXT
  3.  */
  4. /* Specification: RFC 1922 */
  5. #define ESC 0x1b
  6. #define SO  0x0e
  7. #define SI  0x0f
  8. /*
  9.  * The state is composed of one of the following values
  10.  */
  11. #define STATE_ASCII          0
  12. #define STATE_TWOBYTE        1
  13. /*
  14.  * and one of the following values, << 8
  15.  */
  16. #define STATE2_NONE                   0
  17. #define STATE2_DESIGNATED_GB2312      1
  18. #define STATE2_DESIGNATED_CNS11643_1  2
  19. #define STATE2_DESIGNATED_ISO_IR_165  3
  20. /*
  21.  * and one of the following values, << 16
  22.  */
  23. #define STATE3_NONE                   0
  24. #define STATE3_DESIGNATED_CNS11643_2  1
  25. /*
  26.  * and one of the following values, << 24
  27.  */
  28. #define STATE4_NONE                   0
  29. #define STATE4_DESIGNATED_CNS11643_3  1
  30. #define STATE4_DESIGNATED_CNS11643_4  2
  31. #define STATE4_DESIGNATED_CNS11643_5  3
  32. #define STATE4_DESIGNATED_CNS11643_6  4
  33. #define STATE4_DESIGNATED_CNS11643_7  5
  34. #define SPLIT_STATE 
  35.   unsigned int state1 = state & 0xff, state2 = (state >> 8) & 0xff, state3 = (state >> 16) & 0xff, state4 = state >> 24
  36. #define COMBINE_STATE 
  37.   state = (state4 << 24) | (state3 << 16) | (state2 << 8) | state1
  38. static int
  39. iso2022_cn_ext_mbtowc (conv_t conv, wchar_t *pwc, const unsigned char *s, int n)
  40. {
  41.   state_t state = conv->istate;
  42.   SPLIT_STATE;
  43.   int count = 0;
  44.   unsigned char c;
  45.   for (;;) {
  46.     c = *s;
  47.     if (c == ESC) {
  48.       if (n < count+4)
  49.         goto none;
  50.       if (s[1] == '$') {
  51.         if (s[2] == ')') {
  52.           if (s[3] == 'A') {
  53.             state2 = STATE2_DESIGNATED_GB2312;
  54.             s += 4; count += 4;
  55.             if (n < count+1)
  56.               goto none;
  57.             continue;
  58.           }
  59.           if (s[3] == 'G') {
  60.             state2 = STATE2_DESIGNATED_CNS11643_1;
  61.             s += 4; count += 4;
  62.             if (n < count+1)
  63.               goto none;
  64.             continue;
  65.           }
  66.           if (s[3] == 'E') {
  67.             state2 = STATE2_DESIGNATED_ISO_IR_165;
  68.             s += 4; count += 4;
  69.             if (n < count+1)
  70.               goto none;
  71.             continue;
  72.           }
  73.         }
  74.         if (s[2] == '*') {
  75.           if (s[3] == 'H') {
  76.             state3 = STATE3_DESIGNATED_CNS11643_2;
  77.             s += 4; count += 4;
  78.             if (n < count+1)
  79.               goto none;
  80.             continue;
  81.           }
  82.         }
  83.         if (s[2] == '+') {
  84.           if (s[3] == 'I') {
  85.             state4 = STATE4_DESIGNATED_CNS11643_3;
  86.             s += 4; count += 4;
  87.             if (n < count+1)
  88.               goto none;
  89.             continue;
  90.           }
  91.           if (s[3] == 'J') {
  92.             state4 = STATE4_DESIGNATED_CNS11643_4;
  93.             s += 4; count += 4;
  94.             if (n < count+1)
  95.               goto none;
  96.             continue;
  97.           }
  98.           if (s[3] == 'K') {
  99.             state4 = STATE4_DESIGNATED_CNS11643_5;
  100.             s += 4; count += 4;
  101.             if (n < count+1)
  102.               goto none;
  103.             continue;
  104.           }
  105.           if (s[3] == 'L') {
  106.             state4 = STATE4_DESIGNATED_CNS11643_6;
  107.             s += 4; count += 4;
  108.             if (n < count+1)
  109.               goto none;
  110.             continue;
  111.           }
  112.           if (s[3] == 'M') {
  113.             state4 = STATE4_DESIGNATED_CNS11643_7;
  114.             s += 4; count += 4;
  115.             if (n < count+1)
  116.               goto none;
  117.             continue;
  118.           }
  119.         }
  120.       }
  121.       if (s[1] == 'N') {
  122.         switch (state3) {
  123.           case STATE3_NONE:
  124.             return RET_ILSEQ;
  125.           case STATE3_DESIGNATED_CNS11643_2:
  126.             if (s[2] < 0x80 && s[3] < 0x80) {
  127.               int ret = cns11643_2_mbtowc(conv,pwc,s+2,2);
  128.               if (ret == RET_ILSEQ)
  129.                 return RET_ILSEQ;
  130.               if (ret != 2) abort();
  131.               COMBINE_STATE;
  132.               conv->istate = state;
  133.               return count+4;
  134.             } else
  135.               return RET_ILSEQ;
  136.           default: abort();
  137.         }
  138.       }
  139.       if (s[1] == 'O') {
  140.         switch (state4) {
  141.           case STATE4_NONE:
  142.             return RET_ILSEQ;
  143.           case STATE4_DESIGNATED_CNS11643_3:
  144.             if (s[2] < 0x80 && s[3] < 0x80) {
  145.               int ret = cns11643_3_mbtowc(conv,pwc,s+2,2);
  146.               if (ret == RET_ILSEQ)
  147.                 return RET_ILSEQ;
  148.               if (ret != 2) abort();
  149.               COMBINE_STATE;
  150.               conv->istate = state;
  151.               return count+4;
  152.             } else
  153.               return RET_ILSEQ;
  154.           case STATE4_DESIGNATED_CNS11643_4:
  155.             if (s[2] < 0x80 && s[3] < 0x80) {
  156.               /* We don't have a CNS 11643-4 to Unicode table yet. */
  157.               return RET_ILSEQ;
  158.             } else
  159.               return RET_ILSEQ;
  160.           case STATE4_DESIGNATED_CNS11643_5:
  161.             if (s[2] < 0x80 && s[3] < 0x80) {
  162.               /* We don't have a CNS 11643-5 to Unicode table yet. */
  163.               return RET_ILSEQ;
  164.             } else
  165.               return RET_ILSEQ;
  166.           case STATE4_DESIGNATED_CNS11643_6:
  167.             if (s[2] < 0x80 && s[3] < 0x80) {
  168.               /* We don't have a CNS 11643-6 to Unicode table yet. */
  169.               return RET_ILSEQ;
  170.             } else
  171.               return RET_ILSEQ;
  172.           case STATE4_DESIGNATED_CNS11643_7:
  173.             if (s[2] < 0x80 && s[3] < 0x80) {
  174.               /* We don't have a CNS 11643-7 to Unicode table yet. */
  175.               return RET_ILSEQ;
  176.             } else
  177.               return RET_ILSEQ;
  178.           default: abort();
  179.         }
  180.       }
  181.       return RET_ILSEQ;
  182.     }
  183.     if (c == SO) {
  184.       if (state2 != STATE2_DESIGNATED_GB2312 && state2 != STATE2_DESIGNATED_CNS11643_1 && state2 != STATE2_DESIGNATED_ISO_IR_165)
  185.         return RET_ILSEQ;
  186.       state1 = STATE_TWOBYTE;
  187.       s++; count++;
  188.       if (n < count+1)
  189.         goto none;
  190.       continue;
  191.     }
  192.     if (c == SI) {
  193.       state1 = STATE_ASCII;
  194.       s++; count++;
  195.       if (n < count+1)
  196.         goto none;
  197.       continue;
  198.     }
  199.     break;
  200.   }
  201.   switch (state1) {
  202.     case STATE_ASCII:
  203.       if (c < 0x80) {
  204.         int ret = ascii_mbtowc(conv,pwc,s,1);
  205.         if (ret == RET_ILSEQ)
  206.           return RET_ILSEQ;
  207.         if (ret != 1) abort();
  208.         if (*pwc == 0x000a || *pwc == 0x000d) {
  209.           state2 = STATE2_NONE; state3 = STATE3_NONE; state4 = STATE3_NONE;
  210.         }
  211.         COMBINE_STATE;
  212.         conv->istate = state;
  213.         return count+1;
  214.       } else
  215.         return RET_ILSEQ;
  216.     case STATE_TWOBYTE:
  217.       if (n < count+2)
  218.         goto none;
  219.       if (s[0] < 0x80 && s[1] < 0x80) {
  220.         int ret;
  221.         switch (state2) {
  222.           case STATE2_NONE:
  223.             return RET_ILSEQ;
  224.           case STATE2_DESIGNATED_GB2312:
  225.             ret = gb2312_mbtowc(conv,pwc,s,2); break;
  226.           case STATE2_DESIGNATED_CNS11643_1:
  227.             ret = cns11643_1_mbtowc(conv,pwc,s,2); break;
  228.           case STATE2_DESIGNATED_ISO_IR_165:
  229.             ret = isoir165_mbtowc(conv,pwc,s,2); break;
  230.           default: abort();
  231.         }
  232.         if (ret == RET_ILSEQ)
  233.           return RET_ILSEQ;
  234.         if (ret != 2) abort();
  235.         COMBINE_STATE;
  236.         conv->istate = state;
  237.         return count+2;
  238.       } else
  239.         return RET_ILSEQ;
  240.     default: abort();
  241.   }
  242. none:
  243.   COMBINE_STATE;
  244.   conv->istate = state;
  245.   return RET_TOOFEW(count);
  246. }
  247. static int
  248. iso2022_cn_ext_wctomb (conv_t conv, unsigned char *r, wchar_t wc, int n)
  249. {
  250.   state_t state = conv->ostate;
  251.   SPLIT_STATE;
  252.   unsigned char buf[3];
  253.   int ret;
  254.   /* Try ASCII. */
  255.   ret = ascii_wctomb(conv,buf,wc,1);
  256.   if (ret != RET_ILSEQ) {
  257.     if (ret != 1) abort();
  258.     if (buf[0] < 0x80) {
  259.       int count = (state1 == STATE_ASCII ? 1 : 2);
  260.       if (n < count)
  261.         return RET_TOOSMALL;
  262.       if (state1 != STATE_ASCII) {
  263.         r[0] = SI;
  264.         r += 1;
  265.         state1 = STATE_ASCII;
  266.       }
  267.       r[0] = buf[0];
  268.       if (wc == 0x000a || wc == 0x000d) {
  269.         state2 = STATE2_NONE; state3 = STATE3_NONE; state4 = STATE3_NONE;
  270.       }
  271.       COMBINE_STATE;
  272.       conv->ostate = state;
  273.       return count;
  274.     }
  275.   }
  276.   /* Try GB 2312-1980. */
  277.   ret = gb2312_wctomb(conv,buf,wc,2);
  278.   if (ret != RET_ILSEQ) {
  279.     if (ret != 2) abort();
  280.     if (buf[0] < 0x80 && buf[1] < 0x80) {
  281.       int count = (state2 == STATE2_DESIGNATED_GB2312 ? 0 : 4) + (state1 == STATE_TWOBYTE ? 0 : 1) + 2;
  282.       if (n < count)
  283.         return RET_TOOSMALL;
  284.       if (state2 != STATE2_DESIGNATED_GB2312) {
  285.         r[0] = ESC;
  286.         r[1] = '$';
  287.         r[2] = ')';
  288.         r[3] = 'A';
  289.         r += 4;
  290.         state2 = STATE2_DESIGNATED_GB2312;
  291.       }
  292.       if (state1 != STATE_TWOBYTE) {
  293.         r[0] = SO;
  294.         r += 1;
  295.         state1 = STATE_TWOBYTE;
  296.       }
  297.       r[0] = buf[0];
  298.       r[1] = buf[1];
  299.       COMBINE_STATE;
  300.       conv->ostate = state;
  301.       return count;
  302.     }
  303.   }
  304.   ret = cns11643_wctomb(conv,buf,wc,3);
  305.   if (ret != RET_ILSEQ) {
  306.     if (ret != 3) abort();
  307.     /* Try CNS 11643-1992 Plane 1. */
  308.     if (buf[0] == 0 && buf[1] < 0x80 && buf[2] < 0x80) {
  309.       int count = (state2 == STATE2_DESIGNATED_CNS11643_1 ? 0 : 4) + (state1 == STATE_TWOBYTE ? 0 : 1) + 2;
  310.       if (n < count)
  311.         return RET_TOOSMALL;
  312.       if (state2 != STATE2_DESIGNATED_CNS11643_1) {
  313.         r[0] = ESC;
  314.         r[1] = '$';
  315.         r[2] = ')';
  316.         r[3] = 'G';
  317.         r += 4;
  318.         state2 = STATE2_DESIGNATED_CNS11643_1;
  319.       }
  320.       if (state1 != STATE_TWOBYTE) {
  321.         r[0] = SO;
  322.         r += 1;
  323.         state1 = STATE_TWOBYTE;
  324.       }
  325.       r[0] = buf[1];
  326.       r[1] = buf[2];
  327.       COMBINE_STATE;
  328.       conv->ostate = state;
  329.       return count;
  330.     }
  331.     /* Try CNS 11643-1992 Plane 2. */
  332.     if (buf[0] == 1 && buf[1] < 0x80 && buf[2] < 0x80) {
  333.       int count = (state3 == STATE3_DESIGNATED_CNS11643_2 ? 0 : 4) + 4;
  334.       if (n < count)
  335.         return RET_TOOSMALL;
  336.       if (state3 != STATE3_DESIGNATED_CNS11643_2) {
  337.         r[0] = ESC;
  338.         r[1] = '$';
  339.         r[2] = '*';
  340.         r[3] = 'H';
  341.         r += 4;
  342.         state3 = STATE3_DESIGNATED_CNS11643_2;
  343.       }
  344.       r[0] = ESC;
  345.       r[1] = 'N';
  346.       r[2] = buf[1];
  347.       r[3] = buf[2];
  348.       COMBINE_STATE;
  349.       conv->ostate = state;
  350.       return count;
  351.     }
  352.     /* Try CNS 11643-1992 Plane 3. */
  353.     if (buf[0] == 2 && buf[1] < 0x80 && buf[2] < 0x80) {
  354.       int count = (state4 == STATE4_DESIGNATED_CNS11643_3 ? 0 : 4) + 4;
  355.       if (n < count)
  356.         return RET_TOOSMALL;
  357.       if (state4 != STATE4_DESIGNATED_CNS11643_3) {
  358.         r[0] = ESC;
  359.         r[1] = '$';
  360.         r[2] = '+';
  361.         r[3] = 'I';
  362.         r += 4;
  363.         state4 = STATE4_DESIGNATED_CNS11643_3;
  364.       }
  365.       r[0] = ESC;
  366.       r[1] = 'O';
  367.       r[2] = buf[1];
  368.       r[3] = buf[2];
  369.       COMBINE_STATE;
  370.       conv->ostate = state;
  371.       return count;
  372.     }
  373.     /* No table for CNS 11643-1992 Plane 4 yet. */
  374.     /* No table for CNS 11643-1992 Plane 5 yet. */
  375.     /* No table for CNS 11643-1992 Plane 6 yet. */
  376.     /* No table for CNS 11643-1992 Plane 7 yet. */
  377.   }
  378.   /* Try ISO-IR-165. */
  379.   ret = isoir165_wctomb(conv,buf,wc,2);
  380.   if (ret != RET_ILSEQ) {
  381.     if (ret != 2) abort();
  382.     if (buf[0] < 0x80 && buf[1] < 0x80) {
  383.       int count = (state2 == STATE2_DESIGNATED_ISO_IR_165 ? 0 : 4) + (state1 == STATE_TWOBYTE ? 0 : 1) + 2;
  384.       if (n < count)
  385.         return RET_TOOSMALL;
  386.       if (state2 != STATE2_DESIGNATED_ISO_IR_165) {
  387.         r[0] = ESC;
  388.         r[1] = '$';
  389.         r[2] = ')';
  390.         r[3] = 'E';
  391.         r += 4;
  392.         state2 = STATE2_DESIGNATED_ISO_IR_165;
  393.       }
  394.       if (state1 != STATE_TWOBYTE) {
  395.         r[0] = SO;
  396.         r += 1;
  397.         state1 = STATE_TWOBYTE;
  398.       }
  399.       r[0] = buf[0];
  400.       r[1] = buf[1];
  401.       COMBINE_STATE;
  402.       conv->ostate = state;
  403.       return count;
  404.     }
  405.   }
  406.   return RET_ILSEQ;
  407. }
  408. static int
  409. iso2022_cn_ext_reset (conv_t conv, unsigned char *r, int n)
  410. {
  411.   state_t state = conv->ostate;
  412.   SPLIT_STATE;
  413.   (void)state2;
  414.   (void)state3;
  415.   (void)state4;
  416.   if (state1 != STATE_ASCII) {
  417.     if (n < 1)
  418.       return RET_TOOSMALL;
  419.     r[0] = SI;
  420.     /* conv->ostate = 0; will be done by the caller */
  421.     return 1;
  422.   } else
  423.     return 0;
  424. }
  425. #undef COMBINE_STATE
  426. #undef SPLIT_STATE
  427. #undef STATE4_DESIGNATED_CNS11643_7
  428. #undef STATE4_DESIGNATED_CNS11643_6
  429. #undef STATE4_DESIGNATED_CNS11643_5
  430. #undef STATE4_DESIGNATED_CNS11643_4
  431. #undef STATE4_DESIGNATED_CNS11643_3
  432. #undef STATE4_NONE
  433. #undef STATE3_DESIGNATED_CNS11643_2
  434. #undef STATE3_NONE
  435. #undef STATE2_DESIGNATED_ISO_IR_165
  436. #undef STATE2_DESIGNATED_CNS11643_1
  437. #undef STATE2_DESIGNATED_GB2312
  438. #undef STATE2_NONE
  439. #undef STATE_TWOBYTE
  440. #undef STATE_ASCII