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