File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libiconv / lib / iso2022_jp.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
   22:  */
   23: 
   24: /* Specification: RFC 1468 */
   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: 
   35: static int
   36: iso2022_jp_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
   37: {
   38:   state_t state = conv->istate;
   39:   int count = 0;
   40:   unsigned char c;
   41:   for (;;) {
   42:     c = *s;
   43:     if (c == ESC) {
   44:       if (n < count+3)
   45:         goto none;
   46:       if (s[1] == '(') {
   47:         if (s[2] == 'B') {
   48:           state = STATE_ASCII;
   49:           s += 3; count += 3;
   50:           if (n < count+1)
   51:             goto none;
   52:           continue;
   53:         }
   54:         if (s[2] == 'J') {
   55:           state = STATE_JISX0201ROMAN;
   56:           s += 3; count += 3;
   57:           if (n < count+1)
   58:             goto none;
   59:           continue;
   60:         }
   61:         goto ilseq;
   62:       }
   63:       if (s[1] == '$') {
   64:         if (s[2] == '@' || s[2] == 'B') {
   65:           /* We don't distinguish JIS X 0208-1978 and JIS X 0208-1983. */
   66:           state = STATE_JISX0208;
   67:           s += 3; count += 3;
   68:           if (n < count+1)
   69:             goto none;
   70:           continue;
   71:         }
   72:         goto ilseq;
   73:       }
   74:       goto ilseq;
   75:     }
   76:     break;
   77:   }
   78:   switch (state) {
   79:     case STATE_ASCII:
   80:       if (c < 0x80) {
   81:         int ret = ascii_mbtowc(conv,pwc,s,1);
   82:         if (ret == RET_ILSEQ)
   83:           goto ilseq;
   84:         if (ret != 1) abort();
   85:         conv->istate = state;
   86:         return count+1;
   87:       } else
   88:         goto ilseq;
   89:     case STATE_JISX0201ROMAN:
   90:       if (c < 0x80) {
   91:         int ret = jisx0201_mbtowc(conv,pwc,s,1);
   92:         if (ret == RET_ILSEQ)
   93:           goto ilseq;
   94:         if (ret != 1) abort();
   95:         conv->istate = state;
   96:         return count+1;
   97:       } else
   98:         goto ilseq;
   99:     case STATE_JISX0208:
  100:       if (n < count+2)
  101:         goto none;
  102:       if (s[0] < 0x80 && s[1] < 0x80) {
  103:         int ret = jisx0208_mbtowc(conv,pwc,s,2);
  104:         if (ret == RET_ILSEQ)
  105:           goto ilseq;
  106:         if (ret != 2) abort();
  107:         conv->istate = state;
  108:         return count+2;
  109:       } else
  110:         goto ilseq;
  111:     default: abort();
  112:   }
  113: 
  114: none:
  115:   conv->istate = state;
  116:   return RET_TOOFEW(count);
  117: 
  118: ilseq:
  119:   conv->istate = state;
  120:   return RET_SHIFT_ILSEQ(count);
  121: }
  122: 
  123: static int
  124: iso2022_jp_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, size_t n)
  125: {
  126:   state_t state = conv->ostate;
  127:   unsigned char buf[2];
  128:   int ret;
  129: 
  130:   /* Try ASCII. */
  131:   ret = ascii_wctomb(conv,buf,wc,1);
  132:   if (ret != RET_ILUNI) {
  133:     if (ret != 1) abort();
  134:     if (buf[0] < 0x80) {
  135:       int count = (state == STATE_ASCII ? 1 : 4);
  136:       if (n < count)
  137:         return RET_TOOSMALL;
  138:       if (state != STATE_ASCII) {
  139:         r[0] = ESC;
  140:         r[1] = '(';
  141:         r[2] = 'B';
  142:         r += 3;
  143:         state = STATE_ASCII;
  144:       }
  145:       r[0] = buf[0];
  146:       conv->ostate = state;
  147:       return count;
  148:     }
  149:   }
  150: 
  151:   /* Try JIS X 0201-1976 Roman. */
  152:   ret = jisx0201_wctomb(conv,buf,wc,1);
  153:   if (ret != RET_ILUNI) {
  154:     if (ret != 1) abort();
  155:     if (buf[0] < 0x80) {
  156:       int count = (state == STATE_JISX0201ROMAN ? 1 : 4);
  157:       if (n < count)
  158:         return RET_TOOSMALL;
  159:       if (state != STATE_JISX0201ROMAN) {
  160:         r[0] = ESC;
  161:         r[1] = '(';
  162:         r[2] = 'J';
  163:         r += 3;
  164:         state = STATE_JISX0201ROMAN;
  165:       }
  166:       r[0] = buf[0];
  167:       conv->ostate = state;
  168:       return count;
  169:     }
  170:   }
  171: 
  172:   /* Try JIS X 0208-1990 in place of JIS X 0208-1978 and JIS X 0208-1983. */
  173:   ret = jisx0208_wctomb(conv,buf,wc,2);
  174:   if (ret != RET_ILUNI) {
  175:     if (ret != 2) abort();
  176:     if (buf[0] < 0x80 && buf[1] < 0x80) {
  177:       int count = (state == STATE_JISX0208 ? 2 : 5);
  178:       if (n < count)
  179:         return RET_TOOSMALL;
  180:       if (state != STATE_JISX0208) {
  181:         r[0] = ESC;
  182:         r[1] = '$';
  183:         r[2] = 'B';
  184:         r += 3;
  185:         state = STATE_JISX0208;
  186:       }
  187:       r[0] = buf[0];
  188:       r[1] = buf[1];
  189:       conv->ostate = state;
  190:       return count;
  191:     }
  192:   }
  193: 
  194:   return RET_ILUNI;
  195: }
  196: 
  197: static int
  198: iso2022_jp_reset (conv_t conv, unsigned char *r, size_t n)
  199: {
  200:   state_t state = conv->ostate;
  201:   if (state != STATE_ASCII) {
  202:     if (n < 3)
  203:       return RET_TOOSMALL;
  204:     r[0] = ESC;
  205:     r[1] = '(';
  206:     r[2] = 'B';
  207:     /* conv->ostate = 0; will be done by the caller */
  208:     return 3;
  209:   } else
  210:     return 0;
  211: }
  212: 
  213: #undef STATE_JISX0208
  214: #undef STATE_JISX0201ROMAN
  215: #undef STATE_ASCII

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