]>
glassweightruler.freedombox.rocks Git - Ventoy.git/blob - LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/utf.c
3 exFAT file system implementation library.
5 Free exFAT implementation.
6 Copyright (C) 2010-2018 Andrew Nayenko
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 static char* wchar_to_utf8(char* output
, wchar_t wc
, size_t outsize
)
32 *output
++ = (char) wc
;
38 *output
++ = 0xc0 | (wc
>> 6);
39 *output
++ = 0x80 | (wc
& 0x3f);
41 else if (wc
<= 0xffff)
45 *output
++ = 0xe0 | (wc
>> 12);
46 *output
++ = 0x80 | ((wc
>> 6) & 0x3f);
47 *output
++ = 0x80 | (wc
& 0x3f);
49 else if (wc
<= 0x1fffff)
53 *output
++ = 0xf0 | (wc
>> 18);
54 *output
++ = 0x80 | ((wc
>> 12) & 0x3f);
55 *output
++ = 0x80 | ((wc
>> 6) & 0x3f);
56 *output
++ = 0x80 | (wc
& 0x3f);
58 else if (wc
<= 0x3ffffff)
62 *output
++ = 0xf8 | (wc
>> 24);
63 *output
++ = 0x80 | ((wc
>> 18) & 0x3f);
64 *output
++ = 0x80 | ((wc
>> 12) & 0x3f);
65 *output
++ = 0x80 | ((wc
>> 6) & 0x3f);
66 *output
++ = 0x80 | (wc
& 0x3f);
68 else if (wc
<= 0x7fffffff)
72 *output
++ = 0xfc | (wc
>> 30);
73 *output
++ = 0x80 | ((wc
>> 24) & 0x3f);
74 *output
++ = 0x80 | ((wc
>> 18) & 0x3f);
75 *output
++ = 0x80 | ((wc
>> 12) & 0x3f);
76 *output
++ = 0x80 | ((wc
>> 6) & 0x3f);
77 *output
++ = 0x80 | (wc
& 0x3f);
85 static const le16_t
* utf16_to_wchar(const le16_t
* input
, wchar_t* wc
,
88 if ((le16_to_cpu(input
[0]) & 0xfc00) == 0xd800)
90 if (insize
< 2 || (le16_to_cpu(input
[1]) & 0xfc00) != 0xdc00)
92 *wc
= ((wchar_t) (le16_to_cpu(input
[0]) & 0x3ff) << 10);
93 *wc
|= (le16_to_cpu(input
[1]) & 0x3ff);
99 *wc
= le16_to_cpu(*input
);
104 int utf16_to_utf8(char* output
, const le16_t
* input
, size_t outsize
,
107 const le16_t
* inp
= input
;
111 while (inp
- input
< insize
)
113 inp
= utf16_to_wchar(inp
, &wc
, insize
- (inp
- input
));
116 exfat_error("illegal UTF-16 sequence");
119 outp
= wchar_to_utf8(outp
, wc
, outsize
- (outp
- output
));
122 exfat_error("name is too long");
123 return -ENAMETOOLONG
;
128 if (outp
- output
>= outsize
)
130 exfat_error("name is too long");
131 return -ENAMETOOLONG
;
137 static const char* utf8_to_wchar(const char* input
, wchar_t* wc
,
140 if ((input
[0] & 0x80) == 0 && insize
>= 1)
142 *wc
= (wchar_t) input
[0];
145 if ((input
[0] & 0xe0) == 0xc0 && insize
>= 2)
147 *wc
= (((wchar_t) input
[0] & 0x1f) << 6) |
148 ((wchar_t) input
[1] & 0x3f);
151 if ((input
[0] & 0xf0) == 0xe0 && insize
>= 3)
153 *wc
= (((wchar_t) input
[0] & 0x0f) << 12) |
154 (((wchar_t) input
[1] & 0x3f) << 6) |
155 ((wchar_t) input
[2] & 0x3f);
158 if ((input
[0] & 0xf8) == 0xf0 && insize
>= 4)
160 *wc
= (((wchar_t) input
[0] & 0x07) << 18) |
161 (((wchar_t) input
[1] & 0x3f) << 12) |
162 (((wchar_t) input
[2] & 0x3f) << 6) |
163 ((wchar_t) input
[3] & 0x3f);
166 if ((input
[0] & 0xfc) == 0xf8 && insize
>= 5)
168 *wc
= (((wchar_t) input
[0] & 0x03) << 24) |
169 (((wchar_t) input
[1] & 0x3f) << 18) |
170 (((wchar_t) input
[2] & 0x3f) << 12) |
171 (((wchar_t) input
[3] & 0x3f) << 6) |
172 ((wchar_t) input
[4] & 0x3f);
175 if ((input
[0] & 0xfe) == 0xfc && insize
>= 6)
177 *wc
= (((wchar_t) input
[0] & 0x01) << 30) |
178 (((wchar_t) input
[1] & 0x3f) << 24) |
179 (((wchar_t) input
[2] & 0x3f) << 18) |
180 (((wchar_t) input
[3] & 0x3f) << 12) |
181 (((wchar_t) input
[4] & 0x3f) << 6) |
182 ((wchar_t) input
[5] & 0x3f);
188 static le16_t
* wchar_to_utf16(le16_t
* output
, wchar_t wc
, size_t outsize
)
190 if (wc
<= 0xffff) /* if character is from BMP */
194 output
[0] = cpu_to_le16(wc
);
200 output
[0] = cpu_to_le16(0xd800 | ((wc
>> 10) & 0x3ff));
201 output
[1] = cpu_to_le16(0xdc00 | (wc
& 0x3ff));
205 int utf8_to_utf16(le16_t
* output
, const char* input
, size_t outsize
,
208 const char* inp
= input
;
209 le16_t
* outp
= output
;
212 while (inp
- input
< insize
)
214 inp
= utf8_to_wchar(inp
, &wc
, insize
- (inp
- input
));
217 exfat_error("illegal UTF-8 sequence");
220 outp
= wchar_to_utf16(outp
, wc
, outsize
- (outp
- output
));
223 exfat_error("name is too long");
224 return -ENAMETOOLONG
;
229 if (outp
- output
>= outsize
)
231 exfat_error("name is too long");
232 return -ENAMETOOLONG
;
234 *outp
= cpu_to_le16(0);
238 size_t utf16_length(const le16_t
* str
)
242 while (le16_to_cpu(str
[i
]))