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