1 /*++ 2 3 Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR> 4 This program and the accompanying materials 5 are licensed and made available under the terms and conditions of the BSD License 6 which accompanies this distribution. The full text of the license may be found at 7 http://opensource.org/licenses/bsd-license.php 8 9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 12 13 Module Name: 14 15 PrintLib.c 16 17 Abstract: 18 19 Print Library. 20 21 --*/ 22 23 #include "PrintLibInternal.h" 24 25 #define WARNING_STATUS_NUMBER 4 26 #define ERROR_STATUS_NUMBER 31 27 #define ASSERT_UNICODE_BUFFER(Buffer) ASSERT ((((UINTN) (Buffer)) & 0x01) == 0) 28 29 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *StatusString [] = { 30 "Success", // RETURN_SUCCESS = 0 31 "Warning Unknown Glyph", // RETURN_WARN_UNKNOWN_GLYPH = 1 32 "Warning Delete Failure", // RETURN_WARN_DELETE_FAILURE = 2 33 "Warning Write Failure", // RETURN_WARN_WRITE_FAILURE = 3 34 "Warning Buffer Too Small", // RETURN_WARN_BUFFER_TOO_SMALL = 4 35 "Load Error", // RETURN_LOAD_ERROR = 1 | MAX_BIT 36 "Invalid Parameter", // RETURN_INVALID_PARAMETER = 2 | MAX_BIT 37 "Unsupported", // RETURN_UNSUPPORTED = 3 | MAX_BIT 38 "Bad Buffer Size", // RETURN_BAD_BUFFER_SIZE = 4 | MAX_BIT 39 "Buffer Too Small", // RETURN_BUFFER_TOO_SMALL, = 5 | MAX_BIT 40 "Not Ready", // RETURN_NOT_READY = 6 | MAX_BIT 41 "Device Error", // RETURN_DEVICE_ERROR = 7 | MAX_BIT 42 "Write Protected", // RETURN_WRITE_PROTECTED = 8 | MAX_BIT 43 "Out of Resources", // RETURN_OUT_OF_RESOURCES = 9 | MAX_BIT 44 "Volume Corrupt", // RETURN_VOLUME_CORRUPTED = 10 | MAX_BIT 45 "Volume Full", // RETURN_VOLUME_FULL = 11 | MAX_BIT 46 "No Media", // RETURN_NO_MEDIA = 12 | MAX_BIT 47 "Media changed", // RETURN_MEDIA_CHANGED = 13 | MAX_BIT 48 "Not Found", // RETURN_NOT_FOUND = 14 | MAX_BIT 49 "Access Denied", // RETURN_ACCESS_DENIED = 15 | MAX_BIT 50 "No Response", // RETURN_NO_RESPONSE = 16 | MAX_BIT 51 "No mapping", // RETURN_NO_MAPPING = 17 | MAX_BIT 52 "Time out", // RETURN_TIMEOUT = 18 | MAX_BIT 53 "Not started", // RETURN_NOT_STARTED = 19 | MAX_BIT 54 "Already started", // RETURN_ALREADY_STARTED = 20 | MAX_BIT 55 "Aborted", // RETURN_ABORTED = 21 | MAX_BIT 56 "ICMP Error", // RETURN_ICMP_ERROR = 22 | MAX_BIT 57 "TFTP Error", // RETURN_TFTP_ERROR = 23 | MAX_BIT 58 "Protocol Error", // RETURN_PROTOCOL_ERROR = 24 | MAX_BIT 59 "Incompatible Version", // RETURN_INCOMPATIBLE_VERSION = 25 | MAX_BIT 60 "Security Violation", // RETURN_SECURITY_VIOLATION = 26 | MAX_BIT 61 "CRC Error", // RETURN_CRC_ERROR = 27 | MAX_BIT 62 "End of Media", // RETURN_END_OF_MEDIA = 28 | MAX_BIT 63 "Reserved (29)", // RESERVED = 29 | MAX_BIT 64 "Reserved (30)", // RESERVED = 30 | MAX_BIT 65 "End of File" // RETURN_END_OF_FILE = 31 | MAX_BIT 66 }; 67 68 /** 69 Worker function that produces a Null-terminated string in an output buffer 70 based on a Null-terminated format string and a VA_LIST argument list. 71 72 VSPrint function to process format and place the results in Buffer. Since a 73 VA_LIST is used this rountine allows the nesting of Vararg routines. Thus 74 this is the main print working routine. 75 76 @param Buffer Character buffer to print the results of the parsing 77 of Format into. 78 @param BufferSize Maximum number of characters to put into buffer. 79 @param Flags Intial flags value. 80 Can only have FORMAT_UNICODE and OUTPUT_UNICODE set. 81 @param Format Null-terminated format string. 82 @param Marker Vararg list consumed by processing Format. 83 84 @return Number of characters printed not including the Null-terminator. 85 86 **/ 87 UINTN 88 BasePrintLibVSPrint ( 89 OUT CHAR8 *Buffer, 90 IN UINTN BufferSize, 91 IN UINTN Flags, 92 IN CONST CHAR8 *Format, 93 IN VA_LIST Marker 94 ) 95 { 96 CHAR8 *OriginalBuffer; 97 CHAR8 *EndBuffer; 98 CHAR8 ValueBuffer[MAXIMUM_VALUE_CHARACTERS]; 99 UINTN BytesPerOutputCharacter; 100 UINTN BytesPerFormatCharacter; 101 UINTN FormatMask; 102 UINTN FormatCharacter; 103 UINTN Width; 104 UINTN Precision; 105 INT64 Value; 106 CONST CHAR8 *ArgumentString; 107 UINTN Character; 108 GUID *TmpGuid; 109 TIME *TmpTime; 110 UINTN Count; 111 UINTN ArgumentMask; 112 INTN BytesPerArgumentCharacter; 113 UINTN ArgumentCharacter; 114 BOOLEAN Done; 115 UINTN Index; 116 CHAR8 Prefix; 117 BOOLEAN ZeroPad; 118 BOOLEAN Comma; 119 UINTN Digits; 120 UINTN Radix; 121 RETURN_STATUS Status; 122 123 if (BufferSize == 0) { 124 return 0; 125 } 126 ASSERT (Buffer != NULL); 127 128 if ((Flags & OUTPUT_UNICODE) != 0) { 129 BytesPerOutputCharacter = 2; 130 } else { 131 BytesPerOutputCharacter = 1; 132 } 133 134 // 135 // Reserve space for the Null terminator. 136 // 137 BufferSize--; 138 OriginalBuffer = Buffer; 139 // 140 // Set the tag for the end of the input Buffer. 141 // 142 EndBuffer = Buffer + BufferSize * BytesPerOutputCharacter; 143 144 if ((Flags & FORMAT_UNICODE) != 0) { 145 // 146 // Make sure format string cannot contain more than PcdMaximumUnicodeStringLength 147 // Unicode characters if PcdMaximumUnicodeStringLength is not zero. 148 // 149 ASSERT (StrSize ((CHAR16 *) Format) != 0); 150 BytesPerFormatCharacter = 2; 151 FormatMask = 0xffff; 152 } else { 153 // 154 // Make sure format string cannot contain more than PcdMaximumAsciiStringLength 155 // Ascii characters if PcdMaximumAsciiStringLength is not zero. 156 // 157 ASSERT (AsciiStrSize (Format) != 0); 158 BytesPerFormatCharacter = 1; 159 FormatMask = 0xff; 160 } 161 162 163 164 // 165 // Get the first character from the format string 166 // 167 FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask; 168 169 // 170 // Loop until the end of the format string is reached or the output buffer is full 171 // 172 while (FormatCharacter != 0 && Buffer < EndBuffer) { 173 // 174 // Clear all the flag bits except those that may have been passed in 175 // 176 Flags &= (OUTPUT_UNICODE | FORMAT_UNICODE); 177 178 // 179 // Set the default width to zero, and the default precision to 1 180 // 181 Width = 0; 182 Precision = 1; 183 Prefix = 0; 184 Comma = FALSE; 185 ZeroPad = FALSE; 186 Count = 0; 187 Digits = 0; 188 189 switch (FormatCharacter) { 190 case '%': 191 // 192 // Parse Flags and Width 193 // 194 for (Done = FALSE; !Done; ) { 195 Format += BytesPerFormatCharacter; 196 FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask; 197 switch (FormatCharacter) { 198 case '.': 199 Flags |= PRECISION; 200 break; 201 case '-': 202 Flags |= LEFT_JUSTIFY; 203 break; 204 case '+': 205 Flags |= PREFIX_SIGN; 206 break; 207 case ' ': 208 Flags |= PREFIX_BLANK; 209 break; 210 case ',': 211 Flags |= COMMA_TYPE; 212 break; 213 case 'L': 214 case 'l': 215 Flags |= LONG_TYPE; 216 break; 217 case '*': 218 if ((Flags & PRECISION) == 0) { 219 Flags |= PAD_TO_WIDTH; 220 Width = VA_ARG (Marker, UINTN); 221 } else { 222 Precision = VA_ARG (Marker, UINTN); 223 } 224 break; 225 case '0': 226 if ((Flags & PRECISION) == 0) { 227 Flags |= PREFIX_ZERO; 228 } 229 case '1': 230 case '2': 231 case '3': 232 case '4': 233 case '5': 234 case '6': 235 case '7': 236 case '8': 237 case '9': 238 for (Count = 0; ((FormatCharacter >= '0') && (FormatCharacter <= '9')); ){ 239 Count = (Count * 10) + FormatCharacter - '0'; 240 Format += BytesPerFormatCharacter; 241 FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask; 242 } 243 Format -= BytesPerFormatCharacter; 244 if ((Flags & PRECISION) == 0) { 245 Flags |= PAD_TO_WIDTH; 246 Width = Count; 247 } else { 248 Precision = Count; 249 } 250 break; 251 252 case '\0': 253 // 254 // Make no output if Format string terminates unexpectedly when 255 // looking up for flag, width, precision and type. 256 // 257 Format -= BytesPerFormatCharacter; 258 Precision = 0; 259 // 260 // break skipped on purpose. 261 // 262 default: 263 Done = TRUE; 264 break; 265 } 266 } 267 268 // 269 // Handle each argument type 270 // 271 switch (FormatCharacter) { 272 case 'p': 273 // 274 // Flag space, +, 0, L & l are invalid for type p. 275 // 276 Flags &= ~(PREFIX_BLANK | PREFIX_SIGN | PREFIX_ZERO | LONG_TYPE); 277 if (sizeof (VOID *) > 4) { 278 Flags |= LONG_TYPE; 279 } 280 case 'X': 281 Flags |= PREFIX_ZERO; 282 // 283 // break skipped on purpose 284 // 285 case 'x': 286 Flags |= RADIX_HEX; 287 // 288 // break skipped on purpose 289 // 290 case 'd': 291 if ((Flags & LONG_TYPE) == 0) { 292 Value = (VA_ARG (Marker, int)); 293 } else { 294 Value = VA_ARG (Marker, INT64); 295 } 296 if ((Flags & PREFIX_BLANK) != 0) { 297 Prefix = ' '; 298 } 299 if ((Flags & PREFIX_SIGN) != 0) { 300 Prefix = '+'; 301 } 302 if ((Flags & COMMA_TYPE) != 0) { 303 Comma = TRUE; 304 } 305 if ((Flags & RADIX_HEX) == 0) { 306 Radix = 10; 307 if (Comma) { 308 Flags &= (~PREFIX_ZERO); 309 Precision = 1; 310 } 311 if (Value < 0) { 312 Flags |= PREFIX_SIGN; 313 Prefix = '-'; 314 Value = -Value; 315 } 316 } else { 317 Radix = 16; 318 Comma = FALSE; 319 if ((Flags & LONG_TYPE) == 0 && Value < 0) { 320 Value = (unsigned int)Value; 321 } 322 } 323 // 324 // Convert Value to a reversed string 325 // 326 Count = BasePrintLibValueToString (ValueBuffer, Value, Radix); 327 if (Value == 0 && Precision == 0) { 328 Count = 0; 329 } 330 ArgumentString = (CHAR8 *)ValueBuffer + Count; 331 332 Digits = Count % 3; 333 if (Digits != 0) { 334 Digits = 3 - Digits; 335 } 336 if (Comma && Count != 0) { 337 Count += ((Count - 1) / 3); 338 } 339 if (Prefix != 0) { 340 Count++; 341 Precision++; 342 } 343 Flags |= ARGUMENT_REVERSED; 344 ZeroPad = TRUE; 345 if ((Flags & PREFIX_ZERO) != 0) { 346 if ((Flags & LEFT_JUSTIFY) == 0) { 347 if ((Flags & PAD_TO_WIDTH) != 0) { 348 if ((Flags & PRECISION) == 0) { 349 Precision = Width; 350 } 351 } 352 } 353 } 354 break; 355 356 case 's': 357 case 'S': 358 Flags |= ARGUMENT_UNICODE; 359 // 360 // break skipped on purpose 361 // 362 case 'a': 363 ArgumentString = (CHAR8 *)VA_ARG (Marker, CHAR8 *); 364 if (ArgumentString == NULL) { 365 Flags &= (~ARGUMENT_UNICODE); 366 ArgumentString = "<null string>"; 367 } 368 break; 369 370 case 'c': 371 Character = VA_ARG (Marker, UINTN) & 0xffff; 372 ArgumentString = (CHAR8 *)&Character; 373 Flags |= ARGUMENT_UNICODE; 374 break; 375 376 case 'g': 377 TmpGuid = VA_ARG (Marker, GUID *); 378 if (TmpGuid == NULL) { 379 ArgumentString = "<null guid>"; 380 } else { 381 BasePrintLibSPrint ( 382 ValueBuffer, 383 MAXIMUM_VALUE_CHARACTERS, 384 0, 385 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", 386 TmpGuid->Data1, 387 TmpGuid->Data2, 388 TmpGuid->Data3, 389 TmpGuid->Data4[0], 390 TmpGuid->Data4[1], 391 TmpGuid->Data4[2], 392 TmpGuid->Data4[3], 393 TmpGuid->Data4[4], 394 TmpGuid->Data4[5], 395 TmpGuid->Data4[6], 396 TmpGuid->Data4[7] 397 ); 398 ArgumentString = ValueBuffer; 399 } 400 break; 401 402 case 't': 403 TmpTime = VA_ARG (Marker, TIME *); 404 if (TmpTime == NULL) { 405 ArgumentString = "<null time>"; 406 } else { 407 BasePrintLibSPrint ( 408 ValueBuffer, 409 MAXIMUM_VALUE_CHARACTERS, 410 0, 411 "%02d/%02d/%04d %02d:%02d", 412 TmpTime->Month, 413 TmpTime->Day, 414 TmpTime->Year, 415 TmpTime->Hour, 416 TmpTime->Minute 417 ); 418 ArgumentString = ValueBuffer; 419 } 420 break; 421 422 case 'r': 423 Status = VA_ARG (Marker, RETURN_STATUS); 424 ArgumentString = ValueBuffer; 425 if (RETURN_ERROR (Status)) { 426 // 427 // Clear error bit 428 // 429 Index = Status & ~MAX_BIT; 430 if (Index > 0 && Index <= ERROR_STATUS_NUMBER) { 431 ArgumentString = StatusString [Index + WARNING_STATUS_NUMBER]; 432 } 433 } else { 434 Index = (UINTN) Status; 435 if (Index <= WARNING_STATUS_NUMBER) { 436 ArgumentString = StatusString [Index]; 437 } 438 } 439 if (ArgumentString == ValueBuffer) { 440 BasePrintLibSPrint ((CHAR8 *) ValueBuffer, MAXIMUM_VALUE_CHARACTERS, 0, "%08X", Status); 441 } 442 break; 443 444 case '\n': 445 ArgumentString = "\n\r"; 446 break; 447 448 case '%': 449 default: 450 // 451 // if the type is '%' or unknown, then print it to the screen 452 // 453 ArgumentString = (CHAR8 *)&FormatCharacter; 454 Flags |= ARGUMENT_UNICODE; 455 break; 456 } 457 break; 458 459 case '\n': 460 ArgumentString = "\n\r"; 461 break; 462 463 default: 464 ArgumentString = (CHAR8 *)&FormatCharacter; 465 Flags |= ARGUMENT_UNICODE; 466 break; 467 } 468 469 // 470 // Retrieve the ArgumentString attriubutes 471 // 472 if ((Flags & ARGUMENT_UNICODE) != 0) { 473 ArgumentMask = 0xffff; 474 BytesPerArgumentCharacter = 2; 475 } else { 476 ArgumentMask = 0xff; 477 BytesPerArgumentCharacter = 1; 478 } 479 if ((Flags & ARGUMENT_REVERSED) != 0) { 480 BytesPerArgumentCharacter = -BytesPerArgumentCharacter; 481 } else { 482 // 483 // Compute the number of characters in ArgumentString and store it in Count 484 // ArgumentString is either null-terminated, or it contains Precision characters 485 // 486 for (Count = 0; Count < Precision || ((Flags & PRECISION) == 0); Count++) { 487 ArgumentCharacter = ((ArgumentString[Count * BytesPerArgumentCharacter] & 0xff) | ((ArgumentString[Count * BytesPerArgumentCharacter + 1]) << 8)) & ArgumentMask; 488 if (ArgumentCharacter == 0) { 489 break; 490 } 491 } 492 } 493 494 if (Precision < Count) { 495 Precision = Count; 496 } 497 498 // 499 // Pad before the string 500 // 501 if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH)) { 502 Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Width - Precision, ' ', BytesPerOutputCharacter); 503 } 504 505 if (ZeroPad) { 506 if (Prefix != 0) { 507 Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, Prefix, BytesPerOutputCharacter); 508 } 509 Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Precision - Count, '0', BytesPerOutputCharacter); 510 } else { 511 Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Precision - Count, ' ', BytesPerOutputCharacter); 512 if (Prefix != 0) { 513 Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, Prefix, BytesPerOutputCharacter); 514 } 515 } 516 517 // 518 // Output the Prefix character if it is present 519 // 520 Index = 0; 521 if (Prefix != 0) { 522 Index++; 523 } 524 525 // 526 // Copy the string into the output buffer performing the required type conversions 527 // 528 while (Index < Count) { 529 ArgumentCharacter = ((*ArgumentString & 0xff) | (*(ArgumentString + 1) << 8)) & ArgumentMask; 530 531 Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, ArgumentCharacter, BytesPerOutputCharacter); 532 ArgumentString += BytesPerArgumentCharacter; 533 Index++; 534 if (Comma) { 535 Digits++; 536 if (Digits == 3) { 537 Digits = 0; 538 Index++; 539 if (Index < Count) { 540 Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, ',', BytesPerOutputCharacter); 541 } 542 } 543 } 544 } 545 546 // 547 // Pad after the string 548 // 549 if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH | LEFT_JUSTIFY)) { 550 Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Width - Precision, ' ', BytesPerOutputCharacter); 551 } 552 553 // 554 // Get the next character from the format string 555 // 556 Format += BytesPerFormatCharacter; 557 558 // 559 // Get the next character from the format string 560 // 561 FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask; 562 } 563 564 // 565 // Null terminate the Unicode or ASCII string 566 // 567 BasePrintLibFillBuffer (Buffer, EndBuffer + BytesPerOutputCharacter, 1, 0, BytesPerOutputCharacter); 568 // 569 // Make sure output buffer cannot contain more than PcdMaximumUnicodeStringLength 570 // Unicode characters if PcdMaximumUnicodeStringLength is not zero. 571 // 572 ASSERT ((((Flags & OUTPUT_UNICODE) == 0)) || (StrSize ((CHAR16 *) OriginalBuffer) != 0)); 573 // 574 // Make sure output buffer cannot contain more than PcdMaximumAsciiStringLength 575 // ASCII characters if PcdMaximumAsciiStringLength is not zero. 576 // 577 ASSERT ((((Flags & OUTPUT_UNICODE) != 0)) || (AsciiStrSize (OriginalBuffer) != 0)); 578 579 return ((Buffer - OriginalBuffer) / BytesPerOutputCharacter); 580 } 581 582 /** 583 Worker function that produces a Null-terminated string in an output buffer 584 based on a Null-terminated format string and variable argument list. 585 586 VSPrint function to process format and place the results in Buffer. Since a 587 VA_LIST is used this rountine allows the nesting of Vararg routines. Thus 588 this is the main print working routine. 589 590 @param Buffer Character buffer to print the results of the parsing 591 of Format into. 592 @param BufferSize Maximum number of characters to put into buffer. 593 Zero means no limit. 594 @param Flags Intial flags value. 595 Can only have FORMAT_UNICODE and OUTPUT_UNICODE set 596 @param FormatString Null-terminated format string. 597 598 @return Number of characters printed not including the Null-terminator. 599 600 **/ 601 UINTN 602 BasePrintLibSPrint ( 603 OUT CHAR8 *StartOfBuffer, 604 IN UINTN BufferSize, 605 IN UINTN Flags, 606 IN CONST CHAR8 *FormatString, 607 ... 608 ) 609 { 610 VA_LIST Marker; 611 UINTN NumberOfPrinted; 612 613 VA_START (Marker, FormatString); 614 NumberOfPrinted = BasePrintLibVSPrint (StartOfBuffer, BufferSize, Flags, FormatString, Marker); 615 VA_END (Marker); 616 return NumberOfPrinted; 617 } 618 619 /** 620 Produces a Null-terminated Unicode string in an output buffer based on 621 a Null-terminated Unicode format string and a VA_LIST argument list 622 623 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer 624 and BufferSize. 625 The Unicode string is produced by parsing the format string specified by FormatString. 626 Arguments are pulled from the variable argument list specified by Marker based on the 627 contents of the format string. 628 The number of Unicode characters in the produced output buffer is returned not including 629 the Null-terminator. 630 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned. 631 632 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). 633 If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT(). 634 If BufferSize > 1 and FormatString is NULL, then ASSERT(). 635 If BufferSize > 1 and FormatString is not aligned on a 16-bit boundary, then ASSERT(). 636 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 637 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then 638 ASSERT(). 639 If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string 640 contains more than PcdMaximumUnicodeStringLength Unicode characters not including the 641 Null-terminator, then ASSERT(). 642 643 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated 644 Unicode string. 645 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. 646 @param FormatString Null-terminated Unicode format string. 647 @param Marker VA_LIST marker for the variable argument list. 648 649 @return The number of Unicode characters in the produced output buffer not including the 650 Null-terminator. 651 652 **/ 653 UINTN 654 EFIAPI 655 UnicodeVSPrint ( 656 OUT CHAR16 *StartOfBuffer, 657 IN UINTN BufferSize, 658 IN CONST CHAR16 *FormatString, 659 IN VA_LIST Marker 660 ) 661 { 662 ASSERT_UNICODE_BUFFER(StartOfBuffer); 663 ASSERT_UNICODE_BUFFER(FormatString); 664 return BasePrintLibVSPrint ((CHAR8 *)StartOfBuffer, BufferSize >> 1, FORMAT_UNICODE | OUTPUT_UNICODE, (CHAR8 *)FormatString, Marker); 665 } 666 667 /** 668 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated 669 Unicode format string and variable argument list. 670 671 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer 672 and BufferSize. 673 The Unicode string is produced by parsing the format string specified by FormatString. 674 Arguments are pulled from the variable argument list based on the contents of the format string. 675 The number of Unicode characters in the produced output buffer is returned not including 676 the Null-terminator. 677 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned. 678 679 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). 680 If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT(). 681 If BufferSize > 1 and FormatString is NULL, then ASSERT(). 682 If BufferSize > 1 and FormatString is not aligned on a 16-bit boundary, then ASSERT(). 683 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 684 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then 685 ASSERT(). 686 If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string 687 contains more than PcdMaximumUnicodeStringLength Unicode characters not including the 688 Null-terminator, then ASSERT(). 689 690 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated 691 Unicode string. 692 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. 693 @param FormatString Null-terminated Unicode format string. 694 695 @return The number of Unicode characters in the produced output buffer not including the 696 Null-terminator. 697 698 **/ 699 UINTN 700 EFIAPI 701 UnicodeSPrint ( 702 OUT CHAR16 *StartOfBuffer, 703 IN UINTN BufferSize, 704 IN CONST CHAR16 *FormatString, 705 ... 706 ) 707 { 708 VA_LIST Marker; 709 UINTN NumberOfPrinted; 710 711 VA_START (Marker, FormatString); 712 NumberOfPrinted = UnicodeVSPrint (StartOfBuffer, BufferSize, FormatString, Marker); 713 VA_END (Marker); 714 return NumberOfPrinted; 715 } 716 717 /** 718 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated 719 ASCII format string and a VA_LIST argument list 720 721 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer 722 and BufferSize. 723 The Unicode string is produced by parsing the format string specified by FormatString. 724 Arguments are pulled from the variable argument list specified by Marker based on the 725 contents of the format string. 726 The number of Unicode characters in the produced output buffer is returned not including 727 the Null-terminator. 728 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned. 729 730 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). 731 If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT(). 732 If BufferSize > 1 and FormatString is NULL, then ASSERT(). 733 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than 734 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then 735 ASSERT(). 736 If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string 737 contains more than PcdMaximumUnicodeStringLength Unicode characters not including the 738 Null-terminator, then ASSERT(). 739 740 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated 741 Unicode string. 742 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. 743 @param FormatString Null-terminated Unicode format string. 744 @param Marker VA_LIST marker for the variable argument list. 745 746 @return The number of Unicode characters in the produced output buffer not including the 747 Null-terminator. 748 749 **/ 750 UINTN 751 EFIAPI 752 UnicodeVSPrintAsciiFormat ( 753 OUT CHAR16 *StartOfBuffer, 754 IN UINTN BufferSize, 755 IN CONST CHAR8 *FormatString, 756 IN VA_LIST Marker 757 ) 758 { 759 ASSERT_UNICODE_BUFFER(StartOfBuffer); 760 return BasePrintLibVSPrint ((CHAR8 *)StartOfBuffer, BufferSize >> 1, OUTPUT_UNICODE,FormatString, Marker); 761 } 762 763 /** 764 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated 765 ASCII format string and variable argument list. 766 767 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer 768 and BufferSize. 769 The Unicode string is produced by parsing the format string specified by FormatString. 770 Arguments are pulled from the variable argument list based on the contents of the 771 format string. 772 The number of Unicode characters in the produced output buffer is returned not including 773 the Null-terminator. 774 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned. 775 776 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT(). 777 If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT(). 778 If BufferSize > 1 and FormatString is NULL, then ASSERT(). 779 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than 780 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then 781 ASSERT(). 782 If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string 783 contains more than PcdMaximumUnicodeStringLength Unicode characters not including the 784 Null-terminator, then ASSERT(). 785 786 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated 787 Unicode string. 788 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. 789 @param FormatString Null-terminated Unicode format string. 790 791 @return The number of Unicode characters in the produced output buffer not including the 792 Null-terminator. 793 794 **/ 795 UINTN 796 EFIAPI 797 UnicodeSPrintAsciiFormat ( 798 OUT CHAR16 *StartOfBuffer, 799 IN UINTN BufferSize, 800 IN CONST CHAR8 *FormatString, 801 ... 802 ) 803 { 804 VA_LIST Marker; 805 UINTN NumberOfPrinted; 806 807 VA_START (Marker, FormatString); 808 NumberOfPrinted = UnicodeVSPrintAsciiFormat (StartOfBuffer, BufferSize, FormatString, Marker); 809 VA_END (Marker); 810 return NumberOfPrinted; 811 } 812 813 /** 814 Converts a decimal value to a Null-terminated Unicode string. 815 816 Converts the decimal number specified by Value to a Null-terminated Unicode 817 string specified by Buffer containing at most Width characters. No padding of spaces 818 is ever performed. If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed. 819 The number of Unicode characters in Buffer is returned not including the Null-terminator. 820 If the conversion contains more than Width characters, then only the first 821 Width characters are returned, and the total number of characters 822 required to perform the conversion is returned. 823 Additional conversion parameters are specified in Flags. 824 825 The Flags bit LEFT_JUSTIFY is always ignored. 826 All conversions are left justified in Buffer. 827 If Width is 0, PREFIX_ZERO is ignored in Flags. 828 If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas 829 are inserted every 3rd digit starting from the right. 830 If RADIX_HEX is set in Flags, then the output buffer will be 831 formatted in hexadecimal format. 832 If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in Buffer is a '-'. 833 If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, 834 then Buffer is padded with '0' characters so the combination of the optional '-' 835 sign character, '0' characters, digit characters for Value, and the Null-terminator 836 add up to Width characters. 837 If both COMMA_TYPE and RADIX_HEX are set in Flags, then ASSERT(). 838 If Buffer is NULL, then ASSERT(). 839 If Buffer is not aligned on a 16-bit boundary, then ASSERT(). 840 If unsupported bits are set in Flags, then ASSERT(). 841 If both COMMA_TYPE and RADIX_HEX are set in Flags, then ASSERT(). 842 If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT() 843 844 @param Buffer Pointer to the output buffer for the produced Null-terminated 845 Unicode string. 846 @param Flags The bitmask of flags that specify left justification, zero pad, and commas. 847 @param Value The 64-bit signed value to convert to a string. 848 @param Width The maximum number of Unicode characters to place in Buffer, not including 849 the Null-terminator. 850 851 @return The number of Unicode characters in Buffer not including the Null-terminator. 852 853 **/ 854 UINTN 855 EFIAPI 856 UnicodeValueToString ( 857 IN OUT CHAR16 *Buffer, 858 IN UINTN Flags, 859 IN INT64 Value, 860 IN UINTN Width 861 ) 862 { 863 ASSERT_UNICODE_BUFFER(Buffer); 864 return BasePrintLibConvertValueToString ((CHAR8 *)Buffer, Flags, Value, Width, 2); 865 } 866 867 /** 868 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated 869 ASCII format string and a VA_LIST argument list. 870 871 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer 872 and BufferSize. 873 The ASCII string is produced by parsing the format string specified by FormatString. 874 Arguments are pulled from the variable argument list specified by Marker based on 875 the contents of the format string. 876 The number of ASCII characters in the produced output buffer is returned not including 877 the Null-terminator. 878 If BufferSize is 0, then no output buffer is produced and 0 is returned. 879 880 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). 881 If BufferSize > 0 and FormatString is NULL, then ASSERT(). 882 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than 883 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then 884 ASSERT(). 885 If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string 886 contains more than PcdMaximumAsciiStringLength ASCII characters not including the 887 Null-terminator, then ASSERT(). 888 889 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated 890 ASCII string. 891 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. 892 @param FormatString Null-terminated Unicode format string. 893 @param Marker VA_LIST marker for the variable argument list. 894 895 @return The number of ASCII characters in the produced output buffer not including the 896 Null-terminator. 897 898 **/ 899 UINTN 900 EFIAPI 901 AsciiVSPrint ( 902 OUT CHAR8 *StartOfBuffer, 903 IN UINTN BufferSize, 904 IN CONST CHAR8 *FormatString, 905 IN VA_LIST Marker 906 ) 907 { 908 return BasePrintLibVSPrint (StartOfBuffer, BufferSize, 0, FormatString, Marker); 909 } 910 911 /** 912 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated 913 ASCII format string and variable argument list. 914 915 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer 916 and BufferSize. 917 The ASCII string is produced by parsing the format string specified by FormatString. 918 Arguments are pulled from the variable argument list based on the contents of the 919 format string. 920 The number of ASCII characters in the produced output buffer is returned not including 921 the Null-terminator. 922 If BufferSize is 0, then no output buffer is produced and 0 is returned. 923 924 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). 925 If BufferSize > 0 and FormatString is NULL, then ASSERT(). 926 If PcdMaximumAsciiStringLength is not zero, and FormatString contains more than 927 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, then 928 ASSERT(). 929 If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string 930 contains more than PcdMaximumAsciiStringLength ASCII characters not including the 931 Null-terminator, then ASSERT(). 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 Null-terminated Unicode format string. 937 938 @return The number of ASCII characters in the produced output buffer not including the 939 Null-terminator. 940 941 **/ 942 UINTN 943 EFIAPI 944 AsciiSPrint ( 945 OUT CHAR8 *StartOfBuffer, 946 IN UINTN BufferSize, 947 IN CONST CHAR8 *FormatString, 948 ... 949 ) 950 { 951 VA_LIST Marker; 952 UINTN NumberOfPrinted; 953 954 VA_START (Marker, FormatString); 955 NumberOfPrinted = AsciiVSPrint (StartOfBuffer, BufferSize, FormatString, Marker); 956 VA_END (Marker); 957 return NumberOfPrinted; 958 } 959 960 /** 961 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated 962 ASCII format string and a VA_LIST argument list. 963 964 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer 965 and BufferSize. 966 The ASCII string is produced by parsing the format string specified by FormatString. 967 Arguments are pulled from the variable argument list specified by Marker based on 968 the contents of the format string. 969 The number of ASCII characters in the produced output buffer is returned not including 970 the Null-terminator. 971 If BufferSize is 0, then no output buffer is produced and 0 is returned. 972 973 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). 974 If BufferSize > 0 and FormatString is NULL, then ASSERT(). 975 If BufferSize > 0 and FormatString is not aligned on a 16-bit boundary, then ASSERT(). 976 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 977 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then 978 ASSERT(). 979 If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string 980 contains more than PcdMaximumAsciiStringLength ASCII characters not including the 981 Null-terminator, then ASSERT(). 982 983 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated 984 ASCII string. 985 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. 986 @param FormatString Null-terminated Unicode format string. 987 @param Marker VA_LIST marker for the variable argument list. 988 989 @return The number of ASCII characters in the produced output buffer not including the 990 Null-terminator. 991 992 **/ 993 UINTN 994 EFIAPI 995 AsciiVSPrintUnicodeFormat ( 996 OUT CHAR8 *StartOfBuffer, 997 IN UINTN BufferSize, 998 IN CONST CHAR16 *FormatString, 999 IN VA_LIST Marker 1000 ) 1001 { 1002 ASSERT_UNICODE_BUFFER (FormatString); 1003 return BasePrintLibVSPrint (StartOfBuffer, BufferSize, FORMAT_UNICODE, (CHAR8 *)FormatString, Marker); 1004 } 1005 1006 /** 1007 Produces a Null-terminated ASCII string in an output buffer based on a Null-terminated 1008 ASCII format string and variable argument list. 1009 1010 Produces a Null-terminated ASCII string in the output buffer specified by StartOfBuffer 1011 and BufferSize. 1012 The ASCII string is produced by parsing the format string specified by FormatString. 1013 Arguments are pulled from the variable argument list based on the contents of the 1014 format string. 1015 The number of ASCII characters in the produced output buffer is returned not including 1016 the Null-terminator. 1017 If BufferSize is 0, then no output buffer is produced and 0 is returned. 1018 1019 If BufferSize > 0 and StartOfBuffer is NULL, then ASSERT(). 1020 If BufferSize > 0 and FormatString is NULL, then ASSERT(). 1021 If BufferSize > 0 and FormatString is not aligned on a 16-bit boundary, then ASSERT(). 1022 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than 1023 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then 1024 ASSERT(). 1025 If PcdMaximumAsciiStringLength is not zero, and produced Null-terminated ASCII string 1026 contains more than PcdMaximumAsciiStringLength ASCII characters not including the 1027 Null-terminator, then ASSERT(). 1028 1029 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated 1030 ASCII string. 1031 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. 1032 @param FormatString Null-terminated Unicode format string. 1033 1034 @return The number of ASCII characters in the produced output buffer not including the 1035 Null-terminator. 1036 1037 **/ 1038 UINTN 1039 EFIAPI 1040 AsciiSPrintUnicodeFormat ( 1041 OUT CHAR8 *StartOfBuffer, 1042 IN UINTN BufferSize, 1043 IN CONST CHAR16 *FormatString, 1044 ... 1045 ) 1046 { 1047 VA_LIST Marker; 1048 UINTN NumberOfPrinted; 1049 1050 VA_START (Marker, FormatString); 1051 NumberOfPrinted = AsciiVSPrintUnicodeFormat (StartOfBuffer, BufferSize, FormatString, Marker); 1052 VA_END (Marker); 1053 return NumberOfPrinted; 1054 } 1055 1056 1057 /** 1058 Converts a decimal value to a Null-terminated ASCII string. 1059 1060 Converts the decimal number specified by Value to a Null-terminated ASCII string 1061 specified by Buffer containing at most Width characters. No padding of spaces 1062 is ever performed. 1063 If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed. 1064 The number of ASCII characters in Buffer is returned not including the Null-terminator. 1065 If the conversion contains more than Width characters, then only the first Width 1066 characters are returned, and the total number of characters required to perform 1067 the conversion is returned. 1068 Additional conversion parameters are specified in Flags. 1069 The Flags bit LEFT_JUSTIFY is always ignored. 1070 All conversions are left justified in Buffer. 1071 If Width is 0, PREFIX_ZERO is ignored in Flags. 1072 If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas 1073 are inserted every 3rd digit starting from the right. 1074 If RADIX_HEX is set in Flags, then the output buffer will be 1075 formatted in hexadecimal format. 1076 If Value is < 0 and RADIX_HEX is not set in Flags, then the fist character in Buffer is a '-'. 1077 If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, 1078 then Buffer is padded with '0' characters so the combination of the optional '-' 1079 sign character, '0' characters, digit characters for Value, and the Null-terminator 1080 add up to Width characters. 1081 1082 If Buffer is NULL, then ASSERT(). 1083 If unsupported bits are set in Flags, then ASSERT(). 1084 If both COMMA_TYPE and RADIX_HEX are set in Flags, then ASSERT(). 1085 If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT() 1086 1087 @param Buffer Pointer to the output buffer for the produced Null-terminated 1088 ASCII string. 1089 @param Flags The bitmask of flags that specify left justification, zero pad, and commas. 1090 @param Value The 64-bit signed value to convert to a string. 1091 @param Width The maximum number of ASCII characters to place in Buffer, not including 1092 the Null-terminator. 1093 1094 @return The number of ASCII characters in Buffer not including the Null-terminator. 1095 1096 **/ 1097 UINTN 1098 EFIAPI 1099 AsciiValueToString ( 1100 IN OUT CHAR8 *Buffer, 1101 IN UINTN Flags, 1102 IN INT64 Value, 1103 IN UINTN Width 1104 ) 1105 { 1106 return BasePrintLibConvertValueToString (Buffer, Flags, Value, Width, 1); 1107 } 1108 1109