]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/DxePrintLibPrint2Protocol/PrintLib.c
MdeModulePkg: Remove code wrapped by DISABLE_NEW_DEPRECATED_INTERFACES
[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 /**
596 Converts a decimal value to a Null-terminated Unicode string.
597
598 Converts the decimal number specified by Value to a Null-terminated Unicode
599 string specified by Buffer containing at most Width characters. No padding of
600 spaces is ever performed. If Width is 0 then a width of
601 MAXIMUM_VALUE_CHARACTERS is assumed. If the conversion contains more than
602 Width characters, then only the first Width characters are placed in Buffer.
603 Additional conversion parameters are specified in Flags.
604
605 The Flags bit LEFT_JUSTIFY is always ignored.
606 All conversions are left justified in Buffer.
607 If Width is 0, PREFIX_ZERO is ignored in Flags.
608 If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and
609 commas are inserted every 3rd digit starting from the right.
610 If RADIX_HEX is set in Flags, then the output buffer will be formatted in
611 hexadecimal format.
612 If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in
613 Buffer is a '-'.
614 If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, then
615 Buffer is padded with '0' characters so the combination of the optional '-'
616 sign character, '0' characters, digit characters for Value, and the
617 Null-terminator add up to Width characters.
618
619 If Buffer is not aligned on a 16-bit boundary, then ASSERT().
620 If an error would be returned, then the function will also ASSERT().
621
622 @param Buffer The pointer to the output buffer for the produced
623 Null-terminated Unicode string.
624 @param BufferSize The size of Buffer in bytes, including the
625 Null-terminator.
626 @param Flags The bitmask of flags that specify left justification,
627 zero pad, and commas.
628 @param Value The 64-bit signed value to convert to a string.
629 @param Width The maximum number of Unicode characters to place in
630 Buffer, not including the Null-terminator.
631
632 @retval RETURN_SUCCESS The decimal value is converted.
633 @retval RETURN_BUFFER_TOO_SMALL If BufferSize cannot hold the converted
634 value.
635 @retval RETURN_INVALID_PARAMETER If Buffer is NULL.
636 If PcdMaximumUnicodeStringLength is not
637 zero, and BufferSize is greater than
638 (PcdMaximumUnicodeStringLength *
639 sizeof (CHAR16) + 1).
640 If unsupported bits are set in Flags.
641 If both COMMA_TYPE and RADIX_HEX are set in
642 Flags.
643 If Width >= MAXIMUM_VALUE_CHARACTERS.
644
645 **/
646 RETURN_STATUS
647 EFIAPI
648 UnicodeValueToStringS (
649 IN OUT CHAR16 *Buffer,
650 IN UINTN BufferSize,
651 IN UINTN Flags,
652 IN INT64 Value,
653 IN UINTN Width
654 )
655 {
656 return mPrint2SProtocol->UnicodeValueToStringS (Buffer, BufferSize, Flags, Value, Width);
657 }
658
659 /**
660 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
661 ASCII format string and a VA_LIST argument list.
662
663 This function is similar as vsnprintf_s defined in C11.
664
665 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
666 and BufferSize.
667 The ASCII string is produced by parsing the format string specified by FormatString.
668 Arguments are pulled from the variable argument list specified by Marker based on
669 the contents of the format string.
670 The number of ASCII characters in the produced output buffer is returned not including
671 the Null-terminator.
672
673 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
674 unmodified and 0 is returned.
675 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
676 unmodified and 0 is returned.
677 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
678 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
679 is unmodified and 0 is returned.
680 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
681 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
682 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
683
684 If BufferSize is 0, then no output buffer is produced and 0 is returned.
685
686 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
687 ASCII string.
688 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
689 @param FormatString A Null-terminated ASCII format string.
690 @param Marker VA_LIST marker for the variable argument list.
691
692 @return The number of ASCII characters in the produced output buffer not including the
693 Null-terminator.
694
695 **/
696 UINTN
697 EFIAPI
698 AsciiVSPrint (
699 OUT CHAR8 *StartOfBuffer,
700 IN UINTN BufferSize,
701 IN CONST CHAR8 *FormatString,
702 IN VA_LIST Marker
703 )
704 {
705 UINT64 BaseListMarker[256 / sizeof (UINT64)];
706 BOOLEAN Converted;
707
708 Converted = DxePrintLibPrint2ProtocolVaListToBaseList (
709 TRUE,
710 FormatString,
711 Marker,
712 (BASE_LIST)BaseListMarker,
713 sizeof (BaseListMarker) - 8
714 );
715 if (!Converted) {
716 return 0;
717 }
718
719 return AsciiBSPrint (StartOfBuffer, BufferSize, FormatString, (BASE_LIST)BaseListMarker);
720 }
721
722 /**
723 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
724 ASCII format string and a BASE_LIST argument list.
725
726 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
727 and BufferSize.
728 The ASCII string is produced by parsing the format string specified by FormatString.
729 Arguments are pulled from the variable argument list specified by Marker based on
730 the contents of the format string.
731 The number of ASCII characters in the produced output buffer is returned not including
732 the Null-terminator.
733
734 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
735 unmodified and 0 is returned.
736 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
737 unmodified and 0 is returned.
738 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
739 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
740 is unmodified and 0 is returned.
741 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
742 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
743 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
744
745 If BufferSize is 0, then no output buffer is produced and 0 is returned.
746
747 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
748 ASCII string.
749 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
750 @param FormatString A Null-terminated ASCII format string.
751 @param Marker BASE_LIST marker for the variable argument list.
752
753 @return The number of ASCII characters in the produced output buffer not including the
754 Null-terminator.
755
756 **/
757 UINTN
758 EFIAPI
759 AsciiBSPrint (
760 OUT CHAR8 *StartOfBuffer,
761 IN UINTN BufferSize,
762 IN CONST CHAR8 *FormatString,
763 IN BASE_LIST Marker
764 )
765 {
766 return mPrint2SProtocol->AsciiBSPrint (StartOfBuffer, BufferSize, FormatString, Marker);
767 }
768
769 /**
770 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
771 ASCII format string and variable argument list.
772
773 This function is similar as snprintf_s defined in C11.
774
775 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
776 and BufferSize.
777 The ASCII string is produced by parsing the format string specified by FormatString.
778 Arguments are pulled from the variable argument list based on the contents of the
779 format string.
780 The number of ASCII characters in the produced output buffer is returned not including
781 the Null-terminator.
782
783 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
784 unmodified and 0 is returned.
785 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
786 unmodified and 0 is returned.
787 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
788 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
789 is unmodified and 0 is returned.
790 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than
791 PcdMaximumAsciiStringLength Ascii characters not including the Null-terminator, then
792 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
793
794 If BufferSize is 0, then no output buffer is produced and 0 is returned.
795
796 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
797 ASCII string.
798 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
799 @param FormatString A Null-terminated ASCII format string.
800 @param ... Variable argument list whose contents are accessed based on the
801 format string specified by FormatString.
802
803 @return The number of ASCII characters in the produced output buffer not including the
804 Null-terminator.
805
806 **/
807 UINTN
808 EFIAPI
809 AsciiSPrint (
810 OUT CHAR8 *StartOfBuffer,
811 IN UINTN BufferSize,
812 IN CONST CHAR8 *FormatString,
813 ...
814 )
815 {
816 VA_LIST Marker;
817 UINTN NumberOfPrinted;
818
819 VA_START (Marker, FormatString);
820 NumberOfPrinted = AsciiVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);
821 VA_END (Marker);
822 return NumberOfPrinted;
823 }
824
825 /**
826 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
827 Unicode format string and a VA_LIST argument list.
828
829 This function is similar as vsnprintf_s defined in C11.
830
831 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
832 and BufferSize.
833 The ASCII string is produced by parsing the format string specified by FormatString.
834 Arguments are pulled from the variable argument list specified by Marker based on
835 the contents of the format string.
836 The number of ASCII characters in the produced output buffer is returned not including
837 the Null-terminator.
838
839 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
840
841 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
842 unmodified and 0 is returned.
843 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
844 unmodified and 0 is returned.
845 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
846 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
847 is unmodified and 0 is returned.
848 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
849 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
850 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
851
852 If BufferSize is 0, then no output buffer is produced and 0 is returned.
853
854 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
855 ASCII string.
856 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
857 @param FormatString A Null-terminated Unicode format string.
858 @param Marker VA_LIST marker for the variable argument list.
859
860 @return The number of ASCII characters in the produced output buffer not including the
861 Null-terminator.
862
863 **/
864 UINTN
865 EFIAPI
866 AsciiVSPrintUnicodeFormat (
867 OUT CHAR8 *StartOfBuffer,
868 IN UINTN BufferSize,
869 IN CONST CHAR16 *FormatString,
870 IN VA_LIST Marker
871 )
872 {
873 UINT64 BaseListMarker[256 / sizeof (UINT64)];
874 BOOLEAN Converted;
875
876 ASSERT_UNICODE_BUFFER (FormatString);
877
878 Converted = DxePrintLibPrint2ProtocolVaListToBaseList (
879 FALSE,
880 (CHAR8 *)FormatString,
881 Marker,
882 (BASE_LIST)BaseListMarker,
883 sizeof (BaseListMarker) - 8
884 );
885 if (!Converted) {
886 return 0;
887 }
888
889 return AsciiBSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, (BASE_LIST)BaseListMarker);
890 }
891
892 /**
893 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
894 Unicode format string and a BASE_LIST argument list.
895
896 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer
897 and BufferSize.
898 The ASCII string is produced by parsing the format string specified by FormatString.
899 Arguments are pulled from the variable argument list specified by Marker based on
900 the contents of the format string.
901 The number of ASCII characters in the produced output buffer is returned not including
902 the Null-terminator.
903
904 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
905
906 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
907 unmodified and 0 is returned.
908 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
909 unmodified and 0 is returned.
910 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
911 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
912 is unmodified and 0 is returned.
913 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
914 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
915 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
916
917 If BufferSize is 0, then no output buffer is produced and 0 is returned.
918
919 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
920 ASCII string.
921 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
922 @param FormatString A Null-terminated Unicode format string.
923 @param Marker BASE_LIST marker for the variable argument list.
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 AsciiBSPrintUnicodeFormat (
932 OUT CHAR8 *StartOfBuffer,
933 IN UINTN BufferSize,
934 IN CONST CHAR16 *FormatString,
935 IN BASE_LIST Marker
936 )
937 {
938 ASSERT_UNICODE_BUFFER (FormatString);
939 return mPrint2SProtocol->AsciiBSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, Marker);
940 }
941
942 /**
943 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated
944 Unicode format string and variable argument list.
945
946 This function is similar as snprintf_s defined in C11.
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 based on the contents of the
952 format string.
953 The number of ASCII characters in the produced output buffer is returned not including
954 the Null-terminator.
955
956 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
957
958 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). Also, the output buffer is
959 unmodified and 0 is returned.
960 If BufferSize > 0 and FormatString is NULL, then ASSERT(). Also, the output buffer is
961 unmodified and 0 is returned.
962 If PcdMaximumAsciiStringLength is not zero, and BufferSize >
963 (PcdMaximumAsciiStringLength * sizeof (CHAR8)), then ASSERT(). Also, the output buffer
964 is unmodified and 0 is returned.
965 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
966 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
967 ASSERT(). Also, the output buffer is unmodified and 0 is returned.
968
969 If BufferSize is 0, then no output buffer is produced and 0 is returned.
970
971 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
972 ASCII string.
973 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
974 @param FormatString A Null-terminated Unicode format string.
975 @param ... Variable argument list whose contents are accessed based on the
976 format string specified by FormatString.
977
978 @return The number of ASCII characters in the produced output buffer not including the
979 Null-terminator.
980
981 **/
982 UINTN
983 EFIAPI
984 AsciiSPrintUnicodeFormat (
985 OUT CHAR8 *StartOfBuffer,
986 IN UINTN BufferSize,
987 IN CONST CHAR16 *FormatString,
988 ...
989 )
990 {
991 VA_LIST Marker;
992 UINTN NumberOfPrinted;
993
994 VA_START (Marker, FormatString);
995 NumberOfPrinted = AsciiVSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, Marker);
996 VA_END (Marker);
997 return NumberOfPrinted;
998 }
999
1000
1001 /**
1002 Converts a decimal value to a Null-terminated Ascii string.
1003
1004 Converts the decimal number specified by Value to a Null-terminated Ascii
1005 string specified by Buffer containing at most Width characters. No padding of
1006 spaces is ever performed. If Width is 0 then a width of
1007 MAXIMUM_VALUE_CHARACTERS is assumed. If the conversion contains more than
1008 Width characters, then only the first Width characters are placed in Buffer.
1009 Additional conversion parameters are specified in Flags.
1010
1011 The Flags bit LEFT_JUSTIFY is always ignored.
1012 All conversions are left justified in Buffer.
1013 If Width is 0, PREFIX_ZERO is ignored in Flags.
1014 If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and
1015 commas are inserted every 3rd digit starting from the right.
1016 If RADIX_HEX is set in Flags, then the output buffer will be formatted in
1017 hexadecimal format.
1018 If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in
1019 Buffer is a '-'.
1020 If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, then
1021 Buffer is padded with '0' characters so the combination of the optional '-'
1022 sign character, '0' characters, digit characters for Value, and the
1023 Null-terminator add up to Width characters.
1024
1025 If an error would be returned, then the function will ASSERT().
1026
1027 @param Buffer The pointer to the output buffer for the produced
1028 Null-terminated Ascii string.
1029 @param BufferSize The size of Buffer in bytes, including the
1030 Null-terminator.
1031 @param Flags The bitmask of flags that specify left justification,
1032 zero pad, and commas.
1033 @param Value The 64-bit signed value to convert to a string.
1034 @param Width The maximum number of Ascii characters to place in
1035 Buffer, not including the Null-terminator.
1036
1037 @retval RETURN_SUCCESS The decimal value is converted.
1038 @retval RETURN_BUFFER_TOO_SMALL If BufferSize cannot hold the converted
1039 value.
1040 @retval RETURN_INVALID_PARAMETER If Buffer is NULL.
1041 If PcdMaximumAsciiStringLength is not
1042 zero, and BufferSize is greater than
1043 PcdMaximumAsciiStringLength.
1044 If unsupported bits are set in Flags.
1045 If both COMMA_TYPE and RADIX_HEX are set in
1046 Flags.
1047 If Width >= MAXIMUM_VALUE_CHARACTERS.
1048
1049 **/
1050 RETURN_STATUS
1051 EFIAPI
1052 AsciiValueToStringS (
1053 IN OUT CHAR8 *Buffer,
1054 IN UINTN BufferSize,
1055 IN UINTN Flags,
1056 IN INT64 Value,
1057 IN UINTN Width
1058 )
1059 {
1060 return mPrint2SProtocol->AsciiValueToStringS (Buffer, BufferSize, Flags, Value, Width);
1061 }
1062
1063 #define PREFIX_SIGN BIT1
1064 #define PREFIX_BLANK BIT2
1065 #define LONG_TYPE BIT4
1066 #define OUTPUT_UNICODE BIT6
1067 #define FORMAT_UNICODE BIT8
1068 #define PAD_TO_WIDTH BIT9
1069 #define ARGUMENT_UNICODE BIT10
1070 #define PRECISION BIT11
1071 #define ARGUMENT_REVERSED BIT12
1072 #define COUNT_ONLY_NO_PRINT BIT13
1073 #define UNSIGNED_TYPE BIT14
1074
1075 //
1076 // Record date and time information
1077 //
1078 typedef struct {
1079 UINT16 Year;
1080 UINT8 Month;
1081 UINT8 Day;
1082 UINT8 Hour;
1083 UINT8 Minute;
1084 UINT8 Second;
1085 UINT8 Pad1;
1086 UINT32 Nanosecond;
1087 INT16 TimeZone;
1088 UINT8 Daylight;
1089 UINT8 Pad2;
1090 } TIME;
1091
1092 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mHexStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
1093
1094 /**
1095 Internal function that convert a number to a string in Buffer.
1096
1097 Print worker function that converts a decimal or hexadecimal number to an ASCII string in Buffer.
1098
1099 @param Buffer Location to place the ASCII string of Value.
1100 @param Value The value to convert to a Decimal or Hexadecimal string in Buffer.
1101 @param Radix Radix of the value
1102
1103 @return A pointer to the end of buffer filled with ASCII string.
1104
1105 **/
1106 CHAR8 *
1107 InternalPrintLibValueToString (
1108 IN OUT CHAR8 *Buffer,
1109 IN INT64 Value,
1110 IN UINTN Radix
1111 )
1112 {
1113 UINT32 Remainder;
1114
1115 //
1116 // Loop to convert one digit at a time in reverse order
1117 //
1118 *Buffer = 0;
1119 do {
1120 Value = (INT64)DivU64x32Remainder ((UINT64)Value, (UINT32)Radix, &Remainder);
1121 *(++Buffer) = mHexStr[Remainder];
1122 } while (Value != 0);
1123
1124 //
1125 // Return pointer of the end of filled buffer.
1126 //
1127 return Buffer;
1128 }
1129
1130 /**
1131 Worker function that produces a Null-terminated string in an output buffer
1132 based on a Null-terminated format string and a VA_LIST argument list.
1133
1134 VSPrint function to process format and place the results in Buffer. Since a
1135 VA_LIST is used this routine allows the nesting of Vararg routines. Thus
1136 this is the main print working routine.
1137
1138 If COUNT_ONLY_NO_PRINT is set in Flags, Buffer will not be modified at all.
1139
1140 @param[out] Buffer The character buffer to print the results of the
1141 parsing of Format into.
1142 @param[in] BufferSize The maximum number of characters to put into
1143 buffer.
1144 @param[in] Flags Initial flags value.
1145 Can only have FORMAT_UNICODE, OUTPUT_UNICODE,
1146 and COUNT_ONLY_NO_PRINT set.
1147 @param[in] Format A Null-terminated format string.
1148 @param[in] VaListMarker VA_LIST style variable argument list consumed by
1149 processing Format.
1150 @param[in] BaseListMarker BASE_LIST style variable argument list consumed
1151 by processing Format.
1152
1153 @return The number of characters printed not including the Null-terminator.
1154 If COUNT_ONLY_NO_PRINT was set returns the same, but without any
1155 modification to Buffer.
1156
1157 **/
1158 UINTN
1159 InternalPrintLibSPrintMarker (
1160 OUT CHAR8 *Buffer,
1161 IN UINTN BufferSize,
1162 IN UINTN Flags,
1163 IN CONST CHAR8 *Format,
1164 IN VA_LIST VaListMarker, OPTIONAL
1165 IN BASE_LIST BaseListMarker OPTIONAL
1166 );
1167
1168 /**
1169 Worker function that produces a Null-terminated string in an output buffer
1170 based on a Null-terminated format string and variable argument list.
1171
1172 VSPrint function to process format and place the results in Buffer. Since a
1173 VA_LIST is used this routine allows the nesting of Vararg routines. Thus
1174 this is the main print working routine
1175
1176 @param StartOfBuffer The character buffer to print the results of the parsing
1177 of Format into.
1178 @param BufferSize The maximum number of characters to put into buffer.
1179 Zero means no limit.
1180 @param Flags Initial flags value.
1181 Can only have FORMAT_UNICODE and OUTPUT_UNICODE set
1182 @param FormatString A Null-terminated format string.
1183 @param ... The variable argument list.
1184
1185 @return The number of characters printed.
1186
1187 **/
1188 UINTN
1189 EFIAPI
1190 InternalPrintLibSPrint (
1191 OUT CHAR8 *StartOfBuffer,
1192 IN UINTN BufferSize,
1193 IN UINTN Flags,
1194 IN CONST CHAR8 *FormatString,
1195 ...
1196 )
1197 {
1198 VA_LIST Marker;
1199 UINTN NumberOfPrinted;
1200
1201 VA_START (Marker, FormatString);
1202 NumberOfPrinted = InternalPrintLibSPrintMarker (StartOfBuffer, BufferSize, Flags, FormatString, Marker, NULL);
1203 VA_END (Marker);
1204 return NumberOfPrinted;
1205 }
1206
1207 #define WARNING_STATUS_NUMBER 5
1208 #define ERROR_STATUS_NUMBER 33
1209
1210 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 * CONST mStatusString[] = {
1211 "Success", // RETURN_SUCCESS = 0
1212 "Warning Unknown Glyph", // RETURN_WARN_UNKNOWN_GLYPH = 1
1213 "Warning Delete Failure", // RETURN_WARN_DELETE_FAILURE = 2
1214 "Warning Write Failure", // RETURN_WARN_WRITE_FAILURE = 3
1215 "Warning Buffer Too Small", // RETURN_WARN_BUFFER_TOO_SMALL = 4
1216 "Warning Stale Data", // RETURN_WARN_STALE_DATA = 5
1217 "Load Error", // RETURN_LOAD_ERROR = 1 | MAX_BIT
1218 "Invalid Parameter", // RETURN_INVALID_PARAMETER = 2 | MAX_BIT
1219 "Unsupported", // RETURN_UNSUPPORTED = 3 | MAX_BIT
1220 "Bad Buffer Size", // RETURN_BAD_BUFFER_SIZE = 4 | MAX_BIT
1221 "Buffer Too Small", // RETURN_BUFFER_TOO_SMALL, = 5 | MAX_BIT
1222 "Not Ready", // RETURN_NOT_READY = 6 | MAX_BIT
1223 "Device Error", // RETURN_DEVICE_ERROR = 7 | MAX_BIT
1224 "Write Protected", // RETURN_WRITE_PROTECTED = 8 | MAX_BIT
1225 "Out of Resources", // RETURN_OUT_OF_RESOURCES = 9 | MAX_BIT
1226 "Volume Corrupt", // RETURN_VOLUME_CORRUPTED = 10 | MAX_BIT
1227 "Volume Full", // RETURN_VOLUME_FULL = 11 | MAX_BIT
1228 "No Media", // RETURN_NO_MEDIA = 12 | MAX_BIT
1229 "Media changed", // RETURN_MEDIA_CHANGED = 13 | MAX_BIT
1230 "Not Found", // RETURN_NOT_FOUND = 14 | MAX_BIT
1231 "Access Denied", // RETURN_ACCESS_DENIED = 15 | MAX_BIT
1232 "No Response", // RETURN_NO_RESPONSE = 16 | MAX_BIT
1233 "No mapping", // RETURN_NO_MAPPING = 17 | MAX_BIT
1234 "Time out", // RETURN_TIMEOUT = 18 | MAX_BIT
1235 "Not started", // RETURN_NOT_STARTED = 19 | MAX_BIT
1236 "Already started", // RETURN_ALREADY_STARTED = 20 | MAX_BIT
1237 "Aborted", // RETURN_ABORTED = 21 | MAX_BIT
1238 "ICMP Error", // RETURN_ICMP_ERROR = 22 | MAX_BIT
1239 "TFTP Error", // RETURN_TFTP_ERROR = 23 | MAX_BIT
1240 "Protocol Error", // RETURN_PROTOCOL_ERROR = 24 | MAX_BIT
1241 "Incompatible Version", // RETURN_INCOMPATIBLE_VERSION = 25 | MAX_BIT
1242 "Security Violation", // RETURN_SECURITY_VIOLATION = 26 | MAX_BIT
1243 "CRC Error", // RETURN_CRC_ERROR = 27 | MAX_BIT
1244 "End of Media", // RETURN_END_OF_MEDIA = 28 | MAX_BIT
1245 "Reserved (29)", // RESERVED = 29 | MAX_BIT
1246 "Reserved (30)", // RESERVED = 30 | MAX_BIT
1247 "End of File", // RETURN_END_OF_FILE = 31 | MAX_BIT
1248 "Invalid Language", // RETURN_INVALID_LANGUAGE = 32 | MAX_BIT
1249 "Compromised Data" // RETURN_COMPROMISED_DATA = 33 | MAX_BIT
1250 };
1251
1252 /**
1253 Internal function that places the character into the Buffer.
1254
1255 Internal function that places ASCII or Unicode character into the Buffer.
1256
1257 @param Buffer The buffer to place the Unicode or ASCII string.
1258 @param EndBuffer The end of the input Buffer. No characters will be
1259 placed after that.
1260 @param Length The count of character to be placed into Buffer.
1261 (Negative value indicates no buffer fill.)
1262 @param Character The character to be placed into Buffer.
1263 @param Increment The character increment in Buffer.
1264
1265 @return Buffer.
1266
1267 **/
1268 CHAR8 *
1269 InternalPrintLibFillBuffer (
1270 OUT CHAR8 *Buffer,
1271 IN CHAR8 *EndBuffer,
1272 IN INTN Length,
1273 IN UINTN Character,
1274 IN INTN Increment
1275 )
1276 {
1277 INTN Index;
1278
1279 for (Index = 0; Index < Length && Buffer < EndBuffer; Index++) {
1280 *Buffer = (CHAR8) Character;
1281 if (Increment != 1) {
1282 *(Buffer + 1) = (CHAR8)(Character >> 8);
1283 }
1284 Buffer += Increment;
1285 }
1286
1287 return Buffer;
1288 }
1289
1290 /**
1291 Worker function that produces a Null-terminated string in an output buffer
1292 based on a Null-terminated format string and a VA_LIST argument list.
1293
1294 VSPrint function to process format and place the results in Buffer. Since a
1295 VA_LIST is used this routine allows the nesting of Vararg routines. Thus
1296 this is the main print working routine.
1297
1298 If COUNT_ONLY_NO_PRINT is set in Flags, Buffer will not be modified at all.
1299
1300 @param[out] Buffer The character buffer to print the results of the
1301 parsing of Format into.
1302 @param[in] BufferSize The maximum number of characters to put into
1303 buffer.
1304 @param[in] Flags Initial flags value.
1305 Can only have FORMAT_UNICODE, OUTPUT_UNICODE,
1306 and COUNT_ONLY_NO_PRINT set.
1307 @param[in] Format A Null-terminated format string.
1308 @param[in] VaListMarker VA_LIST style variable argument list consumed by
1309 processing Format.
1310 @param[in] BaseListMarker BASE_LIST style variable argument list consumed
1311 by processing Format.
1312
1313 @return The number of characters printed not including the Null-terminator.
1314 If COUNT_ONLY_NO_PRINT was set returns the same, but without any
1315 modification to Buffer.
1316
1317 **/
1318 UINTN
1319 InternalPrintLibSPrintMarker (
1320 OUT CHAR8 *Buffer,
1321 IN UINTN BufferSize,
1322 IN UINTN Flags,
1323 IN CONST CHAR8 *Format,
1324 IN VA_LIST VaListMarker, OPTIONAL
1325 IN BASE_LIST BaseListMarker OPTIONAL
1326 )
1327 {
1328 CHAR8 *OriginalBuffer;
1329 CHAR8 *EndBuffer;
1330 CHAR8 ValueBuffer[MAXIMUM_VALUE_CHARACTERS];
1331 UINT32 BytesPerOutputCharacter;
1332 UINTN BytesPerFormatCharacter;
1333 UINTN FormatMask;
1334 UINTN FormatCharacter;
1335 UINTN Width;
1336 UINTN Precision;
1337 INT64 Value;
1338 CONST CHAR8 *ArgumentString;
1339 UINTN Character;
1340 GUID *TmpGuid;
1341 TIME *TmpTime;
1342 UINTN Count;
1343 UINTN ArgumentMask;
1344 INTN BytesPerArgumentCharacter;
1345 UINTN ArgumentCharacter;
1346 BOOLEAN Done;
1347 UINTN Index;
1348 CHAR8 Prefix;
1349 BOOLEAN ZeroPad;
1350 BOOLEAN Comma;
1351 UINTN Digits;
1352 UINTN Radix;
1353 RETURN_STATUS Status;
1354 UINT32 GuidData1;
1355 UINT16 GuidData2;
1356 UINT16 GuidData3;
1357 UINTN LengthToReturn;
1358
1359 //
1360 // If you change this code be sure to match the 2 versions of this function.
1361 // Nearly identical logic is found in the BasePrintLib and
1362 // DxePrintLibPrint2Protocol (both PrintLib instances).
1363 //
1364
1365 //
1366 // 1. Buffer shall not be a null pointer when both BufferSize > 0 and
1367 // COUNT_ONLY_NO_PRINT is not set in Flags.
1368 //
1369 if ((BufferSize > 0) && ((Flags & COUNT_ONLY_NO_PRINT) == 0)) {
1370 SAFE_PRINT_CONSTRAINT_CHECK ((Buffer != NULL), 0);
1371 }
1372
1373 //
1374 // 2. Format shall not be a null pointer when BufferSize > 0 or when
1375 // COUNT_ONLY_NO_PRINT is set in Flags.
1376 //
1377 if ((BufferSize > 0) || ((Flags & COUNT_ONLY_NO_PRINT) != 0)) {
1378 SAFE_PRINT_CONSTRAINT_CHECK ((Format != NULL), 0);
1379 }
1380
1381 //
1382 // 3. BufferSize shall not be greater than RSIZE_MAX for Unicode output or
1383 // ASCII_RSIZE_MAX for Ascii output.
1384 //
1385 if ((Flags & OUTPUT_UNICODE) != 0) {
1386 if (RSIZE_MAX != 0) {
1387 SAFE_PRINT_CONSTRAINT_CHECK ((BufferSize <= RSIZE_MAX), 0);
1388 }
1389 BytesPerOutputCharacter = 2;
1390 } else {
1391 if (ASCII_RSIZE_MAX != 0) {
1392 SAFE_PRINT_CONSTRAINT_CHECK ((BufferSize <= ASCII_RSIZE_MAX), 0);
1393 }
1394 BytesPerOutputCharacter = 1;
1395 }
1396
1397 //
1398 // 4. Format shall not contain more than RSIZE_MAX Unicode characters or
1399 // ASCII_RSIZE_MAX Ascii characters.
1400 //
1401 if ((Flags & FORMAT_UNICODE) != 0) {
1402 if (RSIZE_MAX != 0) {
1403 SAFE_PRINT_CONSTRAINT_CHECK ((StrnLenS ((CHAR16 *)Format, RSIZE_MAX + 1) <= RSIZE_MAX), 0);
1404 }
1405 BytesPerFormatCharacter = 2;
1406 FormatMask = 0xffff;
1407 } else {
1408 if (ASCII_RSIZE_MAX != 0) {
1409 SAFE_PRINT_CONSTRAINT_CHECK ((AsciiStrnLenS (Format, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), 0);
1410 }
1411 BytesPerFormatCharacter = 1;
1412 FormatMask = 0xff;
1413 }
1414
1415 if ((Flags & COUNT_ONLY_NO_PRINT) != 0) {
1416 if (BufferSize == 0) {
1417 Buffer = NULL;
1418 }
1419 } else {
1420 //
1421 // We can run without a Buffer for counting only.
1422 //
1423 if (BufferSize == 0) {
1424 return 0;
1425 }
1426 }
1427
1428 LengthToReturn = 0;
1429 EndBuffer = NULL;
1430 OriginalBuffer = NULL;
1431
1432 //
1433 // Reserve space for the Null terminator.
1434 //
1435 if (Buffer != NULL) {
1436 BufferSize--;
1437 OriginalBuffer = Buffer;
1438
1439 //
1440 // Set the tag for the end of the input Buffer.
1441 //
1442 EndBuffer = Buffer + BufferSize * BytesPerOutputCharacter;
1443 }
1444
1445 //
1446 // Get the first character from the format string
1447 //
1448 FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;
1449
1450 //
1451 // Loop until the end of the format string is reached or the output buffer is full
1452 //
1453 while (FormatCharacter != 0) {
1454 if ((Buffer != NULL) && (Buffer >= EndBuffer)) {
1455 break;
1456 }
1457 //
1458 // Clear all the flag bits except those that may have been passed in
1459 //
1460 Flags &= (UINTN) (OUTPUT_UNICODE | FORMAT_UNICODE | COUNT_ONLY_NO_PRINT);
1461
1462 //
1463 // Set the default width to zero, and the default precision to 1
1464 //
1465 Width = 0;
1466 Precision = 1;
1467 Prefix = 0;
1468 Comma = FALSE;
1469 ZeroPad = FALSE;
1470 Count = 0;
1471 Digits = 0;
1472
1473 switch (FormatCharacter) {
1474 case '%':
1475 //
1476 // Parse Flags and Width
1477 //
1478 for (Done = FALSE; !Done; ) {
1479 Format += BytesPerFormatCharacter;
1480 FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;
1481 switch (FormatCharacter) {
1482 case '.':
1483 Flags |= PRECISION;
1484 break;
1485 case '-':
1486 Flags |= LEFT_JUSTIFY;
1487 break;
1488 case '+':
1489 Flags |= PREFIX_SIGN;
1490 break;
1491 case ' ':
1492 Flags |= PREFIX_BLANK;
1493 break;
1494 case ',':
1495 Flags |= COMMA_TYPE;
1496 break;
1497 case 'L':
1498 case 'l':
1499 Flags |= LONG_TYPE;
1500 break;
1501 case '*':
1502 if ((Flags & PRECISION) == 0) {
1503 Flags |= PAD_TO_WIDTH;
1504 if (BaseListMarker == NULL) {
1505 Width = VA_ARG (VaListMarker, UINTN);
1506 } else {
1507 Width = BASE_ARG (BaseListMarker, UINTN);
1508 }
1509 } else {
1510 if (BaseListMarker == NULL) {
1511 Precision = VA_ARG (VaListMarker, UINTN);
1512 } else {
1513 Precision = BASE_ARG (BaseListMarker, UINTN);
1514 }
1515 }
1516 break;
1517 case '0':
1518 if ((Flags & PRECISION) == 0) {
1519 Flags |= PREFIX_ZERO;
1520 }
1521 case '1':
1522 case '2':
1523 case '3':
1524 case '4':
1525 case '5':
1526 case '6':
1527 case '7':
1528 case '8':
1529 case '9':
1530 for (Count = 0; ((FormatCharacter >= '0') && (FormatCharacter <= '9')); ){
1531 Count = (Count * 10) + FormatCharacter - '0';
1532 Format += BytesPerFormatCharacter;
1533 FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;
1534 }
1535 Format -= BytesPerFormatCharacter;
1536 if ((Flags & PRECISION) == 0) {
1537 Flags |= PAD_TO_WIDTH;
1538 Width = Count;
1539 } else {
1540 Precision = Count;
1541 }
1542 break;
1543
1544 case '\0':
1545 //
1546 // Make no output if Format string terminates unexpectedly when
1547 // looking up for flag, width, precision and type.
1548 //
1549 Format -= BytesPerFormatCharacter;
1550 Precision = 0;
1551 //
1552 // break skipped on purpose.
1553 //
1554 default:
1555 Done = TRUE;
1556 break;
1557 }
1558 }
1559
1560 //
1561 // Handle each argument type
1562 //
1563 switch (FormatCharacter) {
1564 case 'p':
1565 //
1566 // Flag space, +, 0, L & l are invalid for type p.
1567 //
1568 Flags &= ~((UINTN) (PREFIX_BLANK | PREFIX_SIGN | PREFIX_ZERO | LONG_TYPE));
1569 if (sizeof (VOID *) > 4) {
1570 Flags |= LONG_TYPE;
1571 }
1572 //
1573 // break skipped on purpose
1574 //
1575 case 'X':
1576 Flags |= PREFIX_ZERO;
1577 //
1578 // break skipped on purpose
1579 //
1580 case 'x':
1581 Flags |= RADIX_HEX;
1582 //
1583 // break skipped on purpose
1584 //
1585 case 'u':
1586 if ((Flags & RADIX_HEX) == 0) {
1587 Flags &= ~((UINTN) (PREFIX_SIGN));
1588 Flags |= UNSIGNED_TYPE;
1589 }
1590 //
1591 // break skipped on purpose
1592 //
1593 case 'd':
1594 if ((Flags & LONG_TYPE) == 0) {
1595 //
1596 // 'd', 'u', 'x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".
1597 // This assumption is made so the format string definition is compatible with the ANSI C
1598 // Specification for formatted strings. It is recommended that the Base Types be used
1599 // everywhere, but in this one case, compliance with ANSI C is more important, and
1600 // provides an implementation that is compatible with that largest possible set of CPU
1601 // architectures. This is why the type "int" is used in this one case.
1602 //
1603 if (BaseListMarker == NULL) {
1604 Value = VA_ARG (VaListMarker, int);
1605 } else {
1606 Value = BASE_ARG (BaseListMarker, int);
1607 }
1608 } else {
1609 if (BaseListMarker == NULL) {
1610 Value = VA_ARG (VaListMarker, INT64);
1611 } else {
1612 Value = BASE_ARG (BaseListMarker, INT64);
1613 }
1614 }
1615 if ((Flags & PREFIX_BLANK) != 0) {
1616 Prefix = ' ';
1617 }
1618 if ((Flags & PREFIX_SIGN) != 0) {
1619 Prefix = '+';
1620 }
1621 if ((Flags & COMMA_TYPE) != 0) {
1622 Comma = TRUE;
1623 }
1624 if ((Flags & RADIX_HEX) == 0) {
1625 Radix = 10;
1626 if (Comma) {
1627 Flags &= ~((UINTN) PREFIX_ZERO);
1628 Precision = 1;
1629 }
1630 if (Value < 0 && (Flags & UNSIGNED_TYPE) == 0) {
1631 Flags |= PREFIX_SIGN;
1632 Prefix = '-';
1633 Value = -Value;
1634 } else if ((Flags & UNSIGNED_TYPE) != 0 && (Flags & LONG_TYPE) == 0) {
1635 //
1636 // 'd', 'u', 'x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".
1637 // This assumption is made so the format string definition is compatible with the ANSI C
1638 // Specification for formatted strings. It is recommended that the Base Types be used
1639 // everywhere, but in this one case, compliance with ANSI C is more important, and
1640 // provides an implementation that is compatible with that largest possible set of CPU
1641 // architectures. This is why the type "unsigned int" is used in this one case.
1642 //
1643 Value = (unsigned int)Value;
1644 }
1645 } else {
1646 Radix = 16;
1647 Comma = FALSE;
1648 if ((Flags & LONG_TYPE) == 0 && Value < 0) {
1649 //
1650 // 'd', 'u', 'x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".
1651 // This assumption is made so the format string definition is compatible with the ANSI C
1652 // Specification for formatted strings. It is recommended that the Base Types be used
1653 // everywhere, but in this one case, compliance with ANSI C is more important, and
1654 // provides an implementation that is compatible with that largest possible set of CPU
1655 // architectures. This is why the type "unsigned int" is used in this one case.
1656 //
1657 Value = (unsigned int)Value;
1658 }
1659 }
1660 //
1661 // Convert Value to a reversed string
1662 //
1663 Count = InternalPrintLibValueToString (ValueBuffer, Value, Radix) - ValueBuffer;
1664 if (Value == 0 && Precision == 0) {
1665 Count = 0;
1666 }
1667 ArgumentString = (CHAR8 *)ValueBuffer + Count;
1668
1669 Digits = Count % 3;
1670 if (Digits != 0) {
1671 Digits = 3 - Digits;
1672 }
1673 if (Comma && Count != 0) {
1674 Count += ((Count - 1) / 3);
1675 }
1676 if (Prefix != 0) {
1677 Count++;
1678 Precision++;
1679 }
1680 Flags |= ARGUMENT_REVERSED;
1681 ZeroPad = TRUE;
1682 if ((Flags & PREFIX_ZERO) != 0) {
1683 if ((Flags & LEFT_JUSTIFY) == 0) {
1684 if ((Flags & PAD_TO_WIDTH) != 0) {
1685 if ((Flags & PRECISION) == 0) {
1686 Precision = Width;
1687 }
1688 }
1689 }
1690 }
1691 break;
1692
1693 case 's':
1694 case 'S':
1695 Flags |= ARGUMENT_UNICODE;
1696 //
1697 // break skipped on purpose
1698 //
1699 case 'a':
1700 if (BaseListMarker == NULL) {
1701 ArgumentString = VA_ARG (VaListMarker, CHAR8 *);
1702 } else {
1703 ArgumentString = BASE_ARG (BaseListMarker, CHAR8 *);
1704 }
1705 if (ArgumentString == NULL) {
1706 Flags &= (~(UINTN)ARGUMENT_UNICODE);
1707 ArgumentString = "<null string>";
1708 }
1709 //
1710 // Set the default precision for string to be zero if not specified.
1711 //
1712 if ((Flags & PRECISION) == 0) {
1713 Precision = 0;
1714 }
1715 break;
1716
1717 case 'c':
1718 if (BaseListMarker == NULL) {
1719 Character = VA_ARG (VaListMarker, UINTN) & 0xffff;
1720 } else {
1721 Character = BASE_ARG (BaseListMarker, UINTN) & 0xffff;
1722 }
1723 ArgumentString = (CHAR8 *)&Character;
1724 Flags |= ARGUMENT_UNICODE;
1725 break;
1726
1727 case 'g':
1728 if (BaseListMarker == NULL) {
1729 TmpGuid = VA_ARG (VaListMarker, GUID *);
1730 } else {
1731 TmpGuid = BASE_ARG (BaseListMarker, GUID *);
1732 }
1733 if (TmpGuid == NULL) {
1734 ArgumentString = "<null guid>";
1735 } else {
1736 GuidData1 = ReadUnaligned32 (&(TmpGuid->Data1));
1737 GuidData2 = ReadUnaligned16 (&(TmpGuid->Data2));
1738 GuidData3 = ReadUnaligned16 (&(TmpGuid->Data3));
1739 InternalPrintLibSPrint (
1740 ValueBuffer,
1741 MAXIMUM_VALUE_CHARACTERS,
1742 0,
1743 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1744 GuidData1,
1745 GuidData2,
1746 GuidData3,
1747 TmpGuid->Data4[0],
1748 TmpGuid->Data4[1],
1749 TmpGuid->Data4[2],
1750 TmpGuid->Data4[3],
1751 TmpGuid->Data4[4],
1752 TmpGuid->Data4[5],
1753 TmpGuid->Data4[6],
1754 TmpGuid->Data4[7]
1755 );
1756 ArgumentString = ValueBuffer;
1757 }
1758 break;
1759
1760 case 't':
1761 if (BaseListMarker == NULL) {
1762 TmpTime = VA_ARG (VaListMarker, TIME *);
1763 } else {
1764 TmpTime = BASE_ARG (BaseListMarker, TIME *);
1765 }
1766 if (TmpTime == NULL) {
1767 ArgumentString = "<null time>";
1768 } else {
1769 InternalPrintLibSPrint (
1770 ValueBuffer,
1771 MAXIMUM_VALUE_CHARACTERS,
1772 0,
1773 "%02d/%02d/%04d %02d:%02d",
1774 TmpTime->Month,
1775 TmpTime->Day,
1776 TmpTime->Year,
1777 TmpTime->Hour,
1778 TmpTime->Minute
1779 );
1780 ArgumentString = ValueBuffer;
1781 }
1782 break;
1783
1784 case 'r':
1785 if (BaseListMarker == NULL) {
1786 Status = VA_ARG (VaListMarker, RETURN_STATUS);
1787 } else {
1788 Status = BASE_ARG (BaseListMarker, RETURN_STATUS);
1789 }
1790 ArgumentString = ValueBuffer;
1791 if (RETURN_ERROR (Status)) {
1792 //
1793 // Clear error bit
1794 //
1795 Index = Status & ~MAX_BIT;
1796 if (Index > 0 && Index <= ERROR_STATUS_NUMBER) {
1797 ArgumentString = mStatusString [Index + WARNING_STATUS_NUMBER];
1798 }
1799 } else {
1800 Index = Status;
1801 if (Index <= WARNING_STATUS_NUMBER) {
1802 ArgumentString = mStatusString [Index];
1803 }
1804 }
1805 if (ArgumentString == ValueBuffer) {
1806 InternalPrintLibSPrint ((CHAR8 *) ValueBuffer, MAXIMUM_VALUE_CHARACTERS, 0, "%08X", Status);
1807 }
1808 break;
1809
1810 case '\r':
1811 Format += BytesPerFormatCharacter;
1812 FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;
1813 if (FormatCharacter == '\n') {
1814 //
1815 // Translate '\r\n' to '\r\n'
1816 //
1817 ArgumentString = "\r\n";
1818 } else {
1819 //
1820 // Translate '\r' to '\r'
1821 //
1822 ArgumentString = "\r";
1823 Format -= BytesPerFormatCharacter;
1824 }
1825 break;
1826
1827 case '\n':
1828 //
1829 // Translate '\n' to '\r\n' and '\n\r' to '\r\n'
1830 //
1831 ArgumentString = "\r\n";
1832 Format += BytesPerFormatCharacter;
1833 FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;
1834 if (FormatCharacter != '\r') {
1835 Format -= BytesPerFormatCharacter;
1836 }
1837 break;
1838
1839 case '%':
1840 default:
1841 //
1842 // if the type is '%' or unknown, then print it to the screen
1843 //
1844 ArgumentString = (CHAR8 *)&FormatCharacter;
1845 Flags |= ARGUMENT_UNICODE;
1846 break;
1847 }
1848 break;
1849
1850 case '\r':
1851 Format += BytesPerFormatCharacter;
1852 FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;
1853 if (FormatCharacter == '\n') {
1854 //
1855 // Translate '\r\n' to '\r\n'
1856 //
1857 ArgumentString = "\r\n";
1858 } else {
1859 //
1860 // Translate '\r' to '\r'
1861 //
1862 ArgumentString = "\r";
1863 Format -= BytesPerFormatCharacter;
1864 }
1865 break;
1866
1867 case '\n':
1868 //
1869 // Translate '\n' to '\r\n' and '\n\r' to '\r\n'
1870 //
1871 ArgumentString = "\r\n";
1872 Format += BytesPerFormatCharacter;
1873 FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;
1874 if (FormatCharacter != '\r') {
1875 Format -= BytesPerFormatCharacter;
1876 }
1877 break;
1878
1879 default:
1880 ArgumentString = (CHAR8 *)&FormatCharacter;
1881 Flags |= ARGUMENT_UNICODE;
1882 break;
1883 }
1884
1885 //
1886 // Retrieve the ArgumentString attriubutes
1887 //
1888 if ((Flags & ARGUMENT_UNICODE) != 0) {
1889 ArgumentMask = 0xffff;
1890 BytesPerArgumentCharacter = 2;
1891 } else {
1892 ArgumentMask = 0xff;
1893 BytesPerArgumentCharacter = 1;
1894 }
1895 if ((Flags & ARGUMENT_REVERSED) != 0) {
1896 BytesPerArgumentCharacter = -BytesPerArgumentCharacter;
1897 } else {
1898 //
1899 // Compute the number of characters in ArgumentString and store it in Count
1900 // ArgumentString is either null-terminated, or it contains Precision characters
1901 //
1902 for (Count = 0;
1903 (ArgumentString[Count * BytesPerArgumentCharacter] != '\0' ||
1904 (BytesPerArgumentCharacter > 1 &&
1905 ArgumentString[Count * BytesPerArgumentCharacter + 1]!= '\0')) &&
1906 (Count < Precision || ((Flags & PRECISION) == 0));
1907 Count++) {
1908 ArgumentCharacter = ((ArgumentString[Count * BytesPerArgumentCharacter] & 0xff) | ((ArgumentString[Count * BytesPerArgumentCharacter + 1]) << 8)) & ArgumentMask;
1909 if (ArgumentCharacter == 0) {
1910 break;
1911 }
1912 }
1913 }
1914
1915 if (Precision < Count) {
1916 Precision = Count;
1917 }
1918
1919 //
1920 // Pad before the string
1921 //
1922 if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH)) {
1923 LengthToReturn += ((Width - Precision) * BytesPerOutputCharacter);
1924 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {
1925 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, Width - Precision, ' ', BytesPerOutputCharacter);
1926 }
1927 }
1928
1929 if (ZeroPad) {
1930 if (Prefix != 0) {
1931 LengthToReturn += (1 * BytesPerOutputCharacter);
1932 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {
1933 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, 1, Prefix, BytesPerOutputCharacter);
1934 }
1935 }
1936 LengthToReturn += ((Precision - Count) * BytesPerOutputCharacter);
1937 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {
1938 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, Precision - Count, '0', BytesPerOutputCharacter);
1939 }
1940 } else {
1941 LengthToReturn += ((Precision - Count) * BytesPerOutputCharacter);
1942 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {
1943 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, Precision - Count, ' ', BytesPerOutputCharacter);
1944 }
1945 if (Prefix != 0) {
1946 LengthToReturn += (1 * BytesPerOutputCharacter);
1947 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {
1948 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, 1, Prefix, BytesPerOutputCharacter);
1949 }
1950 }
1951 }
1952
1953 //
1954 // Output the Prefix character if it is present
1955 //
1956 Index = 0;
1957 if (Prefix != 0) {
1958 Index++;
1959 }
1960
1961 //
1962 // Copy the string into the output buffer performing the required type conversions
1963 //
1964 while (Index < Count &&
1965 (ArgumentString[0] != '\0' ||
1966 (BytesPerArgumentCharacter > 1 && ArgumentString[1] != '\0'))) {
1967 ArgumentCharacter = ((*ArgumentString & 0xff) | (((UINT8)*(ArgumentString + 1)) << 8)) & ArgumentMask;
1968
1969 LengthToReturn += (1 * BytesPerOutputCharacter);
1970 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {
1971 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, 1, ArgumentCharacter, BytesPerOutputCharacter);
1972 }
1973 ArgumentString += BytesPerArgumentCharacter;
1974 Index++;
1975 if (Comma) {
1976 Digits++;
1977 if (Digits == 3) {
1978 Digits = 0;
1979 Index++;
1980 if (Index < Count) {
1981 LengthToReturn += (1 * BytesPerOutputCharacter);
1982 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {
1983 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, 1, ',', BytesPerOutputCharacter);
1984 }
1985 }
1986 }
1987 }
1988 }
1989
1990 //
1991 // Pad after the string
1992 //
1993 if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH | LEFT_JUSTIFY)) {
1994 LengthToReturn += ((Width - Precision) * BytesPerOutputCharacter);
1995 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {
1996 Buffer = InternalPrintLibFillBuffer (Buffer, EndBuffer, Width - Precision, ' ', BytesPerOutputCharacter);
1997 }
1998 }
1999
2000 //
2001 // Get the next character from the format string
2002 //
2003 Format += BytesPerFormatCharacter;
2004
2005 //
2006 // Get the next character from the format string
2007 //
2008 FormatCharacter = ((*Format & 0xff) | ((BytesPerFormatCharacter == 1) ? 0 : (*(Format + 1) << 8))) & FormatMask;
2009 }
2010
2011 if ((Flags & COUNT_ONLY_NO_PRINT) != 0) {
2012 return (LengthToReturn / BytesPerOutputCharacter);
2013 }
2014
2015 ASSERT (Buffer != NULL);
2016 //
2017 // Null terminate the Unicode or ASCII string
2018 //
2019 InternalPrintLibFillBuffer (Buffer, EndBuffer + BytesPerOutputCharacter, 1, 0, BytesPerOutputCharacter);
2020
2021 return ((Buffer - OriginalBuffer) / BytesPerOutputCharacter);
2022 }
2023
2024 /**
2025 Returns the number of characters that would be produced by if the formatted
2026 output were produced not including the Null-terminator.
2027
2028 If FormatString is not aligned on a 16-bit boundary, then ASSERT().
2029
2030 If FormatString is NULL, then ASSERT() and 0 is returned.
2031 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more
2032 than PcdMaximumUnicodeStringLength Unicode characters not including the
2033 Null-terminator, then ASSERT() and 0 is returned.
2034
2035 @param[in] FormatString A Null-terminated Unicode format string.
2036 @param[in] Marker VA_LIST marker for the variable argument list.
2037
2038 @return The number of characters that would be produced, not including the
2039 Null-terminator.
2040 **/
2041 UINTN
2042 EFIAPI
2043 SPrintLength (
2044 IN CONST CHAR16 *FormatString,
2045 IN VA_LIST Marker
2046 )
2047 {
2048 ASSERT_UNICODE_BUFFER (FormatString);
2049 return InternalPrintLibSPrintMarker (NULL, 0, FORMAT_UNICODE | OUTPUT_UNICODE | COUNT_ONLY_NO_PRINT, (CHAR8 *)FormatString, Marker, NULL);
2050 }
2051
2052 /**
2053 Returns the number of characters that would be produced by if the formatted
2054 output were produced not including the Null-terminator.
2055
2056 If FormatString is NULL, then ASSERT() and 0 is returned.
2057 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more
2058 than PcdMaximumAsciiStringLength Ascii characters not including the
2059 Null-terminator, then ASSERT() and 0 is returned.
2060
2061 @param[in] FormatString A Null-terminated ASCII format string.
2062 @param[in] Marker VA_LIST marker for the variable argument list.
2063
2064 @return The number of characters that would be produced, not including the
2065 Null-terminator.
2066 **/
2067 UINTN
2068 EFIAPI
2069 SPrintLengthAsciiFormat (
2070 IN CONST CHAR8 *FormatString,
2071 IN VA_LIST Marker
2072 )
2073 {
2074 return InternalPrintLibSPrintMarker (NULL, 0, OUTPUT_UNICODE | COUNT_ONLY_NO_PRINT, (CHAR8 *)FormatString, Marker, NULL);
2075 }