]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Compatibility/FrameworkHiiOnUefiHiiThunk/Strings.c
Retire language conversion APIs from HII library class.
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiOnUefiHiiThunk / Strings.c
1 /**@file
2 This file implements the protocol functions related to string package.
3
4 Copyright (c) 2006 - 2008, Intel Corporation
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 "HiiDatabase.h"
17
18 typedef struct {
19 CHAR8 *Iso639;
20 CHAR8 *Rfc3066;
21 } ISO639TORFC3066MAP;
22
23 ISO639TORFC3066MAP Iso639ToRfc3066Map [] = {
24 {"eng", "en-US"},
25 {"fra", "fr-FR"},
26 };
27
28 //
29 // Lookup table of ISO639-2 3 character language codes to ISO 639-1 2 character language codes
30 // Each entry is 5 CHAR8 values long. The first 3 CHAR8 values are the ISO 639-2 code.
31 // The last 2 CHAR8 values are the ISO 639-1 code.
32 //
33 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 Iso639ToRfc3066ConversionTable[] =
34 "\
35 aaraa\
36 abkab\
37 afraf\
38 amham\
39 araar\
40 asmas\
41 aymay\
42 azeaz\
43 bakba\
44 belbe\
45 benbn\
46 bihbh\
47 bisbi\
48 bodbo\
49 brebr\
50 bulbg\
51 catca\
52 cescs\
53 corkw\
54 cosco\
55 cymcy\
56 danda\
57 deude\
58 dzodz\
59 ellel\
60 engen\
61 epoeo\
62 estet\
63 euseu\
64 faofo\
65 fasfa\
66 fijfj\
67 finfi\
68 frafr\
69 fryfy\
70 gaiga\
71 gdhgd\
72 glggl\
73 grngn\
74 gujgu\
75 hauha\
76 hebhe\
77 hinhi\
78 hrvhr\
79 hunhu\
80 hyehy\
81 ikuiu\
82 ileie\
83 inaia\
84 indid\
85 ipkik\
86 islis\
87 itait\
88 jawjw\
89 jpnja\
90 kalkl\
91 kankn\
92 kasks\
93 katka\
94 kazkk\
95 khmkm\
96 kinrw\
97 kirky\
98 korko\
99 kurku\
100 laolo\
101 latla\
102 lavlv\
103 linln\
104 litlt\
105 ltzlb\
106 malml\
107 marmr\
108 mkdmk\
109 mlgmg\
110 mltmt\
111 molmo\
112 monmn\
113 mrimi\
114 msams\
115 myamy\
116 nauna\
117 nepne\
118 nldnl\
119 norno\
120 ocioc\
121 ormom\
122 panpa\
123 polpl\
124 porpt\
125 pusps\
126 quequ\
127 rohrm\
128 ronro\
129 runrn\
130 rusru\
131 sagsg\
132 sansa\
133 sinsi\
134 slksk\
135 slvsl\
136 smise\
137 smosm\
138 snasn\
139 sndsd\
140 somso\
141 sotst\
142 spaes\
143 sqisq\
144 srpsr\
145 sswss\
146 sunsu\
147 swasw\
148 swesv\
149 tamta\
150 tattt\
151 telte\
152 tgktg\
153 tgltl\
154 thath\
155 tsnts\
156 tuktk\
157 twitw\
158 uigug\
159 ukruk\
160 urdur\
161 uzbuz\
162 vievi\
163 volvo\
164 wolwo\
165 xhoxh\
166 yidyi\
167 zhaza\
168 zhozh\
169 zulzu\
170 ";
171
172 CHAR8 *
173 ConvertIso639ToRfc3066 (
174 CHAR8 *Iso638Lang
175 )
176 {
177 UINTN Index;
178 CHAR8 AsciiLanguage[ISO_639_2_ENTRY_SIZE + 1];
179
180 AsciiStrnCpy (AsciiLanguage, Iso638Lang, sizeof (AsciiLanguage));
181 for (Index = 0; Index < ISO_639_2_ENTRY_SIZE + 1; Index ++) {
182 if (AsciiLanguage [Index] == 0) {
183 break;
184 } else if (AsciiLanguage [Index] >= 'A' && AsciiLanguage [Index] <= 'Z') {
185 AsciiLanguage [Index] = (CHAR8) (AsciiLanguage [Index] - 'A' + 'a');
186 }
187 }
188
189 for (Index = 0; Index < sizeof (Iso639ToRfc3066Map) / sizeof (Iso639ToRfc3066Map[0]); Index++) {
190 if (AsciiStrnCmp (AsciiLanguage, Iso639ToRfc3066Map[Index].Iso639, AsciiStrSize (AsciiLanguage)) == 0) {
191 return Iso639ToRfc3066Map[Index].Rfc3066;
192 }
193 }
194
195 return (CHAR8 *) NULL;
196 }
197
198 /**
199 Convert language code from RFC3066 to ISO639-2.
200
201 @param LanguageRfc3066 RFC3066 language code.
202 @param LanguageIso639 ISO639-2 language code.
203
204 @retval EFI_SUCCESS Language code converted.
205 @retval EFI_NOT_FOUND Language code not found.
206
207 **/
208 EFI_STATUS
209 EFIAPI
210 ConvertRfc3066LanguageToIso639Language (
211 IN CHAR8 *LanguageRfc3066,
212 OUT CHAR8 *LanguageIso639
213 )
214 {
215 UINTN Index;
216
217 if ((LanguageRfc3066[2] != '-') && (LanguageRfc3066[2] != 0)) {
218 CopyMem (LanguageIso639, LanguageRfc3066, 3);
219 return EFI_SUCCESS;
220 }
221
222 for (Index = 0; Iso639ToRfc3066ConversionTable[Index] != 0; Index += 5) {
223 if (CompareMem (LanguageRfc3066, &Iso639ToRfc3066ConversionTable[Index + 3], 2) == 0) {
224 CopyMem (LanguageIso639, &Iso639ToRfc3066ConversionTable[Index], 3);
225 return EFI_SUCCESS;
226 }
227 }
228
229 return EFI_NOT_FOUND;
230 }
231
232
233 /**
234 Convert language code from ISO639-2 to RFC3066 and return the converted language.
235 Caller is responsible for freeing the allocated buffer.
236
237 LanguageIso639 contain a single ISO639-2 code such as
238 "eng" or "fra".
239
240 If LanguageIso639 is NULL, then ASSERT.
241 If LanguageRfc3066 is NULL, then ASSERT.
242
243 @param LanguageIso639 ISO639-2 language code.
244
245 @return the allocated buffer or NULL, if the language is not found.
246
247 **/
248 CHAR8*
249 EFIAPI
250 ConvertIso639LanguageToRfc3066Language (
251 IN CONST CHAR8 *LanguageIso639
252 )
253 {
254 UINTN Index;
255 CHAR8 *Rfc3066Language;
256
257 for (Index = 0; Iso639ToRfc3066ConversionTable[Index] != 0; Index += 5) {
258 if (CompareMem (LanguageIso639, &Iso639ToRfc3066ConversionTable[Index], 3) == 0) {
259 Rfc3066Language = AllocateZeroPool (3);
260 if (Rfc3066Language != NULL) {
261 Rfc3066Language = CopyMem (Rfc3066Language, &Iso639ToRfc3066ConversionTable[Index + 3], 2);
262 }
263 return Rfc3066Language;
264 }
265 }
266
267 return NULL;
268 }
269
270 /**
271 Test if all of the characters in a string have corresponding font characters.
272
273 This is a deprecated API. No Framework HII module is calling it. This function will ASSERT and
274 return EFI_UNSUPPORTED.
275
276 @param This A pointer to the EFI_HII_PROTOCOL instance.
277 @param StringToTest A pointer to a Unicode string.
278 @param FirstMissing A pointer to an index into the string. On input, the index of
279 the first character in the StringToTest to examine. On exit, the index
280 of the first character encountered for which a glyph is unavailable.
281 If all glyphs in the string are available, the index is the index of the terminator
282 of the string.
283 @param GlyphBufferSize A pointer to a value. On output, if the function returns EFI_SUCCESS,
284 it contains the amount of memory that is required to store the string? glyph equivalent.
285
286 @retval EFI_UNSUPPORTED The function performs nothing and return EFI_UNSUPPORTED.
287 **/
288 EFI_STATUS
289 EFIAPI
290 HiiTestString (
291 IN EFI_HII_PROTOCOL *This,
292 IN CHAR16 *StringToTest,
293 IN OUT UINT32 *FirstMissing,
294 OUT UINT32 *GlyphBufferSize
295 )
296 {
297 ASSERT (FALSE);
298
299 return EFI_UNSUPPORTED;
300 }
301
302
303 /**
304 Find the corressponding TAG GUID from a Framework HII Handle given.
305
306 @param Private The HII Thunk Module Private context.
307 @param FwHiiHandle The Framemwork HII Handle.
308 @param TagGuid The output of TAG GUID found.
309
310 @return NULL If Framework HII Handle is invalid.
311 @return The corresponding HII Thunk Context.
312 **/
313 EFI_STATUS
314 GetTagGuidByFwHiiHandle (
315 IN CONST HII_THUNK_PRIVATE_DATA *Private,
316 IN FRAMEWORK_EFI_HII_HANDLE FwHiiHandle,
317 OUT EFI_GUID *TagGuid
318 )
319 {
320 LIST_ENTRY *Link;
321 HII_THUNK_CONTEXT *ThunkContext;
322
323 ASSERT (TagGuid != NULL);
324
325 Link = GetFirstNode (&Private->ThunkContextListHead);
326 while (!IsNull (&Private->ThunkContextListHead, Link)) {
327
328 ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);
329
330 if (FwHiiHandle == ThunkContext->FwHiiHandle) {
331 CopyGuid (TagGuid, &ThunkContext->TagGuid);
332 return EFI_SUCCESS;
333 }
334
335 Link = GetNextNode (&Private->ThunkContextListHead, Link);
336 }
337
338 return EFI_NOT_FOUND;
339 }
340
341 /**
342 Create or update the String given a new string and String ID.
343
344 @param ThunkContext The Thunk Context.
345 @param Rfc3066AsciiLanguage The RFC 3066 Language code in ASCII string format.
346 @param NewString The new string.
347 @param StringId The String ID. If StringId is 0, a new String Token
348 is created. Otherwise, the String Token StringId is
349 updated.
350
351
352 @retval EFI_SUCCESS The new string is created or updated successfully.
353 The new String Token ID is returned in StringId if
354 *StringId is 0 on input.
355 @return Others The update of string failed.
356
357 **/
358 EFI_STATUS
359 UpdateString (
360 IN CONST HII_THUNK_CONTEXT *ThunkContext,
361 IN CONST CHAR8 *Rfc3066AsciiLanguage,
362 IN CHAR16 *NewString,
363 IN OUT STRING_REF *StringId
364 )
365 {
366 EFI_STRING_ID NewStringId;
367
368 NewStringId = HiiSetString (ThunkContext->UefiHiiHandle, *StringId, NewString, Rfc3066AsciiLanguage);
369 *StringId = NewStringId;
370 if (NewStringId == 0) {
371 //
372 // Only EFI_INVALID_PARAMETER is defined in HII 0.92 specification.
373 //
374 return EFI_INVALID_PARAMETER;
375 } else {
376 return EFI_SUCCESS;
377 }
378 }
379
380 /**
381 Create or update a String Token in a String Package.
382
383 If *Reference == 0, a new String Token is created.
384
385 @param This A pointer to the EFI_HII_PROTOCOL instance.
386 @param Language Pointer to a NULL-terminated string containing a single ISO 639-2 language
387 identifier, indicating the language to print. A string consisting of
388 all spaces indicates that the string is applicable to all languages.
389 @param Handle The handle of the language pack to which the string is to be added.
390 @param Token The string token assigned to the string.
391 @param NewString The string to be added.
392
393
394 @retval EFI_SUCCESS The string was effectively registered.
395 @retval EFI_INVALID_PARAMETER The Handle was unknown. The string is not created or updated in the
396 the string package.
397 **/
398
399 EFI_STATUS
400 EFIAPI
401 HiiNewString (
402 IN EFI_HII_PROTOCOL *This,
403 IN CHAR16 *Language,
404 IN FRAMEWORK_EFI_HII_HANDLE Handle,
405 IN OUT STRING_REF *Reference,
406 IN CHAR16 *NewString
407 )
408 {
409 EFI_STATUS Status;
410 HII_THUNK_PRIVATE_DATA *Private;
411 EFI_GUID TagGuid;
412 LIST_ENTRY *Link;
413 HII_THUNK_CONTEXT *ThunkContext;
414 HII_THUNK_CONTEXT *StringPackThunkContext;
415 EFI_STRING_ID StringId;
416 EFI_STRING_ID LastStringId;
417 CHAR8 AsciiLanguage[ISO_639_2_ENTRY_SIZE + 1];
418 CHAR16 LanguageCopy[ISO_639_2_ENTRY_SIZE + 1];
419 CHAR8 *Rfc3066AsciiLanguage;
420
421 LastStringId = (EFI_STRING_ID) 0;
422 StringId = (EFI_STRING_ID) 0;
423 Rfc3066AsciiLanguage = NULL;
424
425 if (Language != NULL) {
426 ZeroMem (AsciiLanguage, sizeof (AsciiLanguage));;
427 ZeroMem (LanguageCopy, sizeof (LanguageCopy));
428 CopyMem (LanguageCopy, Language, ISO_639_2_ENTRY_SIZE * sizeof (CHAR16));
429 UnicodeStrToAsciiStr (LanguageCopy, AsciiLanguage);
430 Rfc3066AsciiLanguage = ConvertIso639ToRfc3066 (AsciiLanguage);
431 ASSERT (Rfc3066AsciiLanguage != NULL);
432 }
433
434 Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
435
436 StringPackThunkContext = FwHiiHandleToThunkContext (Private, Handle);
437 if (StringPackThunkContext == NULL) {
438 return EFI_INVALID_PARAMETER;
439 }
440
441 if (StringPackThunkContext->SharingStringPack) {
442 Status = GetTagGuidByFwHiiHandle (Private, Handle, &TagGuid);
443 ASSERT_EFI_ERROR (Status);
444
445 Link = GetFirstNode (&Private->ThunkContextListHead);
446 while (!IsNull (&Private->ThunkContextListHead, Link)) {
447 ThunkContext = HII_THUNK_CONTEXT_FROM_LINK (Link);
448
449 if (CompareGuid (&TagGuid, &ThunkContext->TagGuid)) {
450 if (ThunkContext->SharingStringPack) {
451 StringId = *Reference;
452 Status = UpdateString (ThunkContext, Rfc3066AsciiLanguage, NewString, &StringId);
453 if (EFI_ERROR (Status)) {
454 break;
455 }
456
457 DEBUG_CODE_BEGIN ();
458 if (*Reference == 0) {
459 //
460 // When creating new string token, make sure all created token is the same
461 // for all string packages registered using FW HII interface.
462 //
463 if (LastStringId == (EFI_STRING_ID) 0) {
464 LastStringId = StringId;
465 } else {
466 if (LastStringId != StringId) {
467 ASSERT(FALSE);
468 }
469 }
470 }
471 DEBUG_CODE_END ();
472
473 }
474 }
475
476 Link = GetNextNode (&Private->ThunkContextListHead, Link);
477 }
478 } else {
479 StringId = *Reference;
480 Status = UpdateString (StringPackThunkContext, Rfc3066AsciiLanguage, NewString, &StringId);
481 }
482
483 if (!EFI_ERROR (Status)) {
484 if (*Reference == 0) {
485 *Reference = StringId;
486 }
487 } else {
488 //
489 // Only EFI_INVALID_PARAMETER is defined in HII 0.92 specification.
490 //
491 Status = EFI_INVALID_PARAMETER;
492 }
493
494 return Status;
495 }
496
497 /**
498 This function removes any new strings that were added after the initial string export for this handle.
499 UEFI HII String Protocol does not have Reset String function. This function perform nothing.
500
501 @param This A pointer to the EFI_HII_PROTOCOL instance.
502 @param Handle The HII handle on which the string resides.
503
504 @retval EFI_SUCCESS This function is a NOP and always return EFI_SUCCESS.
505
506 **/
507 EFI_STATUS
508 EFIAPI
509 HiiResetStrings (
510 IN EFI_HII_PROTOCOL *This,
511 IN FRAMEWORK_EFI_HII_HANDLE Handle
512 )
513 {
514 return EFI_SUCCESS;
515 }
516
517 /**
518 This function extracts a string from a package already registered with the EFI HII database.
519
520 @param This A pointer to the EFI_HII_PROTOCOL instance.
521 @param Handle The HII handle on which the string resides.
522 @param Token The string token assigned to the string.
523 @param Raw If TRUE, the string is returned unedited in the internal storage format described
524 above. If false, the string returned is edited by replacing <cr> with <space>
525 and by removing special characters such as the <wide> prefix.
526 @param LanguageString Pointer to a NULL-terminated string containing a single ISO 639-2 language
527 identifier, indicating the language to print. If the LanguageString is empty (starts
528 with a NULL), the default system language will be used to determine the language.
529 @param BufferLength Length of the StringBuffer. If the status reports that the buffer width is too
530 small, this parameter is filled with the length of the buffer needed.
531 @param StringBuffer The buffer designed to receive the characters in the string. Type EFI_STRING is
532 defined in String.
533
534 @retval EFI_INVALID_PARAMETER If input parameter is invalid.
535 @retval EFI_BUFFER_TOO_SMALL If the *BufferLength is too small.
536 @retval EFI_SUCCESS Operation is successful.
537
538 **/
539 EFI_STATUS
540 EFIAPI
541 HiiThunkGetString (
542 IN EFI_HII_PROTOCOL *This,
543 IN FRAMEWORK_EFI_HII_HANDLE Handle,
544 IN STRING_REF Token,
545 IN BOOLEAN Raw,
546 IN CHAR16 *LanguageString,
547 IN OUT UINTN *BufferLengthTemp,
548 OUT EFI_STRING StringBuffer
549 )
550 {
551 HII_THUNK_PRIVATE_DATA *Private;
552 CHAR8 *Iso639AsciiLanguage;
553 CHAR8 *Rfc3066AsciiLanguage;
554 CHAR8 *SupportedLanguages;
555 CHAR8 *PlatformLanguage;
556 CHAR8 *BestLanguage;
557 EFI_HII_HANDLE UefiHiiHandle;
558 EFI_STATUS Status;
559
560 Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
561
562 Iso639AsciiLanguage = NULL;
563 Rfc3066AsciiLanguage = NULL;
564
565 if (LanguageString != NULL) {
566 Iso639AsciiLanguage = AllocateZeroPool (StrLen (LanguageString) + 1);
567 if (Iso639AsciiLanguage == NULL) {
568 return EFI_OUT_OF_RESOURCES;
569 }
570 UnicodeStrToAsciiStr (LanguageString, Iso639AsciiLanguage);
571
572 //
573 // Caller of Framework HII Interface uses the Language Identification String defined
574 // in Iso639. So map it to the Language Identifier defined in RFC3066.
575 //
576 Rfc3066AsciiLanguage = ConvertIso639ToRfc3066 (Iso639AsciiLanguage);
577
578 //
579 // If Rfc3066AsciiLanguage is NULL, more language mapping must be added to
580 // Iso639ToRfc3066Map.
581 //
582 ASSERT (Rfc3066AsciiLanguage != NULL);
583
584 }
585
586 UefiHiiHandle = FwHiiHandleToUefiHiiHandle (Private, Handle);
587 if (UefiHiiHandle == NULL) {
588 Status = EFI_NOT_FOUND;
589 goto Done;
590 }
591
592 if (Rfc3066AsciiLanguage == NULL) {
593 //
594 // Get the languages that the package specified by HiiHandle supports
595 //
596 SupportedLanguages = HiiGetSupportedLanguages (UefiHiiHandle);
597 if (SupportedLanguages == NULL) {
598 goto Error2;
599 }
600
601 //
602 // Get the current platform language setting
603 //
604 PlatformLanguage = GetEfiGlobalVariable (L"PlatformLang");
605 if (PlatformLanguage == NULL) {
606 goto Error1;
607 }
608
609 //
610 // Get the best matching language from SupportedLanguages
611 //
612 BestLanguage = GetBestLanguage (
613 SupportedLanguages,
614 FALSE, // RFC 4646 mode
615 PlatformLanguage, // Next highest priority
616 SupportedLanguages, // Lowest priority
617 NULL
618 );
619 if (BestLanguage == NULL) {
620 FreePool (PlatformLanguage);
621 Error1:
622 FreePool (SupportedLanguages);
623 Error2:
624 Status = EFI_INVALID_PARAMETER;
625 goto Done;
626 }
627
628 Status = mHiiStringProtocol->GetString (
629 mHiiStringProtocol,
630 BestLanguage,
631 UefiHiiHandle,
632 Token,
633 StringBuffer,
634 BufferLengthTemp,
635 NULL
636 );
637 FreePool (BestLanguage);
638 } else {
639 Status = mHiiStringProtocol->GetString (
640 mHiiStringProtocol,
641 Rfc3066AsciiLanguage,
642 UefiHiiHandle,
643 Token,
644 StringBuffer,
645 BufferLengthTemp,
646 NULL
647 );
648 }
649
650 Done:
651 if (Iso639AsciiLanguage != NULL) {
652 FreePool (Iso639AsciiLanguage);
653 }
654
655 return Status;
656 }
657
658 /**
659
660 This function allows a program to extract a part of a string of not more than a given width.
661 With repeated calls, this allows a calling program to extract "lines" of text that fit inside
662 columns. The effort of measuring the fit of strings inside columns is localized to this call.
663
664 This is a deprecated API. No Framework HII module is calling it. This function will ASSERT and
665 return EFI_UNSUPPORTED.
666
667 @param This A pointer to the EFI_HII_PROTOCOL instance.
668 @param Handle The HII handle on which the string resides.
669 @param Token The string token assigned to the string.
670 @param Raw If TRUE, the string is returned unedited in the internal storage format described
671 above. If false, the string returned is edited by replacing <cr> with <space>
672 and by removing special characters such as the <wide> prefix.
673 @param LanguageString Pointer to a NULL-terminated string containing a single ISO 639-2 language
674 identifier, indicating the language to print. If the LanguageString is empty (starts
675 with a NULL), the default system language will be used to determine the language.
676 @param BufferLength Length of the StringBuffer. If the status reports that the buffer width is too
677 small, this parameter is filled with the length of the buffer needed.
678 @param StringBuffer The buffer designed to receive the characters in the string. Type EFI_STRING is
679 defined in String.
680
681 @retval EFI_UNSUPPORTED.
682 **/
683 EFI_STATUS
684 EFIAPI
685 HiiGetLine (
686 IN EFI_HII_PROTOCOL *This,
687 IN FRAMEWORK_EFI_HII_HANDLE Handle,
688 IN STRING_REF Token,
689 IN OUT UINT16 *Index,
690 IN UINT16 LineWidth,
691 IN CHAR16 *LanguageString,
692 IN OUT UINT16 *BufferLength,
693 OUT EFI_STRING StringBuffer
694 )
695 {
696 ASSERT (FALSE);
697 return EFI_UNSUPPORTED;
698 }
699
700