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