File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libiconv / lib / hz.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:  * HZ
   22:  */
   23: 
   24: /* Specification: RFC 1842, RFC 1843 */
   25: 
   26: /*
   27:  * The state is 1 in GB mode, 0 in ASCII mode.
   28:  */
   29: 
   30: static int
   31: hz_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
   32: {
   33:   state_t state = conv->istate;
   34:   unsigned int count = 0;
   35:   unsigned char c;
   36:   for (;;) {
   37:     c = *s;
   38:     if (c == '~') {
   39:       if (n < count+2)
   40:         goto none;
   41:       c = s[1];
   42:       if (state == 0) {
   43:         if (c == '~') {
   44:           *pwc = (ucs4_t) '~';
   45:           conv->istate = state;
   46:           return count+2;
   47:         }
   48:         if (c == '{') {
   49:           state = 1;
   50:           s += 2; count += 2;
   51:           if (n < count+1)
   52:             goto none;
   53:           continue;
   54:         }
   55:         if (c == '\n') {
   56:           s += 2; count += 2;
   57:           if (n < count+1)
   58:             goto none;
   59:           continue;
   60:         }
   61:       } else {
   62:         if (c == '}') {
   63:           state = 0;
   64:           s += 2; count += 2;
   65:           if (n < count+1)
   66:             goto none;
   67:           continue;
   68:         }
   69:       }
   70:       goto ilseq;
   71:     }
   72:     break;
   73:   }
   74:   if (state == 0) {
   75:     *pwc = (ucs4_t) c;
   76:     conv->istate = state;
   77:     return count+1;
   78:   } else {
   79:     int ret;
   80:     if (n < count+2)
   81:       goto none;
   82:     ret = gb2312_mbtowc(conv,pwc,s,2);
   83:     if (ret == RET_ILSEQ)
   84:       goto ilseq;
   85:     if (ret != 2) abort();
   86:     conv->istate = state;
   87:     return count+2;
   88:   }
   89: 
   90: none:
   91:   conv->istate = state;
   92:   return RET_TOOFEW(count);
   93: 
   94: ilseq:
   95:   conv->istate = state;
   96:   return RET_SHIFT_ILSEQ(count);
   97: }
   98: 
   99: static int
  100: hz_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, size_t n)
  101: {
  102:   state_t state = conv->ostate;
  103:   unsigned char buf[2];
  104:   int ret;
  105: 
  106:   /* Code set 0 (ASCII or GB 1988-89) */
  107:   ret = ascii_wctomb(conv,buf,wc,1);
  108:   if (ret != RET_ILUNI) {
  109:     if (ret != 1) abort();
  110:     if (buf[0] < 0x80) {
  111:       int count = (state ? 3 : 1);
  112:       if (n < count)
  113:         return RET_TOOSMALL;
  114:       if (state) {
  115:         r[0] = '~';
  116:         r[1] = '}';
  117:         r += 2;
  118:         state = 0;
  119:       }
  120:       r[0] = buf[0];
  121:       conv->ostate = state;
  122:       return count;
  123:     }
  124:   }
  125: 
  126:   /* Code set 1 (GB 2312-1980) */
  127:   ret = gb2312_wctomb(conv,buf,wc,2);
  128:   if (ret != RET_ILUNI) {
  129:     if (ret != 2) abort();
  130:     if (buf[0] < 0x80 && buf[1] < 0x80) {
  131:       int count = (state ? 2 : 4);
  132:       if (n < count)
  133:         return RET_TOOSMALL;
  134:       if (!state) {
  135:         r[0] = '~';
  136:         r[1] = '{';
  137:         r += 2;
  138:         state = 1;
  139:       }
  140:       r[0] = buf[0];
  141:       r[1] = buf[1];
  142:       conv->ostate = state;
  143:       return count;
  144:     }
  145:   }
  146: 
  147:   return RET_ILUNI;
  148: }
  149: 
  150: static int
  151: hz_reset (conv_t conv, unsigned char *r, size_t n)
  152: {
  153:   state_t state = conv->ostate;
  154:   if (state) {
  155:     if (n < 2)
  156:       return RET_TOOSMALL;
  157:     r[0] = '~';
  158:     r[1] = '}';
  159:     /* conv->ostate = 0; will be done by the caller */
  160:     return 2;
  161:   } else
  162:     return 0;
  163: }

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