From d6a82eaf8d8971f9d4eecda80f421281363c0772 Mon Sep 17 00:00:00 2001 From: lgao4 Date: Tue, 9 Feb 2010 07:12:35 +0000 Subject: [PATCH] Update HiiString Protocol and HiiSetString Api in HiiLib 1. Reserve the unique string identifier for all languages in the package list. 2. Track MaxStringId to do the simple check for the requested StringId > MaxStringId, which can improve performance. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9954 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/Library/UefiHiiLib/HiiString.c | 8 +- .../Universal/HiiDatabaseDxe/Database.c | 2 +- .../Universal/HiiDatabaseDxe/HiiDatabase.h | 8 +- .../Universal/HiiDatabaseDxe/String.c | 259 ++++++++++++------ MdePkg/Include/Protocol/HiiString.h | 4 +- 5 files changed, 192 insertions(+), 89 deletions(-) diff --git a/MdeModulePkg/Library/UefiHiiLib/HiiString.c b/MdeModulePkg/Library/UefiHiiLib/HiiString.c index b61a9958d0..70e0f4d648 100644 --- a/MdeModulePkg/Library/UefiHiiLib/HiiString.c +++ b/MdeModulePkg/Library/UefiHiiLib/HiiString.c @@ -1,7 +1,7 @@ /** @file HII Library implementation that uses DXE protocols and services. - Copyright (c) 2006 - 2008, Intel Corporation
+ Copyright (c) 2006 - 2010, 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 @@ -66,7 +66,6 @@ HiiSetString ( CHAR8 *AllocatedLanguages; CHAR8 *Supported; CHAR8 *Language; - EFI_STRING_ID NewStringId; ASSERT (HiiHandle != NULL); ASSERT (String != NULL); @@ -90,7 +89,6 @@ HiiSetString ( return (EFI_STRING_ID)(0); } - NewStringId = 0; Status = EFI_INVALID_PARAMETER; // // Loop through each language that the string supports @@ -113,7 +111,7 @@ HiiSetString ( // If StringId is 0, then call NewString(). Otherwise, call SetString() // if (StringId == (EFI_STRING_ID)(0)) { - Status = gHiiString->NewString (gHiiString, HiiHandle, &NewStringId, Language, NULL, String, NULL); + Status = gHiiString->NewString (gHiiString, HiiHandle, &StringId, Language, NULL, String, NULL); } else { Status = gHiiString->SetString (gHiiString, HiiHandle, StringId, Language, String, NULL); } @@ -133,8 +131,6 @@ HiiSetString ( if (EFI_ERROR (Status)) { return (EFI_STRING_ID)(0); - } else if (StringId == (EFI_STRING_ID)(0)) { - return NewStringId; } else { return StringId; } diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/Database.c b/MdeModulePkg/Universal/HiiDatabaseDxe/Database.c index d148b02bf6..22841eb080 100644 --- a/MdeModulePkg/Universal/HiiDatabaseDxe/Database.c +++ b/MdeModulePkg/Universal/HiiDatabaseDxe/Database.c @@ -857,7 +857,7 @@ InsertStringPackage ( // // Collect all font block info // - Status = FindStringBlock (Private, StringPackage, (EFI_STRING_ID) (-1), NULL, NULL, NULL, NULL); + Status = FindStringBlock (Private, StringPackage, (EFI_STRING_ID) (-1), NULL, NULL, NULL, &StringPackage->MaxStringId); if (EFI_ERROR (Status)) { return Status; } diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabase.h b/MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabase.h index d449079ab2..c0069e6b9b 100644 --- a/MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabase.h +++ b/MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabase.h @@ -127,6 +127,7 @@ typedef struct _HII_STRING_PACKAGE_INSTANCE { LIST_ENTRY StringEntry; LIST_ENTRY FontInfoList; // local font info list UINT8 FontId; + EFI_STRING_ID MaxStringId; // record StringId } HII_STRING_PACKAGE_INSTANCE; // @@ -422,8 +423,9 @@ GetSystemFont ( /** Parse all string blocks to find a String block specified by StringId. If StringId = (EFI_STRING_ID) (-1), find out all EFI_HII_SIBT_FONT blocks - within this string package and backup its information. - If StringId = 0, output the string id of last string block (EFI_HII_SIBT_END). + within this string package and backup its information. If LastStringId is + specified, the string id of last string block will also be output. + If StringId = 0, output the string id of last string block (EFI_HII_SIBT_STRING). @param Private Hii database private structure. @param StringPackage Hii string package instance. @@ -433,7 +435,7 @@ GetSystemFont ( @param StringBlockAddr Output the block address of found string block. @param StringTextOffset Offset, relative to the found block address, of the string text information. - @param LastStringId Output the last string id when StringId = 0. + @param LastStringId Output the last string id when StringId = 0 or StringId = -1. @retval EFI_SUCCESS The string text and font is retrieved successfully. diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/String.c b/MdeModulePkg/Universal/HiiDatabaseDxe/String.c index 00ff6ce786..bda7d5ac06 100644 --- a/MdeModulePkg/Universal/HiiDatabaseDxe/String.c +++ b/MdeModulePkg/Universal/HiiDatabaseDxe/String.c @@ -2,7 +2,7 @@ Implementation for EFI_HII_STRING_PROTOCOL. -Copyright (c) 2007, Intel Corporation +Copyright (c) 2007 - 2010, 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 @@ -235,25 +235,26 @@ GetStringFontInfo ( /** Parse all string blocks to find a String block specified by StringId. If StringId = (EFI_STRING_ID) (-1), find out all EFI_HII_SIBT_FONT blocks - within this string package and backup its information. - If StringId = 0, output the string id of last string block (EFI_HII_SIBT_END). + within this string package and backup its information. If LastStringId is + specified, the string id of last string block will also be output. + If StringId = 0, output the string id of last string block (EFI_HII_SIBT_STRING). - @param Private Hii database private structure. - @param StringPackage Hii string package instance. - @param StringId The string's id, which is unique within - PackageList. - @param BlockType Output the block type of found string block. - @param StringBlockAddr Output the block address of found string block. - @param StringTextOffset Offset, relative to the found block address, of - the string text information. - @param LastStringId Output the last string id when StringId = 0. + @param Private Hii database private structure. + @param StringPackage Hii string package instance. + @param StringId The string's id, which is unique within + PackageList. + @param BlockType Output the block type of found string block. + @param StringBlockAddr Output the block address of found string block. + @param StringTextOffset Offset, relative to the found block address, of + the string text information. + @param LastStringId Output the last string id when StringId = 0 or StringId = -1. - @retval EFI_SUCCESS The string text and font is retrieved - successfully. - @retval EFI_NOT_FOUND The specified text or font info can not be found - out. - @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the - task. + @retval EFI_SUCCESS The string text and font is retrieved + successfully. + @retval EFI_NOT_FOUND The specified text or font info can not be found + out. + @retval EFI_OUT_OF_RESOURCES The system is out of resources to accomplish the + task. **/ EFI_STATUS @@ -295,8 +296,15 @@ FindStringBlock ( if (StringId != (EFI_STRING_ID) (-1) && StringId != 0) { ASSERT (BlockType != NULL && StringBlockAddr != NULL && StringTextOffset != NULL); + if (StringId > StringPackage->MaxStringId) { + return EFI_NOT_FOUND; + } } else { ASSERT (Private != NULL && Private->Signature == HII_DATABASE_PRIVATE_DATA_SIGNATURE); + if (StringId == 0 && LastStringId != NULL) { + *LastStringId = StringPackage->MaxStringId; + return EFI_SUCCESS; + } } ZeroMem (&Zero, sizeof (CHAR16)); @@ -547,13 +555,12 @@ FindStringBlock ( BlockHdr = StringPackage->StringBlock + BlockSize; } - + + // + // Get last string ID + // if (StringId == (EFI_STRING_ID) (-1)) { - return EFI_SUCCESS; - } - - if (StringId == 0 && LastStringId != NULL) { - *LastStringId = CurrentStringId; + *LastStringId = CurrentStringId - 1; return EFI_SUCCESS; } @@ -909,7 +916,10 @@ SetStringWorker ( /** This function adds the string String to the group of strings owned by PackageList, with the - specified font information StringFontInfo and returns a new string id. + specified font information StringFontInfo and returns a new string id. + The new string identifier is guaranteed to be unique within the package list. + That new string identifier is reserved for all languages in the package list. + @param This A pointer to the EFI_HII_STRING_PROTOCOL instance. @param PackageList Handle of the package list where this string will @@ -952,7 +962,6 @@ HiiNewString ( { EFI_STATUS Status; LIST_ENTRY *Link; - BOOLEAN Matched; HII_DATABASE_PRIVATE_DATA *Private; HII_DATABASE_RECORD *DatabaseRecord; HII_DATABASE_PACKAGE_LIST_INSTANCE *PackageListNode; @@ -968,6 +977,12 @@ HiiNewString ( EFI_HII_SIBT_EXT2_BLOCK Ext2; HII_FONT_INFO *LocalFont; HII_GLOBAL_FONT_INFO *GlobalFont; + EFI_STRING_ID NewStringId; + EFI_STRING_ID NextStringId; + EFI_STRING_ID Index; + HII_STRING_PACKAGE_INSTANCE *MatchStringPackage; + BOOLEAN NewStringPackageCreated; + if (This == NULL || String == NULL || StringId == NULL || Language == NULL || PackageList == NULL) { return EFI_INVALID_PARAMETER; @@ -1004,37 +1019,113 @@ HiiNewString ( return EFI_NOT_FOUND; } - // - // Try to get the matching string package. Create a new string package when failed. - // + Status = EFI_SUCCESS; + NewStringPackageCreated = FALSE; + NewStringId = 0; + NextStringId = 0; StringPackage = NULL; - Matched = FALSE; + MatchStringPackage = NULL; for (Link = PackageListNode->StringPkgHdr.ForwardLink; Link != &PackageListNode->StringPkgHdr; Link = Link->ForwardLink ) { StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE); + // + // Create a string block and corresponding font block if exists, then append them + // to the end of the string package. + // + Status = FindStringBlock ( + Private, + StringPackage, + 0, + NULL, + NULL, + NULL, + &NextStringId + ); + if (EFI_ERROR (Status)) { + goto Done; + } + // + // Make sure that new StringId is same in all String Packages for the different language. + // + if (NewStringId != 0 && NewStringId != NextStringId) { + ASSERT (FALSE); + Status = EFI_INVALID_PARAMETER; + goto Done; + } + NewStringId = NextStringId; + // + // Get the matched string package with language. + // if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language)) { - Matched = TRUE; - break; + MatchStringPackage = StringPackage; + } else { + OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize; + // + // Create a blank EFI_HII_SIBT_STRING_UCS2_BLOCK to reserve new string ID. + // + Ucs2BlockSize = (UINT32) sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK); + + StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + Ucs2BlockSize); + if (StringBlock == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + // + // Copy original string blocks, except the EFI_HII_SIBT_END. + // + CopyMem (StringBlock, StringPackage->StringBlock, OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK)); + // + // Create a blank EFI_HII_SIBT_STRING_UCS2 block + // + BlockPtr = StringBlock + OldBlockSize - sizeof (EFI_HII_SIBT_END_BLOCK); + *BlockPtr = EFI_HII_SIBT_STRING_UCS2; + BlockPtr += sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK); + + // + // Append a EFI_HII_SIBT_END block to the end. + // + *BlockPtr = EFI_HII_SIBT_END; + FreePool (StringPackage->StringBlock); + StringPackage->StringBlock = StringBlock; + StringPackage->StringPkgHdr->Header.Length += Ucs2BlockSize; + PackageListNode->PackageListHdr.PackageLength += Ucs2BlockSize; } } + if (NewStringId == 0) { + // + // No string package is found. + // Create new string package. StringId 1 is reserved for Language Name string. + // + *StringId = 2; + } else { + // + // Set new StringId + // + *StringId = NewStringId + 1; + } - if (!Matched) { + if (MatchStringPackage != NULL) { + StringPackage = MatchStringPackage; + } else { // // LanguageName is required to create a new string package. // if (LanguageName == NULL) { - return EFI_INVALID_PARAMETER; + Status = EFI_INVALID_PARAMETER; + goto Done; } StringPackage = AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE)); if (StringPackage == NULL) { - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + goto Done; } - StringPackage->Signature = HII_STRING_PACKAGE_SIGNATURE; - StringPackage->FontId = 0; + StringPackage->Signature = HII_STRING_PACKAGE_SIGNATURE; + StringPackage->MaxStringId = *StringId; + StringPackage->FontId = 0; InitializeListHead (&StringPackage->FontInfoList); // @@ -1044,12 +1135,13 @@ HiiNewString ( StringPackage->StringPkgHdr = AllocateZeroPool (HeaderSize); if (StringPackage->StringPkgHdr == NULL) { FreePool (StringPackage); - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + goto Done; } StringPackage->StringPkgHdr->Header.Type = EFI_HII_PACKAGE_STRINGS; StringPackage->StringPkgHdr->HdrSize = HeaderSize; StringPackage->StringPkgHdr->StringInfoOffset = HeaderSize; - CopyMem (StringPackage->StringPkgHdr->LanguageWindow, mLanguageWindow, 16 * sizeof (CHAR16));; + CopyMem (StringPackage->StringPkgHdr->LanguageWindow, mLanguageWindow, 16 * sizeof (CHAR16)); StringPackage->StringPkgHdr->LanguageName = 1; AsciiStrCpy (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language); @@ -1057,15 +1149,16 @@ HiiNewString ( // Calculate the length of the string blocks, including string block to record // printable language full name and EFI_HII_SIBT_END_BLOCK. // - Ucs2BlockSize = (UINT32) (StrSize ((CHAR16 *) LanguageName) + - sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK) - sizeof (CHAR16)); + Ucs2BlockSize = (UINT32) (StrSize ((CHAR16 *) LanguageName) + + (*StringId - 1) * sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK) - sizeof (CHAR16)); BlockSize = Ucs2BlockSize + sizeof (EFI_HII_SIBT_END_BLOCK); StringPackage->StringBlock = (UINT8 *) AllocateZeroPool (BlockSize); if (StringPackage->StringBlock == NULL) { FreePool (StringPackage->StringPkgHdr); FreePool (StringPackage); - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + goto Done; } // @@ -1076,7 +1169,10 @@ HiiNewString ( BlockPtr += sizeof (EFI_HII_STRING_BLOCK); CopyMem (BlockPtr, (EFI_STRING) LanguageName, StrSize ((EFI_STRING) LanguageName)); BlockPtr += StrSize ((EFI_STRING) LanguageName); - + for (Index = 2; Index <= *StringId - 1; Index ++) { + *BlockPtr = EFI_HII_SIBT_STRING_UCS2; + BlockPtr += sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK); + } // // Insert the end block // @@ -1088,24 +1184,7 @@ HiiNewString ( StringPackage->StringPkgHdr->Header.Length = HeaderSize + BlockSize; PackageListNode->PackageListHdr.PackageLength += StringPackage->StringPkgHdr->Header.Length; InsertTailList (&PackageListNode->StringPkgHdr, &StringPackage->StringEntry); - - } - - // - // Create a string block and corresponding font block if exists, then append them - // to the end of the string package. - // - Status = FindStringBlock ( - Private, - StringPackage, - 0, - NULL, - NULL, - NULL, - StringId - ); - if (EFI_ERROR (Status)) { - return Status; + NewStringPackageCreated = TRUE; } OldBlockSize = StringPackage->StringPkgHdr->Header.Length - StringPackage->StringPkgHdr->HdrSize; @@ -1114,13 +1193,13 @@ HiiNewString ( // // Create a EFI_HII_SIBT_STRING_UCS2_BLOCK since font info is not specified. // - Ucs2BlockSize = (UINT32) (StrSize (String) + sizeof (EFI_HII_SIBT_STRING_UCS2_BLOCK) - sizeof (CHAR16)); StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + Ucs2BlockSize); if (StringBlock == NULL) { - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + goto Done; } // // Copy original string blocks, except the EFI_HII_SIBT_END. @@ -1159,7 +1238,8 @@ HiiNewString ( // StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + Ucs2FontBlockSize); if (StringBlock == NULL) { - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + goto Done; } // // Copy original string blocks, except the EFI_HII_SIBT_END. @@ -1195,7 +1275,8 @@ HiiNewString ( sizeof (EFI_HII_SIBT_FONT_BLOCK) - sizeof (CHAR16)); StringBlock = (UINT8 *) AllocateZeroPool (OldBlockSize + FontBlockSize + Ucs2FontBlockSize); if (StringBlock == NULL) { - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + goto Done; } // // Copy original string blocks, except the EFI_HII_SIBT_END. @@ -1225,7 +1306,7 @@ HiiNewString ( &((EFI_FONT_INFO *) StringFontInfo)->FontName, StrSize (((EFI_FONT_INFO *) StringFontInfo)->FontName) ); - + BlockPtr += StrSize (((EFI_FONT_INFO *) StringFontInfo)->FontName); // // Create a EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK // @@ -1253,20 +1334,42 @@ HiiNewString ( } } - // - // Trigger any registered notification function - // - if (!Matched) { - return InvokeRegisteredFunction ( - Private, - EFI_HII_DATABASE_NOTIFY_NEW_PACK, - (VOID *) StringPackage, - EFI_HII_PACKAGE_STRINGS, - PackageList - ); +Done: + if (!EFI_ERROR (Status) && NewStringPackageCreated) { + // + // Trigger any registered notification function for new string package + // + Status = InvokeRegisteredFunction ( + Private, + EFI_HII_DATABASE_NOTIFY_NEW_PACK, + (VOID *) StringPackage, + EFI_HII_PACKAGE_STRINGS, + PackageList + ); } - return EFI_SUCCESS; + if (!EFI_ERROR (Status)) { + // + // Update MaxString Id to new StringId + // + for (Link = PackageListNode->StringPkgHdr.ForwardLink; + Link != &PackageListNode->StringPkgHdr; + Link = Link->ForwardLink + ) { + StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE); + StringPackage->MaxStringId = *StringId; + } + } else if (NewStringPackageCreated) { + // + // Free the allocated new string Package when new string can't be added. + // + RemoveEntryList (&StringPackage->StringEntry); + FreePool (StringPackage->StringBlock); + FreePool (StringPackage->StringPkgHdr); + FreePool (StringPackage); + } + + return Status; } diff --git a/MdePkg/Include/Protocol/HiiString.h b/MdePkg/Include/Protocol/HiiString.h index d0b7e0d221..169696e79c 100644 --- a/MdePkg/Include/Protocol/HiiString.h +++ b/MdePkg/Include/Protocol/HiiString.h @@ -1,7 +1,7 @@ /** @file The file provides services to manipulate string data. - Copyright (c) 2006 - 2008, Intel Corporation + Copyright (c) 2006 - 2010, 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 @@ -25,6 +25,8 @@ typedef struct _EFI_HII_STRING_PROTOCOL EFI_HII_STRING_PROTOCOL; /** This function adds the string String to the group of strings owned by PackageList, with the specified font information StringFontInfo and returns a new string id. + The new string identifier is guaranteed to be unique within the package list. + That new string identifier is reserved for all languages in the package list. @param This A pointer to the EFI_HII_STRING_PROTOCOL instance. @param PackageList Handle of the package list where this string will