Blame


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