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
);
76 Worker function that converts a VA_LIST to a BASE_LIST based on a Null-terminated
79 @param AsciiFormat TRUE if Format is an ASCII string. FALSE if Format is a Unicode string.
80 @param Format Null-terminated format string.
81 @param VaListMarker VA_LIST style variable argument list consumed by processing Format.
82 @param BaseListMarker BASE_LIST style variable argument list consumed by processing Format.
83 @param Size The size, in bytes, of the BaseListMarker buffer.
85 @return TRUE The VA_LIST has been converted to BASE_LIST.
86 @return FALSE The VA_LIST has not been converted to BASE_LIST.
90 DxePrintLibPrint2ProtocolVaListToBaseList (
91 IN BOOLEAN AsciiFormat
,
92 IN CONST CHAR8
*Format
,
93 IN VA_LIST VaListMarker
,
94 OUT BASE_LIST BaseListMarker
,
98 BASE_LIST BaseListStart
;
99 UINTN BytesPerFormatCharacter
;
101 UINTN FormatCharacter
;
105 ASSERT (BaseListMarker
!= NULL
);
106 SAFE_PRINT_CONSTRAINT_CHECK ((Format
!= NULL
), FALSE
);
108 BaseListStart
= BaseListMarker
;
111 if (ASCII_RSIZE_MAX
!= 0) {
112 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
);
120 BytesPerFormatCharacter
= 2;
125 // Get the first character from the format string
127 FormatCharacter
= ((*Format
& 0xff) | ((BytesPerFormatCharacter
== 1) ? 0 : (*(Format
+ 1) << 8))) & FormatMask
;
129 while (FormatCharacter
!= 0) {
130 if (FormatCharacter
== '%') {
134 // Parse Flags and Width
136 for (Done
= FALSE
; !Done
; ) {
138 // Get the next character from the format string
140 Format
+= BytesPerFormatCharacter
;
143 // Get the next character from the format string
145 FormatCharacter
= ((*Format
& 0xff) | ((BytesPerFormatCharacter
== 1) ? 0 : (*(Format
+ 1) << 8))) & FormatMask
;
147 switch (FormatCharacter
) {
169 BASE_ARG (BaseListMarker
, UINTN
) = VA_ARG (VaListMarker
, UINTN
);
173 // Make no output if Format string terminates unexpectedly when
174 // looking up for flag, width, precision and type.
176 Format
-= BytesPerFormatCharacter
;
178 // break skipped on purpose.
187 // Handle each argument type
189 switch (FormatCharacter
) {
191 if (sizeof (VOID
*) > 4) {
199 BASE_ARG (BaseListMarker
, INT64
) = VA_ARG (VaListMarker
, INT64
);
201 BASE_ARG (BaseListMarker
, int) = VA_ARG (VaListMarker
, int);
209 BASE_ARG (BaseListMarker
, VOID
*) = VA_ARG (VaListMarker
, VOID
*);
212 BASE_ARG (BaseListMarker
, UINTN
) = VA_ARG (VaListMarker
, UINTN
);
215 BASE_ARG (BaseListMarker
, RETURN_STATUS
) = VA_ARG (VaListMarker
, RETURN_STATUS
);
221 // If BASE_LIST is larger than Size, then return FALSE
223 if (((UINTN
)BaseListMarker
- (UINTN
)BaseListStart
) > Size
) {
224 DEBUG ((DEBUG_ERROR
, "The input variable argument list is too long. Please consider breaking into multiple print calls.\n"));
229 // Get the next character from the format string
231 Format
+= BytesPerFormatCharacter
;
234 // Get the next character from the format string
236 FormatCharacter
= ((*Format
& 0xff) | ((BytesPerFormatCharacter
== 1) ? 0 : (*(Format
+ 1) << 8))) & FormatMask
;
242 Produces a Null-terminated Unicode string in an output buffer based on
243 a Null-terminated Unicode format string and a VA_LIST argument list.
245 This function is similar as vsnprintf_s defined in C11.
247 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
249 The Unicode string is produced by parsing the format string specified by FormatString.
250 Arguments are pulled from the variable argument list specified by Marker based on the
251 contents of the format string.
252 The number of Unicode characters in the produced output buffer is returned not including
255 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
256 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
258 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
259 unmodified and 0 is returned.
260 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
261 unmodified and 0 is returned.
262 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
263 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
264 buffer is unmodified and 0 is returned.
265 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
266 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
267 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
269 If BufferSize is 0 or 1, then the output buffer is unmodified and 0 is returned.
271 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
273 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
274 @param FormatString A Null-terminated Unicode format string.
275 @param Marker VA_LIST marker for the variable argument list.
277 @return The number of Unicode characters in the produced output buffer not including the
284 OUT CHAR16
*StartOfBuffer
,
286 IN CONST CHAR16
*FormatString
,
290 UINT64 BaseListMarker
[256 / sizeof (UINT64
)];
293 ASSERT_UNICODE_BUFFER (StartOfBuffer
);
294 ASSERT_UNICODE_BUFFER (FormatString
);
296 Converted
= DxePrintLibPrint2ProtocolVaListToBaseList (
298 (CHAR8
*)FormatString
,
300 (BASE_LIST
)BaseListMarker
,
301 sizeof (BaseListMarker
) - 8
307 return UnicodeBSPrint (StartOfBuffer
, BufferSize
, FormatString
, (BASE_LIST
)BaseListMarker
);
311 Produces a Null-terminated Unicode string in an output buffer based on
312 a Null-terminated Unicode format string and a BASE_LIST argument list.
314 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
316 The Unicode string is produced by parsing the format string specified by FormatString.
317 Arguments are pulled from the variable argument list specified by Marker based on the
318 contents of the format string.
319 The number of Unicode characters in the produced output buffer is returned not including
322 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
323 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
325 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
326 unmodified and 0 is returned.
327 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
328 unmodified and 0 is returned.
329 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
330 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
331 buffer is unmodified and 0 is returned.
332 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
333 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
334 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
336 If BufferSize is 0 or 1, then the output buffer is unmodified and 0 is returned.
338 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
340 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
341 @param FormatString A Null-terminated Unicode format string.
342 @param Marker BASE_LIST marker for the variable argument list.
344 @return The number of Unicode characters in the produced output buffer not including the
351 OUT CHAR16
*StartOfBuffer
,
353 IN CONST CHAR16
*FormatString
,
357 ASSERT_UNICODE_BUFFER (StartOfBuffer
);
358 ASSERT_UNICODE_BUFFER (FormatString
);
359 return mPrint2SProtocol
->UnicodeBSPrint (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
363 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
364 Unicode format string and variable argument list.
366 This function is similar as snprintf_s defined in C11.
368 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
370 The Unicode string is produced by parsing the format string specified by FormatString.
371 Arguments are pulled from the variable argument list based on the contents of the format string.
372 The number of Unicode characters in the produced output buffer is returned not including
375 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
376 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
378 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
379 unmodified and 0 is returned.
380 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
381 unmodified and 0 is returned.
382 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
383 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
384 buffer is unmodified and 0 is returned.
385 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
386 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
387 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
389 If BufferSize is 0 or 1, then the output buffer is unmodified and 0 is returned.
391 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
393 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
394 @param FormatString A Null-terminated Unicode format string.
395 @param ... Variable argument list whose contents are accessed based on the
396 format string specified by FormatString.
398 @return The number of Unicode characters in the produced output buffer not including the
405 OUT CHAR16
*StartOfBuffer
,
407 IN CONST CHAR16
*FormatString
,
412 UINTN NumberOfPrinted
;
414 VA_START (Marker
, FormatString
);
415 NumberOfPrinted
= UnicodeVSPrint (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
417 return NumberOfPrinted
;
421 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
422 ASCII format string and a VA_LIST argument list.
424 This function is similar as vsnprintf_s defined in C11.
426 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
428 The Unicode string is produced by parsing the format string specified by FormatString.
429 Arguments are pulled from the variable argument list specified by Marker based on the
430 contents of the format string.
431 The number of Unicode characters in the produced output buffer is returned not including
434 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
436 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
437 unmodified and 0 is returned.
438 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
439 unmodified and 0 is returned.
440 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
441 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
442 buffer is unmodified and 0 is returned.
443 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
444 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
445 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
447 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.
449 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
451 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
452 @param FormatString A Null-terminated ASCII format string.
453 @param Marker VA_LIST marker for the variable argument list.
455 @return The number of Unicode characters in the produced output buffer not including the
461 UnicodeVSPrintAsciiFormat (
462 OUT CHAR16
*StartOfBuffer
,
464 IN CONST CHAR8
*FormatString
,
468 UINT64 BaseListMarker
[256 / sizeof (UINT64
)];
471 ASSERT_UNICODE_BUFFER (StartOfBuffer
);
473 Converted
= DxePrintLibPrint2ProtocolVaListToBaseList (
477 (BASE_LIST
)BaseListMarker
,
478 sizeof (BaseListMarker
) - 8
484 return UnicodeBSPrintAsciiFormat (StartOfBuffer
, BufferSize
, FormatString
, (BASE_LIST
)BaseListMarker
);
488 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
489 ASCII format string and a BASE_LIST argument list.
491 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
493 The Unicode string is produced by parsing the format string specified by FormatString.
494 Arguments are pulled from the variable argument list specified by Marker based on the
495 contents of the format string.
496 The number of Unicode characters in the produced output buffer is returned not including
499 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
501 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
502 unmodified and 0 is returned.
503 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
504 unmodified and 0 is returned.
505 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
506 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
507 buffer is unmodified and 0 is returned.
508 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
509 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
510 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
512 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.
514 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
516 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
517 @param FormatString A Null-terminated ASCII format string.
518 @param Marker BASE_LIST marker for the variable argument list.
520 @return The number of Unicode characters in the produced output buffer not including the
526 UnicodeBSPrintAsciiFormat (
527 OUT CHAR16
*StartOfBuffer
,
529 IN CONST CHAR8
*FormatString
,
533 ASSERT_UNICODE_BUFFER (StartOfBuffer
);
534 return mPrint2SProtocol
->UnicodeBSPrintAsciiFormat (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
538 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
539 ASCII format string and variable argument list.
541 This function is similar as snprintf_s defined in C11.
543 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
545 The Unicode string is produced by parsing the format string specified by FormatString.
546 Arguments are pulled from the variable argument list based on the contents of the
548 The number of Unicode characters in the produced output buffer is returned not including
551 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
553 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
554 unmodified and 0 is returned.
555 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
556 unmodified and 0 is returned.
557 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
558 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
559 buffer is unmodified and 0 is returned.
560 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
561 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
562 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
564 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.
566 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
568 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
569 @param FormatString A Null-terminated ASCII format string.
570 @param ... Variable argument list whose contents are accessed based on the
571 format string specified by FormatString.
573 @return The number of Unicode characters in the produced output buffer not including the
579 UnicodeSPrintAsciiFormat (
580 OUT CHAR16
*StartOfBuffer
,
582 IN CONST CHAR8
*FormatString
,
587 UINTN NumberOfPrinted
;
589 VA_START (Marker
, FormatString
);
590 NumberOfPrinted
= UnicodeVSPrintAsciiFormat (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
592 return NumberOfPrinted
;
596 Converts a decimal value to a Null-terminated Unicode string.
598 Converts the decimal number specified by Value to a Null-terminated Unicode
599 string specified by Buffer containing at most Width characters. No padding of
600 spaces is ever performed. If Width is 0 then a width of
601 MAXIMUM_VALUE_CHARACTERS is assumed. If the conversion contains more than
602 Width characters, then only the first Width characters are placed in Buffer.
603 Additional conversion parameters are specified in Flags.
605 The Flags bit LEFT_JUSTIFY is always ignored.
606 All conversions are left justified in Buffer.
607 If Width is 0, PREFIX_ZERO is ignored in Flags.
608 If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and
609 commas are inserted every 3rd digit starting from the right.
610 If RADIX_HEX is set in Flags, then the output buffer will be formatted in
612 If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in
614 If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, then
615 Buffer is padded with '0' characters so the combination of the optional '-'
616 sign character, '0' characters, digit characters for Value, and the
617 Null-terminator add up to Width characters.
619 If Buffer is not aligned on a 16-bit boundary, then ASSERT().
620 If an error would be returned, then the function will also ASSERT().
622 @param Buffer The pointer to the output buffer for the produced
623 Null-terminated Unicode string.
624 @param BufferSize The size of Buffer in bytes, including the
626 @param Flags The bitmask of flags that specify left justification,
627 zero pad, and commas.
628 @param Value The 64-bit signed value to convert to a string.
629 @param Width The maximum number of Unicode characters to place in
630 Buffer, not including the Null-terminator.
632 @retval RETURN_SUCCESS The decimal value is converted.
633 @retval RETURN_BUFFER_TOO_SMALL If BufferSize cannot hold the converted
635 @retval RETURN_INVALID_PARAMETER If Buffer is NULL.
636 If PcdMaximumUnicodeStringLength is not
637 zero, and BufferSize is greater than
638 (PcdMaximumUnicodeStringLength *
639 sizeof (CHAR16) + 1).
640 If unsupported bits are set in Flags.
641 If both COMMA_TYPE and RADIX_HEX are set in
643 If Width >= MAXIMUM_VALUE_CHARACTERS.
648 UnicodeValueToStringS (
649 IN OUT CHAR16
*Buffer
,
656 return mPrint2SProtocol
->UnicodeValueToStringS (Buffer
, BufferSize
, Flags
, Value
, Width
);
660 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
661 ASCII format string and a VA_LIST argument list.
663 This function is similar as vsnprintf_s defined in C11.
665 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
667 The ASCII string is produced by parsing the format string specified by FormatString.
668 Arguments are pulled from the variable argument list specified by Marker based on
669 the contents of the format string.
670 The number of ASCII characters in the produced output buffer is returned not including
673 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
674 unmodified and 0 is returned.
675 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
676 unmodified and 0 is returned.
677 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
678 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
679 is unmodified and 0 is returned.
680 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
681 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
682 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
684 If BufferSize is 0, then no output buffer is produced and 0 is returned.
686 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
688 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
689 @param FormatString A Null-terminated ASCII format string.
690 @param Marker VA_LIST marker for the variable argument list.
692 @return The number of ASCII characters in the produced output buffer not including the
699 OUT CHAR8
*StartOfBuffer
,
701 IN CONST CHAR8
*FormatString
,
705 UINT64 BaseListMarker
[256 / sizeof (UINT64
)];
708 Converted
= DxePrintLibPrint2ProtocolVaListToBaseList (
712 (BASE_LIST
)BaseListMarker
,
713 sizeof (BaseListMarker
) - 8
719 return AsciiBSPrint (StartOfBuffer
, BufferSize
, FormatString
, (BASE_LIST
)BaseListMarker
);
723 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
724 ASCII format string and a BASE_LIST argument list.
726 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
728 The ASCII string is produced by parsing the format string specified by FormatString.
729 Arguments are pulled from the variable argument list specified by Marker based on
730 the contents of the format string.
731 The number of ASCII characters in the produced output buffer is returned not including
734 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
735 unmodified and 0 is returned.
736 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
737 unmodified and 0 is returned.
738 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
739 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
740 is unmodified and 0 is returned.
741 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
742 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
743 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
745 If BufferSize is 0, then no output buffer is produced and 0 is returned.
747 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
749 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
750 @param FormatString A Null-terminated ASCII format string.
751 @param Marker BASE_LIST marker for the variable argument list.
753 @return The number of ASCII characters in the produced output buffer not including the
760 OUT CHAR8
*StartOfBuffer
,
762 IN CONST CHAR8
*FormatString
,
766 return mPrint2SProtocol
->AsciiBSPrint (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
770 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
771 ASCII format string and variable argument list.
773 This function is similar as snprintf_s defined in C11.
775 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
777 The ASCII string is produced by parsing the format string specified by FormatString.
778 Arguments are pulled from the variable argument list based on the contents of the
780 The number of ASCII characters in the produced output buffer is returned not including
783 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
784 unmodified and 0 is returned.
785 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
786 unmodified and 0 is returned.
787 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
788 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
789 is unmodified and 0 is returned.
790 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
791 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
792 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
794 If BufferSize is 0, then no output buffer is produced and 0 is returned.
796 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
798 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
799 @param FormatString A Null-terminated ASCII format string.
800 @param ... Variable argument list whose contents are accessed based on the
801 format string specified by FormatString.
803 @return The number of ASCII characters in the produced output buffer not including the
810 OUT CHAR8
*StartOfBuffer
,
812 IN CONST CHAR8
*FormatString
,
817 UINTN NumberOfPrinted
;
819 VA_START (Marker
, FormatString
);
820 NumberOfPrinted
= AsciiVSPrint (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
822 return NumberOfPrinted
;
826 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
827 Unicode format string and a VA_LIST argument list.
829 This function is similar as vsnprintf_s defined in C11.
831 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
833 The ASCII string is produced by parsing the format string specified by FormatString.
834 Arguments are pulled from the variable argument list specified by Marker based on
835 the contents of the format string.
836 The number of ASCII characters in the produced output buffer is returned not including
839 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
841 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
842 unmodified and 0 is returned.
843 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
844 unmodified and 0 is returned.
845 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
846 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
847 is unmodified and 0 is returned.
848 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
849 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
850 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
852 If BufferSize is 0, then no output buffer is produced and 0 is returned.
854 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
856 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
857 @param FormatString A Null-terminated Unicode format string.
858 @param Marker VA_LIST marker for the variable argument list.
860 @return The number of ASCII characters in the produced output buffer not including the
866 AsciiVSPrintUnicodeFormat (
867 OUT CHAR8
*StartOfBuffer
,
869 IN CONST CHAR16
*FormatString
,
873 UINT64 BaseListMarker
[256 / sizeof (UINT64
)];
876 ASSERT_UNICODE_BUFFER (FormatString
);
878 Converted
= DxePrintLibPrint2ProtocolVaListToBaseList (
880 (CHAR8
*)FormatString
,
882 (BASE_LIST
)BaseListMarker
,
883 sizeof (BaseListMarker
) - 8
889 return AsciiBSPrintUnicodeFormat (StartOfBuffer
, BufferSize
, FormatString
, (BASE_LIST
)BaseListMarker
);
893 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
894 Unicode format string and a BASE_LIST argument list.
896 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
898 The ASCII string is produced by parsing the format string specified by FormatString.
899 Arguments are pulled from the variable argument list specified by Marker based on
900 the contents of the format string.
901 The number of ASCII characters in the produced output buffer is returned not including
904 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
906 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
907 unmodified and 0 is returned.
908 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
909 unmodified and 0 is returned.
910 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
911 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
912 is unmodified and 0 is returned.
913 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
914 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
915 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
917 If BufferSize is 0, then no output buffer is produced and 0 is returned.
919 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
921 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
922 @param FormatString A Null-terminated Unicode format string.
923 @param Marker BASE_LIST marker for the variable argument list.
925 @return The number of ASCII characters in the produced output buffer not including the
931 AsciiBSPrintUnicodeFormat (
932 OUT CHAR8
*StartOfBuffer
,
934 IN CONST CHAR16
*FormatString
,
938 ASSERT_UNICODE_BUFFER (FormatString
);
939 return mPrint2SProtocol
->AsciiBSPrintUnicodeFormat (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
943 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
944 Unicode format string and variable argument list.
946 This function is similar as snprintf_s defined in C11.
948 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
950 The ASCII string is produced by parsing the format string specified by FormatString.
951 Arguments are pulled from the variable argument list based on the contents of the
953 The number of ASCII characters in the produced output buffer is returned not including
956 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
958 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
959 unmodified and 0 is returned.
960 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
961 unmodified and 0 is returned.
962 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
963 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
964 is unmodified and 0 is returned.
965 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
966 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
967 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
969 If BufferSize is 0, then no output buffer is produced and 0 is returned.
971 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
973 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
974 @param FormatString A Null-terminated Unicode format string.
975 @param ... Variable argument list whose contents are accessed based on the
976 format string specified by FormatString.
978 @return The number of ASCII characters in the produced output buffer not including the
984 AsciiSPrintUnicodeFormat (
985 OUT CHAR8
*StartOfBuffer
,
987 IN CONST CHAR16
*FormatString
,
992 UINTN NumberOfPrinted
;
994 VA_START (Marker
, FormatString
);
995 NumberOfPrinted
= AsciiVSPrintUnicodeFormat (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
997 return NumberOfPrinted
;
1002 Converts a decimal value to a Null-terminated Ascii string.
1004 Converts the decimal number specified by Value to a Null-terminated Ascii
1005 string specified by Buffer containing at most Width characters. No padding of
1006 spaces is ever performed. If Width is 0 then a width of
1007 MAXIMUM_VALUE_CHARACTERS is assumed. If the conversion contains more than
1008 Width characters, then only the first Width characters are placed in Buffer.
1009 Additional conversion parameters are specified in Flags.
1011 The Flags bit LEFT_JUSTIFY is always ignored.
1012 All conversions are left justified in Buffer.
1013 If Width is 0, PREFIX_ZERO is ignored in Flags.
1014 If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and
1015 commas are inserted every 3rd digit starting from the right.
1016 If RADIX_HEX is set in Flags, then the output buffer will be formatted in
1018 If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in
1020 If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, then
1021 Buffer is padded with '0' characters so the combination of the optional '-'
1022 sign character, '0' characters, digit characters for Value, and the
1023 Null-terminator add up to Width characters.
1025 If an error would be returned, then the function will ASSERT().
1027 @param Buffer The pointer to the output buffer for the produced
1028 Null-terminated Ascii string.
1029 @param BufferSize The size of Buffer in bytes, including the
1031 @param Flags The bitmask of flags that specify left justification,
1032 zero pad, and commas.
1033 @param Value The 64-bit signed value to convert to a string.
1034 @param Width The maximum number of Ascii characters to place in
1035 Buffer, not including the Null-terminator.
1037 @retval RETURN_SUCCESS The decimal value is converted.
1038 @retval RETURN_BUFFER_TOO_SMALL If BufferSize cannot hold the converted
1040 @retval RETURN_INVALID_PARAMETER If Buffer is NULL.
1041 If PcdMaximumAsciiStringLength is not
1042 zero, and BufferSize is greater than
1043 PcdMaximumAsciiStringLength.
1044 If unsupported bits are set in Flags.
1045 If both COMMA_TYPE and RADIX_HEX are set in
1047 If Width >= MAXIMUM_VALUE_CHARACTERS.
1052 AsciiValueToStringS (
1053 IN OUT CHAR8
*Buffer
,
1054 IN UINTN BufferSize
,
1060 return mPrint2SProtocol
->AsciiValueToStringS (Buffer
, BufferSize
, Flags
, Value
, Width
);
1063 #define PREFIX_SIGN BIT1
1064 #define PREFIX_BLANK BIT2
1065 #define LONG_TYPE BIT4
1066 #define OUTPUT_UNICODE BIT6
1067 #define FORMAT_UNICODE BIT8
1068 #define PAD_TO_WIDTH BIT9
1069 #define ARGUMENT_UNICODE BIT10
1070 #define PRECISION BIT11
1071 #define ARGUMENT_REVERSED BIT12
1072 #define COUNT_ONLY_NO_PRINT BIT13
1073 #define UNSIGNED_TYPE BIT14
1076 // Record date and time information
1092 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mHexStr
[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
1095 Internal function that convert a number to a string in Buffer.
1097 Print worker function that converts a decimal or hexadecimal number to an ASCII string in Buffer.
1099 @param Buffer Location to place the ASCII string of Value.
1100 @param Value The value to convert to a Decimal or Hexadecimal string in Buffer.
1101 @param Radix Radix of the value
1103 @return A pointer to the end of buffer filled with ASCII string.
1107 InternalPrintLibValueToString (
1108 IN OUT CHAR8
*Buffer
,
1116 // Loop to convert one digit at a time in reverse order
1120 Value
= (INT64
)DivU64x32Remainder ((UINT64
)Value
, (UINT32
)Radix
, &Remainder
);
1121 *(++Buffer
) = mHexStr
[Remainder
];
1122 } while (Value
!= 0);
1125 // Return pointer of the end of filled buffer.
1131 Worker function that produces a Null-terminated string in an output buffer
1132 based on a Null-terminated format string and a VA_LIST argument list.
1134 VSPrint function to process format and place the results in Buffer. Since a
1135 VA_LIST is used this routine allows the nesting of Vararg routines. Thus
1136 this is the main print working routine.
1138 If COUNT_ONLY_NO_PRINT is set in Flags, Buffer will not be modified at all.
1140 @param[out] Buffer The character buffer to print the results of the
1141 parsing of Format into.
1142 @param[in] BufferSize The maximum number of characters to put into
1144 @param[in] Flags Initial flags value.
1145 Can only have FORMAT_UNICODE, OUTPUT_UNICODE,
1146 and COUNT_ONLY_NO_PRINT set.
1147 @param[in] Format A Null-terminated format string.
1148 @param[in] VaListMarker VA_LIST style variable argument list consumed by
1150 @param[in] BaseListMarker BASE_LIST style variable argument list consumed
1151 by processing Format.
1153 @return The number of characters printed not including the Null-terminator.
1154 If COUNT_ONLY_NO_PRINT was set returns the same, but without any
1155 modification to Buffer.
1159 InternalPrintLibSPrintMarker (
1161 IN UINTN BufferSize
,
1163 IN CONST CHAR8
*Format
,
1164 IN VA_LIST VaListMarker
, OPTIONAL
1165 IN BASE_LIST BaseListMarker OPTIONAL
1169 Worker function that produces a Null-terminated string in an output buffer
1170 based on a Null-terminated format string and variable argument list.
1172 VSPrint function to process format and place the results in Buffer. Since a
1173 VA_LIST is used this routine allows the nesting of Vararg routines. Thus
1174 this is the main print working routine
1176 @param StartOfBuffer The character buffer to print the results of the parsing
1178 @param BufferSize The maximum number of characters to put into buffer.
1179 Zero means no limit.
1180 @param Flags Initial flags value.
1181 Can only have FORMAT_UNICODE and OUTPUT_UNICODE set
1182 @param FormatString A Null-terminated format string.
1183 @param ... The variable argument list.
1185 @return The number of characters printed.
1190 InternalPrintLibSPrint (
1191 OUT CHAR8
*StartOfBuffer
,
1192 IN UINTN BufferSize
,
1194 IN CONST CHAR8
*FormatString
,
1199 UINTN NumberOfPrinted
;
1201 VA_START (Marker
, FormatString
);
1202 NumberOfPrinted
= InternalPrintLibSPrintMarker (StartOfBuffer
, BufferSize
, Flags
, FormatString
, Marker
, NULL
);
1204 return NumberOfPrinted
;
1207 #define WARNING_STATUS_NUMBER 5
1208 #define ERROR_STATUS_NUMBER 33
1210 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8
* CONST mStatusString
[] = {
1211 "Success", // RETURN_SUCCESS = 0
1212 "Warning Unknown Glyph", // RETURN_WARN_UNKNOWN_GLYPH = 1
1213 "Warning Delete Failure", // RETURN_WARN_DELETE_FAILURE = 2
1214 "Warning Write Failure", // RETURN_WARN_WRITE_FAILURE = 3
1215 "Warning Buffer Too Small", // RETURN_WARN_BUFFER_TOO_SMALL = 4
1216 "Warning Stale Data", // RETURN_WARN_STALE_DATA = 5
1217 "Load Error", // RETURN_LOAD_ERROR = 1 | MAX_BIT
1218 "Invalid Parameter", // RETURN_INVALID_PARAMETER = 2 | MAX_BIT
1219 "Unsupported", // RETURN_UNSUPPORTED = 3 | MAX_BIT
1220 "Bad Buffer Size", // RETURN_BAD_BUFFER_SIZE = 4 | MAX_BIT
1221 "Buffer Too Small", // RETURN_BUFFER_TOO_SMALL, = 5 | MAX_BIT
1222 "Not Ready", // RETURN_NOT_READY = 6 | MAX_BIT
1223 "Device Error", // RETURN_DEVICE_ERROR = 7 | MAX_BIT
1224 "Write Protected", // RETURN_WRITE_PROTECTED = 8 | MAX_BIT
1225 "Out of Resources", // RETURN_OUT_OF_RESOURCES = 9 | MAX_BIT
1226 "Volume Corrupt", // RETURN_VOLUME_CORRUPTED = 10 | MAX_BIT
1227 "Volume Full", // RETURN_VOLUME_FULL = 11 | MAX_BIT
1228 "No Media", // RETURN_NO_MEDIA = 12 | MAX_BIT
1229 "Media changed", // RETURN_MEDIA_CHANGED = 13 | MAX_BIT
1230 "Not Found", // RETURN_NOT_FOUND = 14 | MAX_BIT
1231 "Access Denied", // RETURN_ACCESS_DENIED = 15 | MAX_BIT
1232 "No Response", // RETURN_NO_RESPONSE = 16 | MAX_BIT
1233 "No mapping", // RETURN_NO_MAPPING = 17 | MAX_BIT
1234 "Time out", // RETURN_TIMEOUT = 18 | MAX_BIT
1235 "Not started", // RETURN_NOT_STARTED = 19 | MAX_BIT
1236 "Already started", // RETURN_ALREADY_STARTED = 20 | MAX_BIT
1237 "Aborted", // RETURN_ABORTED = 21 | MAX_BIT
1238 "ICMP Error", // RETURN_ICMP_ERROR = 22 | MAX_BIT
1239 "TFTP Error", // RETURN_TFTP_ERROR = 23 | MAX_BIT
1240 "Protocol Error", // RETURN_PROTOCOL_ERROR = 24 | MAX_BIT
1241 "Incompatible Version", // RETURN_INCOMPATIBLE_VERSION = 25 | MAX_BIT
1242 "Security Violation", // RETURN_SECURITY_VIOLATION = 26 | MAX_BIT
1243 "CRC Error", // RETURN_CRC_ERROR = 27 | MAX_BIT
1244 "End of Media", // RETURN_END_OF_MEDIA = 28 | MAX_BIT
1245 "Reserved (29)", // RESERVED = 29 | MAX_BIT
1246 "Reserved (30)", // RESERVED = 30 | MAX_BIT
1247 "End of File", // RETURN_END_OF_FILE = 31 | MAX_BIT
1248 "Invalid Language", // RETURN_INVALID_LANGUAGE = 32 | MAX_BIT
1249 "Compromised Data" // RETURN_COMPROMISED_DATA = 33 | MAX_BIT
1253 Internal function that places the character into the Buffer.
1255 Internal function that places ASCII or Unicode character into the Buffer.
1257 @param Buffer The buffer to place the Unicode or ASCII string.
1258 @param EndBuffer The end of the input Buffer. No characters will be
1260 @param Length The count of character to be placed into Buffer.
1261 (Negative value indicates no buffer fill.)
1262 @param Character The character to be placed into Buffer.
1263 @param Increment The character increment in Buffer.
1269 InternalPrintLibFillBuffer (
1271 IN CHAR8
*EndBuffer
,
1279 for (Index
= 0; Index
< Length
&& Buffer
< EndBuffer
; Index
++) {
1280 *Buffer
= (CHAR8
) Character
;
1281 if (Increment
!= 1) {
1282 *(Buffer
+ 1) = (CHAR8
)(Character
>> 8);
1284 Buffer
+= Increment
;
1291 Worker function that produces a Null-terminated string in an output buffer
1292 based on a Null-terminated format string and a VA_LIST argument list.
1294 VSPrint function to process format and place the results in Buffer. Since a
1295 VA_LIST is used this routine allows the nesting of Vararg routines. Thus
1296 this is the main print working routine.
1298 If COUNT_ONLY_NO_PRINT is set in Flags, Buffer will not be modified at all.
1300 @param[out] Buffer The character buffer to print the results of the
1301 parsing of Format into.
1302 @param[in] BufferSize The maximum number of characters to put into
1304 @param[in] Flags Initial flags value.
1305 Can only have FORMAT_UNICODE, OUTPUT_UNICODE,
1306 and COUNT_ONLY_NO_PRINT set.
1307 @param[in] Format A Null-terminated format string.
1308 @param[in] VaListMarker VA_LIST style variable argument list consumed by
1310 @param[in] BaseListMarker BASE_LIST style variable argument list consumed
1311 by processing Format.
1313 @return The number of characters printed not including the Null-terminator.
1314 If COUNT_ONLY_NO_PRINT was set returns the same, but without any
1315 modification to Buffer.
1319 InternalPrintLibSPrintMarker (
1321 IN UINTN BufferSize
,
1323 IN CONST CHAR8
*Format
,
1324 IN VA_LIST VaListMarker
, OPTIONAL
1325 IN BASE_LIST BaseListMarker OPTIONAL
1328 CHAR8
*OriginalBuffer
;
1330 CHAR8 ValueBuffer
[MAXIMUM_VALUE_CHARACTERS
];
1331 UINT32 BytesPerOutputCharacter
;
1332 UINTN BytesPerFormatCharacter
;
1334 UINTN FormatCharacter
;
1338 CONST CHAR8
*ArgumentString
;
1344 INTN BytesPerArgumentCharacter
;
1345 UINTN ArgumentCharacter
;
1353 RETURN_STATUS Status
;
1357 UINTN LengthToReturn
;
1360 // If you change this code be sure to match the 2 versions of this function.
1361 // Nearly identical logic is found in the BasePrintLib and
1362 // DxePrintLibPrint2Protocol (both PrintLib instances).
1366 // 1. Buffer shall not be a null pointer when both BufferSize > 0 and
1367 // COUNT_ONLY_NO_PRINT is not set in Flags.
1369 if ((BufferSize
> 0) && ((Flags
& COUNT_ONLY_NO_PRINT
) == 0)) {
1370 SAFE_PRINT_CONSTRAINT_CHECK ((Buffer
!= NULL
), 0);
1374 // 2. Format shall not be a null pointer when BufferSize > 0 or when
1375 // COUNT_ONLY_NO_PRINT is set in Flags.
1377 if ((BufferSize
> 0) || ((Flags
& COUNT_ONLY_NO_PRINT
) != 0)) {
1378 SAFE_PRINT_CONSTRAINT_CHECK ((Format
!= NULL
), 0);
1382 // 3. BufferSize shall not be greater than RSIZE_MAX for Unicode output or
1383 // ASCII_RSIZE_MAX for Ascii output.
1385 if ((Flags
& OUTPUT_UNICODE
) != 0) {
1386 if (RSIZE_MAX
!= 0) {
1387 SAFE_PRINT_CONSTRAINT_CHECK ((BufferSize
<= RSIZE_MAX
), 0);
1389 BytesPerOutputCharacter
= 2;
1391 if (ASCII_RSIZE_MAX
!= 0) {
1392 SAFE_PRINT_CONSTRAINT_CHECK ((BufferSize
<= ASCII_RSIZE_MAX
), 0);
1394 BytesPerOutputCharacter
= 1;
1398 // 4. Format shall not contain more than RSIZE_MAX Unicode characters or
1399 // ASCII_RSIZE_MAX Ascii characters.
1401 if ((Flags
& FORMAT_UNICODE
) != 0) {
1402 if (RSIZE_MAX
!= 0) {
1403 SAFE_PRINT_CONSTRAINT_CHECK ((StrnLenS ((CHAR16
*)Format
, RSIZE_MAX
+ 1) <= RSIZE_MAX
), 0);
1405 BytesPerFormatCharacter
= 2;
1406 FormatMask
= 0xffff;
1408 if (ASCII_RSIZE_MAX
!= 0) {
1409 SAFE_PRINT_CONSTRAINT_CHECK ((AsciiStrnLenS (Format
, ASCII_RSIZE_MAX
+ 1) <= ASCII_RSIZE_MAX
), 0);
1411 BytesPerFormatCharacter
= 1;
1415 if ((Flags
& COUNT_ONLY_NO_PRINT
) != 0) {
1416 if (BufferSize
== 0) {
1421 // We can run without a Buffer for counting only.
1423 if (BufferSize
== 0) {
1430 OriginalBuffer
= NULL
;
1433 // Reserve space for the Null terminator.
1435 if (Buffer
!= NULL
) {
1437 OriginalBuffer
= Buffer
;
1440 // Set the tag for the end of the input Buffer.
1442 EndBuffer
= Buffer
+ BufferSize
* BytesPerOutputCharacter
;
1446 // Get the first character from the format string
1448 FormatCharacter
= ((*Format
& 0xff) | ((BytesPerFormatCharacter
== 1) ? 0 : (*(Format
+ 1) << 8))) & FormatMask
;
1451 // Loop until the end of the format string is reached or the output buffer is full
1453 while (FormatCharacter
!= 0) {
1454 if ((Buffer
!= NULL
) && (Buffer
>= EndBuffer
)) {
1458 // Clear all the flag bits except those that may have been passed in
1460 Flags
&= (UINTN
) (OUTPUT_UNICODE
| FORMAT_UNICODE
| COUNT_ONLY_NO_PRINT
);
1463 // Set the default width to zero, and the default precision to 1
1473 switch (FormatCharacter
) {
1476 // Parse Flags and Width
1478 for (Done
= FALSE
; !Done
; ) {
1479 Format
+= BytesPerFormatCharacter
;
1480 FormatCharacter
= ((*Format
& 0xff) | ((BytesPerFormatCharacter
== 1) ? 0 : (*(Format
+ 1) << 8))) & FormatMask
;
1481 switch (FormatCharacter
) {
1486 Flags
|= LEFT_JUSTIFY
;
1489 Flags
|= PREFIX_SIGN
;
1492 Flags
|= PREFIX_BLANK
;
1495 Flags
|= COMMA_TYPE
;
1502 if ((Flags
& PRECISION
) == 0) {
1503 Flags
|= PAD_TO_WIDTH
;
1504 if (BaseListMarker
== NULL
) {
1505 Width
= VA_ARG (VaListMarker
, UINTN
);
1507 Width
= BASE_ARG (BaseListMarker
, UINTN
);
1510 if (BaseListMarker
== NULL
) {
1511 Precision
= VA_ARG (VaListMarker
, UINTN
);
1513 Precision
= BASE_ARG (BaseListMarker
, UINTN
);
1518 if ((Flags
& PRECISION
) == 0) {
1519 Flags
|= PREFIX_ZERO
;
1530 for (Count
= 0; ((FormatCharacter
>= '0') && (FormatCharacter
<= '9')); ){
1531 Count
= (Count
* 10) + FormatCharacter
- '0';
1532 Format
+= BytesPerFormatCharacter
;
1533 FormatCharacter
= ((*Format
& 0xff) | ((BytesPerFormatCharacter
== 1) ? 0 : (*(Format
+ 1) << 8))) & FormatMask
;
1535 Format
-= BytesPerFormatCharacter
;
1536 if ((Flags
& PRECISION
) == 0) {
1537 Flags
|= PAD_TO_WIDTH
;
1546 // Make no output if Format string terminates unexpectedly when
1547 // looking up for flag, width, precision and type.
1549 Format
-= BytesPerFormatCharacter
;
1552 // break skipped on purpose.
1561 // Handle each argument type
1563 switch (FormatCharacter
) {
1566 // Flag space, +, 0, L & l are invalid for type p.
1568 Flags
&= ~((UINTN
) (PREFIX_BLANK
| PREFIX_SIGN
| PREFIX_ZERO
| LONG_TYPE
));
1569 if (sizeof (VOID
*) > 4) {
1573 // break skipped on purpose
1576 Flags
|= PREFIX_ZERO
;
1578 // break skipped on purpose
1583 // break skipped on purpose
1586 if ((Flags
& RADIX_HEX
) == 0) {
1587 Flags
&= ~((UINTN
) (PREFIX_SIGN
));
1588 Flags
|= UNSIGNED_TYPE
;
1591 // break skipped on purpose
1594 if ((Flags
& LONG_TYPE
) == 0) {
1596 // 'd', 'u', 'x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".
1597 // This assumption is made so the format string definition is compatible with the ANSI C
1598 // Specification for formatted strings. It is recommended that the Base Types be used
1599 // everywhere, but in this one case, compliance with ANSI C is more important, and
1600 // provides an implementation that is compatible with that largest possible set of CPU
1601 // architectures. This is why the type "int" is used in this one case.
1603 if (BaseListMarker
== NULL
) {
1604 Value
= VA_ARG (VaListMarker
, int);
1606 Value
= BASE_ARG (BaseListMarker
, int);
1609 if (BaseListMarker
== NULL
) {
1610 Value
= VA_ARG (VaListMarker
, INT64
);
1612 Value
= BASE_ARG (BaseListMarker
, INT64
);
1615 if ((Flags
& PREFIX_BLANK
) != 0) {
1618 if ((Flags
& PREFIX_SIGN
) != 0) {
1621 if ((Flags
& COMMA_TYPE
) != 0) {
1624 if ((Flags
& RADIX_HEX
) == 0) {
1627 Flags
&= ~((UINTN
) PREFIX_ZERO
);
1630 if (Value
< 0 && (Flags
& UNSIGNED_TYPE
) == 0) {
1631 Flags
|= PREFIX_SIGN
;
1634 } else if ((Flags
& UNSIGNED_TYPE
) != 0 && (Flags
& LONG_TYPE
) == 0) {
1636 // 'd', 'u', 'x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".
1637 // This assumption is made so the format string definition is compatible with the ANSI C
1638 // Specification for formatted strings. It is recommended that the Base Types be used
1639 // everywhere, but in this one case, compliance with ANSI C is more important, and
1640 // provides an implementation that is compatible with that largest possible set of CPU
1641 // architectures. This is why the type "unsigned int" is used in this one case.
1643 Value
= (unsigned int)Value
;
1648 if ((Flags
& LONG_TYPE
) == 0 && Value
< 0) {
1650 // 'd', 'u', 'x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".
1651 // This assumption is made so the format string definition is compatible with the ANSI C
1652 // Specification for formatted strings. It is recommended that the Base Types be used
1653 // everywhere, but in this one case, compliance with ANSI C is more important, and
1654 // provides an implementation that is compatible with that largest possible set of CPU
1655 // architectures. This is why the type "unsigned int" is used in this one case.
1657 Value
= (unsigned int)Value
;
1661 // Convert Value to a reversed string
1663 Count
= InternalPrintLibValueToString (ValueBuffer
, Value
, Radix
) - ValueBuffer
;
1664 if (Value
== 0 && Precision
== 0) {
1667 ArgumentString
= (CHAR8
*)ValueBuffer
+ Count
;
1671 Digits
= 3 - Digits
;
1673 if (Comma
&& Count
!= 0) {
1674 Count
+= ((Count
- 1) / 3);
1680 Flags
|= ARGUMENT_REVERSED
;
1682 if ((Flags
& PREFIX_ZERO
) != 0) {
1683 if ((Flags
& LEFT_JUSTIFY
) == 0) {
1684 if ((Flags
& PAD_TO_WIDTH
) != 0) {
1685 if ((Flags
& PRECISION
) == 0) {
1695 Flags
|= ARGUMENT_UNICODE
;
1697 // break skipped on purpose
1700 if (BaseListMarker
== NULL
) {
1701 ArgumentString
= VA_ARG (VaListMarker
, CHAR8
*);
1703 ArgumentString
= BASE_ARG (BaseListMarker
, CHAR8
*);
1705 if (ArgumentString
== NULL
) {
1706 Flags
&= (~(UINTN
)ARGUMENT_UNICODE
);
1707 ArgumentString
= "<null string>";
1710 // Set the default precision for string to be zero if not specified.
1712 if ((Flags
& PRECISION
) == 0) {
1718 if (BaseListMarker
== NULL
) {
1719 Character
= VA_ARG (VaListMarker
, UINTN
) & 0xffff;
1721 Character
= BASE_ARG (BaseListMarker
, UINTN
) & 0xffff;
1723 ArgumentString
= (CHAR8
*)&Character
;
1724 Flags
|= ARGUMENT_UNICODE
;
1728 if (BaseListMarker
== NULL
) {
1729 TmpGuid
= VA_ARG (VaListMarker
, GUID
*);
1731 TmpGuid
= BASE_ARG (BaseListMarker
, GUID
*);
1733 if (TmpGuid
== NULL
) {
1734 ArgumentString
= "<null guid>";
1736 GuidData1
= ReadUnaligned32 (&(TmpGuid
->Data1
));
1737 GuidData2
= ReadUnaligned16 (&(TmpGuid
->Data2
));
1738 GuidData3
= ReadUnaligned16 (&(TmpGuid
->Data3
));
1739 InternalPrintLibSPrint (
1741 MAXIMUM_VALUE_CHARACTERS
,
1743 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1756 ArgumentString
= ValueBuffer
;
1761 if (BaseListMarker
== NULL
) {
1762 TmpTime
= VA_ARG (VaListMarker
, TIME
*);
1764 TmpTime
= BASE_ARG (BaseListMarker
, TIME
*);
1766 if (TmpTime
== NULL
) {
1767 ArgumentString
= "<null time>";
1769 InternalPrintLibSPrint (
1771 MAXIMUM_VALUE_CHARACTERS
,
1773 "%02d/%02d/%04d %02d:%02d",
1780 ArgumentString
= ValueBuffer
;
1785 if (BaseListMarker
== NULL
) {
1786 Status
= VA_ARG (VaListMarker
, RETURN_STATUS
);
1788 Status
= BASE_ARG (BaseListMarker
, RETURN_STATUS
);
1790 ArgumentString
= ValueBuffer
;
1791 if (RETURN_ERROR (Status
)) {
1795 Index
= Status
& ~MAX_BIT
;
1796 if (Index
> 0 && Index
<= ERROR_STATUS_NUMBER
) {
1797 ArgumentString
= mStatusString
[Index
+ WARNING_STATUS_NUMBER
];
1801 if (Index
<= WARNING_STATUS_NUMBER
) {
1802 ArgumentString
= mStatusString
[Index
];
1805 if (ArgumentString
== ValueBuffer
) {
1806 InternalPrintLibSPrint ((CHAR8
*) ValueBuffer
, MAXIMUM_VALUE_CHARACTERS
, 0, "%08X", Status
);
1811 Format
+= BytesPerFormatCharacter
;
1812 FormatCharacter
= ((*Format
& 0xff) | ((BytesPerFormatCharacter
== 1) ? 0 : (*(Format
+ 1) << 8))) & FormatMask
;
1813 if (FormatCharacter
== '\n') {
1815 // Translate '\r\n' to '\r\n'
1817 ArgumentString
= "\r\n";
1820 // Translate '\r' to '\r'
1822 ArgumentString
= "\r";
1823 Format
-= BytesPerFormatCharacter
;
1829 // Translate '\n' to '\r\n' and '\n\r' to '\r\n'
1831 ArgumentString
= "\r\n";
1832 Format
+= BytesPerFormatCharacter
;
1833 FormatCharacter
= ((*Format
& 0xff) | ((BytesPerFormatCharacter
== 1) ? 0 : (*(Format
+ 1) << 8))) & FormatMask
;
1834 if (FormatCharacter
!= '\r') {
1835 Format
-= BytesPerFormatCharacter
;
1842 // if the type is '%' or unknown, then print it to the screen
1844 ArgumentString
= (CHAR8
*)&FormatCharacter
;
1845 Flags
|= ARGUMENT_UNICODE
;
1851 Format
+= BytesPerFormatCharacter
;
1852 FormatCharacter
= ((*Format
& 0xff) | ((BytesPerFormatCharacter
== 1) ? 0 : (*(Format
+ 1) << 8))) & FormatMask
;
1853 if (FormatCharacter
== '\n') {
1855 // Translate '\r\n' to '\r\n'
1857 ArgumentString
= "\r\n";
1860 // Translate '\r' to '\r'
1862 ArgumentString
= "\r";
1863 Format
-= BytesPerFormatCharacter
;
1869 // Translate '\n' to '\r\n' and '\n\r' to '\r\n'
1871 ArgumentString
= "\r\n";
1872 Format
+= BytesPerFormatCharacter
;
1873 FormatCharacter
= ((*Format
& 0xff) | ((BytesPerFormatCharacter
== 1) ? 0 : (*(Format
+ 1) << 8))) & FormatMask
;
1874 if (FormatCharacter
!= '\r') {
1875 Format
-= BytesPerFormatCharacter
;
1880 ArgumentString
= (CHAR8
*)&FormatCharacter
;
1881 Flags
|= ARGUMENT_UNICODE
;
1886 // Retrieve the ArgumentString attriubutes
1888 if ((Flags
& ARGUMENT_UNICODE
) != 0) {
1889 ArgumentMask
= 0xffff;
1890 BytesPerArgumentCharacter
= 2;
1892 ArgumentMask
= 0xff;
1893 BytesPerArgumentCharacter
= 1;
1895 if ((Flags
& ARGUMENT_REVERSED
) != 0) {
1896 BytesPerArgumentCharacter
= -BytesPerArgumentCharacter
;
1899 // Compute the number of characters in ArgumentString and store it in Count
1900 // ArgumentString is either null-terminated, or it contains Precision characters
1903 (ArgumentString
[Count
* BytesPerArgumentCharacter
] != '\0' ||
1904 (BytesPerArgumentCharacter
> 1 &&
1905 ArgumentString
[Count
* BytesPerArgumentCharacter
+ 1]!= '\0')) &&
1906 (Count
< Precision
|| ((Flags
& PRECISION
) == 0));
1908 ArgumentCharacter
= ((ArgumentString
[Count
* BytesPerArgumentCharacter
] & 0xff) | ((ArgumentString
[Count
* BytesPerArgumentCharacter
+ 1]) << 8)) & ArgumentMask
;
1909 if (ArgumentCharacter
== 0) {
1915 if (Precision
< Count
) {
1920 // Pad before the string
1922 if ((Flags
& (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) == (PAD_TO_WIDTH
)) {
1923 LengthToReturn
+= ((Width
- Precision
) * BytesPerOutputCharacter
);
1924 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1925 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, Width
- Precision
, ' ', BytesPerOutputCharacter
);
1931 LengthToReturn
+= (1 * BytesPerOutputCharacter
);
1932 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1933 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, 1, Prefix
, BytesPerOutputCharacter
);
1936 LengthToReturn
+= ((Precision
- Count
) * BytesPerOutputCharacter
);
1937 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1938 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, Precision
- Count
, '0', BytesPerOutputCharacter
);
1941 LengthToReturn
+= ((Precision
- Count
) * BytesPerOutputCharacter
);
1942 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1943 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, Precision
- Count
, ' ', BytesPerOutputCharacter
);
1946 LengthToReturn
+= (1 * BytesPerOutputCharacter
);
1947 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1948 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, 1, Prefix
, BytesPerOutputCharacter
);
1954 // Output the Prefix character if it is present
1962 // Copy the string into the output buffer performing the required type conversions
1964 while (Index
< Count
&&
1965 (ArgumentString
[0] != '\0' ||
1966 (BytesPerArgumentCharacter
> 1 && ArgumentString
[1] != '\0'))) {
1967 ArgumentCharacter
= ((*ArgumentString
& 0xff) | (((UINT8
)*(ArgumentString
+ 1)) << 8)) & ArgumentMask
;
1969 LengthToReturn
+= (1 * BytesPerOutputCharacter
);
1970 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1971 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, 1, ArgumentCharacter
, BytesPerOutputCharacter
);
1973 ArgumentString
+= BytesPerArgumentCharacter
;
1980 if (Index
< Count
) {
1981 LengthToReturn
+= (1 * BytesPerOutputCharacter
);
1982 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1983 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, 1, ',', BytesPerOutputCharacter
);
1991 // Pad after the string
1993 if ((Flags
& (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) == (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) {
1994 LengthToReturn
+= ((Width
- Precision
) * BytesPerOutputCharacter
);
1995 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1996 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, Width
- Precision
, ' ', BytesPerOutputCharacter
);
2001 // Get the next character from the format string
2003 Format
+= BytesPerFormatCharacter
;
2006 // Get the next character from the format string
2008 FormatCharacter
= ((*Format
& 0xff) | ((BytesPerFormatCharacter
== 1) ? 0 : (*(Format
+ 1) << 8))) & FormatMask
;
2011 if ((Flags
& COUNT_ONLY_NO_PRINT
) != 0) {
2012 return (LengthToReturn
/ BytesPerOutputCharacter
);
2015 ASSERT (Buffer
!= NULL
);
2017 // Null terminate the Unicode or ASCII string
2019 InternalPrintLibFillBuffer (Buffer
, EndBuffer
+ BytesPerOutputCharacter
, 1, 0, BytesPerOutputCharacter
);
2021 return ((Buffer
- OriginalBuffer
) / BytesPerOutputCharacter
);
2025 Returns the number of characters that would be produced by if the formatted
2026 output were produced not including the Null-terminator.
2028 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
2030 If FormatString is NULL, then ASSERT() and 0 is returned.
2031 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more
2032 than PcdMaximumUnicodeStringLength Unicode characters not including the
2033 Null-terminator, then ASSERT() and 0 is returned.
2035 @param[in] FormatString A Null-terminated Unicode format string.
2036 @param[in] Marker VA_LIST marker for the variable argument list.
2038 @return The number of characters that would be produced, not including the
2044 IN CONST CHAR16
*FormatString
,
2048 ASSERT_UNICODE_BUFFER (FormatString
);
2049 return InternalPrintLibSPrintMarker (NULL
, 0, FORMAT_UNICODE
| OUTPUT_UNICODE
| COUNT_ONLY_NO_PRINT
, (CHAR8
*)FormatString
, Marker
, NULL
);
2053 Returns the number of characters that would be produced by if the formatted
2054 output were produced not including the Null-terminator.
2056 If FormatString is NULL, then ASSERT() and 0 is returned.
2057 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more
2058 than PcdMaximumAsciiStringLength Ascii characters not including the
2059 Null-terminator, then ASSERT() and 0 is returned.
2061 @param[in] FormatString A Null-terminated ASCII format string.
2062 @param[in] Marker VA_LIST marker for the variable argument list.
2064 @return The number of characters that would be produced, not including the
2069 SPrintLengthAsciiFormat (
2070 IN CONST CHAR8
*FormatString
,
2074 return InternalPrintLibSPrintMarker (NULL
, 0, OUTPUT_UNICODE
| COUNT_ONLY_NO_PRINT
, (CHAR8
*)FormatString
, Marker
, NULL
);