]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/DxePrintLibPrint2Protocol/PrintLib.c
MdeModulePkg: Add %u and %lu support for PrintLib and DebugLib.
[mirror_edk2.git] / MdeModulePkg / Library / DxePrintLibPrint2Protocol / PrintLib.c
CommitLineData
504214c4 1/** @file\r
bee67555 2 Instance of Print Library based on gEfiPrint2ProtocolGuid.\r
a0afd019 3\r
504214c4 4 Implement the print library instance by wrap the interface \r
bee67555 5 provided in the Print2 protocol. This protocol is defined as the internal\r
504214c4
LG
6 protocol related to this implementation, not in the public spec. So, this \r
7 library instance is only for this code base.\r
8\r
586d81d1 9Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
cd5ebaa0 10This program and the accompanying materials\r
a0afd019 11are licensed and made available under the terms and conditions of the BSD License\r
12which accompanies this distribution. The full text of the license may be found at\r
13http://opensource.org/licenses/bsd-license.php\r
14\r
15THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
16WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
17\r
504214c4 18**/\r
a0afd019 19\r
60c93673 20#include <Uefi.h>\r
f405c067 21#include <Base.h>\r
0ed0c867 22#include <Protocol/Print2.h>\r
504dcb0a 23\r
24#include <Library/PrintLib.h>\r
25\r
26#include <Library/BaseLib.h>\r
bee67555 27#include <Library/DebugLib.h>\r
a0afd019 28\r
bee67555 29EFI_PRINT2_PROTOCOL *mPrint2Protocol = NULL;\r
a0afd019 30\r
ce95aa7a 31/**\r
bee67555 32 The constructor function caches the pointer to Print2 protocol.\r
33 \r
34 The constructor function locates Print2 protocol from protocol database.\r
35 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. \r
ce95aa7a 36\r
bee67555 37 @param ImageHandle The firmware allocated handle for the EFI image.\r
38 @param SystemTable A pointer to the EFI System Table.\r
39 \r
40 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
ce95aa7a 41\r
42**/\r
2ad4dad0
LG
43EFI_STATUS\r
44EFIAPI\r
bee67555 45PrintLibConstructor (\r
46 IN EFI_HANDLE ImageHandle,\r
47 IN EFI_SYSTEM_TABLE *SystemTable\r
a0afd019 48 )\r
a0afd019 49{\r
bee67555 50 EFI_STATUS Status;\r
51\r
35289219 52 Status = SystemTable->BootServices->LocateProtocol (\r
53 &gEfiPrint2ProtocolGuid,\r
54 NULL,\r
55 (VOID**) &mPrint2Protocol\r
56 );\r
bee67555 57 ASSERT_EFI_ERROR (Status);\r
58 ASSERT (mPrint2Protocol != NULL);\r
59\r
60 return Status;\r
2ad4dad0
LG
61}\r
62\r
bee67555 63\r
504dcb0a 64/**\r
65 Worker function that converts a VA_LIST to a BASE_LIST based on a Null-terminated \r
66 format string.\r
67\r
68 @param AsciiFormat TRUE if Format is an ASCII string. FALSE if Format is a Unicode string.\r
69 @param Format Null-terminated format string.\r
70 @param VaListMarker VA_LIST style variable argument list consumed by processing Format.\r
71 @param BaseListMarker BASE_LIST style variable argument list consumed by processing Format.\r
72 @param Size The size, in bytes, of the BaseListMarker buffer.\r
73\r
74 @return The number of bytes in BaseListMarker. 0 if BaseListMarker is too small.\r
75\r
76**/\r
77BOOLEAN\r
78DxePrintLibPrint2ProtocolVaListToBaseList (\r
79 IN BOOLEAN AsciiFormat,\r
80 IN CONST CHAR8 *Format,\r
81 IN VA_LIST VaListMarker,\r
82 OUT BASE_LIST BaseListMarker,\r
83 IN UINTN Size\r
84 )\r
85{\r
86 BASE_LIST BaseListStart;\r
87 UINTN BytesPerFormatCharacter;\r
88 UINTN FormatMask;\r
89 UINTN FormatCharacter;\r
90 BOOLEAN Long;\r
91 BOOLEAN Done;\r
92\r
93 ASSERT (Format != NULL);\r
504dcb0a 94 ASSERT (BaseListMarker != NULL);\r
95\r
96 BaseListStart = BaseListMarker;\r
97\r
98 if (AsciiFormat) {\r
99 ASSERT (AsciiStrSize (Format) != 0);\r
100 BytesPerFormatCharacter = 1;\r
101 FormatMask = 0xff;\r
102 } else {\r
103 ASSERT (StrSize ((CHAR16 *) Format) != 0);\r
104 BytesPerFormatCharacter = 2;\r
105 FormatMask = 0xffff;\r
106 }\r
107\r
108 //\r
109 // Get the first character from the format string\r
110 //\r
111 FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
112\r
113 while (FormatCharacter != 0) {\r
114 if (FormatCharacter == '%') {\r
115 Long = FALSE;\r
116\r
117 //\r
118 // Parse Flags and Width\r
119 //\r
120 for (Done = FALSE; !Done; ) {\r
121 //\r
122 // Get the next character from the format string\r
123 //\r
124 Format += BytesPerFormatCharacter;\r
125\r
126 //\r
127 // Get the next character from the format string\r
128 //\r
129 FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
130\r
131 switch (FormatCharacter) {\r
132 case '.': \r
133 case '-': \r
134 case '+': \r
135 case ' ': \r
136 case ',': \r
137 case '0':\r
138 case '1':\r
139 case '2':\r
140 case '3':\r
141 case '4':\r
142 case '5':\r
143 case '6':\r
144 case '7':\r
145 case '8':\r
146 case '9':\r
147 break;\r
148 case 'L':\r
149 case 'l': \r
150 Long = TRUE;\r
151 break;\r
152 case '*':\r
153 BASE_ARG (BaseListMarker, UINTN) = VA_ARG (VaListMarker, UINTN);\r
154 break;\r
155 case '\0':\r
156 //\r
157 // Make no output if Format string terminates unexpectedly when\r
158 // looking up for flag, width, precision and type. \r
159 //\r
160 Format -= BytesPerFormatCharacter;\r
161 //\r
162 // break skipped on purpose.\r
163 //\r
164 default:\r
165 Done = TRUE;\r
166 break;\r
167 }\r
168 } \r
169 \r
170 //\r
171 // Handle each argument type\r
172 //\r
173 switch (FormatCharacter) {\r
174 case 'p':\r
175 if (sizeof (VOID *) > 4) {\r
176 Long = TRUE;\r
177 }\r
178 case 'X':\r
179 case 'x':\r
796fecd8 180 case 'u':\r
504dcb0a 181 case 'd':\r
182 if (Long) {\r
183 BASE_ARG (BaseListMarker, INT64) = VA_ARG (VaListMarker, INT64);\r
184 } else {\r
185 BASE_ARG (BaseListMarker, int) = VA_ARG (VaListMarker, int);\r
186 }\r
187 break;\r
188 case 's':\r
189 case 'S':\r
190 case 'a':\r
191 case 'g':\r
192 case 't':\r
193 BASE_ARG (BaseListMarker, VOID *) = VA_ARG (VaListMarker, VOID *);\r
194 break;\r
195 case 'c':\r
196 BASE_ARG (BaseListMarker, UINTN) = VA_ARG (VaListMarker, UINTN);\r
197 break;\r
198 case 'r':\r
199 BASE_ARG (BaseListMarker, RETURN_STATUS) = VA_ARG (VaListMarker, RETURN_STATUS);\r
200 break;\r
201 }\r
202 }\r
203\r
204 //\r
205 // If BASE_LIST is larger than Size, then return FALSE\r
206 //\r
207 if ((UINTN)((UINT8 *)BaseListMarker - (UINT8 *)BaseListStart) > Size) {\r
208 return FALSE;\r
209 }\r
210\r
211 //\r
212 // Get the next character from the format string\r
213 //\r
214 Format += BytesPerFormatCharacter;\r
215\r
216 //\r
217 // Get the next character from the format string\r
218 //\r
219 FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
220 }\r
221 return TRUE;\r
222}\r
223\r
2ad4dad0
LG
224/**\r
225 Produces a Null-terminated Unicode string in an output buffer based on \r
226 a Null-terminated Unicode format string and a VA_LIST argument list\r
227 \r
228 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer\r
229 and BufferSize. \r
230 The Unicode string is produced by parsing the format string specified by FormatString. \r
231 Arguments are pulled from the variable argument list specified by Marker based on the \r
232 contents of the format string. \r
233 The number of Unicode characters in the produced output buffer is returned not including\r
234 the Null-terminator.\r
235 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.\r
236\r
237 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().\r
238 If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().\r
239 If BufferSize > 1 and FormatString is NULL, then ASSERT().\r
240 If BufferSize > 1 and FormatString is not aligned on a 16-bit boundary, then ASSERT().\r
241 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than \r
242 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then\r
243 ASSERT().\r
244 If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string\r
245 contains more than PcdMaximumUnicodeStringLength Unicode characters not including the\r
246 Null-terminator, then ASSERT().\r
247\r
248 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated \r
249 Unicode string.\r
250 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
251 @param FormatString Null-terminated Unicode format string.\r
252 @param Marker VA_LIST marker for the variable argument list.\r
253 \r
254 @return The number of Unicode characters in the produced output buffer not including the\r
255 Null-terminator.\r
256\r
257**/\r
258UINTN\r
259EFIAPI\r
260UnicodeVSPrint (\r
261 OUT CHAR16 *StartOfBuffer,\r
262 IN UINTN BufferSize,\r
263 IN CONST CHAR16 *FormatString,\r
264 IN VA_LIST Marker\r
265 )\r
266{\r
97f77815 267 UINT64 BaseListMarker[256 / sizeof (UINT64)];\r
504dcb0a 268\r
269 DxePrintLibPrint2ProtocolVaListToBaseList (\r
270 FALSE, \r
271 (CHAR8 *)FormatString, \r
272 Marker, \r
273 (BASE_LIST)BaseListMarker, \r
274 sizeof (BaseListMarker) - 8\r
275 );\r
276\r
277 return UnicodeBSPrint (StartOfBuffer, BufferSize, FormatString, (BASE_LIST)BaseListMarker);\r
278}\r
279\r
280/**\r
281 Produces a Null-terminated Unicode string in an output buffer based on \r
282 a Null-terminated Unicode format string and a BASE_LIST argument list\r
283 \r
284 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer\r
285 and BufferSize. \r
286 The Unicode string is produced by parsing the format string specified by FormatString. \r
287 Arguments are pulled from the variable argument list specified by Marker based on the \r
288 contents of the format string. \r
289 The number of Unicode characters in the produced output buffer is returned not including\r
290 the Null-terminator.\r
291 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.\r
292\r
293 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().\r
294 If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().\r
295 If BufferSize > 1 and FormatString is NULL, then ASSERT().\r
296 If BufferSize > 1 and FormatString is not aligned on a 16-bit boundary, then ASSERT().\r
297 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than \r
298 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then\r
299 ASSERT().\r
300 If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string\r
301 contains more than PcdMaximumUnicodeStringLength Unicode characters not including the\r
302 Null-terminator, then ASSERT().\r
303\r
304 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated \r
305 Unicode string.\r
306 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
307 @param FormatString Null-terminated Unicode format string.\r
308 @param Marker BASE_LIST marker for the variable argument list.\r
309 \r
310 @return The number of Unicode characters in the produced output buffer not including the\r
311 Null-terminator.\r
312\r
313**/\r
314UINTN\r
315EFIAPI\r
316UnicodeBSPrint (\r
317 OUT CHAR16 *StartOfBuffer,\r
318 IN UINTN BufferSize,\r
319 IN CONST CHAR16 *FormatString,\r
320 IN BASE_LIST Marker\r
321 )\r
322{\r
323 return mPrint2Protocol->UnicodeBSPrint (StartOfBuffer, BufferSize, FormatString, Marker);\r
a0afd019 324}\r
325\r
2ad4dad0
LG
326/**\r
327 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated \r
328 Unicode format string and variable argument list.\r
329 \r
330 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer\r
331 and BufferSize.\r
332 The Unicode string is produced by parsing the format string specified by FormatString.\r
333 Arguments are pulled from the variable argument list based on the contents of the format string.\r
334 The number of Unicode characters in the produced output buffer is returned not including\r
335 the Null-terminator.\r
336 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.\r
337\r
338 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().\r
339 If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().\r
340 If BufferSize > 1 and FormatString is NULL, then ASSERT().\r
341 If BufferSize > 1 and FormatString is not aligned on a 16-bit boundary, then ASSERT().\r
342 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than \r
343 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then\r
344 ASSERT().\r
345 If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string\r
346 contains more than PcdMaximumUnicodeStringLength Unicode characters not including the\r
347 Null-terminator, then ASSERT().\r
348\r
349 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated \r
350 Unicode string.\r
351 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
352 @param FormatString Null-terminated Unicode format string.\r
71898234 353 @param ... Variable argument list whose contents are accessed based on the \r
354 format string specified by FormatString.\r
ce95aa7a 355\r
2ad4dad0
LG
356 @return The number of Unicode characters in the produced output buffer not including the\r
357 Null-terminator.\r
358\r
359**/\r
a0afd019 360UINTN\r
2ad4dad0 361EFIAPI\r
a0afd019 362UnicodeSPrint (\r
363 OUT CHAR16 *StartOfBuffer,\r
364 IN UINTN BufferSize,\r
2ad4dad0 365 IN CONST CHAR16 *FormatString,\r
a0afd019 366 ...\r
367 )\r
a0afd019 368{\r
2ad4dad0 369 VA_LIST Marker;\r
3bbe68a3 370 UINTN NumberOfPrinted;\r
a0afd019 371\r
372 VA_START (Marker, FormatString);\r
3bbe68a3 373 NumberOfPrinted = UnicodeVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);\r
374 VA_END (Marker);\r
375 return NumberOfPrinted;\r
a0afd019 376}\r
377\r
2ad4dad0
LG
378/**\r
379 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated\r
380 ASCII format string and a VA_LIST argument list\r
381 \r
382 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer\r
383 and BufferSize.\r
384 The Unicode string is produced by parsing the format string specified by FormatString.\r
385 Arguments are pulled from the variable argument list specified by Marker based on the \r
386 contents of the format string.\r
387 The number of Unicode characters in the produced output buffer is returned not including\r
388 the Null-terminator.\r
389 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.\r
390\r
391 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().\r
392 If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().\r
393 If BufferSize > 1 and FormatString is NULL, then ASSERT().\r
394 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than\r
395 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then\r
396 ASSERT().\r
397 If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string\r
398 contains more than PcdMaximumUnicodeStringLength Unicode characters not including the\r
399 Null-terminator, then ASSERT().\r
400\r
401 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated \r
402 Unicode string.\r
403 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
404 @param FormatString Null-terminated Unicode format string.\r
405 @param Marker VA_LIST marker for the variable argument list.\r
406 \r
407 @return The number of Unicode characters in the produced output buffer not including the\r
408 Null-terminator.\r
409\r
410**/\r
a0afd019 411UINTN\r
2ad4dad0
LG
412EFIAPI\r
413UnicodeVSPrintAsciiFormat (\r
414 OUT CHAR16 *StartOfBuffer,\r
415 IN UINTN BufferSize,\r
416 IN CONST CHAR8 *FormatString,\r
417 IN VA_LIST Marker\r
a0afd019 418 )\r
2ad4dad0 419{\r
97f77815 420 UINT64 BaseListMarker[256 / sizeof (UINT64)];\r
504dcb0a 421\r
422 DxePrintLibPrint2ProtocolVaListToBaseList (\r
423 TRUE, \r
424 FormatString, \r
425 Marker, \r
426 (BASE_LIST)BaseListMarker, \r
427 sizeof (BaseListMarker) - 8\r
428 );\r
429\r
430 return UnicodeBSPrintAsciiFormat (StartOfBuffer, BufferSize, FormatString, (BASE_LIST)BaseListMarker);\r
431}\r
432\r
433/**\r
434 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated\r
435 ASCII format string and a BASE_LIST argument list\r
436 \r
437 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer\r
438 and BufferSize.\r
439 The Unicode string is produced by parsing the format string specified by FormatString.\r
440 Arguments are pulled from the variable argument list specified by Marker based on the \r
441 contents of the format string.\r
442 The number of Unicode characters in the produced output buffer is returned not including\r
443 the Null-terminator.\r
444 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.\r
445\r
446 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().\r
447 If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().\r
448 If BufferSize > 1 and FormatString is NULL, then ASSERT().\r
449 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than\r
450 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then\r
451 ASSERT().\r
452 If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string\r
453 contains more than PcdMaximumUnicodeStringLength Unicode characters not including the\r
454 Null-terminator, then ASSERT().\r
455\r
456 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated \r
457 Unicode string.\r
458 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
459 @param FormatString Null-terminated Unicode format string.\r
460 @param Marker BASE_LIST marker for the variable argument list.\r
461 \r
462 @return The number of Unicode characters in the produced output buffer not including the\r
463 Null-terminator.\r
464\r
465**/\r
466UINTN\r
467EFIAPI\r
468UnicodeBSPrintAsciiFormat (\r
469 OUT CHAR16 *StartOfBuffer,\r
470 IN UINTN BufferSize,\r
471 IN CONST CHAR8 *FormatString,\r
472 IN BASE_LIST Marker\r
473 )\r
474{\r
475 return mPrint2Protocol->UnicodeBSPrintAsciiFormat (StartOfBuffer, BufferSize, FormatString, Marker);\r
2ad4dad0 476}\r
a0afd019 477\r
2ad4dad0
LG
478/**\r
479 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated \r
480 ASCII format string and variable argument list.\r
481 \r
482 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer\r
483 and BufferSize.\r
484 The Unicode string is produced by parsing the format string specified by FormatString.\r
485 Arguments are pulled from the variable argument list based on the contents of the \r
486 format string.\r
487 The number of Unicode characters in the produced output buffer is returned not including\r
488 the Null-terminator.\r
489 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.\r
490\r
491 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().\r
492 If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().\r
493 If BufferSize > 1 and FormatString is NULL, then ASSERT().\r
494 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than\r
495 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then\r
496 ASSERT().\r
497 If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string\r
498 contains more than PcdMaximumUnicodeStringLength Unicode characters not including the\r
499 Null-terminator, then ASSERT().\r
500\r
501 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated \r
502 Unicode string.\r
503 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
504 @param FormatString Null-terminated Unicode format string.\r
71898234 505 @param ... Variable argument list whose contents are accessed based on the \r
506 format string specified by FormatString.\r
2ad4dad0
LG
507 \r
508 @return The number of Unicode characters in the produced output buffer not including the\r
509 Null-terminator.\r
510\r
511**/\r
512UINTN\r
513EFIAPI\r
514UnicodeSPrintAsciiFormat (\r
515 OUT CHAR16 *StartOfBuffer,\r
516 IN UINTN BufferSize,\r
517 IN CONST CHAR8 *FormatString,\r
518 ...\r
519 )\r
520{\r
521 VA_LIST Marker;\r
3bbe68a3 522 UINTN NumberOfPrinted;\r
a0afd019 523\r
2ad4dad0 524 VA_START (Marker, FormatString);\r
3bbe68a3 525 NumberOfPrinted = UnicodeVSPrintAsciiFormat (StartOfBuffer, BufferSize, FormatString, Marker);\r
526 VA_END (Marker);\r
527 return NumberOfPrinted;\r
2ad4dad0 528}\r
a0afd019 529\r
2ad4dad0
LG
530/**\r
531 Converts a decimal value to a Null-terminated Unicode string.\r
532 \r
533 Converts the decimal number specified by Value to a Null-terminated Unicode \r
534 string specified by Buffer containing at most Width characters. No padding of spaces \r
535 is ever performed. If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed.\r
536 The number of Unicode characters in Buffer is returned not including the Null-terminator.\r
537 If the conversion contains more than Width characters, then only the first\r
538 Width characters are returned, and the total number of characters \r
539 required to perform the conversion is returned.\r
540 Additional conversion parameters are specified in Flags. \r
541 \r
542 The Flags bit LEFT_JUSTIFY is always ignored.\r
543 All conversions are left justified in Buffer.\r
544 If Width is 0, PREFIX_ZERO is ignored in Flags.\r
545 If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas\r
546 are inserted every 3rd digit starting from the right.\r
df8d0595 547 If RADIX_HEX is set in Flags, then the output buffer will be \r
2ad4dad0 548 formatted in hexadecimal format.\r
df8d0595 549 If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in Buffer is a '-'.\r
2ad4dad0
LG
550 If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, \r
551 then Buffer is padded with '0' characters so the combination of the optional '-' \r
552 sign character, '0' characters, digit characters for Value, and the Null-terminator\r
553 add up to Width characters.\r
df8d0595 554 If both COMMA_TYPE and RADIX_HEX are set in Flags, then ASSERT().\r
2ad4dad0
LG
555 If Buffer is NULL, then ASSERT().\r
556 If Buffer is not aligned on a 16-bit boundary, then ASSERT().\r
557 If unsupported bits are set in Flags, then ASSERT().\r
df8d0595 558 If both COMMA_TYPE and RADIX_HEX are set in Flags, then ASSERT().\r
2ad4dad0
LG
559 If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT()\r
560\r
561 @param Buffer Pointer to the output buffer for the produced Null-terminated\r
562 Unicode string.\r
563 @param Flags The bitmask of flags that specify left justification, zero pad, and commas.\r
564 @param Value The 64-bit signed value to convert to a string.\r
565 @param Width The maximum number of Unicode characters to place in Buffer, not including\r
566 the Null-terminator.\r
567 \r
568 @return The number of Unicode characters in Buffer not including the Null-terminator.\r
569\r
570**/\r
571UINTN\r
572EFIAPI\r
573UnicodeValueToString (\r
574 IN OUT CHAR16 *Buffer,\r
575 IN UINTN Flags,\r
576 IN INT64 Value,\r
577 IN UINTN Width\r
578 )\r
579{\r
bee67555 580 return mPrint2Protocol->UnicodeValueToString (Buffer, Flags, Value, Width);\r
2ad4dad0 581}\r
a0afd019 582\r
2ad4dad0
LG
583/**\r
584 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated\r
585 ASCII format string and a VA_LIST argument list.\r
586 \r
587 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer\r
588 and BufferSize.\r
589 The ASCII string is produced by parsing the format string specified by FormatString.\r
590 Arguments are pulled from the variable argument list specified by Marker based on \r
591 the contents of the format string.\r
592 The number of ASCII characters in the produced output buffer is returned not including\r
593 the Null-terminator.\r
594 If BufferSize is 0, then no output buffer is produced and 0 is returned.\r
595\r
596 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT().\r
597 If BufferSize > 0 and FormatString is NULL, then ASSERT().\r
598 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than\r
599 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then\r
600 ASSERT().\r
601 If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string\r
602 contains more than PcdMaximumAsciiStringLength ASCII characters not including the\r
603 Null-terminator, then ASSERT().\r
604\r
605 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated \r
606 ASCII string.\r
607 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
608 @param FormatString Null-terminated Unicode format string.\r
609 @param Marker VA_LIST marker for the variable argument list.\r
610 \r
611 @return The number of ASCII characters in the produced output buffer not including the\r
612 Null-terminator.\r
613\r
614**/\r
615UINTN\r
616EFIAPI\r
617AsciiVSPrint (\r
618 OUT CHAR8 *StartOfBuffer,\r
619 IN UINTN BufferSize,\r
620 IN CONST CHAR8 *FormatString,\r
621 IN VA_LIST Marker\r
622 )\r
a0afd019 623{\r
97f77815 624 UINT64 BaseListMarker[256 / sizeof (UINT64)];\r
504dcb0a 625\r
626 DxePrintLibPrint2ProtocolVaListToBaseList (\r
627 TRUE, \r
628 FormatString, \r
629 Marker, \r
630 (BASE_LIST)BaseListMarker, \r
631 sizeof (BaseListMarker) - 8\r
632 );\r
633\r
634 return AsciiBSPrint (StartOfBuffer, BufferSize, FormatString, (BASE_LIST)BaseListMarker);\r
635}\r
636\r
637/**\r
638 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated\r
639 ASCII format string and a BASE_LIST argument list.\r
640 \r
641 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer\r
642 and BufferSize.\r
643 The ASCII string is produced by parsing the format string specified by FormatString.\r
644 Arguments are pulled from the variable argument list specified by Marker based on \r
645 the contents of the format string.\r
646 The number of ASCII characters in the produced output buffer is returned not including\r
647 the Null-terminator.\r
648 If BufferSize is 0, then no output buffer is produced and 0 is returned.\r
649\r
650 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT().\r
651 If BufferSize > 0 and FormatString is NULL, then ASSERT().\r
652 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than\r
653 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then\r
654 ASSERT().\r
655 If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string\r
656 contains more than PcdMaximumAsciiStringLength ASCII characters not including the\r
657 Null-terminator, then ASSERT().\r
658\r
659 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated \r
660 ASCII string.\r
661 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
662 @param FormatString Null-terminated Unicode format string.\r
663 @param Marker BASE_LIST marker for the variable argument list.\r
664 \r
665 @return The number of ASCII characters in the produced output buffer not including the\r
666 Null-terminator.\r
667\r
668**/\r
669UINTN\r
670EFIAPI\r
671AsciiBSPrint (\r
672 OUT CHAR8 *StartOfBuffer,\r
673 IN UINTN BufferSize,\r
674 IN CONST CHAR8 *FormatString,\r
675 IN BASE_LIST Marker\r
676 )\r
677{\r
678 return mPrint2Protocol->AsciiBSPrint (StartOfBuffer, BufferSize, FormatString, Marker);\r
a0afd019 679}\r
680\r
2ad4dad0
LG
681/**\r
682 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated\r
683 ASCII format string and variable argument list.\r
684 \r
685 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer\r
686 and BufferSize.\r
687 The ASCII string is produced by parsing the format string specified by FormatString.\r
688 Arguments are pulled from the variable argument list based on the contents of the \r
689 format string.\r
690 The number of ASCII characters in the produced output buffer is returned not including\r
691 the Null-terminator.\r
692 If BufferSize is 0, then no output buffer is produced and 0 is returned.\r
693\r
694 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT().\r
695 If BufferSize > 0 and FormatString is NULL, then ASSERT().\r
696 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than\r
697 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then\r
698 ASSERT().\r
699 If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string\r
700 contains more than PcdMaximumAsciiStringLength ASCII characters not including the\r
701 Null-terminator, then ASSERT().\r
702\r
703 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated \r
704 ASCII string.\r
705 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
706 @param FormatString Null-terminated Unicode format string.\r
71898234 707 @param ... Variable argument list whose contents are accessed based on the \r
708 format string specified by FormatString.\r
ce95aa7a 709\r
2ad4dad0
LG
710 @return The number of ASCII characters in the produced output buffer not including the\r
711 Null-terminator.\r
712\r
713**/\r
a0afd019 714UINTN\r
2ad4dad0 715EFIAPI\r
a0afd019 716AsciiSPrint (\r
717 OUT CHAR8 *StartOfBuffer,\r
718 IN UINTN BufferSize,\r
2ad4dad0 719 IN CONST CHAR8 *FormatString,\r
a0afd019 720 ...\r
721 )\r
2ad4dad0
LG
722{\r
723 VA_LIST Marker;\r
3bbe68a3 724 UINTN NumberOfPrinted;\r
2ad4dad0
LG
725\r
726 VA_START (Marker, FormatString);\r
3bbe68a3 727 NumberOfPrinted = AsciiVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);\r
728 VA_END (Marker);\r
729 return NumberOfPrinted;\r
2ad4dad0 730}\r
a0afd019 731\r
2ad4dad0
LG
732/**\r
733 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated\r
734 ASCII format string and a VA_LIST argument list.\r
735 \r
736 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer\r
737 and BufferSize.\r
738 The ASCII string is produced by parsing the format string specified by FormatString.\r
739 Arguments are pulled from the variable argument list specified by Marker based on \r
740 the contents of the format string.\r
741 The number of ASCII characters in the produced output buffer is returned not including\r
742 the Null-terminator.\r
743 If BufferSize is 0, then no output buffer is produced and 0 is returned.\r
744\r
745 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT().\r
746 If BufferSize > 0 and FormatString is NULL, then ASSERT().\r
747 If BufferSize > 0 and FormatString is not aligned on a 16-bit boundary, then ASSERT().\r
748 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than\r
749 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then\r
750 ASSERT().\r
751 If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string\r
752 contains more than PcdMaximumAsciiStringLength ASCII characters not including the\r
753 Null-terminator, then ASSERT().\r
754\r
755 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated \r
756 ASCII string.\r
757 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
758 @param FormatString Null-terminated Unicode format string.\r
759 @param Marker VA_LIST marker for the variable argument list.\r
760 \r
761 @return The number of ASCII characters in the produced output buffer not including the\r
762 Null-terminator.\r
763\r
764**/\r
765UINTN\r
766EFIAPI\r
767AsciiVSPrintUnicodeFormat (\r
768 OUT CHAR8 *StartOfBuffer,\r
769 IN UINTN BufferSize,\r
770 IN CONST CHAR16 *FormatString,\r
771 IN VA_LIST Marker\r
772 )\r
a0afd019 773{\r
97f77815 774 UINT64 BaseListMarker[256 / sizeof (UINT64)];\r
504dcb0a 775\r
776 DxePrintLibPrint2ProtocolVaListToBaseList (\r
777 FALSE, \r
778 (CHAR8 *)FormatString, \r
779 Marker, \r
780 (BASE_LIST)BaseListMarker, \r
781 sizeof (BaseListMarker) - 8\r
782 );\r
783\r
784 return AsciiBSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, (BASE_LIST)BaseListMarker);\r
785}\r
786\r
787/**\r
788 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated\r
789 ASCII format string and a BASE_LIST argument list.\r
790 \r
791 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer\r
792 and BufferSize.\r
793 The ASCII string is produced by parsing the format string specified by FormatString.\r
794 Arguments are pulled from the variable argument list specified by Marker based on \r
795 the contents of the format string.\r
796 The number of ASCII characters in the produced output buffer is returned not including\r
797 the Null-terminator.\r
798 If BufferSize is 0, then no output buffer is produced and 0 is returned.\r
799\r
800 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT().\r
801 If BufferSize > 0 and FormatString is NULL, then ASSERT().\r
802 If BufferSize > 0 and FormatString is not aligned on a 16-bit boundary, then ASSERT().\r
803 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than\r
804 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then\r
805 ASSERT().\r
806 If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string\r
807 contains more than PcdMaximumAsciiStringLength ASCII characters not including the\r
808 Null-terminator, then ASSERT().\r
809\r
810 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated \r
811 ASCII string.\r
812 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
813 @param FormatString Null-terminated Unicode format string.\r
814 @param Marker BASE_LIST marker for the variable argument list.\r
815 \r
816 @return The number of ASCII characters in the produced output buffer not including the\r
817 Null-terminator.\r
818\r
819**/\r
820UINTN\r
821EFIAPI\r
822AsciiBSPrintUnicodeFormat (\r
823 OUT CHAR8 *StartOfBuffer,\r
824 IN UINTN BufferSize,\r
825 IN CONST CHAR16 *FormatString,\r
826 IN BASE_LIST Marker\r
827 )\r
828{\r
829 return mPrint2Protocol->AsciiBSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, Marker);\r
2ad4dad0
LG
830}\r
831\r
832/**\r
833 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated\r
834 ASCII format string and variable argument list.\r
835 \r
836 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer\r
837 and BufferSize.\r
838 The ASCII string is produced by parsing the format string specified by FormatString.\r
839 Arguments are pulled from the variable argument list based on the contents of the \r
840 format string.\r
841 The number of ASCII characters in the produced output buffer is returned not including\r
842 the Null-terminator.\r
843 If BufferSize is 0, then no output buffer is produced and 0 is returned.\r
844\r
845 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT().\r
846 If BufferSize > 0 and FormatString is NULL, then ASSERT().\r
847 If BufferSize > 0 and FormatString is not aligned on a 16-bit boundary, then ASSERT().\r
848 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than\r
849 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then\r
850 ASSERT().\r
851 If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string\r
852 contains more than PcdMaximumAsciiStringLength ASCII characters not including the\r
853 Null-terminator, then ASSERT().\r
854\r
855 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated \r
856 ASCII string.\r
857 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
858 @param FormatString Null-terminated Unicode format string.\r
71898234 859 @param ... Variable argument list whose contents are accessed based on the \r
860 format string specified by FormatString.\r
ce95aa7a 861\r
2ad4dad0
LG
862 @return The number of ASCII characters in the produced output buffer not including the\r
863 Null-terminator.\r
864\r
865**/\r
866UINTN\r
867EFIAPI\r
868AsciiSPrintUnicodeFormat (\r
869 OUT CHAR8 *StartOfBuffer,\r
870 IN UINTN BufferSize,\r
871 IN CONST CHAR16 *FormatString,\r
872 ...\r
873 )\r
874{\r
875 VA_LIST Marker;\r
3bbe68a3 876 UINTN NumberOfPrinted;\r
a0afd019 877\r
878 VA_START (Marker, FormatString);\r
3bbe68a3 879 NumberOfPrinted = AsciiVSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, Marker);\r
880 VA_END (Marker);\r
881 return NumberOfPrinted;\r
2ad4dad0
LG
882}\r
883\r
884\r
885/**\r
886 Converts a decimal value to a Null-terminated ASCII string.\r
887 \r
888 Converts the decimal number specified by Value to a Null-terminated ASCII string \r
889 specified by Buffer containing at most Width characters. No padding of spaces \r
890 is ever performed.\r
891 If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed.\r
892 The number of ASCII characters in Buffer is returned not including the Null-terminator.\r
893 If the conversion contains more than Width characters, then only the first Width\r
894 characters are returned, and the total number of characters required to perform\r
895 the conversion is returned.\r
896 Additional conversion parameters are specified in Flags. \r
897 The Flags bit LEFT_JUSTIFY is always ignored.\r
898 All conversions are left justified in Buffer.\r
899 If Width is 0, PREFIX_ZERO is ignored in Flags.\r
900 If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas\r
901 are inserted every 3rd digit starting from the right.\r
df8d0595 902 If RADIX_HEX is set in Flags, then the output buffer will be \r
2ad4dad0 903 formatted in hexadecimal format.\r
df8d0595 904 If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in Buffer is a '-'.\r
2ad4dad0
LG
905 If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, \r
906 then Buffer is padded with '0' characters so the combination of the optional '-' \r
907 sign character, '0' characters, digit characters for Value, and the Null-terminator\r
908 add up to Width characters.\r
909 \r
910 If Buffer is NULL, then ASSERT().\r
911 If unsupported bits are set in Flags, then ASSERT().\r
df8d0595 912 If both COMMA_TYPE and RADIX_HEX are set in Flags, then ASSERT().\r
2ad4dad0
LG
913 If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT()\r
914\r
915 @param Buffer Pointer to the output buffer for the produced Null-terminated\r
916 ASCII string.\r
917 @param Flags The bitmask of flags that specify left justification, zero pad, and commas.\r
918 @param Value The 64-bit signed value to convert to a string.\r
919 @param Width The maximum number of ASCII characters to place in Buffer, not including\r
920 the Null-terminator.\r
921 \r
922 @return The number of ASCII characters in Buffer not including the Null-terminator.\r
923\r
924**/\r
925UINTN\r
926EFIAPI\r
927AsciiValueToString (\r
ea99d5d1 928 OUT CHAR8 *Buffer,\r
929 IN UINTN Flags,\r
930 IN INT64 Value,\r
931 IN UINTN Width\r
2ad4dad0
LG
932 )\r
933{\r
bee67555 934 return mPrint2Protocol->AsciiValueToString (Buffer, Flags, Value, Width);\r
a0afd019 935}\r
f405c067 936\r
937#define PREFIX_SIGN BIT1\r
938#define PREFIX_BLANK BIT2\r
939#define LONG_TYPE BIT4\r
940#define OUTPUT_UNICODE BIT6\r
941#define FORMAT_UNICODE BIT8\r
942#define PAD_TO_WIDTH BIT9\r
943#define ARGUMENT_UNICODE BIT10\r
944#define PRECISION BIT11\r
945#define ARGUMENT_REVERSED BIT12\r
946#define COUNT_ONLY_NO_PRINT BIT13\r
796fecd8 947#define UNSIGNED_TYPE BIT14\r
f405c067 948\r
949//\r
950// Record date and time information\r
951//\r
952typedef struct {\r
953 UINT16 Year;\r
954 UINT8 Month;\r
955 UINT8 Day;\r
956 UINT8 Hour;\r
957 UINT8 Minute;\r
958 UINT8 Second;\r
959 UINT8 Pad1;\r
960 UINT32 Nanosecond;\r
961 INT16 TimeZone;\r
962 UINT8 Daylight;\r
963 UINT8 Pad2;\r
964} TIME;\r
965\r
966GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mHexStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};\r
967\r
968/**\r
969 Internal function that convert a number to a string in Buffer.\r
970\r
971 Print worker function that converts a decimal or hexadecimal number to an ASCII string in Buffer.\r
972\r
973 @param Buffer Location to place the ASCII string of Value.\r
974 @param Value The value to convert to a Decimal or Hexadecimal string in Buffer.\r
975 @param Radix Radix of the value\r
976\r
977 @return A pointer to the end of buffer filled with ASCII string.\r
978\r
979**/\r
980CHAR8 *\r
981InternalPrintLibValueToString (\r
982 IN OUT CHAR8 *Buffer, \r
983 IN INT64 Value, \r
984 IN UINTN Radix\r
985 )\r
986{\r
987 UINT32 Remainder;\r
988\r
989 //\r
990 // Loop to convert one digit at a time in reverse order\r
991 //\r
992 *Buffer = 0;\r
993 do {\r
994 Value = (INT64)DivU64x32Remainder ((UINT64)Value, (UINT32)Radix, &Remainder);\r
995 *(++Buffer) = mHexStr[Remainder];\r
996 } while (Value != 0);\r
997\r
998 //\r
999 // Return pointer of the end of filled buffer.\r
1000 //\r
1001 return Buffer;\r
1002}\r
1003\r
1004/**\r
1005 Worker function that produces a Null-terminated string in an output buffer \r
1006 based on a Null-terminated format string and a VA_LIST argument list.\r
1007\r
1008 VSPrint function to process format and place the results in Buffer. Since a \r
1009 VA_LIST is used this routine allows the nesting of Vararg routines. Thus \r
1010 this is the main print working routine.\r
1011\r
1012 If COUNT_ONLY_NO_PRINT is set in Flags, Buffer will not be modified at all.\r
1013\r
1014 @param[out] Buffer The character buffer to print the results of the \r
1015 parsing of Format into.\r
1016 @param[in] BufferSize The maximum number of characters to put into \r
1017 buffer.\r
1018 @param[in] Flags Initial flags value.\r
1019 Can only have FORMAT_UNICODE, OUTPUT_UNICODE, \r
1020 and COUNT_ONLY_NO_PRINT set.\r
1021 @param[in] Format A Null-terminated format string.\r
1022 @param[in] VaListMarker VA_LIST style variable argument list consumed by\r
1023 processing Format.\r
1024 @param[in] BaseListMarker BASE_LIST style variable argument list consumed\r
1025 by processing Format.\r
1026\r
1027 @return The number of characters printed not including the Null-terminator.\r
1028 If COUNT_ONLY_NO_PRINT was set returns the same, but without any\r
1029 modification to Buffer.\r
1030\r
1031**/\r
1032UINTN\r
1033InternalPrintLibSPrintMarker (\r
1034 OUT CHAR8 *Buffer,\r
1035 IN UINTN BufferSize,\r
1036 IN UINTN Flags,\r
1037 IN CONST CHAR8 *Format,\r
1038 IN VA_LIST VaListMarker, OPTIONAL\r
1039 IN BASE_LIST BaseListMarker OPTIONAL\r
1040 );\r
1041\r
1042/**\r
1043 Worker function that produces a Null-terminated string in an output buffer \r
1044 based on a Null-terminated format string and variable argument list.\r
1045\r
1046 VSPrint function to process format and place the results in Buffer. Since a \r
1047 VA_LIST is used this routine allows the nesting of Vararg routines. Thus \r
1048 this is the main print working routine\r
1049\r
1050 @param StartOfBuffer The character buffer to print the results of the parsing\r
1051 of Format into.\r
1052 @param BufferSize The maximum number of characters to put into buffer.\r
1053 Zero means no limit.\r
1054 @param Flags Initial flags value.\r
1055 Can only have FORMAT_UNICODE and OUTPUT_UNICODE set\r
1056 @param FormatString A Null-terminated format string.\r
1057 @param ... The variable argument list.\r
1058\r
1059 @return The number of characters printed.\r
1060\r
1061**/\r
1062UINTN\r
1063EFIAPI\r
1064InternalPrintLibSPrint (\r
1065 OUT CHAR8 *StartOfBuffer,\r
1066 IN UINTN BufferSize,\r
1067 IN UINTN Flags,\r
1068 IN CONST CHAR8 *FormatString,\r
1069 ...\r
1070 )\r
1071{\r
1072 VA_LIST Marker;\r
3bbe68a3 1073 UINTN NumberOfPrinted;\r
f405c067 1074\r
1075 VA_START (Marker, FormatString);\r
3bbe68a3 1076 NumberOfPrinted = InternalPrintLibSPrintMarker (StartOfBuffer, BufferSize, Flags, FormatString, Marker, NULL);\r
1077 VA_END (Marker);\r
1078 return NumberOfPrinted;\r
f405c067 1079}\r
1080\r
586d81d1
LG
1081#define WARNING_STATUS_NUMBER 5\r
1082#define ERROR_STATUS_NUMBER 33\r
f405c067 1083\r
1084GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mStatusString[] = {\r
1085 "Success", // RETURN_SUCCESS = 0\r
1086 "Warning Unknown Glyph", // RETURN_WARN_UNKNOWN_GLYPH = 1\r
1087 "Warning Delete Failure", // RETURN_WARN_DELETE_FAILURE = 2\r
1088 "Warning Write Failure", // RETURN_WARN_WRITE_FAILURE = 3\r
1089 "Warning Buffer Too Small", // RETURN_WARN_BUFFER_TOO_SMALL = 4\r
586d81d1 1090 "Warning Stale Data", // RETURN_WARN_STALE_DATA = 5\r
f405c067 1091 "Load Error", // RETURN_LOAD_ERROR = 1 | MAX_BIT\r
1092 "Invalid Parameter", // RETURN_INVALID_PARAMETER = 2 | MAX_BIT\r
1093 "Unsupported", // RETURN_UNSUPPORTED = 3 | MAX_BIT\r
1094 "Bad Buffer Size", // RETURN_BAD_BUFFER_SIZE = 4 | MAX_BIT\r
1095 "Buffer Too Small", // RETURN_BUFFER_TOO_SMALL, = 5 | MAX_BIT\r
1096 "Not Ready", // RETURN_NOT_READY = 6 | MAX_BIT\r
1097 "Device Error", // RETURN_DEVICE_ERROR = 7 | MAX_BIT\r
1098 "Write Protected", // RETURN_WRITE_PROTECTED = 8 | MAX_BIT\r
1099 "Out of Resources", // RETURN_OUT_OF_RESOURCES = 9 | MAX_BIT\r
1100 "Volume Corrupt", // RETURN_VOLUME_CORRUPTED = 10 | MAX_BIT\r
1101 "Volume Full", // RETURN_VOLUME_FULL = 11 | MAX_BIT\r
1102 "No Media", // RETURN_NO_MEDIA = 12 | MAX_BIT\r
1103 "Media changed", // RETURN_MEDIA_CHANGED = 13 | MAX_BIT\r
1104 "Not Found", // RETURN_NOT_FOUND = 14 | MAX_BIT\r
1105 "Access Denied", // RETURN_ACCESS_DENIED = 15 | MAX_BIT\r
1106 "No Response", // RETURN_NO_RESPONSE = 16 | MAX_BIT\r
1107 "No mapping", // RETURN_NO_MAPPING = 17 | MAX_BIT\r
1108 "Time out", // RETURN_TIMEOUT = 18 | MAX_BIT\r
1109 "Not started", // RETURN_NOT_STARTED = 19 | MAX_BIT\r
1110 "Already started", // RETURN_ALREADY_STARTED = 20 | MAX_BIT\r
1111 "Aborted", // RETURN_ABORTED = 21 | MAX_BIT\r
1112 "ICMP Error", // RETURN_ICMP_ERROR = 22 | MAX_BIT\r
1113 "TFTP Error", // RETURN_TFTP_ERROR = 23 | MAX_BIT\r
586d81d1
LG
1114 "Protocol Error", // RETURN_PROTOCOL_ERROR = 24 | MAX_BIT\r
1115 "Incompatible Version", // RETURN_INCOMPATIBLE_VERSION = 25 | MAX_BIT\r
1116 "Security Violation", // RETURN_SECURITY_VIOLATION = 26 | MAX_BIT\r
1117 "CRC Error", // RETURN_CRC_ERROR = 27 | MAX_BIT\r
1118 "End of Media", // RETURN_END_OF_MEDIA = 28 | MAX_BIT\r
1119 "Reserved (29)", // RESERVED = 29 | MAX_BIT\r
1120 "Reserved (30)", // RESERVED = 30 | MAX_BIT\r
1121 "End of File", // RETURN_END_OF_FILE = 31 | MAX_BIT\r
1122 "Invalid Language", // RETURN_INVALID_LANGUAGE = 32 | MAX_BIT\r
1123 "Compromised Data" // RETURN_COMPROMISED_DATA = 33 | MAX_BIT\r
f405c067 1124};\r
1125\r
586d81d1
LG
1126/**\r
1127 Internal function that places the character into the Buffer.\r
1128\r
1129 Internal function that places ASCII or Unicode character into the Buffer.\r
1130\r
1131 @param Buffer The buffer to place the Unicode or ASCII string.\r
1132 @param EndBuffer The end of the input Buffer. No characters will be\r
1133 placed after that. \r
1134 @param Length The count of character to be placed into Buffer.\r
1135 (Negative value indicates no buffer fill.)\r
1136 @param Character The character to be placed into Buffer.\r
1137 @param Increment The character increment in Buffer.\r
1138\r
1139 @return Buffer.\r
1140\r
1141**/\r
1142CHAR8 *\r
1143InternalPrintLibFillBuffer (\r
1144 OUT CHAR8 *Buffer,\r
1145 IN CHAR8 *EndBuffer,\r
1146 IN INTN Length,\r
1147 IN UINTN Character,\r
1148 IN INTN Increment\r
1149 )\r
1150{\r
1151 INTN Index;\r
1152 \r
1153 for (Index = 0; Index < Length && Buffer < EndBuffer; Index++) {\r
1154 *Buffer = (CHAR8) Character;\r
1155 if (Increment != 1) {\r
1156 *(Buffer + 1) = (CHAR8)(Character >> 8);\r
1157 }\r
1158 Buffer += Increment;\r
1159 }\r
1160\r
1161 return Buffer;\r
1162}\r
1163\r
f405c067 1164/**\r
1165 Worker function that produces a Null-terminated string in an output buffer \r
1166 based on a Null-terminated format string and a VA_LIST argument list.\r
1167\r
1168 VSPrint function to process format and place the results in Buffer. Since a \r
1169 VA_LIST is used this routine allows the nesting of Vararg routines. Thus \r
1170 this is the main print working routine.\r
1171\r
1172 If COUNT_ONLY_NO_PRINT is set in Flags, Buffer will not be modified at all.\r
1173\r
1174 @param[out] Buffer The character buffer to print the results of the \r
1175 parsing of Format into.\r
1176 @param[in] BufferSize The maximum number of characters to put into \r
1177 buffer.\r
1178 @param[in] Flags Initial flags value.\r
1179 Can only have FORMAT_UNICODE, OUTPUT_UNICODE, \r
1180 and COUNT_ONLY_NO_PRINT set.\r
1181 @param[in] Format A Null-terminated format string.\r
1182 @param[in] VaListMarker VA_LIST style variable argument list consumed by\r
1183 processing Format.\r
1184 @param[in] BaseListMarker BASE_LIST style variable argument list consumed\r
1185 by processing Format.\r
1186\r
1187 @return The number of characters printed not including the Null-terminator.\r
1188 If COUNT_ONLY_NO_PRINT was set returns the same, but without any\r
1189 modification to Buffer.\r
1190\r
1191**/\r
1192UINTN\r
1193InternalPrintLibSPrintMarker (\r
1194 OUT CHAR8 *Buffer,\r
1195 IN UINTN BufferSize,\r
1196 IN UINTN Flags,\r
1197 IN CONST CHAR8 *Format,\r
1198 IN VA_LIST VaListMarker, OPTIONAL\r
1199 IN BASE_LIST BaseListMarker OPTIONAL\r
1200 )\r
1201{\r
586d81d1 1202 CHAR8 *OriginalBuffer;\r
f405c067 1203 CHAR8 *EndBuffer;\r
1204 CHAR8 ValueBuffer[MAXIMUM_VALUE_CHARACTERS];\r
1205 UINT32 BytesPerOutputCharacter;\r
1206 UINTN BytesPerFormatCharacter;\r
1207 UINTN FormatMask;\r
1208 UINTN FormatCharacter;\r
1209 UINTN Width;\r
1210 UINTN Precision;\r
1211 INT64 Value;\r
1212 CONST CHAR8 *ArgumentString;\r
1213 UINTN Character;\r
1214 GUID *TmpGuid;\r
1215 TIME *TmpTime;\r
1216 UINTN Count;\r
1217 UINTN ArgumentMask;\r
1218 INTN BytesPerArgumentCharacter;\r
1219 UINTN ArgumentCharacter;\r
1220 BOOLEAN Done;\r
1221 UINTN Index;\r
1222 CHAR8 Prefix;\r
1223 BOOLEAN ZeroPad;\r
1224 BOOLEAN Comma;\r
1225 UINTN Digits;\r
1226 UINTN Radix;\r
1227 RETURN_STATUS Status;\r
1228 UINT32 GuidData1;\r
1229 UINT16 GuidData2;\r
1230 UINT16 GuidData3;\r
be5ec8c5 1231 UINTN LengthToReturn;\r
f405c067 1232\r
1233 //\r
1234 // If you change this code be sure to match the 2 versions of this function.\r
1235 // Nearly identical logic is found in the BasePrintLib and \r
1236 // DxePrintLibPrint2Protocol (both PrintLib instances).\r
1237 //\r
1238\r
586d81d1
LG
1239 if ((Flags & COUNT_ONLY_NO_PRINT) != 0) {\r
1240 if (BufferSize == 0) {\r
1241 Buffer = NULL;\r
1242 }\r
1243 } else {\r
1244 //\r
1245 // We can run without a Buffer for counting only.\r
1246 //\r
1247 if (BufferSize == 0) {\r
1248 return 0;\r
1249 }\r
1250 ASSERT (Buffer != NULL);\r
1251 }\r
f405c067 1252\r
ad9aa87b 1253 if ((Flags & OUTPUT_UNICODE) != 0) {\r
f405c067 1254 BytesPerOutputCharacter = 2;\r
1255 } else {\r
1256 BytesPerOutputCharacter = 1;\r
1257 }\r
1258\r
1259 LengthToReturn = 0;\r
586d81d1
LG
1260 EndBuffer = NULL;\r
1261 OriginalBuffer = NULL;\r
f405c067 1262\r
1263 //\r
1264 // Reserve space for the Null terminator.\r
1265 //\r
586d81d1
LG
1266 if (Buffer != NULL) {\r
1267 BufferSize--;\r
1268 OriginalBuffer = Buffer;\r
f405c067 1269\r
586d81d1
LG
1270 //\r
1271 // Set the tag for the end of the input Buffer.\r
1272 //\r
1273 EndBuffer = Buffer + BufferSize * BytesPerOutputCharacter;\r
1274 }\r
f405c067 1275\r
1276 if ((Flags & FORMAT_UNICODE) != 0) {\r
1277 //\r
1278 // Make sure format string cannot contain more than PcdMaximumUnicodeStringLength\r
1279 // Unicode characters if PcdMaximumUnicodeStringLength is not zero. \r
1280 //\r
1281 ASSERT (StrSize ((CHAR16 *) Format) != 0);\r
1282 BytesPerFormatCharacter = 2;\r
1283 FormatMask = 0xffff;\r
1284 } else {\r
1285 //\r
1286 // Make sure format string cannot contain more than PcdMaximumAsciiStringLength\r
1287 // Ascii characters if PcdMaximumAsciiStringLength is not zero. \r
1288 //\r
1289 ASSERT (AsciiStrSize (Format) != 0);\r
1290 BytesPerFormatCharacter = 1;\r
1291 FormatMask = 0xff;\r
1292 }\r
1293\r
1294 //\r
1295 // Get the first character from the format string\r
1296 //\r
1297 FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
1298\r
1299 //\r
1300 // Loop until the end of the format string is reached or the output buffer is full\r
1301 //\r
586d81d1
LG
1302 while (FormatCharacter != 0) {\r
1303 if ((Buffer != NULL) && (Buffer >= EndBuffer)) {\r
1304 break;\r
1305 }\r
f405c067 1306 //\r
1307 // Clear all the flag bits except those that may have been passed in\r
1308 //\r
586d81d1 1309 Flags &= (UINTN) (OUTPUT_UNICODE | FORMAT_UNICODE | COUNT_ONLY_NO_PRINT);\r
f405c067 1310\r
1311 //\r
1312 // Set the default width to zero, and the default precision to 1\r
1313 //\r
1314 Width = 0;\r
1315 Precision = 1;\r
1316 Prefix = 0;\r
1317 Comma = FALSE;\r
1318 ZeroPad = FALSE;\r
1319 Count = 0;\r
1320 Digits = 0;\r
1321\r
1322 switch (FormatCharacter) {\r
1323 case '%':\r
1324 //\r
1325 // Parse Flags and Width\r
1326 //\r
1327 for (Done = FALSE; !Done; ) {\r
1328 Format += BytesPerFormatCharacter;\r
1329 FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
1330 switch (FormatCharacter) {\r
1331 case '.': \r
1332 Flags |= PRECISION; \r
1333 break;\r
1334 case '-': \r
1335 Flags |= LEFT_JUSTIFY; \r
1336 break;\r
1337 case '+': \r
1338 Flags |= PREFIX_SIGN; \r
1339 break;\r
1340 case ' ': \r
1341 Flags |= PREFIX_BLANK; \r
1342 break;\r
1343 case ',': \r
1344 Flags |= COMMA_TYPE; \r
1345 break;\r
1346 case 'L':\r
1347 case 'l': \r
1348 Flags |= LONG_TYPE; \r
1349 break;\r
1350 case '*':\r
1351 if ((Flags & PRECISION) == 0) {\r
1352 Flags |= PAD_TO_WIDTH;\r
1353 if (BaseListMarker == NULL) {\r
1354 Width = VA_ARG (VaListMarker, UINTN);\r
1355 } else {\r
1356 Width = BASE_ARG (BaseListMarker, UINTN);\r
1357 }\r
1358 } else {\r
1359 if (BaseListMarker == NULL) {\r
1360 Precision = VA_ARG (VaListMarker, UINTN);\r
1361 } else {\r
1362 Precision = BASE_ARG (BaseListMarker, UINTN);\r
1363 }\r
1364 }\r
1365 break;\r
1366 case '0':\r
1367 if ((Flags & PRECISION) == 0) {\r
1368 Flags |= PREFIX_ZERO;\r
1369 }\r
1370 case '1':\r
1371 case '2':\r
1372 case '3':\r
1373 case '4':\r
1374 case '5':\r
1375 case '6':\r
1376 case '7':\r
1377 case '8':\r
1378 case '9':\r
1379 for (Count = 0; ((FormatCharacter >= '0') && (FormatCharacter <= '9')); ){\r
1380 Count = (Count * 10) + FormatCharacter - '0';\r
1381 Format += BytesPerFormatCharacter;\r
1382 FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
1383 }\r
1384 Format -= BytesPerFormatCharacter;\r
1385 if ((Flags & PRECISION) == 0) {\r
1386 Flags |= PAD_TO_WIDTH;\r
1387 Width = Count;\r
1388 } else {\r
1389 Precision = Count;\r
1390 }\r
1391 break;\r
1392 \r
1393 case '\0':\r
1394 //\r
1395 // Make no output if Format string terminates unexpectedly when\r
1396 // looking up for flag, width, precision and type. \r
1397 //\r
1398 Format -= BytesPerFormatCharacter;\r
1399 Precision = 0;\r
1400 //\r
1401 // break skipped on purpose.\r
1402 //\r
1403 default:\r
1404 Done = TRUE;\r
1405 break;\r
1406 }\r
1407 } \r
1408\r
1409 //\r
1410 // Handle each argument type\r
1411 //\r
1412 switch (FormatCharacter) {\r
1413 case 'p':\r
1414 //\r
1415 // Flag space, +, 0, L & l are invalid for type p.\r
1416 //\r
586d81d1 1417 Flags &= ~((UINTN) (PREFIX_BLANK | PREFIX_SIGN | PREFIX_ZERO | LONG_TYPE));\r
f405c067 1418 if (sizeof (VOID *) > 4) {\r
1419 Flags |= LONG_TYPE;\r
1420 }\r
586d81d1
LG
1421 //\r
1422 // break skipped on purpose\r
1423 //\r
f405c067 1424 case 'X':\r
1425 Flags |= PREFIX_ZERO;\r
1426 //\r
1427 // break skipped on purpose\r
1428 //\r
1429 case 'x':\r
1430 Flags |= RADIX_HEX;\r
1431 //\r
1432 // break skipped on purpose\r
1433 //\r
796fecd8
QS
1434 case 'u':\r
1435 if ((Flags & RADIX_HEX) == 0) {\r
1436 Flags &= ~((UINTN) (PREFIX_SIGN));\r
1437 Flags |= UNSIGNED_TYPE;\r
1438 }\r
1439 //\r
1440 // break skipped on purpose\r
1441 //\r
f405c067 1442 case 'd':\r
1443 if ((Flags & LONG_TYPE) == 0) {\r
1444 //\r
796fecd8 1445 // 'd', 'u', 'x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".\r
f405c067 1446 // This assumption is made so the format string definition is compatible with the ANSI C\r
1447 // Specification for formatted strings. It is recommended that the Base Types be used \r
1448 // everywhere, but in this one case, compliance with ANSI C is more important, and \r
1449 // provides an implementation that is compatible with that largest possible set of CPU \r
1450 // architectures. This is why the type "int" is used in this one case.\r
1451 //\r
1452 if (BaseListMarker == NULL) {\r
1453 Value = VA_ARG (VaListMarker, int);\r
1454 } else {\r
1455 Value = BASE_ARG (BaseListMarker, int);\r
1456 }\r
1457 } else {\r
1458 if (BaseListMarker == NULL) {\r
1459 Value = VA_ARG (VaListMarker, INT64);\r
1460 } else {\r
1461 Value = BASE_ARG (BaseListMarker, INT64);\r
1462 }\r
1463 }\r
1464 if ((Flags & PREFIX_BLANK) != 0) {\r
1465 Prefix = ' ';\r
1466 }\r
1467 if ((Flags & PREFIX_SIGN) != 0) {\r
1468 Prefix = '+';\r
1469 }\r
1470 if ((Flags & COMMA_TYPE) != 0) {\r
1471 Comma = TRUE;\r
1472 }\r
1473 if ((Flags & RADIX_HEX) == 0) {\r
1474 Radix = 10;\r
1475 if (Comma) {\r
586d81d1 1476 Flags &= ~((UINTN) PREFIX_ZERO);\r
f405c067 1477 Precision = 1;\r
1478 }\r
796fecd8 1479 if (Value < 0 && (Flags & UNSIGNED_TYPE) == 0) {\r
f405c067 1480 Flags |= PREFIX_SIGN;\r
1481 Prefix = '-';\r
1482 Value = -Value;\r
796fecd8
QS
1483 } else if ((Flags & UNSIGNED_TYPE) != 0 && (Flags & LONG_TYPE) == 0) {\r
1484 //\r
1485 // 'd', 'u', 'x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".\r
1486 // This assumption is made so the format string definition is compatible with the ANSI C\r
1487 // Specification for formatted strings. It is recommended that the Base Types be used \r
1488 // everywhere, but in this one case, compliance with ANSI C is more important, and \r
1489 // provides an implementation that is compatible with that largest possible set of CPU \r
1490 // architectures. This is why the type "unsigned int" is used in this one case.\r
1491 //\r
1492 Value = (unsigned int)Value;\r
f405c067 1493 }\r
1494 } else {\r
1495 Radix = 16;\r
1496 Comma = FALSE;\r
1497 if ((Flags & LONG_TYPE) == 0 && Value < 0) {\r
1498 //\r
796fecd8 1499 // 'd', 'u', 'x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".\r
f405c067 1500 // This assumption is made so the format string definition is compatible with the ANSI C\r
1501 // Specification for formatted strings. It is recommended that the Base Types be used \r
1502 // everywhere, but in this one case, compliance with ANSI C is more important, and \r
1503 // provides an implementation that is compatible with that largest possible set of CPU \r
1504 // architectures. This is why the type "unsigned int" is used in this one case.\r
1505 //\r
1506 Value = (unsigned int)Value;\r
1507 }\r
1508 }\r
1509 //\r
1510 // Convert Value to a reversed string\r
1511 //\r
1512 Count = InternalPrintLibValueToString (ValueBuffer, Value, Radix) - ValueBuffer;\r
1513 if (Value == 0 && Precision == 0) {\r
1514 Count = 0;\r
1515 }\r
1516 ArgumentString = (CHAR8 *)ValueBuffer + Count;\r
1517 \r
1518 Digits = Count % 3;\r
1519 if (Digits != 0) {\r
1520 Digits = 3 - Digits;\r
1521 }\r
1522 if (Comma && Count != 0) {\r
1523 Count += ((Count - 1) / 3);\r
1524 }\r
1525 if (Prefix != 0) {\r
1526 Count++;\r
1527 Precision++;\r
1528 }\r
1529 Flags |= ARGUMENT_REVERSED;\r
1530 ZeroPad = TRUE;\r
1531 if ((Flags & PREFIX_ZERO) != 0) {\r
1532 if ((Flags & LEFT_JUSTIFY) == 0) {\r
1533 if ((Flags & PAD_TO_WIDTH) != 0) {\r
1534 if ((Flags & PRECISION) == 0) {\r
1535 Precision = Width;\r
1536 }\r
1537 }\r
1538 }\r
1539 }\r
1540 break;\r
1541\r
1542 case 's':\r
1543 case 'S':\r
1544 Flags |= ARGUMENT_UNICODE;\r
1545 //\r
1546 // break skipped on purpose\r
1547 //\r
1548 case 'a':\r
1549 if (BaseListMarker == NULL) {\r
1550 ArgumentString = VA_ARG (VaListMarker, CHAR8 *);\r
1551 } else {\r
1552 ArgumentString = BASE_ARG (BaseListMarker, CHAR8 *);\r
1553 }\r
1554 if (ArgumentString == NULL) {\r
6e1e5405 1555 Flags &= (~(UINTN)ARGUMENT_UNICODE);\r
f405c067 1556 ArgumentString = "<null string>";\r
1557 }\r
1558 //\r
1559 // Set the default precision for string to be zero if not specified.\r
1560 //\r
1561 if ((Flags & PRECISION) == 0) {\r
1562 Precision = 0;\r
1563 }\r
1564 break;\r
1565\r
1566 case 'c':\r
1567 if (BaseListMarker == NULL) {\r
1568 Character = VA_ARG (VaListMarker, UINTN) & 0xffff;\r
1569 } else {\r
1570 Character = BASE_ARG (BaseListMarker, UINTN) & 0xffff;\r
1571 }\r
1572 ArgumentString = (CHAR8 *)&Character;\r
1573 Flags |= ARGUMENT_UNICODE;\r
1574 break;\r
1575\r
1576 case 'g':\r
1577 if (BaseListMarker == NULL) {\r
1578 TmpGuid = VA_ARG (VaListMarker, GUID *);\r
1579 } else {\r
1580 TmpGuid = BASE_ARG (BaseListMarker, GUID *);\r
1581 }\r
1582 if (TmpGuid == NULL) {\r
1583 ArgumentString = "<null guid>";\r
1584 } else {\r
1585 GuidData1 = ReadUnaligned32 (&(TmpGuid->Data1));\r
1586 GuidData2 = ReadUnaligned16 (&(TmpGuid->Data2));\r
1587 GuidData3 = ReadUnaligned16 (&(TmpGuid->Data3));\r
1588 InternalPrintLibSPrint (\r
1589 ValueBuffer,\r
1590 MAXIMUM_VALUE_CHARACTERS, \r
1591 0,\r
1592 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",\r
1593 GuidData1,\r
1594 GuidData2,\r
1595 GuidData3,\r
1596 TmpGuid->Data4[0],\r
1597 TmpGuid->Data4[1],\r
1598 TmpGuid->Data4[2],\r
1599 TmpGuid->Data4[3],\r
1600 TmpGuid->Data4[4],\r
1601 TmpGuid->Data4[5],\r
1602 TmpGuid->Data4[6],\r
1603 TmpGuid->Data4[7]\r
1604 );\r
1605 ArgumentString = ValueBuffer;\r
1606 }\r
1607 break;\r
1608\r
1609 case 't':\r
1610 if (BaseListMarker == NULL) {\r
1611 TmpTime = VA_ARG (VaListMarker, TIME *); \r
1612 } else {\r
1613 TmpTime = BASE_ARG (BaseListMarker, TIME *); \r
1614 }\r
1615 if (TmpTime == NULL) {\r
1616 ArgumentString = "<null time>";\r
1617 } else {\r
1618 InternalPrintLibSPrint (\r
1619 ValueBuffer,\r
1620 MAXIMUM_VALUE_CHARACTERS,\r
1621 0,\r
1622 "%02d/%02d/%04d %02d:%02d",\r
1623 TmpTime->Month,\r
1624 TmpTime->Day,\r
1625 TmpTime->Year,\r
1626 TmpTime->Hour,\r
1627 TmpTime->Minute\r
1628 );\r
1629 ArgumentString = ValueBuffer;\r
1630 }\r
1631 break;\r
1632\r
1633 case 'r':\r
1634 if (BaseListMarker == NULL) {\r
1635 Status = VA_ARG (VaListMarker, RETURN_STATUS);\r
1636 } else {\r
1637 Status = BASE_ARG (BaseListMarker, RETURN_STATUS);\r
1638 }\r
1639 ArgumentString = ValueBuffer;\r
1640 if (RETURN_ERROR (Status)) {\r
1641 //\r
1642 // Clear error bit\r
1643 //\r
1644 Index = Status & ~MAX_BIT;\r
1645 if (Index > 0 && Index <= ERROR_STATUS_NUMBER) {\r
1646 ArgumentString = mStatusString [Index + WARNING_STATUS_NUMBER];\r
1647 }\r
1648 } else {\r
1649 Index = Status;\r
1650 if (Index <= WARNING_STATUS_NUMBER) {\r
1651 ArgumentString = mStatusString [Index];\r
1652 }\r
1653 }\r
1654 if (ArgumentString == ValueBuffer) {\r
1655 InternalPrintLibSPrint ((CHAR8 *) ValueBuffer, MAXIMUM_VALUE_CHARACTERS, 0, "%08X", Status);\r
1656 }\r
1657 break;\r
1658\r
1659 case '\r':\r
1660 Format += BytesPerFormatCharacter;\r
1661 FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
1662 if (FormatCharacter == '\n') {\r
1663 //\r
1664 // Translate '\r\n' to '\r\n'\r
1665 //\r
1666 ArgumentString = "\r\n";\r
1667 } else {\r
1668 //\r
1669 // Translate '\r' to '\r'\r
1670 //\r
1671 ArgumentString = "\r";\r
1672 Format -= BytesPerFormatCharacter;\r
1673 }\r
1674 break;\r
1675\r
1676 case '\n':\r
1677 //\r
1678 // Translate '\n' to '\r\n' and '\n\r' to '\r\n'\r
1679 //\r
1680 ArgumentString = "\r\n";\r
1681 Format += BytesPerFormatCharacter;\r
1682 FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
1683 if (FormatCharacter != '\r') {\r
1684 Format -= BytesPerFormatCharacter;\r
1685 }\r
1686 break;\r
1687\r
1688 case '%':\r
1689 default:\r
1690 //\r
1691 // if the type is '%' or unknown, then print it to the screen\r
1692 //\r
1693 ArgumentString = (CHAR8 *)&FormatCharacter;\r
1694 Flags |= ARGUMENT_UNICODE;\r
1695 break;\r
1696 }\r
1697 break;\r
1698 \r
1699 case '\r':\r
1700 Format += BytesPerFormatCharacter;\r
1701 FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
1702 if (FormatCharacter == '\n') {\r
1703 //\r
1704 // Translate '\r\n' to '\r\n'\r
1705 //\r
1706 ArgumentString = "\r\n";\r
1707 } else {\r
1708 //\r
1709 // Translate '\r' to '\r'\r
1710 //\r
1711 ArgumentString = "\r";\r
1712 Format -= BytesPerFormatCharacter;\r
1713 }\r
1714 break;\r
1715\r
1716 case '\n':\r
1717 //\r
1718 // Translate '\n' to '\r\n' and '\n\r' to '\r\n'\r
1719 //\r
1720 ArgumentString = "\r\n";\r
1721 Format += BytesPerFormatCharacter;\r
1722 FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
1723 if (FormatCharacter != '\r') {\r
1724 Format -= BytesPerFormatCharacter;\r
1725 }\r
1726 break;\r
1727\r
1728 default:\r
1729 ArgumentString = (CHAR8 *)&FormatCharacter;\r
1730 Flags |= ARGUMENT_UNICODE;\r
1731 break;\r
1732 }\r
1733\r
1734 //\r
1735 // Retrieve the ArgumentString attriubutes\r
1736 //\r
1737 if ((Flags & ARGUMENT_UNICODE) != 0) {\r
1738 ArgumentMask = 0xffff;\r
1739 BytesPerArgumentCharacter = 2;\r
1740 } else {\r
1741 ArgumentMask = 0xff;\r
1742 BytesPerArgumentCharacter = 1;\r
1743 }\r
1744 if ((Flags & ARGUMENT_REVERSED) != 0) {\r
1745 BytesPerArgumentCharacter = -BytesPerArgumentCharacter;\r
1746 } else {\r
1747 //\r
1748 // Compute the number of characters in ArgumentString and store it in Count\r
1749 // ArgumentString is either null-terminated, or it contains Precision characters\r
1750 //\r
1751 for (Count = 0; Count < Precision || ((Flags & PRECISION) == 0); Count++) {\r
1752 ArgumentCharacter = ((ArgumentString[Count * BytesPerArgumentCharacter] & 0xff) | ((ArgumentString[Count * BytesPerArgumentCharacter + 1]) << 8)) & ArgumentMask;\r
1753 if (ArgumentCharacter == 0) {\r
1754 break;\r
1755 }\r
1756 }\r
1757 }\r
1758\r
1759 if (Precision < Count) {\r
1760 Precision = Count;\r
1761 }\r
1762\r
1763 //\r
1764 // Pad before the string\r
1765 //\r
1766 if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH)) {\r
6bae492f 1767 LengthToReturn += ((Width - Precision) * BytesPerOutputCharacter);\r
586d81d1
LG
1768 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {\r
1769 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, Width - Precision, ' ', BytesPerOutputCharacter);\r
1770 }\r
f405c067 1771 }\r
1772\r
1773 if (ZeroPad) {\r
1774 if (Prefix != 0) {\r
6bae492f 1775 LengthToReturn += (1 * BytesPerOutputCharacter);\r
586d81d1
LG
1776 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {\r
1777 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, 1, Prefix, BytesPerOutputCharacter);\r
1778 }\r
f405c067 1779 }\r
6bae492f 1780 LengthToReturn += ((Precision - Count) * BytesPerOutputCharacter);\r
586d81d1
LG
1781 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {\r
1782 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, Precision - Count, '0', BytesPerOutputCharacter);\r
1783 }\r
f405c067 1784 } else {\r
6bae492f 1785 LengthToReturn += ((Precision - Count) * BytesPerOutputCharacter);\r
586d81d1
LG
1786 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {\r
1787 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, Precision - Count, ' ', BytesPerOutputCharacter);\r
1788 }\r
f405c067 1789 if (Prefix != 0) {\r
6bae492f 1790 LengthToReturn += (1 * BytesPerOutputCharacter);\r
586d81d1
LG
1791 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {\r
1792 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, 1, Prefix, BytesPerOutputCharacter);\r
1793 }\r
f405c067 1794 }\r
1795 }\r
1796\r
1797 //\r
1798 // Output the Prefix character if it is present\r
1799 //\r
1800 Index = 0;\r
1801 if (Prefix != 0) {\r
1802 Index++;\r
1803 }\r
1804\r
1805 //\r
1806 // Copy the string into the output buffer performing the required type conversions\r
1807 //\r
1808 while (Index < Count) {\r
1809 ArgumentCharacter = ((*ArgumentString & 0xff) | (*(ArgumentString + 1) << 8)) & ArgumentMask;\r
1810\r
6bae492f 1811 LengthToReturn += (1 * BytesPerOutputCharacter);\r
586d81d1
LG
1812 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {\r
1813 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, 1, ArgumentCharacter, BytesPerOutputCharacter);\r
1814 }\r
f405c067 1815 ArgumentString += BytesPerArgumentCharacter;\r
1816 Index++;\r
1817 if (Comma) {\r
1818 Digits++;\r
1819 if (Digits == 3) {\r
1820 Digits = 0;\r
1821 Index++;\r
1822 if (Index < Count) {\r
6bae492f 1823 LengthToReturn += (1 * BytesPerOutputCharacter);\r
586d81d1
LG
1824 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {\r
1825 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, 1, ',', BytesPerOutputCharacter);\r
1826 }\r
f405c067 1827 }\r
1828 }\r
1829 }\r
1830 }\r
1831\r
1832 //\r
1833 // Pad after the string\r
1834 //\r
1835 if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH | LEFT_JUSTIFY)) {\r
6bae492f 1836 LengthToReturn += ((Width - Precision) * BytesPerOutputCharacter);\r
586d81d1
LG
1837 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {\r
1838 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, Width - Precision, ' ', BytesPerOutputCharacter);\r
1839 }\r
f405c067 1840 }\r
1841\r
1842 //\r
1843 // Get the next character from the format string\r
1844 //\r
1845 Format += BytesPerFormatCharacter;\r
1846\r
1847 //\r
1848 // Get the next character from the format string\r
1849 //\r
1850 FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;\r
1851 }\r
1852\r
586d81d1
LG
1853 if ((Flags & COUNT_ONLY_NO_PRINT) != 0) {\r
1854 return (LengthToReturn / BytesPerOutputCharacter);\r
1855 }\r
1856\r
1857 ASSERT (Buffer != NULL);\r
1858 //\r
1859 // Null terminate the Unicode or ASCII string\r
1860 //\r
1861 InternalPrintLibFillBuffer (Buffer, EndBuffer + BytesPerOutputCharacter, 1, 0, BytesPerOutputCharacter);\r
1862 //\r
1863 // Make sure output buffer cannot contain more than PcdMaximumUnicodeStringLength\r
1864 // Unicode characters if PcdMaximumUnicodeStringLength is not zero. \r
1865 //\r
1866 ASSERT ((((Flags & OUTPUT_UNICODE) == 0)) || (StrSize ((CHAR16 *) OriginalBuffer) != 0));\r
1867 //\r
1868 // Make sure output buffer cannot contain more than PcdMaximumAsciiStringLength\r
1869 // ASCII characters if PcdMaximumAsciiStringLength is not zero. \r
1870 //\r
1871 ASSERT ((((Flags & OUTPUT_UNICODE) != 0)) || (AsciiStrSize (OriginalBuffer) != 0));\r
1872\r
1873 return ((Buffer - OriginalBuffer) / BytesPerOutputCharacter);\r
f405c067 1874}\r
1875\r
1876/**\r
1877 Returns the number of characters that would be produced by if the formatted \r
1878 output were produced not including the Null-terminator.\r
1879\r
1880 If FormatString is NULL, then ASSERT().\r
1881 If FormatString is not aligned on a 16-bit boundary, then ASSERT().\r
1882\r
1883 @param[in] FormatString A Null-terminated Unicode format string.\r
1884 @param[in] Marker VA_LIST marker for the variable argument list.\r
1885\r
1886 @return The number of characters that would be produced, not including the \r
1887 Null-terminator.\r
1888**/\r
1889UINTN\r
1890EFIAPI\r
1891SPrintLength (\r
1892 IN CONST CHAR16 *FormatString,\r
1893 IN VA_LIST Marker\r
1894 )\r
1895{\r
1896 ASSERT(FormatString != NULL);\r
1897 return InternalPrintLibSPrintMarker (NULL, 0, FORMAT_UNICODE | OUTPUT_UNICODE | COUNT_ONLY_NO_PRINT, (CHAR8 *)FormatString, Marker, NULL);\r
1898}\r
1899\r
1900/**\r
1901 Returns the number of characters that would be produced by if the formatted \r
1902 output were produced not including the Null-terminator.\r
1903\r
1904 If FormatString is NULL, then ASSERT().\r
1905\r
1906 @param[in] FormatString A Null-terminated ASCII format string.\r
1907 @param[in] Marker VA_LIST marker for the variable argument list.\r
1908\r
1909 @return The number of characters that would be produced, not including the \r
1910 Null-terminator.\r
1911**/\r
1912UINTN\r
1913EFIAPI\r
1914SPrintLengthAsciiFormat (\r
1915 IN CONST CHAR8 *FormatString,\r
1916 IN VA_LIST Marker\r
1917 )\r
1918{\r
1919 ASSERT(FormatString != NULL);\r
1920 return InternalPrintLibSPrintMarker (NULL, 0, OUTPUT_UNICODE | COUNT_ONLY_NO_PRINT, (CHAR8 *)FormatString, Marker, NULL);\r
1921}\r