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