+ Internal function that converts a decimal value to a Null-terminated string.\r
+\r
+ Converts the decimal number specified by Value to a Null-terminated string\r
+ specified by Buffer containing at most Width characters. If Width is 0 then a\r
+ width of MAXIMUM_VALUE_CHARACTERS is assumed. If the conversion contains more\r
+ than Width characters, then only the first Width characters are placed in\r
+ Buffer. Additional conversion parameters are specified in Flags.\r
+ The Flags bit LEFT_JUSTIFY is always ignored.\r
+ All conversions are left justified in Buffer.\r
+ If Width is 0, PREFIX_ZERO is ignored in Flags.\r
+ If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and\r
+ commas are inserted every 3rd digit starting from the right.\r
+ If Value is < 0, then the fist character in Buffer is a '-'.\r
+ If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored,\r
+ then Buffer is padded with '0' characters so the combination of the optional\r
+ '-' sign character, '0' characters, digit characters for Value, and the\r
+ Null-terminator add up to Width characters.\r
+\r
+ If an error would be returned, the function will ASSERT().\r
+\r
+ @param Buffer The pointer to the output buffer for the produced\r
+ Null-terminated string.\r
+ @param BufferSize The size of Buffer in bytes, including the\r
+ Null-terminator.\r
+ @param Flags The bitmask of flags that specify left justification,\r
+ zero pad, and commas.\r
+ @param Value The 64-bit signed value to convert to a string.\r
+ @param Width The maximum number of characters to place in Buffer,\r
+ not including the Null-terminator.\r
+ @param Increment The character increment in Buffer.\r
+\r
+ @retval RETURN_SUCCESS The decimal value is converted.\r
+ @retval RETURN_BUFFER_TOO_SMALL If BufferSize cannot hold the converted\r
+ value.\r
+ @retval RETURN_INVALID_PARAMETER If Buffer is NULL.\r
+ If Increment is 1 and\r
+ PcdMaximumAsciiStringLength is not zero,\r
+ BufferSize is greater than\r
+ PcdMaximumAsciiStringLength.\r
+ If Increment is not 1 and\r
+ PcdMaximumUnicodeStringLength is not zero,\r
+ BufferSize is greater than\r
+ (PcdMaximumUnicodeStringLength *\r
+ sizeof (CHAR16) + 1).\r
+ If unsupported bits are set in Flags.\r
+ If both COMMA_TYPE and RADIX_HEX are set in\r
+ Flags.\r
+ If Width >= MAXIMUM_VALUE_CHARACTERS.\r
+\r
+**/\r
+RETURN_STATUS\r
+BasePrintLibConvertValueToStringS (\r
+ IN OUT CHAR8 *Buffer,\r
+ IN UINTN BufferSize,\r
+ IN UINTN Flags,\r
+ IN INT64 Value,\r
+ IN UINTN Width,\r
+ IN UINTN Increment\r
+ )\r
+{\r
+ CHAR8 *EndBuffer;\r
+ CHAR8 ValueBuffer[MAXIMUM_VALUE_CHARACTERS];\r
+ CHAR8 *ValueBufferPtr;\r
+ UINTN Count;\r
+ UINTN Digits;\r
+ UINTN Index;\r
+ UINTN Radix;\r
+\r
+ //\r
+ // 1. Buffer shall not be a null pointer.\r
+ //\r
+ SAFE_PRINT_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);\r
+\r
+ //\r
+ // 2. BufferSize shall not be greater than (RSIZE_MAX * sizeof (CHAR16)) for\r
+ // Unicode output string or shall not be greater than ASCII_RSIZE_MAX for\r
+ // Ascii output string.\r
+ //\r
+ if (Increment == 1) {\r
+ //\r
+ // Ascii output string\r
+ //\r
+ if (ASCII_RSIZE_MAX != 0) {\r
+ SAFE_PRINT_CONSTRAINT_CHECK ((BufferSize <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);\r
+ }\r
+ } else {\r
+ //\r
+ // Unicode output string\r
+ //\r
+ if (RSIZE_MAX != 0) {\r
+ SAFE_PRINT_CONSTRAINT_CHECK ((BufferSize <= RSIZE_MAX * sizeof (CHAR16) + 1), RETURN_INVALID_PARAMETER);\r
+ }\r
+ }\r
+\r
+ //\r
+ // 3. Flags shall be set properly.\r
+ //\r
+ SAFE_PRINT_CONSTRAINT_CHECK (((Flags & ~(LEFT_JUSTIFY | COMMA_TYPE | PREFIX_ZERO | RADIX_HEX)) == 0), RETURN_INVALID_PARAMETER);\r
+ SAFE_PRINT_CONSTRAINT_CHECK ((((Flags & COMMA_TYPE) == 0) || ((Flags & RADIX_HEX) == 0)), RETURN_INVALID_PARAMETER);\r
+\r
+ //\r
+ // 4. Width shall be smaller than MAXIMUM_VALUE_CHARACTERS.\r
+ //\r
+ SAFE_PRINT_CONSTRAINT_CHECK ((Width < MAXIMUM_VALUE_CHARACTERS), RETURN_INVALID_PARAMETER);\r
+\r
+ //\r
+ // Width is 0 or COMMA_TYPE is set, PREFIX_ZERO is ignored.\r
+ //\r
+ if (Width == 0 || (Flags & COMMA_TYPE) != 0) {\r
+ Flags &= ~((UINTN) PREFIX_ZERO);\r
+ }\r
+ //\r
+ // If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed.\r
+ //\r
+ if (Width == 0) {\r
+ Width = MAXIMUM_VALUE_CHARACTERS - 1;\r
+ }\r
+\r
+ //\r
+ // Count the characters of the output string.\r
+ //\r
+ Count = 0;\r
+ Radix = ((Flags & RADIX_HEX) == 0)? 10 : 16;\r
+\r
+ if ((Flags & PREFIX_ZERO) != 0) {\r
+ Count = Width;\r
+ } else {\r
+ if ((Value < 0) && ((Flags & RADIX_HEX) == 0)) {\r
+ Count++; // minus sign\r
+ ValueBufferPtr = BasePrintLibValueToString (ValueBuffer, -Value, Radix);\r
+ } else {\r
+ ValueBufferPtr = BasePrintLibValueToString (ValueBuffer, Value, Radix);\r
+ }\r
+ Digits = ValueBufferPtr - ValueBuffer;\r
+ Count += Digits;\r
+\r
+ if ((Flags & COMMA_TYPE) != 0) {\r
+ Count += (Digits - 1) / 3; // commas\r
+ }\r
+ }\r
+\r
+ Width = MIN (Count, Width);\r
+\r
+ //\r
+ // 5. BufferSize shall be large enough to hold the converted string.\r
+ //\r
+ SAFE_PRINT_CONSTRAINT_CHECK ((BufferSize >= (Width + 1) * Increment), RETURN_BUFFER_TOO_SMALL);\r
+\r
+ //\r
+ // Set the tag for the end of the input Buffer.\r
+ //\r
+ EndBuffer = Buffer + Width * Increment;\r
+\r
+ //\r
+ // Convert decimal negative\r
+ //\r
+ if ((Value < 0) && ((Flags & RADIX_HEX) == 0)) {\r
+ Value = -Value;\r
+ Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, '-', Increment);\r
+ Width--;\r
+ }\r
+\r
+ //\r
+ // Count the length of the value string.\r
+ //\r
+ ValueBufferPtr = BasePrintLibValueToString (ValueBuffer, Value, Radix);\r
+ Count = ValueBufferPtr - ValueBuffer;\r
+\r
+ //\r
+ // Append Zero\r
+ //\r
+ if ((Flags & PREFIX_ZERO) != 0) {\r
+ Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Width - Count, '0', Increment);\r
+ }\r
+\r
+ //\r
+ // Print Comma type for every 3 characters\r
+ //\r
+ Digits = Count % 3;\r
+ if (Digits != 0) {\r
+ Digits = 3 - Digits;\r
+ }\r
+ for (Index = 0; Index < Count; Index++) {\r
+ Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, *ValueBufferPtr--, Increment);\r
+ if ((Flags & COMMA_TYPE) != 0) {\r
+ Digits++;\r
+ if (Digits == 3) {\r
+ Digits = 0;\r
+ if ((Index + 1) < Count) {\r
+ Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, ',', Increment);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // Print Null-terminator\r
+ //\r
+ BasePrintLibFillBuffer (Buffer, EndBuffer + Increment, 1, 0, Increment);\r
+\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+ Worker function that produces a Null-terminated string in an output buffer\r