Home | History | Annotate | Download | only in BasePrintLib
      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