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 - 2017, Intel Corporation. All rights reserved.<BR>
10 This program and the accompanying materials
11 are licensed and made available under the terms and conditions of the BSD License
12 which accompanies this distribution. The full text of the license may be found at
13 http://opensource.org/licenses/bsd-license.php
15 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
16 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
22 #include <Protocol/Print2.h>
24 #include <Library/PrintLib.h>
26 #include <Library/BaseLib.h>
27 #include <Library/DebugLib.h>
28 #include <Library/PcdLib.h>
30 #define ASSERT_UNICODE_BUFFER(Buffer) ASSERT ((((UINTN) (Buffer)) & 0x01) == 0)
35 #define RSIZE_MAX (PcdGet32 (PcdMaximumUnicodeStringLength))
36 #define ASCII_RSIZE_MAX (PcdGet32 (PcdMaximumAsciiStringLength))
38 #define SAFE_PRINT_CONSTRAINT_CHECK(Expression, RetVal) \
40 ASSERT (Expression); \
41 if (!(Expression)) { \
46 EFI_PRINT2S_PROTOCOL
*mPrint2SProtocol
= NULL
;
49 The constructor function caches the pointer to Print2S protocol.
51 The constructor function locates Print2S protocol from protocol database.
52 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
54 @param ImageHandle The firmware allocated handle for the EFI image.
55 @param SystemTable A pointer to the EFI System Table.
57 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
63 IN EFI_HANDLE ImageHandle
,
64 IN EFI_SYSTEM_TABLE
*SystemTable
69 Status
= SystemTable
->BootServices
->LocateProtocol (
70 &gEfiPrint2SProtocolGuid
,
72 (VOID
**) &mPrint2SProtocol
74 ASSERT_EFI_ERROR (Status
);
75 ASSERT (mPrint2SProtocol
!= NULL
);
82 Worker function that converts a VA_LIST to a BASE_LIST based on a Null-terminated
85 @param AsciiFormat TRUE if Format is an ASCII string. FALSE if Format is a Unicode string.
86 @param Format Null-terminated format string.
87 @param VaListMarker VA_LIST style variable argument list consumed by processing Format.
88 @param BaseListMarker BASE_LIST style variable argument list consumed by processing Format.
89 @param Size The size, in bytes, of the BaseListMarker buffer.
91 @return TRUE The VA_LIST has been converted to BASE_LIST.
92 @return FALSE The VA_LIST has not been converted to BASE_LIST.
96 DxePrintLibPrint2ProtocolVaListToBaseList (
97 IN BOOLEAN AsciiFormat
,
98 IN CONST CHAR8
*Format
,
99 IN VA_LIST VaListMarker
,
100 OUT BASE_LIST BaseListMarker
,
104 BASE_LIST BaseListStart
;
105 UINTN BytesPerFormatCharacter
;
107 UINTN FormatCharacter
;
111 ASSERT (BaseListMarker
!= NULL
);
112 SAFE_PRINT_CONSTRAINT_CHECK ((Format
!= NULL
), FALSE
);
114 BaseListStart
= BaseListMarker
;
117 if (ASCII_RSIZE_MAX
!= 0) {
118 SAFE_PRINT_CONSTRAINT_CHECK ((AsciiStrnLenS (Format
, ASCII_RSIZE_MAX
+ 1) <= ASCII_RSIZE_MAX
), FALSE
);
120 BytesPerFormatCharacter
= 1;
123 if (RSIZE_MAX
!= 0) {
124 SAFE_PRINT_CONSTRAINT_CHECK ((StrnLenS ((CHAR16
*)Format
, RSIZE_MAX
+ 1) <= RSIZE_MAX
), FALSE
);
126 BytesPerFormatCharacter
= 2;
131 // Get the first character from the format string
133 FormatCharacter
= ((*Format
& 0xff) | (*(Format
+ 1) << 8)) & FormatMask
;
135 while (FormatCharacter
!= 0) {
136 if (FormatCharacter
== '%') {
140 // Parse Flags and Width
142 for (Done
= FALSE
; !Done
; ) {
144 // Get the next character from the format string
146 Format
+= BytesPerFormatCharacter
;
149 // Get the next character from the format string
151 FormatCharacter
= ((*Format
& 0xff) | (*(Format
+ 1) << 8)) & FormatMask
;
153 switch (FormatCharacter
) {
175 BASE_ARG (BaseListMarker
, UINTN
) = VA_ARG (VaListMarker
, UINTN
);
179 // Make no output if Format string terminates unexpectedly when
180 // looking up for flag, width, precision and type.
182 Format
-= BytesPerFormatCharacter
;
184 // break skipped on purpose.
193 // Handle each argument type
195 switch (FormatCharacter
) {
197 if (sizeof (VOID
*) > 4) {
205 BASE_ARG (BaseListMarker
, INT64
) = VA_ARG (VaListMarker
, INT64
);
207 BASE_ARG (BaseListMarker
, int) = VA_ARG (VaListMarker
, int);
215 BASE_ARG (BaseListMarker
, VOID
*) = VA_ARG (VaListMarker
, VOID
*);
218 BASE_ARG (BaseListMarker
, UINTN
) = VA_ARG (VaListMarker
, UINTN
);
221 BASE_ARG (BaseListMarker
, RETURN_STATUS
) = VA_ARG (VaListMarker
, RETURN_STATUS
);
227 // If BASE_LIST is larger than Size, then return FALSE
229 if ((UINTN
)((UINT8
*)BaseListMarker
- (UINT8
*)BaseListStart
) > Size
) {
230 DEBUG ((DEBUG_ERROR
, "The input variable argument list is too long. Please consider breaking into multiple print calls.\n"));
235 // Get the next character from the format string
237 Format
+= BytesPerFormatCharacter
;
240 // Get the next character from the format string
242 FormatCharacter
= ((*Format
& 0xff) | (*(Format
+ 1) << 8)) & FormatMask
;
248 Produces a Null-terminated Unicode string in an output buffer based on
249 a Null-terminated Unicode format string and a VA_LIST argument list.
251 This function is similar as vsnprintf_s defined in C11.
253 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
255 The Unicode string is produced by parsing the format string specified by FormatString.
256 Arguments are pulled from the variable argument list specified by Marker based on the
257 contents of the format string.
258 The number of Unicode characters in the produced output buffer is returned not including
261 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
262 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
264 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
265 unmodified and 0 is returned.
266 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
267 unmodified and 0 is returned.
268 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
269 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
270 buffer is unmodified and 0 is returned.
271 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
272 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
273 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
275 If BufferSize is 0 or 1, then the output buffer is unmodified and 0 is returned.
277 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
279 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
280 @param FormatString A Null-terminated Unicode format string.
281 @param Marker VA_LIST marker for the variable argument list.
283 @return The number of Unicode characters in the produced output buffer not including the
290 OUT CHAR16
*StartOfBuffer
,
292 IN CONST CHAR16
*FormatString
,
296 UINT64 BaseListMarker
[256 / sizeof (UINT64
)];
299 ASSERT_UNICODE_BUFFER (StartOfBuffer
);
300 ASSERT_UNICODE_BUFFER (FormatString
);
302 Converted
= DxePrintLibPrint2ProtocolVaListToBaseList (
304 (CHAR8
*)FormatString
,
306 (BASE_LIST
)BaseListMarker
,
307 sizeof (BaseListMarker
) - 8
313 return UnicodeBSPrint (StartOfBuffer
, BufferSize
, FormatString
, (BASE_LIST
)BaseListMarker
);
317 Produces a Null-terminated Unicode string in an output buffer based on
318 a Null-terminated Unicode format string and a BASE_LIST argument list.
320 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
322 The Unicode string is produced by parsing the format string specified by FormatString.
323 Arguments are pulled from the variable argument list specified by Marker based on the
324 contents of the format string.
325 The number of Unicode characters in the produced output buffer is returned not including
328 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
329 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
331 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
332 unmodified and 0 is returned.
333 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
334 unmodified and 0 is returned.
335 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
336 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
337 buffer is unmodified and 0 is returned.
338 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
339 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
340 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
342 If BufferSize is 0 or 1, then the output buffer is unmodified and 0 is returned.
344 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
346 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
347 @param FormatString A Null-terminated Unicode format string.
348 @param Marker BASE_LIST marker for the variable argument list.
350 @return The number of Unicode characters in the produced output buffer not including the
357 OUT CHAR16
*StartOfBuffer
,
359 IN CONST CHAR16
*FormatString
,
363 ASSERT_UNICODE_BUFFER (StartOfBuffer
);
364 ASSERT_UNICODE_BUFFER (FormatString
);
365 return mPrint2SProtocol
->UnicodeBSPrint (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
369 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
370 Unicode format string and variable argument list.
372 This function is similar as snprintf_s defined in C11.
374 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
376 The Unicode string is produced by parsing the format string specified by FormatString.
377 Arguments are pulled from the variable argument list based on the contents of the format string.
378 The number of Unicode characters in the produced output buffer is returned not including
381 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
382 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
384 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
385 unmodified and 0 is returned.
386 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
387 unmodified and 0 is returned.
388 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
389 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
390 buffer is unmodified and 0 is returned.
391 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
392 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
393 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
395 If BufferSize is 0 or 1, then the output buffer is unmodified and 0 is returned.
397 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
399 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
400 @param FormatString A Null-terminated Unicode format string.
401 @param ... Variable argument list whose contents are accessed based on the
402 format string specified by FormatString.
404 @return The number of Unicode characters in the produced output buffer not including the
411 OUT CHAR16
*StartOfBuffer
,
413 IN CONST CHAR16
*FormatString
,
418 UINTN NumberOfPrinted
;
420 VA_START (Marker
, FormatString
);
421 NumberOfPrinted
= UnicodeVSPrint (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
423 return NumberOfPrinted
;
427 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
428 ASCII format string and a VA_LIST argument list.
430 This function is similar as vsnprintf_s defined in C11.
432 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
434 The Unicode string is produced by parsing the format string specified by FormatString.
435 Arguments are pulled from the variable argument list specified by Marker based on the
436 contents of the format string.
437 The number of Unicode characters in the produced output buffer is returned not including
440 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
442 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
443 unmodified and 0 is returned.
444 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
445 unmodified and 0 is returned.
446 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
447 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
448 buffer is unmodified and 0 is returned.
449 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
450 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
451 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
453 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.
455 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
457 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
458 @param FormatString A Null-terminated ASCII format string.
459 @param Marker VA_LIST marker for the variable argument list.
461 @return The number of Unicode characters in the produced output buffer not including the
467 UnicodeVSPrintAsciiFormat (
468 OUT CHAR16
*StartOfBuffer
,
470 IN CONST CHAR8
*FormatString
,
474 UINT64 BaseListMarker
[256 / sizeof (UINT64
)];
477 ASSERT_UNICODE_BUFFER (StartOfBuffer
);
479 Converted
= DxePrintLibPrint2ProtocolVaListToBaseList (
483 (BASE_LIST
)BaseListMarker
,
484 sizeof (BaseListMarker
) - 8
490 return UnicodeBSPrintAsciiFormat (StartOfBuffer
, BufferSize
, FormatString
, (BASE_LIST
)BaseListMarker
);
494 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
495 ASCII format string and a BASE_LIST argument list.
497 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
499 The Unicode string is produced by parsing the format string specified by FormatString.
500 Arguments are pulled from the variable argument list specified by Marker based on the
501 contents of the format string.
502 The number of Unicode characters in the produced output buffer is returned not including
505 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
507 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
508 unmodified and 0 is returned.
509 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
510 unmodified and 0 is returned.
511 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
512 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
513 buffer is unmodified and 0 is returned.
514 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
515 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
516 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
518 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.
520 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
522 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
523 @param FormatString A Null-terminated ASCII format string.
524 @param Marker BASE_LIST marker for the variable argument list.
526 @return The number of Unicode characters in the produced output buffer not including the
532 UnicodeBSPrintAsciiFormat (
533 OUT CHAR16
*StartOfBuffer
,
535 IN CONST CHAR8
*FormatString
,
539 ASSERT_UNICODE_BUFFER (StartOfBuffer
);
540 return mPrint2SProtocol
->UnicodeBSPrintAsciiFormat (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
544 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
545 ASCII format string and variable argument list.
547 This function is similar as snprintf_s defined in C11.
549 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
551 The Unicode string is produced by parsing the format string specified by FormatString.
552 Arguments are pulled from the variable argument list based on the contents of the
554 The number of Unicode characters in the produced output buffer is returned not including
557 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
559 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
560 unmodified and 0 is returned.
561 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
562 unmodified and 0 is returned.
563 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
564 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
565 buffer is unmodified and 0 is returned.
566 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
567 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
568 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
570 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.
572 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
574 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
575 @param FormatString A Null-terminated ASCII format string.
576 @param ... Variable argument list whose contents are accessed based on the
577 format string specified by FormatString.
579 @return The number of Unicode characters in the produced output buffer not including the
585 UnicodeSPrintAsciiFormat (
586 OUT CHAR16
*StartOfBuffer
,
588 IN CONST CHAR8
*FormatString
,
593 UINTN NumberOfPrinted
;
595 VA_START (Marker
, FormatString
);
596 NumberOfPrinted
= UnicodeVSPrintAsciiFormat (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
598 return NumberOfPrinted
;
602 Converts a decimal value to a Null-terminated Unicode string.
604 Converts the decimal number specified by Value to a Null-terminated Unicode
605 string specified by Buffer containing at most Width characters. No padding of spaces
606 is ever performed. If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed.
607 The number of Unicode characters in Buffer is returned not including the Null-terminator.
608 If the conversion contains more than Width characters, then only the first
609 Width characters are returned, and the total number of characters
610 required to perform the conversion is returned.
611 Additional conversion parameters are specified in Flags.
613 The Flags bit LEFT_JUSTIFY is always ignored.
614 All conversions are left justified in Buffer.
615 If Width is 0, PREFIX_ZERO is ignored in Flags.
616 If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas
617 are inserted every 3rd digit starting from the right.
618 If RADIX_HEX is set in Flags, then the output buffer will be
619 formatted in hexadecimal format.
620 If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in Buffer is a '-'.
621 If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored,
622 then Buffer is padded with '0' characters so the combination of the optional '-'
623 sign character, '0' characters, digit characters for Value, and the Null-terminator
624 add up to Width characters.
625 If both COMMA_TYPE and RADIX_HEX are set in Flags, then ASSERT().
626 If Buffer is NULL, then ASSERT().
627 If Buffer is not aligned on a 16-bit boundary, then ASSERT().
628 If unsupported bits are set in Flags, then ASSERT().
629 If both COMMA_TYPE and RADIX_HEX are set in Flags, then ASSERT().
630 If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT()
632 @param Buffer Pointer to the output buffer for the produced Null-terminated
634 @param Flags The bitmask of flags that specify left justification, zero pad, and commas.
635 @param Value The 64-bit signed value to convert to a string.
636 @param Width The maximum number of Unicode characters to place in Buffer, not including
639 @return The number of Unicode characters in Buffer not including the Null-terminator.
644 UnicodeValueToString (
645 IN OUT CHAR16
*Buffer
,
651 RETURN_STATUS Status
;
655 BufferSize
= (MAXIMUM_VALUE_CHARACTERS
+ 1) * sizeof (CHAR16
);
657 BufferSize
= (Width
+ 1) * sizeof (CHAR16
);
660 Status
= mPrint2SProtocol
->UnicodeValueToStringS (Buffer
, BufferSize
, Flags
, Value
, Width
);
661 if (RETURN_ERROR (Status
)) {
665 return StrnLenS (Buffer
, BufferSize
/ sizeof (CHAR16
));
669 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
670 ASCII format string and a VA_LIST argument list.
672 This function is similar as vsnprintf_s defined in C11.
674 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
676 The ASCII string is produced by parsing the format string specified by FormatString.
677 Arguments are pulled from the variable argument list specified by Marker based on
678 the contents of the format string.
679 The number of ASCII characters in the produced output buffer is returned not including
682 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
683 unmodified and 0 is returned.
684 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
685 unmodified and 0 is returned.
686 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
687 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
688 is unmodified and 0 is returned.
689 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
690 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
691 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
693 If BufferSize is 0, then no output buffer is produced and 0 is returned.
695 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
697 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
698 @param FormatString A Null-terminated ASCII format string.
699 @param Marker VA_LIST marker for the variable argument list.
701 @return The number of ASCII characters in the produced output buffer not including the
708 OUT CHAR8
*StartOfBuffer
,
710 IN CONST CHAR8
*FormatString
,
714 UINT64 BaseListMarker
[256 / sizeof (UINT64
)];
717 Converted
= DxePrintLibPrint2ProtocolVaListToBaseList (
721 (BASE_LIST
)BaseListMarker
,
722 sizeof (BaseListMarker
) - 8
728 return AsciiBSPrint (StartOfBuffer
, BufferSize
, FormatString
, (BASE_LIST
)BaseListMarker
);
732 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
733 ASCII format string and a BASE_LIST argument list.
735 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
737 The ASCII string is produced by parsing the format string specified by FormatString.
738 Arguments are pulled from the variable argument list specified by Marker based on
739 the contents of the format string.
740 The number of ASCII characters in the produced output buffer is returned not including
743 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
744 unmodified and 0 is returned.
745 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
746 unmodified and 0 is returned.
747 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
748 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
749 is unmodified and 0 is returned.
750 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
751 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
752 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
754 If BufferSize is 0, then no output buffer is produced and 0 is returned.
756 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
758 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
759 @param FormatString A Null-terminated ASCII format string.
760 @param Marker BASE_LIST marker for the variable argument list.
762 @return The number of ASCII characters in the produced output buffer not including the
769 OUT CHAR8
*StartOfBuffer
,
771 IN CONST CHAR8
*FormatString
,
775 return mPrint2SProtocol
->AsciiBSPrint (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
779 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
780 ASCII format string and variable argument list.
782 This function is similar as snprintf_s defined in C11.
784 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
786 The ASCII string is produced by parsing the format string specified by FormatString.
787 Arguments are pulled from the variable argument list based on the contents of the
789 The number of ASCII characters in the produced output buffer is returned not including
792 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
793 unmodified and 0 is returned.
794 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
795 unmodified and 0 is returned.
796 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
797 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
798 is unmodified and 0 is returned.
799 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
800 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
801 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
803 If BufferSize is 0, then no output buffer is produced and 0 is returned.
805 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
807 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
808 @param FormatString A Null-terminated ASCII format string.
809 @param ... Variable argument list whose contents are accessed based on the
810 format string specified by FormatString.
812 @return The number of ASCII characters in the produced output buffer not including the
819 OUT CHAR8
*StartOfBuffer
,
821 IN CONST CHAR8
*FormatString
,
826 UINTN NumberOfPrinted
;
828 VA_START (Marker
, FormatString
);
829 NumberOfPrinted
= AsciiVSPrint (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
831 return NumberOfPrinted
;
835 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
836 Unicode format string and a VA_LIST argument list.
838 This function is similar as vsnprintf_s defined in C11.
840 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
842 The ASCII string is produced by parsing the format string specified by FormatString.
843 Arguments are pulled from the variable argument list specified by Marker based on
844 the contents of the format string.
845 The number of ASCII characters in the produced output buffer is returned not including
848 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
850 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
851 unmodified and 0 is returned.
852 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
853 unmodified and 0 is returned.
854 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
855 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
856 is unmodified and 0 is returned.
857 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
858 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
859 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
861 If BufferSize is 0, then no output buffer is produced and 0 is returned.
863 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
865 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
866 @param FormatString A Null-terminated Unicode format string.
867 @param Marker VA_LIST marker for the variable argument list.
869 @return The number of ASCII characters in the produced output buffer not including the
875 AsciiVSPrintUnicodeFormat (
876 OUT CHAR8
*StartOfBuffer
,
878 IN CONST CHAR16
*FormatString
,
882 UINT64 BaseListMarker
[256 / sizeof (UINT64
)];
885 ASSERT_UNICODE_BUFFER (FormatString
);
887 Converted
= DxePrintLibPrint2ProtocolVaListToBaseList (
889 (CHAR8
*)FormatString
,
891 (BASE_LIST
)BaseListMarker
,
892 sizeof (BaseListMarker
) - 8
898 return AsciiBSPrintUnicodeFormat (StartOfBuffer
, BufferSize
, FormatString
, (BASE_LIST
)BaseListMarker
);
902 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
903 Unicode format string and a BASE_LIST argument list.
905 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
907 The ASCII string is produced by parsing the format string specified by FormatString.
908 Arguments are pulled from the variable argument list specified by Marker based on
909 the contents of the format string.
910 The number of ASCII characters in the produced output buffer is returned not including
913 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
915 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
916 unmodified and 0 is returned.
917 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
918 unmodified and 0 is returned.
919 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
920 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
921 is unmodified and 0 is returned.
922 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
923 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
924 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
926 If BufferSize is 0, then no output buffer is produced and 0 is returned.
928 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
930 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
931 @param FormatString A Null-terminated Unicode format string.
932 @param Marker BASE_LIST marker for the variable argument list.
934 @return The number of ASCII characters in the produced output buffer not including the
940 AsciiBSPrintUnicodeFormat (
941 OUT CHAR8
*StartOfBuffer
,
943 IN CONST CHAR16
*FormatString
,
947 ASSERT_UNICODE_BUFFER (FormatString
);
948 return mPrint2SProtocol
->AsciiBSPrintUnicodeFormat (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
952 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
953 Unicode format string and variable argument list.
955 This function is similar as snprintf_s defined in C11.
957 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
959 The ASCII string is produced by parsing the format string specified by FormatString.
960 Arguments are pulled from the variable argument list based on the contents of the
962 The number of ASCII characters in the produced output buffer is returned not including
965 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
967 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
968 unmodified and 0 is returned.
969 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
970 unmodified and 0 is returned.
971 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
972 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
973 is unmodified and 0 is returned.
974 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
975 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
976 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
978 If BufferSize is 0, then no output buffer is produced and 0 is returned.
980 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
982 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
983 @param FormatString A Null-terminated Unicode format string.
984 @param ... Variable argument list whose contents are accessed based on the
985 format string specified by FormatString.
987 @return The number of ASCII characters in the produced output buffer not including the
993 AsciiSPrintUnicodeFormat (
994 OUT CHAR8
*StartOfBuffer
,
996 IN CONST CHAR16
*FormatString
,
1001 UINTN NumberOfPrinted
;
1003 VA_START (Marker
, FormatString
);
1004 NumberOfPrinted
= AsciiVSPrintUnicodeFormat (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
1006 return NumberOfPrinted
;
1011 Converts a decimal value to a Null-terminated ASCII string.
1013 Converts the decimal number specified by Value to a Null-terminated ASCII string
1014 specified by Buffer containing at most Width characters. No padding of spaces
1016 If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed.
1017 The number of ASCII characters in Buffer is returned not including the Null-terminator.
1018 If the conversion contains more than Width characters, then only the first Width
1019 characters are returned, and the total number of characters required to perform
1020 the conversion is returned.
1021 Additional conversion parameters are specified in Flags.
1022 The Flags bit LEFT_JUSTIFY is always ignored.
1023 All conversions are left justified in Buffer.
1024 If Width is 0, PREFIX_ZERO is ignored in Flags.
1025 If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas
1026 are inserted every 3rd digit starting from the right.
1027 If RADIX_HEX is set in Flags, then the output buffer will be
1028 formatted in hexadecimal format.
1029 If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in Buffer is a '-'.
1030 If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored,
1031 then Buffer is padded with '0' characters so the combination of the optional '-'
1032 sign character, '0' characters, digit characters for Value, and the Null-terminator
1033 add up to Width characters.
1035 If Buffer is NULL, then ASSERT().
1036 If unsupported bits are set in Flags, then ASSERT().
1037 If both COMMA_TYPE and RADIX_HEX are set in Flags, then ASSERT().
1038 If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT()
1040 @param Buffer Pointer to the output buffer for the produced Null-terminated
1042 @param Flags The bitmask of flags that specify left justification, zero pad, and commas.
1043 @param Value The 64-bit signed value to convert to a string.
1044 @param Width The maximum number of ASCII characters to place in Buffer, not including
1045 the Null-terminator.
1047 @return The number of ASCII characters in Buffer not including the Null-terminator.
1052 AsciiValueToString (
1059 RETURN_STATUS Status
;
1063 BufferSize
= (MAXIMUM_VALUE_CHARACTERS
+ 1) * sizeof (CHAR8
);
1065 BufferSize
= (Width
+ 1) * sizeof (CHAR8
);
1068 Status
= mPrint2SProtocol
->AsciiValueToStringS (Buffer
, BufferSize
, Flags
, Value
, Width
);
1069 if (RETURN_ERROR (Status
)) {
1073 return AsciiStrnLenS (Buffer
, BufferSize
/ sizeof (CHAR8
));
1076 #define PREFIX_SIGN BIT1
1077 #define PREFIX_BLANK BIT2
1078 #define LONG_TYPE BIT4
1079 #define OUTPUT_UNICODE BIT6
1080 #define FORMAT_UNICODE BIT8
1081 #define PAD_TO_WIDTH BIT9
1082 #define ARGUMENT_UNICODE BIT10
1083 #define PRECISION BIT11
1084 #define ARGUMENT_REVERSED BIT12
1085 #define COUNT_ONLY_NO_PRINT BIT13
1086 #define UNSIGNED_TYPE BIT14
1089 // Record date and time information
1105 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mHexStr
[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
1108 Internal function that convert a number to a string in Buffer.
1110 Print worker function that converts a decimal or hexadecimal number to an ASCII string in Buffer.
1112 @param Buffer Location to place the ASCII string of Value.
1113 @param Value The value to convert to a Decimal or Hexadecimal string in Buffer.
1114 @param Radix Radix of the value
1116 @return A pointer to the end of buffer filled with ASCII string.
1120 InternalPrintLibValueToString (
1121 IN OUT CHAR8
*Buffer
,
1129 // Loop to convert one digit at a time in reverse order
1133 Value
= (INT64
)DivU64x32Remainder ((UINT64
)Value
, (UINT32
)Radix
, &Remainder
);
1134 *(++Buffer
) = mHexStr
[Remainder
];
1135 } while (Value
!= 0);
1138 // Return pointer of the end of filled buffer.
1144 Worker function that produces a Null-terminated string in an output buffer
1145 based on a Null-terminated format string and a VA_LIST argument list.
1147 VSPrint function to process format and place the results in Buffer. Since a
1148 VA_LIST is used this routine allows the nesting of Vararg routines. Thus
1149 this is the main print working routine.
1151 If COUNT_ONLY_NO_PRINT is set in Flags, Buffer will not be modified at all.
1153 @param[out] Buffer The character buffer to print the results of the
1154 parsing of Format into.
1155 @param[in] BufferSize The maximum number of characters to put into
1157 @param[in] Flags Initial flags value.
1158 Can only have FORMAT_UNICODE, OUTPUT_UNICODE,
1159 and COUNT_ONLY_NO_PRINT set.
1160 @param[in] Format A Null-terminated format string.
1161 @param[in] VaListMarker VA_LIST style variable argument list consumed by
1163 @param[in] BaseListMarker BASE_LIST style variable argument list consumed
1164 by processing Format.
1166 @return The number of characters printed not including the Null-terminator.
1167 If COUNT_ONLY_NO_PRINT was set returns the same, but without any
1168 modification to Buffer.
1172 InternalPrintLibSPrintMarker (
1174 IN UINTN BufferSize
,
1176 IN CONST CHAR8
*Format
,
1177 IN VA_LIST VaListMarker
, OPTIONAL
1178 IN BASE_LIST BaseListMarker OPTIONAL
1182 Worker function that produces a Null-terminated string in an output buffer
1183 based on a Null-terminated format string and variable argument list.
1185 VSPrint function to process format and place the results in Buffer. Since a
1186 VA_LIST is used this routine allows the nesting of Vararg routines. Thus
1187 this is the main print working routine
1189 @param StartOfBuffer The character buffer to print the results of the parsing
1191 @param BufferSize The maximum number of characters to put into buffer.
1192 Zero means no limit.
1193 @param Flags Initial flags value.
1194 Can only have FORMAT_UNICODE and OUTPUT_UNICODE set
1195 @param FormatString A Null-terminated format string.
1196 @param ... The variable argument list.
1198 @return The number of characters printed.
1203 InternalPrintLibSPrint (
1204 OUT CHAR8
*StartOfBuffer
,
1205 IN UINTN BufferSize
,
1207 IN CONST CHAR8
*FormatString
,
1212 UINTN NumberOfPrinted
;
1214 VA_START (Marker
, FormatString
);
1215 NumberOfPrinted
= InternalPrintLibSPrintMarker (StartOfBuffer
, BufferSize
, Flags
, FormatString
, Marker
, NULL
);
1217 return NumberOfPrinted
;
1220 #define WARNING_STATUS_NUMBER 5
1221 #define ERROR_STATUS_NUMBER 33
1223 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8
* CONST mStatusString
[] = {
1224 "Success", // RETURN_SUCCESS = 0
1225 "Warning Unknown Glyph", // RETURN_WARN_UNKNOWN_GLYPH = 1
1226 "Warning Delete Failure", // RETURN_WARN_DELETE_FAILURE = 2
1227 "Warning Write Failure", // RETURN_WARN_WRITE_FAILURE = 3
1228 "Warning Buffer Too Small", // RETURN_WARN_BUFFER_TOO_SMALL = 4
1229 "Warning Stale Data", // RETURN_WARN_STALE_DATA = 5
1230 "Load Error", // RETURN_LOAD_ERROR = 1 | MAX_BIT
1231 "Invalid Parameter", // RETURN_INVALID_PARAMETER = 2 | MAX_BIT
1232 "Unsupported", // RETURN_UNSUPPORTED = 3 | MAX_BIT
1233 "Bad Buffer Size", // RETURN_BAD_BUFFER_SIZE = 4 | MAX_BIT
1234 "Buffer Too Small", // RETURN_BUFFER_TOO_SMALL, = 5 | MAX_BIT
1235 "Not Ready", // RETURN_NOT_READY = 6 | MAX_BIT
1236 "Device Error", // RETURN_DEVICE_ERROR = 7 | MAX_BIT
1237 "Write Protected", // RETURN_WRITE_PROTECTED = 8 | MAX_BIT
1238 "Out of Resources", // RETURN_OUT_OF_RESOURCES = 9 | MAX_BIT
1239 "Volume Corrupt", // RETURN_VOLUME_CORRUPTED = 10 | MAX_BIT
1240 "Volume Full", // RETURN_VOLUME_FULL = 11 | MAX_BIT
1241 "No Media", // RETURN_NO_MEDIA = 12 | MAX_BIT
1242 "Media changed", // RETURN_MEDIA_CHANGED = 13 | MAX_BIT
1243 "Not Found", // RETURN_NOT_FOUND = 14 | MAX_BIT
1244 "Access Denied", // RETURN_ACCESS_DENIED = 15 | MAX_BIT
1245 "No Response", // RETURN_NO_RESPONSE = 16 | MAX_BIT
1246 "No mapping", // RETURN_NO_MAPPING = 17 | MAX_BIT
1247 "Time out", // RETURN_TIMEOUT = 18 | MAX_BIT
1248 "Not started", // RETURN_NOT_STARTED = 19 | MAX_BIT
1249 "Already started", // RETURN_ALREADY_STARTED = 20 | MAX_BIT
1250 "Aborted", // RETURN_ABORTED = 21 | MAX_BIT
1251 "ICMP Error", // RETURN_ICMP_ERROR = 22 | MAX_BIT
1252 "TFTP Error", // RETURN_TFTP_ERROR = 23 | MAX_BIT
1253 "Protocol Error", // RETURN_PROTOCOL_ERROR = 24 | MAX_BIT
1254 "Incompatible Version", // RETURN_INCOMPATIBLE_VERSION = 25 | MAX_BIT
1255 "Security Violation", // RETURN_SECURITY_VIOLATION = 26 | MAX_BIT
1256 "CRC Error", // RETURN_CRC_ERROR = 27 | MAX_BIT
1257 "End of Media", // RETURN_END_OF_MEDIA = 28 | MAX_BIT
1258 "Reserved (29)", // RESERVED = 29 | MAX_BIT
1259 "Reserved (30)", // RESERVED = 30 | MAX_BIT
1260 "End of File", // RETURN_END_OF_FILE = 31 | MAX_BIT
1261 "Invalid Language", // RETURN_INVALID_LANGUAGE = 32 | MAX_BIT
1262 "Compromised Data" // RETURN_COMPROMISED_DATA = 33 | MAX_BIT
1266 Internal function that places the character into the Buffer.
1268 Internal function that places ASCII or Unicode character into the Buffer.
1270 @param Buffer The buffer to place the Unicode or ASCII string.
1271 @param EndBuffer The end of the input Buffer. No characters will be
1273 @param Length The count of character to be placed into Buffer.
1274 (Negative value indicates no buffer fill.)
1275 @param Character The character to be placed into Buffer.
1276 @param Increment The character increment in Buffer.
1282 InternalPrintLibFillBuffer (
1284 IN CHAR8
*EndBuffer
,
1292 for (Index
= 0; Index
< Length
&& Buffer
< EndBuffer
; Index
++) {
1293 *Buffer
= (CHAR8
) Character
;
1294 if (Increment
!= 1) {
1295 *(Buffer
+ 1) = (CHAR8
)(Character
>> 8);
1297 Buffer
+= Increment
;
1304 Worker function that produces a Null-terminated string in an output buffer
1305 based on a Null-terminated format string and a VA_LIST argument list.
1307 VSPrint function to process format and place the results in Buffer. Since a
1308 VA_LIST is used this routine allows the nesting of Vararg routines. Thus
1309 this is the main print working routine.
1311 If COUNT_ONLY_NO_PRINT is set in Flags, Buffer will not be modified at all.
1313 @param[out] Buffer The character buffer to print the results of the
1314 parsing of Format into.
1315 @param[in] BufferSize The maximum number of characters to put into
1317 @param[in] Flags Initial flags value.
1318 Can only have FORMAT_UNICODE, OUTPUT_UNICODE,
1319 and COUNT_ONLY_NO_PRINT set.
1320 @param[in] Format A Null-terminated format string.
1321 @param[in] VaListMarker VA_LIST style variable argument list consumed by
1323 @param[in] BaseListMarker BASE_LIST style variable argument list consumed
1324 by processing Format.
1326 @return The number of characters printed not including the Null-terminator.
1327 If COUNT_ONLY_NO_PRINT was set returns the same, but without any
1328 modification to Buffer.
1332 InternalPrintLibSPrintMarker (
1334 IN UINTN BufferSize
,
1336 IN CONST CHAR8
*Format
,
1337 IN VA_LIST VaListMarker
, OPTIONAL
1338 IN BASE_LIST BaseListMarker OPTIONAL
1341 CHAR8
*OriginalBuffer
;
1343 CHAR8 ValueBuffer
[MAXIMUM_VALUE_CHARACTERS
];
1344 UINT32 BytesPerOutputCharacter
;
1345 UINTN BytesPerFormatCharacter
;
1347 UINTN FormatCharacter
;
1351 CONST CHAR8
*ArgumentString
;
1357 INTN BytesPerArgumentCharacter
;
1358 UINTN ArgumentCharacter
;
1366 RETURN_STATUS Status
;
1370 UINTN LengthToReturn
;
1373 // If you change this code be sure to match the 2 versions of this function.
1374 // Nearly identical logic is found in the BasePrintLib and
1375 // DxePrintLibPrint2Protocol (both PrintLib instances).
1379 // 1. Buffer shall not be a null pointer when both BufferSize > 0 and
1380 // COUNT_ONLY_NO_PRINT is not set in Flags.
1382 if ((BufferSize
> 0) && ((Flags
& COUNT_ONLY_NO_PRINT
) == 0)) {
1383 SAFE_PRINT_CONSTRAINT_CHECK ((Buffer
!= NULL
), 0);
1387 // 2. Format shall not be a null pointer when BufferSize > 0 or when
1388 // COUNT_ONLY_NO_PRINT is set in Flags.
1390 if ((BufferSize
> 0) || ((Flags
& COUNT_ONLY_NO_PRINT
) != 0)) {
1391 SAFE_PRINT_CONSTRAINT_CHECK ((Format
!= NULL
), 0);
1395 // 3. BufferSize shall not be greater than RSIZE_MAX for Unicode output or
1396 // ASCII_RSIZE_MAX for Ascii output.
1398 if ((Flags
& OUTPUT_UNICODE
) != 0) {
1399 if (RSIZE_MAX
!= 0) {
1400 SAFE_PRINT_CONSTRAINT_CHECK ((BufferSize
<= RSIZE_MAX
), 0);
1402 BytesPerOutputCharacter
= 2;
1404 if (ASCII_RSIZE_MAX
!= 0) {
1405 SAFE_PRINT_CONSTRAINT_CHECK ((BufferSize
<= ASCII_RSIZE_MAX
), 0);
1407 BytesPerOutputCharacter
= 1;
1411 // 4. Format shall not contain more than RSIZE_MAX Unicode characters or
1412 // ASCII_RSIZE_MAX Ascii characters.
1414 if ((Flags
& FORMAT_UNICODE
) != 0) {
1415 if (RSIZE_MAX
!= 0) {
1416 SAFE_PRINT_CONSTRAINT_CHECK ((StrnLenS ((CHAR16
*)Format
, RSIZE_MAX
+ 1) <= RSIZE_MAX
), 0);
1418 BytesPerFormatCharacter
= 2;
1419 FormatMask
= 0xffff;
1421 if (ASCII_RSIZE_MAX
!= 0) {
1422 SAFE_PRINT_CONSTRAINT_CHECK ((AsciiStrnLenS (Format
, ASCII_RSIZE_MAX
+ 1) <= ASCII_RSIZE_MAX
), 0);
1424 BytesPerFormatCharacter
= 1;
1428 if ((Flags
& COUNT_ONLY_NO_PRINT
) != 0) {
1429 if (BufferSize
== 0) {
1434 // We can run without a Buffer for counting only.
1436 if (BufferSize
== 0) {
1443 OriginalBuffer
= NULL
;
1446 // Reserve space for the Null terminator.
1448 if (Buffer
!= NULL
) {
1450 OriginalBuffer
= Buffer
;
1453 // Set the tag for the end of the input Buffer.
1455 EndBuffer
= Buffer
+ BufferSize
* BytesPerOutputCharacter
;
1459 // Get the first character from the format string
1461 FormatCharacter
= ((*Format
& 0xff) | (*(Format
+ 1) << 8)) & FormatMask
;
1464 // Loop until the end of the format string is reached or the output buffer is full
1466 while (FormatCharacter
!= 0) {
1467 if ((Buffer
!= NULL
) && (Buffer
>= EndBuffer
)) {
1471 // Clear all the flag bits except those that may have been passed in
1473 Flags
&= (UINTN
) (OUTPUT_UNICODE
| FORMAT_UNICODE
| COUNT_ONLY_NO_PRINT
);
1476 // Set the default width to zero, and the default precision to 1
1486 switch (FormatCharacter
) {
1489 // Parse Flags and Width
1491 for (Done
= FALSE
; !Done
; ) {
1492 Format
+= BytesPerFormatCharacter
;
1493 FormatCharacter
= ((*Format
& 0xff) | (*(Format
+ 1) << 8)) & FormatMask
;
1494 switch (FormatCharacter
) {
1499 Flags
|= LEFT_JUSTIFY
;
1502 Flags
|= PREFIX_SIGN
;
1505 Flags
|= PREFIX_BLANK
;
1508 Flags
|= COMMA_TYPE
;
1515 if ((Flags
& PRECISION
) == 0) {
1516 Flags
|= PAD_TO_WIDTH
;
1517 if (BaseListMarker
== NULL
) {
1518 Width
= VA_ARG (VaListMarker
, UINTN
);
1520 Width
= BASE_ARG (BaseListMarker
, UINTN
);
1523 if (BaseListMarker
== NULL
) {
1524 Precision
= VA_ARG (VaListMarker
, UINTN
);
1526 Precision
= BASE_ARG (BaseListMarker
, UINTN
);
1531 if ((Flags
& PRECISION
) == 0) {
1532 Flags
|= PREFIX_ZERO
;
1543 for (Count
= 0; ((FormatCharacter
>= '0') && (FormatCharacter
<= '9')); ){
1544 Count
= (Count
* 10) + FormatCharacter
- '0';
1545 Format
+= BytesPerFormatCharacter
;
1546 FormatCharacter
= ((*Format
& 0xff) | (*(Format
+ 1) << 8)) & FormatMask
;
1548 Format
-= BytesPerFormatCharacter
;
1549 if ((Flags
& PRECISION
) == 0) {
1550 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) {
1586 // break skipped on purpose
1589 Flags
|= PREFIX_ZERO
;
1591 // break skipped on purpose
1596 // break skipped on purpose
1599 if ((Flags
& RADIX_HEX
) == 0) {
1600 Flags
&= ~((UINTN
) (PREFIX_SIGN
));
1601 Flags
|= UNSIGNED_TYPE
;
1604 // break skipped on purpose
1607 if ((Flags
& LONG_TYPE
) == 0) {
1609 // 'd', 'u', 'x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".
1610 // This assumption is made so the format string definition is compatible with the ANSI C
1611 // Specification for formatted strings. It is recommended that the Base Types be used
1612 // everywhere, but in this one case, compliance with ANSI C is more important, and
1613 // provides an implementation that is compatible with that largest possible set of CPU
1614 // architectures. This is why the type "int" is used in this one case.
1616 if (BaseListMarker
== NULL
) {
1617 Value
= VA_ARG (VaListMarker
, int);
1619 Value
= BASE_ARG (BaseListMarker
, int);
1622 if (BaseListMarker
== NULL
) {
1623 Value
= VA_ARG (VaListMarker
, INT64
);
1625 Value
= BASE_ARG (BaseListMarker
, INT64
);
1628 if ((Flags
& PREFIX_BLANK
) != 0) {
1631 if ((Flags
& PREFIX_SIGN
) != 0) {
1634 if ((Flags
& COMMA_TYPE
) != 0) {
1637 if ((Flags
& RADIX_HEX
) == 0) {
1640 Flags
&= ~((UINTN
) PREFIX_ZERO
);
1643 if (Value
< 0 && (Flags
& UNSIGNED_TYPE
) == 0) {
1644 Flags
|= PREFIX_SIGN
;
1647 } else if ((Flags
& UNSIGNED_TYPE
) != 0 && (Flags
& LONG_TYPE
) == 0) {
1649 // 'd', 'u', 'x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".
1650 // This assumption is made so the format string definition is compatible with the ANSI C
1651 // Specification for formatted strings. It is recommended that the Base Types be used
1652 // everywhere, but in this one case, compliance with ANSI C is more important, and
1653 // provides an implementation that is compatible with that largest possible set of CPU
1654 // architectures. This is why the type "unsigned int" is used in this one case.
1656 Value
= (unsigned int)Value
;
1661 if ((Flags
& LONG_TYPE
) == 0 && Value
< 0) {
1663 // 'd', 'u', 'x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".
1664 // This assumption is made so the format string definition is compatible with the ANSI C
1665 // Specification for formatted strings. It is recommended that the Base Types be used
1666 // everywhere, but in this one case, compliance with ANSI C is more important, and
1667 // provides an implementation that is compatible with that largest possible set of CPU
1668 // architectures. This is why the type "unsigned int" is used in this one case.
1670 Value
= (unsigned int)Value
;
1674 // Convert Value to a reversed string
1676 Count
= InternalPrintLibValueToString (ValueBuffer
, Value
, Radix
) - ValueBuffer
;
1677 if (Value
== 0 && Precision
== 0) {
1680 ArgumentString
= (CHAR8
*)ValueBuffer
+ Count
;
1684 Digits
= 3 - Digits
;
1686 if (Comma
&& Count
!= 0) {
1687 Count
+= ((Count
- 1) / 3);
1693 Flags
|= ARGUMENT_REVERSED
;
1695 if ((Flags
& PREFIX_ZERO
) != 0) {
1696 if ((Flags
& LEFT_JUSTIFY
) == 0) {
1697 if ((Flags
& PAD_TO_WIDTH
) != 0) {
1698 if ((Flags
& PRECISION
) == 0) {
1708 Flags
|= ARGUMENT_UNICODE
;
1710 // break skipped on purpose
1713 if (BaseListMarker
== NULL
) {
1714 ArgumentString
= VA_ARG (VaListMarker
, CHAR8
*);
1716 ArgumentString
= BASE_ARG (BaseListMarker
, CHAR8
*);
1718 if (ArgumentString
== NULL
) {
1719 Flags
&= (~(UINTN
)ARGUMENT_UNICODE
);
1720 ArgumentString
= "<null string>";
1723 // Set the default precision for string to be zero if not specified.
1725 if ((Flags
& PRECISION
) == 0) {
1731 if (BaseListMarker
== NULL
) {
1732 Character
= VA_ARG (VaListMarker
, UINTN
) & 0xffff;
1734 Character
= BASE_ARG (BaseListMarker
, UINTN
) & 0xffff;
1736 ArgumentString
= (CHAR8
*)&Character
;
1737 Flags
|= ARGUMENT_UNICODE
;
1741 if (BaseListMarker
== NULL
) {
1742 TmpGuid
= VA_ARG (VaListMarker
, GUID
*);
1744 TmpGuid
= BASE_ARG (BaseListMarker
, GUID
*);
1746 if (TmpGuid
== NULL
) {
1747 ArgumentString
= "<null guid>";
1749 GuidData1
= ReadUnaligned32 (&(TmpGuid
->Data1
));
1750 GuidData2
= ReadUnaligned16 (&(TmpGuid
->Data2
));
1751 GuidData3
= ReadUnaligned16 (&(TmpGuid
->Data3
));
1752 InternalPrintLibSPrint (
1754 MAXIMUM_VALUE_CHARACTERS
,
1756 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1769 ArgumentString
= ValueBuffer
;
1774 if (BaseListMarker
== NULL
) {
1775 TmpTime
= VA_ARG (VaListMarker
, TIME
*);
1777 TmpTime
= BASE_ARG (BaseListMarker
, TIME
*);
1779 if (TmpTime
== NULL
) {
1780 ArgumentString
= "<null time>";
1782 InternalPrintLibSPrint (
1784 MAXIMUM_VALUE_CHARACTERS
,
1786 "%02d/%02d/%04d %02d:%02d",
1793 ArgumentString
= ValueBuffer
;
1798 if (BaseListMarker
== NULL
) {
1799 Status
= VA_ARG (VaListMarker
, RETURN_STATUS
);
1801 Status
= BASE_ARG (BaseListMarker
, RETURN_STATUS
);
1803 ArgumentString
= ValueBuffer
;
1804 if (RETURN_ERROR (Status
)) {
1808 Index
= Status
& ~MAX_BIT
;
1809 if (Index
> 0 && Index
<= ERROR_STATUS_NUMBER
) {
1810 ArgumentString
= mStatusString
[Index
+ WARNING_STATUS_NUMBER
];
1814 if (Index
<= WARNING_STATUS_NUMBER
) {
1815 ArgumentString
= mStatusString
[Index
];
1818 if (ArgumentString
== ValueBuffer
) {
1819 InternalPrintLibSPrint ((CHAR8
*) ValueBuffer
, MAXIMUM_VALUE_CHARACTERS
, 0, "%08X", Status
);
1824 Format
+= BytesPerFormatCharacter
;
1825 FormatCharacter
= ((*Format
& 0xff) | (*(Format
+ 1) << 8)) & FormatMask
;
1826 if (FormatCharacter
== '\n') {
1828 // Translate '\r\n' to '\r\n'
1830 ArgumentString
= "\r\n";
1833 // Translate '\r' to '\r'
1835 ArgumentString
= "\r";
1836 Format
-= BytesPerFormatCharacter
;
1842 // Translate '\n' to '\r\n' and '\n\r' to '\r\n'
1844 ArgumentString
= "\r\n";
1845 Format
+= BytesPerFormatCharacter
;
1846 FormatCharacter
= ((*Format
& 0xff) | (*(Format
+ 1) << 8)) & FormatMask
;
1847 if (FormatCharacter
!= '\r') {
1848 Format
-= BytesPerFormatCharacter
;
1855 // if the type is '%' or unknown, then print it to the screen
1857 ArgumentString
= (CHAR8
*)&FormatCharacter
;
1858 Flags
|= ARGUMENT_UNICODE
;
1864 Format
+= BytesPerFormatCharacter
;
1865 FormatCharacter
= ((*Format
& 0xff) | (*(Format
+ 1) << 8)) & FormatMask
;
1866 if (FormatCharacter
== '\n') {
1868 // Translate '\r\n' to '\r\n'
1870 ArgumentString
= "\r\n";
1873 // Translate '\r' to '\r'
1875 ArgumentString
= "\r";
1876 Format
-= BytesPerFormatCharacter
;
1882 // Translate '\n' to '\r\n' and '\n\r' to '\r\n'
1884 ArgumentString
= "\r\n";
1885 Format
+= BytesPerFormatCharacter
;
1886 FormatCharacter
= ((*Format
& 0xff) | (*(Format
+ 1) << 8)) & FormatMask
;
1887 if (FormatCharacter
!= '\r') {
1888 Format
-= BytesPerFormatCharacter
;
1893 ArgumentString
= (CHAR8
*)&FormatCharacter
;
1894 Flags
|= ARGUMENT_UNICODE
;
1899 // Retrieve the ArgumentString attriubutes
1901 if ((Flags
& ARGUMENT_UNICODE
) != 0) {
1902 ArgumentMask
= 0xffff;
1903 BytesPerArgumentCharacter
= 2;
1905 ArgumentMask
= 0xff;
1906 BytesPerArgumentCharacter
= 1;
1908 if ((Flags
& ARGUMENT_REVERSED
) != 0) {
1909 BytesPerArgumentCharacter
= -BytesPerArgumentCharacter
;
1912 // Compute the number of characters in ArgumentString and store it in Count
1913 // ArgumentString is either null-terminated, or it contains Precision characters
1915 for (Count
= 0; Count
< Precision
|| ((Flags
& PRECISION
) == 0); Count
++) {
1916 ArgumentCharacter
= ((ArgumentString
[Count
* BytesPerArgumentCharacter
] & 0xff) | ((ArgumentString
[Count
* BytesPerArgumentCharacter
+ 1]) << 8)) & ArgumentMask
;
1917 if (ArgumentCharacter
== 0) {
1923 if (Precision
< Count
) {
1928 // Pad before the string
1930 if ((Flags
& (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) == (PAD_TO_WIDTH
)) {
1931 LengthToReturn
+= ((Width
- Precision
) * BytesPerOutputCharacter
);
1932 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1933 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, Width
- Precision
, ' ', BytesPerOutputCharacter
);
1939 LengthToReturn
+= (1 * BytesPerOutputCharacter
);
1940 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1941 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, 1, Prefix
, BytesPerOutputCharacter
);
1944 LengthToReturn
+= ((Precision
- Count
) * BytesPerOutputCharacter
);
1945 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1946 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, Precision
- Count
, '0', BytesPerOutputCharacter
);
1949 LengthToReturn
+= ((Precision
- Count
) * BytesPerOutputCharacter
);
1950 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1951 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, Precision
- Count
, ' ', BytesPerOutputCharacter
);
1954 LengthToReturn
+= (1 * BytesPerOutputCharacter
);
1955 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1956 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, 1, Prefix
, BytesPerOutputCharacter
);
1962 // Output the Prefix character if it is present
1970 // Copy the string into the output buffer performing the required type conversions
1972 while (Index
< Count
) {
1973 ArgumentCharacter
= ((*ArgumentString
& 0xff) | (*(ArgumentString
+ 1) << 8)) & ArgumentMask
;
1975 LengthToReturn
+= (1 * BytesPerOutputCharacter
);
1976 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1977 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, 1, ArgumentCharacter
, BytesPerOutputCharacter
);
1979 ArgumentString
+= BytesPerArgumentCharacter
;
1986 if (Index
< Count
) {
1987 LengthToReturn
+= (1 * BytesPerOutputCharacter
);
1988 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1989 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, 1, ',', BytesPerOutputCharacter
);
1997 // Pad after the string
1999 if ((Flags
& (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) == (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) {
2000 LengthToReturn
+= ((Width
- Precision
) * BytesPerOutputCharacter
);
2001 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
2002 Buffer
= InternalPrintLibFillBuffer (Buffer
, EndBuffer
, Width
- Precision
, ' ', BytesPerOutputCharacter
);
2007 // Get the next character from the format string
2009 Format
+= BytesPerFormatCharacter
;
2012 // Get the next character from the format string
2014 FormatCharacter
= ((*Format
& 0xff) | (*(Format
+ 1) << 8)) & FormatMask
;
2017 if ((Flags
& COUNT_ONLY_NO_PRINT
) != 0) {
2018 return (LengthToReturn
/ BytesPerOutputCharacter
);
2021 ASSERT (Buffer
!= NULL
);
2023 // Null terminate the Unicode or ASCII string
2025 InternalPrintLibFillBuffer (Buffer
, EndBuffer
+ BytesPerOutputCharacter
, 1, 0, BytesPerOutputCharacter
);
2027 return ((Buffer
- OriginalBuffer
) / BytesPerOutputCharacter
);
2031 Returns the number of characters that would be produced by if the formatted
2032 output were produced not including the Null-terminator.
2034 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
2036 If FormatString is NULL, then ASSERT() and 0 is returned.
2037 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more
2038 than PcdMaximumUnicodeStringLength Unicode characters not including the
2039 Null-terminator, then ASSERT() and 0 is returned.
2041 @param[in] FormatString A Null-terminated Unicode format string.
2042 @param[in] Marker VA_LIST marker for the variable argument list.
2044 @return The number of characters that would be produced, not including the
2050 IN CONST CHAR16
*FormatString
,
2054 ASSERT_UNICODE_BUFFER (FormatString
);
2055 return InternalPrintLibSPrintMarker (NULL
, 0, FORMAT_UNICODE
| OUTPUT_UNICODE
| COUNT_ONLY_NO_PRINT
, (CHAR8
*)FormatString
, Marker
, NULL
);
2059 Returns the number of characters that would be produced by if the formatted
2060 output were produced not including the Null-terminator.
2062 If FormatString is NULL, then ASSERT() and 0 is returned.
2063 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more
2064 than PcdMaximumAsciiStringLength Ascii characters not including the
2065 Null-terminator, then ASSERT() and 0 is returned.
2067 @param[in] FormatString A Null-terminated ASCII format string.
2068 @param[in] Marker VA_LIST marker for the variable argument list.
2070 @return The number of characters that would be produced, not including the
2075 SPrintLengthAsciiFormat (
2076 IN CONST CHAR8
*FormatString
,
2080 return InternalPrintLibSPrintMarker (NULL
, 0, OUTPUT_UNICODE
| COUNT_ONLY_NO_PRINT
, (CHAR8
*)FormatString
, Marker
, NULL
);