File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libiconv / lib / iso2022_jp1.h
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 13:38:46 2021 UTC (3 years, 3 months ago) by misho
Branches: libiconv, MAIN
CVS tags: v1_16p0, HEAD
libiconv 1.16

    1: /*
    2:  * Copyright (C) 1999-2001, 2008, 2016 Free Software Foundation, Inc.
    3:  * This file is part of the GNU LIBICONV Library.
    4:  *
    5:  * The GNU LIBICONV Library is free software; you can redistribute it
    6:  * and/or modify it under the terms of the GNU Library General Public
    7:  * License as published by the Free Software Foundation; either version 2
    8:  * of the License, or (at your option) any later version.
    9:  *
   10:  * The GNU LIBICONV Library is distributed in the hope that it will be
   11:  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
   12:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13:  * Library General Public License for more details.
   14:  *
   15:  * You should have received a copy of the GNU Library General Public
   16:  * License along with the GNU LIBICONV Library; see the file COPYING.LIB.
   17:  * If not, see <https://www.gnu.org/licenses/>.
   18:  */
   19: 
   20: /*
   21:  * ISO-2022-JP-1
   22:  */
   23: 
   24: /* Specification: RFC 2237 */
   25: 
   26: #define ESC 0x1b
   27: 
   28: /*
   29:  * The state can be one of the following values.
   30:  */
   31: #define STATE_ASCII          0
   32: #define STATE_JISX0201ROMAN  1
   33: #define STATE_JISX0208       2
   34: #define STATE_JISX0212       3
   35: 
   36: static int
   37: iso2022_jp1_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
   38: {
   39:   state_t state = conv->istate;
   40:   int count = 0;
   41:   unsigned char c;
   42:   for (;;) {
   43:     c = *s;
   44:     if (c == ESC) {
   45:       if (n < count+3)
   46:         goto none;
   47:       if (s[1] == '(') {
   48:         if (s[2] == 'B') {
   49:           state = STATE_ASCII;
   50:           s += 3; count += 3;
   51:           if (n < count+1)
   52:             goto none;
   53:           continue;
   54:         }
   55:         if (s[2] == 'J') {
   56:           state = STATE_JISX0201ROMAN;
   57:           s += 3; count += 3;
   58:           if (n < count+1)
   59:             goto none;
   60:           continue;
   61:         }
   62:         goto ilseq;
   63:       }
   64:       if (s[1] == '$') {
   65:         if (s[2] == '@' || s[2] == 'B') {
   66:           /* We don't distinguish JIS X 0208-1978 and JIS X 0208-1983. */
   67:           state = STATE_JISX0208;
   68:           s += 3; count += 3;
   69:           if (n < count+1)
   70:             goto none;
   71:           continue;
   72:         }
   73:         if (s[2] == '(') {
   74:           if (n < count+4)
   75:             goto none;
   76:           if (s[3] == 'D') {
   77:             state = STATE_JISX0212;
   78:             s += 4; count += 4;
   79:             if (n < count+1)
   80:               goto none;
   81:             continue;
   82:           }
   83:         }
   84:         goto ilseq;
   85:       }
   86:       goto ilseq;
   87:     }
   88:     break;
   89:   }
   90:   switch (state) {
   91:     case STATE_ASCII:
   92:       if (c < 0x80) {
   93:         int ret = ascii_mbtowc(conv,pwc,s,1);
   94:         if (ret == RET_ILSEQ)
   95:           goto ilseq;
   96:         if (ret != 1) abort();
   97:         conv->istate = state;
   98:         return count+1;
   99:       } else
  100:         goto ilseq;
  101:     case STATE_JISX0201ROMAN:
  102:       if (c < 0x80) {
  103:         int ret = jisx0201_mbtowc(conv,pwc,s,1);
  104:         if (ret == RET_ILSEQ)
  105:           goto ilseq;
  106:         if (ret != 1) abort();
  107:         conv->istate = state;
  108:         return count+1;
  109:       } else
  110:         goto ilseq;
  111:     case STATE_JISX0208:
  112:       if (n < count+2)
  113:         goto none;
  114:       if (s[0] < 0x80 && s[1] < 0x80) {
  115:         int ret = jisx0208_mbtowc(conv,pwc,s,2);
  116:         if (ret == RET_ILSEQ)
  117:           goto ilseq;
  118:         if (ret != 2) abort();
  119:         conv->istate = state;
  120:         return count+2;
  121:       } else
  122:         goto ilseq;
  123:     case STATE_JISX0212:
  124:       if (n < count+2)
  125:         goto none;
  126:       if (s[0] < 0x80 && s[1] < 0x80) {
  127:         int ret = jisx0212_mbtowc(conv,pwc,s,2);
  128:         if (ret == RET_ILSEQ)
  129:           goto ilseq;
  130:         if (ret != 2) abort();
  131:         conv->istate = state;
  132:         return count+2;
  133:       } else
  134:         goto ilseq;
  135:     default: abort();
  136:   }
  137: 
  138: none:
  139:   conv->istate = state;
  140:   return RET_TOOFEW(count);
  141: 
  142: ilseq:
  143:   conv->istate = state;
  144:   return RET_SHIFT_ILSEQ(count);
  145: }
  146: 
  147: static int
  148: iso2022_jp1_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, size_t n)
  149: {
  150:   state_t state = conv->ostate;
  151:   unsigned char buf[2];
  152:   int ret;
  153: 
  154:   /* Try ASCII. */
  155:   ret = ascii_wctomb(conv,buf,wc,1);
  156:   if (ret != RET_ILUNI) {
  157:     if (ret != 1) abort();
  158:     if (buf[0] < 0x80) {
  159:       int count = (state == STATE_ASCII ? 1 : 4);
  160:       if (n < count)
  161:         return RET_TOOSMALL;
  162:       if (state != STATE_ASCII) {
  163:         r[0] = ESC;
  164:         r[1] = '(';
  165:         r[2] = 'B';
  166:         r += 3;
  167:         state = STATE_ASCII;
  168:       }
  169:       r[0] = buf[0];
  170:       conv->ostate = state;
  171:       return count;
  172:     }
  173:   }
  174: 
  175:   /* Try JIS X 0201-1976 Roman. */
  176:   ret = jisx0201_wctomb(conv,buf,wc,1);
  177:   if (ret != RET_ILUNI) {
  178:     if (ret != 1) abort();
  179:     if (buf[0] < 0x80) {
  180:       int count = (state == STATE_JISX0201ROMAN ? 1 : 4);
  181:       if (n < count)
  182:         return RET_TOOSMALL;
  183:       if (state != STATE_JISX0201ROMAN) {
  184:         r[0] = ESC;
  185:         r[1] = '(';
  186:         r[2] = 'J';
  187:         r += 3;
  188:         state = STATE_JISX0201ROMAN;
  189:       }
  190:       r[0] = buf[0];
  191:       conv->ostate = state;
  192:       return count;
  193:     }
  194:   }
  195: 
  196:   /* Try JIS X 0208-1990 in place of JIS X 0208-1978 and JIS X 0208-1983. */
  197:   ret = jisx0208_wctomb(conv,buf,wc,2);
  198:   if (ret != RET_ILUNI) {
  199:     if (ret != 2) abort();
  200:     if (buf[0] < 0x80 && buf[1] < 0x80) {
  201:       int count = (state == STATE_JISX0208 ? 2 : 5);
  202:       if (n < count)
  203:         return RET_TOOSMALL;
  204:       if (state != STATE_JISX0208) {
  205:         r[0] = ESC;
  206:         r[1] = '$';
  207:         r[2] = 'B';
  208:         r += 3;
  209:         state = STATE_JISX0208;
  210:       }
  211:       r[0] = buf[0];
  212:       r[1] = buf[1];
  213:       conv->ostate = state;
  214:       return count;
  215:     }
  216:   }
  217: 
  218:   /* Try JIS X 0212-1990. */
  219:   ret = jisx0212_wctomb(conv,buf,wc,2);
  220:   if (ret != RET_ILUNI) {
  221:     if (ret != 2) abort();
  222:     if (buf[0] < 0x80 && buf[1] < 0x80) {
  223:       int count = (state == STATE_JISX0212 ? 2 : 6);
  224:       if (n < count)
  225:         return RET_TOOSMALL;
  226:       if (state != STATE_JISX0212) {
  227:         r[0] = ESC;
  228:         r[1] = '$';
  229:         r[2] = '(';
  230:         r[3] = 'D';
  231:         r += 4;
  232:         state = STATE_JISX0212;
  233:       }
  234:       r[0] = buf[0];
  235:       r[1] = buf[1];
  236:       conv->ostate = state;
  237:       return count;
  238:     }
  239:   }
  240: 
  241:   return RET_ILUNI;
  242: }
  243: 
  244: static int
  245: iso2022_jp1_reset (conv_t conv, unsigned char *r, size_t n)
  246: {
  247:   state_t state = conv->ostate;
  248:   if (state != STATE_ASCII) {
  249:     if (n < 3)
  250:       return RET_TOOSMALL;
  251:     r[0] = ESC;
  252:     r[1] = '(';
  253:     r[2] = 'B';
  254:     /* conv->ostate = 0; will be done by the caller */
  255:     return 3;
  256:   } else
  257:     return 0;
  258: }
  259: 
  260: #undef STATE_JISX0212
  261: #undef STATE_JISX0208
  262: #undef STATE_JISX0201ROMAN
  263: #undef STATE_ASCII

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>