]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/Dxe/EfiUiLib/EfiUiLib.c
b913d3fac2a83a1b7954fb56a98eb80eb811d96b
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / EfiUiLib / EfiUiLib.c
1 /*++
2
3 Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13 EfiUiLib.c
14
15 Abstract:
16 Collection of usefull UI functions.
17
18 Revision History:
19
20 --*/
21
22 #include "EfiUiLib.h"
23
24 #define IS_DIGIT(Ch) (((Ch) >= L'0') && ((Ch) <= L'9'))
25
26 STATIC
27 EFI_STATUS
28 EfiStringToValue (
29 OUT UINT64 *Val,
30 IN CHAR16 *String,
31 OUT UINT8 *EndIdx OPTIONAL
32 )
33 /*++
34
35 Routine Description:
36 Parses and converts Unicode string to decimal value.
37 The returned value is 64-bit.
38 The string is expected in decimal format,
39 the string is parsed and format verified.
40 This function is missing from the libs. One day it maybe
41 replaced with a lib function when it'll become available.
42
43 Arguments:
44 Val - pointer to the variable to store the value to
45 String - string that contains the value to parse and convert
46 EndIdx - index on which the parsing stopped. It points to the
47 first character that was not part of the returned Val.
48 It's valid only if the function returns success.
49 It's optional and it could be NULL.
50
51 Returns:
52 EFI_SUCCESS - if successful
53 EFI_INVALID_PARAMETER - if String is in unexpected format
54
55 --*/
56 {
57 UINT8 i;
58 UINT64 TempVal;
59
60 TempVal = 0;
61 //
62 // Iterate upto 20 digits, only so many could fit in the UINT64
63 //
64 for (i = 0; i <= 20; i++) {
65 //
66 // test if the next character is not a digit
67 //
68 if (!IS_DIGIT (String[i])) {
69 //
70 // If here, there is no more digits,
71 // return with success if there was at least one to process
72 //
73 if (i == 0) {
74 break;
75 }
76
77 *Val = TempVal;
78
79 if (EndIdx != NULL) {
80 *EndIdx = i;
81 }
82
83 return EFI_SUCCESS;
84 }
85 //
86 // If here, there is a digit to process
87 //
88 TempVal = MultU64x32 (TempVal, 10) + String[i] - L'0';
89 }
90 //
91 // if here, there was some sort of format error
92 //
93 return EFI_INVALID_PARAMETER;
94 }
95
96 CHAR16 *
97 StrHzToString (
98 OUT CHAR16 *String,
99 IN UINT64 Val
100 )
101 /*++
102
103 Routine Description:
104 Converts frequency in Hz to Unicode string.
105 Three significant digits are delivered.
106 Used for things like processor info display.
107
108 Arguments:
109 String - string that will contain the frequency.
110 Val - value to convert, minimum is 100000 i.e., 0.1 MHz.
111
112 --*/
113 // GC_TODO: function comment is missing 'Returns:'
114 {
115 CHAR16 HlpStr[8];
116 UINT32 i;
117 UINT32 IdxPoint;
118 UINT32 IdxUnits;
119 static CHAR16 *FreqUnits[] = { L" Hz", L" kHz", L" MHz", L" GHz", L" THz", L" PHz" };
120
121 //
122 // Normalize to 9999 or less.
123 //
124 i = 0;
125 while (Val >= 10000) {
126 Val = DivU64x32 (Val, 10, NULL);
127 i++;
128 }
129 //
130 // Make it rounded to the nearest, but only by
131 // a .3. This assures that .6 is not rounded.
132 //
133 if (Val >= 1000) {
134 Val += 3;
135 Val = DivU64x32 (Val, 10, NULL);
136 i++;
137 }
138
139 EfiValueToString (String, Val, 0, 0);
140
141 //
142 // Get rid of that cursed number!
143 //
144 if (!EfiStrCmp (&String[1], L"66")) {
145 String[2] = L'7';
146 }
147 //
148 // Compute index to the units substrings.
149 //
150 IdxUnits = (i + 2) / 3;
151
152 if (IdxUnits >= (sizeof (FreqUnits) / sizeof (FreqUnits)[0])) {
153 //
154 // Frequency is too high.
155 //
156 EfiStrCpy (String, L"OVERFLOW");
157 return String;
158 }
159 //
160 // Compute the position of the decimal point.
161 //
162 IdxPoint = i % 3;
163
164 //
165 // Test if decimal point needs to be inserted.
166 //
167 if (IdxPoint != 0) {
168 //
169 // Save the part after decimal point.
170 //
171 EfiStrCpy (HlpStr, &String[IdxPoint]);
172
173 //
174 // Insert the point.
175 //
176 String[IdxPoint] = L'.';
177
178 //
179 // Reattach the saved part.
180 //
181 EfiStrCpy (&String[IdxPoint + 1], HlpStr);
182
183 //
184 // Clear the insignificant zero.
185 //
186 if (String[3] == L'0') {
187 String[4 - IdxPoint] = L'\0';
188 }
189 }
190 //
191 // Attach units.
192 //
193 EfiStrCat (String, FreqUnits[IdxUnits]);
194
195 return String;
196 }
197
198 CHAR16 *
199 StrBytesToString (
200 OUT CHAR16 *String,
201 IN UINT64 Val
202 )
203 /*++
204
205 Routine Description:
206 Converts size in bytes to Unicode string.
207 Used for memory/cache size display.
208
209 Arguments:
210 String - string that will contain the value
211 Val - value to convert in bytes
212
213 --*/
214 // GC_TODO: function comment is missing 'Returns:'
215 {
216 UINTN i;
217 UINTN Rem;
218 static CHAR16 *SizeUnits[] = { L" B", L" kB", L" MB", L" GB", L" TB", L" PB" };
219
220 for (i = 0; i < (sizeof (SizeUnits) / sizeof (SizeUnits)[0]); i++) {
221
222 DivU64x32 (Val, 1024, &Rem);
223
224 //
225 // Done if:
226 // 1. less than 1k
227 // 2. less than 8k and there are fractions of 1k
228 //
229 if ((Val < 1024) || ((Val < 8192) && (Rem != 0))) {
230
231 EfiValueToString (String, Val, 0, 0);
232
233 //
234 // attach units
235 //
236 EfiStrCat (String, SizeUnits[i]);
237 return String;
238 }
239 //
240 // prescale down by 1k with rounding to the nearest
241 //
242 Val = DivU64x32 (Val + 511, 1024, NULL);
243 }
244
245 EfiStrCpy (String, L"OVERFLOW");
246
247 return String;
248 }
249
250 CHAR16 *
251 StrVersionToString (
252 OUT CHAR16 *String,
253 IN UINT8 Version
254 )
255 /*++
256
257 Routine Description:
258 Converts 8 bit version value to Unicode string.
259 The upper nibble contains the upper part, the lower nibble contains the minor part.
260 The output format is <major>.<minor>.
261
262 Arguments:
263 String - string that will contain the value
264 Version - value to convert
265
266 --*/
267 // GC_TODO: function comment is missing 'Returns:'
268 {
269 CHAR16 HlpStr[4];
270
271 EfiValueToString (String, 0x0F & Version, 0, 0);
272 EfiStrCat (String, L".");
273 EfiValueToString (HlpStr, 0x0F & (Version >> 4), 0, 0);
274 EfiStrCat (String, HlpStr);
275
276 return String;
277 }
278
279 CHAR16 *
280 StrMacToString (
281 OUT CHAR16 *String,
282 IN EFI_MAC_ADDRESS *MacAddr,
283 IN UINT32 AddrSize
284 )
285 /*++
286
287 Routine Description:
288 Converts MAC address to Unicode string.
289 The value is 64-bit and the resulting string will be 12
290 digit hex number in pairs of digits separated by dashes.
291
292 Arguments:
293 String - string that will contain the value
294 Val - value to convert
295
296 --*/
297 // GC_TODO: function comment is missing 'Returns:'
298 // GC_TODO: MacAddr - add argument and description to function comment
299 // GC_TODO: AddrSize - add argument and description to function comment
300 {
301 UINT32 i;
302
303 for (i = 0; i < AddrSize; i++) {
304
305 EfiValueToHexStr (
306 &String[2 * i],
307 MacAddr->Addr[i] & 0xFF,
308 PREFIX_ZERO,
309 2
310 );
311 }
312 //
313 // Terminate the string.
314 //
315 String[2 * AddrSize] = L'\0';
316
317 return String;
318 }
319
320 CHAR16 *
321 StrIp4AdrToString (
322 OUT CHAR16 *String,
323 IN EFI_IPv4_ADDRESS *Ip4Addr
324 )
325 /*++
326
327 Routine Description:
328 Converts IP v4 address to Unicode string.
329 The value is 64-bit and the resulting string will
330 be four decimal values 0-255 separated by dots.
331
332 Arguments:
333 String - string that will contain the value
334 Ip4Addr - value to convert from
335
336 --*/
337 // GC_TODO: function comment is missing 'Returns:'
338 {
339 INT32 i;
340 CHAR16 HlpStr[4];
341
342 String[0] = L'\0';
343
344 for (i = 0; i < 4; i++) {
345
346 EfiValueToString (HlpStr, Ip4Addr->Addr[i], 0, 0);
347 EfiStrCat (String, HlpStr);
348
349 if (i < 3) {
350 EfiStrCat (String, L".");
351 }
352 }
353
354 return String;
355 }
356
357 EFI_STATUS
358 StrStringToIp4Adr (
359 OUT EFI_IPv4_ADDRESS *Ip4Addr,
360 IN CHAR16 *String
361 )
362 /*++
363
364 Routine Description:
365 Parses and converts Unicode string to IP v4 address.
366 The value will 64-bit.
367 The string must be four decimal values 0-255 separated by dots.
368 The string is parsed and format verified.
369
370 Arguments:
371 Ip4Addr - pointer to the variable to store the value to
372 String - string that contains the value to parse and convert
373
374 Returns:
375 EFI_SUCCESS - if successful
376 EFI_INVALID_PARAMETER - if String contains invalid IP v4 format
377
378 --*/
379 {
380 EFI_STATUS Status;
381
382 EFI_IPv4_ADDRESS RetVal;
383 UINT64 TempVal;
384 UINT8 Idx;
385 UINT8 i;
386
387 Idx = 0;
388 TempVal = 0;
389 //
390 // Iterate the decimal values separated by dots
391 //
392 for (i = 0; i < 4; i++) {
393 //
394 // get the value of a decimal
395 //
396 Status = EfiStringToValue (&TempVal, String, &Idx);
397 if ((EFI_ERROR (Status)) || (TempVal > 255)) {
398 break;
399 }
400
401 RetVal.Addr[i] = (UINT8) TempVal;
402 String += Idx;
403
404 //
405 // test if it is the last decimal value
406 //
407 if (i == 3) {
408 if (String[0] != L'\0') {
409 //
410 // the string must end with string termination character
411 //
412 break;
413 }
414
415 *Ip4Addr = RetVal;
416 return EFI_SUCCESS;
417 }
418 //
419 // Test for presence of a dot, it is required between the values
420 //
421 if (String++[0] != L'.') {
422 break;
423 }
424 }
425
426 return EFI_INVALID_PARAMETER;
427 }
428
429 CHAR16 *
430 Ascii2Unicode (
431 OUT CHAR16 *UnicodeStr,
432 IN CHAR8 *AsciiStr
433 )
434 /*++
435
436 Routine Description:
437 Converts ASCII characters to Unicode.
438
439 Arguments:
440 UnicodeStr - the Unicode string to be written to. The buffer must be large enough.
441 AsciiStr - The ASCII string to be converted.
442
443 Returns:
444 The address to the Unicode string - same as UnicodeStr.
445
446 --*/
447 {
448 CHAR16 *Str;
449
450 Str = UnicodeStr;
451
452 while (TRUE) {
453
454 *(UnicodeStr++) = (CHAR16) *AsciiStr;
455
456 if (*(AsciiStr++) == '\0') {
457 return Str;
458 }
459 }
460 }
461
462 CHAR8 *
463 Unicode2Ascii (
464 OUT CHAR8 *AsciiStr,
465 IN CHAR16 *UnicodeStr
466 )
467 /*++
468
469 Routine Description:
470 Converts ASCII characters to Unicode.
471 Assumes that the Unicode characters are only these defined in the ASCII set.
472
473 Arguments:
474 AsciiStr - The ASCII string to be written to. The buffer must be large enough.
475 UnicodeStr - the Unicode string to be converted.
476
477 Returns:
478 The address to the ASCII string - same as AsciiStr.
479
480 --*/
481 {
482 CHAR8 *Str;
483
484 Str = AsciiStr;
485
486 while (TRUE) {
487
488 *AsciiStr = (CHAR8) *(UnicodeStr++);
489
490 if (*(AsciiStr++) == '\0') {
491 return Str;
492 }
493 }
494 }