5 Copyright (c) 2004-2006 Intel Corporation. All rights reserved
6 This software and associated documentation (if any) is furnished
7 under a license and may only be used or copied in accordance
8 with the terms of the license. Except as permitted by such
9 license, no part of this software or documentation may be
10 reproduced, stored in a retrieval system, or transmitted in any
11 form or by any means without the express written consent of
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 Module Name: PrintLib.c
21 #include <Common/UefiBaseTypes.h>
22 #include <Library/PrintLib.h>
24 #include "CommonLib.h"
25 #include "PrintLibInternal.h"
30 } STATUS_LOOKUP_TABLE_ENTRY
;
32 static CONST STATUS_LOOKUP_TABLE_ENTRY StatusString
[] = {
33 { RETURN_SUCCESS
, "Success" },
34 { RETURN_LOAD_ERROR
, "Load Error" },
35 { RETURN_INVALID_PARAMETER
, "Invalid Parameter" },
36 { RETURN_UNSUPPORTED
, "Unsupported" },
37 { RETURN_BAD_BUFFER_SIZE
, "Bad Buffer Size" },
38 { RETURN_BUFFER_TOO_SMALL
, "Buffer Too Small" },
39 { RETURN_NOT_READY
, "Not Ready" },
40 { RETURN_DEVICE_ERROR
, "Device Error" },
41 { RETURN_WRITE_PROTECTED
, "Write Protected" },
42 { RETURN_OUT_OF_RESOURCES
, "Out of Resources" },
43 { RETURN_VOLUME_CORRUPTED
, "Volume Corrupt" },
44 { RETURN_VOLUME_FULL
, "Volume Full" },
45 { RETURN_NO_MEDIA
, "No Media" },
46 { RETURN_MEDIA_CHANGED
, "Media changed" },
47 { RETURN_NOT_FOUND
, "Not Found" },
48 { RETURN_ACCESS_DENIED
, "Access Denied" },
49 { RETURN_NO_RESPONSE
, "No Response" },
50 { RETURN_NO_MAPPING
, "No mapping" },
51 { RETURN_TIMEOUT
, "Time out" },
52 { RETURN_NOT_STARTED
, "Not started" },
53 { RETURN_ALREADY_STARTED
, "Already started" },
54 { RETURN_ABORTED
, "Aborted" },
55 { RETURN_ICMP_ERROR
, "ICMP Error" },
56 { RETURN_TFTP_ERROR
, "TFTP Error" },
57 { RETURN_PROTOCOL_ERROR
, "Protocol Error" },
58 { RETURN_WARN_UNKNOWN_GLYPH
, "Warning Unknown Glyph" },
59 { RETURN_WARN_DELETE_FAILURE
, "Warning Delete Failure" },
60 { RETURN_WARN_WRITE_FAILURE
, "Warning Write Failure" },
61 { RETURN_WARN_BUFFER_TOO_SMALL
, "Warning Buffer Too Small" },
67 VSPrint function to process format and place the results in Buffer. Since a
68 VA_LIST is used this rountine allows the nesting of Vararg routines. Thus
69 this is the main print working routine
71 @param StartOfBuffer Unicode buffer to print the results of the parsing of Format into.
73 @param BufferSize Maximum number of characters to put into buffer. Zero means
76 @param Flags Intial flags value. Can only have FORMAT_UNICODE and OUTPUT_UNICODE set
78 @param FormatString Unicode format string see file header for more details.
80 @param Marker Vararg list consumed by processing Format.
82 @return Number of characters printed.
90 IN CONST CHAR8
*Format
,
94 CHAR8
*OriginalBuffer
;
95 CHAR8 ValueBuffer
[MAXIMUM_VALUE_CHARACTERS
];
96 UINTN BytesPerOutputCharacter
;
97 UINTN BytesPerFormatCharacter
;
99 UINTN FormatCharacter
;
103 CHAR8
*ArgumentString
;
109 INTN BytesPerArgumentCharacter
;
110 UINTN ArgumentCharacter
;
118 RETURN_STATUS Status
;
120 OriginalBuffer
= Buffer
;
122 if ((Flags
& OUTPUT_UNICODE
) != 0) {
123 BytesPerOutputCharacter
= 2;
125 BytesPerOutputCharacter
= 1;
127 if ((Flags
& FORMAT_UNICODE
) != 0) {
128 BytesPerFormatCharacter
= 2;
131 BytesPerFormatCharacter
= 1;
136 // Reserve space for the Null terminator.
137 // If BufferSize is 0, this will set BufferSize to the max unsigned value
142 // Get the first character from the format string
144 FormatCharacter
= (*Format
| (*(Format
+ 1) << 8)) & FormatMask
;
147 // Loop until the end of the format string is reached or the output buffer is full
149 while (FormatCharacter
!= 0 && BufferSize
> 0) {
151 // Clear all the flag bits except those that may have been passed in
153 Flags
&= (OUTPUT_UNICODE
| FORMAT_UNICODE
);
156 // Set the default width to zero, and the default precision to 1
166 switch (FormatCharacter
) {
169 // Parse Flags and Width
171 for (Done
= FALSE
; !Done
; ) {
172 Format
+= BytesPerFormatCharacter
;
173 FormatCharacter
= (*Format
| (*(Format
+ 1) << 8)) & FormatMask
;
174 switch (FormatCharacter
) {
179 Flags
|= LEFT_JUSTIFY
;
182 Flags
|= PREFIX_SIGN
;
185 Flags
|= PREFIX_BLANK
;
195 if ((Flags
& PRECISION
) == 0) {
196 Flags
|= PAD_TO_WIDTH
;
197 Width
= VA_ARG (Marker
, UINTN
);
199 Precision
= VA_ARG (Marker
, UINTN
);
203 if ((Flags
& PRECISION
) == 0) {
204 Flags
|= PREFIX_ZERO
;
215 for (Count
= 0; ((FormatCharacter
>= '0') && (FormatCharacter
<= '9')); ){
216 Count
= (Count
* 10) + FormatCharacter
- '0';
217 Format
+= BytesPerFormatCharacter
;
218 FormatCharacter
= (*Format
| (*(Format
+ 1) << 8)) & FormatMask
;
220 Format
-= BytesPerFormatCharacter
;
221 if ((Flags
& PRECISION
) == 0) {
222 Flags
|= PAD_TO_WIDTH
;
235 // Limit the maximum field width to the remaining characters in the output buffer
237 if (Width
> BufferSize
) {
242 // Handle each argument type
244 switch (FormatCharacter
) {
246 Flags
|= PREFIX_ZERO
;
248 // break skiped on purpose
253 // break skiped on purpose
256 if ((Flags
& LONG_TYPE
) == 0) {
257 Value
= (VA_ARG (Marker
, INTN
));
259 Value
= VA_ARG (Marker
, INT64
);
261 if ((Flags
& PREFIX_BLANK
) != 0) {
264 if ((Flags
& PREFIX_SIGN
) != 0) {
267 if ((Flags
& COMMA_TYPE
) != 0) {
270 if ((Flags
& RADIX_HEX
) == 0) {
273 Flags
&= (~PREFIX_ZERO
);
277 Flags
|= PREFIX_SIGN
;
284 if ((Flags
& LONG_TYPE
) == 0 && Value
< 0) {
285 Value
= (UINTN
)Value
;
289 // Convert Value to a reversed string
291 Count
= BasePrintLibValueToString (ValueBuffer
, Value
, Radix
);
292 if (Value
== 0 && Precision
== 0) {
295 ArgumentString
= (CHAR8
*)ValueBuffer
+ Count
;
296 Digits
= 3 - (Count
% 3);
297 if (Comma
&& Count
!= 0) {
298 Count
+= ((Count
- 1) / 3);
303 Flags
|= ARGUMENT_REVERSED
;
305 if ((Flags
& PREFIX_ZERO
) != 0) {
306 if ((Flags
& PAD_TO_WIDTH
) != 0) {
307 if ((Flags
& PRECISION
) == 0) {
316 Flags
|= ARGUMENT_UNICODE
;
318 // break skipped on purpose
321 ArgumentString
= (CHAR8
*)VA_ARG (Marker
, CHAR8
*);
322 if (ArgumentString
== NULL
) {
323 Flags
&= (~ARGUMENT_UNICODE
);
324 ArgumentString
= "<null string>";
329 Character
= VA_ARG (Marker
, UINTN
) & 0xffff;
330 ArgumentString
= (CHAR8
*)&Character
;
331 Flags
|= ARGUMENT_UNICODE
;
335 TmpGuid
= VA_ARG (Marker
, GUID
*);
336 if (TmpGuid
== NULL
) {
337 ArgumentString
= "<null guid>";
343 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
356 ArgumentString
= ValueBuffer
;
361 TmpTime
= VA_ARG (Marker
, TIME
*);
362 if (TmpTime
== NULL
) {
363 ArgumentString
= "<null time>";
369 "%02d/%02d/%04d %02d:%02d",
376 ArgumentString
= ValueBuffer
;
381 Status
= VA_ARG (Marker
, RETURN_STATUS
);
382 ArgumentString
= ValueBuffer
;
383 for (Index
= 0; StatusString
[Index
].String
!= NULL
; Index
++) {
384 if (Status
== StatusString
[Index
].Status
) {
385 ArgumentString
= StatusString
[Index
].String
;
388 if (ArgumentString
== ValueBuffer
) {
389 BasePrintLibSPrint ((CHAR8
*) ValueBuffer
, 0, 0, "%08X", Status
);
396 // if the type is '%' or unknown, then print it to the screen
398 ArgumentString
= (CHAR8
*)&FormatCharacter
;
399 Flags
|= ARGUMENT_UNICODE
;
404 ArgumentString
= "\r\n";
407 ArgumentString
= (CHAR8
*)&FormatCharacter
;
408 Flags
|= ARGUMENT_UNICODE
;
413 // Retrieve the ArgumentString attriubutes
415 if ((Flags
& ARGUMENT_UNICODE
) != 0) {
416 ArgumentMask
= 0xffff;
417 BytesPerArgumentCharacter
= 2;
420 BytesPerArgumentCharacter
= 1;
422 if ((Flags
& ARGUMENT_REVERSED
) != 0) {
423 BytesPerArgumentCharacter
= -BytesPerArgumentCharacter
;
426 // Compute the number of characters in ArgumentString and store it in Count
427 // ArgumentString is either null-terminated, or it contains Precision characters
429 for (Count
= 0; Count
< Precision
|| ((Flags
& PRECISION
) == 0); Count
++) {
430 ArgumentCharacter
= ((ArgumentString
[Count
* BytesPerArgumentCharacter
] & 0xff) | ((ArgumentString
[Count
* BytesPerArgumentCharacter
+ 1]) << 8)) & ArgumentMask
;
431 if (ArgumentCharacter
== 0) {
438 // Limit the length of the string to append to the remaining characters in the output buffer
440 if (Count
> BufferSize
) {
443 if (Precision
< Count
) {
448 // Pad before the string
450 if ((Flags
& (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) == (PAD_TO_WIDTH
)) {
451 Buffer
= BasePrintLibFillBuffer (Buffer
, Width
- Precision
, ' ', BytesPerOutputCharacter
);
456 Buffer
= BasePrintLibFillBuffer (Buffer
, 1, Prefix
, BytesPerOutputCharacter
);
458 Buffer
= BasePrintLibFillBuffer (Buffer
, Precision
- Count
, '0', BytesPerOutputCharacter
);
460 Buffer
= BasePrintLibFillBuffer (Buffer
, Precision
- Count
, ' ', BytesPerOutputCharacter
);
462 Buffer
= BasePrintLibFillBuffer (Buffer
, 1, Prefix
, BytesPerOutputCharacter
);
467 // Output the Prefix character if it is present
475 // Copy the string into the output buffer performing the required type conversions
477 while (Index
< Count
) {
478 ArgumentCharacter
= ((*ArgumentString
& 0xff) | (*(ArgumentString
+ 1) << 8)) & ArgumentMask
;
480 Buffer
= BasePrintLibFillBuffer (Buffer
, 1, ArgumentCharacter
, BytesPerOutputCharacter
);
481 ArgumentString
+= BytesPerArgumentCharacter
;
489 Buffer
= BasePrintLibFillBuffer (Buffer
, 1, ',', BytesPerOutputCharacter
);
496 // Pad after the string
498 if ((Flags
& (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) == (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) {
499 Buffer
= BasePrintLibFillBuffer (Buffer
, Width
- Precision
, ' ', BytesPerOutputCharacter
);
503 // Reduce the number of characters
508 // Get the next character from the format string
510 Format
+= BytesPerFormatCharacter
;
513 // Get the next character from the format string
515 FormatCharacter
= (*Format
| (*(Format
+ 1) << 8)) & FormatMask
;
519 // Null terminate the Unicode or ASCII string
521 Buffer
= BasePrintLibFillBuffer (Buffer
, 1, 0, BytesPerOutputCharacter
);
523 return ((Buffer
- OriginalBuffer
) / BytesPerOutputCharacter
);
528 OUT CHAR8
*StartOfBuffer
,
531 IN CONST CHAR8
*FormatString
,
537 VA_START (Marker
, FormatString
);
538 return BasePrintLibVSPrint (StartOfBuffer
, BufferSize
, Flags
, FormatString
, Marker
);
544 OUT CHAR16
*StartOfBuffer
,
546 IN CONST CHAR16
*FormatString
,
550 return BasePrintLibVSPrint ((CHAR8
*)StartOfBuffer
, BufferSize
>> 1, FORMAT_UNICODE
| OUTPUT_UNICODE
, (CHAR8
*)FormatString
, Marker
);
556 OUT CHAR16
*StartOfBuffer
,
558 IN CONST CHAR16
*FormatString
,
564 VA_START (Marker
, FormatString
);
565 return UnicodeVSPrint (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
570 UnicodeVSPrintAsciiFormat (
571 OUT CHAR16
*StartOfBuffer
,
573 IN CONST CHAR8
*FormatString
,
577 return BasePrintLibVSPrint ((CHAR8
*)StartOfBuffer
, BufferSize
>> 1, OUTPUT_UNICODE
,FormatString
, Marker
);
582 UnicodeSPrintAsciiFormat (
583 OUT CHAR16
*StartOfBuffer
,
585 IN CONST CHAR8
*FormatString
,
591 VA_START (Marker
, FormatString
);
592 return UnicodeVSPrintAsciiFormat (StartOfBuffer
, BufferSize
>> 1, FormatString
, Marker
);
598 OUT CHAR8
*StartOfBuffer
,
600 IN CONST CHAR8
*FormatString
,
604 return BasePrintLibVSPrint (StartOfBuffer
, BufferSize
, 0, FormatString
, Marker
);
610 OUT CHAR8
*StartOfBuffer
,
612 IN CONST CHAR8
*FormatString
,
618 VA_START (Marker
, FormatString
);
619 return AsciiVSPrint (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
624 AsciiVSPrintUnicodeFormat (
625 OUT CHAR8
*StartOfBuffer
,
627 IN CONST CHAR16
*FormatString
,
631 return BasePrintLibVSPrint (StartOfBuffer
, BufferSize
, FORMAT_UNICODE
, (CHAR8
*)FormatString
, Marker
);
636 AsciiSPrintUnicodeFormat (
637 OUT CHAR8
*StartOfBuffer
,
639 IN CONST CHAR16
*FormatString
,
645 VA_START (Marker
, FormatString
);
646 return AsciiVSPrintUnicodeFormat (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
651 UnicodeValueToString (
652 IN OUT CHAR16
*Buffer
,
658 return BasePrintLibConvertValueToString ((CHAR8
*)Buffer
, Flags
, Value
, Width
, 2);
664 IN OUT CHAR8
*Buffer
,
670 return BasePrintLibConvertValueToString ((CHAR8
*)Buffer
, Flags
, Value
, Width
, 1);