3 Copyright (c) 2004-2006 Intel Corporation. All rights reserved
4 This program and the accompanying materials are licensed and made available
5 under the terms and conditions of the BSD License which accompanies this
6 distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
23 #include <Common/UefiBaseTypes.h>
24 #include <Library/PrintLib.h>
26 #include "CommonLib.h"
27 #include "PrintLibInternal.h"
32 } STATUS_LOOKUP_TABLE_ENTRY
;
34 static CONST STATUS_LOOKUP_TABLE_ENTRY StatusString
[] = {
35 { RETURN_SUCCESS
, "Success" },
36 { RETURN_LOAD_ERROR
, "Load Error" },
37 { RETURN_INVALID_PARAMETER
, "Invalid Parameter" },
38 { RETURN_UNSUPPORTED
, "Unsupported" },
39 { RETURN_BAD_BUFFER_SIZE
, "Bad Buffer Size" },
40 { RETURN_BUFFER_TOO_SMALL
, "Buffer Too Small" },
41 { RETURN_NOT_READY
, "Not Ready" },
42 { RETURN_DEVICE_ERROR
, "Device Error" },
43 { RETURN_WRITE_PROTECTED
, "Write Protected" },
44 { RETURN_OUT_OF_RESOURCES
, "Out of Resources" },
45 { RETURN_VOLUME_CORRUPTED
, "Volume Corrupt" },
46 { RETURN_VOLUME_FULL
, "Volume Full" },
47 { RETURN_NO_MEDIA
, "No Media" },
48 { RETURN_MEDIA_CHANGED
, "Media changed" },
49 { RETURN_NOT_FOUND
, "Not Found" },
50 { RETURN_ACCESS_DENIED
, "Access Denied" },
51 { RETURN_NO_RESPONSE
, "No Response" },
52 { RETURN_NO_MAPPING
, "No mapping" },
53 { RETURN_TIMEOUT
, "Time out" },
54 { RETURN_NOT_STARTED
, "Not started" },
55 { RETURN_ALREADY_STARTED
, "Already started" },
56 { RETURN_ABORTED
, "Aborted" },
57 { RETURN_ICMP_ERROR
, "ICMP Error" },
58 { RETURN_TFTP_ERROR
, "TFTP Error" },
59 { RETURN_PROTOCOL_ERROR
, "Protocol Error" },
60 { RETURN_WARN_UNKNOWN_GLYPH
, "Warning Unknown Glyph" },
61 { RETURN_WARN_DELETE_FAILURE
, "Warning Delete Failure" },
62 { RETURN_WARN_WRITE_FAILURE
, "Warning Write Failure" },
63 { RETURN_WARN_BUFFER_TOO_SMALL
, "Warning Buffer Too Small" },
69 VSPrint function to process format and place the results in Buffer. Since a
70 VA_LIST is used this rountine allows the nesting of Vararg routines. Thus
71 this is the main print working routine
73 @param StartOfBuffer Unicode buffer to print the results of the parsing of Format into.
75 @param BufferSize Maximum number of characters to put into buffer. Zero means
78 @param Flags Intial flags value. Can only have FORMAT_UNICODE and OUTPUT_UNICODE set
80 @param FormatString Unicode format string see file header for more details.
82 @param Marker Vararg list consumed by processing Format.
84 @return Number of characters printed.
92 IN CONST CHAR8
*Format
,
96 CHAR8
*OriginalBuffer
;
97 CHAR8 ValueBuffer
[MAXIMUM_VALUE_CHARACTERS
];
98 UINTN BytesPerOutputCharacter
;
99 UINTN BytesPerFormatCharacter
;
101 UINTN FormatCharacter
;
105 CHAR8
*ArgumentString
;
111 INTN BytesPerArgumentCharacter
;
112 UINTN ArgumentCharacter
;
120 RETURN_STATUS Status
;
122 OriginalBuffer
= Buffer
;
124 if ((Flags
& OUTPUT_UNICODE
) != 0) {
125 BytesPerOutputCharacter
= 2;
127 BytesPerOutputCharacter
= 1;
129 if ((Flags
& FORMAT_UNICODE
) != 0) {
130 BytesPerFormatCharacter
= 2;
133 BytesPerFormatCharacter
= 1;
138 // Reserve space for the Null terminator.
139 // If BufferSize is 0, this will set BufferSize to the max unsigned value
144 // Get the first character from the format string
146 FormatCharacter
= (*Format
| (*(Format
+ 1) << 8)) & FormatMask
;
149 // Loop until the end of the format string is reached or the output buffer is full
151 while (FormatCharacter
!= 0 && BufferSize
> 0) {
153 // Clear all the flag bits except those that may have been passed in
155 Flags
&= (OUTPUT_UNICODE
| FORMAT_UNICODE
);
158 // Set the default width to zero, and the default precision to 1
168 switch (FormatCharacter
) {
171 // Parse Flags and Width
173 for (Done
= FALSE
; !Done
; ) {
174 Format
+= BytesPerFormatCharacter
;
175 FormatCharacter
= (*Format
| (*(Format
+ 1) << 8)) & FormatMask
;
176 switch (FormatCharacter
) {
181 Flags
|= LEFT_JUSTIFY
;
184 Flags
|= PREFIX_SIGN
;
187 Flags
|= PREFIX_BLANK
;
197 if ((Flags
& PRECISION
) == 0) {
198 Flags
|= PAD_TO_WIDTH
;
199 Width
= VA_ARG (Marker
, UINTN
);
201 Precision
= VA_ARG (Marker
, UINTN
);
205 if ((Flags
& PRECISION
) == 0) {
206 Flags
|= PREFIX_ZERO
;
217 for (Count
= 0; ((FormatCharacter
>= '0') && (FormatCharacter
<= '9')); ){
218 Count
= (Count
* 10) + FormatCharacter
- '0';
219 Format
+= BytesPerFormatCharacter
;
220 FormatCharacter
= (*Format
| (*(Format
+ 1) << 8)) & FormatMask
;
222 Format
-= BytesPerFormatCharacter
;
223 if ((Flags
& PRECISION
) == 0) {
224 Flags
|= PAD_TO_WIDTH
;
237 // Limit the maximum field width to the remaining characters in the output buffer
239 if (Width
> BufferSize
) {
244 // Handle each argument type
246 switch (FormatCharacter
) {
248 Flags
|= PREFIX_ZERO
;
250 // break skiped on purpose
255 // break skiped on purpose
258 if ((Flags
& LONG_TYPE
) == 0) {
259 Value
= (VA_ARG (Marker
, INTN
));
261 Value
= VA_ARG (Marker
, INT64
);
263 if ((Flags
& PREFIX_BLANK
) != 0) {
266 if ((Flags
& PREFIX_SIGN
) != 0) {
269 if ((Flags
& COMMA_TYPE
) != 0) {
272 if ((Flags
& RADIX_HEX
) == 0) {
275 Flags
&= (~PREFIX_ZERO
);
279 Flags
|= PREFIX_SIGN
;
286 if ((Flags
& LONG_TYPE
) == 0 && Value
< 0) {
287 Value
= (UINTN
)Value
;
291 // Convert Value to a reversed string
293 Count
= BasePrintLibValueToString (ValueBuffer
, Value
, Radix
);
294 if (Value
== 0 && Precision
== 0) {
297 ArgumentString
= (CHAR8
*)ValueBuffer
+ Count
;
298 Digits
= 3 - (Count
% 3);
299 if (Comma
&& Count
!= 0) {
300 Count
+= ((Count
- 1) / 3);
305 Flags
|= ARGUMENT_REVERSED
;
307 if ((Flags
& PREFIX_ZERO
) != 0) {
308 if ((Flags
& PAD_TO_WIDTH
) != 0) {
309 if ((Flags
& PRECISION
) == 0) {
318 Flags
|= ARGUMENT_UNICODE
;
320 // break skipped on purpose
323 ArgumentString
= (CHAR8
*)VA_ARG (Marker
, CHAR8
*);
324 if (ArgumentString
== NULL
) {
325 Flags
&= (~ARGUMENT_UNICODE
);
326 ArgumentString
= "<null string>";
331 Character
= VA_ARG (Marker
, UINTN
) & 0xffff;
332 ArgumentString
= (CHAR8
*)&Character
;
333 Flags
|= ARGUMENT_UNICODE
;
337 TmpGuid
= VA_ARG (Marker
, GUID
*);
338 if (TmpGuid
== NULL
) {
339 ArgumentString
= "<null guid>";
345 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
358 ArgumentString
= ValueBuffer
;
363 TmpTime
= VA_ARG (Marker
, TIME
*);
364 if (TmpTime
== NULL
) {
365 ArgumentString
= "<null time>";
371 "%02d/%02d/%04d %02d:%02d",
378 ArgumentString
= ValueBuffer
;
383 Status
= VA_ARG (Marker
, RETURN_STATUS
);
384 ArgumentString
= ValueBuffer
;
385 for (Index
= 0; StatusString
[Index
].String
!= NULL
; Index
++) {
386 if (Status
== StatusString
[Index
].Status
) {
387 ArgumentString
= StatusString
[Index
].String
;
390 if (ArgumentString
== ValueBuffer
) {
391 BasePrintLibSPrint ((CHAR8
*) ValueBuffer
, 0, 0, "%08X", Status
);
398 // if the type is '%' or unknown, then print it to the screen
400 ArgumentString
= (CHAR8
*)&FormatCharacter
;
401 Flags
|= ARGUMENT_UNICODE
;
406 ArgumentString
= "\n";
410 ArgumentString
= (CHAR8
*)&FormatCharacter
;
411 Flags
|= ARGUMENT_UNICODE
;
416 // Retrieve the ArgumentString attriubutes
418 if ((Flags
& ARGUMENT_UNICODE
) != 0) {
419 ArgumentMask
= 0xffff;
420 BytesPerArgumentCharacter
= 2;
423 BytesPerArgumentCharacter
= 1;
425 if ((Flags
& ARGUMENT_REVERSED
) != 0) {
426 BytesPerArgumentCharacter
= -BytesPerArgumentCharacter
;
429 // Compute the number of characters in ArgumentString and store it in Count
430 // ArgumentString is either null-terminated, or it contains Precision characters
432 for (Count
= 0; Count
< Precision
|| ((Flags
& PRECISION
) == 0); Count
++) {
433 ArgumentCharacter
= ((ArgumentString
[Count
* BytesPerArgumentCharacter
] & 0xff) | ((ArgumentString
[Count
* BytesPerArgumentCharacter
+ 1]) << 8)) & ArgumentMask
;
434 if (ArgumentCharacter
== 0) {
441 // Limit the length of the string to append to the remaining characters in the output buffer
443 if (Count
> BufferSize
) {
446 if (Precision
< Count
) {
451 // Pad before the string
453 if ((Flags
& (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) == (PAD_TO_WIDTH
)) {
454 Buffer
= BasePrintLibFillBuffer (Buffer
, Width
- Precision
, ' ', BytesPerOutputCharacter
);
459 Buffer
= BasePrintLibFillBuffer (Buffer
, 1, Prefix
, BytesPerOutputCharacter
);
461 Buffer
= BasePrintLibFillBuffer (Buffer
, Precision
- Count
, '0', BytesPerOutputCharacter
);
463 Buffer
= BasePrintLibFillBuffer (Buffer
, Precision
- Count
, ' ', BytesPerOutputCharacter
);
465 Buffer
= BasePrintLibFillBuffer (Buffer
, 1, Prefix
, BytesPerOutputCharacter
);
470 // Output the Prefix character if it is present
478 // Copy the string into the output buffer performing the required type conversions
480 while (Index
< Count
) {
481 ArgumentCharacter
= ((*ArgumentString
& 0xff) | (*(ArgumentString
+ 1) << 8)) & ArgumentMask
;
483 Buffer
= BasePrintLibFillBuffer (Buffer
, 1, ArgumentCharacter
, BytesPerOutputCharacter
);
484 ArgumentString
+= BytesPerArgumentCharacter
;
492 Buffer
= BasePrintLibFillBuffer (Buffer
, 1, ',', BytesPerOutputCharacter
);
499 // Pad after the string
501 if ((Flags
& (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) == (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) {
502 Buffer
= BasePrintLibFillBuffer (Buffer
, Width
- Precision
, ' ', BytesPerOutputCharacter
);
506 // Reduce the number of characters
511 // Get the next character from the format string
513 Format
+= BytesPerFormatCharacter
;
516 // Get the next character from the format string
518 FormatCharacter
= (*Format
| (*(Format
+ 1) << 8)) & FormatMask
;
522 // Null terminate the Unicode or ASCII string
524 Buffer
= BasePrintLibFillBuffer (Buffer
, 1, 0, BytesPerOutputCharacter
);
526 return ((Buffer
- OriginalBuffer
) / BytesPerOutputCharacter
);
531 OUT CHAR8
*StartOfBuffer
,
534 IN CONST CHAR8
*FormatString
,
540 VA_START (Marker
, FormatString
);
541 return BasePrintLibVSPrint (StartOfBuffer
, BufferSize
, Flags
, FormatString
, Marker
);
547 OUT CHAR16
*StartOfBuffer
,
549 IN CONST CHAR16
*FormatString
,
553 return BasePrintLibVSPrint ((CHAR8
*)StartOfBuffer
, BufferSize
>> 1, FORMAT_UNICODE
| OUTPUT_UNICODE
, (CHAR8
*)FormatString
, Marker
);
559 OUT CHAR16
*StartOfBuffer
,
561 IN CONST CHAR16
*FormatString
,
567 VA_START (Marker
, FormatString
);
568 return UnicodeVSPrint (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
573 UnicodeVSPrintAsciiFormat (
574 OUT CHAR16
*StartOfBuffer
,
576 IN CONST CHAR8
*FormatString
,
580 return BasePrintLibVSPrint ((CHAR8
*)StartOfBuffer
, BufferSize
>> 1, OUTPUT_UNICODE
,FormatString
, Marker
);
585 UnicodeSPrintAsciiFormat (
586 OUT CHAR16
*StartOfBuffer
,
588 IN CONST CHAR8
*FormatString
,
594 VA_START (Marker
, FormatString
);
595 return UnicodeVSPrintAsciiFormat (StartOfBuffer
, BufferSize
>> 1, FormatString
, Marker
);
601 OUT CHAR8
*StartOfBuffer
,
603 IN CONST CHAR8
*FormatString
,
607 return BasePrintLibVSPrint (StartOfBuffer
, BufferSize
, 0, FormatString
, Marker
);
613 OUT CHAR8
*StartOfBuffer
,
615 IN CONST CHAR8
*FormatString
,
621 VA_START (Marker
, FormatString
);
622 return AsciiVSPrint (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
627 AsciiVSPrintUnicodeFormat (
628 OUT CHAR8
*StartOfBuffer
,
630 IN CONST CHAR16
*FormatString
,
634 return BasePrintLibVSPrint (StartOfBuffer
, BufferSize
, FORMAT_UNICODE
, (CHAR8
*)FormatString
, Marker
);
639 AsciiSPrintUnicodeFormat (
640 OUT CHAR8
*StartOfBuffer
,
642 IN CONST CHAR16
*FormatString
,
648 VA_START (Marker
, FormatString
);
649 return AsciiVSPrintUnicodeFormat (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
654 UnicodeValueToString (
655 IN OUT CHAR16
*Buffer
,
661 return BasePrintLibConvertValueToString ((CHAR8
*)Buffer
, Flags
, Value
, Width
, 2);
667 IN OUT CHAR8
*Buffer
,
673 return BasePrintLibConvertValueToString ((CHAR8
*)Buffer
, Flags
, Value
, Width
, 1);