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