1 
2 /*
3  * EUC-JP
4  */
5 
6 static int
euc_jp_mbtowc(conv_t conv,ucs4_t * pwc,const unsigned char * s,int n)7 euc_jp_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n)
8 {
9   unsigned char c = *s;
10   /* Code set 0 (ASCII or JIS X 0201-1976 Roman) */
11   if (c < 0x80)
12     return ascii_mbtowc(conv,pwc,s,n);
13   /* Code set 1 (JIS X 0208) */
14   if (c >= 0xa1 && c < 0xff) {
15     if (n < 2)
16       return RET_TOOFEW(0);
17     if (c < 0xf5) {
18       unsigned char c2 = s[1];
19       if (c2 >= 0xa1 && c2 < 0xff) {
20         unsigned char buf[2];
21         buf[0] = c-0x80; buf[1] = c2-0x80;
22         return jisx0208_mbtowc(conv,pwc,buf,2);
23       } else
24         return RET_ILSEQ;
25     } else {
26       /* User-defined range. See
27        * Ken Lunde's "CJKV Information Processing", table 4-66, p. 206. */
28       unsigned char c2 = s[1];
29       if (c2 >= 0xa1 && c2 < 0xff) {
30         *pwc = 0xe000 + 94*(c-0xf5) + (c2-0xa1);
31         return 2;
32       } else
33         return RET_ILSEQ;
34     }
35   }
36   /* Code set 2 (half-width katakana) */
37   if (c == 0x8e) {
38     if (n < 2)
39       return RET_TOOFEW(0);
40     {
41       unsigned char c2 = s[1];
42       if (c2 >= 0xa1 && c2 < 0xe0) {
43         int ret = jisx0201_mbtowc(conv,pwc,s+1,n-1);
44         if (ret == RET_ILSEQ)
45           return RET_ILSEQ;
46         if (ret != 1) abort();
47         return 2;
48       } else
49         return RET_ILSEQ;
50     }
51   }
52   /* Code set 3 (JIS X 0212-1990) */
53   if (c == 0x8f) {
54     if (n < 2)
55       return RET_TOOFEW(0);
56     {
57       unsigned char c2 = s[1];
58       if (c2 >= 0xa1 && c2 < 0xff) {
59         if (n < 3)
60           return RET_TOOFEW(0);
61         if (c2 < 0xf5) {
62           unsigned char c3 = s[2];
63           if (c3 >= 0xa1 && c3 < 0xff) {
64             unsigned char buf[2];
65             int ret;
66             buf[0] = c2-0x80; buf[1] = c3-0x80;
67             ret = jisx0212_mbtowc(conv,pwc,buf,2);
68             if (ret == RET_ILSEQ)
69               return RET_ILSEQ;
70             if (ret != 2) abort();
71             return 3;
72           } else
73             return RET_ILSEQ;
74         } else {
75           /* User-defined range. See
76            * Ken Lunde's "CJKV Information Processing", table 4-66, p. 206. */
77           unsigned char c3 = s[2];
78           if (c3 >= 0xa1 && c3 < 0xff) {
79             *pwc = 0xe3ac + 94*(c2-0xf5) + (c3-0xa1);
80             return 3;
81           } else
82             return RET_ILSEQ;
83         }
84       } else
85         return RET_ILSEQ;
86     }
87   }
88   return RET_ILSEQ;
89 }
90 
91 static int
euc_jp_wctomb(conv_t conv,unsigned char * r,ucs4_t wc,int n)92 euc_jp_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n)
93 {
94   unsigned char buf[2];
95   int ret;
96 
97   /* Code set 0 (ASCII or JIS X 0201-1976 Roman) */
98   ret = ascii_wctomb(conv,r,wc,n);
99   if (ret != RET_ILSEQ)
100     return ret;
101 
102   /* Code set 1 (JIS X 0208) */
103   ret = jisx0208_wctomb(conv,buf,wc,2);
104   if (ret != RET_ILSEQ) {
105     if (ret != 2) abort();
106     if (n < 2)
107       return RET_TOOSMALL;
108     r[0] = buf[0]+0x80;
109     r[1] = buf[1]+0x80;
110     return 2;
111   }
112 
113   /* Code set 2 (half-width katakana) */
114   ret = jisx0201_wctomb(conv,buf,wc,1);
115   if (ret != RET_ILSEQ && buf[0] >= 0x80) {
116     if (ret != 1) abort();
117     if (n < 2)
118       return RET_TOOSMALL;
119     r[0] = 0x8e;
120     r[1] = buf[0];
121     return 2;
122   }
123 
124   /* Code set 3 (JIS X 0212-1990) */
125   ret = jisx0212_wctomb(conv,buf,wc,2);
126   if (ret != RET_ILSEQ) {
127     if (ret != 2) abort();
128     if (n < 3)
129       return RET_TOOSMALL;
130     r[0] = 0x8f;
131     r[1] = buf[0]+0x80;
132     r[2] = buf[1]+0x80;
133     return 3;
134   }
135 
136   /* User-defined range. See
137    * Ken Lunde's "CJKV Information Processing", table 4-66, p. 206. */
138   if (wc >= 0xe000 && wc < 0xe758) {
139     if (wc < 0xe3ac) {
140       unsigned char c1, c2;
141       if (n < 2)
142         return RET_TOOSMALL;
143       c1 = (unsigned int) (wc - 0xe000) / 94;
144       c2 = (unsigned int) (wc - 0xe000) % 94;
145       r[0] = c1+0xf5;
146       r[1] = c2+0xa1;
147       return 2;
148     } else {
149       unsigned char c1, c2;
150       if (n < 2)
151         return RET_TOOSMALL;
152       c1 = (unsigned int) (wc - 0xe3ac) / 94;
153       c2 = (unsigned int) (wc - 0xe3ac) % 94;
154       r[0] = 0x8f;
155       r[1] = c1+0xf5;
156       r[2] = c2+0xa1;
157       return 3;
158     }
159   }
160 
161   return RET_ILSEQ;
162 }
163