Check in following modules,
[mirror_edk2.git] / MdeModulePkg / Universal / Console / TerminalDxe / vtutf8.c
1 /*++
2
3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 vtutf8.c
15
16 Abstract:
17
18
19 Revision History
20 --*/
21
22
23 //
24 // Include common header file for this module.
25 //
26 #include "CommonHeader.h"
27
28 #include "Terminal.h"
29
30 VOID
31 VTUTF8RawDataToUnicode (
32 IN TERMINAL_DEV *TerminalDevice
33 )
34 {
35 UTF8_CHAR Utf8Char;
36 UINT8 ValidBytes;
37 UINT16 UnicodeChar;
38
39 ValidBytes = 0;
40 //
41 // pop the raw data out from the raw fifo,
42 // and translate it into unicode, then push
43 // the unicode into unicode fifo, until the raw fifo is empty.
44 //
45 while (!IsRawFiFoEmpty (TerminalDevice)) {
46
47 GetOneValidUtf8Char (TerminalDevice, &Utf8Char, &ValidBytes);
48
49 if (ValidBytes < 1 || ValidBytes > 3) {
50 continue;
51 }
52
53 Utf8ToUnicode (Utf8Char, ValidBytes, (CHAR16 *) &UnicodeChar);
54
55 UnicodeFiFoInsertOneKey (TerminalDevice, UnicodeChar);
56 }
57 }
58
59 VOID
60 GetOneValidUtf8Char (
61 IN TERMINAL_DEV *Utf8Device,
62 OUT UTF8_CHAR *Utf8Char,
63 OUT UINT8 *ValidBytes
64 )
65 {
66 UINT8 Temp;
67 UINT8 Index;
68 BOOLEAN FetchFlag;
69
70 Temp = 0;
71 Index = 0;
72 FetchFlag = TRUE;
73
74 //
75 // if no valid Utf8 char is found in the RawFiFo,
76 // then *ValidBytes will be zero.
77 //
78 *ValidBytes = 0;
79
80 while (!IsRawFiFoEmpty (Utf8Device)) {
81
82 RawFiFoRemoveOneKey (Utf8Device, &Temp);
83
84 switch (*ValidBytes) {
85
86 case 0:
87 if ((Temp & 0x80) == 0) {
88 //
89 // one-byte utf8 char
90 //
91 *ValidBytes = 1;
92
93 Utf8Char->Utf8_1 = Temp;
94
95 FetchFlag = FALSE;
96
97 } else if ((Temp & 0xe0) == 0xc0) {
98 //
99 // two-byte utf8 char
100 //
101 *ValidBytes = 2;
102
103 Utf8Char->Utf8_2[1] = Temp;
104
105 } else if ((Temp & 0xf0) == 0xe0) {
106 //
107 // three-byte utf8 char
108 //
109 *ValidBytes = 3;
110
111 Utf8Char->Utf8_3[2] = Temp;
112
113 Index++;
114
115 } else {
116 //
117 // reset *ValidBytes to zero, let valid utf8 char search restart
118 //
119 *ValidBytes = 0;
120 }
121
122 break;
123
124 case 2:
125 if ((Temp & 0xc0) == 0x80) {
126
127 Utf8Char->Utf8_2[0] = Temp;
128
129 FetchFlag = FALSE;
130
131 } else {
132
133 *ValidBytes = 0;
134 }
135 break;
136
137 case 3:
138 if ((Temp & 0xc0) == 0x80) {
139
140 Utf8Char->Utf8_3[2 - Index] = Temp;
141 Index++;
142 if (Index == 3) {
143 FetchFlag = FALSE;
144 }
145 } else {
146
147 *ValidBytes = 0;
148 Index = 0;
149 }
150 break;
151
152 default:
153 break;
154 }
155
156 if (!FetchFlag) {
157 break;
158 }
159 }
160
161 return ;
162 }
163
164 VOID
165 Utf8ToUnicode (
166 IN UTF8_CHAR Utf8Char,
167 IN UINT8 ValidBytes,
168 OUT CHAR16 *UnicodeChar
169 )
170 {
171 UINT8 UnicodeByte0;
172 UINT8 UnicodeByte1;
173 UINT8 Byte0;
174 UINT8 Byte1;
175 UINT8 Byte2;
176
177 *UnicodeChar = 0;
178
179 //
180 // translate utf8 code to unicode, in terminal standard,
181 // up to 3 bytes utf8 code is supported.
182 //
183 switch (ValidBytes) {
184 case 1:
185 //
186 // one-byte utf8 code
187 //
188 *UnicodeChar = (UINT16) Utf8Char.Utf8_1;
189 break;
190
191 case 2:
192 //
193 // two-byte utf8 code
194 //
195 Byte0 = Utf8Char.Utf8_2[0];
196 Byte1 = Utf8Char.Utf8_2[1];
197
198 UnicodeByte0 = (UINT8) ((Byte1 << 6) | (Byte0 & 0x3f));
199 UnicodeByte1 = (UINT8) ((Byte1 >> 2) & 0x07);
200 *UnicodeChar = (UINT16) (UnicodeByte0 | (UnicodeByte1 << 8));
201 break;
202
203 case 3:
204 //
205 // three-byte utf8 code
206 //
207 Byte0 = Utf8Char.Utf8_3[0];
208 Byte1 = Utf8Char.Utf8_3[1];
209 Byte2 = Utf8Char.Utf8_3[2];
210
211 UnicodeByte0 = (UINT8) ((Byte1 << 6) | (Byte0 & 0x3f));
212 UnicodeByte1 = (UINT8) ((Byte2 << 4) | ((Byte1 >> 2) & 0x0f));
213 *UnicodeChar = (UINT16) (UnicodeByte0 | (UnicodeByte1 << 8));
214
215 default:
216 break;
217 }
218
219 return ;
220 }
221
222 VOID
223 UnicodeToUtf8 (
224 IN CHAR16 Unicode,
225 OUT UTF8_CHAR *Utf8Char,
226 OUT UINT8 *ValidBytes
227 )
228 {
229 UINT8 UnicodeByte0;
230 UINT8 UnicodeByte1;
231 //
232 // translate unicode to utf8 code
233 //
234 UnicodeByte0 = (UINT8) Unicode;
235 UnicodeByte1 = (UINT8) (Unicode >> 8);
236
237 if (Unicode < 0x0080) {
238
239 Utf8Char->Utf8_1 = (UINT8) (UnicodeByte0 & 0x7f);
240 *ValidBytes = 1;
241
242 } else if (Unicode < 0x0800) {
243 //
244 // byte sequence: high -> low
245 // Utf8_2[0], Utf8_2[1]
246 //
247 Utf8Char->Utf8_2[1] = (UINT8) ((UnicodeByte0 & 0x3f) + 0x80);
248 Utf8Char->Utf8_2[0] = (UINT8) ((((UnicodeByte1 << 2) + (UnicodeByte0 >> 6)) & 0x1f) + 0xc0);
249
250 *ValidBytes = 2;
251
252 } else {
253 //
254 // byte sequence: high -> low
255 // Utf8_3[0], Utf8_3[1], Utf8_3[2]
256 //
257 Utf8Char->Utf8_3[2] = (UINT8) ((UnicodeByte0 & 0x3f) + 0x80);
258 Utf8Char->Utf8_3[1] = (UINT8) ((((UnicodeByte1 << 2) + (UnicodeByte0 >> 6)) & 0x3f) + 0x80);
259 Utf8Char->Utf8_3[0] = (UINT8) (((UnicodeByte1 >> 4) & 0x0f) + 0xe0);
260
261 *ValidBytes = 3;
262 }
263 }
264
265 EFI_STATUS
266 VTUTF8TestString (
267 IN TERMINAL_DEV *TerminalDevice,
268 IN CHAR16 *WString
269 )
270 {
271 //
272 // to utf8, all kind of characters are supported.
273 //
274 return EFI_SUCCESS;
275 }