4 Copyright (c) 2006, Intel Corporation<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 Module Name: PrintLib.c
17 #include "PrintLibInternal.h"
22 } STATUS_LOOKUP_TABLE_ENTRY
;
24 static CONST STATUS_LOOKUP_TABLE_ENTRY StatusString
[] = {
25 { RETURN_SUCCESS
, "Success" },
26 { RETURN_LOAD_ERROR
, "Load Error" },
27 { RETURN_INVALID_PARAMETER
, "Invalid Parameter" },
28 { RETURN_UNSUPPORTED
, "Unsupported" },
29 { RETURN_BAD_BUFFER_SIZE
, "Bad Buffer Size" },
30 { RETURN_BUFFER_TOO_SMALL
, "Buffer Too Small" },
31 { RETURN_NOT_READY
, "Not Ready" },
32 { RETURN_DEVICE_ERROR
, "Device Error" },
33 { RETURN_WRITE_PROTECTED
, "Write Protected" },
34 { RETURN_OUT_OF_RESOURCES
, "Out of Resources" },
35 { RETURN_VOLUME_CORRUPTED
, "Volume Corrupt" },
36 { RETURN_VOLUME_FULL
, "Volume Full" },
37 { RETURN_NO_MEDIA
, "No Media" },
38 { RETURN_MEDIA_CHANGED
, "Media changed" },
39 { RETURN_NOT_FOUND
, "Not Found" },
40 { RETURN_ACCESS_DENIED
, "Access Denied" },
41 { RETURN_NO_RESPONSE
, "No Response" },
42 { RETURN_NO_MAPPING
, "No mapping" },
43 { RETURN_TIMEOUT
, "Time out" },
44 { RETURN_NOT_STARTED
, "Not started" },
45 { RETURN_ALREADY_STARTED
, "Already started" },
46 { RETURN_ABORTED
, "Aborted" },
47 { RETURN_ICMP_ERROR
, "ICMP Error" },
48 { RETURN_TFTP_ERROR
, "TFTP Error" },
49 { RETURN_PROTOCOL_ERROR
, "Protocol Error" },
50 { RETURN_WARN_UNKNOWN_GLYPH
, "Warning Unknown Glyph" },
51 { RETURN_WARN_DELETE_FAILURE
, "Warning Delete Failure" },
52 { RETURN_WARN_WRITE_FAILURE
, "Warning Write Failure" },
53 { RETURN_WARN_BUFFER_TOO_SMALL
, "Warning Buffer Too Small" },
59 VSPrint function to process format and place the results in Buffer. Since a
60 VA_LIST is used this rountine allows the nesting of Vararg routines. Thus
61 this is the main print working routine
63 @param StartOfBuffer Unicode buffer to print the results of the parsing of Format into.
65 @param BufferSize Maximum number of characters to put into buffer. Zero means
68 @param Flags Intial flags value. Can only have FORMAT_UNICODE and OUTPUT_UNICODE set
70 @param FormatString Unicode format string see file header for more details.
72 @param Marker Vararg list consumed by processing Format.
74 @return Number of characters printed.
82 IN CONST CHAR8
*Format
,
86 CHAR8
*OriginalBuffer
;
87 CHAR8 ValueBuffer
[MAXIMUM_VALUE_CHARACTERS
];
88 UINTN BytesPerOutputCharacter
;
89 UINTN BytesPerFormatCharacter
;
91 UINTN FormatCharacter
;
95 CHAR8
*ArgumentString
;
101 INTN BytesPerArgumentCharacter
;
102 UINTN ArgumentCharacter
;
110 RETURN_STATUS Status
;
112 OriginalBuffer
= Buffer
;
114 if ((Flags
& OUTPUT_UNICODE
) != 0) {
115 BytesPerOutputCharacter
= 2;
117 BytesPerOutputCharacter
= 1;
119 if ((Flags
& FORMAT_UNICODE
) != 0) {
120 BytesPerFormatCharacter
= 2;
123 BytesPerFormatCharacter
= 1;
128 // Reserve space for the Null terminator.
129 // If BufferSize is 0, this will set BufferSize to the max unsigned value
134 // Get the first character from the format string
136 FormatCharacter
= (*Format
| (*(Format
+ 1) << 8)) & FormatMask
;
139 // Loop until the end of the format string is reached or the output buffer is full
141 while (FormatCharacter
!= 0 && BufferSize
> 0) {
143 // Clear all the flag bits except those that may have been passed in
145 Flags
&= (OUTPUT_UNICODE
| FORMAT_UNICODE
);
148 // Set the default width to zero, and the default precision to 1
158 switch (FormatCharacter
) {
161 // Parse Flags and Width
163 for (Done
= FALSE
; !Done
; ) {
164 Format
+= BytesPerFormatCharacter
;
165 FormatCharacter
= (*Format
| (*(Format
+ 1) << 8)) & FormatMask
;
166 switch (FormatCharacter
) {
171 Flags
|= LEFT_JUSTIFY
;
174 Flags
|= PREFIX_SIGN
;
177 Flags
|= PREFIX_BLANK
;
187 if ((Flags
& PRECISION
) == 0) {
188 Flags
|= PAD_TO_WIDTH
;
189 Width
= VA_ARG (Marker
, UINTN
);
191 Precision
= VA_ARG (Marker
, UINTN
);
195 if ((Flags
& PRECISION
) == 0) {
196 Flags
|= PREFIX_ZERO
;
207 for (Count
= 0; ((FormatCharacter
>= '0') && (FormatCharacter
<= '9')); ){
208 Count
= (Count
* 10) + FormatCharacter
- '0';
209 Format
+= BytesPerFormatCharacter
;
210 FormatCharacter
= (*Format
| (*(Format
+ 1) << 8)) & FormatMask
;
212 Format
-= BytesPerFormatCharacter
;
213 if ((Flags
& PRECISION
) == 0) {
214 Flags
|= PAD_TO_WIDTH
;
227 // Limit the maximum field width to the remaining characters in the output buffer
229 if (Width
> BufferSize
) {
234 // Handle each argument type
236 switch (FormatCharacter
) {
238 Flags
|= PREFIX_ZERO
;
240 // break skiped on purpose
245 // break skiped on purpose
248 if ((Flags
& LONG_TYPE
) == 0) {
249 Value
= (VA_ARG (Marker
, INTN
));
251 Value
= VA_ARG (Marker
, INT64
);
253 if ((Flags
& PREFIX_BLANK
) != 0) {
256 if ((Flags
& PREFIX_SIGN
) != 0) {
259 if ((Flags
& COMMA_TYPE
) != 0) {
262 if ((Flags
& RADIX_HEX
) == 0) {
265 Flags
&= (~PREFIX_ZERO
);
269 Flags
|= PREFIX_SIGN
;
276 if ((Flags
& LONG_TYPE
) == 0 && Value
< 0) {
277 Value
= (UINTN
)Value
;
281 // Convert Value to a reversed string
283 Count
= BasePrintLibValueToString (ValueBuffer
, Value
, Radix
);
284 if (Value
== 0 && Precision
== 0) {
287 ArgumentString
= (CHAR8
*)ValueBuffer
+ Count
;
288 Digits
= 3 - (Count
% 3);
289 if (Comma
&& Count
!= 0) {
290 Count
+= ((Count
- 1) / 3);
295 Flags
|= ARGUMENT_REVERSED
;
297 if ((Flags
& PREFIX_ZERO
) != 0) {
298 if ((Flags
& PAD_TO_WIDTH
) != 0) {
299 if ((Flags
& PRECISION
) == 0) {
308 Flags
|= ARGUMENT_UNICODE
;
310 // break skipped on purpose
313 ArgumentString
= (CHAR8
*)VA_ARG (Marker
, CHAR8
*);
314 if (ArgumentString
== NULL
) {
315 Flags
&= (~ARGUMENT_UNICODE
);
316 ArgumentString
= "<null string>";
321 Character
= VA_ARG (Marker
, UINTN
) & 0xffff;
322 ArgumentString
= (CHAR8
*)&Character
;
323 Flags
|= ARGUMENT_UNICODE
;
327 TmpGuid
= VA_ARG (Marker
, GUID
*);
328 if (TmpGuid
== NULL
) {
329 ArgumentString
= "<null guid>";
335 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
348 ArgumentString
= ValueBuffer
;
353 TmpTime
= VA_ARG (Marker
, TIME
*);
354 if (TmpTime
== NULL
) {
355 ArgumentString
= "<null time>";
361 "%02d/%02d/%04d %02d:%02d",
368 ArgumentString
= ValueBuffer
;
373 Status
= VA_ARG (Marker
, RETURN_STATUS
);
374 ArgumentString
= ValueBuffer
;
375 for (Index
= 0; StatusString
[Index
].String
!= NULL
; Index
++) {
376 if (Status
== StatusString
[Index
].Status
) {
377 ArgumentString
= StatusString
[Index
].String
;
380 if (ArgumentString
== ValueBuffer
) {
381 BasePrintLibSPrint ((CHAR8
*) ValueBuffer
, 0, 0, "%08X", Status
);
388 // if the type is '%' or unknown, then print it to the screen
390 ArgumentString
= (CHAR8
*)&FormatCharacter
;
391 Flags
|= ARGUMENT_UNICODE
;
396 ArgumentString
= "\r\n";
399 ArgumentString
= (CHAR8
*)&FormatCharacter
;
400 Flags
|= ARGUMENT_UNICODE
;
405 // Retrieve the ArgumentString attriubutes
407 if ((Flags
& ARGUMENT_UNICODE
) != 0) {
408 ArgumentMask
= 0xffff;
409 BytesPerArgumentCharacter
= 2;
412 BytesPerArgumentCharacter
= 1;
414 if ((Flags
& ARGUMENT_REVERSED
) != 0) {
415 BytesPerArgumentCharacter
= -BytesPerArgumentCharacter
;
418 // Compute the number of characters in ArgumentString and store it in Count
419 // ArgumentString is either null-terminated, or it contains Precision characters
421 for (Count
= 0; Count
< Precision
|| ((Flags
& PRECISION
) == 0); Count
++) {
422 ArgumentCharacter
= ((ArgumentString
[Count
* BytesPerArgumentCharacter
] & 0xff) | ((ArgumentString
[Count
* BytesPerArgumentCharacter
+ 1]) << 8)) & ArgumentMask
;
423 if (ArgumentCharacter
== 0) {
430 // Limit the length of the string to append to the remaining characters in the output buffer
432 if (Count
> BufferSize
) {
435 if (Precision
< Count
) {
440 // Pad before the string
442 if ((Flags
& (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) == (PAD_TO_WIDTH
)) {
443 Buffer
= BasePrintLibFillBuffer (Buffer
, Width
- Precision
, ' ', BytesPerOutputCharacter
);
448 Buffer
= BasePrintLibFillBuffer (Buffer
, 1, Prefix
, BytesPerOutputCharacter
);
450 Buffer
= BasePrintLibFillBuffer (Buffer
, Precision
- Count
, '0', BytesPerOutputCharacter
);
452 Buffer
= BasePrintLibFillBuffer (Buffer
, Precision
- Count
, ' ', BytesPerOutputCharacter
);
454 Buffer
= BasePrintLibFillBuffer (Buffer
, 1, Prefix
, BytesPerOutputCharacter
);
459 // Output the Prefix character if it is present
467 // Copy the string into the output buffer performing the required type conversions
469 while (Index
< Count
) {
470 ArgumentCharacter
= ((*ArgumentString
& 0xff) | (*(ArgumentString
+ 1) << 8)) & ArgumentMask
;
472 Buffer
= BasePrintLibFillBuffer (Buffer
, 1, ArgumentCharacter
, BytesPerOutputCharacter
);
473 ArgumentString
+= BytesPerArgumentCharacter
;
481 Buffer
= BasePrintLibFillBuffer (Buffer
, 1, ',', BytesPerOutputCharacter
);
488 // Pad after the string
490 if ((Flags
& (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) == (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) {
491 Buffer
= BasePrintLibFillBuffer (Buffer
, Width
- Precision
, ' ', BytesPerOutputCharacter
);
495 // Reduce the number of characters
500 // Get the next character from the format string
502 Format
+= BytesPerFormatCharacter
;
505 // Get the next character from the format string
507 FormatCharacter
= (*Format
| (*(Format
+ 1) << 8)) & FormatMask
;
511 // Null terminate the Unicode or ASCII string
513 Buffer
= BasePrintLibFillBuffer (Buffer
, 1, 0, BytesPerOutputCharacter
);
515 return ((Buffer
- OriginalBuffer
) / BytesPerOutputCharacter
);
520 OUT CHAR8
*StartOfBuffer
,
523 IN CONST CHAR8
*FormatString
,
529 VA_START (Marker
, FormatString
);
530 return BasePrintLibVSPrint (StartOfBuffer
, BufferSize
, Flags
, FormatString
, Marker
);
536 OUT CHAR16
*StartOfBuffer
,
538 IN CONST CHAR16
*FormatString
,
542 return BasePrintLibVSPrint ((CHAR8
*)StartOfBuffer
, BufferSize
>> 1, FORMAT_UNICODE
| OUTPUT_UNICODE
, (CHAR8
*)FormatString
, Marker
);
548 OUT CHAR16
*StartOfBuffer
,
550 IN CONST CHAR16
*FormatString
,
556 VA_START (Marker
, FormatString
);
557 return UnicodeVSPrint (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
562 UnicodeVSPrintAsciiFormat (
563 OUT CHAR16
*StartOfBuffer
,
565 IN CONST CHAR8
*FormatString
,
569 return BasePrintLibVSPrint ((CHAR8
*)StartOfBuffer
, BufferSize
>> 1, OUTPUT_UNICODE
,FormatString
, Marker
);
574 UnicodeSPrintAsciiFormat (
575 OUT CHAR16
*StartOfBuffer
,
577 IN CONST CHAR8
*FormatString
,
583 VA_START (Marker
, FormatString
);
584 return UnicodeVSPrintAsciiFormat (StartOfBuffer
, BufferSize
>> 1, FormatString
, Marker
);
590 OUT CHAR8
*StartOfBuffer
,
592 IN CONST CHAR8
*FormatString
,
596 return BasePrintLibVSPrint (StartOfBuffer
, BufferSize
, 0, FormatString
, Marker
);
602 OUT CHAR8
*StartOfBuffer
,
604 IN CONST CHAR8
*FormatString
,
610 VA_START (Marker
, FormatString
);
611 return AsciiVSPrint (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
616 AsciiVSPrintUnicodeFormat (
617 OUT CHAR8
*StartOfBuffer
,
619 IN CONST CHAR16
*FormatString
,
623 return BasePrintLibVSPrint (StartOfBuffer
, BufferSize
, FORMAT_UNICODE
, (CHAR8
*)FormatString
, Marker
);
628 AsciiSPrintUnicodeFormat (
629 OUT CHAR8
*StartOfBuffer
,
631 IN CONST CHAR16
*FormatString
,
637 VA_START (Marker
, FormatString
);
638 return AsciiVSPrintUnicodeFormat (StartOfBuffer
, BufferSize
, FormatString
, Marker
);