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