]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/DxePrintLibPrint2Protocol/PrintLib.c
MdeModulePkg: Add EDK2 Platform Boot Manager Protocol
[mirror_edk2.git] / MdeModulePkg / Library / DxePrintLibPrint2Protocol / PrintLib.c
1 /** @file
2 Instance of Print Library based on gEfiPrint2SProtocolGuid.
3
4 Implement the print library instance by wrap the interface
5 provided in the Print2S protocol. This protocol is defined as the internal
6 protocol related to this implementation, not in the public spec. So, this
7 library instance is only for this code base.
8
9 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
10 SPDX-License-Identifier: BSD-2-Clause-Patent
11
12 **/
13
14 #include <Uefi.h>
15 #include <Base.h>
16 #include <Protocol/Print2.h>
17
18 #include <Library/PrintLib.h>
19
20 #include <Library/BaseLib.h>
21 #include <Library/DebugLib.h>
22 #include <Library/PcdLib.h>
23
24 #define ASSERT_UNICODE_BUFFER(Buffer) ASSERT ((((UINTN) (Buffer)) & 0x01) == 0)
25
26 //
27 // Safe print checks
28 //
29 #define RSIZE_MAX (PcdGet32 (PcdMaximumUnicodeStringLength))
30 #define ASCII_RSIZE_MAX (PcdGet32 (PcdMaximumAsciiStringLength))
31
32 #define SAFE_PRINT_CONSTRAINT_CHECK(Expression, RetVal) \
33 do { \
34 ASSERT (Expression); \
35 if (!(Expression)) { \
36 return RetVal; \
37 } \
38 } while (FALSE)
39
40 EFI_PRINT2S_PROTOCOL *mPrint2SProtocol = NULL;
41
42 /**
43 The constructor function caches the pointer to Print2S protocol.
44
45 The constructor function locates Print2S protocol from protocol database.
46 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
47
48 @param ImageHandle The firmware allocated handle for the EFI image.
49 @param SystemTable A pointer to the EFI System Table.
50
51 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
52
53 **/
54 EFI_STATUS
55 EFIAPI
56 PrintLibConstructor (
57 IN EFI_HANDLE ImageHandle,
58 IN EFI_SYSTEM_TABLE *SystemTable
59 )
60 {
61 EFI_STATUS Status;
62
63 Status = SystemTable->BootServices->LocateProtocol (
64 &gEfiPrint2SProtocolGuid,
65 NULL,
66 (VOID**) &mPrint2SProtocol
67 );
68 ASSERT_EFI_ERROR (Status);
69 ASSERT (mPrint2SProtocol != NULL);
70
71 return Status;
72 }
73
74
75 /**
76 Worker function that converts a VA_LIST to a BASE_LIST based on a Null-terminated
77 format string.
78
79 @param AsciiFormat TRUE if Format is an ASCII string. FALSE if Format is a Unicode string.
80 @param Format Null-terminated format string.
81 @param VaListMarker VA_LIST style variable argument list consumed by processing Format.
82 @param BaseListMarker BASE_LIST style variable argument list consumed by processing Format.
83 @param Size The size, in bytes, of the BaseListMarker buffer.
84
85 @return TRUE The VA_LIST has been converted to BASE_LIST.
86 @return FALSE The VA_LIST has not been converted to BASE_LIST.
87
88 **/
89 BOOLEAN
90 DxePrintLibPrint2ProtocolVaListToBaseList (
91 IN BOOLEAN AsciiFormat,
92 IN CONST CHAR8 *Format,
93 IN VA_LIST VaListMarker,
94 OUT BASE_LIST BaseListMarker,
95 IN UINTN Size
96 )
97 {
98 BASE_LIST BaseListStart;
99 UINTN BytesPerFormatCharacter;
100 UINTN FormatMask;
101 UINTN FormatCharacter;
102 BOOLEAN Long;
103 BOOLEAN Done;
104
105 ASSERT (BaseListMarker != NULL);
106 SAFE_PRINT_CONSTRAINT_CHECK ((Format != NULL), FALSE);
107
108 BaseListStart = BaseListMarker;
109
110 if (AsciiFormat) {
111 if (ASCII_RSIZE_MAX != 0) {
112 SAFE_PRINT_CONSTRAINT_CHECK ((AsciiStrnLenS (Format, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), FALSE);
113 }
114 BytesPerFormatCharacter = 1;
115 FormatMask = 0xff;
116 } else {
117 if (RSIZE_MAX != 0) {
118 SAFE_PRINT_CONSTRAINT_CHECK ((StrnLenS ((CHAR16 *)Format, RSIZE_MAX + 1) <= RSIZE_MAX), FALSE);
119 }
120 BytesPerFormatCharacter = 2;
121 FormatMask = 0xffff;
122 }
123
124 //
125 // Get the first character from the format string
126 //
127 FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;
128
129 while (FormatCharacter != 0) {
130 if (FormatCharacter == '%') {
131 Long = FALSE;
132
133 //
134 // Parse Flags and Width
135 //
136 for (Done = FALSE; !Done; ) {
137 //
138 // Get the next character from the format string
139 //
140 Format += BytesPerFormatCharacter;
141
142 //
143 // Get the next character from the format string
144 //
145 FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;
146
147 switch (FormatCharacter) {
148 case '.':
149 case '-':
150 case '+':
151 case ' ':
152 case ',':
153 case '0':
154 case '1':
155 case '2':
156 case '3':
157 case '4':
158 case '5':
159 case '6':
160 case '7':
161 case '8':
162 case '9':
163 break;
164 case 'L':
165 case 'l':
166 Long = TRUE;
167 break;
168 case '*':
169 BASE_ARG (BaseListMarker, UINTN) = VA_ARG (VaListMarker, UINTN);
170 break;
171 case '\0':
172 //
173 // Make no output if Format string terminates unexpectedly when
174 // looking up for flag, width, precision and type.
175 //
176 Format -= BytesPerFormatCharacter;
177 //
178 // break skipped on purpose.
179 //
180 default:
181 Done = TRUE;
182 break;
183 }
184 }
185
186 //
187 // Handle each argument type
188 //
189 switch (FormatCharacter) {
190 case 'p':
191 if (sizeof (VOID *) > 4) {
192 Long = TRUE;
193 }
194 case 'X':
195 case 'x':
196 case 'u':
197 case 'd':
198 if (Long) {
199 BASE_ARG (BaseListMarker, INT64) = VA_ARG (VaListMarker, INT64);
200 } else {
201 BASE_ARG (BaseListMarker, int) = VA_ARG (VaListMarker, int);
202 }
203 break;
204 case 's':
205 case 'S':
206 case 'a':
207 case 'g':
208 case 't':
209 BASE_ARG (BaseListMarker, VOID *) = VA_ARG (VaListMarker, VOID *);
210 break;
211 case 'c':
212 BASE_ARG (BaseListMarker, UINTN) = VA_ARG (VaListMarker, UINTN);
213 break;
214 case 'r':
215 BASE_ARG (BaseListMarker, RETURN_STATUS) = VA_ARG (VaListMarker, RETURN_STATUS);
216 break;
217 }
218 }
219
220 //
221 // If BASE_LIST is larger than Size, then return FALSE
222 //
223 if (((UINTN)BaseListMarker - (UINTN)BaseListStart) > Size) {
224 DEBUG ((DEBUG_ERROR, "The input variable argument list is too long. Please consider breaking into multiple print calls.\n"));
225 return FALSE;
226 }
227
228 //
229 // Get the next character from the format string
230 //
231 Format += BytesPerFormatCharacter;
232
233 //
234 // Get the next character from the format string
235 //
236 FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;
237 }
238 return TRUE;
239 }
240
241 /**
242 Produces a Null-terminated Unicode string in an output buffer based on
243 a Null-terminated Unicode format string and a VA_LIST argument list.
244
245 This function is similar as vsnprintf_s defined in C11.
246
247 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
248 and BufferSize.
249 The Unicode string is produced by parsing the format string specified by FormatString.
250 Arguments are pulled from the variable argument list specified by Marker based on the
251 contents of the format string.
252 The number of Unicode characters in the produced output buffer is returned not including
253 the Null-terminator.
254
255 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
256 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
257
258 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
259 unmodified and 0 is returned.
260 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
261 unmodified and 0 is returned.
262 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
263 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
264 buffer is unmodified and 0 is returned.
265 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
266 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
267 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
268
269 If BufferSize is 0 or 1, then the output buffer is unmodified and 0 is returned.
270
271 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
272 Unicode string.
273 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
274 @param FormatString A Null-terminated Unicode format string.
275 @param Marker VA_LIST marker for the variable argument list.
276
277 @return The number of Unicode characters in the produced output buffer not including the
278 Null-terminator.
279
280 **/
281 UINTN
282 EFIAPI
283 UnicodeVSPrint (
284 OUT CHAR16 *StartOfBuffer,
285 IN UINTN BufferSize,
286 IN CONST CHAR16 *FormatString,
287 IN VA_LIST Marker
288 )
289 {
290 UINT64 BaseListMarker[256 / sizeof (UINT64)];
291 BOOLEAN Converted;
292
293 ASSERT_UNICODE_BUFFER (StartOfBuffer);
294 ASSERT_UNICODE_BUFFER (FormatString);
295
296 Converted = DxePrintLibPrint2ProtocolVaListToBaseList (
297 FALSE,
298 (CHAR8 *)FormatString,
299 Marker,
300 (BASE_LIST)BaseListMarker,
301 sizeof (BaseListMarker) - 8
302 );
303 if (!Converted) {
304 return 0;
305 }
306
307 return UnicodeBSPrint (StartOfBuffer, BufferSize, FormatString, (BASE_LIST)BaseListMarker);
308 }
309
310 /**
311 Produces a Null-terminated Unicode string in an output buffer based on
312 a Null-terminated Unicode format string and a BASE_LIST argument list.
313
314 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
315 and BufferSize.
316 The Unicode string is produced by parsing the format string specified by FormatString.
317 Arguments are pulled from the variable argument list specified by Marker based on the
318 contents of the format string.
319 The number of Unicode characters in the produced output buffer is returned not including
320 the Null-terminator.
321
322 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
323 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
324
325 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
326 unmodified and 0 is returned.
327 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
328 unmodified and 0 is returned.
329 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
330 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
331 buffer is unmodified and 0 is returned.
332 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
333 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
334 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
335
336 If BufferSize is 0 or 1, then the output buffer is unmodified and 0 is returned.
337
338 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
339 Unicode string.
340 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
341 @param FormatString A Null-terminated Unicode format string.
342 @param Marker BASE_LIST marker for the variable argument list.
343
344 @return The number of Unicode characters in the produced output buffer not including the
345 Null-terminator.
346
347 **/
348 UINTN
349 EFIAPI
350 UnicodeBSPrint (
351 OUT CHAR16 *StartOfBuffer,
352 IN UINTN BufferSize,
353 IN CONST CHAR16 *FormatString,
354 IN BASE_LIST Marker
355 )
356 {
357 ASSERT_UNICODE_BUFFER (StartOfBuffer);
358 ASSERT_UNICODE_BUFFER (FormatString);
359 return mPrint2SProtocol->UnicodeBSPrint (StartOfBuffer, BufferSize, FormatString, Marker);
360 }
361
362 /**
363 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
364 Unicode format string and variable argument list.
365
366 This function is similar as snprintf_s defined in C11.
367
368 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
369 and BufferSize.
370 The Unicode string is produced by parsing the format string specified by FormatString.
371 Arguments are pulled from the variable argument list based on the contents of the format string.
372 The number of Unicode characters in the produced output buffer is returned not including
373 the Null-terminator.
374
375 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
376 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
377
378 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
379 unmodified and 0 is returned.
380 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
381 unmodified and 0 is returned.
382 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
383 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
384 buffer is unmodified and 0 is returned.
385 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
386 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
387 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
388
389 If BufferSize is 0 or 1, then the output buffer is unmodified and 0 is returned.
390
391 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
392 Unicode string.
393 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
394 @param FormatString A Null-terminated Unicode format string.
395 @param ... Variable argument list whose contents are accessed based on the
396 format string specified by FormatString.
397
398 @return The number of Unicode characters in the produced output buffer not including the
399 Null-terminator.
400
401 **/
402 UINTN
403 EFIAPI
404 UnicodeSPrint (
405 OUT CHAR16 *StartOfBuffer,
406 IN UINTN BufferSize,
407 IN CONST CHAR16 *FormatString,
408 ...
409 )
410 {
411 VA_LIST Marker;
412 UINTN NumberOfPrinted;
413
414 VA_START (Marker, FormatString);
415 NumberOfPrinted = UnicodeVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);
416 VA_END (Marker);
417 return NumberOfPrinted;
418 }
419
420 /**
421 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
422 ASCII format string and a VA_LIST argument list.
423
424 This function is similar as vsnprintf_s defined in C11.
425
426 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
427 and BufferSize.
428 The Unicode string is produced by parsing the format string specified by FormatString.
429 Arguments are pulled from the variable argument list specified by Marker based on the
430 contents of the format string.
431 The number of Unicode characters in the produced output buffer is returned not including
432 the Null-terminator.
433
434 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
435
436 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
437 unmodified and 0 is returned.
438 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
439 unmodified and 0 is returned.
440 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
441 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
442 buffer is unmodified and 0 is returned.
443 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
444 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
445 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
446
447 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.
448
449 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
450 Unicode string.
451 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
452 @param FormatString A Null-terminated ASCII format string.
453 @param Marker VA_LIST marker for the variable argument list.
454
455 @return The number of Unicode characters in the produced output buffer not including the
456 Null-terminator.
457
458 **/
459 UINTN
460 EFIAPI
461 UnicodeVSPrintAsciiFormat (
462 OUT CHAR16 *StartOfBuffer,
463 IN UINTN BufferSize,
464 IN CONST CHAR8 *FormatString,
465 IN VA_LIST Marker
466 )
467 {
468 UINT64 BaseListMarker[256 / sizeof (UINT64)];
469 BOOLEAN Converted;
470
471 ASSERT_UNICODE_BUFFER (StartOfBuffer);
472
473 Converted = DxePrintLibPrint2ProtocolVaListToBaseList (
474 TRUE,
475 FormatString,
476 Marker,
477 (BASE_LIST)BaseListMarker,
478 sizeof (BaseListMarker) - 8
479 );
480 if (!Converted) {
481 return 0;
482 }
483
484 return UnicodeBSPrintAsciiFormat (StartOfBuffer, BufferSize, FormatString, (BASE_LIST)BaseListMarker);
485 }
486
487 /**
488 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
489 ASCII format string and a BASE_LIST argument list.
490
491 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
492 and BufferSize.
493 The Unicode string is produced by parsing the format string specified by FormatString.
494 Arguments are pulled from the variable argument list specified by Marker based on the
495 contents of the format string.
496 The number of Unicode characters in the produced output buffer is returned not including
497 the Null-terminator.
498
499 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
500
501 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
502 unmodified and 0 is returned.
503 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
504 unmodified and 0 is returned.
505 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
506 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
507 buffer is unmodified and 0 is returned.
508 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
509 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
510 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
511
512 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.
513
514 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
515 Unicode string.
516 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
517 @param FormatString A Null-terminated ASCII format string.
518 @param Marker BASE_LIST marker for the variable argument list.
519
520 @return The number of Unicode characters in the produced output buffer not including the
521 Null-terminator.
522
523 **/
524 UINTN
525 EFIAPI
526 UnicodeBSPrintAsciiFormat (
527 OUT CHAR16 *StartOfBuffer,
528 IN UINTN BufferSize,
529 IN CONST CHAR8 *FormatString,
530 IN BASE_LIST Marker
531 )
532 {
533 ASSERT_UNICODE_BUFFER (StartOfBuffer);
534 return mPrint2SProtocol->UnicodeBSPrintAsciiFormat (StartOfBuffer, BufferSize, FormatString, Marker);
535 }
536
537 /**
538 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
539 ASCII format string and variable argument list.
540
541 This function is similar as snprintf_s defined in C11.
542
543 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
544 and BufferSize.
545 The Unicode string is produced by parsing the format string specified by FormatString.
546 Arguments are pulled from the variable argument list based on the contents of the
547 format string.
548 The number of Unicode characters in the produced output buffer is returned not including
549 the Null-terminator.
550
551 If StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
552
553 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
554 unmodified and 0 is returned.
555 If BufferSize > 1 and FormatString is NULL, then ASSERT(). Also, the output buffer is
556 unmodified and 0 is returned.
557 If PcdMaximumUnicodeStringLength is not zero, and BufferSize >
558 (PcdMaximumUnicodeStringLength * sizeof (CHAR16) + 1), then ASSERT(). Also, the output
559 buffer is unmodified and 0 is returned.
560 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
561 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
562 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
563
564 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.
565
566 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
567 Unicode string.
568 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
569 @param FormatString A Null-terminated ASCII format string.
570 @param ... Variable argument list whose contents are accessed based on the
571 format string specified by FormatString.
572
573 @return The number of Unicode characters in the produced output buffer not including the
574 Null-terminator.
575
576 **/
577 UINTN
578 EFIAPI
579 UnicodeSPrintAsciiFormat (
580 OUT CHAR16 *StartOfBuffer,
581 IN UINTN BufferSize,
582 IN CONST CHAR8 *FormatString,
583 ...
584 )
585 {
586 VA_LIST Marker;
587 UINTN NumberOfPrinted;
588
589 VA_START (Marker, FormatString);
590 NumberOfPrinted = UnicodeVSPrintAsciiFormat (StartOfBuffer, BufferSize, FormatString, Marker);
591 VA_END (Marker);
592 return NumberOfPrinted;
593 }
594
595 #ifndef DISABLE_NEW_DEPRECATED_INTERFACES
596
597 /**
598 [ATTENTION] This function is deprecated for security reason.
599
600 Converts a decimal value to a Null-terminated Unicode string.
601
602 Converts the decimal number specified by Value to a Null-terminated Unicode
603 string specified by Buffer containing at most Width characters. No padding of spaces
604 is ever performed. If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed.
605 The number of Unicode characters in Buffer is returned not including the Null-terminator.
606 If the conversion contains more than Width characters, then only the first
607 Width characters are returned, and the total number of characters
608 required to perform the conversion is returned.
609 Additional conversion parameters are specified in Flags.
610
611 The Flags bit LEFT_JUSTIFY is always ignored.
612 All conversions are left justified in Buffer.
613 If Width is 0, PREFIX_ZERO is ignored in Flags.
614 If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas
615 are inserted every 3rd digit starting from the right.
616 If RADIX_HEX is set in Flags, then the output buffer will be
617 formatted in hexadecimal format.
618 If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in Buffer is a '-'.
619 If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored,
620 then Buffer is padded with '0' characters so the combination of the optional '-'
621 sign character, '0' characters, digit characters for Value, and the Null-terminator
622 add up to Width characters.
623 If both COMMA_TYPE and RADIX_HEX are set in Flags, then ASSERT().
624 If Buffer is NULL, then ASSERT().
625 If Buffer is not aligned on a 16-bit boundary, then ASSERT().
626 If unsupported bits are set in Flags, then ASSERT().
627 If both COMMA_TYPE and RADIX_HEX are set in Flags, then ASSERT().
628 If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT()
629
630 @param Buffer Pointer to the output buffer for the produced Null-terminated
631 Unicode string.
632 @param Flags The bitmask of flags that specify left justification, zero pad, and commas.
633 @param Value The 64-bit signed value to convert to a string.
634 @param Width The maximum number of Unicode characters to place in Buffer, not including
635 the Null-terminator.
636
637 @return The number of Unicode characters in Buffer not including the Null-terminator.
638
639 **/
640 UINTN
641 EFIAPI
642 UnicodeValueToString (
643 IN OUT CHAR16 *Buffer,
644 IN UINTN Flags,
645 IN INT64 Value,
646 IN UINTN Width
647 )
648 {
649 RETURN_STATUS Status;
650 UINTN BufferSize;
651
652 if (Width == 0) {
653 BufferSize = (MAXIMUM_VALUE_CHARACTERS + 1) * sizeof (CHAR16);
654 } else {
655 BufferSize = (Width + 1) * sizeof (CHAR16);
656 }
657
658 Status = mPrint2SProtocol->UnicodeValueToStringS (Buffer, BufferSize, Flags, Value, Width);
659 if (RETURN_ERROR (Status)) {
660 return 0;
661 }
662
663 return StrnLenS (Buffer, BufferSize / sizeof (CHAR16));
664 }
665
666 #endif
667
668 /**
669 Converts a decimal value to a Null-terminated Unicode string.
670
671 Converts the decimal number specified by Value to a Null-terminated Unicode
672 string specified by Buffer containing at most Width characters. No padding of
673 spaces is ever performed. If Width is 0 then a width of
674 MAXIMUM_VALUE_CHARACTERS is assumed. If the conversion contains more than
675 Width characters, then only the first Width characters are placed in Buffer.
676 Additional conversion parameters are specified in Flags.
677
678 The Flags bit LEFT_JUSTIFY is always ignored.
679 All conversions are left justified in Buffer.
680 If Width is 0, PREFIX_ZERO is ignored in Flags.
681 If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and
682 commas are inserted every 3rd digit starting from the right.
683 If RADIX_HEX is set in Flags, then the output buffer will be formatted in
684 hexadecimal format.
685 If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in
686 Buffer is a '-'.
687 If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, then
688 Buffer is padded with '0' characters so the combination of the optional '-'
689 sign character, '0' characters, digit characters for Value, and the
690 Null-terminator add up to Width characters.
691
692 If Buffer is not aligned on a 16-bit boundary, then ASSERT().
693 If an error would be returned, then the function will also ASSERT().
694
695 @param Buffer The pointer to the output buffer for the produced
696 Null-terminated Unicode string.
697 @param BufferSize The size of Buffer in bytes, including the
698 Null-terminator.
699 @param Flags The bitmask of flags that specify left justification,
700 zero pad, and commas.
701 @param Value The 64-bit signed value to convert to a string.
702 @param Width The maximum number of Unicode characters to place in
703 Buffer, not including the Null-terminator.
704
705 @retval RETURN_SUCCESS The decimal value is converted.
706 @retval RETURN_BUFFER_TOO_SMALL If BufferSize cannot hold the converted
707 value.
708 @retval RETURN_INVALID_PARAMETER If Buffer is NULL.
709 If PcdMaximumUnicodeStringLength is not
710 zero, and BufferSize is greater than
711 (PcdMaximumUnicodeStringLength *
712 sizeof (CHAR16) + 1).
713 If unsupported bits are set in Flags.
714 If both COMMA_TYPE and RADIX_HEX are set in
715 Flags.
716 If Width >= MAXIMUM_VALUE_CHARACTERS.
717
718 **/
719 RETURN_STATUS
720 EFIAPI
721 UnicodeValueToStringS (
722 IN OUT CHAR16 *Buffer,
723 IN UINTN BufferSize,
724 IN UINTN Flags,
725 IN INT64 Value,
726 IN UINTN Width
727 )
728 {
729 return mPrint2SProtocol->UnicodeValueToStringS (Buffer, BufferSize, Flags, Value, Width);
730 }
731
732 /**
733 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
734 ASCII format string and a VA_LIST argument list.
735
736 This function is similar as vsnprintf_s defined in C11.
737
738 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
739 and BufferSize.
740 The ASCII string is produced by parsing the format string specified by FormatString.
741 Arguments are pulled from the variable argument list specified by Marker based on
742 the contents of the format string.
743 The number of ASCII characters in the produced output buffer is returned not including
744 the Null-terminator.
745
746 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
747 unmodified and 0 is returned.
748 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
749 unmodified and 0 is returned.
750 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
751 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
752 is unmodified and 0 is returned.
753 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
754 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
755 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
756
757 If BufferSize is 0, then no output buffer is produced and 0 is returned.
758
759 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
760 ASCII string.
761 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
762 @param FormatString A Null-terminated ASCII format string.
763 @param Marker VA_LIST marker for the variable argument list.
764
765 @return The number of ASCII characters in the produced output buffer not including the
766 Null-terminator.
767
768 **/
769 UINTN
770 EFIAPI
771 AsciiVSPrint (
772 OUT CHAR8 *StartOfBuffer,
773 IN UINTN BufferSize,
774 IN CONST CHAR8 *FormatString,
775 IN VA_LIST Marker
776 )
777 {
778 UINT64 BaseListMarker[256 / sizeof (UINT64)];
779 BOOLEAN Converted;
780
781 Converted = DxePrintLibPrint2ProtocolVaListToBaseList (
782 TRUE,
783 FormatString,
784 Marker,
785 (BASE_LIST)BaseListMarker,
786 sizeof (BaseListMarker) - 8
787 );
788 if (!Converted) {
789 return 0;
790 }
791
792 return AsciiBSPrint (StartOfBuffer, BufferSize, FormatString, (BASE_LIST)BaseListMarker);
793 }
794
795 /**
796 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
797 ASCII format string and a BASE_LIST argument list.
798
799 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
800 and BufferSize.
801 The ASCII string is produced by parsing the format string specified by FormatString.
802 Arguments are pulled from the variable argument list specified by Marker based on
803 the contents of the format string.
804 The number of ASCII characters in the produced output buffer is returned not including
805 the Null-terminator.
806
807 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
808 unmodified and 0 is returned.
809 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
810 unmodified and 0 is returned.
811 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
812 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
813 is unmodified and 0 is returned.
814 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
815 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
816 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
817
818 If BufferSize is 0, then no output buffer is produced and 0 is returned.
819
820 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
821 ASCII string.
822 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
823 @param FormatString A Null-terminated ASCII format string.
824 @param Marker BASE_LIST marker for the variable argument list.
825
826 @return The number of ASCII characters in the produced output buffer not including the
827 Null-terminator.
828
829 **/
830 UINTN
831 EFIAPI
832 AsciiBSPrint (
833 OUT CHAR8 *StartOfBuffer,
834 IN UINTN BufferSize,
835 IN CONST CHAR8 *FormatString,
836 IN BASE_LIST Marker
837 )
838 {
839 return mPrint2SProtocol->AsciiBSPrint (StartOfBuffer, BufferSize, FormatString, Marker);
840 }
841
842 /**
843 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
844 ASCII format string and variable argument list.
845
846 This function is similar as snprintf_s defined in C11.
847
848 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
849 and BufferSize.
850 The ASCII string is produced by parsing the format string specified by FormatString.
851 Arguments are pulled from the variable argument list based on the contents of the
852 format string.
853 The number of ASCII characters in the produced output buffer is returned not including
854 the Null-terminator.
855
856 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
857 unmodified and 0 is returned.
858 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
859 unmodified and 0 is returned.
860 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
861 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
862 is unmodified and 0 is returned.
863 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
864 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
865 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
866
867 If BufferSize is 0, then no output buffer is produced and 0 is returned.
868
869 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
870 ASCII string.
871 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
872 @param FormatString A Null-terminated ASCII format string.
873 @param ... Variable argument list whose contents are accessed based on the
874 format string specified by FormatString.
875
876 @return The number of ASCII characters in the produced output buffer not including the
877 Null-terminator.
878
879 **/
880 UINTN
881 EFIAPI
882 AsciiSPrint (
883 OUT CHAR8 *StartOfBuffer,
884 IN UINTN BufferSize,
885 IN CONST CHAR8 *FormatString,
886 ...
887 )
888 {
889 VA_LIST Marker;
890 UINTN NumberOfPrinted;
891
892 VA_START (Marker, FormatString);
893 NumberOfPrinted = AsciiVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);
894 VA_END (Marker);
895 return NumberOfPrinted;
896 }
897
898 /**
899 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
900 Unicode format string and a VA_LIST argument list.
901
902 This function is similar as vsnprintf_s defined in C11.
903
904 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
905 and BufferSize.
906 The ASCII string is produced by parsing the format string specified by FormatString.
907 Arguments are pulled from the variable argument list specified by Marker based on
908 the contents of the format string.
909 The number of ASCII characters in the produced output buffer is returned not including
910 the Null-terminator.
911
912 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
913
914 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
915 unmodified and 0 is returned.
916 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
917 unmodified and 0 is returned.
918 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
919 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
920 is unmodified and 0 is returned.
921 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
922 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
923 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
924
925 If BufferSize is 0, then no output buffer is produced and 0 is returned.
926
927 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
928 ASCII string.
929 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
930 @param FormatString A Null-terminated Unicode format string.
931 @param Marker VA_LIST marker for the variable argument list.
932
933 @return The number of ASCII characters in the produced output buffer not including the
934 Null-terminator.
935
936 **/
937 UINTN
938 EFIAPI
939 AsciiVSPrintUnicodeFormat (
940 OUT CHAR8 *StartOfBuffer,
941 IN UINTN BufferSize,
942 IN CONST CHAR16 *FormatString,
943 IN VA_LIST Marker
944 )
945 {
946 UINT64 BaseListMarker[256 / sizeof (UINT64)];
947 BOOLEAN Converted;
948
949 ASSERT_UNICODE_BUFFER (FormatString);
950
951 Converted = DxePrintLibPrint2ProtocolVaListToBaseList (
952 FALSE,
953 (CHAR8 *)FormatString,
954 Marker,
955 (BASE_LIST)BaseListMarker,
956 sizeof (BaseListMarker) - 8
957 );
958 if (!Converted) {
959 return 0;
960 }
961
962 return AsciiBSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, (BASE_LIST)BaseListMarker);
963 }
964
965 /**
966 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
967 Unicode format string and a BASE_LIST argument list.
968
969 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
970 and BufferSize.
971 The ASCII string is produced by parsing the format string specified by FormatString.
972 Arguments are pulled from the variable argument list specified by Marker based on
973 the contents of the format string.
974 The number of ASCII characters in the produced output buffer is returned not including
975 the Null-terminator.
976
977 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
978
979 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
980 unmodified and 0 is returned.
981 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
982 unmodified and 0 is returned.
983 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
984 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
985 is unmodified and 0 is returned.
986 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
987 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
988 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
989
990 If BufferSize is 0, then no output buffer is produced and 0 is returned.
991
992 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
993 ASCII string.
994 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
995 @param FormatString A Null-terminated Unicode format string.
996 @param Marker BASE_LIST marker for the variable argument list.
997
998 @return The number of ASCII characters in the produced output buffer not including the
999 Null-terminator.
1000
1001 **/
1002 UINTN
1003 EFIAPI
1004 AsciiBSPrintUnicodeFormat (
1005 OUT CHAR8 *StartOfBuffer,
1006 IN UINTN BufferSize,
1007 IN CONST CHAR16 *FormatString,
1008 IN BASE_LIST Marker
1009 )
1010 {
1011 ASSERT_UNICODE_BUFFER (FormatString);
1012 return mPrint2SProtocol->AsciiBSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, Marker);
1013 }
1014
1015 /**
1016 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
1017 Unicode format string and variable argument list.
1018
1019 This function is similar as snprintf_s defined in C11.
1020
1021 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
1022 and BufferSize.
1023 The ASCII string is produced by parsing the format string specified by FormatString.
1024 Arguments are pulled from the variable argument list based on the contents of the
1025 format string.
1026 The number of ASCII characters in the produced output buffer is returned not including
1027 the Null-terminator.
1028
1029 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
1030
1031 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
1032 unmodified and 0 is returned.
1033 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
1034 unmodified and 0 is returned.
1035 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
1036 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
1037 is unmodified and 0 is returned.
1038 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
1039 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
1040 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
1041
1042 If BufferSize is 0, then no output buffer is produced and 0 is returned.
1043
1044 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
1045 ASCII string.
1046 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
1047 @param FormatString A Null-terminated Unicode format string.
1048 @param ... Variable argument list whose contents are accessed based on the
1049 format string specified by FormatString.
1050
1051 @return The number of ASCII characters in the produced output buffer not including the
1052 Null-terminator.
1053
1054 **/
1055 UINTN
1056 EFIAPI
1057 AsciiSPrintUnicodeFormat (
1058 OUT CHAR8 *StartOfBuffer,
1059 IN UINTN BufferSize,
1060 IN CONST CHAR16 *FormatString,
1061 ...
1062 )
1063 {
1064 VA_LIST Marker;
1065 UINTN NumberOfPrinted;
1066
1067 VA_START (Marker, FormatString);
1068 NumberOfPrinted = AsciiVSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, Marker);
1069 VA_END (Marker);
1070 return NumberOfPrinted;
1071 }
1072
1073
1074 #ifndef DISABLE_NEW_DEPRECATED_INTERFACES
1075
1076 /**
1077 [ATTENTION] This function is deprecated for security reason.
1078
1079 Converts a decimal value to a Null-terminated ASCII string.
1080
1081 Converts the decimal number specified by Value to a Null-terminated ASCII string
1082 specified by Buffer containing at most Width characters. No padding of spaces
1083 is ever performed.
1084 If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed.
1085 The number of ASCII characters in Buffer is returned not including the Null-terminator.
1086 If the conversion contains more than Width characters, then only the first Width
1087 characters are returned, and the total number of characters required to perform
1088 the conversion is returned.
1089 Additional conversion parameters are specified in Flags.
1090 The Flags bit LEFT_JUSTIFY is always ignored.
1091 All conversions are left justified in Buffer.
1092 If Width is 0, PREFIX_ZERO is ignored in Flags.
1093 If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas
1094 are inserted every 3rd digit starting from the right.
1095 If RADIX_HEX is set in Flags, then the output buffer will be
1096 formatted in hexadecimal format.
1097 If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in Buffer is a '-'.
1098 If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored,
1099 then Buffer is padded with '0' characters so the combination of the optional '-'
1100 sign character, '0' characters, digit characters for Value, and the Null-terminator
1101 add up to Width characters.
1102
1103 If Buffer is NULL, then ASSERT().
1104 If unsupported bits are set in Flags, then ASSERT().
1105 If both COMMA_TYPE and RADIX_HEX are set in Flags, then ASSERT().
1106 If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT()
1107
1108 @param Buffer Pointer to the output buffer for the produced Null-terminated
1109 ASCII string.
1110 @param Flags The bitmask of flags that specify left justification, zero pad, and commas.
1111 @param Value The 64-bit signed value to convert to a string.
1112 @param Width The maximum number of ASCII characters to place in Buffer, not including
1113 the Null-terminator.
1114
1115 @return The number of ASCII characters in Buffer not including the Null-terminator.
1116
1117 **/
1118 UINTN
1119 EFIAPI
1120 AsciiValueToString (
1121 OUT CHAR8 *Buffer,
1122 IN UINTN Flags,
1123 IN INT64 Value,
1124 IN UINTN Width
1125 )
1126 {
1127 RETURN_STATUS Status;
1128 UINTN BufferSize;
1129
1130 if (Width == 0) {
1131 BufferSize = (MAXIMUM_VALUE_CHARACTERS + 1) * sizeof (CHAR8);
1132 } else {
1133 BufferSize = (Width + 1) * sizeof (CHAR8);
1134 }
1135
1136 Status = mPrint2SProtocol->AsciiValueToStringS (Buffer, BufferSize, Flags, Value, Width);
1137 if (RETURN_ERROR (Status)) {
1138 return 0;
1139 }
1140
1141 return AsciiStrnLenS (Buffer, BufferSize / sizeof (CHAR8));
1142 }
1143
1144 #endif
1145
1146 /**
1147 Converts a decimal value to a Null-terminated Ascii string.
1148
1149 Converts the decimal number specified by Value to a Null-terminated Ascii
1150 string specified by Buffer containing at most Width characters. No padding of
1151 spaces is ever performed. If Width is 0 then a width of
1152 MAXIMUM_VALUE_CHARACTERS is assumed. If the conversion contains more than
1153 Width characters, then only the first Width characters are placed in Buffer.
1154 Additional conversion parameters are specified in Flags.
1155
1156 The Flags bit LEFT_JUSTIFY is always ignored.
1157 All conversions are left justified in Buffer.
1158 If Width is 0, PREFIX_ZERO is ignored in Flags.
1159 If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and
1160 commas are inserted every 3rd digit starting from the right.
1161 If RADIX_HEX is set in Flags, then the output buffer will be formatted in
1162 hexadecimal format.
1163 If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in
1164 Buffer is a '-'.
1165 If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, then
1166 Buffer is padded with '0' characters so the combination of the optional '-'
1167 sign character, '0' characters, digit characters for Value, and the
1168 Null-terminator add up to Width characters.
1169
1170 If an error would be returned, then the function will ASSERT().
1171
1172 @param Buffer The pointer to the output buffer for the produced
1173 Null-terminated Ascii string.
1174 @param BufferSize The size of Buffer in bytes, including the
1175 Null-terminator.
1176 @param Flags The bitmask of flags that specify left justification,
1177 zero pad, and commas.
1178 @param Value The 64-bit signed value to convert to a string.
1179 @param Width The maximum number of Ascii characters to place in
1180 Buffer, not including the Null-terminator.
1181
1182 @retval RETURN_SUCCESS The decimal value is converted.
1183 @retval RETURN_BUFFER_TOO_SMALL If BufferSize cannot hold the converted
1184 value.
1185 @retval RETURN_INVALID_PARAMETER If Buffer is NULL.
1186 If PcdMaximumAsciiStringLength is not
1187 zero, and BufferSize is greater than
1188 PcdMaximumAsciiStringLength.
1189 If unsupported bits are set in Flags.
1190 If both COMMA_TYPE and RADIX_HEX are set in
1191 Flags.
1192 If Width >= MAXIMUM_VALUE_CHARACTERS.
1193
1194 **/
1195 RETURN_STATUS
1196 EFIAPI
1197 AsciiValueToStringS (
1198 IN OUT CHAR8 *Buffer,
1199 IN UINTN BufferSize,
1200 IN UINTN Flags,
1201 IN INT64 Value,
1202 IN UINTN Width
1203 )
1204 {
1205 return mPrint2SProtocol->AsciiValueToStringS (Buffer, BufferSize, Flags, Value, Width);
1206 }
1207
1208 #define PREFIX_SIGN BIT1
1209 #define PREFIX_BLANK BIT2
1210 #define LONG_TYPE BIT4
1211 #define OUTPUT_UNICODE BIT6
1212 #define FORMAT_UNICODE BIT8
1213 #define PAD_TO_WIDTH BIT9
1214 #define ARGUMENT_UNICODE BIT10
1215 #define PRECISION BIT11
1216 #define ARGUMENT_REVERSED BIT12
1217 #define COUNT_ONLY_NO_PRINT BIT13
1218 #define UNSIGNED_TYPE BIT14
1219
1220 //
1221 // Record date and time information
1222 //
1223 typedef struct {
1224 UINT16 Year;
1225 UINT8 Month;
1226 UINT8 Day;
1227 UINT8 Hour;
1228 UINT8 Minute;
1229 UINT8 Second;
1230 UINT8 Pad1;
1231 UINT32 Nanosecond;
1232 INT16 TimeZone;
1233 UINT8 Daylight;
1234 UINT8 Pad2;
1235 } TIME;
1236
1237 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mHexStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
1238
1239 /**
1240 Internal function that convert a number to a string in Buffer.
1241
1242 Print worker function that converts a decimal or hexadecimal number to an ASCII string in Buffer.
1243
1244 @param Buffer Location to place the ASCII string of Value.
1245 @param Value The value to convert to a Decimal or Hexadecimal string in Buffer.
1246 @param Radix Radix of the value
1247
1248 @return A pointer to the end of buffer filled with ASCII string.
1249
1250 **/
1251 CHAR8 *
1252 InternalPrintLibValueToString (
1253 IN OUT CHAR8 *Buffer,
1254 IN INT64 Value,
1255 IN UINTN Radix
1256 )
1257 {
1258 UINT32 Remainder;
1259
1260 //
1261 // Loop to convert one digit at a time in reverse order
1262 //
1263 *Buffer = 0;
1264 do {
1265 Value = (INT64)DivU64x32Remainder ((UINT64)Value, (UINT32)Radix, &Remainder);
1266 *(++Buffer) = mHexStr[Remainder];
1267 } while (Value != 0);
1268
1269 //
1270 // Return pointer of the end of filled buffer.
1271 //
1272 return Buffer;
1273 }
1274
1275 /**
1276 Worker function that produces a Null-terminated string in an output buffer
1277 based on a Null-terminated format string and a VA_LIST argument list.
1278
1279 VSPrint function to process format and place the results in Buffer. Since a
1280 VA_LIST is used this routine allows the nesting of Vararg routines. Thus
1281 this is the main print working routine.
1282
1283 If COUNT_ONLY_NO_PRINT is set in Flags, Buffer will not be modified at all.
1284
1285 @param[out] Buffer The character buffer to print the results of the
1286 parsing of Format into.
1287 @param[in] BufferSize The maximum number of characters to put into
1288 buffer.
1289 @param[in] Flags Initial flags value.
1290 Can only have FORMAT_UNICODE, OUTPUT_UNICODE,
1291 and COUNT_ONLY_NO_PRINT set.
1292 @param[in] Format A Null-terminated format string.
1293 @param[in] VaListMarker VA_LIST style variable argument list consumed by
1294 processing Format.
1295 @param[in] BaseListMarker BASE_LIST style variable argument list consumed
1296 by processing Format.
1297
1298 @return The number of characters printed not including the Null-terminator.
1299 If COUNT_ONLY_NO_PRINT was set returns the same, but without any
1300 modification to Buffer.
1301
1302 **/
1303 UINTN
1304 InternalPrintLibSPrintMarker (
1305 OUT CHAR8 *Buffer,
1306 IN UINTN BufferSize,
1307 IN UINTN Flags,
1308 IN CONST CHAR8 *Format,
1309 IN VA_LIST VaListMarker, OPTIONAL
1310 IN BASE_LIST BaseListMarker OPTIONAL
1311 );
1312
1313 /**
1314 Worker function that produces a Null-terminated string in an output buffer
1315 based on a Null-terminated format string and variable argument list.
1316
1317 VSPrint function to process format and place the results in Buffer. Since a
1318 VA_LIST is used this routine allows the nesting of Vararg routines. Thus
1319 this is the main print working routine
1320
1321 @param StartOfBuffer The character buffer to print the results of the parsing
1322 of Format into.
1323 @param BufferSize The maximum number of characters to put into buffer.
1324 Zero means no limit.
1325 @param Flags Initial flags value.
1326 Can only have FORMAT_UNICODE and OUTPUT_UNICODE set
1327 @param FormatString A Null-terminated format string.
1328 @param ... The variable argument list.
1329
1330 @return The number of characters printed.
1331
1332 **/
1333 UINTN
1334 EFIAPI
1335 InternalPrintLibSPrint (
1336 OUT CHAR8 *StartOfBuffer,
1337 IN UINTN BufferSize,
1338 IN UINTN Flags,
1339 IN CONST CHAR8 *FormatString,
1340 ...
1341 )
1342 {
1343 VA_LIST Marker;
1344 UINTN NumberOfPrinted;
1345
1346 VA_START (Marker, FormatString);
1347 NumberOfPrinted = InternalPrintLibSPrintMarker (StartOfBuffer, BufferSize, Flags, FormatString, Marker, NULL);
1348 VA_END (Marker);
1349 return NumberOfPrinted;
1350 }
1351
1352 #define WARNING_STATUS_NUMBER 5
1353 #define ERROR_STATUS_NUMBER 33
1354
1355 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 * CONST mStatusString[] = {
1356 "Success", // RETURN_SUCCESS = 0
1357 "Warning Unknown Glyph", // RETURN_WARN_UNKNOWN_GLYPH = 1
1358 "Warning Delete Failure", // RETURN_WARN_DELETE_FAILURE = 2
1359 "Warning Write Failure", // RETURN_WARN_WRITE_FAILURE = 3
1360 "Warning Buffer Too Small", // RETURN_WARN_BUFFER_TOO_SMALL = 4
1361 "Warning Stale Data", // RETURN_WARN_STALE_DATA = 5
1362 "Load Error", // RETURN_LOAD_ERROR = 1 | MAX_BIT
1363 "Invalid Parameter", // RETURN_INVALID_PARAMETER = 2 | MAX_BIT
1364 "Unsupported", // RETURN_UNSUPPORTED = 3 | MAX_BIT
1365 "Bad Buffer Size", // RETURN_BAD_BUFFER_SIZE = 4 | MAX_BIT
1366 "Buffer Too Small", // RETURN_BUFFER_TOO_SMALL, = 5 | MAX_BIT
1367 "Not Ready", // RETURN_NOT_READY = 6 | MAX_BIT
1368 "Device Error", // RETURN_DEVICE_ERROR = 7 | MAX_BIT
1369 "Write Protected", // RETURN_WRITE_PROTECTED = 8 | MAX_BIT
1370 "Out of Resources", // RETURN_OUT_OF_RESOURCES = 9 | MAX_BIT
1371 "Volume Corrupt", // RETURN_VOLUME_CORRUPTED = 10 | MAX_BIT
1372 "Volume Full", // RETURN_VOLUME_FULL = 11 | MAX_BIT
1373 "No Media", // RETURN_NO_MEDIA = 12 | MAX_BIT
1374 "Media changed", // RETURN_MEDIA_CHANGED = 13 | MAX_BIT
1375 "Not Found", // RETURN_NOT_FOUND = 14 | MAX_BIT
1376 "Access Denied", // RETURN_ACCESS_DENIED = 15 | MAX_BIT
1377 "No Response", // RETURN_NO_RESPONSE = 16 | MAX_BIT
1378 "No mapping", // RETURN_NO_MAPPING = 17 | MAX_BIT
1379 "Time out", // RETURN_TIMEOUT = 18 | MAX_BIT
1380 "Not started", // RETURN_NOT_STARTED = 19 | MAX_BIT
1381 "Already started", // RETURN_ALREADY_STARTED = 20 | MAX_BIT
1382 "Aborted", // RETURN_ABORTED = 21 | MAX_BIT
1383 "ICMP Error", // RETURN_ICMP_ERROR = 22 | MAX_BIT
1384 "TFTP Error", // RETURN_TFTP_ERROR = 23 | MAX_BIT
1385 "Protocol Error", // RETURN_PROTOCOL_ERROR = 24 | MAX_BIT
1386 "Incompatible Version", // RETURN_INCOMPATIBLE_VERSION = 25 | MAX_BIT
1387 "Security Violation", // RETURN_SECURITY_VIOLATION = 26 | MAX_BIT
1388 "CRC Error", // RETURN_CRC_ERROR = 27 | MAX_BIT
1389 "End of Media", // RETURN_END_OF_MEDIA = 28 | MAX_BIT
1390 "Reserved (29)", // RESERVED = 29 | MAX_BIT
1391 "Reserved (30)", // RESERVED = 30 | MAX_BIT
1392 "End of File", // RETURN_END_OF_FILE = 31 | MAX_BIT
1393 "Invalid Language", // RETURN_INVALID_LANGUAGE = 32 | MAX_BIT
1394 "Compromised Data" // RETURN_COMPROMISED_DATA = 33 | MAX_BIT
1395 };
1396
1397 /**
1398 Internal function that places the character into the Buffer.
1399
1400 Internal function that places ASCII or Unicode character into the Buffer.
1401
1402 @param Buffer The buffer to place the Unicode or ASCII string.
1403 @param EndBuffer The end of the input Buffer. No characters will be
1404 placed after that.
1405 @param Length The count of character to be placed into Buffer.
1406 (Negative value indicates no buffer fill.)
1407 @param Character The character to be placed into Buffer.
1408 @param Increment The character increment in Buffer.
1409
1410 @return Buffer.
1411
1412 **/
1413 CHAR8 *
1414 InternalPrintLibFillBuffer (
1415 OUT CHAR8 *Buffer,
1416 IN CHAR8 *EndBuffer,
1417 IN INTN Length,
1418 IN UINTN Character,
1419 IN INTN Increment
1420 )
1421 {
1422 INTN Index;
1423
1424 for (Index = 0; Index < Length && Buffer < EndBuffer; Index++) {
1425 *Buffer = (CHAR8) Character;
1426 if (Increment != 1) {
1427 *(Buffer + 1) = (CHAR8)(Character >> 8);
1428 }
1429 Buffer += Increment;
1430 }
1431
1432 return Buffer;
1433 }
1434
1435 /**
1436 Worker function that produces a Null-terminated string in an output buffer
1437 based on a Null-terminated format string and a VA_LIST argument list.
1438
1439 VSPrint function to process format and place the results in Buffer. Since a
1440 VA_LIST is used this routine allows the nesting of Vararg routines. Thus
1441 this is the main print working routine.
1442
1443 If COUNT_ONLY_NO_PRINT is set in Flags, Buffer will not be modified at all.
1444
1445 @param[out] Buffer The character buffer to print the results of the
1446 parsing of Format into.
1447 @param[in] BufferSize The maximum number of characters to put into
1448 buffer.
1449 @param[in] Flags Initial flags value.
1450 Can only have FORMAT_UNICODE, OUTPUT_UNICODE,
1451 and COUNT_ONLY_NO_PRINT set.
1452 @param[in] Format A Null-terminated format string.
1453 @param[in] VaListMarker VA_LIST style variable argument list consumed by
1454 processing Format.
1455 @param[in] BaseListMarker BASE_LIST style variable argument list consumed
1456 by processing Format.
1457
1458 @return The number of characters printed not including the Null-terminator.
1459 If COUNT_ONLY_NO_PRINT was set returns the same, but without any
1460 modification to Buffer.
1461
1462 **/
1463 UINTN
1464 InternalPrintLibSPrintMarker (
1465 OUT CHAR8 *Buffer,
1466 IN UINTN BufferSize,
1467 IN UINTN Flags,
1468 IN CONST CHAR8 *Format,
1469 IN VA_LIST VaListMarker, OPTIONAL
1470 IN BASE_LIST BaseListMarker OPTIONAL
1471 )
1472 {
1473 CHAR8 *OriginalBuffer;
1474 CHAR8 *EndBuffer;
1475 CHAR8 ValueBuffer[MAXIMUM_VALUE_CHARACTERS];
1476 UINT32 BytesPerOutputCharacter;
1477 UINTN BytesPerFormatCharacter;
1478 UINTN FormatMask;
1479 UINTN FormatCharacter;
1480 UINTN Width;
1481 UINTN Precision;
1482 INT64 Value;
1483 CONST CHAR8 *ArgumentString;
1484 UINTN Character;
1485 GUID *TmpGuid;
1486 TIME *TmpTime;
1487 UINTN Count;
1488 UINTN ArgumentMask;
1489 INTN BytesPerArgumentCharacter;
1490 UINTN ArgumentCharacter;
1491 BOOLEAN Done;
1492 UINTN Index;
1493 CHAR8 Prefix;
1494 BOOLEAN ZeroPad;
1495 BOOLEAN Comma;
1496 UINTN Digits;
1497 UINTN Radix;
1498 RETURN_STATUS Status;
1499 UINT32 GuidData1;
1500 UINT16 GuidData2;
1501 UINT16 GuidData3;
1502 UINTN LengthToReturn;
1503
1504 //
1505 // If you change this code be sure to match the 2 versions of this function.
1506 // Nearly identical logic is found in the BasePrintLib and
1507 // DxePrintLibPrint2Protocol (both PrintLib instances).
1508 //
1509
1510 //
1511 // 1. Buffer shall not be a null pointer when both BufferSize > 0 and
1512 // COUNT_ONLY_NO_PRINT is not set in Flags.
1513 //
1514 if ((BufferSize > 0) && ((Flags & COUNT_ONLY_NO_PRINT) == 0)) {
1515 SAFE_PRINT_CONSTRAINT_CHECK ((Buffer != NULL), 0);
1516 }
1517
1518 //
1519 // 2. Format shall not be a null pointer when BufferSize > 0 or when
1520 // COUNT_ONLY_NO_PRINT is set in Flags.
1521 //
1522 if ((BufferSize > 0) || ((Flags & COUNT_ONLY_NO_PRINT) != 0)) {
1523 SAFE_PRINT_CONSTRAINT_CHECK ((Format != NULL), 0);
1524 }
1525
1526 //
1527 // 3. BufferSize shall not be greater than RSIZE_MAX for Unicode output or
1528 // ASCII_RSIZE_MAX for Ascii output.
1529 //
1530 if ((Flags & OUTPUT_UNICODE) != 0) {
1531 if (RSIZE_MAX != 0) {
1532 SAFE_PRINT_CONSTRAINT_CHECK ((BufferSize <= RSIZE_MAX), 0);
1533 }
1534 BytesPerOutputCharacter = 2;
1535 } else {
1536 if (ASCII_RSIZE_MAX != 0) {
1537 SAFE_PRINT_CONSTRAINT_CHECK ((BufferSize <= ASCII_RSIZE_MAX), 0);
1538 }
1539 BytesPerOutputCharacter = 1;
1540 }
1541
1542 //
1543 // 4. Format shall not contain more than RSIZE_MAX Unicode characters or
1544 // ASCII_RSIZE_MAX Ascii characters.
1545 //
1546 if ((Flags & FORMAT_UNICODE) != 0) {
1547 if (RSIZE_MAX != 0) {
1548 SAFE_PRINT_CONSTRAINT_CHECK ((StrnLenS ((CHAR16 *)Format, RSIZE_MAX + 1) <= RSIZE_MAX), 0);
1549 }
1550 BytesPerFormatCharacter = 2;
1551 FormatMask = 0xffff;
1552 } else {
1553 if (ASCII_RSIZE_MAX != 0) {
1554 SAFE_PRINT_CONSTRAINT_CHECK ((AsciiStrnLenS (Format, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), 0);
1555 }
1556 BytesPerFormatCharacter = 1;
1557 FormatMask = 0xff;
1558 }
1559
1560 if ((Flags & COUNT_ONLY_NO_PRINT) != 0) {
1561 if (BufferSize == 0) {
1562 Buffer = NULL;
1563 }
1564 } else {
1565 //
1566 // We can run without a Buffer for counting only.
1567 //
1568 if (BufferSize == 0) {
1569 return 0;
1570 }
1571 }
1572
1573 LengthToReturn = 0;
1574 EndBuffer = NULL;
1575 OriginalBuffer = NULL;
1576
1577 //
1578 // Reserve space for the Null terminator.
1579 //
1580 if (Buffer != NULL) {
1581 BufferSize--;
1582 OriginalBuffer = Buffer;
1583
1584 //
1585 // Set the tag for the end of the input Buffer.
1586 //
1587 EndBuffer = Buffer + BufferSize * BytesPerOutputCharacter;
1588 }
1589
1590 //
1591 // Get the first character from the format string
1592 //
1593 FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;
1594
1595 //
1596 // Loop until the end of the format string is reached or the output buffer is full
1597 //
1598 while (FormatCharacter != 0) {
1599 if ((Buffer != NULL) && (Buffer >= EndBuffer)) {
1600 break;
1601 }
1602 //
1603 // Clear all the flag bits except those that may have been passed in
1604 //
1605 Flags &= (UINTN) (OUTPUT_UNICODE | FORMAT_UNICODE | COUNT_ONLY_NO_PRINT);
1606
1607 //
1608 // Set the default width to zero, and the default precision to 1
1609 //
1610 Width = 0;
1611 Precision = 1;
1612 Prefix = 0;
1613 Comma = FALSE;
1614 ZeroPad = FALSE;
1615 Count = 0;
1616 Digits = 0;
1617
1618 switch (FormatCharacter) {
1619 case '%':
1620 //
1621 // Parse Flags and Width
1622 //
1623 for (Done = FALSE; !Done; ) {
1624 Format += BytesPerFormatCharacter;
1625 FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;
1626 switch (FormatCharacter) {
1627 case '.':
1628 Flags |= PRECISION;
1629 break;
1630 case '-':
1631 Flags |= LEFT_JUSTIFY;
1632 break;
1633 case '+':
1634 Flags |= PREFIX_SIGN;
1635 break;
1636 case ' ':
1637 Flags |= PREFIX_BLANK;
1638 break;
1639 case ',':
1640 Flags |= COMMA_TYPE;
1641 break;
1642 case 'L':
1643 case 'l':
1644 Flags |= LONG_TYPE;
1645 break;
1646 case '*':
1647 if ((Flags & PRECISION) == 0) {
1648 Flags |= PAD_TO_WIDTH;
1649 if (BaseListMarker == NULL) {
1650 Width = VA_ARG (VaListMarker, UINTN);
1651 } else {
1652 Width = BASE_ARG (BaseListMarker, UINTN);
1653 }
1654 } else {
1655 if (BaseListMarker == NULL) {
1656 Precision = VA_ARG (VaListMarker, UINTN);
1657 } else {
1658 Precision = BASE_ARG (BaseListMarker, UINTN);
1659 }
1660 }
1661 break;
1662 case '0':
1663 if ((Flags & PRECISION) == 0) {
1664 Flags |= PREFIX_ZERO;
1665 }
1666 case '1':
1667 case '2':
1668 case '3':
1669 case '4':
1670 case '5':
1671 case '6':
1672 case '7':
1673 case '8':
1674 case '9':
1675 for (Count = 0; ((FormatCharacter >= '0') && (FormatCharacter <= '9')); ){
1676 Count = (Count * 10) + FormatCharacter - '0';
1677 Format += BytesPerFormatCharacter;
1678 FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;
1679 }
1680 Format -= BytesPerFormatCharacter;
1681 if ((Flags & PRECISION) == 0) {
1682 Flags |= PAD_TO_WIDTH;
1683 Width = Count;
1684 } else {
1685 Precision = Count;
1686 }
1687 break;
1688
1689 case '\0':
1690 //
1691 // Make no output if Format string terminates unexpectedly when
1692 // looking up for flag, width, precision and type.
1693 //
1694 Format -= BytesPerFormatCharacter;
1695 Precision = 0;
1696 //
1697 // break skipped on purpose.
1698 //
1699 default:
1700 Done = TRUE;
1701 break;
1702 }
1703 }
1704
1705 //
1706 // Handle each argument type
1707 //
1708 switch (FormatCharacter) {
1709 case 'p':
1710 //
1711 // Flag space, +, 0, L & l are invalid for type p.
1712 //
1713 Flags &= ~((UINTN) (PREFIX_BLANK | PREFIX_SIGN | PREFIX_ZERO | LONG_TYPE));
1714 if (sizeof (VOID *) > 4) {
1715 Flags |= LONG_TYPE;
1716 }
1717 //
1718 // break skipped on purpose
1719 //
1720 case 'X':
1721 Flags |= PREFIX_ZERO;
1722 //
1723 // break skipped on purpose
1724 //
1725 case 'x':
1726 Flags |= RADIX_HEX;
1727 //
1728 // break skipped on purpose
1729 //
1730 case 'u':
1731 if ((Flags & RADIX_HEX) == 0) {
1732 Flags &= ~((UINTN) (PREFIX_SIGN));
1733 Flags |= UNSIGNED_TYPE;
1734 }
1735 //
1736 // break skipped on purpose
1737 //
1738 case 'd':
1739 if ((Flags & LONG_TYPE) == 0) {
1740 //
1741 // 'd', 'u', 'x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".
1742 // This assumption is made so the format string definition is compatible with the ANSI C
1743 // Specification for formatted strings. It is recommended that the Base Types be used
1744 // everywhere, but in this one case, compliance with ANSI C is more important, and
1745 // provides an implementation that is compatible with that largest possible set of CPU
1746 // architectures. This is why the type "int" is used in this one case.
1747 //
1748 if (BaseListMarker == NULL) {
1749 Value = VA_ARG (VaListMarker, int);
1750 } else {
1751 Value = BASE_ARG (BaseListMarker, int);
1752 }
1753 } else {
1754 if (BaseListMarker == NULL) {
1755 Value = VA_ARG (VaListMarker, INT64);
1756 } else {
1757 Value = BASE_ARG (BaseListMarker, INT64);
1758 }
1759 }
1760 if ((Flags & PREFIX_BLANK) != 0) {
1761 Prefix = ' ';
1762 }
1763 if ((Flags & PREFIX_SIGN) != 0) {
1764 Prefix = '+';
1765 }
1766 if ((Flags & COMMA_TYPE) != 0) {
1767 Comma = TRUE;
1768 }
1769 if ((Flags & RADIX_HEX) == 0) {
1770 Radix = 10;
1771 if (Comma) {
1772 Flags &= ~((UINTN) PREFIX_ZERO);
1773 Precision = 1;
1774 }
1775 if (Value < 0 && (Flags & UNSIGNED_TYPE) == 0) {
1776 Flags |= PREFIX_SIGN;
1777 Prefix = '-';
1778 Value = -Value;
1779 } else if ((Flags & UNSIGNED_TYPE) != 0 && (Flags & LONG_TYPE) == 0) {
1780 //
1781 // 'd', 'u', 'x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".
1782 // This assumption is made so the format string definition is compatible with the ANSI C
1783 // Specification for formatted strings. It is recommended that the Base Types be used
1784 // everywhere, but in this one case, compliance with ANSI C is more important, and
1785 // provides an implementation that is compatible with that largest possible set of CPU
1786 // architectures. This is why the type "unsigned int" is used in this one case.
1787 //
1788 Value = (unsigned int)Value;
1789 }
1790 } else {
1791 Radix = 16;
1792 Comma = FALSE;
1793 if ((Flags & LONG_TYPE) == 0 && Value < 0) {
1794 //
1795 // 'd', 'u', 'x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".
1796 // This assumption is made so the format string definition is compatible with the ANSI C
1797 // Specification for formatted strings. It is recommended that the Base Types be used
1798 // everywhere, but in this one case, compliance with ANSI C is more important, and
1799 // provides an implementation that is compatible with that largest possible set of CPU
1800 // architectures. This is why the type "unsigned int" is used in this one case.
1801 //
1802 Value = (unsigned int)Value;
1803 }
1804 }
1805 //
1806 // Convert Value to a reversed string
1807 //
1808 Count = InternalPrintLibValueToString (ValueBuffer, Value, Radix) - ValueBuffer;
1809 if (Value == 0 && Precision == 0) {
1810 Count = 0;
1811 }
1812 ArgumentString = (CHAR8 *)ValueBuffer + Count;
1813
1814 Digits = Count % 3;
1815 if (Digits != 0) {
1816 Digits = 3 - Digits;
1817 }
1818 if (Comma && Count != 0) {
1819 Count += ((Count - 1) / 3);
1820 }
1821 if (Prefix != 0) {
1822 Count++;
1823 Precision++;
1824 }
1825 Flags |= ARGUMENT_REVERSED;
1826 ZeroPad = TRUE;
1827 if ((Flags & PREFIX_ZERO) != 0) {
1828 if ((Flags & LEFT_JUSTIFY) == 0) {
1829 if ((Flags & PAD_TO_WIDTH) != 0) {
1830 if ((Flags & PRECISION) == 0) {
1831 Precision = Width;
1832 }
1833 }
1834 }
1835 }
1836 break;
1837
1838 case 's':
1839 case 'S':
1840 Flags |= ARGUMENT_UNICODE;
1841 //
1842 // break skipped on purpose
1843 //
1844 case 'a':
1845 if (BaseListMarker == NULL) {
1846 ArgumentString = VA_ARG (VaListMarker, CHAR8 *);
1847 } else {
1848 ArgumentString = BASE_ARG (BaseListMarker, CHAR8 *);
1849 }
1850 if (ArgumentString == NULL) {
1851 Flags &= (~(UINTN)ARGUMENT_UNICODE);
1852 ArgumentString = "<null string>";
1853 }
1854 //
1855 // Set the default precision for string to be zero if not specified.
1856 //
1857 if ((Flags & PRECISION) == 0) {
1858 Precision = 0;
1859 }
1860 break;
1861
1862 case 'c':
1863 if (BaseListMarker == NULL) {
1864 Character = VA_ARG (VaListMarker, UINTN) & 0xffff;
1865 } else {
1866 Character = BASE_ARG (BaseListMarker, UINTN) & 0xffff;
1867 }
1868 ArgumentString = (CHAR8 *)&Character;
1869 Flags |= ARGUMENT_UNICODE;
1870 break;
1871
1872 case 'g':
1873 if (BaseListMarker == NULL) {
1874 TmpGuid = VA_ARG (VaListMarker, GUID *);
1875 } else {
1876 TmpGuid = BASE_ARG (BaseListMarker, GUID *);
1877 }
1878 if (TmpGuid == NULL) {
1879 ArgumentString = "<null guid>";
1880 } else {
1881 GuidData1 = ReadUnaligned32 (&(TmpGuid->Data1));
1882 GuidData2 = ReadUnaligned16 (&(TmpGuid->Data2));
1883 GuidData3 = ReadUnaligned16 (&(TmpGuid->Data3));
1884 InternalPrintLibSPrint (
1885 ValueBuffer,
1886 MAXIMUM_VALUE_CHARACTERS,
1887 0,
1888 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1889 GuidData1,
1890 GuidData2,
1891 GuidData3,
1892 TmpGuid->Data4[0],
1893 TmpGuid->Data4[1],
1894 TmpGuid->Data4[2],
1895 TmpGuid->Data4[3],
1896 TmpGuid->Data4[4],
1897 TmpGuid->Data4[5],
1898 TmpGuid->Data4[6],
1899 TmpGuid->Data4[7]
1900 );
1901 ArgumentString = ValueBuffer;
1902 }
1903 break;
1904
1905 case 't':
1906 if (BaseListMarker == NULL) {
1907 TmpTime = VA_ARG (VaListMarker, TIME *);
1908 } else {
1909 TmpTime = BASE_ARG (BaseListMarker, TIME *);
1910 }
1911 if (TmpTime == NULL) {
1912 ArgumentString = "<null time>";
1913 } else {
1914 InternalPrintLibSPrint (
1915 ValueBuffer,
1916 MAXIMUM_VALUE_CHARACTERS,
1917 0,
1918 "%02d/%02d/%04d %02d:%02d",
1919 TmpTime->Month,
1920 TmpTime->Day,
1921 TmpTime->Year,
1922 TmpTime->Hour,
1923 TmpTime->Minute
1924 );
1925 ArgumentString = ValueBuffer;
1926 }
1927 break;
1928
1929 case 'r':
1930 if (BaseListMarker == NULL) {
1931 Status = VA_ARG (VaListMarker, RETURN_STATUS);
1932 } else {
1933 Status = BASE_ARG (BaseListMarker, RETURN_STATUS);
1934 }
1935 ArgumentString = ValueBuffer;
1936 if (RETURN_ERROR (Status)) {
1937 //
1938 // Clear error bit
1939 //
1940 Index = Status & ~MAX_BIT;
1941 if (Index > 0 && Index <= ERROR_STATUS_NUMBER) {
1942 ArgumentString = mStatusString [Index + WARNING_STATUS_NUMBER];
1943 }
1944 } else {
1945 Index = Status;
1946 if (Index <= WARNING_STATUS_NUMBER) {
1947 ArgumentString = mStatusString [Index];
1948 }
1949 }
1950 if (ArgumentString == ValueBuffer) {
1951 InternalPrintLibSPrint ((CHAR8 *) ValueBuffer, MAXIMUM_VALUE_CHARACTERS, 0, "%08X", Status);
1952 }
1953 break;
1954
1955 case '\r':
1956 Format += BytesPerFormatCharacter;
1957 FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;
1958 if (FormatCharacter == '\n') {
1959 //
1960 // Translate '\r\n' to '\r\n'
1961 //
1962 ArgumentString = "\r\n";
1963 } else {
1964 //
1965 // Translate '\r' to '\r'
1966 //
1967 ArgumentString = "\r";
1968 Format -= BytesPerFormatCharacter;
1969 }
1970 break;
1971
1972 case '\n':
1973 //
1974 // Translate '\n' to '\r\n' and '\n\r' to '\r\n'
1975 //
1976 ArgumentString = "\r\n";
1977 Format += BytesPerFormatCharacter;
1978 FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;
1979 if (FormatCharacter != '\r') {
1980 Format -= BytesPerFormatCharacter;
1981 }
1982 break;
1983
1984 case '%':
1985 default:
1986 //
1987 // if the type is '%' or unknown, then print it to the screen
1988 //
1989 ArgumentString = (CHAR8 *)&FormatCharacter;
1990 Flags |= ARGUMENT_UNICODE;
1991 break;
1992 }
1993 break;
1994
1995 case '\r':
1996 Format += BytesPerFormatCharacter;
1997 FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;
1998 if (FormatCharacter == '\n') {
1999 //
2000 // Translate '\r\n' to '\r\n'
2001 //
2002 ArgumentString = "\r\n";
2003 } else {
2004 //
2005 // Translate '\r' to '\r'
2006 //
2007 ArgumentString = "\r";
2008 Format -= BytesPerFormatCharacter;
2009 }
2010 break;
2011
2012 case '\n':
2013 //
2014 // Translate '\n' to '\r\n' and '\n\r' to '\r\n'
2015 //
2016 ArgumentString = "\r\n";
2017 Format += BytesPerFormatCharacter;
2018 FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;
2019 if (FormatCharacter != '\r') {
2020 Format -= BytesPerFormatCharacter;
2021 }
2022 break;
2023
2024 default:
2025 ArgumentString = (CHAR8 *)&FormatCharacter;
2026 Flags |= ARGUMENT_UNICODE;
2027 break;
2028 }
2029
2030 //
2031 // Retrieve the ArgumentString attriubutes
2032 //
2033 if ((Flags & ARGUMENT_UNICODE) != 0) {
2034 ArgumentMask = 0xffff;
2035 BytesPerArgumentCharacter = 2;
2036 } else {
2037 ArgumentMask = 0xff;
2038 BytesPerArgumentCharacter = 1;
2039 }
2040 if ((Flags & ARGUMENT_REVERSED) != 0) {
2041 BytesPerArgumentCharacter = -BytesPerArgumentCharacter;
2042 } else {
2043 //
2044 // Compute the number of characters in ArgumentString and store it in Count
2045 // ArgumentString is either null-terminated, or it contains Precision characters
2046 //
2047 for (Count = 0;
2048 (ArgumentString[Count * BytesPerArgumentCharacter] != '\0' ||
2049 (BytesPerArgumentCharacter > 1 &&
2050 ArgumentString[Count * BytesPerArgumentCharacter + 1]!= '\0')) &&
2051 (Count < Precision || ((Flags & PRECISION) == 0));
2052 Count++) {
2053 ArgumentCharacter = ((ArgumentString[Count * BytesPerArgumentCharacter] & 0xff) | ((ArgumentString[Count * BytesPerArgumentCharacter + 1]) << 8)) & ArgumentMask;
2054 if (ArgumentCharacter == 0) {
2055 break;
2056 }
2057 }
2058 }
2059
2060 if (Precision < Count) {
2061 Precision = Count;
2062 }
2063
2064 //
2065 // Pad before the string
2066 //
2067 if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH)) {
2068 LengthToReturn += ((Width - Precision) * BytesPerOutputCharacter);
2069 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {
2070 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, Width - Precision, ' ', BytesPerOutputCharacter);
2071 }
2072 }
2073
2074 if (ZeroPad) {
2075 if (Prefix != 0) {
2076 LengthToReturn += (1 * BytesPerOutputCharacter);
2077 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {
2078 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, 1, Prefix, BytesPerOutputCharacter);
2079 }
2080 }
2081 LengthToReturn += ((Precision - Count) * BytesPerOutputCharacter);
2082 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {
2083 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, Precision - Count, '0', BytesPerOutputCharacter);
2084 }
2085 } else {
2086 LengthToReturn += ((Precision - Count) * BytesPerOutputCharacter);
2087 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {
2088 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, Precision - Count, ' ', BytesPerOutputCharacter);
2089 }
2090 if (Prefix != 0) {
2091 LengthToReturn += (1 * BytesPerOutputCharacter);
2092 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {
2093 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, 1, Prefix, BytesPerOutputCharacter);
2094 }
2095 }
2096 }
2097
2098 //
2099 // Output the Prefix character if it is present
2100 //
2101 Index = 0;
2102 if (Prefix != 0) {
2103 Index++;
2104 }
2105
2106 //
2107 // Copy the string into the output buffer performing the required type conversions
2108 //
2109 while (Index < Count &&
2110 (ArgumentString[0] != '\0' ||
2111 (BytesPerArgumentCharacter > 1 && ArgumentString[1] != '\0'))) {
2112 ArgumentCharacter = ((*ArgumentString & 0xff) | (((UINT8)*(ArgumentString + 1)) << 8)) & ArgumentMask;
2113
2114 LengthToReturn += (1 * BytesPerOutputCharacter);
2115 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {
2116 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, 1, ArgumentCharacter, BytesPerOutputCharacter);
2117 }
2118 ArgumentString += BytesPerArgumentCharacter;
2119 Index++;
2120 if (Comma) {
2121 Digits++;
2122 if (Digits == 3) {
2123 Digits = 0;
2124 Index++;
2125 if (Index < Count) {
2126 LengthToReturn += (1 * BytesPerOutputCharacter);
2127 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {
2128 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, 1, ',', BytesPerOutputCharacter);
2129 }
2130 }
2131 }
2132 }
2133 }
2134
2135 //
2136 // Pad after the string
2137 //
2138 if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH | LEFT_JUSTIFY)) {
2139 LengthToReturn += ((Width - Precision) * BytesPerOutputCharacter);
2140 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {
2141 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, Width - Precision, ' ', BytesPerOutputCharacter);
2142 }
2143 }
2144
2145 //
2146 // Get the next character from the format string
2147 //
2148 Format += BytesPerFormatCharacter;
2149
2150 //
2151 // Get the next character from the format string
2152 //
2153 FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;
2154 }
2155
2156 if ((Flags & COUNT_ONLY_NO_PRINT) != 0) {
2157 return (LengthToReturn / BytesPerOutputCharacter);
2158 }
2159
2160 ASSERT (Buffer != NULL);
2161 //
2162 // Null terminate the Unicode or ASCII string
2163 //
2164 InternalPrintLibFillBuffer (Buffer, EndBuffer + BytesPerOutputCharacter, 1, 0, BytesPerOutputCharacter);
2165
2166 return ((Buffer - OriginalBuffer) / BytesPerOutputCharacter);
2167 }
2168
2169 /**
2170 Returns the number of characters that would be produced by if the formatted
2171 output were produced not including the Null-terminator.
2172
2173 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
2174
2175 If FormatString is NULL, then ASSERT() and 0 is returned.
2176 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more
2177 than PcdMaximumUnicodeStringLength Unicode characters not including the
2178 Null-terminator, then ASSERT() and 0 is returned.
2179
2180 @param[in] FormatString A Null-terminated Unicode format string.
2181 @param[in] Marker VA_LIST marker for the variable argument list.
2182
2183 @return The number of characters that would be produced, not including the
2184 Null-terminator.
2185 **/
2186 UINTN
2187 EFIAPI
2188 SPrintLength (
2189 IN CONST CHAR16 *FormatString,
2190 IN VA_LIST Marker
2191 )
2192 {
2193 ASSERT_UNICODE_BUFFER (FormatString);
2194 return InternalPrintLibSPrintMarker (NULL, 0, FORMAT_UNICODE | OUTPUT_UNICODE | COUNT_ONLY_NO_PRINT, (CHAR8 *)FormatString, Marker, NULL);
2195 }
2196
2197 /**
2198 Returns the number of characters that would be produced by if the formatted
2199 output were produced not including the Null-terminator.
2200
2201 If FormatString is NULL, then ASSERT() and 0 is returned.
2202 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more
2203 than PcdMaximumAsciiStringLength Ascii characters not including the
2204 Null-terminator, then ASSERT() and 0 is returned.
2205
2206 @param[in] FormatString A Null-terminated ASCII format string.
2207 @param[in] Marker VA_LIST marker for the variable argument list.
2208
2209 @return The number of characters that would be produced, not including the
2210 Null-terminator.
2211 **/
2212 UINTN
2213 EFIAPI
2214 SPrintLengthAsciiFormat (
2215 IN CONST CHAR8 *FormatString,
2216 IN VA_LIST Marker
2217 )
2218 {
2219 return InternalPrintLibSPrintMarker (NULL, 0, OUTPUT_UNICODE | COUNT_ONLY_NO_PRINT, (CHAR8 *)FormatString, Marker, NULL);
2220 }