/** @file Implementation translation among different code tyies. Copyright (c) 2006, Intel Corporation.
All rights reserved. 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" 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)) { GetOneValidUtf8Char (TerminalDevice, &Utf8Char, &ValidBytes); if (ValidBytes < 1 || ValidBytes > 3) { continue; } Utf8ToUnicode (Utf8Char, ValidBytes, (CHAR16 *) &UnicodeChar); UnicodeFiFoInsertOneKey (TerminalDevice, UnicodeChar); } } 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: if ((Temp & 0xc0) == 0x80) { Utf8Char->Utf8_2[0] = Temp; FetchFlag = FALSE; } else { *ValidBytes = 0; } break; case 3: if ((Temp & 0xc0) == 0x80) { Utf8Char->Utf8_3[2 - Index] = Temp; Index++; if (Index == 3) { FetchFlag = FALSE; } } else { *ValidBytes = 0; Index = 0; } break; default: break; } if (!FetchFlag) { break; } } return ; } 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 ; } 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; } } EFI_STATUS VTUTF8TestString ( IN TERMINAL_DEV *TerminalDevice, IN CHAR16 *WString ) { // // to utf8, all kind of characters are supported. // return EFI_SUCCESS; }