]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/UefiHiiLib/HiiString.c
Add in an ASSERT to check the return of HiiLibGetSupportedLanguages. This function...
[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 ASSERT (Languages != NULL);
203
204 LangStrings = Languages;
205 while (*LangStrings != 0) {
206 HiiLibGetNextLanguage (&LangStrings, Lang);
207
208 //
209 // For each language supported by the package,
210 // a string token is created.
211 //
212 Status = mHiiStringProt->NewString (
213 mHiiStringProt,
214 PackageList,
215 StringId,
216 Lang,
217 NULL,
218 String,
219 NULL
220 );
221 if (EFI_ERROR (Status)) {
222 break;
223 }
224 }
225
226 FreePool (Languages);
227
228 return Status;
229
230 }
231
232
233 /**
234 This function update the specified string in String Package of each language
235 supported by the package list.
236
237 If String is NULL, then ASSERT.
238 If PackageList could not be found in the default HII database, then ASSERT.
239 If StringId is not found in PackageList, then ASSERT.
240
241 @param PackageList Handle of the package list where this string will
242 be added.
243 @param StringId Ths String Id to be updated.
244 @param String Points to the new null-terminated string.
245
246 @retval EFI_SUCCESS The new string was added successfully.
247 @retval EFI_OUT_OF_RESOURCES Could not add the string due to lack of resources.
248
249 **/
250 EFI_STATUS
251 EFIAPI
252 HiiLibSetString (
253 IN EFI_HII_HANDLE PackageList,
254 IN EFI_STRING_ID StringId,
255 IN CONST EFI_STRING String
256 )
257 {
258 EFI_STATUS Status;
259 CHAR8 *Languages;
260 CHAR8 *LangStrings;
261 CHAR8 Lang[RFC_3066_ENTRY_SIZE];
262
263 ASSERT (IsHiiHandleRegistered (PackageList));
264
265 Status = EFI_SUCCESS;
266
267 Languages = HiiLibGetSupportedLanguages (PackageList);
268 ASSERT (Languages != NULL);
269
270 LangStrings = Languages;
271 while (*LangStrings != 0) {
272 HiiLibGetNextLanguage (&LangStrings, Lang);
273
274 //
275 // For each language supported by the package,
276 // the string is updated.
277 //
278 Status = mHiiStringProt->SetString (
279 mHiiStringProt,
280 PackageList,
281 StringId,
282 Lang,
283 String,
284 NULL
285 );
286 if (EFI_ERROR (Status)) {
287 break;
288 }
289 }
290
291 FreePool (Languages);
292
293 return Status;
294 }
295
296
297 /**
298 Get the string given the StringId and String package Producer's Guid. The caller
299 is responsible to free the *String.
300
301 If PackageList with the matching ProducerGuid is not found, then ASSERT.
302 If PackageList with the matching ProducerGuid is found but no String is
303 specified by StringId is found, then ASSERT.
304
305 @param ProducerGuid The Guid of String package list.
306 @param StringId The String ID.
307 @param String The output string.
308
309 @retval EFI_SUCCESS Operation is successful.
310 @retval EFI_OUT_OF_RESOURCES There is not enought memory in the system.
311
312 **/
313 EFI_STATUS
314 EFIAPI
315 HiiLibGetStringFromToken (
316 IN EFI_GUID *ProducerGuid,
317 IN EFI_STRING_ID StringId,
318 OUT EFI_STRING *String
319 )
320 {
321 EFI_STATUS Status;
322 UINTN Index;
323 UINTN HandleBufferLen;
324 EFI_HII_HANDLE *HiiHandleBuffer;
325 EFI_GUID Guid;
326
327 Status = HiiLibGetHiiHandles (&HandleBufferLen, &HiiHandleBuffer);
328 if (EFI_ERROR(Status)) {
329 return Status;
330 }
331 for (Index = 0; Index < (HandleBufferLen / sizeof (EFI_HII_HANDLE)); Index++) {
332 Status = HiiLibExtractGuidFromHiiHandle (HiiHandleBuffer[Index], &Guid);
333 if (EFI_ERROR(Status)) {
334 return Status;
335 }
336 if (CompareGuid (&Guid, ProducerGuid)) {
337 break;
338 }
339 }
340
341 if (Index >= (HandleBufferLen / sizeof (EFI_HII_HANDLE))) {
342 //
343 // If PackageList with the matching ProducerGuid is not found, then ASSERT.
344 //
345 ASSERT (FALSE);
346 Status = EFI_NOT_FOUND;
347 goto Out;
348 }
349
350 Status = HiiLibGetStringFromHandle (HiiHandleBuffer[Index], StringId, String);
351
352 Out:
353 if (HiiHandleBuffer != NULL) {
354 FreePool (HiiHandleBuffer);
355 }
356 return Status;
357 }
358
359 /**
360 This function try to retrieve string from String package of current language.
361 If fails, it try to retrieve string from String package of first language it support.
362
363 If StringSize is NULL, then ASSERT.
364 If String is NULL and *StringSize is not 0, then ASSERT.
365 If PackageList could not be found in the default HII database, then ASSERT.
366 If StringId is not found in PackageList, then ASSERT.
367
368 @param PackageList The package list in the HII database to search for
369 the specified string.
370 @param StringId The string's id, which is unique within
371 PackageList.
372 @param String Points to the new null-terminated string.
373 @param StringSize On entry, points to the size of the buffer pointed
374 to by String, in bytes. On return, points to the
375 length of the string, in bytes.
376
377 @retval EFI_SUCCESS The string was returned successfully.
378 @retval EFI_NOT_FOUND The string specified by StringId is not available.
379 @retval EFI_BUFFER_TOO_SMALL The buffer specified by StringLength is too small
380 to hold the string.
381
382 **/
383 EFI_STATUS
384 EFIAPI
385 HiiLibGetString (
386 IN EFI_HII_HANDLE PackageList,
387 IN EFI_STRING_ID StringId,
388 OUT EFI_STRING String,
389 IN OUT UINTN *StringSize
390 )
391 {
392 EFI_STATUS Status;
393 CHAR8 *Languages;
394 CHAR8 *LangStrings;
395 CHAR8 Lang[RFC_3066_ENTRY_SIZE];
396 CHAR8 CurrentLang[RFC_3066_ENTRY_SIZE];
397
398 ASSERT (StringSize != NULL);
399 ASSERT (!(*StringSize != 0 && String == NULL));
400 ASSERT (IsHiiHandleRegistered (PackageList));
401
402 GetCurrentLanguage (CurrentLang);
403
404 Status = mHiiStringProt->GetString (
405 mHiiStringProt,
406 CurrentLang,
407 PackageList,
408 StringId,
409 String,
410 StringSize,
411 NULL
412 );
413
414 if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
415 Languages = HiiLibGetSupportedLanguages (PackageList);
416 ASSERT (Languages != NULL);
417
418 LangStrings = Languages;
419 HiiLibGetNextLanguage (&LangStrings, Lang);
420 FreePool (Languages);
421
422 Status = mHiiStringProt->GetString (
423 mHiiStringProt,
424 Lang,
425 PackageList,
426 StringId,
427 String,
428 StringSize,
429 NULL
430 );
431 }
432
433 return Status;
434 }
435
436
437 /**
438 Get string specified by StringId form the HiiHandle. The caller
439 is responsible to free the *String.
440
441 If String is NULL, then ASSERT.
442 If HiiHandle could not be found in the default HII database, then ASSERT.
443 If StringId is not found in PackageList, then ASSERT.
444
445 @param HiiHandle The HII handle of package list.
446 @param StringId The String ID.
447 @param String The output string.
448
449 @retval EFI_NOT_FOUND String is not found.
450 @retval EFI_SUCCESS Operation is successful.
451 @retval EFI_OUT_OF_RESOURCES There is not enought memory in the system.
452
453 **/
454 EFI_STATUS
455 EFIAPI
456 HiiLibGetStringFromHandle (
457 IN EFI_HII_HANDLE HiiHandle,
458 IN EFI_STRING_ID StringId,
459 OUT EFI_STRING *String
460 )
461 {
462 EFI_STATUS Status;
463 UINTN StringSize;
464
465 ASSERT (String != NULL);
466
467 StringSize = HII_LIB_DEFAULT_STRING_SIZE;
468 *String = AllocateZeroPool (StringSize);
469 if (*String == NULL) {
470 return EFI_OUT_OF_RESOURCES;
471 }
472
473 Status = HiiLibGetString (HiiHandle, StringId, *String, &StringSize);
474 if (Status == EFI_BUFFER_TOO_SMALL) {
475 FreePool (*String);
476 *String = AllocateZeroPool (StringSize);
477 if (*String == NULL) {
478 return EFI_OUT_OF_RESOURCES;
479 }
480 Status = HiiLibGetString (HiiHandle, StringId, *String, &StringSize);
481 }
482
483 return Status;
484 }
485
486
487
488 /**
489 Convert language code from RFC3066 to ISO639-2.
490
491 @param LanguageRfc3066 RFC3066 language code.
492 @param LanguageIso639 ISO639-2 language code.
493
494 @retval EFI_SUCCESS Language code converted.
495 @retval EFI_NOT_FOUND Language code not found.
496
497 **/
498 EFI_STATUS
499 EFIAPI
500 ConvertRfc3066LanguageToIso639Language (
501 IN CHAR8 *LanguageRfc3066,
502 OUT CHAR8 *LanguageIso639
503 )
504 {
505 UINTN Index;
506
507 if ((LanguageRfc3066[2] != '-') && (LanguageRfc3066[2] != 0)) {
508 CopyMem (LanguageIso639, LanguageRfc3066, 3);
509 return EFI_SUCCESS;
510 }
511
512 for (Index = 0; Iso639ToRfc3066ConversionTable[Index] != 0; Index += 5) {
513 if (CompareMem (LanguageRfc3066, &Iso639ToRfc3066ConversionTable[Index + 3], 2) == 0) {
514 CopyMem (LanguageIso639, &Iso639ToRfc3066ConversionTable[Index], 3);
515 return EFI_SUCCESS;
516 }
517 }
518
519 return EFI_NOT_FOUND;
520 }
521
522
523 /**
524 Convert language code from ISO639-2 to RFC3066.
525
526 LanguageIso639 contain a single ISO639-2 code such as
527 "eng" or "fra".
528
529 The LanguageRfc3066 must be a buffer large enough
530 for RFC_3066_ENTRY_SIZE characters.
531
532 If LanguageIso639 is NULL, then ASSERT.
533 If LanguageRfc3066 is NULL, then ASSERT.
534
535 @param LanguageIso639 ISO639-2 language code.
536 @param LanguageRfc3066 RFC3066 language code.
537
538 @retval EFI_SUCCESS Language code converted.
539 @retval EFI_NOT_FOUND Language code not found.
540
541 **/
542 EFI_STATUS
543 EFIAPI
544 ConvertIso639LanguageToRfc3066Language (
545 IN CONST CHAR8 *LanguageIso639,
546 OUT CHAR8 *LanguageRfc3066
547 )
548 {
549 UINTN Index;
550
551 for (Index = 0; Iso639ToRfc3066ConversionTable[Index] != 0; Index += 5) {
552 if (CompareMem (LanguageIso639, &Iso639ToRfc3066ConversionTable[Index], 3) == 0) {
553 CopyMem (LanguageRfc3066, &Iso639ToRfc3066ConversionTable[Index + 3], 2);
554 return EFI_SUCCESS;
555 }
556 }
557
558 return EFI_NOT_FOUND;
559 }
560
561 /**
562 Convert language code list from RFC3066 to ISO639-2, e.g. "en-US;fr-FR" will
563 be converted to "engfra".
564
565 @param SupportedLanguages The RFC3066 language list.
566
567 @return The ISO639-2 language list.
568
569 **/
570 CHAR8 *
571 EFIAPI
572 Rfc3066ToIso639 (
573 CHAR8 *SupportedLanguages
574 )
575 {
576 CHAR8 *Languages;
577 CHAR8 *ReturnValue;
578 CHAR8 *LangCodes;
579 CHAR8 LangRfc3066[RFC_3066_ENTRY_SIZE];
580 CHAR8 LangIso639[ISO_639_2_ENTRY_SIZE];
581 EFI_STATUS Status;
582
583 ReturnValue = AllocateZeroPool (AsciiStrSize (SupportedLanguages));
584 if (ReturnValue == NULL) {
585 return ReturnValue;
586 }
587
588 Languages = ReturnValue;
589 LangCodes = SupportedLanguages;
590 while (*LangCodes != 0) {
591 HiiLibGetNextLanguage (&LangCodes, LangRfc3066);
592
593 Status = ConvertRfc3066LanguageToIso639Language (LangRfc3066, LangIso639);
594 if (!EFI_ERROR (Status)) {
595 CopyMem (Languages, LangIso639, 3);
596 Languages = Languages + 3;
597 }
598 }
599
600 return ReturnValue;
601 }
602
603