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
This commit is contained in:
lgao4 2010-02-09 07:12:35 +00:00
parent 995c594047
commit d6a82eaf8d
5 changed files with 192 additions and 89 deletions

View File

@ -1,7 +1,7 @@
/** @file
HII Library implementation that uses DXE protocols and services.
Copyright (c) 2006 - 2008, Intel Corporation<BR>
Copyright (c) 2006 - 2010, Intel Corporation<BR>
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;
}

View File

@ -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;
}

View File

@ -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.

View File

@ -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,8 +235,9 @@ 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.
@ -246,7 +247,7 @@ GetStringFontInfo (
@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.
@ -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));
@ -548,12 +556,11 @@ FindStringBlock (
}
//
// 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;
}
@ -910,6 +917,9 @@ 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.
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,93 +1019,17 @@ 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);
if (HiiCompareLanguage (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language)) {
Matched = TRUE;
break;
}
}
if (!Matched) {
//
// LanguageName is required to create a new string package.
//
if (LanguageName == NULL) {
return EFI_INVALID_PARAMETER;
}
StringPackage = AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE));
if (StringPackage == NULL) {
return EFI_OUT_OF_RESOURCES;
}
StringPackage->Signature = HII_STRING_PACKAGE_SIGNATURE;
StringPackage->FontId = 0;
InitializeListHead (&StringPackage->FontInfoList);
//
// Fill in the string package header
//
HeaderSize = (UINT32) (AsciiStrSize ((CHAR8 *) Language) - 1 + sizeof (EFI_HII_STRING_PACKAGE_HDR));
StringPackage->StringPkgHdr = AllocateZeroPool (HeaderSize);
if (StringPackage->StringPkgHdr == NULL) {
FreePool (StringPackage);
return EFI_OUT_OF_RESOURCES;
}
StringPackage->StringPkgHdr->Header.Type = EFI_HII_PACKAGE_STRINGS;
StringPackage->StringPkgHdr->HdrSize = HeaderSize;
StringPackage->StringPkgHdr->StringInfoOffset = HeaderSize;
CopyMem (StringPackage->StringPkgHdr->LanguageWindow, mLanguageWindow, 16 * sizeof (CHAR16));;
StringPackage->StringPkgHdr->LanguageName = 1;
AsciiStrCpy (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language);
//
// 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));
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;
}
//
// Insert the string block of printable language full name
//
BlockPtr = StringPackage->StringBlock;
*BlockPtr = EFI_HII_SIBT_STRING_UCS2;
BlockPtr += sizeof (EFI_HII_STRING_BLOCK);
CopyMem (BlockPtr, (EFI_STRING) LanguageName, StrSize ((EFI_STRING) LanguageName));
BlockPtr += StrSize ((EFI_STRING) LanguageName);
//
// Insert the end block
//
*BlockPtr = EFI_HII_SIBT_END;
//
// Append this string package node to string package array in this package list.
//
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.
@ -1102,10 +1041,150 @@ HiiNewString (
NULL,
NULL,
NULL,
StringId
&NextStringId
);
if (EFI_ERROR (Status)) {
return 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)) {
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 (MatchStringPackage != NULL) {
StringPackage = MatchStringPackage;
} else {
//
// LanguageName is required to create a new string package.
//
if (LanguageName == NULL) {
Status = EFI_INVALID_PARAMETER;
goto Done;
}
StringPackage = AllocateZeroPool (sizeof (HII_STRING_PACKAGE_INSTANCE));
if (StringPackage == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
StringPackage->Signature = HII_STRING_PACKAGE_SIGNATURE;
StringPackage->MaxStringId = *StringId;
StringPackage->FontId = 0;
InitializeListHead (&StringPackage->FontInfoList);
//
// Fill in the string package header
//
HeaderSize = (UINT32) (AsciiStrSize ((CHAR8 *) Language) - 1 + sizeof (EFI_HII_STRING_PACKAGE_HDR));
StringPackage->StringPkgHdr = AllocateZeroPool (HeaderSize);
if (StringPackage->StringPkgHdr == NULL) {
FreePool (StringPackage);
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));
StringPackage->StringPkgHdr->LanguageName = 1;
AsciiStrCpy (StringPackage->StringPkgHdr->Language, (CHAR8 *) Language);
//
// 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) +
(*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);
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
//
// Insert the string block of printable language full name
//
BlockPtr = StringPackage->StringBlock;
*BlockPtr = EFI_HII_SIBT_STRING_UCS2;
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
//
*BlockPtr = EFI_HII_SIBT_END;
//
// Append this string package node to string package array in this package list.
//
StringPackage->StringPkgHdr->Header.Length = HeaderSize + BlockSize;
PackageListNode->PackageListHdr.PackageLength += StringPackage->StringPkgHdr->Header.Length;
InsertTailList (&PackageListNode->StringPkgHdr, &StringPackage->StringEntry);
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,11 +1334,12 @@ HiiNewString (
}
}
Done:
if (!EFI_ERROR (Status) && NewStringPackageCreated) {
//
// Trigger any registered notification function
// Trigger any registered notification function for new string package
//
if (!Matched) {
return InvokeRegisteredFunction (
Status = InvokeRegisteredFunction (
Private,
EFI_HII_DATABASE_NOTIFY_NEW_PACK,
(VOID *) StringPackage,
@ -1266,7 +1348,28 @@ HiiNewString (
);
}
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;
}

View File

@ -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