]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/UefiHiiLib/HiiString.c
Apply GetBestLanguage() API in UEFI to display HII string.
[mirror_edk2.git] / MdeModulePkg / Library / UefiHiiLib / HiiString.c
CommitLineData
08e4b3cf 1/** @file\r
2 HII Library implementation that uses DXE protocols and services.\r
3\r
4 Copyright (c) 2006 - 2008, Intel Corporation<BR>\r
5 All rights reserved. This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15\r
16#include "InternalHiiLib.h"\r
17\r
18\r
19//\r
20// Lookup table of ISO639-2 3 character language codes to ISO 639-1 2 character language codes\r
21// Each entry is 5 CHAR8 values long. The first 3 CHAR8 values are the ISO 639-2 code.\r
22// The last 2 CHAR8 values are the ISO 639-1 code.\r
23//\r
24GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 Iso639ToRfc3066ConversionTable[] =\r
25"\\r
26aaraa\\r
27abkab\\r
28afraf\\r
29amham\\r
30araar\\r
31asmas\\r
32aymay\\r
33azeaz\\r
34bakba\\r
35belbe\\r
36benbn\\r
37bihbh\\r
38bisbi\\r
39bodbo\\r
40brebr\\r
41bulbg\\r
42catca\\r
43cescs\\r
44corkw\\r
45cosco\\r
46cymcy\\r
47danda\\r
48deude\\r
49dzodz\\r
50ellel\\r
51engen\\r
52epoeo\\r
53estet\\r
54euseu\\r
55faofo\\r
56fasfa\\r
57fijfj\\r
58finfi\\r
59frafr\\r
60fryfy\\r
61gaiga\\r
62gdhgd\\r
63glggl\\r
64grngn\\r
65gujgu\\r
66hauha\\r
67hebhe\\r
68hinhi\\r
69hrvhr\\r
70hunhu\\r
71hyehy\\r
72ikuiu\\r
73ileie\\r
74inaia\\r
75indid\\r
76ipkik\\r
77islis\\r
78itait\\r
79jawjw\\r
80jpnja\\r
81kalkl\\r
82kankn\\r
83kasks\\r
84katka\\r
85kazkk\\r
86khmkm\\r
87kinrw\\r
88kirky\\r
89korko\\r
90kurku\\r
91laolo\\r
92latla\\r
93lavlv\\r
94linln\\r
95litlt\\r
96ltzlb\\r
97malml\\r
98marmr\\r
99mkdmk\\r
100mlgmg\\r
101mltmt\\r
102molmo\\r
103monmn\\r
104mrimi\\r
105msams\\r
106myamy\\r
107nauna\\r
108nepne\\r
109nldnl\\r
110norno\\r
111ocioc\\r
112ormom\\r
113panpa\\r
114polpl\\r
115porpt\\r
116pusps\\r
117quequ\\r
118rohrm\\r
119ronro\\r
120runrn\\r
121rusru\\r
122sagsg\\r
123sansa\\r
124sinsi\\r
125slksk\\r
126slvsl\\r
127smise\\r
128smosm\\r
129snasn\\r
130sndsd\\r
131somso\\r
132sotst\\r
133spaes\\r
134sqisq\\r
135srpsr\\r
136sswss\\r
137sunsu\\r
138swasw\\r
139swesv\\r
140tamta\\r
141tattt\\r
142telte\\r
143tgktg\\r
144tgltl\\r
145thath\\r
146tsnts\\r
147tuktk\\r
148twitw\\r
149uigug\\r
150ukruk\\r
151urdur\\r
152uzbuz\\r
153vievi\\r
154volvo\\r
155wolwo\\r
156xhoxh\\r
157yidyi\\r
158zhaza\\r
159zhozh\\r
160zulzu\\r
161";\r
162\r
163\r
164\r
165/**\r
166 This function adds the string into String Package of each language\r
167 supported by the package list.\r
168\r
169 If String is NULL, then ASSERT.\r
170 If StringId is NULL, the ASSERT.\r
171 If PackageList could not be found in the default HII database, then ASSERT.\r
172\r
173 @param PackageList Handle of the package list where this string will\r
174 be added.\r
175 @param StringId On return, contains the new strings id, which is\r
176 unique within PackageList.\r
177 @param String Points to the new null-terminated string.\r
178\r
179 @retval EFI_SUCCESS The new string was added successfully.\r
180 @retval EFI_OUT_OF_RESOURCES Could not add the string due to lack of resources.\r
181\r
182**/\r
183EFI_STATUS\r
184EFIAPI\r
185HiiLibNewString (\r
186 IN EFI_HII_HANDLE PackageList,\r
187 OUT EFI_STRING_ID *StringId,\r
188 IN CONST EFI_STRING String\r
189 )\r
190{\r
191 EFI_STATUS Status;\r
192 CHAR8 *Languages;\r
193 CHAR8 *LangStrings;\r
ea7cd3ec 194 CHAR8 *Lang;\r
08e4b3cf 195\r
196 ASSERT (String != NULL);\r
197 ASSERT (StringId != NULL);\r
198\r
199 Status = EFI_SUCCESS;\r
200\r
201 Languages = HiiLibGetSupportedLanguages (PackageList);\r
6cd8bf64 202 ASSERT (Languages != NULL);\r
ea7cd3ec 203 //\r
204 // Allocate working buffer to contain substring of Languages.\r
205 //\r
206 Lang = AllocatePool (AsciiStrSize (Languages));\r
207 ASSERT (Lang != NULL);\r
08e4b3cf 208\r
209 LangStrings = Languages;\r
210 while (*LangStrings != 0) {\r
211 HiiLibGetNextLanguage (&LangStrings, Lang);\r
212\r
213 //\r
214 // For each language supported by the package,\r
215 // a string token is created.\r
216 //\r
217 Status = mHiiStringProt->NewString (\r
218 mHiiStringProt,\r
219 PackageList,\r
220 StringId,\r
221 Lang,\r
222 NULL,\r
223 String,\r
224 NULL\r
225 );\r
226 if (EFI_ERROR (Status)) {\r
227 break;\r
228 }\r
229 }\r
230\r
ea7cd3ec 231 FreePool (Lang);\r
08e4b3cf 232 FreePool (Languages);\r
233\r
234 return Status;\r
235 \r
236}\r
237\r
238\r
239/**\r
240 This function update the specified string in String Package of each language\r
241 supported by the package list.\r
242\r
243 If String is NULL, then ASSERT.\r
244 If PackageList could not be found in the default HII database, then ASSERT.\r
245 If StringId is not found in PackageList, then ASSERT.\r
246\r
247 @param PackageList Handle of the package list where this string will\r
248 be added.\r
249 @param StringId Ths String Id to be updated.\r
250 @param String Points to the new null-terminated string.\r
251\r
252 @retval EFI_SUCCESS The new string was added successfully.\r
253 @retval EFI_OUT_OF_RESOURCES Could not add the string due to lack of resources.\r
254\r
255**/\r
256EFI_STATUS\r
257EFIAPI\r
258HiiLibSetString (\r
259 IN EFI_HII_HANDLE PackageList,\r
260 IN EFI_STRING_ID StringId,\r
261 IN CONST EFI_STRING String\r
262 )\r
263{\r
264 EFI_STATUS Status;\r
265 CHAR8 *Languages;\r
266 CHAR8 *LangStrings;\r
ea7cd3ec 267 CHAR8 *Lang;\r
08e4b3cf 268\r
269 ASSERT (IsHiiHandleRegistered (PackageList));\r
270\r
271 Status = EFI_SUCCESS;\r
272\r
273 Languages = HiiLibGetSupportedLanguages (PackageList);\r
274 ASSERT (Languages != NULL);\r
275\r
ea7cd3ec 276 //\r
277 // Allocate working buffer to contain substring of Languages.\r
278 //\r
279 Lang = AllocatePool (AsciiStrSize (Languages));\r
280 ASSERT (Lang != NULL);\r
281\r
08e4b3cf 282 LangStrings = Languages;\r
283 while (*LangStrings != 0) {\r
284 HiiLibGetNextLanguage (&LangStrings, Lang);\r
285\r
286 //\r
287 // For each language supported by the package,\r
288 // the string is updated.\r
289 //\r
290 Status = mHiiStringProt->SetString (\r
291 mHiiStringProt,\r
292 PackageList,\r
293 StringId,\r
294 Lang,\r
295 String,\r
296 NULL\r
297 );\r
298 if (EFI_ERROR (Status)) {\r
299 break;\r
300 }\r
301 }\r
302\r
ea7cd3ec 303 FreePool (Lang);\r
08e4b3cf 304 FreePool (Languages);\r
305\r
306 return Status;\r
307}\r
308\r
309\r
310/**\r
311 Get the string given the StringId and String package Producer's Guid. The caller\r
312 is responsible to free the *String.\r
313\r
314 If PackageList with the matching ProducerGuid is not found, then ASSERT.\r
315 If PackageList with the matching ProducerGuid is found but no String is\r
316 specified by StringId is found, then ASSERT.\r
317\r
318 @param ProducerGuid The Guid of String package list.\r
319 @param StringId The String ID.\r
320 @param String The output string.\r
321\r
322 @retval EFI_SUCCESS Operation is successful.\r
323 @retval EFI_OUT_OF_RESOURCES There is not enought memory in the system.\r
324\r
325**/\r
326EFI_STATUS\r
327EFIAPI\r
328HiiLibGetStringFromToken (\r
329 IN EFI_GUID *ProducerGuid,\r
330 IN EFI_STRING_ID StringId,\r
331 OUT EFI_STRING *String\r
332 )\r
333{\r
334 EFI_STATUS Status;\r
335 UINTN Index;\r
336 UINTN HandleBufferLen;\r
337 EFI_HII_HANDLE *HiiHandleBuffer;\r
338 EFI_GUID Guid;\r
339\r
340 Status = HiiLibGetHiiHandles (&HandleBufferLen, &HiiHandleBuffer);\r
4a1102c9 341 if (HiiHandleBuffer == NULL) {\r
342 return EFI_NOT_FOUND;\r
08e4b3cf 343 }\r
344 for (Index = 0; Index < (HandleBufferLen / sizeof (EFI_HII_HANDLE)); Index++) {\r
345 Status = HiiLibExtractGuidFromHiiHandle (HiiHandleBuffer[Index], &Guid);\r
346 if (EFI_ERROR(Status)) {\r
347 return Status;\r
348 }\r
349 if (CompareGuid (&Guid, ProducerGuid)) {\r
350 break;\r
351 }\r
352 }\r
353\r
354 if (Index >= (HandleBufferLen / sizeof (EFI_HII_HANDLE))) {\r
355 //\r
356 // If PackageList with the matching ProducerGuid is not found, then ASSERT.\r
357 //\r
358 ASSERT (FALSE);\r
359 Status = EFI_NOT_FOUND;\r
360 goto Out;\r
361 }\r
362\r
363 Status = HiiLibGetStringFromHandle (HiiHandleBuffer[Index], StringId, String);\r
364\r
365Out:\r
4a1102c9 366 FreePool (HiiHandleBuffer);\r
367\r
08e4b3cf 368 return Status;\r
369}\r
370\r
371/**\r
372 This function try to retrieve string from String package of current language.\r
373 If fails, it try to retrieve string from String package of first language it support.\r
374\r
375 If StringSize is NULL, then ASSERT.\r
376 If String is NULL and *StringSize is not 0, then ASSERT.\r
377 If PackageList could not be found in the default HII database, then ASSERT.\r
378 If StringId is not found in PackageList, then ASSERT.\r
379\r
380 @param PackageList The package list in the HII database to search for\r
381 the specified string.\r
382 @param StringId The string's id, which is unique within\r
383 PackageList.\r
384 @param String Points to the new null-terminated string.\r
385 @param StringSize On entry, points to the size of the buffer pointed\r
386 to by String, in bytes. On return, points to the\r
387 length of the string, in bytes.\r
388\r
389 @retval EFI_SUCCESS The string was returned successfully.\r
390 @retval EFI_NOT_FOUND The string specified by StringId is not available.\r
391 @retval EFI_BUFFER_TOO_SMALL The buffer specified by StringLength is too small\r
392 to hold the string.\r
393\r
394**/\r
395EFI_STATUS\r
396EFIAPI\r
397HiiLibGetString (\r
398 IN EFI_HII_HANDLE PackageList,\r
399 IN EFI_STRING_ID StringId,\r
400 OUT EFI_STRING String,\r
401 IN OUT UINTN *StringSize\r
402 )\r
403{\r
404 EFI_STATUS Status;\r
405 CHAR8 *Languages;\r
ea7cd3ec 406 CHAR8 *CurrentLang;\r
407 CHAR8 *BestLanguage;\r
08e4b3cf 408\r
409 ASSERT (StringSize != NULL);\r
410 ASSERT (!(*StringSize != 0 && String == NULL));\r
411 ASSERT (IsHiiHandleRegistered (PackageList));\r
412\r
ea7cd3ec 413 Languages = HiiLibGetSupportedLanguages (PackageList);\r
414 ASSERT (Languages != NULL);\r
08e4b3cf 415\r
ea7cd3ec 416 CurrentLang = GetEfiGlobalVariable (L"PlatformLang");\r
417 \r
418 Status = EFI_NOT_FOUND;\r
419 BestLanguage = GetBestLanguage (\r
420 Languages,\r
421 FALSE,\r
422 (CurrentLang != NULL) ? CurrentLang : "",\r
423 (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang),\r
424 Languages,\r
425 NULL\r
426 );\r
427 if (BestLanguage != NULL ) {\r
428 Status = mHiiStringProt->GetString (\r
08e4b3cf 429 mHiiStringProt,\r
ea7cd3ec 430 BestLanguage,\r
08e4b3cf 431 PackageList,\r
432 StringId,\r
433 String,\r
434 StringSize,\r
435 NULL\r
436 );\r
ea7cd3ec 437 FreePool (BestLanguage);\r
438 }\r
439 if (CurrentLang != NULL) {\r
440 FreePool (CurrentLang);\r
08e4b3cf 441 }\r
ea7cd3ec 442 FreePool (Languages);\r
08e4b3cf 443\r
444 return Status;\r
445}\r
446\r
447\r
448/**\r
449 Get string specified by StringId form the HiiHandle. The caller\r
450 is responsible to free the *String.\r
451\r
452 If String is NULL, then ASSERT.\r
453 If HiiHandle could not be found in the default HII database, then ASSERT.\r
454 If StringId is not found in PackageList, then ASSERT.\r
455\r
456 @param HiiHandle The HII handle of package list.\r
457 @param StringId The String ID.\r
458 @param String The output string.\r
459\r
460 @retval EFI_NOT_FOUND String is not found.\r
461 @retval EFI_SUCCESS Operation is successful.\r
462 @retval EFI_OUT_OF_RESOURCES There is not enought memory in the system.\r
463\r
464**/\r
465EFI_STATUS\r
466EFIAPI\r
467HiiLibGetStringFromHandle (\r
468 IN EFI_HII_HANDLE HiiHandle,\r
469 IN EFI_STRING_ID StringId,\r
470 OUT EFI_STRING *String\r
471 )\r
472{\r
473 EFI_STATUS Status;\r
474 UINTN StringSize;\r
475\r
476 ASSERT (String != NULL);\r
477\r
478 StringSize = HII_LIB_DEFAULT_STRING_SIZE;\r
479 *String = AllocateZeroPool (StringSize);\r
480 if (*String == NULL) {\r
481 return EFI_OUT_OF_RESOURCES;\r
482 }\r
483\r
484 Status = HiiLibGetString (HiiHandle, StringId, *String, &StringSize);\r
485 if (Status == EFI_BUFFER_TOO_SMALL) {\r
486 FreePool (*String);\r
487 *String = AllocateZeroPool (StringSize);\r
488 if (*String == NULL) {\r
489 return EFI_OUT_OF_RESOURCES;\r
490 }\r
491 Status = HiiLibGetString (HiiHandle, StringId, *String, &StringSize);\r
492 }\r
493\r
494 return Status;\r
495}\r
496\r
497\r
498\r
499/**\r
500 Convert language code from RFC3066 to ISO639-2.\r
501\r
502 @param LanguageRfc3066 RFC3066 language code.\r
503 @param LanguageIso639 ISO639-2 language code.\r
504\r
505 @retval EFI_SUCCESS Language code converted.\r
506 @retval EFI_NOT_FOUND Language code not found.\r
507\r
508**/\r
509EFI_STATUS\r
510EFIAPI\r
511ConvertRfc3066LanguageToIso639Language (\r
512 IN CHAR8 *LanguageRfc3066,\r
513 OUT CHAR8 *LanguageIso639\r
514 )\r
515{\r
516 UINTN Index;\r
517\r
518 if ((LanguageRfc3066[2] != '-') && (LanguageRfc3066[2] != 0)) {\r
519 CopyMem (LanguageIso639, LanguageRfc3066, 3);\r
520 return EFI_SUCCESS;\r
521 }\r
522\r
523 for (Index = 0; Iso639ToRfc3066ConversionTable[Index] != 0; Index += 5) {\r
524 if (CompareMem (LanguageRfc3066, &Iso639ToRfc3066ConversionTable[Index + 3], 2) == 0) {\r
525 CopyMem (LanguageIso639, &Iso639ToRfc3066ConversionTable[Index], 3);\r
526 return EFI_SUCCESS;\r
527 }\r
528 }\r
529\r
530 return EFI_NOT_FOUND;\r
531}\r
532\r
533\r
534/**\r
ea7cd3ec 535 Convert language code from ISO639-2 to RFC3066 and return the converted language.\r
536 Caller is responsible for freeing the allocated buffer.\r
08e4b3cf 537\r
538 LanguageIso639 contain a single ISO639-2 code such as\r
539 "eng" or "fra".\r
540\r
08e4b3cf 541 If LanguageIso639 is NULL, then ASSERT.\r
542 If LanguageRfc3066 is NULL, then ASSERT.\r
543\r
544 @param LanguageIso639 ISO639-2 language code.\r
08e4b3cf 545\r
ea7cd3ec 546 @return the allocated buffer or NULL, if the language is not found.\r
08e4b3cf 547\r
548**/\r
ea7cd3ec 549CHAR8*\r
08e4b3cf 550EFIAPI\r
551ConvertIso639LanguageToRfc3066Language (\r
ea7cd3ec 552 IN CONST CHAR8 *LanguageIso639\r
08e4b3cf 553 )\r
554{\r
555 UINTN Index;\r
556 \r
557 for (Index = 0; Iso639ToRfc3066ConversionTable[Index] != 0; Index += 5) {\r
558 if (CompareMem (LanguageIso639, &Iso639ToRfc3066ConversionTable[Index], 3) == 0) {\r
ea7cd3ec 559 return AllocateCopyPool (2, &Iso639ToRfc3066ConversionTable[Index + 3]);\r
08e4b3cf 560 }\r
561 }\r
562\r
ea7cd3ec 563 return NULL;\r
08e4b3cf 564}\r
565\r
566/**\r
567 Convert language code list from RFC3066 to ISO639-2, e.g. "en-US;fr-FR" will\r
568 be converted to "engfra".\r
569\r
570 @param SupportedLanguages The RFC3066 language list.\r
571\r
572 @return The ISO639-2 language list.\r
573\r
574**/\r
575CHAR8 *\r
576EFIAPI\r
577Rfc3066ToIso639 (\r
578 CHAR8 *SupportedLanguages\r
579 )\r
580{\r
581 CHAR8 *Languages;\r
582 CHAR8 *ReturnValue;\r
583 CHAR8 *LangCodes;\r
ea7cd3ec 584 CHAR8 *LangRfc3066;\r
08e4b3cf 585 CHAR8 LangIso639[ISO_639_2_ENTRY_SIZE];\r
ea7cd3ec 586 UINTN LanguageSize;\r
08e4b3cf 587 EFI_STATUS Status;\r
588\r
ea7cd3ec 589 LanguageSize = AsciiStrSize (SupportedLanguages);\r
590 ReturnValue = AllocateZeroPool (LanguageSize);\r
08e4b3cf 591 if (ReturnValue == NULL) {\r
592 return ReturnValue;\r
593 }\r
594\r
ea7cd3ec 595 //\r
596 // Allocate working buffer to contain substring in SupportedLanguages;\r
597 //\r
598 LangRfc3066 = AllocatePool (LanguageSize);\r
599 if (LangRfc3066 == NULL) {\r
600 FreePool (ReturnValue);\r
601 return NULL;\r
602 }\r
08e4b3cf 603 Languages = ReturnValue;\r
604 LangCodes = SupportedLanguages;\r
605 while (*LangCodes != 0) {\r
606 HiiLibGetNextLanguage (&LangCodes, LangRfc3066);\r
607\r
608 Status = ConvertRfc3066LanguageToIso639Language (LangRfc3066, LangIso639);\r
609 if (!EFI_ERROR (Status)) {\r
610 CopyMem (Languages, LangIso639, 3);\r
611 Languages = Languages + 3;\r
612 }\r
613 }\r
614\r
ea7cd3ec 615 FreePool (LangRfc3066);\r
08e4b3cf 616 return ReturnValue;\r
617}\r
618\r
619\r