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