]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Console/TerminalDxe/Vtutf8.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / Console / TerminalDxe / Vtutf8.c
CommitLineData
4bc6ad39
RN
1/** @file\r
2 Implementation of translation upon VT-UTF8.\r
3\r
d1102dba 4Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
4bc6ad39
RN
6\r
7**/\r
8\r
9#include "Terminal.h"\r
10\r
11/**\r
12 Translate all VT-UTF8 characters in the Raw FIFI into unicode characters,\r
13 and insert them into Unicode FIFO.\r
14\r
15 @param TerminalDevice The terminal device.\r
16\r
17**/\r
18VOID\r
19VTUTF8RawDataToUnicode (\r
20 IN TERMINAL_DEV *TerminalDevice\r
21 )\r
22{\r
23 UTF8_CHAR Utf8Char;\r
24 UINT8 ValidBytes;\r
25 UINT16 UnicodeChar;\r
26\r
27 ValidBytes = 0;\r
28 //\r
29 // pop the raw data out from the raw fifo,\r
30 // and translate it into unicode, then push\r
31 // the unicode into unicode fifo, until the raw fifo is empty.\r
32 //\r
33 while (!IsRawFiFoEmpty (TerminalDevice) && !IsUnicodeFiFoFull (TerminalDevice)) {\r
34\r
35 GetOneValidUtf8Char (TerminalDevice, &Utf8Char, &ValidBytes);\r
36\r
37 if (ValidBytes < 1 || ValidBytes > 3) {\r
38 continue;\r
39 }\r
40\r
41 Utf8ToUnicode (Utf8Char, ValidBytes, (CHAR16 *) &UnicodeChar);\r
42\r
43 UnicodeFiFoInsertOneKey (TerminalDevice, UnicodeChar);\r
44 }\r
45}\r
46\r
47/**\r
48 Get one valid VT-UTF8 characters set from Raw Data FIFO.\r
49\r
50 @param Utf8Device The terminal device.\r
51 @param Utf8Char Returned valid VT-UTF8 characters set.\r
52 @param ValidBytes The count of returned VT-VTF8 characters.\r
53 If ValidBytes is zero, no valid VT-UTF8 returned.\r
54\r
55**/\r
56VOID\r
57GetOneValidUtf8Char (\r
58 IN TERMINAL_DEV *Utf8Device,\r
59 OUT UTF8_CHAR *Utf8Char,\r
60 OUT UINT8 *ValidBytes\r
61 )\r
62{\r
63 UINT8 Temp;\r
64 UINT8 Index;\r
65 BOOLEAN FetchFlag;\r
66\r
67 Temp = 0;\r
68 Index = 0;\r
69 FetchFlag = TRUE;\r
70\r
71 //\r
72 // if no valid Utf8 char is found in the RawFiFo,\r
73 // then *ValidBytes will be zero.\r
74 //\r
75 *ValidBytes = 0;\r
76\r
77 while (!IsRawFiFoEmpty (Utf8Device)) {\r
78\r
79 RawFiFoRemoveOneKey (Utf8Device, &Temp);\r
80\r
81 switch (*ValidBytes) {\r
82\r
83 case 0:\r
84 if ((Temp & 0x80) == 0) {\r
85 //\r
86 // one-byte utf8 char\r
87 //\r
88 *ValidBytes = 1;\r
89\r
90 Utf8Char->Utf8_1 = Temp;\r
91\r
92 FetchFlag = FALSE;\r
93\r
94 } else if ((Temp & 0xe0) == 0xc0) {\r
95 //\r
96 // two-byte utf8 char\r
97 //\r
98 *ValidBytes = 2;\r
99\r
100 Utf8Char->Utf8_2[1] = Temp;\r
101\r
102 } else if ((Temp & 0xf0) == 0xe0) {\r
103 //\r
104 // three-byte utf8 char\r
105 //\r
106 *ValidBytes = 3;\r
107\r
108 Utf8Char->Utf8_3[2] = Temp;\r
109\r
110 Index++;\r
111\r
112 } else {\r
113 //\r
114 // reset *ValidBytes to zero, let valid utf8 char search restart\r
115 //\r
116 *ValidBytes = 0;\r
117 }\r
118\r
119 break;\r
120\r
121 case 2:\r
122 //\r
123 // two-byte utf8 char go on\r
124 //\r
125 if ((Temp & 0xc0) == 0x80) {\r
126\r
127 Utf8Char->Utf8_2[0] = Temp;\r
128\r
129 FetchFlag = FALSE;\r
130\r
131 } else {\r
132\r
133 *ValidBytes = 0;\r
134 }\r
135 break;\r
136\r
137 case 3:\r
138 //\r
139 // three-byte utf8 char go on\r
140 //\r
141 if ((Temp & 0xc0) == 0x80) {\r
142 if (Index == 1) {\r
143 Utf8Char->Utf8_3[1] = Temp;\r
144 Index++;\r
145 } else {\r
146 Utf8Char->Utf8_3[0] = Temp;\r
147 FetchFlag = FALSE;\r
148 }\r
149 } else {\r
150 //\r
151 // reset *ValidBytes and Index to zero, let valid utf8 char search restart\r
152 //\r
153 *ValidBytes = 0;\r
154 Index = 0;\r
155 }\r
156 break;\r
157\r
158 default:\r
159 break;\r
160 }\r
161\r
162 if (!FetchFlag) {\r
163 break;\r
164 }\r
165 }\r
166\r
167 return ;\r
168}\r
169\r
170/**\r
171 Translate VT-UTF8 characters into one Unicode character.\r
172\r
173 UTF8 Encoding Table\r
d1102dba
LG
174 Bits per Character | Unicode Character Range | Unicode Binary Encoding | UTF8 Binary Encoding\r
175 0-7 | 0x0000 - 0x007F | 00000000 0xxxxxxx | 0xxxxxxx\r
176 8-11 | 0x0080 - 0x07FF | 00000xxx xxxxxxxx | 110xxxxx 10xxxxxx\r
177 12-16 | 0x0800 - 0xFFFF | xxxxxxxx xxxxxxxx | 1110xxxx 10xxxxxx 10xxxxxx\r
4bc6ad39
RN
178\r
179\r
180 @param Utf8Char VT-UTF8 character set needs translating.\r
181 @param ValidBytes The count of valid VT-UTF8 characters.\r
182 @param UnicodeChar Returned unicode character.\r
183\r
184**/\r
185VOID\r
186Utf8ToUnicode (\r
187 IN UTF8_CHAR Utf8Char,\r
188 IN UINT8 ValidBytes,\r
189 OUT CHAR16 *UnicodeChar\r
190 )\r
191{\r
192 UINT8 UnicodeByte0;\r
193 UINT8 UnicodeByte1;\r
194 UINT8 Byte0;\r
195 UINT8 Byte1;\r
196 UINT8 Byte2;\r
197\r
198 *UnicodeChar = 0;\r
199\r
200 //\r
201 // translate utf8 code to unicode, in terminal standard,\r
202 // up to 3 bytes utf8 code is supported.\r
203 //\r
204 switch (ValidBytes) {\r
205 case 1:\r
206 //\r
207 // one-byte utf8 code\r
208 //\r
209 *UnicodeChar = (UINT16) Utf8Char.Utf8_1;\r
210 break;\r
211\r
212 case 2:\r
213 //\r
214 // two-byte utf8 code\r
215 //\r
216 Byte0 = Utf8Char.Utf8_2[0];\r
217 Byte1 = Utf8Char.Utf8_2[1];\r
218\r
219 UnicodeByte0 = (UINT8) ((Byte1 << 6) | (Byte0 & 0x3f));\r
220 UnicodeByte1 = (UINT8) ((Byte1 >> 2) & 0x07);\r
221 *UnicodeChar = (UINT16) (UnicodeByte0 | (UnicodeByte1 << 8));\r
222 break;\r
223\r
224 case 3:\r
225 //\r
226 // three-byte utf8 code\r
227 //\r
228 Byte0 = Utf8Char.Utf8_3[0];\r
229 Byte1 = Utf8Char.Utf8_3[1];\r
230 Byte2 = Utf8Char.Utf8_3[2];\r
231\r
232 UnicodeByte0 = (UINT8) ((Byte1 << 6) | (Byte0 & 0x3f));\r
233 UnicodeByte1 = (UINT8) ((Byte2 << 4) | ((Byte1 >> 2) & 0x0f));\r
234 *UnicodeChar = (UINT16) (UnicodeByte0 | (UnicodeByte1 << 8));\r
235\r
236 default:\r
237 break;\r
238 }\r
239\r
240 return ;\r
241}\r
242\r
243/**\r
244 Translate one Unicode character into VT-UTF8 characters.\r
245\r
246 UTF8 Encoding Table\r
d1102dba
LG
247 Bits per Character | Unicode Character Range | Unicode Binary Encoding | UTF8 Binary Encoding\r
248 0-7 | 0x0000 - 0x007F | 00000000 0xxxxxxx | 0xxxxxxx\r
249 8-11 | 0x0080 - 0x07FF | 00000xxx xxxxxxxx | 110xxxxx 10xxxxxx\r
250 12-16 | 0x0800 - 0xFFFF | xxxxxxxx xxxxxxxx | 1110xxxx 10xxxxxx 10xxxxxx\r
4bc6ad39
RN
251\r
252\r
253 @param Unicode Unicode character need translating.\r
254 @param Utf8Char Return VT-UTF8 character set.\r
255 @param ValidBytes The count of valid VT-UTF8 characters. If\r
256 ValidBytes is zero, no valid VT-UTF8 returned.\r
257\r
258**/\r
259VOID\r
260UnicodeToUtf8 (\r
261 IN CHAR16 Unicode,\r
262 OUT UTF8_CHAR *Utf8Char,\r
263 OUT UINT8 *ValidBytes\r
264 )\r
265{\r
266 UINT8 UnicodeByte0;\r
267 UINT8 UnicodeByte1;\r
268 //\r
269 // translate unicode to utf8 code\r
270 //\r
271 UnicodeByte0 = (UINT8) Unicode;\r
272 UnicodeByte1 = (UINT8) (Unicode >> 8);\r
273\r
274 if (Unicode < 0x0080) {\r
275\r
276 Utf8Char->Utf8_1 = (UINT8) (UnicodeByte0 & 0x7f);\r
277 *ValidBytes = 1;\r
278\r
279 } else if (Unicode < 0x0800) {\r
280 //\r
281 // byte sequence: high -> low\r
282 // Utf8_2[0], Utf8_2[1]\r
283 //\r
284 Utf8Char->Utf8_2[1] = (UINT8) ((UnicodeByte0 & 0x3f) + 0x80);\r
285 Utf8Char->Utf8_2[0] = (UINT8) ((((UnicodeByte1 << 2) + (UnicodeByte0 >> 6)) & 0x1f) + 0xc0);\r
286\r
287 *ValidBytes = 2;\r
288\r
289 } else {\r
290 //\r
291 // byte sequence: high -> low\r
292 // Utf8_3[0], Utf8_3[1], Utf8_3[2]\r
293 //\r
294 Utf8Char->Utf8_3[2] = (UINT8) ((UnicodeByte0 & 0x3f) + 0x80);\r
295 Utf8Char->Utf8_3[1] = (UINT8) ((((UnicodeByte1 << 2) + (UnicodeByte0 >> 6)) & 0x3f) + 0x80);\r
296 Utf8Char->Utf8_3[0] = (UINT8) (((UnicodeByte1 >> 4) & 0x0f) + 0xe0);\r
297\r
298 *ValidBytes = 3;\r
299 }\r
300}\r
301\r
302\r
303/**\r
304 Check if input string is valid VT-UTF8 string.\r
305\r
306 @param TerminalDevice The terminal device.\r
307 @param WString The input string.\r
308\r
309 @retval EFI_SUCCESS If all input characters are valid.\r
310\r
311**/\r
312EFI_STATUS\r
313VTUTF8TestString (\r
314 IN TERMINAL_DEV *TerminalDevice,\r
315 IN CHAR16 *WString\r
316 )\r
317{\r
318 //\r
319 // to utf8, all kind of characters are supported.\r
320 //\r
321 return EFI_SUCCESS;\r
322}\r