]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/UefiHiiLib/HiiString.c
HII Library Class interface refine.
[mirror_edk2.git] / MdeModulePkg / Library / UefiHiiLib / HiiString.c
index 7d8ca5e11720664a8c1f670d9db2d7ce16ba9514..2c317e5de355c1501ba2ac1b4eab0f282396fe45 100644 (file)
@@ -163,339 +163,340 @@ zulzu\
 \r
 \r
 /**\r
-  This function adds the string into String Package of each language\r
-  supported by the package list.\r
-\r
-  If String is NULL, then ASSERT.\r
-  If StringId is NULL, the ASSERT.\r
-  If PackageList could not be found in the default HII database, then ASSERT.\r
-\r
-  @param  PackageList            Handle of the package list where this string will\r
-                                            be added.\r
-  @param  StringId               On return, contains the new strings id, which is\r
-                                          unique within PackageList.\r
-  @param  String                 Points to the new null-terminated string.\r
-\r
-  @retval EFI_SUCCESS             The new string was added successfully.\r
-  @retval EFI_OUT_OF_RESOURCES   Could not add the string due to lack of resources.\r
+  This function create a new string in String Package or updates an existing \r
+  string in a String Package.  If StringId is 0, then a new string is added to\r
+  a String Package.  If StringId is not zero, then a string in String Package is\r
+  updated.  If SupportedLanguages is NULL, then the string is added or updated\r
+  for all the languages that the String Package supports.  If SupportedLanguages\r
+  is not NULL, then the string is added or updated for the set of languages \r
+  specified by SupportedLanguages.\r
+    \r
+  If HiiHandle is NULL, then ASSERT().\r
+  If String is NULL, then ASSERT().\r
+\r
+  @param[in]  HiiHandle           A handle that was previously registered in the \r
+                                  HII Database.\r
+  @param[in]  StringId            If zero, then a new string is created in the \r
+                                  String Package associated with HiiHandle.  If \r
+                                  non-zero, then the string specified by StringId \r
+                                  is updated in the String Package  associated \r
+                                  with HiiHandle. \r
+  @param[in]  String              A pointer to the Null-terminated Unicode string \r
+                                  to add or update in the String Package associated \r
+                                  with HiiHandle.\r
+  @param[in]  SupportedLanguages  A pointer to a Null-terminated ASCII string of \r
+                                  language codes.  If this parameter is NULL, then \r
+                                  String is added or updated in the String Package \r
+                                  associated with HiiHandle for all the languages \r
+                                  that the String Package supports.  If this \r
+                                  parameter is not NULL, then then String is added \r
+                                  or updated in the String Package associated with \r
+                                  HiiHandle for the set oflanguages specified by \r
+                                  SupportedLanguages.  The format of \r
+                                  SupportedLanguages must follow the language \r
+                                  format assumed the HII Database.\r
+\r
+  @retval 0      The string could not be added or updated in the String Package.\r
+  @retval Other  The EFI_STRING_ID of the newly added or updated string.\r
 \r
 **/\r
-EFI_STATUS\r
+EFI_STRING_ID\r
 EFIAPI\r
