2019-09-03 11:58:42 +02:00
|
|
|
/** @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
|
|
|
|
);
|
2020-04-23 11:08:10 +02:00
|
|
|
ASSERT_EFI_ERROR(Status);
|
2019-09-03 11:58:42 +02:00
|
|
|
} else {
|
|
|
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
|
|
|
&mHandle,
|
|
|
|
&gEfiUnicodeCollation2ProtocolGuid,
|
|
|
|
&Unicode2Eng,
|
|
|
|
NULL
|
|
|
|
);
|
2020-04-23 11:08:10 +02:00
|
|
|
ASSERT_EFI_ERROR(Status);
|
2019-09-03 11:58:42 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (FeaturePcdGet (PcdUnicodeCollationSupport)) {
|
|
|
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
|
|
|
&mHandle,
|
|
|
|
&gEfiUnicodeCollationProtocolGuid,
|
|
|
|
&UnicodeEng,
|
|
|
|
NULL
|
|
|
|
);
|
2020-04-23 11:08:10 +02:00
|
|
|
ASSERT_EFI_ERROR(Status);
|
2019-09-03 11:58:42 +02:00
|
|
|
} 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;
|
|
|
|
}
|