最近编写程序,需要用到 CHAR16 的大小写转换,忽然惊奇的发现远比CHAR8的转化复杂,没有可以直接使用的函数。研究了一番,猜测产生这样问题的原因是 CHAR16 是定义给 Unicode 使用的。而Unicode 需要支持多种语言格式,比方说:’a’的大写是’A’,‘一’的大写就是‘壹’了,所以处理上也是复杂的。
从 UEFI Spec 来看,标准的做法要求使用EFI_UNICODE_COLLATION_PROTOCOL 。对应的头文件在 \MdePkg\Include\Protocol\UnicodeCollation.h 中。有下面几个功能:
/// /// The EFI_UNICODE_COLLATION_PROTOCOL is used to perform case-insensitive /// comparisons of strings. /// struct _EFI_UNICODE_COLLATION_PROTOCOL { EFI_UNICODE_COLLATION_STRICOLL StriColl; EFI_UNICODE_COLLATION_METAIMATCH MetaiMatch; EFI_UNICODE_COLLATION_STRLWR StrLwr; EFI_UNICODE_COLLATION_STRUPR StrUpr; // // for supporting fat volumes // EFI_UNICODE_COLLATION_FATTOSTR FatToStr; EFI_UNICODE_COLLATION_STRTOFAT StrToFat; /// /// A Null-terminated ASCII string array that contains one or more language codes. /// When this field is used for UnicodeCollation2, it is specified in RFC 4646 format. /// When it is used for UnicodeCollation, it is specified in ISO 639-2 format. /// CHAR8 *SupportedLanguages; };
StriColl 进行大小写敏感的字符串比较
MetaiMatch 判断字符串是否匹配一个带有通配符的模版
StrLwr 字符串转为小写
StrUpr 字符串转为大写
FatToStr 将8.3格式的OEM字符集的FAT文件名转为字符串
StrToFat 将字符串转为OEM定义的字符集
*SupportedLanguages ASCII给出的语言的列表
上述只是简单的介绍,我也并没有仔细验证,更详细的请阅读UEFI Spec Protocols – String Services 章节。
除了,上面介绍的方法,如果你确定字符串中只有 ASCII , 那么还可以直接处理字符串中的 ASCII ,下面的实例演示了上面的2种做法:
#include <Uefi.h> #include <Library/UefiLib.h> #include <Library/ShellCEntryLib.h> #include <Protocol/UnicodeCollation.h> extern EFI_BOOT_SERVICES *gBS; extern EFI_SYSTEM_TABLE *gST; extern EFI_RUNTIME_SERVICES *gRT; EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollation = NULL; VOID EFIAPI lowercase ( IN OUT CHAR16 *Str ) { UINT32 i; CHAR8 *p; p=(CHAR8 *)Str; for (i=0;i<StrSize(Str);i++) { //Print(L"%d ",*p); if ((*p>='A')&&(*p<='Z')) { *p=*p+32; } p++; } } int EFIAPI main ( IN int Argc, IN CHAR16 **Argv ) { EFI_STATUS Status; CHAR16 *s1=L"Www.Lab-z.Com 1243"; CHAR16 *s2=L"Www.Lab-z.Com 1243"; if (mUnicodeCollation == NULL) { Status = gBS->LocateProtocol( &gEfiUnicodeCollation2ProtocolGuid, NULL, (VOID**)&mUnicodeCollation); if (EFI_ERROR(Status)) { Print(L"Can't find UnicodeCollation2 Protocol!\n"); return EFI_SUCCESS; } } mUnicodeCollation->StrUpr( mUnicodeCollation, s1); Print(L"%s\n",s1); lowercase (s2); Print(L"%s\n",s2); return EFI_SUCCESS; }
运行结果:
完整的代码下载