Signed-off-by: lzeng14 Reviewed-by: lgao4 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11762 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			474 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			474 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Driver to implement English version of Unicode Collation Protocol.
 | 
						|
 | 
						|
Copyright (c) 2006 - 2011, 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 "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;
 | 
						|
}
 |