utf8.c
1.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include "c_def.h"
#include "oem.h"
#include "debug.h"
#if 1//def IPOD_USB_AUDIO
#define MAX_RANGES 6
U8 utf8Byte0Range[MAX_RANGES] = {
0x7F, //1 byte
0xc0, //2 byte -
0xe0, //3 byte -
0xf0, //4 byte
0xf8, //5
0xfc //6
};
//don't do much check
static int getSize( U8 *utf8 )
{
int i;
for( i = 1; i < MAX_RANGES; i ++ ) {
if( utf8[0] < utf8Byte0Range[i] ) break;
}
if( (i == 1 ) && (utf8[0] > utf8Byte0Range[0]) ) i = 100; //make it err
return i;
}
//bigEndian
static U16 decodeWord( U8 **utf8 )
{
U8 *ptr = *utf8;
int size;
U16 tmp;
size = getSize( ptr );
switch( size ) {
case 1:
tmp = ptr[0];
*utf8 += 1;
break;
case 2:
tmp = ptr[0] & 0x1f;
tmp <<= 6;
tmp |= ptr[1] & 0x3f;
*utf8 += 2;
break;
case 3:
tmp = ptr[0] & 0x0f;
tmp <<= 6;
tmp |= ptr[1] & 0x3f;
tmp <<= 6;
tmp |= ptr[2] & 0x3f;
*utf8 += 3;
break;
default:
//err
tmp = 0;
}
return tmp;
}
//len is size in bytes
//maxlen/len16 is size in U16
//len16 include terminal null \0\0
int utf8_toUcs16( U8 *utf8, int len, U16 *ucs16, int maxlen )
{
int len16 = 0;
U16 t16;
U8 *ptr = utf8;
do {
t16 = decodeWord( &ptr );
if (t16 == 0)
{
break;
}
*ucs16 ++ = t16;
#if 0
if( ++len16 >= maxlen ) {
--ucs16;
*ucs16 = 0;
break;
}
#else
if( len16 > maxlen ) {
*ucs16 = 0;
break;
}
len16++;
#endif
} while( t16 != 0 );
#if 1
return len16;
#else
if (len16 > 0)
{
len16 -= 1;
}
return len16;
#endif
}
#endif //IPOD_USB_AUDIO