Blame


1 5cedca1b 2004-05-15 devnull #include <stdlib.h>
2 5cedca1b 2004-05-15 devnull
3 5cedca1b 2004-05-15 devnull /*
4 5cedca1b 2004-05-15 devnull * Use the FSS-UTF transformation proposed by posix.
5 5cedca1b 2004-05-15 devnull * We define 7 byte types:
6 5cedca1b 2004-05-15 devnull * T0 0xxxxxxx 7 free bits
7 5cedca1b 2004-05-15 devnull * Tx 10xxxxxx 6 free bits
8 5cedca1b 2004-05-15 devnull * T1 110xxxxx 5 free bits
9 5cedca1b 2004-05-15 devnull * T2 1110xxxx 4 free bits
10 5cedca1b 2004-05-15 devnull *
11 5cedca1b 2004-05-15 devnull * Encoding is as follows.
12 5cedca1b 2004-05-15 devnull * From hex Thru hex Sequence Bits
13 5cedca1b 2004-05-15 devnull * 00000000 0000007F T0 7
14 5cedca1b 2004-05-15 devnull * 00000080 000007FF T1 Tx 11
15 5cedca1b 2004-05-15 devnull * 00000800 0000FFFF T2 Tx Tx 16
16 5cedca1b 2004-05-15 devnull */
17 5cedca1b 2004-05-15 devnull
18 5cedca1b 2004-05-15 devnull int
19 5cedca1b 2004-05-15 devnull mblen(const char *s, size_t n)
20 5cedca1b 2004-05-15 devnull {
21 5cedca1b 2004-05-15 devnull
22 5cedca1b 2004-05-15 devnull return mbtowc(0, s, n);
23 5cedca1b 2004-05-15 devnull }
24 5cedca1b 2004-05-15 devnull
25 5cedca1b 2004-05-15 devnull int
26 5cedca1b 2004-05-15 devnull mbtowc(wchar_t *pwc, const char *s, size_t n)
27 5cedca1b 2004-05-15 devnull {
28 5cedca1b 2004-05-15 devnull int c, c1, c2;
29 5cedca1b 2004-05-15 devnull long l;
30 5cedca1b 2004-05-15 devnull
31 5cedca1b 2004-05-15 devnull if(!s)
32 5cedca1b 2004-05-15 devnull return 0;
33 5cedca1b 2004-05-15 devnull
34 5cedca1b 2004-05-15 devnull if(n < 1)
35 5cedca1b 2004-05-15 devnull goto bad;
36 5cedca1b 2004-05-15 devnull c = s[0] & 0xff;
37 5cedca1b 2004-05-15 devnull if((c & 0x80) == 0x00) {
38 5cedca1b 2004-05-15 devnull if(pwc)
39 5cedca1b 2004-05-15 devnull *pwc = c;
40 5cedca1b 2004-05-15 devnull if(c == 0)
41 5cedca1b 2004-05-15 devnull return 0;
42 5cedca1b 2004-05-15 devnull return 1;
43 5cedca1b 2004-05-15 devnull }
44 5cedca1b 2004-05-15 devnull
45 5cedca1b 2004-05-15 devnull if(n < 2)
46 5cedca1b 2004-05-15 devnull goto bad;
47 5cedca1b 2004-05-15 devnull c1 = (s[1] ^ 0x80) & 0xff;
48 5cedca1b 2004-05-15 devnull if((c1 & 0xC0) != 0x00)
49 5cedca1b 2004-05-15 devnull goto bad;
50 5cedca1b 2004-05-15 devnull if((c & 0xE0) == 0xC0) {
51 5cedca1b 2004-05-15 devnull l = ((c << 6) | c1) & 0x7FF;
52 5cedca1b 2004-05-15 devnull if(l < 0x080)
53 5cedca1b 2004-05-15 devnull goto bad;
54 5cedca1b 2004-05-15 devnull if(pwc)
55 5cedca1b 2004-05-15 devnull *pwc = l;
56 5cedca1b 2004-05-15 devnull return 2;
57 5cedca1b 2004-05-15 devnull }
58 5cedca1b 2004-05-15 devnull
59 5cedca1b 2004-05-15 devnull if(n < 3)
60 5cedca1b 2004-05-15 devnull goto bad;
61 5cedca1b 2004-05-15 devnull c2 = (s[2] ^ 0x80) & 0xff;
62 5cedca1b 2004-05-15 devnull if((c2 & 0xC0) != 0x00)
63 5cedca1b 2004-05-15 devnull goto bad;
64 5cedca1b 2004-05-15 devnull if((c & 0xF0) == 0xE0) {
65 5cedca1b 2004-05-15 devnull l = ((((c << 6) | c1) << 6) | c2) & 0xFFFF;
66 5cedca1b 2004-05-15 devnull if(l < 0x0800)
67 5cedca1b 2004-05-15 devnull goto bad;
68 5cedca1b 2004-05-15 devnull if(pwc)
69 5cedca1b 2004-05-15 devnull *pwc = l;
70 5cedca1b 2004-05-15 devnull return 3;
71 5cedca1b 2004-05-15 devnull }
72 5cedca1b 2004-05-15 devnull
73 5cedca1b 2004-05-15 devnull /*
74 5cedca1b 2004-05-15 devnull * bad decoding
75 5cedca1b 2004-05-15 devnull */
76 5cedca1b 2004-05-15 devnull bad:
77 5cedca1b 2004-05-15 devnull return -1;
78 5cedca1b 2004-05-15 devnull
79 5cedca1b 2004-05-15 devnull }
80 5cedca1b 2004-05-15 devnull
81 5cedca1b 2004-05-15 devnull int
82 5cedca1b 2004-05-15 devnull wctomb(char *s, wchar_t wchar)
83 5cedca1b 2004-05-15 devnull {
84 5cedca1b 2004-05-15 devnull long c;
85 5cedca1b 2004-05-15 devnull
86 5cedca1b 2004-05-15 devnull if(!s)
87 5cedca1b 2004-05-15 devnull return 0;
88 5cedca1b 2004-05-15 devnull
89 5cedca1b 2004-05-15 devnull c = wchar & 0xFFFF;
90 5cedca1b 2004-05-15 devnull if(c < 0x80) {
91 5cedca1b 2004-05-15 devnull s[0] = c;
92 5cedca1b 2004-05-15 devnull return 1;
93 5cedca1b 2004-05-15 devnull }
94 5cedca1b 2004-05-15 devnull
95 5cedca1b 2004-05-15 devnull if(c < 0x800) {
96 5cedca1b 2004-05-15 devnull s[0] = 0xC0 | (c >> 6);
97 5cedca1b 2004-05-15 devnull s[1] = 0x80 | (c & 0x3F);
98 5cedca1b 2004-05-15 devnull return 2;
99 5cedca1b 2004-05-15 devnull }
100 5cedca1b 2004-05-15 devnull
101 5cedca1b 2004-05-15 devnull s[0] = 0xE0 | (c >> 12);
102 5cedca1b 2004-05-15 devnull s[1] = 0x80 | ((c >> 6) & 0x3F);
103 5cedca1b 2004-05-15 devnull s[2] = 0x80 | (c & 0x3F);
104 5cedca1b 2004-05-15 devnull return 3;
105 5cedca1b 2004-05-15 devnull }
106 5cedca1b 2004-05-15 devnull
107 5cedca1b 2004-05-15 devnull size_t
108 5cedca1b 2004-05-15 devnull mbstowcs(wchar_t *pwcs, const char *s, size_t n)
109 5cedca1b 2004-05-15 devnull {
110 5cedca1b 2004-05-15 devnull int i, d, c;
111 5cedca1b 2004-05-15 devnull
112 5cedca1b 2004-05-15 devnull for(i=0; i < n; i++) {
113 5cedca1b 2004-05-15 devnull c = *s & 0xff;
114 5cedca1b 2004-05-15 devnull if(c < 0x80) {
115 5cedca1b 2004-05-15 devnull *pwcs = c;
116 5cedca1b 2004-05-15 devnull if(c == 0)
117 5cedca1b 2004-05-15 devnull break;
118 5cedca1b 2004-05-15 devnull s++;
119 5cedca1b 2004-05-15 devnull } else {
120 5cedca1b 2004-05-15 devnull d = mbtowc(pwcs, s, 3);
121 5cedca1b 2004-05-15 devnull if(d <= 0)
122 5cedca1b 2004-05-15 devnull return (size_t)((d<0) ? -1 : i);
123 5cedca1b 2004-05-15 devnull s += d;
124 5cedca1b 2004-05-15 devnull }
125 5cedca1b 2004-05-15 devnull pwcs++;
126 5cedca1b 2004-05-15 devnull }
127 5cedca1b 2004-05-15 devnull return i;
128 5cedca1b 2004-05-15 devnull }
129 5cedca1b 2004-05-15 devnull
130 5cedca1b 2004-05-15 devnull size_t
131 5cedca1b 2004-05-15 devnull wcstombs(char *s, const wchar_t *pwcs, size_t n)
132 5cedca1b 2004-05-15 devnull {
133 1f72bc47 2004-05-17 devnull int d;
134 5cedca1b 2004-05-15 devnull long c;
135 5cedca1b 2004-05-15 devnull char *p, *pe;
136 5cedca1b 2004-05-15 devnull char buf[3];
137 5cedca1b 2004-05-15 devnull
138 5cedca1b 2004-05-15 devnull p = s;
139 5cedca1b 2004-05-15 devnull pe = p+n-3;
140 5cedca1b 2004-05-15 devnull while(p < pe) {
141 5cedca1b 2004-05-15 devnull c = *pwcs++;
142 5cedca1b 2004-05-15 devnull if(c < 0x80)
143 5cedca1b 2004-05-15 devnull *p++ = c;
144 5cedca1b 2004-05-15 devnull else
145 5cedca1b 2004-05-15 devnull p += wctomb(p, c);
146 5cedca1b 2004-05-15 devnull if(c == 0)
147 5cedca1b 2004-05-15 devnull return p-s;
148 5cedca1b 2004-05-15 devnull }
149 5cedca1b 2004-05-15 devnull while(p < pe+3) {
150 5cedca1b 2004-05-15 devnull c = *pwcs++;
151 5cedca1b 2004-05-15 devnull d = wctomb(buf, c);
152 5cedca1b 2004-05-15 devnull if(p+d <= pe+3) {
153 5cedca1b 2004-05-15 devnull *p++ = buf[0];
154 5cedca1b 2004-05-15 devnull if(d > 1) {
155 0cadb430 2009-09-11 russcox *p++ = buf[1];
156 5cedca1b 2004-05-15 devnull if(d > 2)
157 0cadb430 2009-09-11 russcox *p++ = buf[2];
158 5cedca1b 2004-05-15 devnull }
159 5cedca1b 2004-05-15 devnull }
160 5cedca1b 2004-05-15 devnull if(c == 0)
161 5cedca1b 2004-05-15 devnull break;
162 5cedca1b 2004-05-15 devnull }
163 5cedca1b 2004-05-15 devnull return p-s;
164 5cedca1b 2004-05-15 devnull }