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