2 Instance of Print Library based on gEfiPrint2SProtocolGuid.
4 Implement the print library instance by wrap the interface
5 provided in the Print2S protocol. This protocol is defined as the internal
6 protocol related to this implementation, not in the public spec. So, this
7 library instance is only for this code base.
9 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
10 SPDX-License-Identifier: BSD-2-Clause-Patent
16 #include <Protocol/Print2.h>
18 #include <Library/PrintLib.h>
20 #include <Library/BaseLib.h>
21 #include <Library/DebugLib.h>
22 #include <Library/PcdLib.h>
24 #define ASSERT_UNICODE_BUFFER(Buffer) ASSERT ((((UINTN) (Buffer)) & 0x01) == 0)
29 #define RSIZE_MAX (PcdGet32 (PcdMaximumUnicodeStringLength))
30 #define ASCII_RSIZE_MAX (PcdGet32 (PcdMaximumAsciiStringLength))
32 #define SAFE_PRINT_CONSTRAINT_CHECK(Expression, RetVal) \
34 ASSERT (Expression); \
35 if (!(Expression)) { \
40 EFI_PRINT2S_PROTOCOL
*mPrint2SProtocol
= NULL
;
43 The constructor function caches the pointer to Print2S protocol.
45 The constructor function locates Print2S protocol from protocol database.
46 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
48 @param ImageHandle The firmware allocated handle for the EFI image.
49 @param SystemTable A pointer to the EFI System Table.
51 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
57 IN EFI_HANDLE ImageHandle
,
58 IN EFI_SYSTEM_TABLE
*SystemTable
63 Status
= SystemTable
->BootServices
->LocateProtocol (
64 &gEfiPrint2SProtocolGuid
,
66 (VOID
**)&mPrint2SProtocol
68 ASSERT_EFI_ERROR (Status
);
69 ASSERT (mPrint2SProtocol
!= NULL
);
75 Worker function that converts a VA_LIST to a BASE_LIST based on a Null-terminated
78 @param AsciiFormat TRUE if Format is an ASCII string. FALSE if Format is a Unicode string.
79 @param Format Null-terminated format string.
80 @param VaListMarker VA_LIST style variable argument list consumed by processing Format.
81 @param BaseListMarker BASE_LIST style variable argument list consumed by processing Format.
82 @param Size The size, in bytes, of the BaseListMarker buffer.
84 @return TRUE The VA_LIST has been converted to BASE_LIST.
85 @return FALSE The VA_LIST has not been converted to BASE_LIST.
89 DxePrintLibPrint2ProtocolVaListToBaseList (
90 IN BOOLEAN AsciiFormat
,
91 IN CONST CHAR8
*Format
,
92 IN VA_LIST VaListMarker
,
93 OUT BASE_LIST BaseListMarker
,
97 BASE_LIST BaseListStart
;
98 UINTN BytesPerFormatCharacter
;
100 UINTN FormatCharacter
;
104 ASSERT (BaseListMarker
!= NULL
);
105 SAFE_PRINT_CONSTRAINT_CHECK ((Format
!= NULL
), FALSE
);
107 BaseListStart
= BaseListMarker
;
110 if (ASCII_RSIZE_MAX
!= 0) {
111 SAFE_PRINT_CONSTRAINT_CHECK ((AsciiStrnLenS (Format
, ASCII_RSIZE_MAX
+ 1) <= ASCII_RSIZE_MAX
), FALSE
);
114 BytesPerFormatCharacter
= 1;
117 if (RSIZE_MAX
!= 0) {
118 SAFE_PRINT_CONSTRAINT_CHECK ((StrnLenS ((CHAR16
*)Format
, RSIZE_MAX
+ 1) <= RSIZE_MAX
), FALSE
);
121 BytesPerFormatCharacter
= 2;
126 // Get the first character from the format string
128 FormatCharacter
= ((*Format
& 0xff) | ((BytesPerFormatCharacter
== 1) ? 0 : (*(Format
+ 1) << 8))) & FormatMask
;
130 while (FormatCharacter
!= 0) {
131 if (FormatCharacter
== '%') {
135 // Parse Flags and Width
137 for (Done
= FALSE
; !Done
; ) {
139 // Get the next character from the format string
141 Format
+= BytesPerFormatCharacter
;
144 // Get the next character from the format string
146 FormatCharacter
= ((*Format
& 0xff) | ((BytesPerFormatCharacter
== 1) ? 0 : (*(Format
+ 1) << 8))) & FormatMask
;
148 switch (FormatCharacter
) {
170 BASE_ARG (BaseListMarker
, UINTN
) = VA_ARG (VaListMarker
, UINTN
);
174 // Make no output if Format string terminates unexpectedly when
175 // looking up for flag, width, precision and type.
177 Format
-= BytesPerFormatCharacter
;
179 // break skipped on purpose.
188 // Handle each argument type
190 switch (FormatCharacter
) {
192 if (sizeof (VOID
*) > 4) {
201 BASE_ARG (BaseListMarker
, INT64
) = VA_ARG (VaListMarker
, INT64
);
203 BASE_ARG (BaseListMarker
, int) = VA_ARG (VaListMarker
, int);
212 BASE_ARG (BaseListMarker
, VOID
*) = VA_ARG (VaListMarker
, VOID
*);
215 BASE_ARG (BaseListMarker
, UINTN
) = VA_ARG (VaListMarker
, UINTN
);
218 BASE_ARG (BaseListMarker
, RETURN_STATUS
) = VA_ARG (VaListMarker
, RETURN_STATUS
);
224 // If BASE_LIST is larger than Size, then return FALSE
226 if (((UINTN
)BaseListMarker
- (UINTN
)BaseListStart
) > Size
) {
227 DEBUG ((DEBUG_ERROR
, "The input variable argument list is too long. Please consider breaking into multiple print calls.\n"));
232 // Get the next character from the format string
234 Format
+= BytesPerFormatCharacter
;
237 // Get the next character from the format string
239 FormatCharacter
= ((*Format
& 0xff) | ((BytesPerFormatCharacter
== 1) ? 0 : (*(Format
+ 1) << 8))) & FormatMask
;
246 Produces a Null-terminated Unicode string in an output buffer based on
247 a Null-terminated Unicode format string and a VA_LIST argument list.
249 This function is similar as vsnprintf_s defined in C11.
251 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
253 The Unicode string is produced by parsing the format string specified by FormatString.
254 Arguments are pulled from the variable argument list specified by Marker based on the
255 contents of the format string.
256 The number of Unicode characters in the produced output buffer is returned not including
259 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
260 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
262 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
263 unmodified and 0 is returned.
264 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
265 unmodified and 0 is returned.
266 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
267 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
268 buffer is unmodified and 0 is returned.
269 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
270 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
271 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
273 If BufferSize is 0 or 1, then the output buffer is unmodified and 0 is returned.
275 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
277 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
278 @param FormatString A Null-terminated Unicode format string.
279 @param Marker VA_LIST marker for the variable argument list.
281 @return The number of Unicode characters in the produced output buffer not including the
288 OUT CHAR16
*StartOfBuffer
,
290 IN CONST CHAR16
*FormatString
,
294 UINT64 BaseListMarker
[256 / sizeof (UINT64
)];
297 ASSERT_UNICODE_BUFFER (StartOfBuffer
);
298 ASSERT_UNICODE_BUFFER (FormatString
);
300 Converted
= DxePrintLibPrint2ProtocolVaListToBaseList (
302 (CHAR8
*)FormatString
,
304 (BASE_LIST
)BaseListMarker
,
305 sizeof (BaseListMarker
) - 8
311 return UnicodeBSPrint (StartOfBuffer
, BufferSize
, FormatString
, (BASE_LIST
)BaseListMarker
);
315 Produces a Null-terminated Unicode string in an output buffer based on
316 a Null-terminated Unicode format string and a BASE_LIST argument list.
318 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
320 The Unicode string is produced by parsing the format string specified by FormatString.
321 Arguments are pulled from the variable argument list specified by Marker based on the
322 contents of the format string.
323 The number of Unicode characters in the produced output buffer is returned not including
326 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
327 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
329 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
330 unmodified and 0 is returned.
331 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
332 unmodified and 0 is returned.
333 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
334 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
335 buffer is unmodified and 0 is returned.
336 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
337 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
338 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
340 If BufferSize is 0 or 1, then the output buffer is unmodified and 0 is returned.
342 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
344 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
345 @param FormatString A Null-terminated Unicode format string.
346 @param Marker BASE_LIST marker for the variable argument list.
348 @return The number of Unicode characters in the produced output buffer not including the
355 OUT CHAR16
*StartOfBuffer
,
357 IN CONST CHAR16
*FormatString
,
361 ASSERT_UNICODE_BUFFER (StartOfBuffer
);
362 ASSERT_UNICODE_BUFFER (FormatString
);
363 return mPrint2SProtocol
->UnicodeBSPrint (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
367 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
368 Unicode format string and variable argument list.
370 This function is similar as snprintf_s defined in C11.
372 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
374 The Unicode string is produced by parsing the format string specified by FormatString.
375 Arguments are pulled from the variable argument list based on the contents of the format string.
376 The number of Unicode characters in the produced output buffer is returned not including
379 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
380 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
382 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
383 unmodified and 0 is returned.
384 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
385 unmodified and 0 is returned.
386 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
387 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
388 buffer is unmodified and 0 is returned.
389 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
390 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
391 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
393 If BufferSize is 0 or 1, then the output buffer is unmodified and 0 is returned.
395 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
397 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
398 @param FormatString A Null-terminated Unicode format string.
399 @param ... Variable argument list whose contents are accessed based on the
400 format string specified by FormatString.
402 @return The number of Unicode characters in the produced output buffer not including the
409 OUT CHAR16
*StartOfBuffer
,
411 IN CONST CHAR16
*FormatString
,
416 UINTN NumberOfPrinted
;
418 VA_START (Marker
, FormatString
);
419 NumberOfPrinted
= UnicodeVSPrint (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
421 return NumberOfPrinted
;
425 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
426 ASCII format string and a VA_LIST argument list.
428 This function is similar as vsnprintf_s defined in C11.
430 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
432 The Unicode string is produced by parsing the format string specified by FormatString.
433 Arguments are pulled from the variable argument list specified by Marker based on the
434 contents of the format string.
435 The number of Unicode characters in the produced output buffer is returned not including
438 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
440 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
441 unmodified and 0 is returned.
442 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
443 unmodified and 0 is returned.
444 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
445 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
446 buffer is unmodified and 0 is returned.
447 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
448 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
449 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
451 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.
453 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
455 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
456 @param FormatString A Null-terminated ASCII format string.
457 @param Marker VA_LIST marker for the variable argument list.
459 @return The number of Unicode characters in the produced output buffer not including the
465 UnicodeVSPrintAsciiFormat (
466 OUT CHAR16
*StartOfBuffer
,
468 IN CONST CHAR8
*FormatString
,
472 UINT64 BaseListMarker
[256 / sizeof (UINT64
)];
475 ASSERT_UNICODE_BUFFER (StartOfBuffer
);
477 Converted
= DxePrintLibPrint2ProtocolVaListToBaseList (
481 (BASE_LIST
)BaseListMarker
,
482 sizeof (BaseListMarker
) - 8
488 return UnicodeBSPrintAsciiFormat (StartOfBuffer
, BufferSize
, FormatString
, (BASE_LIST
)BaseListMarker
);
492 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
493 ASCII format string and a BASE_LIST argument list.
495 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
497 The Unicode string is produced by parsing the format string specified by FormatString.
498 Arguments are pulled from the variable argument list specified by Marker based on the
499 contents of the format string.
500 The number of Unicode characters in the produced output buffer is returned not including
503 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
505 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
506 unmodified and 0 is returned.
507 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
508 unmodified and 0 is returned.
509 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
510 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
511 buffer is unmodified and 0 is returned.
512 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
513 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
514 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
516 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.
518 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
520 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
521 @param FormatString A Null-terminated ASCII format string.
522 @param Marker BASE_LIST marker for the variable argument list.
524 @return The number of Unicode characters in the produced output buffer not including the
530 UnicodeBSPrintAsciiFormat (
531 OUT CHAR16
*StartOfBuffer
,
533 IN CONST CHAR8
*FormatString
,
537 ASSERT_UNICODE_BUFFER (StartOfBuffer
);
538 return mPrint2SProtocol
->UnicodeBSPrintAsciiFormat (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
542 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
543 ASCII format string and variable argument list.
545 This function is similar as snprintf_s defined in C11.
547 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
549 The Unicode string is produced by parsing the format string specified by FormatString.
550 Arguments are pulled from the variable argument list based on the contents of the
552 The number of Unicode characters in the produced output buffer is returned not including
555 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
557 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
558 unmodified and 0 is returned.
559 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
560 unmodified and 0 is returned.
561 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
562 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
563 buffer is unmodified and 0 is returned.
564 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
565 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
566 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
568 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.
570 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
572 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
573 @param FormatString A Null-terminated ASCII format string.
574 @param ... Variable argument list whose contents are accessed based on the
575 format string specified by FormatString.
577 @return The number of Unicode characters in the produced output buffer not including the
583 UnicodeSPrintAsciiFormat (
584 OUT CHAR16
*StartOfBuffer
,
586 IN CONST CHAR8
*FormatString
,
591 UINTN NumberOfPrinted
;
593 VA_START (Marker
, FormatString
);
594 NumberOfPrinted
= UnicodeVSPrintAsciiFormat (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
596 return NumberOfPrinted
;
600 Converts a decimal value to a Null-terminated Unicode string.
602 Converts the decimal number specified by Value to a Null-terminated Unicode
603 string specified by Buffer containing at most Width characters. No padding of
604 spaces is ever performed. If Width is 0 then a width of
605 MAXIMUM_VALUE_CHARACTERS is assumed. If the conversion contains more than
606 Width characters, then only the first Width characters are placed in Buffer.
607 Additional conversion parameters are specified in Flags.
609 The Flags bit LEFT_JUSTIFY is always ignored.
610 All conversions are left justified in Buffer.
611 If Width is 0, PREFIX_ZERO is ignored in Flags.
612 If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and
613 commas are inserted every 3rd digit starting from the right.
614 If RADIX_HEX is set in Flags, then the output buffer will be formatted in
616 If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in
618 If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, then
619 Buffer is padded with '0' characters so the combination of the optional '-'
620 sign character, '0' characters, digit characters for Value, and the
621 Null-terminator add up to Width characters.
623 If Buffer is not aligned on a 16-bit boundary, then ASSERT().
624 If an error would be returned, then the function will also ASSERT().
626 @param Buffer The pointer to the output buffer for the produced
627 Null-terminated Unicode string.
628 @param BufferSize The size of Buffer in bytes, including the
630 @param Flags The bitmask of flags that specify left justification,
631 zero pad, and commas.
632 @param Value The 64-bit signed value to convert to a string.
633 @param Width The maximum number of Unicode characters to place in
634 Buffer, not including the Null-terminator.
636 @retval RETURN_SUCCESS The decimal value is converted.
637 @retval RETURN_BUFFER_TOO_SMALL If BufferSize cannot hold the converted
639 @retval RETURN_INVALID_PARAMETER If Buffer is NULL.
640 If PcdMaximumUnicodeStringLength is not
641 zero, and BufferSize is greater than
642 (PcdMaximumUnicodeStringLength *
643 sizeof (CHAR16) + 1).
644 If unsupported bits are set in Flags.
645 If both COMMA_TYPE and RADIX_HEX are set in
647 If Width >= MAXIMUM_VALUE_CHARACTERS.
652 UnicodeValueToStringS (
653 IN OUT CHAR16
*Buffer
,
660 return mPrint2SProtocol
->UnicodeValueToStringS (Buffer
, BufferSize
, Flags
, Value
, Width
);
664 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
665 ASCII format string and a VA_LIST argument list.
667 This function is similar as vsnprintf_s defined in C11.
669 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
671 The ASCII string is produced by parsing the format string specified by FormatString.
672 Arguments are pulled from the variable argument list specified by Marker based on
673 the contents of the format string.
674 The number of ASCII characters in the produced output buffer is returned not including
677 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
678 unmodified and 0 is returned.
679 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
680 unmodified and 0 is returned.
681 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
682 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
683 is unmodified and 0 is returned.
684 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
685 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
686 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
688 If BufferSize is 0, then no output buffer is produced and 0 is returned.
690 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
692 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
693 @param FormatString A Null-terminated ASCII format string.
694 @param Marker VA_LIST marker for the variable argument list.
696 @return The number of ASCII characters in the produced output buffer not including the
703 OUT CHAR8
*StartOfBuffer
,
705 IN CONST CHAR8
*FormatString
,
709 UINT64 BaseListMarker
[256 / sizeof (UINT64
)];
712 Converted
= DxePrintLibPrint2ProtocolVaListToBaseList (
716 (BASE_LIST
)BaseListMarker
,
717 sizeof (BaseListMarker
) - 8
723 return AsciiBSPrint (StartOfBuffer
, BufferSize
, FormatString
, (BASE_LIST
)BaseListMarker
);
727 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
728 ASCII format string and a BASE_LIST argument list.
730 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
732 The ASCII string is produced by parsing the format string specified by FormatString.
733 Arguments are pulled from the variable argument list specified by Marker based on
734 the contents of the format string.
735 The number of ASCII characters in the produced output buffer is returned not including
738 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
739 unmodified and 0 is returned.
740 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
741 unmodified and 0 is returned.
742 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
743 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
744 is unmodified and 0 is returned.
745 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
746 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
747 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
749 If BufferSize is 0, then no output buffer is produced and 0 is returned.
751 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
753 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
754 @param FormatString A Null-terminated ASCII format string.
755 @param Marker BASE_LIST marker for the variable argument list.
757 @return The number of ASCII characters in the produced output buffer not including the
764 OUT CHAR8
*StartOfBuffer
,
766 IN CONST CHAR8
*FormatString
,
770 return mPrint2SProtocol
->AsciiBSPrint (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
774 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
775 ASCII format string and variable argument list.
777 This function is similar as snprintf_s defined in C11.
779 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
781 The ASCII string is produced by parsing the format string specified by FormatString.
782 Arguments are pulled from the variable argument list based on the contents of the
784 The number of ASCII characters in the produced output buffer is returned not including
787 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
788 unmodified and 0 is returned.
789 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
790 unmodified and 0 is returned.
791 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
792 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
793 is unmodified and 0 is returned.
794 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
795 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
796 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
798 If BufferSize is 0, then no output buffer is produced and 0 is returned.
800 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
802 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
803 @param FormatString A Null-terminated ASCII format string.
804 @param ... Variable argument list whose contents are accessed based on the
805 format string specified by FormatString.
807 @return The number of ASCII characters in the produced output buffer not including the
814 OUT CHAR8
*StartOfBuffer
,
816 IN CONST CHAR8
*FormatString
,
821 UINTN NumberOfPrinted
;
823 VA_START (Marker
, FormatString
);
824 NumberOfPrinted
= AsciiVSPrint (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
826 return NumberOfPrinted
;
830 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
831 Unicode format string and a VA_LIST argument list.
833 This function is similar as vsnprintf_s defined in C11.
835 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
837 The ASCII string is produced by parsing the format string specified by FormatString.
838 Arguments are pulled from the variable argument list specified by Marker based on
839 the contents of the format string.
840 The number of ASCII characters in the produced output buffer is returned not including
843 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
845 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
846 unmodified and 0 is returned.
847 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
848 unmodified and 0 is returned.
849 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
850 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
851 is unmodified and 0 is returned.
852 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
853 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
854 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
856 If BufferSize is 0, then no output buffer is produced and 0 is returned.
858 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
860 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
861 @param FormatString A Null-terminated Unicode format string.
862 @param Marker VA_LIST marker for the variable argument list.
864 @return The number of ASCII characters in the produced output buffer not including the
870 AsciiVSPrintUnicodeFormat (
871 OUT CHAR8
*StartOfBuffer
,
873 IN CONST CHAR16
*FormatString
,
877 UINT64 BaseListMarker
[256 / sizeof (UINT64
)];
880 ASSERT_UNICODE_BUFFER (FormatString
);
882 Converted
= DxePrintLibPrint2ProtocolVaListToBaseList (
884 (CHAR8
*)FormatString
,
886 (BASE_LIST
)BaseListMarker
,
887 sizeof (BaseListMarker
) - 8
893 return AsciiBSPrintUnicodeFormat (StartOfBuffer
, BufferSize
, FormatString
, (BASE_LIST
)BaseListMarker
);
897 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
898 Unicode format string and a BASE_LIST argument list.
900 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
902 The ASCII string is produced by parsing the format string specified by FormatString.
903 Arguments are pulled from the variable argument list specified by Marker based on
904 the contents of the format string.
905 The number of ASCII characters in the produced output buffer is returned not including
908 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
910 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
911 unmodified and 0 is returned.
912 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
913 unmodified and 0 is returned.
914 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
915 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
916 is unmodified and 0 is returned.
917 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
918 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
919 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
921 If BufferSize is 0, then no output buffer is produced and 0 is returned.
923 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
925 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
926 @param FormatString A Null-terminated Unicode format string.
927 @param Marker BASE_LIST marker for the variable argument list.
929 @return The number of ASCII characters in the produced output buffer not including the
935 AsciiBSPrintUnicodeFormat (
936 OUT CHAR8
*StartOfBuffer
,
938 IN CONST CHAR16
*FormatString
,
942 ASSERT_UNICODE_BUFFER (FormatString
);
943 return mPrint2SProtocol
->AsciiBSPrintUnicodeFormat (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
947 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
948 Unicode format string and variable argument list.
950 This function is similar as snprintf_s defined in C11.
952 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
954 The ASCII string is produced by parsing the format string specified by FormatString.
955 Arguments are pulled from the variable argument list based on the contents of the
957 The number of ASCII characters in the produced output buffer is returned not including
960 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
962 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
963 unmodified and 0 is returned.
964 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
965 unmodified and 0 is returned.
966 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
967 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
968 is unmodified and 0 is returned.
969 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
970 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
971 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
973 If BufferSize is 0, then no output buffer is produced and 0 is returned.
975 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
977 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
978 @param FormatString A Null-terminated Unicode format string.
979 @param ... Variable argument list whose contents are accessed based on the
980 format string specified by FormatString.
982 @return The number of ASCII characters in the produced output buffer not including the
988 AsciiSPrintUnicodeFormat (
989 OUT CHAR8
*StartOfBuffer
,
991 IN CONST CHAR16
*FormatString
,
996 UINTN NumberOfPrinted
;
998 VA_START (Marker
, FormatString
);
999 NumberOfPrinted
= AsciiVSPrintUnicodeFormat (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
1001 return NumberOfPrinted
;
1005 Converts a decimal value to a Null-terminated Ascii string.
1007 Converts the decimal number specified by Value to a Null-terminated Ascii
1008 string specified by Buffer containing at most Width characters. No padding of
1009 spaces is ever performed. If Width is 0 then a width of
1010 MAXIMUM_VALUE_CHARACTERS is assumed. If the conversion contains more than
1011 Width characters, then only the first Width characters are placed in Buffer.
1012 Additional conversion parameters are specified in Flags.
1014 The Flags bit LEFT_JUSTIFY is always ignored.
1015 All conversions are left justified in Buffer.
1016 If Width is 0, PREFIX_ZERO is ignored in Flags.
1017 If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and
1018 commas are inserted every 3rd digit starting from the right.
1019 If RADIX_HEX is set in Flags, then the output buffer will be formatted in
1021 If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in
1023 If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, then
1024 Buffer is padded with '0' characters so the combination of the optional '-'
1025 sign character, '0' characters, digit characters for Value, and the
1026 Null-terminator add up to Width characters.
1028 If an error would be returned, then the function will ASSERT().
1030 @param Buffer The pointer to the output buffer for the produced
1031 Null-terminated Ascii string.
1032 @param BufferSize The size of Buffer in bytes, including the
1034 @param Flags The bitmask of flags that specify left justification,
1035 zero pad, and commas.
1036 @param Value The 64-bit signed value to convert to a string.
1037 @param Width The maximum number of Ascii characters to place in
1038 Buffer, not including the Null-terminator.
1040 @retval RETURN_SUCCESS The decimal value is converted.
1041 @retval RETURN_BUFFER_TOO_SMALL If BufferSize cannot hold the converted
1043 @retval RETURN_INVALID_PARAMETER If Buffer is NULL.
1044 If PcdMaximumAsciiStringLength is not
1045 zero, and BufferSize is greater than
1046 PcdMaximumAsciiStringLength.
1047 If unsupported bits are set in Flags.
1048 If both COMMA_TYPE and RADIX_HEX are set in
1050 If Width >= MAXIMUM_VALUE_CHARACTERS.
1055 AsciiValueToStringS (
1056 IN OUT CHAR8
*Buffer
,
1057 IN UINTN BufferSize
,
1063 return mPrint2SProtocol
->AsciiValueToStringS (Buffer
, BufferSize
, Flags
, Value
, Width
);
1066 #define PREFIX_SIGN BIT1
1067 #define PREFIX_BLANK BIT2
1068 #define LONG_TYPE BIT4
1069 #define OUTPUT_UNICODE BIT6
1070 #define FORMAT_UNICODE BIT8
1071 #define PAD_TO_WIDTH BIT9
1072 #define ARGUMENT_UNICODE BIT10
1073 #define PRECISION BIT11
1074 #define ARGUMENT_REVERSED BIT12
1075 #define COUNT_ONLY_NO_PRINT BIT13
1076 #define UNSIGNED_TYPE BIT14
1079 // Record date and time information
1095 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mHexStr
[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1098 Internal function that convert a number to a string in Buffer.
1100 Print worker function that converts a decimal or hexadecimal number to an ASCII string in Buffer.
1102 @param Buffer Location to place the ASCII string of Value.
1103 @param Value The value to convert to a Decimal or Hexadecimal string in Buffer.
1104 @param Radix Radix of the value
1106 @return A pointer to the end of buffer filled with ASCII string.
1110 InternalPrintLibValueToString (
1111 IN OUT CHAR8
*Buffer
,
1119 // Loop to convert one digit at a time in reverse order
1123 Value
= (INT64
)DivU64x32Remainder ((UINT64
)Value
, (UINT32
)Radix
, &Remainder
);
1124 *(++Buffer
) = mHexStr
[Remainder
];
1125 } while (Value
!= 0);
1128 // Return pointer of the end of filled buffer.
1134 Worker function that produces a Null-terminated string in an output buffer
1135 based on a Null-terminated format string and a VA_LIST argument list.
1137 VSPrint function to process format and place the results in Buffer. Since a
1138 VA_LIST is used this routine allows the nesting of Vararg routines. Thus
1139 this is the main print working routine.
1141 If COUNT_ONLY_NO_PRINT is set in Flags, Buffer will not be modified at all.
1143 @param[out] Buffer The character buffer to print the results of the
1144 parsing of Format into.
1145 @param[in] BufferSize The maximum number of characters to put into
1147 @param[in] Flags Initial flags value.
1148 Can only have FORMAT_UNICODE, OUTPUT_UNICODE,
1149 and COUNT_ONLY_NO_PRINT set.
1150 @param[in] Format A Null-terminated format string.
1151 @param[in] VaListMarker VA_LIST style variable argument list consumed by
1153 @param[in] BaseListMarker BASE_LIST style variable argument list consumed
1154 by processing Format.
1156 @return The number of characters printed not including the Null-terminator.
1157 If COUNT_ONLY_NO_PRINT was set returns the same, but without any
1158 modification to Buffer.
1162 InternalPrintLibSPrintMarker (
1164 IN UINTN BufferSize
,
1166 IN CONST CHAR8
*Format
,
1167 IN VA_LIST VaListMarker OPTIONAL
,
1168 IN BASE_LIST BaseListMarker OPTIONAL
1172 Worker function that produces a Null-terminated string in an output buffer
1173 based on a Null-terminated format string and variable argument list.
1175 VSPrint function to process format and place the results in Buffer. Since a
1176 VA_LIST is used this routine allows the nesting of Vararg routines. Thus
1177 this is the main print working routine
1179 @param StartOfBuffer The character buffer to print the results of the parsing
1181 @param BufferSize The maximum number of characters to put into buffer.
1182 Zero means no limit.
1183 @param Flags Initial flags value.
1184 Can only have FORMAT_UNICODE and OUTPUT_UNICODE set
1185 @param FormatString A Null-terminated format string.
1186 @param ... The variable argument list.
1188 @return The number of characters printed.
1193 InternalPrintLibSPrint (
1194 OUT CHAR8
*StartOfBuffer
,
1195 IN UINTN BufferSize
,
1197 IN CONST CHAR8
*FormatString
,
1202 UINTN NumberOfPrinted
;
1204 VA_START (Marker
, FormatString
);
1205 NumberOfPrinted
= InternalPrintLibSPrintMarker (StartOfBuffer
, BufferSize
, Flags
, FormatString
, Marker
, NULL
);
1207 return NumberOfPrinted
;
1210 #define WARNING_STATUS_NUMBER 5
1211 #define ERROR_STATUS_NUMBER 33
1213 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8
*CONST mStatusString
[] = {
1214 "Success", // RETURN_SUCCESS = 0
1215 "Warning Unknown Glyph", // RETURN_WARN_UNKNOWN_GLYPH = 1
1216 "Warning Delete Failure", // RETURN_WARN_DELETE_FAILURE = 2
1217 "Warning Write Failure", // RETURN_WARN_WRITE_FAILURE = 3
1218 "Warning Buffer Too Small", // RETURN_WARN_BUFFER_TOO_SMALL = 4
1219 "Warning Stale Data", // RETURN_WARN_STALE_DATA = 5
1220 "Load Error", // RETURN_LOAD_ERROR = 1 | MAX_BIT
1221 "Invalid Parameter", // RETURN_INVALID_PARAMETER = 2 | MAX_BIT
1222 "Unsupported", // RETURN_UNSUPPORTED = 3 | MAX_BIT
1223 "Bad Buffer Size", // RETURN_BAD_BUFFER_SIZE = 4 | MAX_BIT
1224 "Buffer Too Small", // RETURN_BUFFER_TOO_SMALL, = 5 | MAX_BIT
1225 "Not Ready", // RETURN_NOT_READY = 6 | MAX_BIT
1226 "Device Error", // RETURN_DEVICE_ERROR = 7 | MAX_BIT
1227 "Write Protected", // RETURN_WRITE_PROTECTED = 8 | MAX_BIT
1228 "Out of Resources", // RETURN_OUT_OF_RESOURCES = 9 | MAX_BIT
1229 "Volume Corrupt", // RETURN_VOLUME_CORRUPTED = 10 | MAX_BIT
1230 "Volume Full", // RETURN_VOLUME_FULL = 11 | MAX_BIT
1231 "No Media", // RETURN_NO_MEDIA = 12 | MAX_BIT
1232 "Media changed", // RETURN_MEDIA_CHANGED = 13 | MAX_BIT
1233 "Not Found", // RETURN_NOT_FOUND = 14 | MAX_BIT
1234 "Access Denied", // RETURN_ACCESS_DENIED = 15 | MAX_BIT
1235 "No Response", // RETURN_NO_RESPONSE = 16 | MAX_BIT
1236 "No mapping", // RETURN_NO_MAPPING = 17 | MAX_BIT
1237 "Time out", // RETURN_TIMEOUT = 18 | MAX_BIT
1238 "Not started", // RETURN_NOT_STARTED = 19 | MAX_BIT
1239 "Already started", // RETURN_ALREADY_STARTED = 20 | MAX_BIT
1240 "Aborted", // RETURN_ABORTED = 21 | MAX_BIT
1241 "ICMP Error", // RETURN_ICMP_ERROR = 22 | MAX_BIT
1242 "TFTP Error", // RETURN_TFTP_ERROR = 23 | MAX_BIT
1243 "Protocol Error", // RETURN_PROTOCOL_ERROR = 24 | MAX_BIT
1244 "Incompatible Version", // RETURN_INCOMPATIBLE_VERSION = 25 | MAX_BIT
1245 "Security Violation", // RETURN_SECURITY_VIOLATION = 26 | MAX_BIT
1246 "CRC Error", // RETURN_CRC_ERROR = 27 | MAX_BIT
1247 "End of Media", // RETURN_END_OF_MEDIA = 28 | MAX_BIT
1248 "Reserved (29)", // RESERVED = 29 | MAX_BIT
1249 "Reserved (30)", // RESERVED = 30 | MAX_BIT
1250 "End of File", // RETURN_END_OF_FILE = 31 | MAX_BIT
1251 "Invalid Language", // RETURN_INVALID_LANGUAGE = 32 | MAX_BIT
1252 "Compromised Data" // RETURN_COMPROMISED_DATA = 33 | MAX_BIT
1256 Internal function that places the character into the Buffer.
1258 Internal function that places ASCII or Unicode character into the Buffer.
1260 @param Buffer The buffer to place the Unicode or ASCII string.
1261 @param EndBuffer The end of the input Buffer. No characters will be
1263 @param Length The count of character to be placed into Buffer.
1264 (Negative value indicates no buffer fill.)
1265 @param Character The character to be placed into Buffer.
1266 @param Increment The character increment in Buffer.
1272 InternalPrintLibFillBuffer (
1274 IN CHAR8
*EndBuffer
,
1282 for (Index
= 0; Index
< Length
&& Buffer
< EndBuffer
; Index
++) {
1283 *Buffer
= (CHAR8
)Character
;
1284 if (Increment
!= 1) {
1285 *(Buffer
+ 1) = (CHAR8
)(Character
>> 8);
1288 Buffer
+= Increment
;
1295 Worker function that produces a Null-terminated string in an output buffer
1296 based on a Null-terminated format string and a VA_LIST argument list.
1298 VSPrint function to process format and place the results in Buffer. Since a
1299 VA_LIST is used this routine allows the nesting of Vararg routines. Thus
1300 this is the main print working routine.
1302 If COUNT_ONLY_NO_PRINT is set in Flags, Buffer will not be modified at all.
1304 @param[out] Buffer The character buffer to print the results of the
1305 parsing of Format into.
1306 @param[in] BufferSize The maximum number of characters to put into
1308 @param[in] Flags Initial flags value.
1309 Can only have FORMAT_UNICODE, OUTPUT_UNICODE,
1310 and COUNT_ONLY_NO_PRINT set.
1311 @param[in] Format A Null-terminated format string.
1312 @param[in] VaListMarker VA_LIST style variable argument list consumed by
1314 @param[in] BaseListMarker BASE_LIST style variable argument list consumed
1315 by processing Format.
1317 @return The number of characters printed not including the Null-terminator.
1318 If COUNT_ONLY_NO_PRINT was set returns the same, but without any
1319 modification to Buffer.
1323 InternalPrintLibSPrintMarker (
1325 IN UINTN BufferSize
,
1327 IN CONST CHAR8
*Format
,
1328 IN VA_LIST VaListMarker OPTIONAL
,
1329 IN BASE_LIST BaseListMarker OPTIONAL
1332 CHAR8
*OriginalBuffer
;
1334 CHAR8 ValueBuffer
[MAXIMUM_VALUE_CHARACTERS
];
1335 UINT32 BytesPerOutputCharacter
;
1336 UINTN BytesPerFormatCharacter
;
1338 UINTN FormatCharacter
;
1342 CONST CHAR8
*ArgumentString
;
1348 INTN BytesPerArgumentCharacter
;
1349 UINTN ArgumentCharacter
;
1357 RETURN_STATUS Status
;
1361 UINTN LengthToReturn
;
1364 // If you change this code be sure to match the 2 versions of this function.
1365 // Nearly identical logic is found in the BasePrintLib and
1366 // DxePrintLibPrint2Protocol (both PrintLib instances).
1370 // 1. Buffer shall not be a null pointer when both BufferSize > 0 and
1371 // COUNT_ONLY_NO_PRINT is not set in Flags.
1373 if ((BufferSize
> 0) && ((Flags
& COUNT_ONLY_NO_PRINT
) == 0)) {
1374 SAFE_PRINT_CONSTRAINT_CHECK ((Buffer
!= NULL
), 0);
1378 // 2. Format shall not be a null pointer when BufferSize > 0 or when
1379 // COUNT_ONLY_NO_PRINT is set in Flags.
1381 if ((BufferSize
> 0) || ((Flags
& COUNT_ONLY_NO_PRINT
) != 0)) {
1382 SAFE_PRINT_CONSTRAINT_CHECK ((Format
!= NULL
), 0);
1386 // 3. BufferSize shall not be greater than RSIZE_MAX for Unicode output or
1387 // ASCII_RSIZE_MAX for Ascii output.
1389 if ((Flags
& OUTPUT_UNICODE
) != 0) {
1390 if (RSIZE_MAX
!= 0) {
1391 SAFE_PRINT_CONSTRAINT_CHECK ((BufferSize
<= RSIZE_MAX
), 0);
1394 BytesPerOutputCharacter
= 2;
1396 if (ASCII_RSIZE_MAX
!= 0) {
1397 SAFE_PRINT_CONSTRAINT_CHECK ((BufferSize
<= ASCII_RSIZE_MAX
), 0);
1400 BytesPerOutputCharacter
= 1;
1404 // 4. Format shall not contain more than RSIZE_MAX Unicode characters or
1405 // ASCII_RSIZE_MAX Ascii characters.
1407 if ((Flags
& FORMAT_UNICODE
) != 0) {
1408 if (RSIZE_MAX
!= 0) {
1409 SAFE_PRINT_CONSTRAINT_CHECK ((StrnLenS ((CHAR16
*)Format
, RSIZE_MAX
+ 1) <= RSIZE_MAX
), 0);
1412 BytesPerFormatCharacter
= 2;
1413 FormatMask
= 0xffff;
1415 if (ASCII_RSIZE_MAX
!= 0) {
1416 SAFE_PRINT_CONSTRAINT_CHECK ((AsciiStrnLenS (Format
, ASCII_RSIZE_MAX
+ 1) <= ASCII_RSIZE_MAX
), 0);
1419 BytesPerFormatCharacter
= 1;
1423 if ((Flags
& COUNT_ONLY_NO_PRINT
) != 0) {
1424 if (BufferSize
== 0) {
1429 // We can run without a Buffer for counting only.
1431 if (BufferSize
== 0) {
1438 OriginalBuffer
= NULL
;
1441 // Reserve space for the Null terminator.
1443 if (Buffer
!= NULL
) {
1445 OriginalBuffer
= Buffer
;
1448 // Set the tag for the end of the input Buffer.
1450 EndBuffer
= Buffer
+ BufferSize
* BytesPerOutputCharacter
;
1454 // Get the first character from the format string
1456 FormatCharacter
= ((*Format
& 0xff) | ((BytesPerFormatCharacter
== 1) ? 0 : (*(Format
+ 1) << 8))) & FormatMask
;
1459 // Loop until the end of the format string is reached or the output buffer is full
1461 while (FormatCharacter
!= 0) {
1462 if ((Buffer
!= NULL
) && (Buffer
>= EndBuffer
)) {
1467 // Clear all the flag bits except those that may have been passed in
1469 Flags
&= (UINTN
)(OUTPUT_UNICODE
| FORMAT_UNICODE
| COUNT_ONLY_NO_PRINT
);
1472 // Set the default width to zero, and the default precision to 1
1482 switch (FormatCharacter
) {
1485 // Parse Flags and Width
1487 for (Done
= FALSE
; !Done
; ) {
1488 Format
+= BytesPerFormatCharacter
;
1489 FormatCharacter
= ((*Format
& 0xff) | ((BytesPerFormatCharacter
== 1) ? 0 : (*(Format
+ 1) << 8))) & FormatMask
;
1490 switch (FormatCharacter
) {
1495 Flags
|= LEFT_JUSTIFY
;
1498 Flags
|= PREFIX_SIGN
;
1501 Flags
|= PREFIX_BLANK
;
1504 Flags
|= COMMA_TYPE
;
1511 if ((Flags
& PRECISION
) == 0) {
1512 Flags
|= PAD_TO_WIDTH
;
1513 if (BaseListMarker
== NULL
) {
1514 Width
= VA_ARG (VaListMarker
, UINTN
);
1516 Width
= BASE_ARG (BaseListMarker
, UINTN
);
1519 if (BaseListMarker
== NULL
) {
1520 Precision
= VA_ARG (VaListMarker
, UINTN
);
1522 Precision
= BASE_ARG (BaseListMarker
, UINTN
);
1528 if ((Flags
& PRECISION
) == 0) {
1529 Flags
|= PREFIX_ZERO
;
1541 for (Count
= 0; ((FormatCharacter
>= '0') && (FormatCharacter
<= '9')); ) {
1542 Count
= (Count
* 10) + FormatCharacter
- '0';
1543 Format
+= BytesPerFormatCharacter
;
1544 FormatCharacter
= ((*Format
& 0xff) | ((BytesPerFormatCharacter
== 1) ? 0 : (*(Format
+ 1) << 8))) & FormatMask
;
1547 Format
-= BytesPerFormatCharacter
;
1548 if ((Flags
& PRECISION
) == 0) {
1549 Flags
|= PAD_TO_WIDTH
;
1559 // Make no output if Format string terminates unexpectedly when
1560 // looking up for flag, width, precision and type.
1562 Format
-= BytesPerFormatCharacter
;
1565 // break skipped on purpose.
1574 // Handle each argument type
1576 switch (FormatCharacter
) {
1579 // Flag space, +, 0, L & l are invalid for type p.
1581 Flags
&= ~((UINTN
)(PREFIX_BLANK
| PREFIX_SIGN
| PREFIX_ZERO
| LONG_TYPE
));
1582 if (sizeof (VOID
*) > 4) {
1587 // break skipped on purpose
1590 Flags
|= PREFIX_ZERO
;
1592 // break skipped on purpose
1597 // break skipped on purpose
1600 if ((Flags
& RADIX_HEX
) == 0) {
1601 Flags
&= ~((UINTN
)(PREFIX_SIGN
));
1602 Flags
|= UNSIGNED_TYPE
;
1606 // break skipped on purpose
1609 if ((Flags
& LONG_TYPE
) == 0) {
1611 // 'd', 'u', 'x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".
1612 // This assumption is made so the format string definition is compatible with the ANSI C
1613 // Specification for formatted strings. It is recommended that the Base Types be used
1614 // everywhere, but in this one case, compliance with ANSI C is more important, and
1615 // provides an implementation that is compatible with that largest possible set of CPU
1616 // architectures. This is why the type "int" is used in this one case.
1618 if (BaseListMarker
== NULL
) {
1619 Value
= VA_ARG (VaListMarker
, int);
1621 Value
= BASE_ARG (BaseListMarker
, int);
1624 if (BaseListMarker
== NULL
) {
1625 Value
= VA_ARG (VaListMarker
, INT64
);
1627 Value
= BASE_ARG (BaseListMarker
, INT64
);
1631 if ((Flags
& PREFIX_BLANK
) != 0) {
1635 if ((Flags
& PREFIX_SIGN
) != 0) {
1639 if ((Flags
& COMMA_TYPE
) != 0) {
1643 if ((Flags
& RADIX_HEX
) == 0) {
1646 Flags
&= ~((UINTN
)PREFIX_ZERO
);
1650 if ((Value
< 0) && ((Flags
& UNSIGNED_TYPE
) == 0)) {
1651 Flags
|= PREFIX_SIGN
;
1654 } else if (((Flags
& UNSIGNED_TYPE
) != 0) && ((Flags
& LONG_TYPE
) == 0)) {
1656 // 'd', 'u', 'x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".
1657 // This assumption is made so the format string definition is compatible with the ANSI C
1658 // Specification for formatted strings. It is recommended that the Base Types be used
1659 // everywhere, but in this one case, compliance with ANSI C is more important, and
1660 // provides an implementation that is compatible with that largest possible set of CPU
1661 // architectures. This is why the type "unsigned int" is used in this one case.
1663 Value
= (unsigned int)Value
;
1668 if (((Flags
& LONG_TYPE
) == 0) && (Value
< 0)) {
1670 // 'd', 'u', 'x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".
1671 // This assumption is made so the format string definition is compatible with the ANSI C
1672 // Specification for formatted strings. It is recommended that the Base Types be used
1673 // everywhere, but in this one case, compliance with ANSI C is more important, and
1674 // provides an implementation that is compatible with that largest possible set of CPU
1675 // architectures. This is why the type "unsigned int" is used in this one case.
1677 Value
= (unsigned int)Value
;
1682 // Convert Value to a reversed string
1684 Count
= InternalPrintLibValueToString (ValueBuffer
, Value
, Radix
) - ValueBuffer
;
1685 if ((Value
== 0) && (Precision
== 0)) {
1689 ArgumentString
= (CHAR8
*)ValueBuffer
+ Count
;
1693 Digits
= 3 - Digits
;
1696 if (Comma
&& (Count
!= 0)) {
1697 Count
+= ((Count
- 1) / 3);
1705 Flags
|= ARGUMENT_REVERSED
;
1707 if ((Flags
& PREFIX_ZERO
) != 0) {
1708 if ((Flags
& LEFT_JUSTIFY
) == 0) {
1709 if ((Flags
& PAD_TO_WIDTH
) != 0) {
1710 if ((Flags
& PRECISION
) == 0) {
1721 Flags
|= ARGUMENT_UNICODE
;
1723 // break skipped on purpose
1726 if (BaseListMarker
== NULL
) {
1727 ArgumentString
= VA_ARG (VaListMarker
, CHAR8
*);
1729 ArgumentString
= BASE_ARG (BaseListMarker
, CHAR8
*);
1732 if (ArgumentString
== NULL
) {
1733 Flags
&= (~(UINTN
)ARGUMENT_UNICODE
);
1734 ArgumentString
= "<null string>";
1738 // Set the default precision for string to be zero if not specified.
1740 if ((Flags
& PRECISION
) == 0) {
1747 if (BaseListMarker
== NULL
) {
1748 Character
= VA_ARG (VaListMarker
, UINTN
) & 0xffff;
1750 Character
= BASE_ARG (BaseListMarker
, UINTN
) & 0xffff;
1753 ArgumentString
= (CHAR8
*)&Character
;
1754 Flags
|= ARGUMENT_UNICODE
;
1758 if (BaseListMarker
== NULL
) {
1759 TmpGuid
= VA_ARG (VaListMarker
, GUID
*);
1761 TmpGuid
= BASE_ARG (BaseListMarker
, GUID
*);
1764 if (TmpGuid
== NULL
) {
1765 ArgumentString
= "<null guid>";
1767 GuidData1
= ReadUnaligned32 (&(TmpGuid
->Data1
));
1768 GuidData2
= ReadUnaligned16 (&(TmpGuid
->Data2
));
1769 GuidData3
= ReadUnaligned16 (&(TmpGuid
->Data3
));
1770 InternalPrintLibSPrint (
1772 MAXIMUM_VALUE_CHARACTERS
,
1774 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1787 ArgumentString
= ValueBuffer
;
1793 if (BaseListMarker
== NULL
) {
1794 TmpTime
= VA_ARG (VaListMarker
, TIME
*);
1796 TmpTime
= BASE_ARG (BaseListMarker
, TIME
*);
1799 if (TmpTime
== NULL
) {
1800 ArgumentString
= "<null time>";
1802 InternalPrintLibSPrint (
1804 MAXIMUM_VALUE_CHARACTERS
,
1806 "%02d/%02d/%04d %02d:%02d",
1813 ArgumentString
= ValueBuffer
;
1819 if (BaseListMarker
== NULL
) {
1820 Status
= VA_ARG (VaListMarker
, RETURN_STATUS
);
1822 Status
= BASE_ARG (BaseListMarker
, RETURN_STATUS
);
1825 ArgumentString
= ValueBuffer
;
1826 if (RETURN_ERROR (Status
)) {
1830 Index
= Status
& ~MAX_BIT
;
1831 if ((Index
> 0) && (Index
<= ERROR_STATUS_NUMBER
)) {
1832 ArgumentString
= mStatusString
[Index
+ WARNING_STATUS_NUMBER
];
1836 if (Index
<= WARNING_STATUS_NUMBER
) {
1837 ArgumentString
= mStatusString
[Index
];
1841 if (ArgumentString
== ValueBuffer
) {
1842 InternalPrintLibSPrint ((CHAR8
*)ValueBuffer
, MAXIMUM_VALUE_CHARACTERS
, 0, "%08X", Status
);
1848 Format
+= BytesPerFormatCharacter
;
1849 FormatCharacter
= ((*Format
& 0xff) | ((BytesPerFormatCharacter
== 1) ? 0 : (*(Format
+ 1) << 8))) & FormatMask
;
1850 if (FormatCharacter
== '\n') {
1852 // Translate '\r\n' to '\r\n'
1854 ArgumentString
= "\r\n";
1857 // Translate '\r' to '\r'
1859 ArgumentString
= "\r";
1860 Format
-= BytesPerFormatCharacter
;
1867 // Translate '\n' to '\r\n' and '\n\r' to '\r\n'
1869 ArgumentString
= "\r\n";
1870 Format
+= BytesPerFormatCharacter
;
1871 FormatCharacter
= ((*Format
& 0xff) | ((BytesPerFormatCharacter
== 1) ? 0 : (*(Format
+ 1) << 8))) & FormatMask
;
1872 if (FormatCharacter
!= '\r') {
1873 Format
-= BytesPerFormatCharacter
;
1881 // if the type is '%' or unknown, then print it to the screen
1883 ArgumentString
= (CHAR8
*)&FormatCharacter
;
1884 Flags
|= ARGUMENT_UNICODE
;
1891 Format
+= BytesPerFormatCharacter
;
1892 FormatCharacter
= ((*Format
& 0xff) | ((BytesPerFormatCharacter
== 1) ? 0 : (*(Format
+ 1) << 8))) & FormatMask
;
1893 if (FormatCharacter
== '\n') {
1895 // Translate '\r\n' to '\r\n'
1897 ArgumentString
= "\r\n";
1900 // Translate '\r' to '\r'
1902 ArgumentString
= "\r";
1903 Format
-= BytesPerFormatCharacter
;
1910 // Translate '\n' to '\r\n' and '\n\r' to '\r\n'
1912 ArgumentString
= "\r\n";
1913 Format
+= BytesPerFormatCharacter
;
1914 FormatCharacter
= ((*Format
& 0xff) | ((BytesPerFormatCharacter
== 1) ? 0 : (*(Format
+ 1) << 8))) & FormatMask
;
1915 if (FormatCharacter
!= '\r') {
1916 Format
-= BytesPerFormatCharacter
;
1922 ArgumentString
= (CHAR8
*)&FormatCharacter
;
1923 Flags
|= ARGUMENT_UNICODE
;
1928 // Retrieve the ArgumentString attriubutes
1930 if ((Flags
& ARGUMENT_UNICODE
) != 0) {
1931 ArgumentMask
= 0xffff;
1932 BytesPerArgumentCharacter
= 2;
1934 ArgumentMask
= 0xff;
1935 BytesPerArgumentCharacter
= 1;
1938 if ((Flags
& ARGUMENT_REVERSED
) != 0) {
1939 BytesPerArgumentCharacter
= -BytesPerArgumentCharacter
;
1942 // Compute the number of characters in ArgumentString and store it in Count
1943 // ArgumentString is either null-terminated, or it contains Precision characters
1946 (ArgumentString
[Count
* BytesPerArgumentCharacter
] != '\0' ||
1947 (BytesPerArgumentCharacter
> 1 &&
1948 ArgumentString
[Count
* BytesPerArgumentCharacter
+ 1] != '\0')) &&
1949 (Count
< Precision
|| ((Flags
& PRECISION
) == 0));
1952 ArgumentCharacter
= ((ArgumentString
[Count
* BytesPerArgumentCharacter
] & 0xff) | ((ArgumentString
[Count
* BytesPerArgumentCharacter
+ 1]) << 8)) & ArgumentMask
;
1953 if (ArgumentCharacter
== 0) {
1959 if (Precision
< Count
) {
1964 // Pad before the string
1966 if ((Flags
& (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) == (PAD_TO_WIDTH
)) {
1967 LengthToReturn
+= ((Width
- Precision
) * BytesPerOutputCharacter
);
1968 if (((Flags
& COUNT_ONLY_NO_PRINT
) == 0) && (Buffer
!= NULL
)) {
1969 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, Width
- Precision
, ' ', BytesPerOutputCharacter
);
1975 LengthToReturn
+= (1 * BytesPerOutputCharacter
);
1976 if (((Flags
& COUNT_ONLY_NO_PRINT
) == 0) && (Buffer
!= NULL
)) {
1977 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, 1, Prefix
, BytesPerOutputCharacter
);
1981 LengthToReturn
+= ((Precision
- Count
) * BytesPerOutputCharacter
);
1982 if (((Flags
& COUNT_ONLY_NO_PRINT
) == 0) && (Buffer
!= NULL
)) {
1983 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, Precision
- Count
, '0', BytesPerOutputCharacter
);
1986 LengthToReturn
+= ((Precision
- Count
) * BytesPerOutputCharacter
);
1987 if (((Flags
& COUNT_ONLY_NO_PRINT
) == 0) && (Buffer
!= NULL
)) {
1988 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, Precision
- Count
, ' ', BytesPerOutputCharacter
);
1992 LengthToReturn
+= (1 * BytesPerOutputCharacter
);
1993 if (((Flags
& COUNT_ONLY_NO_PRINT
) == 0) && (Buffer
!= NULL
)) {
1994 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, 1, Prefix
, BytesPerOutputCharacter
);
2000 // Output the Prefix character if it is present
2008 // Copy the string into the output buffer performing the required type conversions
2010 while (Index
< Count
&&
2011 (ArgumentString
[0] != '\0' ||
2012 (BytesPerArgumentCharacter
> 1 && ArgumentString
[1] != '\0')))
2014 ArgumentCharacter
= ((*ArgumentString
& 0xff) | (((UINT8
)*(ArgumentString
+ 1)) << 8)) & ArgumentMask
;
2016 LengthToReturn
+= (1 * BytesPerOutputCharacter
);
2017 if (((Flags
& COUNT_ONLY_NO_PRINT
) == 0) && (Buffer
!= NULL
)) {
2018 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, 1, ArgumentCharacter
, BytesPerOutputCharacter
);
2021 ArgumentString
+= BytesPerArgumentCharacter
;
2028 if (Index
< Count
) {
2029 LengthToReturn
+= (1 * BytesPerOutputCharacter
);
2030 if (((Flags
& COUNT_ONLY_NO_PRINT
) == 0) && (Buffer
!= NULL
)) {
2031 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, 1, ',', BytesPerOutputCharacter
);
2039 // Pad after the string
2041 if ((Flags
& (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) == (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) {
2042 LengthToReturn
+= ((Width
- Precision
) * BytesPerOutputCharacter
);
2043 if (((Flags
& COUNT_ONLY_NO_PRINT
) == 0) && (Buffer
!= NULL
)) {
2044 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, Width
- Precision
, ' ', BytesPerOutputCharacter
);
2049 // Get the next character from the format string
2051 Format
+= BytesPerFormatCharacter
;
2054 // Get the next character from the format string
2056 FormatCharacter
= ((*Format
& 0xff) | ((BytesPerFormatCharacter
== 1) ? 0 : (*(Format
+ 1) << 8))) & FormatMask
;
2059 if ((Flags
& COUNT_ONLY_NO_PRINT
) != 0) {
2060 return (LengthToReturn
/ BytesPerOutputCharacter
);
2063 ASSERT (Buffer
!= NULL
);
2065 // Null terminate the Unicode or ASCII string
2067 InternalPrintLibFillBuffer (Buffer
, EndBuffer
+ BytesPerOutputCharacter
, 1, 0, BytesPerOutputCharacter
);
2069 return ((Buffer
- OriginalBuffer
) / BytesPerOutputCharacter
);
2073 Returns the number of characters that would be produced by if the formatted
2074 output were produced not including the Null-terminator.
2076 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
2078 If FormatString is NULL, then ASSERT() and 0 is returned.
2079 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more
2080 than PcdMaximumUnicodeStringLength Unicode characters not including the
2081 Null-terminator, then ASSERT() and 0 is returned.
2083 @param[in] FormatString A Null-terminated Unicode format string.
2084 @param[in] Marker VA_LIST marker for the variable argument list.
2086 @return The number of characters that would be produced, not including the
2092 IN CONST CHAR16
*FormatString
,
2096 ASSERT_UNICODE_BUFFER (FormatString
);
2097 return InternalPrintLibSPrintMarker (NULL
, 0, FORMAT_UNICODE
| OUTPUT_UNICODE
| COUNT_ONLY_NO_PRINT
, (CHAR8
*)FormatString
, Marker
, NULL
);
2101 Returns the number of characters that would be produced by if the formatted
2102 output were produced not including the Null-terminator.
2104 If FormatString is NULL, then ASSERT() and 0 is returned.
2105 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more
2106 than PcdMaximumAsciiStringLength Ascii characters not including the
2107 Null-terminator, then ASSERT() and 0 is returned.
2109 @param[in] FormatString A Null-terminated ASCII format string.
2110 @param[in] Marker VA_LIST marker for the variable argument list.
2112 @return The number of characters that would be produced, not including the
2117 SPrintLengthAsciiFormat (
2118 IN CONST CHAR8
*FormatString
,
2122 return InternalPrintLibSPrintMarker (NULL
, 0, OUTPUT_UNICODE
| COUNT_ONLY_NO_PRINT
, (CHAR8
*)FormatString
, Marker
, NULL
);