/** @file | |
Driver to implement English version of Unicode Collation Protocol. | |
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include "UnicodeCollationEng.h" | |
CHAR8 mEngUpperMap[MAP_TABLE_SIZE]; | |
CHAR8 mEngLowerMap[MAP_TABLE_SIZE]; | |
CHAR8 mEngInfoMap[MAP_TABLE_SIZE]; | |
CHAR8 mOtherChars[] = { | |
'0', | |
'1', | |
'2', | |
'3', | |
'4', | |
'5', | |
'6', | |
'7', | |
'8', | |
'9', | |
'\\', | |
'.', | |
'_', | |
'^', | |
'$', | |
'~', | |
'!', | |
'#', | |
'%', | |
'&', | |
'-', | |
'{', | |
'}', | |
'(', | |
')', | |
'@', | |
'`', | |
'\'', | |
'\0' | |
}; | |
EFI_HANDLE mHandle = NULL; | |
// | |
// EFI Unicode Collation Protocol supporting ISO 639-2 language code | |
// | |
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_COLLATION_PROTOCOL UnicodeEng = { | |
EngStriColl, | |
EngMetaiMatch, | |
EngStrLwr, | |
EngStrUpr, | |
EngFatToStr, | |
EngStrToFat, | |
"eng" | |
}; | |
// | |
// EFI Unicode Collation2 Protocol supporting RFC 4646 language code | |
// | |
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_COLLATION_PROTOCOL Unicode2Eng = { | |
EngStriColl, | |
EngMetaiMatch, | |
EngStrLwr, | |
EngStrUpr, | |
EngFatToStr, | |
EngStrToFat, | |
"en" | |
}; | |
/** | |
The user Entry Point for English module. | |
This function initializes unicode character mapping and then installs Unicode | |
Collation & Unicode Collation 2 Protocols based on the feature flags. | |
@param ImageHandle The firmware allocated handle for the EFI image. | |
@param SystemTable A pointer to the EFI System Table. | |
@retval EFI_SUCCESS The entry point is executed successfully. | |
@retval other Some error occurs when executing this entry point. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
InitializeUnicodeCollationEng ( | |
IN EFI_HANDLE ImageHandle, | |
IN EFI_SYSTEM_TABLE *SystemTable | |
) | |
{ | |
EFI_STATUS Status; | |
UINTN Index; | |
UINTN Index2; | |
// | |
// Initialize mapping tables for the supported languages | |
// | |
for (Index = 0; Index < MAP_TABLE_SIZE; Index++) { | |
mEngUpperMap[Index] = (CHAR8)Index; | |
mEngLowerMap[Index] = (CHAR8)Index; | |
mEngInfoMap[Index] = 0; | |
if (((Index >= 'a') && (Index <= 'z')) || ((Index >= 0xe0) && (Index <= 0xf6)) || ((Index >= 0xf8) && (Index <= 0xfe))) { | |
Index2 = Index - 0x20; | |
mEngUpperMap[Index] = (CHAR8)Index2; | |
mEngLowerMap[Index2] = (CHAR8)Index; | |
mEngInfoMap[Index] |= CHAR_FAT_VALID; | |
mEngInfoMap[Index2] |= CHAR_FAT_VALID; | |
} | |
} | |
for (Index = 0; mOtherChars[Index] != 0; Index++) { | |
Index2 = mOtherChars[Index]; | |
mEngInfoMap[Index2] |= CHAR_FAT_VALID; | |
} | |
if (FeaturePcdGet (PcdUnicodeCollation2Support)) { | |
if (FeaturePcdGet (PcdUnicodeCollationSupport)) { | |
Status = gBS->InstallMultipleProtocolInterfaces ( | |
&mHandle, | |
&gEfiUnicodeCollationProtocolGuid, | |
&UnicodeEng, | |
&gEfiUnicodeCollation2ProtocolGuid, | |
&Unicode2Eng, | |
NULL | |
); | |
ASSERT_EFI_ERROR (Status); | |
} else { | |
Status = gBS->InstallMultipleProtocolInterfaces ( | |
&mHandle, | |
&gEfiUnicodeCollation2ProtocolGuid, | |
&Unicode2Eng, | |
NULL | |
); | |
ASSERT_EFI_ERROR (Status); | |
} | |
} else { | |
if (FeaturePcdGet (PcdUnicodeCollationSupport)) { | |
Status = gBS->InstallMultipleProtocolInterfaces ( | |
&mHandle, | |
&gEfiUnicodeCollationProtocolGuid, | |
&UnicodeEng, | |
NULL | |
); | |
ASSERT_EFI_ERROR (Status); | |
} else { | |
// | |
// This module must support to produce at least one of Unicode Collation Protocol | |
// and Unicode Collation 2 Protocol. | |
// | |
ASSERT (FALSE); | |
Status = EFI_UNSUPPORTED; | |
} | |
} | |
return Status; | |
} | |
/** | |
Performs a case-insensitive comparison of two Null-terminated strings. | |
@param This Protocol instance pointer. | |
@param Str1 A pointer to a Null-terminated string. | |
@param Str2 A pointer to a Null-terminated string. | |
@retval 0 Str1 is equivalent to Str2 | |
@retval > 0 Str1 is lexically greater than Str2 | |
@retval < 0 Str1 is lexically less than Str2 | |
**/ | |
INTN | |
EFIAPI | |
EngStriColl ( | |
IN EFI_UNICODE_COLLATION_PROTOCOL *This, | |
IN CHAR16 *Str1, | |
IN CHAR16 *Str2 | |
) | |
{ | |
while (*Str1 != 0) { | |
if (TO_UPPER (*Str1) != TO_UPPER (*Str2)) { | |
break; | |
} | |
Str1 += 1; | |
Str2 += 1; | |
} | |
return TO_UPPER (*Str1) - TO_UPPER (*Str2); | |
} | |
/** | |
Converts all the characters in a Null-terminated string to | |
lower case characters. | |
@param This Protocol instance pointer. | |
@param Str A pointer to a Null-terminated string. | |
**/ | |
VOID | |
EFIAPI | |
EngStrLwr ( | |
IN EFI_UNICODE_COLLATION_PROTOCOL *This, | |
IN OUT CHAR16 *Str | |
) | |
{ | |
while (*Str != 0) { | |
*Str = TO_LOWER (*Str); | |
Str += 1; | |
} | |
} | |
/** | |
Converts all the characters in a Null-terminated string to upper | |
case characters. | |
@param This Protocol instance pointer. | |
@param Str A pointer to a Null-terminated string. | |
**/ | |
VOID | |
EFIAPI | |
EngStrUpr ( | |
IN EFI_UNICODE_COLLATION_PROTOCOL *This, | |
IN OUT CHAR16 *Str | |
) | |
{ | |
while (*Str != 0) { | |
*Str = TO_UPPER (*Str); | |
Str += 1; | |
} | |
} | |
/** | |
Performs a case-insensitive comparison of a Null-terminated | |
pattern string and a Null-terminated string. | |
@param This Protocol instance pointer. | |
@param String A pointer to a Null-terminated string. | |
@param Pattern A pointer to a Null-terminated pattern string. | |
@retval TRUE Pattern was found in String. | |
@retval FALSE Pattern was not found in String. | |
**/ | |
BOOLEAN | |
EFIAPI | |
EngMetaiMatch ( | |
IN EFI_UNICODE_COLLATION_PROTOCOL *This, | |
IN CHAR16 *String, | |
IN CHAR16 *Pattern | |
) | |
{ | |
CHAR16 CharC; | |
CHAR16 CharP; | |
CHAR16 Index3; | |
for ( ; ;) { | |
CharP = *Pattern; | |
Pattern += 1; | |
switch (CharP) { | |
case 0: | |
// | |
// End of pattern. If end of string, TRUE match | |
// | |
if (*String != 0) { | |
return FALSE; | |
} else { | |
return TRUE; | |
} | |
case '*': | |
// | |
// Match zero or more chars | |
// | |
while (*String != 0) { | |
if (EngMetaiMatch (This, String, Pattern)) { | |
return TRUE; | |
} | |
String += 1; | |
} | |
return EngMetaiMatch (This, String, Pattern); | |
case '?': | |
// | |
// Match any one char | |
// | |
if (*String == 0) { | |
return FALSE; | |
} | |
String += 1; | |
break; | |
case '[': | |
// | |
// Match char set | |
// | |
CharC = *String; | |
if (CharC == 0) { | |
// | |
// syntax problem | |
// | |
return FALSE; | |
} | |
Index3 = 0; | |
CharP = *Pattern++; | |
while (CharP != 0) { | |
if (CharP == ']') { | |
return FALSE; | |
} | |
if (CharP == '-') { | |
// | |
// if range of chars, get high range | |
// | |
CharP = *Pattern; | |
if ((CharP == 0) || (CharP == ']')) { | |
// | |
// syntax problem | |
// | |
return FALSE; | |
} | |
if ((TO_UPPER (CharC) >= TO_UPPER (Index3)) && (TO_UPPER (CharC) <= TO_UPPER (CharP))) { | |
// | |
// if in range, it's a match | |
// | |
break; | |
} | |
} | |
Index3 = CharP; | |
if (TO_UPPER (CharC) == TO_UPPER (CharP)) { | |
// | |
// if char matches | |
// | |
break; | |
} | |
CharP = *Pattern++; | |
} | |
// | |
// skip to end of match char set | |
// | |
while ((CharP != 0) && (CharP != ']')) { | |
CharP = *Pattern; | |
Pattern += 1; | |
} | |
String += 1; | |
break; | |
default: | |
CharC = *String; | |
if (TO_UPPER (CharC) != TO_UPPER (CharP)) { | |
return FALSE; | |
} | |
String += 1; | |
break; | |
} | |
} | |
} | |
/** | |
Converts an 8.3 FAT file name in an OEM character set to a Null-terminated string. | |
@param This Protocol instance pointer. | |
@param FatSize The size of the string Fat in bytes. | |
@param Fat A pointer to a Null-terminated string that contains an 8.3 file | |
name using an 8-bit OEM character set. | |
@param String A pointer to a Null-terminated string. The string must | |
be preallocated to hold FatSize characters. | |
**/ | |
VOID | |
EFIAPI | |
EngFatToStr ( | |
IN EFI_UNICODE_COLLATION_PROTOCOL *This, | |
IN UINTN FatSize, | |
IN CHAR8 *Fat, | |
OUT CHAR16 *String | |
) | |
{ | |
// | |
// No DBCS issues, just expand and add null terminate to end of string | |
// | |
while ((*Fat != 0) && (FatSize != 0)) { | |
*String = *Fat; | |
String += 1; | |
Fat += 1; | |
FatSize -= 1; | |
} | |
*String = 0; | |
} | |
/** | |
Converts a Null-terminated string to legal characters in a FAT | |
filename using an OEM character set. | |
@param This Protocol instance pointer. | |
@param String A pointer to a Null-terminated string. The string must | |
be preallocated to hold FatSize characters. | |
@param FatSize The size of the string Fat in bytes. | |
@param Fat A pointer to a Null-terminated string that contains an 8.3 file | |
name using an OEM character set. | |
@retval TRUE Fat is a Long File Name | |
@retval FALSE Fat is an 8.3 file name | |
**/ | |
BOOLEAN | |
EFIAPI | |
EngStrToFat ( | |
IN EFI_UNICODE_COLLATION_PROTOCOL *This, | |
IN CHAR16 *String, | |
IN UINTN FatSize, | |
OUT CHAR8 *Fat | |
) | |
{ | |
BOOLEAN SpecialCharExist; | |
SpecialCharExist = FALSE; | |
while ((*String != 0) && (FatSize != 0)) { | |
// | |
// Skip '.' or ' ' when making a fat name | |
// | |
if ((*String != '.') && (*String != ' ')) { | |
// | |
// If this is a valid fat char, move it. | |
// Otherwise, move a '_' and flag the fact that the name needs a long file name. | |
// | |
if ((*String < MAP_TABLE_SIZE) && ((mEngInfoMap[*String] & CHAR_FAT_VALID) != 0)) { | |
*Fat = mEngUpperMap[*String]; | |
} else { | |
*Fat = '_'; | |
SpecialCharExist = TRUE; | |
} | |
Fat += 1; | |
FatSize -= 1; | |
} | |
String += 1; | |
} | |
// | |
// Do not terminate that fat string | |
// | |
return SpecialCharExist; | |
} |