]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/UefiHiiLib/HiiString.c
HII Library Class interface refine.
[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
cb7d01c0 166 This function create a new string in String Package or updates an existing \r
167 string in a String Package. If StringId is 0, then a new string is added to\r
168 a String Package. If StringId is not zero, then a string in String Package is\r
169 updated. If SupportedLanguages is NULL, then the string is added or updated\r
170 for all the languages that the String Package supports. If SupportedLanguages\r
171 is not NULL, then the string is added or updated for the set of languages \r
172 specified by SupportedLanguages.\r
173 \r
174 If HiiHandle is NULL, then ASSERT().\r
175 If String is NULL, then ASSERT().\r
176\r
177 @param[in] HiiHandle A handle that was previously registered in the \r
178 HII Database.\r
179 @param[in] StringId If zero, then a new string is created in the \r
180 String Package associated with HiiHandle. If \r
181 non-zero, then the string specified by StringId \r
182 is updated in the String Package associated \r
183 with HiiHandle. \r
184 @param[in] String A pointer to the Null-terminated Unicode string \r
185 to add or update in the String Package associated \r
186 with HiiHandle.\r
187 @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string of \r
188 language codes. If this parameter is NULL, then \r
189 String is added or updated in the String Package \r
190 associated with HiiHandle for all the languages \r
191 that the String Package supports. If this \r
192 parameter is not NULL, then then String is added \r
193 or updated in the String Package associated with \r
194 HiiHandle for the set oflanguages specified by \r
195 SupportedLanguages. The format of \r
196 SupportedLanguages must follow the language \r
197 format assumed the HII Database.\r
198\r
199 @retval 0 The string could not be added or updated in the String Package.\r
200 @retval Other The EFI_STRING_ID of the newly added or updated string.\r
08e4b3cf 201\r
202**/\r
cb7d01c0 203EFI_STRING_ID\r
08e4b3cf 204EFIAPI\r
cb7d01c0 205HiiSetString (\r
206 IN EFI_HII_HANDLE HiiHandle,\r
207 IN EFI_STRING_ID StringId, OPTIONAL\r
208 IN CONST EFI_STRING String,\r
209 IN CONST CHAR8 *SupportedLanguages OPTIONAL\r
08e4b3cf 210 )\r
211{\r
cb7d01c0 212 EFI_STATUS Status;\r
213 CHAR8 *AllocatedLanguages;\r
214 CHAR8 *Supported;\r
215 CHAR8 *Language;\r
216 EFI_STRING_ID NewStringId;\r
08e4b3cf 217\r
cb7d01c0 218 ASSERT (HiiHandle != NULL);\r
08e4b3cf 219 ASSERT (String != NULL);\r
08e4b3cf 220\r
cb7d01c0 221 if (SupportedLanguages == NULL) {\r
222 //\r
223 // Retrieve the languages that the package specified by HiiHandle supports\r
224 //\r
225 AllocatedLanguages = HiiGetSupportedLanguages (HiiHandle);\r
226 } else {\r
227 //\r
228 // Allocate a copy of the SupportLanguages string that passed in\r
229 //\r
230 AllocatedLanguages = AllocateCopyPool (AsciiStrLen (SupportedLanguages), SupportedLanguages);\r
231 }\r
08e4b3cf 232\r
ea7cd3ec 233 //\r
cb7d01c0 234 // If there are not enough resources for the supported languages string, then return a StringId of 0\r
ea7cd3ec 235 //\r
cb7d01c0 236 if (AllocatedLanguages == NULL) {\r
237 return (EFI_STRING_ID)(0);\r
238 }\r
08e4b3cf 239\r
cb7d01c0 240 NewStringId = 0;\r
241 Status = EFI_INVALID_PARAMETER;\r
242 //\r
243 // Loop through each language that the string supports\r
244 //\r
245 for (Supported = AllocatedLanguages; *Supported != '\0'; ) {\r
246 //\r
247 // Cache a pointer to the beginning of the current language in the list of languages\r
248 //\r
249 Language = Supported;\r
08e4b3cf 250\r
251 //\r
cb7d01c0 252 // Search for the next language seperator and replace it with a Null-terminator\r
08e4b3cf 253 //\r
cb7d01c0 254 for (; *Supported != 0 && *Supported != ';'; Supported++);\r
255 if (*Supported != 0) {\r
256 *(Supported++) = '\0';\r
08e4b3cf 257 }\r
08e4b3cf 258\r
cb7d01c0 259 //\r
260 // If StringId is 0, then call NewString(). Otherwise, call SetString()\r
261 //\r
262 if (StringId == (EFI_STRING_ID)(0)) {\r
263 Status = gHiiString->NewString (gHiiString, HiiHandle, &NewStringId, Language, NULL, String, NULL);\r
264 } else {\r
265 Status = gHiiString->SetString (gHiiString, HiiHandle, StringId, Language, String, NULL);\r
266 }\r
08e4b3cf 267\r
268 //\r
cb7d01c0 269 // If there was an error, then break out of the loop and return a StringId of 0\r
08e4b3cf 270 //\r
08e4b3cf 271 if (EFI_ERROR (Status)) {\r
272 break;\r
273 }\r
274 }\r
275\r
cb7d01c0 276 //\r
277 // Free the buffer of supported languages\r
278 //\r
279 FreePool (AllocatedLanguages);\r
280\r
281 if (EFI_ERROR (Status)) {\r
282 return (EFI_STRING_ID)(0);\r
283 } else if (StringId == (EFI_STRING_ID)(0)) {\r
284 return NewStringId;\r
285 } else {\r
286 return StringId;\r
287 }\r
08e4b3cf 288}\r
289\r
290\r
291/**\r
cb7d01c0 292 Retrieves a string from a string package names by GUID in a specific language. \r
293 If the language is not specified, then a string from a string package in the \r
294 current platform language is retrieved. If the string can not be retrieved \r
295 using the specified language or the current platform language, then the string \r
296 is retrieved from the string package in the first language the string package \r
297 supports. The returned string is allocated using AllocatePool(). The caller \r
298 is responsible for freeing the allocated buffer using FreePool().\r
299 \r
300 If PackageListGuid is NULL, then ASSERT().\r
301 If StringId is 0, then ASSERT.\r
302\r
303 @param[in] PackageListGuid The GUID of a package list that was previously \r
304 registered in the HII Database.\r
305 @param[in] StringId The identifier of the string to retrieved from the \r
306 string package associated with PackageListGuid.\r
307 @param[in] Language The language of the string to retrieve. If this \r
308 parameter is NULL, then the current platform \r
309 language is used. The format of Language must \r
310 follow the language format assumed the HII Database.\r
311\r
312 @retval NULL The package list specified by PackageListGuid is not present in the\r
313 HII Database.\r
314 @retval NULL The string specified by StringId is not present in the string package.\r
315 @retval Other The string was returned.\r
08e4b3cf 316\r
317**/\r
cb7d01c0 318EFI_STRING\r
08e4b3cf 319EFIAPI\r
cb7d01c0 320HiiGetPackageString (\r
321 IN CONST EFI_GUID *PackageListGuid,\r
322 IN EFI_STRING_ID StringId,\r
323 IN CONST CHAR8 *Language OPTIONAL\r
08e4b3cf 324 )\r
325{\r
cb7d01c0 326 EFI_HANDLE *HiiHandleBuffer;\r
327 EFI_HANDLE HiiHandle;\r
08e4b3cf 328\r
cb7d01c0 329 ASSERT (PackageListGuid != NULL);\r
08e4b3cf 330\r
cb7d01c0 331 HiiHandleBuffer = HiiGetHiiHandles (PackageListGuid);\r
332 if (HiiHandleBuffer == NULL) {\r
333 return NULL;\r
08e4b3cf 334 }\r
335\r
cb7d01c0 336 HiiHandle = HiiHandleBuffer[0];\r
4a1102c9 337 FreePool (HiiHandleBuffer);\r
338\r
cb7d01c0 339 return HiiGetString (HiiHandle, StringId, Language);\r
08e4b3cf 340}\r
341\r
342/**\r
cb7d01c0 343 Retrieves a string from a string package in a specific language. If the language\r
344 is not specified, then a string from a string package in the current platform \r
345 language is retrieved. If the string can not be retrieved using the specified \r
346 language or the current platform language, then the string is retrieved from \r
347 the string package in the first language the string package supports. The \r
348 returned string is allocated using AllocatePool(). The caller is responsible \r
349 for freeing the allocated buffer using FreePool().\r
350 \r
351 If HiiHandle is NULL, then ASSERT().\r
352 If StringId is 0, then ASSET.\r
353\r
354 @param[in] HiiHandle A handle that was previously registered in the HII Database.\r
355 @param[in] StringId The identifier of the string to retrieved from the string \r
356 package associated with HiiHandle.\r
357 @param[in] Language The language of the string to retrieve. If this parameter \r
358 is NULL, then the current platform language is used. The \r
359 format of Language must follow the language format assumed \r
360 the HII Database.\r
361\r
362 @retval NULL The string specified by StringId is not present in the string package.\r
363 @retval Other The string was returned.\r
08e4b3cf 364\r
365**/\r
cb7d01c0 366EFI_STRING\r
08e4b3cf 367EFIAPI\r
cb7d01c0 368HiiGetString (\r
369 IN EFI_HII_HANDLE HiiHandle,\r
370 IN EFI_STRING_ID StringId,\r
371 IN CONST CHAR8 *Language OPTIONAL\r
08e4b3cf 372 )\r
373{\r
374 EFI_STATUS Status;\r
cb7d01c0 375 UINTN StringSize;\r
376 CHAR16 TempString;\r
377 EFI_STRING String;\r
378 CHAR8 *SupportedLanguages;\r
379 CHAR8 *PlatformLanguage;\r
ea7cd3ec 380 CHAR8 *BestLanguage;\r
08e4b3cf 381\r
cb7d01c0 382 ASSERT (HiiHandle != NULL);\r
383 ASSERT (StringId != 0);\r
08e4b3cf 384\r
cb7d01c0 385 //\r
386 // Initialize all allocated buffers to NULL\r
387 // \r
388 SupportedLanguages = NULL;\r
389 PlatformLanguage = NULL;\r
390 BestLanguage = NULL;\r
391 String = NULL;\r
08e4b3cf 392\r
cb7d01c0 393 //\r
394 // Get the languages that the package specified by HiiHandle supports\r
395 //\r
396 SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);\r
397 if (SupportedLanguages == NULL) {\r
398 goto Error;\r
08e4b3cf 399 }\r
400\r
cb7d01c0 401 //\r
402 // Get the current platform language setting\r
403 //\r
404 PlatformLanguage = GetEfiGlobalVariable (L"PlatformLang");\r
08e4b3cf 405\r
cb7d01c0 406 //\r
407 // If Languag is NULL, then set it to an empty string, so it will be \r
408 // skipped by GetBestLanguage()\r
409 //\r
410 if (Language == NULL) {\r
411 Language = "";\r
412 }\r
08e4b3cf 413\r
cb7d01c0 414 //\r
415 // Get the best matching language from SupportedLanguages\r
416 //\r
417 BestLanguage = GetBestLanguage (\r
418 SupportedLanguages, \r
419 FALSE, // RFC 4646 mode\r
420 Language, // Highest priority \r
421 PlatformLanguage != NULL ? PlatformLanguage : "", // Next highest priority\r
422 SupportedLanguages, // Lowest priority \r
423 NULL\r
424 );\r
425 if (BestLanguage == NULL) {\r
426 goto Error;\r
427 }\r
08e4b3cf 428\r
cb7d01c0 429 //\r
430 // Retrieve the size of the string in the string package for the BestLanguage\r
431 //\r
432 StringSize = 0;\r
433 Status = gHiiString->GetString (\r
434 gHiiString,\r
435 BestLanguage,\r
436 HiiHandle,\r
437 StringId,\r
438 &TempString,\r
439 &StringSize,\r
440 NULL\r
441 );\r
442 //\r
443 // If GetString() returns EFI_SUCCESS for a zero size, \r
444 // then there are no supported languages registered for HiiHandle. If GetString() \r
445 // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present\r
446 // in the HII Database\r
447 //\r
448 if (Status != EFI_BUFFER_TOO_SMALL) {\r
449 goto Error;\r
450 }\r
08e4b3cf 451\r
cb7d01c0 452 //\r
453 // Allocate a buffer for the return string\r
454 //\r
455 String = AllocateZeroPool (StringSize);\r
456 if (String == NULL) {\r
457 goto Error;\r
458 }\r
08e4b3cf 459\r
cb7d01c0 460 //\r
461 // Retrieve the string from the string package\r
462 //\r
463 Status = gHiiString->GetString (\r
464 gHiiString,\r
465 BestLanguage,\r
466 HiiHandle,\r
467 StringId,\r
468 String,\r
469 &StringSize,\r
470 NULL\r
471 );\r
472 if (EFI_ERROR (Status)) {\r
473 //\r
474 // Free the buffer and return NULL if the supported languages can not be retrieved.\r
475 //\r
476 FreePool (String);\r
477 String = NULL;\r
08e4b3cf 478 }\r
479\r
cb7d01c0 480Error:\r
481 //\r
482 // Free allocated buffers\r
483 //\r
484 if (SupportedLanguages != NULL) {\r
485 FreePool (SupportedLanguages);\r
486 }\r
487 if (PlatformLanguage != NULL) {\r
488 FreePool (PlatformLanguage);\r
489 }\r
490 if (BestLanguage != NULL) {\r
491 FreePool (BestLanguage);\r
08e4b3cf 492 }\r
493\r
cb7d01c0 494 //\r
495 // Return the Null-terminated Unicode string\r
496 //\r
497 return String;\r
08e4b3cf 498}\r
499\r
08e4b3cf 500/**\r
501 Convert language code from RFC3066 to ISO639-2.\r
502\r
503 @param LanguageRfc3066 RFC3066 language code.\r
504 @param LanguageIso639 ISO639-2 language code.\r
505\r
506 @retval EFI_SUCCESS Language code converted.\r
507 @retval EFI_NOT_FOUND Language code not found.\r
508\r
509**/\r
510EFI_STATUS\r
511EFIAPI\r
512ConvertRfc3066LanguageToIso639Language (\r
513 IN CHAR8 *LanguageRfc3066,\r
514 OUT CHAR8 *LanguageIso639\r
515 )\r
516{\r
517 UINTN Index;\r
518\r
519 if ((LanguageRfc3066[2] != '-') && (LanguageRfc3066[2] != 0)) {\r
520 CopyMem (LanguageIso639, LanguageRfc3066, 3);\r
521 return EFI_SUCCESS;\r
522 }\r
523\r
524 for (Index = 0; Iso639ToRfc3066ConversionTable[Index] != 0; Index += 5) {\r
525 if (CompareMem (LanguageRfc3066, &Iso639ToRfc3066ConversionTable[Index + 3], 2) == 0) {\r
526 CopyMem (LanguageIso639, &Iso639ToRfc3066ConversionTable[Index], 3);\r
527 return EFI_SUCCESS;\r
528 }\r
529 }\r
530\r
531 return EFI_NOT_FOUND;\r
532}\r
533\r
534\r
535/**\r
ea7cd3ec 536 Convert language code from ISO639-2 to RFC3066 and return the converted language.\r
537 Caller is responsible for freeing the allocated buffer.\r
08e4b3cf 538\r
539 LanguageIso639 contain a single ISO639-2 code such as\r
540 "eng" or "fra".\r
541\r
08e4b3cf 542 If LanguageIso639 is NULL, then ASSERT.\r
543 If LanguageRfc3066 is NULL, then ASSERT.\r
544\r
545 @param LanguageIso639 ISO639-2 language code.\r
08e4b3cf 546\r
ea7cd3ec 547 @return the allocated buffer or NULL, if the language is not found.\r
08e4b3cf 548\r
549**/\r
ea7cd3ec 550CHAR8*\r
08e4b3cf 551EFIAPI\r
552ConvertIso639LanguageToRfc3066Language (\r
ea7cd3ec 553 IN CONST CHAR8 *LanguageIso639\r
08e4b3cf 554 )\r
555{\r
556 UINTN Index;\r
b1a4c981 557 CHAR8 *Rfc3066Language;\r
08e4b3cf 558 \r
559 for (Index = 0; Iso639ToRfc3066ConversionTable[Index] != 0; Index += 5) {\r
560 if (CompareMem (LanguageIso639, &Iso639ToRfc3066ConversionTable[Index], 3) == 0) {\r
b1a4c981 561 Rfc3066Language = AllocateZeroPool (3);\r
562 if (Rfc3066Language != NULL) {\r
563 Rfc3066Language = CopyMem (Rfc3066Language, &Iso639ToRfc3066ConversionTable[Index + 3], 2);\r
564 }\r
565 return Rfc3066Language;\r
08e4b3cf 566 }\r
567 }\r
568\r
ea7cd3ec 569 return NULL;\r
08e4b3cf 570}\r
571\r
572/**\r
573 Convert language code list from RFC3066 to ISO639-2, e.g. "en-US;fr-FR" will\r
574 be converted to "engfra".\r
575\r
576 @param SupportedLanguages The RFC3066 language list.\r
577\r
578 @return The ISO639-2 language list.\r
579\r
580**/\r
581CHAR8 *\r
582EFIAPI\r
583Rfc3066ToIso639 (\r
584 CHAR8 *SupportedLanguages\r
585 )\r
586{\r
587 CHAR8 *Languages;\r
588 CHAR8 *ReturnValue;\r
589 CHAR8 *LangCodes;\r
ea7cd3ec 590 CHAR8 *LangRfc3066;\r
08e4b3cf 591 CHAR8 LangIso639[ISO_639_2_ENTRY_SIZE];\r
ea7cd3ec 592 UINTN LanguageSize;\r
08e4b3cf 593 EFI_STATUS Status;\r
594\r
ea7cd3ec 595 LanguageSize = AsciiStrSize (SupportedLanguages);\r
596 ReturnValue = AllocateZeroPool (LanguageSize);\r
08e4b3cf 597 if (ReturnValue == NULL) {\r
598 return ReturnValue;\r
599 }\r
600\r
ea7cd3ec 601 //\r
602 // Allocate working buffer to contain substring in SupportedLanguages;\r
603 //\r
604 LangRfc3066 = AllocatePool (LanguageSize);\r
605 if (LangRfc3066 == NULL) {\r
606 FreePool (ReturnValue);\r
607 return NULL;\r
608 }\r
08e4b3cf 609 Languages = ReturnValue;\r
610 LangCodes = SupportedLanguages;\r
611 while (*LangCodes != 0) {\r
612 HiiLibGetNextLanguage (&LangCodes, LangRfc3066);\r
613\r
614 Status = ConvertRfc3066LanguageToIso639Language (LangRfc3066, LangIso639);\r
615 if (!EFI_ERROR (Status)) {\r
616 CopyMem (Languages, LangIso639, 3);\r
617 Languages = Languages + 3;\r
618 }\r
619 }\r
620\r
ea7cd3ec 621 FreePool (LangRfc3066);\r
08e4b3cf 622 return ReturnValue;\r
623}\r
624\r
625\r