\r
typedef struct {\r
CHAR8 *Iso639;\r
- CHAR8 *Rfc3066;\r
-} ISO639TORFC3066MAP;\r
+ CHAR8 *Rfc4646;\r
+} ISO639TORFC4646MAP;\r
\r
-ISO639TORFC3066MAP Iso639ToRfc3066Map [] = {\r
+ISO639TORFC4646MAP Iso639ToRfc4646Map [] = {\r
{"eng", "en-US"},\r
{"fra", "fr-FR"},\r
};\r
\r
+//\r
+// Lookup table of ISO639-2 3 character language codes to ISO 639-1 2 character language codes\r
+// Each entry is 5 CHAR8 values long. The first 3 CHAR8 values are the ISO 639-2 code.\r
+// The last 2 CHAR8 values are the ISO 639-1 code.\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 Iso639ToRfc4646ConversionTable[] =\r
+"\\r
+aaraa\\r
+abkab\\r
+afraf\\r
+amham\\r
+araar\\r
+asmas\\r
+aymay\\r
+azeaz\\r
+bakba\\r
+belbe\\r
+benbn\\r
+bihbh\\r
+bisbi\\r
+bodbo\\r
+brebr\\r
+bulbg\\r
+catca\\r
+cescs\\r
+corkw\\r
+cosco\\r
+cymcy\\r
+danda\\r
+deude\\r
+dzodz\\r
+ellel\\r
+engen\\r
+epoeo\\r
+estet\\r
+euseu\\r
+faofo\\r
+fasfa\\r
+fijfj\\r
+finfi\\r
+frafr\\r
+fryfy\\r
+gaiga\\r
+gdhgd\\r
+glggl\\r
+grngn\\r
+gujgu\\r
+hauha\\r
+hebhe\\r
+hinhi\\r
+hrvhr\\r
+hunhu\\r
+hyehy\\r
+ikuiu\\r
+ileie\\r
+inaia\\r
+indid\\r
+ipkik\\r
+islis\\r
+itait\\r
+jawjw\\r
+jpnja\\r
+kalkl\\r
+kankn\\r
+kasks\\r
+katka\\r
+kazkk\\r
+khmkm\\r
+kinrw\\r
+kirky\\r
+korko\\r
+kurku\\r
+laolo\\r
+latla\\r
+lavlv\\r
+linln\\r
+litlt\\r
+ltzlb\\r
+malml\\r
+marmr\\r
+mkdmk\\r
+mlgmg\\r
+mltmt\\r
+molmo\\r
+monmn\\r
+mrimi\\r
+msams\\r
+myamy\\r
+nauna\\r
+nepne\\r
+nldnl\\r
+norno\\r
+ocioc\\r
+ormom\\r
+panpa\\r
+polpl\\r
+porpt\\r
+pusps\\r
+quequ\\r
+rohrm\\r
+ronro\\r
+runrn\\r
+rusru\\r
+sagsg\\r
+sansa\\r
+sinsi\\r
+slksk\\r
+slvsl\\r
+smise\\r
+smosm\\r
+snasn\\r
+sndsd\\r
+somso\\r
+sotst\\r
+spaes\\r
+sqisq\\r
+srpsr\\r
+sswss\\r
+sunsu\\r
+swasw\\r
+swesv\\r
+tamta\\r
+tattt\\r
+telte\\r
+tgktg\\r
+tgltl\\r
+thath\\r
+tsnts\\r
+tuktk\\r
+twitw\\r
+uigug\\r
+ukruk\\r
+urdur\\r
+uzbuz\\r
+vievi\\r
+volvo\\r
+wolwo\\r
+xhoxh\\r
+yidyi\\r
+zhaza\\r
+zhozh\\r
+zulzu\\r
+";\r
+\r
CHAR8 *\r
-ConvertIso639ToRfc3066 (\r
+ConvertIso639ToRfc4646 (\r
CHAR8 *Iso638Lang\r
)\r
{\r
}\r
}\r
\r
- for (Index = 0; Index < sizeof (Iso639ToRfc3066Map) / sizeof (Iso639ToRfc3066Map[0]); Index++) {\r
- if (AsciiStrnCmp (AsciiLanguage, Iso639ToRfc3066Map[Index].Iso639, AsciiStrSize (AsciiLanguage)) == 0) {\r
- return Iso639ToRfc3066Map[Index].Rfc3066;\r
+ for (Index = 0; Index < sizeof (Iso639ToRfc4646Map) / sizeof (Iso639ToRfc4646Map[0]); Index++) {\r
+ if (AsciiStrnCmp (AsciiLanguage, Iso639ToRfc4646Map[Index].Iso639, AsciiStrSize (AsciiLanguage)) == 0) {\r
+ return Iso639ToRfc4646Map[Index].Rfc4646;\r
}\r
}\r
\r
return (CHAR8 *) NULL;\r
}\r
\r
+/**\r
+ Convert language code from RFC4646 to ISO639-2.\r
+\r
+ @param LanguageRfc4646 RFC4646 language code.\r
+ @param LanguageIso639 ISO639-2 language code.\r
+\r
+ @retval EFI_SUCCESS Language code converted.\r
+ @retval EFI_NOT_FOUND Language code not found.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ConvertRfc4646LanguageToIso639Language (\r
+ IN CHAR8 *LanguageRfc4646,\r
+ OUT CHAR8 *LanguageIso639\r
+ )\r
+{\r
+ UINTN Index;\r
+\r
+ if ((LanguageRfc4646[2] != '-') && (LanguageRfc4646[2] != 0)) {\r
+ CopyMem (LanguageIso639, LanguageRfc4646, 3);\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ for (Index = 0; Iso639ToRfc4646ConversionTable[Index] != 0; Index += 5) {\r
+ if (CompareMem (LanguageRfc4646, &Iso639ToRfc4646ConversionTable[Index + 3], 2) == 0) {\r
+ CopyMem (LanguageIso639, &Iso639ToRfc4646ConversionTable[Index], 3);\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+\r
+/**\r
+ Convert language code from ISO639-2 to RFC4646 and return the converted language.\r
+ Caller is responsible for freeing the allocated buffer.\r
+\r
+ LanguageIso639 contain a single ISO639-2 code such as\r
+ "eng" or "fra".\r
+\r
+ If LanguageIso639 is NULL, then ASSERT.\r
+ If LanguageRfc4646 is NULL, then ASSERT.\r
+\r
+ @param LanguageIso639 ISO639-2 language code.\r
+\r
+ @return the allocated buffer or NULL, if the language is not found.\r
+\r
+**/\r
+CHAR8*\r
+EFIAPI\r
+ConvertIso639LanguageToRfc4646Language (\r
+ IN CONST CHAR8 *LanguageIso639\r
+ )\r
+{\r
+ UINTN Index;\r
+ CHAR8 *Rfc4646Language;\r
+ \r
+ for (Index = 0; Iso639ToRfc4646ConversionTable[Index] != 0; Index += 5) {\r
+ if (CompareMem (LanguageIso639, &Iso639ToRfc4646ConversionTable[Index], 3) == 0) {\r
+ Rfc4646Language = AllocateZeroPool (3);\r
+ if (Rfc4646Language != NULL) {\r
+ Rfc4646Language = CopyMem (Rfc4646Language, &Iso639ToRfc4646ConversionTable[Index + 3], 2);\r
+ }\r
+ return Rfc4646Language;\r
+ }\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ Get next language from language code list (with separator ';').\r
+\r
+ If LangCode is NULL, then ASSERT.\r
+ If Lang is NULL, then ASSERT.\r
+\r
+ @param LangCode On input: point to first language in the list. On\r
+ output: point to next language in the list, or\r
+ NULL if no more language in the list.\r
+ @param Lang The first language in the list.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+GetNextLanguage (\r
+ IN OUT CHAR8 **LangCode,\r
+ OUT CHAR8 *Lang\r
+ )\r
+{\r
+ UINTN Index;\r
+ CHAR8 *StringPtr;\r
+\r
+ ASSERT (LangCode != NULL);\r
+ ASSERT (*LangCode != NULL);\r
+ ASSERT (Lang != NULL);\r
+\r
+ Index = 0;\r
+ StringPtr = *LangCode;\r
+ while (StringPtr[Index] != 0 && StringPtr[Index] != ';') {\r
+ Index++;\r
+ }\r
+\r
+ CopyMem (Lang, StringPtr, Index);\r
+ Lang[Index] = 0;\r
+\r
+ if (StringPtr[Index] == ';') {\r
+ Index++;\r
+ }\r
+ *LangCode = StringPtr + Index;\r
+}\r
+\r
/**\r
Test if all of the characters in a string have corresponding font characters.\r
\r
If all glyphs in the string are available, the index is the index of the terminator \r
of the string. \r
@param GlyphBufferSize A pointer to a value. On output, if the function returns EFI_SUCCESS, \r
- it contains the amount of memory that is required to store the string¡¯s glyph equivalent.\r
+ it contains the amount of memory that is required to store the string? glyph equivalent.\r
\r
@retval EFI_UNSUPPORTED The function performs nothing and return EFI_UNSUPPORTED.\r
**/\r
Create or update the String given a new string and String ID.\r
\r
@param ThunkContext The Thunk Context.\r
- @param Rfc3066AsciiLanguage The RFC 3066 Language code in ASCII string format.\r
+ @param Rfc4646AsciiLanguage The RFC 4646 Language code in ASCII string format.\r
@param NewString The new string.\r
@param StringId The String ID. If StringId is 0, a new String Token\r
is created. Otherwise, the String Token StringId is \r
EFI_STATUS\r
UpdateString (\r
IN CONST HII_THUNK_CONTEXT *ThunkContext,\r
- IN CONST CHAR8 *Rfc3066AsciiLanguage,\r
+ IN CONST CHAR8 *Rfc4646AsciiLanguage,\r
IN CHAR16 *NewString,\r
IN OUT STRING_REF *StringId\r
)\r
{\r
EFI_STRING_ID NewStringId;\r
- EFI_STATUS Status;\r
-\r
\r
- NewStringId = 0;\r
- \r
- if (*StringId == 0) {\r
- //\r
- // Create a new string token.\r
- //\r
- if (Rfc3066AsciiLanguage == NULL) {\r
- //\r
- // For all languages in the package list.\r
- //\r
- Status = HiiLibNewString (ThunkContext->UefiHiiHandle, &NewStringId, NewString);\r
- } else {\r
- //\r
- // For specified language.\r
- //\r
- Status = mHiiStringProtocol->NewString (\r
- mHiiStringProtocol,\r
- ThunkContext->UefiHiiHandle,\r
- &NewStringId,\r
- Rfc3066AsciiLanguage,\r
- NULL,\r
- NewString,\r
- NULL\r
- );\r
- }\r
- } else {\r
- //\r
- // Update the existing string token.\r
- //\r
- if (Rfc3066AsciiLanguage == NULL) {\r
- //\r
- // For all languages in the package list.\r
- //\r
- Status = HiiLibSetString (ThunkContext->UefiHiiHandle, *StringId, NewString);\r
- } else {\r
- //\r
- // For specified language.\r
- //\r
- Status = mHiiStringProtocol->SetString (\r
- mHiiStringProtocol,\r
- ThunkContext->UefiHiiHandle,\r
- *StringId,\r
- Rfc3066AsciiLanguage,\r
- NewString,\r
- NULL\r
- );\r
- }\r
- }\r
- \r
- if (!EFI_ERROR (Status)) {\r
- if (*StringId == 0) {\r
- //\r
- // When creating new string, return the newly created String Token.\r
- //\r
- *StringId = NewStringId;\r
- }\r
- } else {\r
+ NewStringId = HiiSetString (ThunkContext->UefiHiiHandle, *StringId, NewString, Rfc4646AsciiLanguage);\r
+ *StringId = NewStringId;\r
+ if (NewStringId == 0) {\r
//\r
// Only EFI_INVALID_PARAMETER is defined in HII 0.92 specification.\r
//\r
- *StringId = 0;\r
+ return EFI_INVALID_PARAMETER;\r
+ } else {\r
+ return EFI_SUCCESS;\r
}\r
-\r
- return Status;\r
}\r
\r
/**\r
EFI_STRING_ID LastStringId;\r
CHAR8 AsciiLanguage[ISO_639_2_ENTRY_SIZE + 1];\r
CHAR16 LanguageCopy[ISO_639_2_ENTRY_SIZE + 1];\r
- CHAR8 *Rfc3066AsciiLanguage;\r
+ CHAR8 *Rfc4646AsciiLanguage;\r
\r
LastStringId = (EFI_STRING_ID) 0;\r
StringId = (EFI_STRING_ID) 0;\r
- Rfc3066AsciiLanguage = NULL;\r
+ Rfc4646AsciiLanguage = NULL;\r
\r
if (Language != NULL) {\r
ZeroMem (AsciiLanguage, sizeof (AsciiLanguage));;\r
ZeroMem (LanguageCopy, sizeof (LanguageCopy));\r
CopyMem (LanguageCopy, Language, ISO_639_2_ENTRY_SIZE * sizeof (CHAR16));\r
UnicodeStrToAsciiStr (LanguageCopy, AsciiLanguage);\r
- Rfc3066AsciiLanguage = ConvertIso639ToRfc3066 (AsciiLanguage);\r
- ASSERT (Rfc3066AsciiLanguage != NULL);\r
+ Rfc4646AsciiLanguage = ConvertIso639ToRfc4646 (AsciiLanguage);\r
+ ASSERT (Rfc4646AsciiLanguage != NULL);\r
}\r
\r
Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
if (CompareGuid (&TagGuid, &ThunkContext->TagGuid)) {\r
if (ThunkContext->SharingStringPack) {\r
StringId = *Reference;\r
- Status = UpdateString (ThunkContext, Rfc3066AsciiLanguage, NewString, &StringId);\r
+ Status = UpdateString (ThunkContext, Rfc4646AsciiLanguage, NewString, &StringId);\r
if (EFI_ERROR (Status)) {\r
break;\r
}\r
}\r
} else {\r
StringId = *Reference;\r
- Status = UpdateString (StringPackThunkContext, Rfc3066AsciiLanguage, NewString, &StringId);\r
+ Status = UpdateString (StringPackThunkContext, Rfc4646AsciiLanguage, NewString, &StringId);\r
}\r
\r
if (!EFI_ERROR (Status)) {\r
**/\r
EFI_STATUS\r
EFIAPI\r
-HiiGetString (\r
+HiiThunkGetString (\r
IN EFI_HII_PROTOCOL *This,\r
IN FRAMEWORK_EFI_HII_HANDLE Handle,\r
IN STRING_REF Token,\r
OUT EFI_STRING StringBuffer\r
)\r
{\r
- CHAR8 *Iso639AsciiLanguage;\r
HII_THUNK_PRIVATE_DATA *Private;\r
- CHAR8 *Rfc3066AsciiLanguage;\r
+ CHAR8 *Iso639AsciiLanguage;\r
+ CHAR8 *Rfc4646AsciiLanguage;\r
+ CHAR8 *SupportedLanguages;\r
+ CHAR8 *PlatformLanguage;\r
+ CHAR8 *BestLanguage;\r
EFI_HII_HANDLE UefiHiiHandle;\r
EFI_STATUS Status;\r
\r
Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
\r
Iso639AsciiLanguage = NULL;\r
- Rfc3066AsciiLanguage = NULL;\r
+ Rfc4646AsciiLanguage = NULL;\r
\r
if (LanguageString != NULL) {\r
Iso639AsciiLanguage = AllocateZeroPool (StrLen (LanguageString) + 1);\r
\r
//\r
// Caller of Framework HII Interface uses the Language Identification String defined \r
- // in Iso639. So map it to the Language Identifier defined in RFC3066.\r
+ // in Iso639. So map it to the Language Identifier defined in RFC4646.\r
//\r
- Rfc3066AsciiLanguage = ConvertIso639ToRfc3066 (Iso639AsciiLanguage);\r
+ Rfc4646AsciiLanguage = ConvertIso639ToRfc4646 (Iso639AsciiLanguage);\r
\r
//\r
- // If Rfc3066AsciiLanguage is NULL, more language mapping must be added to \r
- // Iso639ToRfc3066Map.\r
+ // If Rfc4646AsciiLanguage is NULL, more language mapping must be added to \r
+ // Iso639ToRfc4646Map.\r
//\r
- ASSERT (Rfc3066AsciiLanguage != NULL);\r
+ ASSERT (Rfc4646AsciiLanguage != NULL);\r
\r
}\r
\r
goto Done;\r
}\r
\r
- if (Rfc3066AsciiLanguage == NULL) {\r
- Status = HiiLibGetString (UefiHiiHandle, Token, StringBuffer, BufferLengthTemp);\r
+ if (Rfc4646AsciiLanguage == NULL) {\r
+ //\r
+ // Get the languages that the package specified by HiiHandle supports\r
+ //\r
+ SupportedLanguages = HiiGetSupportedLanguages (UefiHiiHandle);\r
+ if (SupportedLanguages == NULL) {\r
+ goto Error2;\r
+ }\r
+\r
+ //\r
+ // Get the current platform language setting\r
+ //\r
+ PlatformLanguage = GetEfiGlobalVariable (L"PlatformLang");\r
+ if (PlatformLanguage == NULL) {\r
+ goto Error1;\r
+ }\r
+\r
+ //\r
+ // Get the best matching language from SupportedLanguages\r
+ //\r
+ BestLanguage = GetBestLanguage (\r
+ SupportedLanguages, \r
+ FALSE, // RFC 4646 mode\r
+ PlatformLanguage, // Next highest priority\r
+ SupportedLanguages, // Lowest priority \r
+ NULL\r
+ );\r
+ if (BestLanguage == NULL) {\r
+ FreePool (PlatformLanguage);\r
+Error1:\r
+ FreePool (SupportedLanguages);\r
+Error2:\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+\r
+ Status = mHiiStringProtocol->GetString (\r
+ mHiiStringProtocol,\r
+ BestLanguage,\r
+ UefiHiiHandle,\r
+ Token,\r
+ StringBuffer,\r
+ BufferLengthTemp,\r
+ NULL\r
+ );\r
+ FreePool (BestLanguage);\r
} else {\r
Status = mHiiStringProtocol->GetString (\r
mHiiStringProtocol,\r
- Rfc3066AsciiLanguage,\r
+ Rfc4646AsciiLanguage,\r
UefiHiiHandle,\r
Token,\r
StringBuffer,\r