]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Universal/Console/Terminal/Dxe/vtutf8.c
Updated MSA by putting Specification element at the end of the header section
[mirror_edk2.git] / EdkModulePkg / Universal / Console / Terminal / Dxe / 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 #include "Terminal.h"
24
25 VOID
26 VTUTF8RawDataToUnicode (
27 IN TERMINAL_DEV *TerminalDevice
28 )
29 {
30 UTF8_CHAR Utf8Char;
31 UINT8 ValidBytes;
32 UINT16 UnicodeChar;
33
34 ValidBytes = 0;
35 //
36 // pop the raw data out from the raw fifo,
37 // and translate it into unicode, then push
38 // the unicode into unicode fifo, until the raw fifo is empty.
39 //
40 while (!IsRawFiFoEmpty (TerminalDevice)) {
41
42 GetOneValidUtf8Char (TerminalDevice, &Utf8Char, &ValidBytes);
43
44 if (ValidBytes < 1 || ValidBytes > 3) {
45 continue;
46 }
47
48 Utf8ToUnicode (Utf8Char, ValidBytes, (CHAR16 *) &UnicodeChar);
49
50 UnicodeFiFoInsertOneKey (TerminalDevice, UnicodeChar);
51 }
52 }
53
54 VOID
55 GetOneValidUtf8Char (
56 IN TERMINAL_DEV *Utf8Device,
57 OUT UTF8_CHAR *Utf8Char,
58 OUT UINT8 *ValidBytes
59 )
60 {
61 UINT8 Temp;
62 UINT8 Index;
63 BOOLEAN FetchFlag;
64
65 Temp = 0;
66 Index = 0;
67 FetchFlag = TRUE;
68
69 //
70 // if no valid Utf8 char is found in the RawFiFo,
71 // then *ValidBytes will be zero.
72 //
73 *ValidBytes = 0;
74
75 while (!IsRawFiFoEmpty (Utf8Device)) {
76
77 RawFiFoRemoveOneKey (Utf8Device, &Temp);
78
79 switch (*ValidBytes) {
80
81 case 0:
82 if ((Temp & 0x80) == 0) {
83 //
84 // one-byte utf8 char
85 //
86 *ValidBytes = 1;
87
88 Utf8Char->Utf8_1 = Temp;
89
90 FetchFlag = FALSE;
91
92 } else if ((Temp & 0xe0) == 0xc0) {
93 //
94 // two-byte utf8 char
95 //
96 *ValidBytes = 2;
97
98 Utf8Char->Utf8_2[1] = Temp;
99
100 } else if ((Temp & 0xf0) == 0xe0) {
101 //
102 // three-byte utf8 char
103 //
104 *ValidBytes = 3;
105
106 Utf8Char->Utf8_3[2] = Temp;
107
108 Index++;
109
110 } else {
111 //
112 // reset *ValidBytes to zero, let valid utf8 char search restart
113 //
114 *ValidBytes = 0;
115 }
116
117 break;
118
119 case 2:
120 if ((Temp & 0xc0) == 0x80) {
121
122 Utf8Char->Utf8_2[0] = Temp;
123
124 FetchFlag = FALSE;
125
126 } else {
127
128 *ValidBytes = 0;
129 }
130 break;
131
132 case 3:
133 if ((Temp & 0xc0) == 0x80) {
134
135 Utf8Char->Utf8_3[2 - Index] = Temp;
136 Index++;
137 if (Index == 3) {
138 FetchFlag = FALSE;
139 }
140 } else {
141
142 *ValidBytes = 0;
143 Index = 0;
144 }
145 break;
146
147 default:
148 break;
149 }
150
151 if (!FetchFlag) {
152 break;
153 }
154 }
155
156 return ;
157 }
158
159 VOID
160 Utf8ToUnicode (
161 IN UTF8_CHAR Utf8Char,
162 IN UINT8 ValidBytes,
163 OUT CHAR16 *UnicodeChar
164 )
165 {
166 UINT8 UnicodeByte0;
167 UINT8 UnicodeByte1;
168 UINT8 Byte0;
169 UINT8 Byte1;
170 UINT8 Byte2;
171
172 *UnicodeChar = 0;
173
174 //
175 // translate utf8 code to unicode, in terminal standard,
176 // up to 3 bytes utf8 code is supported.
177 //
178 switch (ValidBytes) {
179 case 1:
180 //
181 // one-byte utf8 code
182 //
183 *UnicodeChar = (UINT16) Utf8Char.Utf8_1;
184 break;
185
186 case 2:
187 //
188 // two-byte utf8 code
189 //
190 Byte0 = Utf8Char.Utf8_2[0];
191 Byte1 = Utf8Char.Utf8_2[1];
192
193 UnicodeByte0 = (UINT8) ((Byte1 << 6) | (Byte0 & 0x3f));
194 UnicodeByte1 = (UINT8) ((Byte1 >> 2) & 0x07);
195 *UnicodeChar = (UINT16) (UnicodeByte0 | (UnicodeByte1 << 8));
196 break;
197
198 case 3:
199 //
200 // three-byte utf8 code
201 //
202 Byte0 = Utf8Char.Utf8_3[0];
203 Byte1 = Utf8Char.Utf8_3[1];
204 Byte2 = Utf8Char.Utf8_3[2];
205
206 UnicodeByte0 = (UINT8) ((Byte1 << 6) | (Byte0 & 0x3f));
207 UnicodeByte1 = (UINT8) ((Byte2 << 4) | ((Byte1 >> 2) & 0x0f));
208 *UnicodeChar = (UINT16) (UnicodeByte0 | (UnicodeByte1 << 8));
209
210 default:
211 break;
212 }
213
214 return ;
215 }
216
217 VOID
218 UnicodeToUtf8 (
219 IN CHAR16 Unicode,
220 OUT UTF8_CHAR *Utf8Char,
221 OUT UINT8 *ValidBytes
222 )
223 {
224 UINT8 UnicodeByte0;
225 UINT8 UnicodeByte1;
226 //
227 // translate unicode to utf8 code
228 //
229 UnicodeByte0 = (UINT8) Unicode;
230 UnicodeByte1 = (UINT8) (Unicode >> 8);
231
232 if (Unicode < 0x0080) {
233
234 Utf8Char->Utf8_1 = (UINT8) (UnicodeByte0 & 0x7f);
235 *ValidBytes = 1;
236
237 } else if (Unicode < 0x0800) {
238 //
239 // byte sequence: high -> low
240 // Utf8_2[0], Utf8_2[1]
241 //
242 Utf8Char->Utf8_2[1] = (UINT8) ((UnicodeByte0 & 0x3f) + 0x80);
243 Utf8Char->Utf8_2[0] = (UINT8) ((((UnicodeByte1 << 2) + (UnicodeByte0 >> 6)) & 0x1f) + 0xc0);
244
245 *ValidBytes = 2;
246
247 } else {
248 //
249 // byte sequence: high -> low
250 // Utf8_3[0], Utf8_3[1], Utf8_3[2]
251 //
252 Utf8Char->Utf8_3[2] = (UINT8) ((UnicodeByte0 & 0x3f) + 0x80);
253 Utf8Char->Utf8_3[1] = (UINT8) ((((UnicodeByte1 << 2) + (UnicodeByte0 >> 6)) & 0x3f) + 0x80);
254 Utf8Char->Utf8_3[0] = (UINT8) (((UnicodeByte1 >> 4) & 0x0f) + 0xe0);
255
256 *ValidBytes = 3;
257 }
258 }
259
260 EFI_STATUS
261 VTUTF8TestString (
262 IN TERMINAL_DEV *TerminalDevice,
263 IN CHAR16 *WString
264 )
265 {
266 //
267 // to utf8, all kind of characters are supported.
268 //
269 return EFI_SUCCESS;
270 }