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