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
= "\r\n";
409 ArgumentString
= (CHAR8
*)&FormatCharacter
;
410 Flags
|= ARGUMENT_UNICODE
;
415 // Retrieve the ArgumentString attriubutes
417 if ((Flags
& ARGUMENT_UNICODE
) != 0) {
418 ArgumentMask
= 0xffff;
419 BytesPerArgumentCharacter
= 2;
422 BytesPerArgumentCharacter
= 1;
424 if ((Flags
& ARGUMENT_REVERSED
) != 0) {
425 BytesPerArgumentCharacter
= -BytesPerArgumentCharacter
;
428 // Compute the number of characters in ArgumentString and store it in Count
429 // ArgumentString is either null-terminated, or it contains Precision characters
431 for (Count
= 0; Count
< Precision
|| ((Flags
& PRECISION
) == 0); Count
++) {
432 ArgumentCharacter
= ((ArgumentString
[Count
* BytesPerArgumentCharacter
] & 0xff) | ((ArgumentString
[Count
* BytesPerArgumentCharacter
+ 1]) << 8)) & ArgumentMask
;
433 if (ArgumentCharacter
== 0) {
440 // Limit the length of the string to append to the remaining characters in the output buffer
442 if (Count
> BufferSize
) {
445 if (Precision
< Count
) {
450 // Pad before the string
452 if ((Flags
& (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) == (PAD_TO_WIDTH
)) {
453 Buffer
= BasePrintLibFillBuffer (Buffer
, Width
- Precision
, ' ', BytesPerOutputCharacter
);
458 Buffer
= BasePrintLibFillBuffer (Buffer
, 1, Prefix
, BytesPerOutputCharacter
);
460 Buffer
= BasePrintLibFillBuffer (Buffer
, Precision
- Count
, '0', BytesPerOutputCharacter
);
462 Buffer
= BasePrintLibFillBuffer (Buffer
, Precision
- Count
, ' ', BytesPerOutputCharacter
);
464 Buffer
= BasePrintLibFillBuffer (Buffer
, 1, Prefix
, BytesPerOutputCharacter
);
469 // Output the Prefix character if it is present
477 // Copy the string into the output buffer performing the required type conversions
479 while (Index
< Count
) {
480 ArgumentCharacter
= ((*ArgumentString
& 0xff) | (*(ArgumentString
+ 1) << 8)) & ArgumentMask
;
482 Buffer
= BasePrintLibFillBuffer (Buffer
, 1, ArgumentCharacter
, BytesPerOutputCharacter
);
483 ArgumentString
+= BytesPerArgumentCharacter
;
491 Buffer
= BasePrintLibFillBuffer (Buffer
, 1, ',', BytesPerOutputCharacter
);
498 // Pad after the string
500 if ((Flags
& (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) == (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) {
501 Buffer
= BasePrintLibFillBuffer (Buffer
, Width
- Precision
, ' ', BytesPerOutputCharacter
);
505 // Reduce the number of characters
510 // Get the next character from the format string
512 Format
+= BytesPerFormatCharacter
;
515 // Get the next character from the format string
517 FormatCharacter
= (*Format
| (*(Format
+ 1) << 8)) & FormatMask
;
521 // Null terminate the Unicode or ASCII string
523 Buffer
= BasePrintLibFillBuffer (Buffer
, 1, 0, BytesPerOutputCharacter
);
525 return ((Buffer
- OriginalBuffer
) / BytesPerOutputCharacter
);
530 OUT CHAR8
*StartOfBuffer
,
533 IN CONST CHAR8
*FormatString
,
539 VA_START (Marker
, FormatString
);
540 return BasePrintLibVSPrint (StartOfBuffer
, BufferSize
, Flags
, FormatString
, Marker
);
546 OUT CHAR16
*StartOfBuffer
,
548 IN CONST CHAR16
*FormatString
,
552 return BasePrintLibVSPrint ((CHAR8
*)StartOfBuffer
, BufferSize
>> 1, FORMAT_UNICODE
| OUTPUT_UNICODE
, (CHAR8
*)FormatString
, Marker
);
558 OUT CHAR16
*StartOfBuffer
,
560 IN CONST CHAR16
*FormatString
,
566 VA_START (Marker
, FormatString
);
567 return UnicodeVSPrint (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
572 UnicodeVSPrintAsciiFormat (
573 OUT CHAR16
*StartOfBuffer
,
575 IN CONST CHAR8
*FormatString
,
579 return BasePrintLibVSPrint ((CHAR8
*)StartOfBuffer
, BufferSize
>> 1, OUTPUT_UNICODE
,FormatString
, Marker
);
584 UnicodeSPrintAsciiFormat (
585 OUT CHAR16
*StartOfBuffer
,
587 IN CONST CHAR8
*FormatString
,
593 VA_START (Marker
, FormatString
);
594 return UnicodeVSPrintAsciiFormat (StartOfBuffer
, BufferSize
>> 1, FormatString
, Marker
);
600 OUT CHAR8
*StartOfBuffer
,
602 IN CONST CHAR8
*FormatString
,
606 return BasePrintLibVSPrint (StartOfBuffer
, BufferSize
, 0, FormatString
, Marker
);
612 OUT CHAR8
*StartOfBuffer
,
614 IN CONST CHAR8
*FormatString
,
620 VA_START (Marker
, FormatString
);
621 return AsciiVSPrint (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
626 AsciiVSPrintUnicodeFormat (
627 OUT CHAR8
*StartOfBuffer
,
629 IN CONST CHAR16
*FormatString
,
633 return BasePrintLibVSPrint (StartOfBuffer
, BufferSize
, FORMAT_UNICODE
, (CHAR8
*)FormatString
, Marker
);
638 AsciiSPrintUnicodeFormat (
639 OUT CHAR8
*StartOfBuffer
,
641 IN CONST CHAR16
*FormatString
,
647 VA_START (Marker
, FormatString
);
648 return AsciiVSPrintUnicodeFormat (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
653 UnicodeValueToString (
654 IN OUT CHAR16
*Buffer
,
660 return BasePrintLibConvertValueToString ((CHAR8
*)Buffer
, Flags
, Value
, Width
, 2);
666 IN OUT CHAR8
*Buffer
,
672 return BasePrintLibConvertValueToString ((CHAR8
*)Buffer
, Flags
, Value
, Width
, 1);