1 /*
   2  * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
   3  * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved.
   4  *
   5  *    ja_JP.SJIS locale table for BSD4.4/rune
   6  *    version 1.0
   7  *    (C) Sin'ichiro MIYATANI / Phase One, Inc
   8  *    May 12, 1995
   9  *
  10  * Redistribution and use in source and binary forms, with or without
  11  * modification, are permitted provided that the following conditions
  12  * are met:
  13  * 1. Redistributions of source code must retain the above copyright
  14  *    notice, this list of conditions and the following disclaimer.
  15  * 2. Redistributions in binary form must reproduce the above copyright
  16  *    notice, this list of conditions and the following disclaimer in the
  17  *    documentation and/or other materials provided with the distribution.
  18  * 3. All advertising materials mentioning features or use of this software
  19  *    must display the following acknowledgement:
  20  *      This product includes software developed by Phase One, Inc.
  21  * 4. The name of Phase One, Inc. may be used to endorse or promote products
  22  *    derived from this software without specific prior written permission.
  23  *
  24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34  * SUCH DAMAGE.
  35  */
  36 
  37 #include "lint.h"
  38 #include <sys/types.h>
  39 #include <errno.h>
  40 #include "runetype.h"
  41 #include <stdlib.h>
  42 #include <string.h>
  43 #include <wchar.h>
  44 #include "mblocal.h"
  45 
  46 static size_t   _MSKanji_mbrtowc(wchar_t *_RESTRICT_KYWD,
  47                     const char *_RESTRICT_KYWD,
  48                     size_t, mbstate_t *_RESTRICT_KYWD);
  49 static int      _MSKanji_mbsinit(const mbstate_t *);
  50 static size_t   _MSKanji_wcrtomb(char *_RESTRICT_KYWD, wchar_t,
  51                     mbstate_t *_RESTRICT_KYWD);
  52 
  53 typedef struct {
  54         wchar_t ch;
  55 } _MSKanjiState;
  56 
  57 int
  58 _MSKanji_init(_RuneLocale *rl)
  59 {
  60 
  61         __mbrtowc = _MSKanji_mbrtowc;
  62         __wcrtomb = _MSKanji_wcrtomb;
  63         __mbsinit = _MSKanji_mbsinit;
  64         _CurrentRuneLocale = rl;
  65         __ctype[520] = 2;
  66         charset_is_ascii = 0;
  67         return (0);
  68 }
  69 
  70 static int
  71 _MSKanji_mbsinit(const mbstate_t *ps)
  72 {
  73 
  74         return (ps == NULL || ((const _MSKanjiState *)ps)->ch == 0);
  75 }
  76 
  77 static size_t
  78 _MSKanji_mbrtowc(wchar_t *_RESTRICT_KYWD pwc, const char *_RESTRICT_KYWD s,
  79     size_t n, mbstate_t *_RESTRICT_KYWD ps)
  80 {
  81         _MSKanjiState *ms;
  82         wchar_t wc;
  83 
  84         ms = (_MSKanjiState *)ps;
  85 
  86         if ((ms->ch & ~0xFF) != 0) {
  87                 /* Bad conversion state. */
  88                 errno = EINVAL;
  89                 return ((size_t)-1);
  90         }
  91 
  92         if (s == NULL) {
  93                 s = "";
  94                 n = 1;
  95                 pwc = NULL;
  96         }
  97 
  98         if (n == 0)
  99                 /* Incomplete multibyte sequence */
 100                 return ((size_t)-2);
 101 
 102         if (ms->ch != 0) {
 103                 if (*s == '\0') {
 104                         errno = EILSEQ;
 105                         return ((size_t)-1);
 106                 }
 107                 wc = (ms->ch << 8) | (*s & 0xFF);
 108                 if (pwc != NULL)
 109                         *pwc = wc;
 110                 ms->ch = 0;
 111                 return (1);
 112         }
 113         wc = *s++ & 0xff;
 114         if ((wc > 0x80 && wc < 0xa0) || (wc >= 0xe0 && wc < 0xfd)) {
 115                 if (n < 2) {
 116                         /* Incomplete multibyte sequence */
 117                         ms->ch = wc;
 118                         return ((size_t)-2);
 119                 }
 120                 if (*s == '\0') {
 121                         errno = EILSEQ;
 122                         return ((size_t)-1);
 123                 }
 124                 wc = (wc << 8) | (*s++ & 0xff);
 125                 if (pwc != NULL)
 126                         *pwc = wc;
 127                 return (2);
 128         } else {
 129                 if (pwc != NULL)
 130                         *pwc = wc;
 131                 return (wc == L'\0' ? 0 : 1);
 132         }
 133 }
 134 
 135 static size_t
 136 _MSKanji_wcrtomb(char *_RESTRICT_KYWD s, wchar_t wc,
 137     mbstate_t *_RESTRICT_KYWD ps)
 138 {
 139         _MSKanjiState *ms;
 140         int len, i;
 141 
 142         ms = (_MSKanjiState *)ps;
 143 
 144         if (ms->ch != 0) {
 145                 errno = EINVAL;
 146                 return ((size_t)-1);
 147         }
 148 
 149         if (s == NULL)
 150                 /* Reset to initial shift state (no-op) */
 151                 return (1);
 152         len = (wc > 0x100) ? 2 : 1;
 153         for (i = len; i-- > 0; )
 154                 *s++ = wc >> (i << 3);
 155         return (len);
 156 }