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