]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BasePrintLib/PrintLib.c
Fix a bug in print library "%a" should not print anything if the var argument points...
[mirror_edk2.git] / MdePkg / Library / BasePrintLib / PrintLib.c
1 /** @file
2 Print Library.
3
4 Copyright (c) 2006 - 2007, 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
9
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.
12
13 **/
14
15 //
16 // Include common header file for this module.
17 //
18
19
20 #include "PrintLibInternal.h"
21
22 #define WARNING_STATUS_NUMBER 4
23 #define ERROR_STATUS_NUMBER 24
24 #define ASSERT_UNICODE_BUFFER(Buffer) ASSERT ((((UINTN) (Buffer)) & 0x01) == 0)
25
26 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *StatusString [] = {
27 "Success", // RETURN_SUCCESS = 0
28 "Warning Unknown Glyph", // RETURN_WARN_UNKNOWN_GLYPH = 1
29 "Warning Delete Failure", // RETURN_WARN_DELETE_FAILURE = 2
30 "Warning Write Failure", // RETURN_WARN_WRITE_FAILURE = 3
31 "Warning Buffer Too Small", // RETURN_WARN_BUFFER_TOO_SMALL = 4
32 "Load Error", // RETURN_LOAD_ERROR = 1 | MAX_BIT
33 "Invalid Parameter", // RETURN_INVALID_PARAMETER = 2 | MAX_BIT
34 "Unsupported", // RETURN_UNSUPPORTED = 3 | MAX_BIT
35 "Bad Buffer Size", // RETURN_BAD_BUFFER_SIZE = 4 | MAX_BIT
36 "Buffer Too Small", // RETURN_BUFFER_TOO_SMALL, = 5 | MAX_BIT
37 "Not Ready", // RETURN_NOT_READY = 6 | MAX_BIT
38 "Device Error", // RETURN_DEVICE_ERROR = 7 | MAX_BIT
39 "Write Protected", // RETURN_WRITE_PROTECTED = 8 | MAX_BIT
40 "Out of Resources", // RETURN_OUT_OF_RESOURCES = 9 | MAX_BIT
41 "Volume Corrupt", // RETURN_VOLUME_CORRUPTED = 10 | MAX_BIT
42 "Volume Full", // RETURN_VOLUME_FULL = 11 | MAX_BIT
43 "No Media", // RETURN_NO_MEDIA = 12 | MAX_BIT
44 "Media changed", // RETURN_MEDIA_CHANGED = 13 | MAX_BIT
45 "Not Found", // RETURN_NOT_FOUND = 14 | MAX_BIT
46 "Access Denied", // RETURN_ACCESS_DENIED = 15 | MAX_BIT
47 "No Response", // RETURN_NO_RESPONSE = 16 | MAX_BIT
48 "No mapping", // RETURN_NO_MAPPING = 17 | MAX_BIT
49 "Time out", // RETURN_TIMEOUT = 18 | MAX_BIT
50 "Not started", // RETURN_NOT_STARTED = 19 | MAX_BIT
51 "Already started", // RETURN_ALREADY_STARTED = 20 | MAX_BIT
52 "Aborted", // RETURN_ABORTED = 21 | MAX_BIT
53 "ICMP Error", // RETURN_ICMP_ERROR = 22 | MAX_BIT
54 "TFTP Error", // RETURN_TFTP_ERROR = 23 | MAX_BIT
55 "Protocol Error" // RETURN_PROTOCOL_ERROR = 24 | MAX_BIT
56 };
57
58 /**
59 Worker function that produces a Null-terminated string in an output buffer
60 based on a Null-terminated format string and a VA_LIST argument list.
61
62 VSPrint function to process format and place the results in Buffer. Since a
63 VA_LIST is used this rountine allows the nesting of Vararg routines. Thus
64 this is the main print working routine.
65
66 @param Buffer Character buffer to print the results of the parsing
67 of Format into.
68 @param BufferSize Maximum number of characters to put into buffer.
69 @param Flags Intial flags value.
70 Can only have FORMAT_UNICODE and OUTPUT_UNICODE set.
71 @param Format Null-terminated format string.
72 @param Marker Vararg list consumed by processing Format.
73
74 @return Number of characters printed not including the Null-terminator.
75
76 **/
77 UINTN
78 BasePrintLibVSPrint (
79 OUT CHAR8 *Buffer,
80 IN UINTN BufferSize,
81 IN UINTN Flags,
82 IN CONST CHAR8 *Format,
83 IN VA_LIST Marker
84 )
85 {
86 CHAR8 *OriginalBuffer;
87 CHAR8 *EndBuffer;
88 CHAR8 ValueBuffer[MAXIMUM_VALUE_CHARACTERS];
89 UINTN BytesPerOutputCharacter;
90 UINTN BytesPerFormatCharacter;
91 UINTN FormatMask;
92 UINTN FormatCharacter;
93 UINTN Width;
94 UINTN Precision;
95 INT64 Value;
96 CONST CHAR8 *ArgumentString;
97 UINTN Character;
98 GUID *TmpGuid;
99 TIME *TmpTime;
100 UINTN Count;
101 UINTN ArgumentMask;
102 INTN BytesPerArgumentCharacter;
103 UINTN ArgumentCharacter;
104 BOOLEAN Done;
105 UINTN Index;
106 CHAR8 Prefix;
107 BOOLEAN ZeroPad;
108 BOOLEAN Comma;
109 UINTN Digits;
110 UINTN Radix;
111 RETURN_STATUS Status;
112
113 if (BufferSize == 0) {
114 return 0;
115 }
116 ASSERT (Buffer != NULL);
117
118 if ((Flags & OUTPUT_UNICODE) != 0) {
119 BytesPerOutputCharacter = 2;
120 } else {
121 BytesPerOutputCharacter = 1;
122 }
123
124 //
125 // Reserve space for the Null terminator.
126 //
127 BufferSize--;
128 OriginalBuffer = Buffer;
129 //
130 // Set the tag for the end of the input Buffer.
131 //
132 EndBuffer = Buffer + BufferSize * BytesPerOutputCharacter;
133
134 if ((Flags & FORMAT_UNICODE) != 0) {
135 //
136 // Make sure format string cannot contain more than PcdMaximumUnicodeStringLength
137 // Unicode characters if PcdMaximumUnicodeStringLength is not zero.
138 //
139 ASSERT (StrSize ((CHAR16 *) Format) != 0);
140 BytesPerFormatCharacter = 2;
141 FormatMask = 0xffff;
142 } else {
143 //
144 // Make sure format string cannot contain more than PcdMaximumAsciiStringLength
145 // Ascii characters if PcdMaximumAsciiStringLength is not zero.
146 //
147 ASSERT (AsciiStrSize (Format) != 0);
148 BytesPerFormatCharacter = 1;
149 FormatMask = 0xff;
150 }
151
152
153
154 //
155 // Get the first character from the format string
156 //
157 FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;
158
159 //
160 // Loop until the end of the format string is reached or the output buffer is full
161 //
162 while (FormatCharacter != 0 && Buffer < EndBuffer) {
163 //
164 // Clear all the flag bits except those that may have been passed in
165 //
166 Flags &= (OUTPUT_UNICODE | FORMAT_UNICODE);
167
168 //
169 // Set the default width to zero, and the default precision to 1
170 //
171 Width = 0;
172 Precision = 1;
173 Prefix = 0;
174 Comma = FALSE;
175 ZeroPad = FALSE;
176 Count = 0;
177 Digits = 0;
178
179 switch (FormatCharacter) {
180 case '%':
181 //
182 // Parse Flags and Width
183 //
184 for (Done = FALSE; !Done; ) {
185 Format += BytesPerFormatCharacter;
186 FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;
187 switch (FormatCharacter) {
188 case '.':
189 Flags |= PRECISION;
190 break;
191 case '-':
192 Flags |= LEFT_JUSTIFY;
193 break;
194 case '+':
195 Flags |= PREFIX_SIGN;
196 break;
197 case ' ':
198 Flags |= PREFIX_BLANK;
199 break;
200 case ',':
201 Flags |= COMMA_TYPE;
202 break;
203 case 'L':
204 case 'l':
205 Flags |= LONG_TYPE;
206 break;
207 case '*':
208 if ((Flags & PRECISION) == 0) {
209 Flags |= PAD_TO_WIDTH;
210 Width = VA_ARG (Marker, UINTN);
211 } else {
212 Precision = VA_ARG (Marker, UINTN);
213 }
214 break;
215 case '0':
216 if ((Flags & PRECISION) == 0) {
217 Flags |= PREFIX_ZERO;
218 }
219 case '1':
220 case '2':
221 case '3':
222 case '4':
223 case '5':
224 case '6':
225 case '7':
226 case '8':
227 case '9':
228 for (Count = 0; ((FormatCharacter >= '0') && (FormatCharacter <= '9')); ){
229 Count = (Count * 10) + FormatCharacter - '0';
230 Format += BytesPerFormatCharacter;
231 FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;
232 }
233 Format -= BytesPerFormatCharacter;
234 if ((Flags & PRECISION) == 0) {
235 Flags |= PAD_TO_WIDTH;
236 Width = Count;
237 } else {
238 Precision = Count;
239 }
240 break;
241
242 case '\0':
243 //
244 // Make no output if Format string terminates unexpectedly when
245 // looking up for flag, width, precision and type.
246 //
247 Format -= BytesPerFormatCharacter;
248 Precision = 0;
249 //
250 // break skipped on purpose.
251 //
252 default:
253 Done = TRUE;
254 break;
255 }
256 }
257
258 //
259 // Handle each argument type
260 //
261 switch (FormatCharacter) {
262 case 'p':
263 //
264 // Flag space, +, 0, L & l are invalid for type p.
265 //
266 Flags &= ~(PREFIX_BLANK | PREFIX_SIGN | PREFIX_ZERO | LONG_TYPE);
267 if (sizeof (VOID *) > 4) {
268 Flags |= LONG_TYPE;
269 }
270 case 'X':
271 Flags |= PREFIX_ZERO;
272 //
273 // break skipped on purpose
274 //
275 case 'x':
276 Flags |= RADIX_HEX;
277 //
278 // break skipped on purpose
279 //
280 case 'd':
281 if ((Flags & LONG_TYPE) == 0) {
282 Value = (VA_ARG (Marker, int));
283 } else {
284 Value = VA_ARG (Marker, INT64);
285 }
286 if ((Flags & PREFIX_BLANK) != 0) {
287 Prefix = ' ';
288 }
289 if ((Flags & PREFIX_SIGN) != 0) {
290 Prefix = '+';
291 }
292 if ((Flags & COMMA_TYPE) != 0) {
293 Comma = TRUE;
294 }
295 if ((Flags & RADIX_HEX) == 0) {
296 Radix = 10;
297 if (Comma) {
298 Flags &= (~PREFIX_ZERO);
299 Precision = 1;
300 }
301 if (Value < 0) {
302 Flags |= PREFIX_SIGN;
303 Prefix = '-';
304 Value = -Value;
305 }
306 } else {
307 Radix = 16;
308 Comma = FALSE;
309 if ((Flags & LONG_TYPE) == 0 && Value < 0) {
310 Value = (unsigned int)Value;
311 }
312 }
313 //
314 // Convert Value to a reversed string
315 //
316 Count = BasePrintLibValueToString (ValueBuffer, Value, Radix);
317 if (Value == 0 && Precision == 0) {
318 Count = 0;
319 }
320 ArgumentString = (CHAR8 *)ValueBuffer + Count;
321
322 Digits = Count % 3;
323 if (Digits != 0) {
324 Digits = 3 - Digits;
325 }
326 if (Comma && Count != 0) {
327 Count += ((Count - 1) / 3);
328 }
329 if (Prefix != 0) {
330 Count++;
331 Precision++;
332 }
333 Flags |= ARGUMENT_REVERSED;
334 ZeroPad = TRUE;
335 if ((Flags & PREFIX_ZERO) != 0) {
336 if ((Flags & LEFT_JUSTIFY) == 0) {
337 if ((Flags & PAD_TO_WIDTH) != 0) {
338 if ((Flags & PRECISION) == 0) {
339 Precision = Width;
340 }
341 }
342 }
343 }
344 break;
345
346 case 's':
347 case 'S':
348 Flags |= ARGUMENT_UNICODE;
349 //
350 // break skipped on purpose
351 //
352 case 'a':
353 ArgumentString = (CHAR8 *)VA_ARG (Marker, CHAR8 *);
354 if (ArgumentString == NULL) {
355 Flags &= (~ARGUMENT_UNICODE);
356 ArgumentString = "<null string>";
357 }
358 //
359 // Set the default precision for string to be zero if not specified.
360 //
361 if ((Flags & PRECISION) == 0) {
362 Precision = 0;
363 }
364 break;
365
366 case 'c':
367 Character = VA_ARG (Marker, UINTN) & 0xffff;
368 ArgumentString = (CHAR8 *)&Character;
369 Flags |= ARGUMENT_UNICODE;
370 break;
371
372 case 'g':
373 TmpGuid = VA_ARG (Marker, GUID *);
374 if (TmpGuid == NULL) {
375 ArgumentString = "<null guid>";
376 } else {
377 BasePrintLibSPrint (
378 ValueBuffer,
379 MAXIMUM_VALUE_CHARACTERS,
380 0,
381 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
382 TmpGuid->Data1,
383 TmpGuid->Data2,
384 TmpGuid->Data3,
385 TmpGuid->Data4[0],
386 TmpGuid->Data4[1],
387 TmpGuid->Data4[2],
388 TmpGuid->Data4[3],
389 TmpGuid->Data4[4],
390 TmpGuid->Data4[5],
391 TmpGuid->Data4[6],
392 TmpGuid->Data4[7]
393 );
394 ArgumentString = ValueBuffer;
395 }
396 break;
397
398 case 't':
399 TmpTime = VA_ARG (Marker, TIME *);
400 if (TmpTime == NULL) {
401 ArgumentString = "<null time>";
402 } else {
403 BasePrintLibSPrint (
404 ValueBuffer,
405 MAXIMUM_VALUE_CHARACTERS,
406 0,
407 "%02d/%02d/%04d %02d:%02d",
408 TmpTime->Month,
409 TmpTime->Day,
410 TmpTime->Year,
411 TmpTime->Hour,
412 TmpTime->Minute
413 );
414 ArgumentString = ValueBuffer;
415 }
416 break;
417
418 case 'r':
419 Status = VA_ARG (Marker, RETURN_STATUS);
420 ArgumentString = ValueBuffer;
421 if (RETURN_ERROR (Status)) {
422 //
423 // Clear error bit
424 //
425 Index = Status & ~MAX_BIT;
426 if (Index > 0 && Index <= ERROR_STATUS_NUMBER) {
427 ArgumentString = StatusString [Index + WARNING_STATUS_NUMBER];
428 }
429 } else {
430 Index = Status;
431 if (Index <= WARNING_STATUS_NUMBER) {
432 ArgumentString = StatusString [Index];
433 }
434 }
435 if (ArgumentString == ValueBuffer) {
436 BasePrintLibSPrint ((CHAR8 *) ValueBuffer, MAXIMUM_VALUE_CHARACTERS, 0, "%08X", Status);
437 }
438 break;
439
440 case '\n':
441 ArgumentString = "\n\r";
442 break;
443
444 case '%':
445 default:
446 //
447 // if the type is '%' or unknown, then print it to the screen
448 //
449 ArgumentString = (CHAR8 *)&FormatCharacter;
450 Flags |= ARGUMENT_UNICODE;
451 break;
452 }
453 break;
454
455 case '\n':
456 ArgumentString = "\n\r";
457 break;
458
459 default:
460 ArgumentString = (CHAR8 *)&FormatCharacter;
461 Flags |= ARGUMENT_UNICODE;
462 break;
463 }
464
465 //
466 // Retrieve the ArgumentString attriubutes
467 //
468 if ((Flags & ARGUMENT_UNICODE) != 0) {
469 ArgumentMask = 0xffff;
470 BytesPerArgumentCharacter = 2;
471 } else {
472 ArgumentMask = 0xff;
473 BytesPerArgumentCharacter = 1;
474 }
475 if ((Flags & ARGUMENT_REVERSED) != 0) {
476 BytesPerArgumentCharacter = -BytesPerArgumentCharacter;
477 } else {
478 //
479 // Compute the number of characters in ArgumentString and store it in Count
480 // ArgumentString is either null-terminated, or it contains Precision characters
481 //
482 for (Count = 0; Count < Precision || ((Flags & PRECISION) == 0); Count++) {
483 ArgumentCharacter = ((ArgumentString[Count * BytesPerArgumentCharacter] & 0xff) | ((ArgumentString[Count * BytesPerArgumentCharacter + 1]) << 8)) & ArgumentMask;
484 if (ArgumentCharacter == 0) {
485 break;
486 }
487 }
488 }
489
490 if (Precision < Count) {
491 Precision = Count;
492 }
493
494 //
495 // Pad before the string
496 //
497 if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH)) {
498 Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Width - Precision, ' ', BytesPerOutputCharacter);
499 }
500
501 if (ZeroPad) {
502 if (Prefix != 0) {
503 Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, Prefix, BytesPerOutputCharacter);
504 }
505 Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Precision - Count, '0', BytesPerOutputCharacter);
506 } else {
507 Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Precision - Count, ' ', BytesPerOutputCharacter);
508 if (Prefix != 0) {
509 Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, Prefix, BytesPerOutputCharacter);
510 }
511 }
512
513 //
514 // Output the Prefix character if it is present
515 //
516 Index = 0;
517 if (Prefix != 0) {
518 Index++;
519 }
520
521 //
522 // Copy the string into the output buffer performing the required type conversions
523 //
524 while (Index < Count) {
525 ArgumentCharacter = ((*ArgumentString & 0xff) | (*(ArgumentString + 1) << 8)) & ArgumentMask;
526
527 Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, ArgumentCharacter, BytesPerOutputCharacter);
528 ArgumentString += BytesPerArgumentCharacter;
529 Index++;
530 if (Comma) {
531 Digits++;
532 if (Digits == 3) {
533 Digits = 0;
534 Index++;
535 if (Index < Count) {
536 Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, ',', BytesPerOutputCharacter);
537 }
538 }
539 }
540 }
541
542 //
543 // Pad after the string
544 //
545 if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH | LEFT_JUSTIFY)) {
546 Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Width - Precision, ' ', BytesPerOutputCharacter);
547 }
548
549 //
550 // Get the next character from the format string
551 //
552 Format += BytesPerFormatCharacter;
553
554 //
555 // Get the next character from the format string
556 //
557 FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;
558 }
559
560 //
561 // Null terminate the Unicode or ASCII string
562 //
563 BasePrintLibFillBuffer (Buffer, EndBuffer + BytesPerOutputCharacter, 1, 0, BytesPerOutputCharacter);
564 //
565 // Make sure output buffer cannot contain more than PcdMaximumUnicodeStringLength
566 // Unicode characters if PcdMaximumUnicodeStringLength is not zero.
567 //
568 ASSERT ((((Flags & OUTPUT_UNICODE) == 0)) || (StrSize ((CHAR16 *) OriginalBuffer) != 0));
569 //
570 // Make sure output buffer cannot contain more than PcdMaximumAsciiStringLength
571 // ASCII characters if PcdMaximumAsciiStringLength is not zero.
572 //
573 ASSERT ((((Flags & OUTPUT_UNICODE) != 0)) || (AsciiStrSize (OriginalBuffer) != 0));
574
575 return ((Buffer - OriginalBuffer) / BytesPerOutputCharacter);
576 }
577
578 /**
579 Worker function that produces a Null-terminated string in an output buffer
580 based on a Null-terminated format string and variable argument list.
581
582 VSPrint function to process format and place the results in Buffer. Since a
583 VA_LIST is used this rountine allows the nesting of Vararg routines. Thus
584 this is the main print working routine.
585
586 @param Buffer Character buffer to print the results of the parsing
587 of Format into.
588 @param BufferSize Maximum number of characters to put into buffer.
589 Zero means no limit.
590 @param Flags Intial flags value.
591 Can only have FORMAT_UNICODE and OUTPUT_UNICODE set
592 @param FormatString Null-terminated format string.
593
594 @return Number of characters printed not including the Null-terminator.
595
596 **/
597 UINTN
598 BasePrintLibSPrint (
599 OUT CHAR8 *StartOfBuffer,
600 IN UINTN BufferSize,
601 IN UINTN Flags,
602 IN CONST CHAR8 *FormatString,
603 ...
604 )
605 {
606 VA_LIST Marker;
607
608 VA_START (Marker, FormatString);
609 return BasePrintLibVSPrint (StartOfBuffer, BufferSize, Flags, FormatString, Marker);
610 }
611
612 /**
613 Produces a Null-terminated Unicode string in an output buffer based on
614 a Null-terminated Unicode format string and a VA_LIST argument list
615
616 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
617 and BufferSize.
618 The Unicode string is produced by parsing the format string specified by FormatString.
619 Arguments are pulled from the variable argument list specified by Marker based on the
620 contents of the format string.
621 The number of Unicode characters in the produced output buffer is returned not including
622 the Null-terminator.
623 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.
624
625 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().
626 If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
627 If BufferSize > 1 and FormatString is NULL, then ASSERT().
628 If BufferSize > 1 and FormatString is not aligned on a 16-bit boundary, then ASSERT().
629 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
630 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
631 ASSERT().
632 If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string
633 contains more than PcdMaximumUnicodeStringLength Unicode characters not including the
634 Null-terminator, then ASSERT().
635
636 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
637 Unicode string.
638 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
639 @param FormatString Null-terminated Unicode format string.
640 @param Marker VA_LIST marker for the variable argument list.
641
642 @return The number of Unicode characters in the produced output buffer not including the
643 Null-terminator.
644
645 **/
646 UINTN
647 EFIAPI
648 UnicodeVSPrint (
649 OUT CHAR16 *StartOfBuffer,
650 IN UINTN BufferSize,
651 IN CONST CHAR16 *FormatString,
652 IN VA_LIST Marker
653 )
654 {
655 ASSERT_UNICODE_BUFFER(StartOfBuffer);
656 ASSERT_UNICODE_BUFFER(FormatString);
657 return BasePrintLibVSPrint ((CHAR8 *)StartOfBuffer, BufferSize >> 1, FORMAT_UNICODE | OUTPUT_UNICODE, (CHAR8 *)FormatString, Marker);
658 }
659
660 /**
661 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
662 Unicode format string and variable argument list.
663
664 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
665 and BufferSize.
666 The Unicode string is produced by parsing the format string specified by FormatString.
667 Arguments are pulled from the variable argument list based on the contents of the format string.
668 The number of Unicode characters in the produced output buffer is returned not including
669 the Null-terminator.
670 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.
671
672 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().
673 If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
674 If BufferSize > 1 and FormatString is NULL, then ASSERT().
675 If BufferSize > 1 and FormatString is not aligned on a 16-bit boundary, then ASSERT().
676 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
677 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
678 ASSERT().
679 If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string
680 contains more than PcdMaximumUnicodeStringLength Unicode characters not including the
681 Null-terminator, then ASSERT().
682
683 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
684 Unicode string.
685 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
686 @param FormatString Null-terminated Unicode format string.
687
688 @return The number of Unicode characters in the produced output buffer not including the
689 Null-terminator.
690
691 **/
692 UINTN
693 EFIAPI
694 UnicodeSPrint (
695 OUT CHAR16 *StartOfBuffer,
696 IN UINTN BufferSize,
697 IN CONST CHAR16 *FormatString,
698 ...
699 )
700 {
701 VA_LIST Marker;
702
703 VA_START (Marker, FormatString);
704 return UnicodeVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);
705 }
706
707 /**
708 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
709 ASCII format string and a VA_LIST argument list
710
711 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
712 and BufferSize.
713 The Unicode string is produced by parsing the format string specified by FormatString.
714 Arguments are pulled from the variable argument list specified by Marker based on the
715 contents of the format string.
716 The number of Unicode characters in the produced output buffer is returned not including
717 the Null-terminator.
718 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.
719
720 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().
721 If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
722 If BufferSize > 1 and FormatString is NULL, then ASSERT().
723 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
724 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then
725 ASSERT().
726 If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string
727 contains more than PcdMaximumUnicodeStringLength Unicode characters not including the
728 Null-terminator, then ASSERT().
729
730 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
731 Unicode string.
732 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
733 @param FormatString Null-terminated Unicode format string.
734 @param Marker VA_LIST marker for the variable argument list.
735
736 @return The number of Unicode characters in the produced output buffer not including the
737 Null-terminator.
738
739 **/
740 UINTN
741 EFIAPI
742 UnicodeVSPrintAsciiFormat (
743 OUT CHAR16 *StartOfBuffer,
744 IN UINTN BufferSize,
745 IN CONST CHAR8 *FormatString,
746 IN VA_LIST Marker
747 )
748 {
749 ASSERT_UNICODE_BUFFER(StartOfBuffer);
750 return BasePrintLibVSPrint ((CHAR8 *)StartOfBuffer, BufferSize >> 1, OUTPUT_UNICODE,FormatString, Marker);
751 }
752
753 /**
754 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
755 ASCII format string and variable argument list.
756
757 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
758 and BufferSize.
759 The Unicode string is produced by parsing the format string specified by FormatString.
760 Arguments are pulled from the variable argument list based on the contents of the
761 format string.
762 The number of Unicode characters in the produced output buffer is returned not including
763 the Null-terminator.
764 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.
765
766 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().
767 If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
768 If BufferSize > 1 and FormatString is NULL, then ASSERT().
769 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
770 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then
771 ASSERT().
772 If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string
773 contains more than PcdMaximumUnicodeStringLength Unicode characters not including the
774 Null-terminator, then ASSERT().
775
776 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
777 Unicode string.
778 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
779 @param FormatString Null-terminated Unicode format string.
780
781 @return The number of Unicode characters in the produced output buffer not including the
782 Null-terminator.
783
784 **/
785 UINTN
786 EFIAPI
787 UnicodeSPrintAsciiFormat (
788 OUT CHAR16 *StartOfBuffer,
789 IN UINTN BufferSize,
790 IN CONST CHAR8 *FormatString,
791 ...
792 )
793 {
794 VA_LIST Marker;
795
796 VA_START (Marker, FormatString);
797 return UnicodeVSPrintAsciiFormat (StartOfBuffer, BufferSize, FormatString, Marker);
798 }
799
800 /**
801 Converts a decimal value to a Null-terminated Unicode string.
802
803 Converts the decimal number specified by Value to a Null-terminated Unicode
804 string specified by Buffer containing at most Width characters. No padding of spaces
805 is ever performed. If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed.
806 The number of Unicode characters in Buffer is returned not including the Null-terminator.
807 If the conversion contains more than Width characters, then only the first
808 Width characters are returned, and the total number of characters
809 required to perform the conversion is returned.
810 Additional conversion parameters are specified in Flags.
811
812 The Flags bit LEFT_JUSTIFY is always ignored.
813 All conversions are left justified in Buffer.
814 If Width is 0, PREFIX_ZERO is ignored in Flags.
815 If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas
816 are inserted every 3rd digit starting from the right.
817 If HEX_RADIX is set in Flags, then the output buffer will be
818 formatted in hexadecimal format.
819 If Value is < 0 and HEX_RADIX is not set in Flags, then the fist character in Buffer is a '-'.
820 If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored,
821 then Buffer is padded with '0' characters so the combination of the optional '-'
822 sign character, '0' characters, digit characters for Value, and the Null-terminator
823 add up to Width characters.
824 If both COMMA_TYPE and HEX_RADIX are set in Flags, then ASSERT().
825 If Buffer is NULL, then ASSERT().
826 If Buffer is not aligned on a 16-bit boundary, then ASSERT().
827 If unsupported bits are set in Flags, then ASSERT().
828 If both COMMA_TYPE and HEX_RADIX are set in Flags, then ASSERT().
829 If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT()
830
831 @param Buffer Pointer to the output buffer for the produced Null-terminated
832 Unicode string.
833 @param Flags The bitmask of flags that specify left justification, zero pad, and commas.
834 @param Value The 64-bit signed value to convert to a string.
835 @param Width The maximum number of Unicode characters to place in Buffer, not including
836 the Null-terminator.
837
838 @return The number of Unicode characters in Buffer not including the Null-terminator.
839
840 **/
841 UINTN
842 EFIAPI
843 UnicodeValueToString (
844 IN OUT CHAR16 *Buffer,
845 IN UINTN Flags,
846 IN INT64 Value,
847 IN UINTN Width
848 )
849 {
850 ASSERT_UNICODE_BUFFER(Buffer);
851 return BasePrintLibConvertValueToString ((CHAR8 *)Buffer, Flags, Value, Width, 2);
852 }
853
854 /**
855 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
856 ASCII format string and a VA_LIST argument list.
857
858 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
859 and BufferSize.
860 The ASCII string is produced by parsing the format string specified by FormatString.
861 Arguments are pulled from the variable argument list specified by Marker based on
862 the contents of the format string.
863 The number of ASCII characters in the produced output buffer is returned not including
864 the Null-terminator.
865 If BufferSize is 0, then no output buffer is produced and 0 is returned.
866
867 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT().
868 If BufferSize > 0 and FormatString is NULL, then ASSERT().
869 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
870 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then
871 ASSERT().
872 If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string
873 contains more than PcdMaximumAsciiStringLength ASCII characters not including the
874 Null-terminator, then ASSERT().
875
876 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
877 ASCII string.
878 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
879 @param FormatString Null-terminated Unicode format string.
880 @param Marker VA_LIST marker for the variable argument list.
881
882 @return The number of ASCII characters in the produced output buffer not including the
883 Null-terminator.
884
885 **/
886 UINTN
887 EFIAPI
888 AsciiVSPrint (
889 OUT CHAR8 *StartOfBuffer,
890 IN UINTN BufferSize,
891 IN CONST CHAR8 *FormatString,
892 IN VA_LIST Marker
893 )
894 {
895 return BasePrintLibVSPrint (StartOfBuffer, BufferSize, 0, FormatString, Marker);
896 }
897
898 /**
899 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
900 ASCII format string and variable argument list.
901
902 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
903 and BufferSize.
904 The ASCII string is produced by parsing the format string specified by FormatString.
905 Arguments are pulled from the variable argument list based on the contents of the
906 format string.
907 The number of ASCII characters in the produced output buffer is returned not including
908 the Null-terminator.
909 If BufferSize is 0, then no output buffer is produced and 0 is returned.
910
911 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT().
912 If BufferSize > 0 and FormatString is NULL, then ASSERT().
913 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
914 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then
915 ASSERT().
916 If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string
917 contains more than PcdMaximumAsciiStringLength ASCII characters not including the
918 Null-terminator, then ASSERT().
919
920 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
921 ASCII string.
922 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
923 @param FormatString Null-terminated Unicode format string.
924
925 @return The number of ASCII characters in the produced output buffer not including the
926 Null-terminator.
927
928 **/
929 UINTN
930 EFIAPI
931 AsciiSPrint (
932 OUT CHAR8 *StartOfBuffer,
933 IN UINTN BufferSize,
934 IN CONST CHAR8 *FormatString,
935 ...
936 )
937 {
938 VA_LIST Marker;
939
940 VA_START (Marker, FormatString);
941 return AsciiVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);
942 }
943
944 /**
945 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
946 ASCII format string and a VA_LIST argument list.
947
948 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
949 and BufferSize.
950 The ASCII string is produced by parsing the format string specified by FormatString.
951 Arguments are pulled from the variable argument list specified by Marker based on
952 the contents of the format string.
953 The number of ASCII characters in the produced output buffer is returned not including
954 the Null-terminator.
955 If BufferSize is 0, then no output buffer is produced and 0 is returned.
956
957 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT().
958 If BufferSize > 0 and FormatString is NULL, then ASSERT().
959 If BufferSize > 0 and FormatString is not aligned on a 16-bit boundary, then ASSERT().
960 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
961 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
962 ASSERT().
963 If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string
964 contains more than PcdMaximumAsciiStringLength ASCII characters not including the
965 Null-terminator, then ASSERT().
966
967 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
968 ASCII string.
969 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
970 @param FormatString Null-terminated Unicode format string.
971 @param Marker VA_LIST marker for the variable argument list.
972
973 @return The number of ASCII characters in the produced output buffer not including the
974 Null-terminator.
975
976 **/
977 UINTN
978 EFIAPI
979 AsciiVSPrintUnicodeFormat (
980 OUT CHAR8 *StartOfBuffer,
981 IN UINTN BufferSize,
982 IN CONST CHAR16 *FormatString,
983 IN VA_LIST Marker
984 )
985 {
986 ASSERT_UNICODE_BUFFER (FormatString);
987 return BasePrintLibVSPrint (StartOfBuffer, BufferSize, FORMAT_UNICODE, (CHAR8 *)FormatString, Marker);
988 }
989
990 /**
991 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
992 ASCII format string and variable argument list.
993
994 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
995 and BufferSize.
996 The ASCII string is produced by parsing the format string specified by FormatString.
997 Arguments are pulled from the variable argument list based on the contents of the
998 format string.
999 The number of ASCII characters in the produced output buffer is returned not including
1000 the Null-terminator.
1001 If BufferSize is 0, then no output buffer is produced and 0 is returned.
1002
1003 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT().
1004 If BufferSize > 0 and FormatString is NULL, then ASSERT().
1005 If BufferSize > 0 and FormatString is not aligned on a 16-bit boundary, then ASSERT().
1006 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
1007 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
1008 ASSERT().
1009 If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string
1010 contains more than PcdMaximumAsciiStringLength ASCII characters not including the
1011 Null-terminator, then ASSERT().
1012
1013 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
1014 ASCII string.
1015 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
1016 @param FormatString Null-terminated Unicode format string.
1017
1018 @return The number of ASCII characters in the produced output buffer not including the
1019 Null-terminator.
1020
1021 **/
1022 UINTN
1023 EFIAPI
1024 AsciiSPrintUnicodeFormat (
1025 OUT CHAR8 *StartOfBuffer,
1026 IN UINTN BufferSize,
1027 IN CONST CHAR16 *FormatString,
1028 ...
1029 )
1030 {
1031 VA_LIST Marker;
1032
1033 VA_START (Marker, FormatString);
1034 return AsciiVSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, Marker);
1035 }
1036
1037
1038 /**
1039 Converts a decimal value to a Null-terminated ASCII string.
1040
1041 Converts the decimal number specified by Value to a Null-terminated ASCII string
1042 specified by Buffer containing at most Width characters. No padding of spaces
1043 is ever performed.
1044 If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed.
1045 The number of ASCII characters in Buffer is returned not including the Null-terminator.
1046 If the conversion contains more than Width characters, then only the first Width
1047 characters are returned, and the total number of characters required to perform
1048 the conversion is returned.
1049 Additional conversion parameters are specified in Flags.
1050 The Flags bit LEFT_JUSTIFY is always ignored.
1051 All conversions are left justified in Buffer.
1052 If Width is 0, PREFIX_ZERO is ignored in Flags.
1053 If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas
1054 are inserted every 3rd digit starting from the right.
1055 If HEX_RADIX is set in Flags, then the output buffer will be
1056 formatted in hexadecimal format.
1057 If Value is < 0 and HEX_RADIX is not set in Flags, then the fist character in Buffer is a '-'.
1058 If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored,
1059 then Buffer is padded with '0' characters so the combination of the optional '-'
1060 sign character, '0' characters, digit characters for Value, and the Null-terminator
1061 add up to Width characters.
1062
1063 If Buffer is NULL, then ASSERT().
1064 If unsupported bits are set in Flags, then ASSERT().
1065 If both COMMA_TYPE and HEX_RADIX are set in Flags, then ASSERT().
1066 If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT()
1067
1068 @param Buffer Pointer to the output buffer for the produced Null-terminated
1069 ASCII string.
1070 @param Flags The bitmask of flags that specify left justification, zero pad, and commas.
1071 @param Value The 64-bit signed value to convert to a string.
1072 @param Width The maximum number of ASCII characters to place in Buffer, not including
1073 the Null-terminator.
1074
1075 @return The number of ASCII characters in Buffer not including the Null-terminator.
1076
1077 **/
1078 UINTN
1079 EFIAPI
1080 AsciiValueToString (
1081 IN OUT CHAR8 *Buffer,
1082 IN UINTN Flags,
1083 IN INT64 Value,
1084 IN UINTN Width
1085 )
1086 {
1087 return BasePrintLibConvertValueToString (Buffer, Flags, Value, Width, 1);
1088 }
1089