| /** @file | |
| Implementation of translation upon VT-UTF8. | |
| Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR> | |
| This program and the accompanying materials | |
| are licensed and made available under the terms and conditions of the BSD License | |
| which accompanies this distribution. The full text of the license may be found at | |
| http://opensource.org/licenses/bsd-license.php | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| **/ | |
| #include "Terminal.h" | |
| /** | |
| Translate all VT-UTF8 characters in the Raw FIFI into unicode characters, | |
| and insert them into Unicode FIFO. | |
| @param TerminalDevice The terminal device. | |
| **/ | |
| VOID | |
| VTUTF8RawDataToUnicode ( | |
| IN TERMINAL_DEV *TerminalDevice | |
| ) | |
| { | |
| UTF8_CHAR Utf8Char; | |
| UINT8 ValidBytes; | |
| UINT16 UnicodeChar; | |
| ValidBytes = 0; | |
| // | |
| // pop the raw data out from the raw fifo, | |
| // and translate it into unicode, then push | |
| // the unicode into unicode fifo, until the raw fifo is empty. | |
| // | |
| while (!IsRawFiFoEmpty (TerminalDevice) && !IsUnicodeFiFoFull (TerminalDevice)) { | |
| GetOneValidUtf8Char (TerminalDevice, &Utf8Char, &ValidBytes); | |
| if (ValidBytes < 1 || ValidBytes > 3) { | |
| continue; | |
| } | |
| Utf8ToUnicode (Utf8Char, ValidBytes, (CHAR16 *) &UnicodeChar); | |
| UnicodeFiFoInsertOneKey (TerminalDevice, UnicodeChar); | |
| } | |
| } | |
| /** | |
| Get one valid VT-UTF8 characters set from Raw Data FIFO. | |
| @param Utf8Device The terminal device. | |
| @param Utf8Char Returned valid VT-UTF8 characters set. | |
| @param ValidBytes The count of returned VT-VTF8 characters. | |
| If ValidBytes is zero, no valid VT-UTF8 returned. | |
| **/ | |
| VOID | |
| GetOneValidUtf8Char ( | |
| IN TERMINAL_DEV *Utf8Device, | |
| OUT UTF8_CHAR *Utf8Char, | |
| OUT UINT8 *ValidBytes | |
| ) | |
| { | |
| UINT8 Temp; | |
| UINT8 Index; | |
| BOOLEAN FetchFlag; | |
| Temp = 0; | |
| Index = 0; | |
| FetchFlag = TRUE; | |
| // | |
| // if no valid Utf8 char is found in the RawFiFo, | |
| // then *ValidBytes will be zero. | |
| // | |
| *ValidBytes = 0; | |
| while (!IsRawFiFoEmpty (Utf8Device)) { | |
| RawFiFoRemoveOneKey (Utf8Device, &Temp); | |
| switch (*ValidBytes) { | |
| case 0: | |
| if ((Temp & 0x80) == 0) { | |
| // | |
| // one-byte utf8 char | |
| // | |
| *ValidBytes = 1; | |
| Utf8Char->Utf8_1 = Temp; | |
| FetchFlag = FALSE; | |
| } else if ((Temp & 0xe0) == 0xc0) { | |
| // | |
| // two-byte utf8 char | |
| // | |
| *ValidBytes = 2; | |
| Utf8Char->Utf8_2[1] = Temp; | |
| } else if ((Temp & 0xf0) == 0xe0) { | |
| // | |
| // three-byte utf8 char | |
| // | |
| *ValidBytes = 3; | |
| Utf8Char->Utf8_3[2] = Temp; | |
| Index++; | |
| } else { | |
| // | |
| // reset *ValidBytes to zero, let valid utf8 char search restart | |
| // | |
| *ValidBytes = 0; | |
| } | |
| break; | |
| case 2: | |
| // | |
| // two-byte utf8 char go on | |
| // | |
| if ((Temp & 0xc0) == 0x80) { | |
| Utf8Char->Utf8_2[0] = Temp; | |
| FetchFlag = FALSE; | |
| } else { | |
| *ValidBytes = 0; | |
| } | |
| break; | |
| case 3: | |
| // | |
| // three-byte utf8 char go on | |
| // | |
| if ((Temp & 0xc0) == 0x80) { | |
| if (Index == 1) { | |
| Utf8Char->Utf8_3[1] = Temp; | |
| Index++; | |
| } else { | |
| Utf8Char->Utf8_3[0] = Temp; | |
| FetchFlag = FALSE; | |
| } | |
| } else { | |
| // | |
| // reset *ValidBytes and Index to zero, let valid utf8 char search restart | |
| // | |
| *ValidBytes = 0; | |
| Index = 0; | |
| } | |
| break; | |
| default: | |
| break; | |
| } | |
| if (!FetchFlag) { | |
| break; | |
| } | |
| } | |
| return ; | |
| } | |
| /** | |
| Translate VT-UTF8 characters into one Unicode character. | |
| UTF8 Encoding Table | |
| Bits per Character | Unicode Character Range | Unicode Binary Encoding | UTF8 Binary Encoding | |
| 0-7 | 0x0000 - 0x007F | 00000000 0xxxxxxx | 0xxxxxxx | |
| 8-11 | 0x0080 - 0x07FF | 00000xxx xxxxxxxx | 110xxxxx 10xxxxxx | |
| 12-16 | 0x0800 - 0xFFFF | xxxxxxxx xxxxxxxx | 1110xxxx 10xxxxxx 10xxxxxx | |
| @param Utf8Char VT-UTF8 character set needs translating. | |
| @param ValidBytes The count of valid VT-UTF8 characters. | |
| @param UnicodeChar Returned unicode character. | |
| **/ | |
| VOID | |
| Utf8ToUnicode ( | |
| IN UTF8_CHAR Utf8Char, | |
| IN UINT8 ValidBytes, | |
| OUT CHAR16 *UnicodeChar | |
| ) | |
| { | |
| UINT8 UnicodeByte0; | |
| UINT8 UnicodeByte1; | |
| UINT8 Byte0; | |
| UINT8 Byte1; | |
| UINT8 Byte2; | |
| *UnicodeChar = 0; | |
| // | |
| // translate utf8 code to unicode, in terminal standard, | |
| // up to 3 bytes utf8 code is supported. | |
| // | |
| switch (ValidBytes) { | |
| case 1: | |
| // | |
| // one-byte utf8 code | |
| // | |
| *UnicodeChar = (UINT16) Utf8Char.Utf8_1; | |
| break; | |
| case 2: | |
| // | |
| // two-byte utf8 code | |
| // | |
| Byte0 = Utf8Char.Utf8_2[0]; | |
| Byte1 = Utf8Char.Utf8_2[1]; | |
| UnicodeByte0 = (UINT8) ((Byte1 << 6) | (Byte0 & 0x3f)); | |
| UnicodeByte1 = (UINT8) ((Byte1 >> 2) & 0x07); | |
| *UnicodeChar = (UINT16) (UnicodeByte0 | (UnicodeByte1 << 8)); | |
| break; | |
| case 3: | |
| // | |
| // three-byte utf8 code | |
| // | |
| Byte0 = Utf8Char.Utf8_3[0]; | |
| Byte1 = Utf8Char.Utf8_3[1]; | |
| Byte2 = Utf8Char.Utf8_3[2]; | |
| UnicodeByte0 = (UINT8) ((Byte1 << 6) | (Byte0 & 0x3f)); | |
| UnicodeByte1 = (UINT8) ((Byte2 << 4) | ((Byte1 >> 2) & 0x0f)); | |
| *UnicodeChar = (UINT16) (UnicodeByte0 | (UnicodeByte1 << 8)); | |
| default: | |
| break; | |
| } | |
| return ; | |
| } | |
| /** | |
| Translate one Unicode character into VT-UTF8 characters. | |
| UTF8 Encoding Table | |
| Bits per Character | Unicode Character Range | Unicode Binary Encoding | UTF8 Binary Encoding | |
| 0-7 | 0x0000 - 0x007F | 00000000 0xxxxxxx | 0xxxxxxx | |
| 8-11 | 0x0080 - 0x07FF | 00000xxx xxxxxxxx | 110xxxxx 10xxxxxx | |
| 12-16 | 0x0800 - 0xFFFF | xxxxxxxx xxxxxxxx | 1110xxxx 10xxxxxx 10xxxxxx | |
| @param Unicode Unicode character need translating. | |
| @param Utf8Char Return VT-UTF8 character set. | |
| @param ValidBytes The count of valid VT-UTF8 characters. If | |
| ValidBytes is zero, no valid VT-UTF8 returned. | |
| **/ | |
| VOID | |
| UnicodeToUtf8 ( | |
| IN CHAR16 Unicode, | |
| OUT UTF8_CHAR *Utf8Char, | |
| OUT UINT8 *ValidBytes | |
| ) | |
| { | |
| UINT8 UnicodeByte0; | |
| UINT8 UnicodeByte1; | |
| // | |
| // translate unicode to utf8 code | |
| // | |
| UnicodeByte0 = (UINT8) Unicode; | |
| UnicodeByte1 = (UINT8) (Unicode >> 8); | |
| if (Unicode < 0x0080) { | |
| Utf8Char->Utf8_1 = (UINT8) (UnicodeByte0 & 0x7f); | |
| *ValidBytes = 1; | |
| } else if (Unicode < 0x0800) { | |
| // | |
| // byte sequence: high -> low | |
| // Utf8_2[0], Utf8_2[1] | |
| // | |
| Utf8Char->Utf8_2[1] = (UINT8) ((UnicodeByte0 & 0x3f) + 0x80); | |
| Utf8Char->Utf8_2[0] = (UINT8) ((((UnicodeByte1 << 2) + (UnicodeByte0 >> 6)) & 0x1f) + 0xc0); | |
| *ValidBytes = 2; | |
| } else { | |
| // | |
| // byte sequence: high -> low | |
| // Utf8_3[0], Utf8_3[1], Utf8_3[2] | |
| // | |
| Utf8Char->Utf8_3[2] = (UINT8) ((UnicodeByte0 & 0x3f) + 0x80); | |
| Utf8Char->Utf8_3[1] = (UINT8) ((((UnicodeByte1 << 2) + (UnicodeByte0 >> 6)) & 0x3f) + 0x80); | |
| Utf8Char->Utf8_3[0] = (UINT8) (((UnicodeByte1 >> 4) & 0x0f) + 0xe0); | |
| *ValidBytes = 3; | |
| } | |
| } | |
| /** | |
| Check if input string is valid VT-UTF8 string. | |
| @param TerminalDevice The terminal device. | |
| @param WString The input string. | |
| @retval EFI_SUCCESS If all input characters are valid. | |
| **/ | |
| EFI_STATUS | |
| VTUTF8TestString ( | |
| IN TERMINAL_DEV *TerminalDevice, | |
| IN CHAR16 *WString | |
| ) | |
| { | |
| // | |
| // to utf8, all kind of characters are supported. | |
| // | |
| return EFI_SUCCESS; | |
| } |