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