1 /*
2   partial mbrtowc implementation:
3   - doesn't change *ps
4   - ignores n
5   - s should NOT be NULL
6   - pwc should NOT be NULL
7 */
8 
9 #include "dictP.h"
10 
11 #include <wchar.h>
12 #include <assert.h>
13 
utf8_to_ucs4(const char * ptr,wchar_t * result)14 static const char * utf8_to_ucs4 (
15    const char *ptr, wchar_t *result)
16 {
17    wchar_t ret;
18    int ch;
19    int octet_count;
20    int bits_count;
21    int i;
22 
23    ret = 0;
24 
25    ch = (unsigned char) *ptr++;
26 
27    if ((ch & 0x80) == 0x00){
28       if (result)
29 	 *result = ch;
30    }else{
31       if ((ch & 0xE0) == 0xC0){
32 	 octet_count = 2;
33 	 ch &= ~0xE0;
34       }else if ((ch & 0xF0) == 0xE0){
35 	 octet_count = 3;
36 	 ch &= ~0xF0;
37       }else if ((ch & 0xF8) == 0xF0){
38 	 octet_count = 4;
39 	 ch &= ~0xF8;
40       }else if ((ch & 0xFC) == 0xF8){
41 	 octet_count = 5;
42 	 ch &= ~0xFC;
43       }else if ((ch & 0xFE) == 0xFC){
44 	 octet_count = 6;
45 	 ch &= ~0xFE;
46       }else{
47 	 return NULL;
48       }
49 
50       bits_count = (octet_count-1) * 6;
51       ret |= (ch << bits_count);
52       for (i=1; i < octet_count; ++i){
53 	 bits_count -= 6;
54 
55 	 ch = (unsigned char) *ptr++;
56 	 if ((ch & 0xC0) != 0x80){
57 	    return NULL;
58 	 }
59 
60 	 ret |= ((ch & 0x3F) << bits_count);
61       }
62 
63       if (result)
64 	 *result = ret;
65    }
66 
67    return ptr;
68 }
69 
mbrtowc__(wchar_t * pwc,const char * s,size_t n,mbstate_t * ps)70 size_t mbrtowc__ (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
71 {
72    const char *end;
73 
74    assert (s);
75    assert (pwc);
76    assert (MB_CUR_MAX__ > 1);
77 
78    end = utf8_to_ucs4 (s, pwc);
79    if (end)
80       return end - s;
81    else
82       return (size_t) -1;
83 }
84