2004-05-15 23:24:00 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Use the FSS-UTF transformation proposed by posix.
|
|
|
|
* We define 7 byte types:
|
|
|
|
* T0 0xxxxxxx 7 free bits
|
|
|
|
* Tx 10xxxxxx 6 free bits
|
|
|
|
* T1 110xxxxx 5 free bits
|
|
|
|
* T2 1110xxxx 4 free bits
|
|
|
|
*
|
|
|
|
* Encoding is as follows.
|
|
|
|
* From hex Thru hex Sequence Bits
|
|
|
|
* 00000000 0000007F T0 7
|
|
|
|
* 00000080 000007FF T1 Tx 11
|
|
|
|
* 00000800 0000FFFF T2 Tx Tx 16
|
|
|
|
*/
|
|
|
|
|
|
|
|
int
|
|
|
|
mblen(const char *s, size_t n)
|
|
|
|
{
|
|
|
|
|
|
|
|
return mbtowc(0, s, n);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
mbtowc(wchar_t *pwc, const char *s, size_t n)
|
|
|
|
{
|
|
|
|
int c, c1, c2;
|
|
|
|
long l;
|
|
|
|
|
|
|
|
if(!s)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if(n < 1)
|
|
|
|
goto bad;
|
|
|
|
c = s[0] & 0xff;
|
|
|
|
if((c & 0x80) == 0x00) {
|
|
|
|
if(pwc)
|
|
|
|
*pwc = c;
|
|
|
|
if(c == 0)
|
|
|
|
return 0;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(n < 2)
|
|
|
|
goto bad;
|
|
|
|
c1 = (s[1] ^ 0x80) & 0xff;
|
|
|
|
if((c1 & 0xC0) != 0x00)
|
|
|
|
goto bad;
|
|
|
|
if((c & 0xE0) == 0xC0) {
|
|
|
|
l = ((c << 6) | c1) & 0x7FF;
|
|
|
|
if(l < 0x080)
|
|
|
|
goto bad;
|
|
|
|
if(pwc)
|
|
|
|
*pwc = l;
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(n < 3)
|
|
|
|
goto bad;
|
|
|
|
c2 = (s[2] ^ 0x80) & 0xff;
|
|
|
|
if((c2 & 0xC0) != 0x00)
|
|
|
|
goto bad;
|
|
|
|
if((c & 0xF0) == 0xE0) {
|
|
|
|
l = ((((c << 6) | c1) << 6) | c2) & 0xFFFF;
|
|
|
|
if(l < 0x0800)
|
|
|
|
goto bad;
|
|
|
|
if(pwc)
|
|
|
|
*pwc = l;
|
|
|
|
return 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* bad decoding
|
|
|
|
*/
|
|
|
|
bad:
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
wctomb(char *s, wchar_t wchar)
|
|
|
|
{
|
|
|
|
long c;
|
|
|
|
|
|
|
|
if(!s)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
c = wchar & 0xFFFF;
|
|
|
|
if(c < 0x80) {
|
|
|
|
s[0] = c;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(c < 0x800) {
|
|
|
|
s[0] = 0xC0 | (c >> 6);
|
|
|
|
s[1] = 0x80 | (c & 0x3F);
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
s[0] = 0xE0 | (c >> 12);
|
|
|
|
s[1] = 0x80 | ((c >> 6) & 0x3F);
|
|
|
|
s[2] = 0x80 | (c & 0x3F);
|
|
|
|
return 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t
|
|
|
|
mbstowcs(wchar_t *pwcs, const char *s, size_t n)
|
|
|
|
{
|
|
|
|
int i, d, c;
|
|
|
|
|
|
|
|
for(i=0; i < n; i++) {
|
|
|
|
c = *s & 0xff;
|
|
|
|
if(c < 0x80) {
|
|
|
|
*pwcs = c;
|
|
|
|
if(c == 0)
|
|
|
|
break;
|
|
|
|
s++;
|
|
|
|
} else {
|
|
|
|
d = mbtowc(pwcs, s, 3);
|
|
|
|
if(d <= 0)
|
|
|
|
return (size_t)((d<0) ? -1 : i);
|
|
|
|
s += d;
|
|
|
|
}
|
|
|
|
pwcs++;
|
|
|
|
}
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t
|
|
|
|
wcstombs(char *s, const wchar_t *pwcs, size_t n)
|
|
|
|
{
|
2004-05-16 07:55:57 +00:00
|
|
|
int /*i,*/ d;
|
2004-05-15 23:24:00 +00:00
|
|
|
long c;
|
|
|
|
char *p, *pe;
|
|
|
|
char buf[3];
|
|
|
|
|
|
|
|
p = s;
|
|
|
|
pe = p+n-3;
|
|
|
|
while(p < pe) {
|
|
|
|
c = *pwcs++;
|
|
|
|
if(c < 0x80)
|
|
|
|
*p++ = c;
|
|
|
|
else
|
|
|
|
p += wctomb(p, c);
|
|
|
|
if(c == 0)
|
|
|
|
return p-s;
|
|
|
|
}
|
|
|
|
while(p < pe+3) {
|
|
|
|
c = *pwcs++;
|
|
|
|
d = wctomb(buf, c);
|
|
|
|
if(p+d <= pe+3) {
|
|
|
|
*p++ = buf[0];
|
|
|
|
if(d > 1) {
|
|
|
|
*p++ = buf[2];
|
|
|
|
if(d > 2)
|
|
|
|
*p++ = buf[3];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(c == 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return p-s;
|
|
|
|
}
|
|
|
|
|