-HiiLibNewString (\r
-  IN  EFI_HII_HANDLE                  PackageList,\r
-  OUT EFI_STRING_ID                   *StringId,\r
-  IN  CONST EFI_STRING                String\r
+HiiSetString (\r
+  IN EFI_HII_HANDLE    HiiHandle,\r
+  IN EFI_STRING_ID     StringId,            OPTIONAL\r
+  IN CONST EFI_STRING  String,\r
+  IN CONST CHAR8       *SupportedLanguages  OPTIONAL\r
   )\r
 {\r
-  EFI_STATUS  Status;\r
-  CHAR8       *Languages;\r
-  CHAR8       *LangStrings;\r
-  CHAR8       *Lang;\r
+  EFI_STATUS     Status;\r
+  CHAR8          *AllocatedLanguages;\r
+  CHAR8          *Supported;\r
+  CHAR8          *Language;\r
+  EFI_STRING_ID  NewStringId;\r
 \r
+  ASSERT (HiiHandle != NULL);\r
   ASSERT (String != NULL);\r
-  ASSERT (StringId != NULL);\r
 \r
-  Status = EFI_SUCCESS;\r
+  if (SupportedLanguages == NULL) {\r
+    //\r
+    // Retrieve the languages that the package specified by HiiHandle supports\r
+    //\r
+    AllocatedLanguages = HiiGetSupportedLanguages (HiiHandle);\r
+  } else {\r
+    //\r
+    // Allocate a copy of the SupportLanguages string that passed in\r
+    //\r
+    AllocatedLanguages = AllocateCopyPool (AsciiStrLen (SupportedLanguages), SupportedLanguages);\r
+  }\r
 \r
-  Languages = HiiLibGetSupportedLanguages (PackageList);\r
-  ASSERT (Languages != NULL);\r
   //\r
-  // Allocate working buffer to contain substring of Languages.\r
+  // If there are not enough resources for the supported languages string, then return a StringId of 0\r
   //\r
-  Lang = AllocatePool (AsciiStrSize (Languages));\r
-  ASSERT (Lang != NULL);\r
+  if (AllocatedLanguages == NULL) {\r
+    return (EFI_STRING_ID)(0);\r
+  }\r
 \r
-  LangStrings = Languages;\r
-  while (*LangStrings != 0) {\r
-    HiiLibGetNextLanguage (&LangStrings, Lang);\r
+  NewStringId = 0;\r
+  Status = EFI_INVALID_PARAMETER;\r
+  //\r
+  // Loop through each language that the string supports\r
+  //\r
+  for (Supported = AllocatedLanguages; *Supported != '\0'; ) {\r
+    //\r
+    // Cache a pointer to the beginning of the current language in the list of languages\r
+    //\r
+    Language = Supported;\r
 \r
     //\r
-    // For each language supported by the package,\r
-    // a string token is created.\r
+    // Search for the next language seperator and replace it with a Null-terminator\r
     //\r
-    Status = gHiiString->NewString (\r
-                                 gHiiString,\r
-                                 PackageList,\r
-                                 StringId,\r
-                                 Lang,\r
-                                 NULL,\r
-                                 String,\r
-                                 NULL\r
-                                 );\r
-    if (EFI_ERROR (Status)) {\r
-      break;\r
+    for (; *Supported != 0 && *Supported != ';'; Supported++);\r
+    if (*Supported != 0) {\r
+      *(Supported++) = '\0';\r
     }\r
-  }\r
-\r
-  FreePool (Lang);\r
-  FreePool (Languages);\r
-\r
-  return Status;\r
-  \r
-}\r
-\r
 \r
-/**\r
-  This function update the specified string in String Package of each language\r
-  supported by the package list.\r
-\r
-  If String is NULL, then ASSERT.\r
-  If PackageList could not be found in the default HII database, then ASSERT.\r
-  If StringId is not found in PackageList, then ASSERT.\r
-\r
-  @param  PackageList            Handle of the package list where this string will\r
-                                            be added.\r
-  @param  StringId               Ths String Id to be updated.\r
-  @param  String                 Points to the new null-terminated string.\r
-\r
-  @retval EFI_SUCCESS            The new string was added successfully.\r
-  @retval EFI_OUT_OF_RESOURCES   Could not add the string due to lack of resources.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-HiiLibSetString (\r
-  IN  EFI_HII_HANDLE                  PackageList,\r
-  IN  EFI_STRING_ID                   StringId,\r
-  IN  CONST EFI_STRING                String\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  CHAR8       *Languages;\r
-  CHAR8       *LangStrings;\r
-  CHAR8       *Lang;\r
-\r
-  ASSERT (IsHiiHandleRegistered (PackageList));\r
-\r
-  Status = EFI_SUCCESS;\r
-\r
-  Languages = HiiLibGetSupportedLanguages (PackageList);\r
-  ASSERT (Languages != NULL);\r
-\r
-  //\r
-  // Allocate working buffer to contain substring of Languages.\r
-  //\r
-  Lang = AllocatePool (AsciiStrSize (Languages));\r
-  ASSERT (Lang != NULL);\r
-\r
-  LangStrings = Languages;\r
-  while (*LangStrings != 0) {\r
-    HiiLibGetNextLanguage (&LangStrings, Lang);\r
+    //\r
+    // If StringId is 0, then call NewString().  Otherwise, call SetString()\r
+    //\r
+    if (StringId == (EFI_STRING_ID)(0)) {\r
+      Status = gHiiString->NewString (gHiiString, HiiHandle, &NewStringId, Language, NULL, String, NULL);\r
+    } else {\r
+      Status = gHiiString->SetString (gHiiString, HiiHandle, StringId, Language, String, NULL);\r
+    }\r
 \r
     //\r
-    // For each language supported by the package,\r
-    // the string is updated.\r
+    // If there was an error, then break out of the loop and return a StringId of 0\r
     //\r
-    Status = gHiiString->SetString (\r
-                                 gHiiString,\r
-                                 PackageList,\r
-                                 StringId,\r
-                                 Lang,\r
-                                 String,\r
-                                 NULL\r
-                                 );\r
     if (EFI_ERROR (Status)) {\r
       break;\r
     }\r
   }\r
 \r
-  FreePool (Lang);\r
-  FreePool (Languages);\r
-\r
-  return Status;\r
+  //\r
+  // Free the buffer of supported languages\r
+  //\r
+  FreePool (AllocatedLanguages);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return (EFI_STRING_ID)(0);\r
+  } else if (StringId == (EFI_STRING_ID)(0)) {\r
+    return NewStringId;\r
+  } else {\r
+    return StringId;\r
+  }\r
 }\r
 \r
 \r
 /**\r
-  Get the string given the StringId and String package Producer's Guid. The caller\r
-  is responsible to free the *String.\r
-\r
-  If PackageList with the matching ProducerGuid is not found, then ASSERT.\r
-  If PackageList with the matching ProducerGuid is found but no String is\r
-  specified by StringId is found, then ASSERT.\r
-\r
-  @param  ProducerGuid           The Guid of String package list.\r
-  @param  StringId               The String ID.\r
-  @param  String                 The output string.\r
-\r
-  @retval EFI_SUCCESS            Operation is successful.\r
-  @retval EFI_OUT_OF_RESOURCES   There is not enought memory in the system.\r
+  Retrieves a string from a string package names by GUID in a specific language.  \r
+  If the language is not specified, then a string from a string package in the \r
+  current platform  language is retrieved.  If the string can not be retrieved \r
+  using the specified language or the current platform language, then the string \r
+  is retrieved from the string package in the first language the string package \r
+  supports.  The returned string is allocated using AllocatePool().  The caller \r
+  is responsible for freeing the allocated buffer using FreePool().\r
+  \r
+  If PackageListGuid is NULL, then ASSERT().\r
+  If StringId is 0, then ASSERT.\r
+\r
+  @param[in]  PackageListGuid  The GUID of a package list that was previously \r
+                               registered in the HII Database.\r
+  @param[in]  StringId         The identifier of the string to retrieved from the \r
+                               string package associated with PackageListGuid.\r
+  @param[in]  Language         The language of the string to retrieve.  If this \r
+                               parameter is NULL, then the current platform \r
+                               language is used.  The format of Language must \r
+                               follow the language format assumed the HII Database.\r
+\r
+  @retval NULL   The package list specified by PackageListGuid is not present in the\r
+                 HII Database.\r
+  @retval NULL   The string specified by StringId is not present in the string package.\r
+  @retval Other  The string was returned.\r
 \r
 **/\r
-EFI_STATUS\r
+EFI_STRING\r
 EFIAPI\r
-HiiLibGetStringFromToken (\r
-  IN  EFI_GUID                        *ProducerGuid,\r
-  IN  EFI_STRING_ID                   StringId,\r
-  OUT EFI_STRING                      *String\r
+HiiGetPackageString (\r
+  IN CONST EFI_GUID  *PackageListGuid,\r
+  IN EFI_STRING_ID   StringId,\r
+  IN CONST CHAR8     *Language  OPTIONAL\r
   )\r
 {\r
-  EFI_STATUS      Status;\r
-  UINTN           Index;\r
-  UINTN           HandleBufferLen;\r
-  EFI_HII_HANDLE  *HiiHandleBuffer;\r
-  EFI_GUID        Guid;\r
+  EFI_HANDLE  *HiiHandleBuffer;\r
+  EFI_HANDLE  HiiHandle;\r
 \r
-  Status = HiiLibGetHiiHandles (&HandleBufferLen, &HiiHandleBuffer);\r
-  if (HiiHandleBuffer == NULL) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-  for (Index = 0; Index < (HandleBufferLen / sizeof (EFI_HII_HANDLE)); Index++) {\r
-    Status = HiiLibExtractGuidFromHiiHandle (HiiHandleBuffer[Index], &Guid);\r
-    if (EFI_ERROR(Status)) {\r
-      return Status;\r
-    }\r
-    if (CompareGuid (&Guid, ProducerGuid)) {\r
-      break;\r
-    }\r
-  }\r
+  ASSERT (PackageListGuid != NULL);\r
 \r
-  if (Index >= (HandleBufferLen / sizeof (EFI_HII_HANDLE))) {\r
-    //\r
-    // If PackageList with the matching ProducerGuid is not found, then ASSERT.\r
-    //\r
-    ASSERT (FALSE);\r
-    Status = EFI_NOT_FOUND;\r
-    goto Out;\r
+  HiiHandleBuffer = HiiGetHiiHandles (PackageListGuid);\r
+  if (HiiHandleBuffer == NULL) {\r
+    return NULL;\r
   }\r
 \r
-  Status = HiiLibGetStringFromHandle (HiiHandleBuffer[Index], StringId, String);\r
-\r
-Out:\r
+  HiiHandle = HiiHandleBuffer[0];\r
   FreePool (HiiHandleBuffer);\r
 \r
-  return Status;\r
+  return HiiGetString (HiiHandle, StringId, Language);\r
 }\r
 \r
 /**\r
-  This function try to retrieve string from String package of current language.\r
-  If fails, it try to retrieve string from String package of first language it support.\r
-\r
-  If StringSize is NULL, then ASSERT.\r
-  If String is NULL and *StringSize is not 0, then ASSERT.\r
-  If PackageList could not be found in the default HII database, then ASSERT.\r
-  If StringId is not found in PackageList, then ASSERT.\r
-\r
-  @param  PackageList     The package list in the HII database to search for\r
-                                     the specified string.\r
-  @param  StringId          The string's id, which is unique within\r
-                                      PackageList.\r
-  @param  String             Points to the new null-terminated string.\r
-  @param  StringSize       On entry, points to the size of the buffer pointed\r
-                                 to by String, in bytes. On return, points to the\r
-                                 length of the string, in bytes.\r
-\r
-  @retval EFI_SUCCESS            The string was returned successfully.\r
-  @retval EFI_NOT_FOUND          The string specified by StringId is not available.\r
-  @retval EFI_BUFFER_TOO_SMALL   The buffer specified by StringLength is too small\r
-                                 to hold the string.\r
+  Retrieves a string from a string package in a specific language.  If the language\r
+  is not specified, then a string from a string package in the current platform \r
+  language is retrieved.  If the string can not be retrieved using the specified \r
+  language or the current platform language, then the string is retrieved from \r
+  the string package in the first language the string package supports.  The \r
+  returned string is allocated using AllocatePool().  The caller is responsible \r
+  for freeing the allocated buffer using FreePool().\r
+  \r
+  If HiiHandle is NULL, then ASSERT().\r
+  If StringId is 0, then ASSET.\r
+\r
+  @param[in]  HiiHandle  A handle that was previously registered in the HII Database.\r
+  @param[in]  StringId   The identifier of the string to retrieved from the string \r
+                         package associated with HiiHandle.\r
+  @param[in]  Language   The language of the string to retrieve.  If this parameter \r
+                         is NULL, then the current platform language is used.  The \r
+                         format of Language must follow the language format assumed \r
+                         the HII Database.\r
+\r
+  @retval NULL   The string specified by StringId is not present in the string package.\r
+  @retval Other  The string was returned.\r
 \r
 **/\r
-EFI_STATUS\r
+EFI_STRING\r
 EFIAPI\r
-HiiLibGetString (\r
-  IN  EFI_HII_HANDLE                  PackageList,\r
-  IN  EFI_STRING_ID                   StringId,\r
-  OUT EFI_STRING                      String,\r
-  IN  OUT UINTN                       *StringSize\r
+HiiGetString (\r
+  IN EFI_HII_HANDLE  HiiHandle,\r
+  IN EFI_STRING_ID   StringId,\r
+  IN CONST CHAR8     *Language  OPTIONAL\r
   )\r
 {\r
   EFI_STATUS  Status;\r
-  CHAR8       *Languages;\r
-  CHAR8       *CurrentLang;\r
+  UINTN       StringSize;\r
+  CHAR16      TempString;\r
+  EFI_STRING  String;\r
+  CHAR8       *SupportedLanguages;\r
+  CHAR8       *PlatformLanguage;\r
   CHAR8       *BestLanguage;\r
 \r
-  ASSERT (StringSize != NULL);\r
-  ASSERT (!(*StringSize != 0 && String == NULL));\r
-  ASSERT (IsHiiHandleRegistered (PackageList));\r
+  ASSERT (HiiHandle != NULL);\r
+  ASSERT (StringId != 0);\r
 \r
-  Languages = HiiLibGetSupportedLanguages (PackageList);\r
-  ASSERT (Languages != NULL);\r
+  //\r
+  // Initialize all allocated buffers to NULL\r
+  // \r
+  SupportedLanguages = NULL;\r
+  PlatformLanguage   = NULL;\r
+  BestLanguage       = NULL;\r
+  String             = NULL;\r
 \r
-  CurrentLang = GetEfiGlobalVariable (L"PlatformLang");\r
-  \r
-  Status = EFI_NOT_FOUND;\r
-  BestLanguage = GetBestLanguage (\r
-                   Languages,\r
-                   FALSE,\r
-                   (CurrentLang != NULL) ? CurrentLang : "",\r
-                   (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang),\r
-                   Languages,\r
-                   NULL\r
-                   );\r
-  if (BestLanguage != NULL ) {\r
-     Status = gHiiString->GetString (\r
-                               gHiiString,\r
-                               BestLanguage,\r
-                               PackageList,\r
-                               StringId,\r
-                               String,\r
-                               StringSize,\r
-                               NULL\r
-                               );\r
-     FreePool (BestLanguage);\r
-  }\r
-  if (CurrentLang != NULL) {\r
-    FreePool (CurrentLang);\r
+  //\r
+  // Get the languages that the package specified by HiiHandle supports\r
+  //\r
+  SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);\r
+  if (SupportedLanguages == NULL) {\r
+    goto Error;\r
   }\r
-  FreePool (Languages);\r
-\r
-  return Status;\r
-}\r
 \r
+  //\r
+  // Get the current platform language setting\r
+  //\r
+  PlatformLanguage = GetEfiGlobalVariable (L"PlatformLang");\r
 \r
-/**\r
-  Get string specified by StringId form the HiiHandle. The caller\r
-  is responsible to free the *String.\r
-\r
-  If String is NULL, then ASSERT.\r
-  If HiiHandle could not be found in the default HII database, then ASSERT.\r
-  If StringId is not found in PackageList, then ASSERT.\r
-\r
-  @param  HiiHandle              The HII handle of package list.\r
-  @param  StringId               The String ID.\r
-  @param  String                 The output string.\r
+  //\r
+  // If Languag is NULL, then set it to an empty string, so it will be \r
+  // skipped by GetBestLanguage()\r
+  //\r
+  if (Language == NULL) {\r
+    Language = "";\r
+  }\r
 \r
-  @retval EFI_NOT_FOUND          String is not found.\r
-  @retval EFI_SUCCESS            Operation is successful.\r
-  @retval EFI_OUT_OF_RESOURCES   There is not enought memory in the system.\r
+  //\r
+  // Get the best matching language from SupportedLanguages\r
+  //\r
+  BestLanguage = GetBestLanguage (\r
+                   SupportedLanguages, \r
+                   FALSE,                                             // RFC 4646 mode\r
+                   Language,                                          // Highest priority \r
+                   PlatformLanguage != NULL ? PlatformLanguage : "",  // Next highest priority\r
+                   SupportedLanguages,                                // Lowest priority \r
+                   NULL\r
+                   );\r
+  if (BestLanguage == NULL) {\r
+    goto Error;\r
+  }\r
 \r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-HiiLibGetStringFromHandle (\r
-  IN  EFI_HII_HANDLE                  HiiHandle,\r
-  IN  EFI_STRING_ID                   StringId,\r
-  OUT EFI_STRING                      *String\r
-  )\r
-{\r
-  EFI_STATUS                          Status;\r
-  UINTN                               StringSize;\r
+  //\r
+  // Retrieve the size of the string in the string package for the BestLanguage\r
+  //\r
+  StringSize = 0;\r
+  Status = gHiiString->GetString (\r
+                         gHiiString,\r
+                         BestLanguage,\r
+                         HiiHandle,\r
+                         StringId,\r
+                         &TempString,\r
+                         &StringSize,\r
+                         NULL\r
+                         );\r
+  //\r
+  // If GetString() returns EFI_SUCCESS for a zero size, \r
+  // then there are no supported languages registered for HiiHandle.  If GetString() \r
+  // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present\r
+  // in the HII Database\r
+  //\r
+  if (Status != EFI_BUFFER_TOO_SMALL) {\r
+    goto Error;\r
+  }\r
 \r
-  ASSERT (String != NULL);\r
+  //\r
+  // Allocate a buffer for the return string\r
+  //\r
+  String = AllocateZeroPool (StringSize);\r
+  if (String == NULL) {\r
+    goto Error;\r
+  }\r
 \r
-  StringSize = HII_LIB_DEFAULT_STRING_SIZE;\r
-  *String    = AllocateZeroPool (StringSize);\r
-  if (*String == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
+  //\r
+  // Retrieve the string from the string package\r
+  //\r
+  Status = gHiiString->GetString (\r
+                         gHiiString,\r
+                         BestLanguage,\r
+                         HiiHandle,\r
+                         StringId,\r
+                         String,\r
+                         &StringSize,\r
+                         NULL\r
+                         );\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Free the buffer and return NULL if the supported languages can not be retrieved.\r
+    //\r
+    FreePool (String);\r
+    String = NULL;\r
   }\r
 \r
-  Status = HiiLibGetString (HiiHandle, StringId, *String, &StringSize);\r
-  if (Status == EFI_BUFFER_TOO_SMALL) {\r
-    FreePool (*String);\r
-    *String = AllocateZeroPool (StringSize);\r
-    if (*String == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-    Status = HiiLibGetString (HiiHandle, StringId, *String, &StringSize);\r
+Error:\r
+  //\r
+  // Free allocated buffers\r
+  //\r
+  if (SupportedLanguages != NULL) {\r
+    FreePool (SupportedLanguages);\r
+  }\r
+  if (PlatformLanguage != NULL) {\r
+    FreePool (PlatformLanguage);\r
+  }\r
+  if (BestLanguage != NULL) {\r
+    FreePool (BestLanguage);\r
   }\r
 \r
-  return Status;\r
+  //\r
+  // Return the Null-terminated Unicode string\r
+  //\r
+  return String;\r
 }\r
 \r
-\r
-\r
 /**\r
   Convert language code from RFC3066 to ISO639-2.\r
 \r