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