+/**\r
+ Check if lang is in supported language codes according to language string.\r
+\r
+ This code is used to check if lang is in in supported language codes. It can handle\r
+ RFC4646 and ISO639 language tags.\r
+ In ISO639 language tags, take 3-characters as a delimitation to find matched string.\r
+ In RFC4646 language tags, take semicolon as a delimitation to find matched string.\r
+\r
+ For example:\r
+ SupportedLang = "engfraengfra"\r
+ Iso639Language = TRUE\r
+ Lang = "eng", the return value is "TRUE", or\r
+ Lang = "chs", the return value is "FALSE".\r
+ Another example:\r
+ SupportedLang = "en;fr;en-US;fr-FR"\r
+ Iso639Language = FALSE\r
+ Lang = "en", the return value is "TRUE", or\r
+ Lang = "zh", the return value is "FALSE".\r
+\r
+ @param SupportedLang Platform supported language codes.\r
+ @param Lang Configured language.\r
+ @param Iso639Language A bool value to signify if the handler is operated on ISO639 or RFC4646.\r
+\r
+ @retval TRUE lang is in supported language codes.\r
+ @retval FALSE lang is not in supported language codes.\r
+\r
+**/\r
+BOOLEAN\r
+IsLangInSupportedLangCodes(\r
+ IN CHAR8 *SupportedLang,\r
+ IN CHAR8 *Lang,\r
+ IN BOOLEAN Iso639Language\r
+ ) \r
+{\r
+ UINTN Index;\r
+ UINTN CompareLength;\r
+ UINTN LanguageLength;\r
+\r
+ if (Iso639Language) {\r
+ CompareLength = ISO_639_2_ENTRY_SIZE;\r
+ for (Index = 0; Index < AsciiStrLen (SupportedLang); Index += CompareLength) {\r
+ if (AsciiStrnCmp (Lang, SupportedLang + Index, CompareLength) == 0) {\r
+ //\r
+ // Successfully find the Lang string in SupportedLang string.\r
+ //\r
+ return TRUE;\r
+ }\r
+ }\r
+ return FALSE;\r
+ } else {\r
+ //\r
+ // Compare RFC4646 language code\r
+ //\r
+ for (LanguageLength = 0; Lang[LanguageLength] != '\0'; LanguageLength++);\r
+\r
+ for (; *SupportedLang != '\0'; SupportedLang += CompareLength) {\r
+ //\r
+ // Skip ';' characters in SupportedLang\r
+ //\r
+ for (; *SupportedLang != '\0' && *SupportedLang == ';'; SupportedLang++);\r
+ //\r
+ // Determine the length of the next language code in SupportedLang\r
+ //\r
+ for (CompareLength = 0; SupportedLang[CompareLength] != '\0' && SupportedLang[CompareLength] != ';'; CompareLength++);\r
+ \r
+ if ((CompareLength == LanguageLength) && \r
+ (AsciiStrnCmp (Lang, SupportedLang, CompareLength) == 0)) {\r
+ //\r
+ // Successfully find the Lang string in SupportedLang string.\r
+ //\r
+ return TRUE;\r
+ }\r
+ }\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+/**\r
+ Initialize Lang or PlatformLang variable, if Lang or PlatformLang variable is not found,\r
+ or it has been set to an unsupported value(not one of platform supported language codes),\r
+ set the default language code to it.\r
+\r
+ @param LangName Language name, L"Lang" or L"PlatformLang".\r
+ @param SupportedLang Platform supported language codes.\r
+ @param DefaultLang Default language code.\r
+ @param Iso639Language A bool value to signify if the handler is operated on ISO639 or RFC4646,\r
+ TRUE for L"Lang" LangName or FALSE for L"PlatformLang" LangName.\r
+\r
+**/\r
+VOID\r
+InitializeLangVariable (\r
+ IN CHAR16 *LangName,\r
+ IN CHAR8 *SupportedLang,\r
+ IN CHAR8 *DefaultLang, \r
+ IN BOOLEAN Iso639Language\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ CHAR8 *Lang;\r
+\r
+ //\r
+ // Find current Lang or PlatformLang from EFI Variable.\r
+ //\r
+ Status = GetEfiGlobalVariable2 (LangName, (VOID **) &Lang, NULL);\r
+ //\r
+ // If Lang or PlatformLang variable is not found,\r
+ // or it has been set to an unsupported value(not one of the supported language codes),\r
+ // set the default language code to it.\r
+ //\r
+ if (EFI_ERROR (Status) || !IsLangInSupportedLangCodes (SupportedLang, Lang, Iso639Language)) {\r
+ //\r
+ // The default language code should be one of the supported language codes.\r
+ //\r
+ ASSERT (IsLangInSupportedLangCodes (SupportedLang, DefaultLang, Iso639Language));\r
+ Status = gRT->SetVariable (\r
+ LangName,\r
+ &gEfiGlobalVariableGuid,\r
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+ AsciiStrSize (DefaultLang),\r
+ DefaultLang\r
+ );\r
+ }\r
+\r
+ if (Lang != NULL) {\r
+ FreePool (Lang);\r
+ }\r
+}\r
+\r