]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Foundation/Library/Dxe/EfiUiLib/EfiUiLib.c
Add in the 1st version of ECP.
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / EfiUiLib / EfiUiLib.c
1 /*++
2
3 Copyright (c) 2007, Intel Corporation
4 All rights reserved. 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 //
388 // Iterate the decimal values separated by dots
389 //
390 for (i = 0; i < 4; i++) {
391 //
392 // get the value of a decimal
393 //
394 Status = EfiStringToValue (&TempVal, String, &Idx);
395 if ((EFI_ERROR (Status)) || (TempVal > 255)) {
396 break;
397 }
398
399 RetVal.Addr[i] = (UINT8) TempVal;
400 String += Idx;
401
402 //
403 // test if it is the last decimal value
404 //
405 if (i == 3) {
406 if (String[0] != L'\0') {
407 //
408 // the string must end with string termination character
409 //
410 break;
411 }
412
413 *Ip4Addr = RetVal;
414 return EFI_SUCCESS;
415 }
416 //
417 // Test for presence of a dot, it is required between the values
418 //
419 if (String++[0] != L'.') {
420 break;
421 }
422 }
423
424 return EFI_INVALID_PARAMETER;
425 }
426
427 CHAR16 *
428 Ascii2Unicode (
429 OUT CHAR16 *UnicodeStr,
430 IN CHAR8 *AsciiStr
431 )
432 /*++
433
434 Routine Description:
435 Converts ASCII characters to Unicode.
436
437 Arguments:
438 UnicodeStr - the Unicode string to be written to. The buffer must be large enough.
439 AsciiStr - The ASCII string to be converted.
440
441 Returns:
442 The address to the Unicode string - same as UnicodeStr.
443
444 --*/
445 {
446 CHAR16 *Str;
447
448 Str = UnicodeStr;
449
450 while (TRUE) {
451
452 *(UnicodeStr++) = (CHAR16) *AsciiStr;
453
454 if (*(AsciiStr++) == '\0') {
455 return Str;
456 }
457 }
458 }
459
460 CHAR8 *
461 Unicode2Ascii (
462 OUT CHAR8 *AsciiStr,
463 IN CHAR16 *UnicodeStr
464 )
465 /*++
466
467 Routine Description:
468 Converts ASCII characters to Unicode.
469 Assumes that the Unicode characters are only these defined in the ASCII set.
470
471 Arguments:
472 AsciiStr - The ASCII string to be written to. The buffer must be large enough.
473 UnicodeStr - the Unicode string to be converted.
474
475 Returns:
476 The address to the ASCII string - same as AsciiStr.
477
478 --*/
479 {
480 CHAR8 *Str;
481
482 Str = AsciiStr;
483
484 while (TRUE) {
485
486 *AsciiStr = (CHAR8) *(UnicodeStr++);
487
488 if (*(AsciiStr++) == '\0') {
489 return Str;
490 }
491 }
492 }