-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Buffers.Text;
using System.Diagnostics;
using System.Globalization;
// user-defined format strings. The following table describes the formatting
// characters that are supported in user defined format strings.
//
- //
+ //
// 0 - Digit placeholder. If the value being
// formatted has a digit in the position where the '0' appears in the format
// string, then that digit is copied to the output string. Otherwise, a '0' is
number.CheckConsistency();
}
- public static string FormatDouble(double value, string format, NumberFormatInfo info)
+ public static string FormatDouble(double value, string? format, NumberFormatInfo info)
{
Span<char> stackBuffer = stackalloc char[CharStackBufferSize];
var sb = new ValueStringBuilder(stackBuffer);
{
Span<char> stackBuffer = stackalloc char[CharStackBufferSize];
var sb = new ValueStringBuilder(stackBuffer);
- string s = FormatDouble(ref sb, value, format, info);
+ string? s = FormatDouble(ref sb, value, format, info);
return s != null ?
TryCopyTo(s, destination, out charsWritten) :
sb.TryCopyTo(destination, out charsWritten);
case 'N':
case 'n':
{
- // The fixed-point and number formats use the precision specifier to indicate the number
+ // The fixed-point and number formats use the precision specifier to indicate the number
// of decimal digits to format. This defaults to NumberFormatInfo.NumberDecimalDigits.
if (precision == -1)
/// Non-null if an existing string can be returned, in which case the builder will be unmodified.
/// Null if no existing string was returned, in which case the formatted output is in the builder.
/// </returns>
- private static unsafe string FormatDouble(ref ValueStringBuilder sb, double value, ReadOnlySpan<char> format, NumberFormatInfo info)
+ private static unsafe string? FormatDouble(ref ValueStringBuilder sb, double value, ReadOnlySpan<char> format, NumberFormatInfo info)
{
if (!double.IsFinite(value))
{
NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, pDigits, DoubleNumberBufferLength);
number.IsNegative = double.IsNegative(value);
- // We need to track the original precision requested since some formats
+ // We need to track the original precision requested since some formats
// accept values like 0 and others may require additional fixups.
int nMaxDigits = GetFloatingPointMaxDigitsAndPrecision(fmt, ref precision, info, out bool isSignificantDigits);
return null;
}
- public static string FormatSingle(float value, string format, NumberFormatInfo info)
+ public static string FormatSingle(float value, string? format, NumberFormatInfo info)
{
Span<char> stackBuffer = stackalloc char[CharStackBufferSize];
var sb = new ValueStringBuilder(stackBuffer);
{
Span<char> stackBuffer = stackalloc char[CharStackBufferSize];
var sb = new ValueStringBuilder(stackBuffer);
- string s = FormatSingle(ref sb, value, format, info);
+ string? s = FormatSingle(ref sb, value, format, info);
return s != null ?
TryCopyTo(s, destination, out charsWritten) :
sb.TryCopyTo(destination, out charsWritten);
/// Non-null if an existing string can be returned, in which case the builder will be unmodified.
/// Null if no existing string was returned, in which case the formatted output is in the builder.
/// </returns>
- private static unsafe string FormatSingle(ref ValueStringBuilder sb, float value, ReadOnlySpan<char> format, NumberFormatInfo info)
+ private static unsafe string? FormatSingle(ref ValueStringBuilder sb, float value, ReadOnlySpan<char> format, NumberFormatInfo info)
{
if (!float.IsFinite(value))
{
NumberBuffer number = new NumberBuffer(NumberBufferKind.FloatingPoint, pDigits, SingleNumberBufferLength);
number.IsNegative = float.IsNegative(value);
- // We need to track the original precision requested since some formats
+ // We need to track the original precision requested since some formats
// accept values like 0 and others may require additional fixups.
int nMaxDigits = GetFloatingPointMaxDigitsAndPrecision(fmt, ref precision, info, out bool isSignificantDigits);
return false;
}
- public static unsafe string FormatInt32(int value, ReadOnlySpan<char> format, IFormatProvider provider)
+ public static unsafe string FormatInt32(int value, ReadOnlySpan<char> format, IFormatProvider? provider)
{
// Fast path for default format with a non-negative value
if (value >= 0 && format.Length == 0)
}
}
- public static unsafe bool TryFormatInt32(int value, ReadOnlySpan<char> format, IFormatProvider provider, Span<char> destination, out int charsWritten)
+ public static unsafe bool TryFormatInt32(int value, ReadOnlySpan<char> format, IFormatProvider? provider, Span<char> destination, out int charsWritten)
{
// Fast path for default format with a non-negative value
if (value >= 0 && format.Length == 0)
}
}
- public static unsafe string FormatUInt32(uint value, ReadOnlySpan<char> format, IFormatProvider provider)
+ public static unsafe string FormatUInt32(uint value, ReadOnlySpan<char> format, IFormatProvider? provider)
{
// Fast path for default format
if (format.Length == 0)
}
}
- public static unsafe bool TryFormatUInt32(uint value, ReadOnlySpan<char> format, IFormatProvider provider, Span<char> destination, out int charsWritten)
+ public static unsafe bool TryFormatUInt32(uint value, ReadOnlySpan<char> format, IFormatProvider? provider, Span<char> destination, out int charsWritten)
{
// Fast path for default format
if (format.Length == 0)
}
}
- public static unsafe string FormatInt64(long value, ReadOnlySpan<char> format, IFormatProvider provider)
+ public static unsafe string FormatInt64(long value, ReadOnlySpan<char> format, IFormatProvider? provider)
{
// Fast path for default format with a non-negative value
if (value >= 0 && format.Length == 0)
}
}
- public static unsafe bool TryFormatInt64(long value, ReadOnlySpan<char> format, IFormatProvider provider, Span<char> destination, out int charsWritten)
+ public static unsafe bool TryFormatInt64(long value, ReadOnlySpan<char> format, IFormatProvider? provider, Span<char> destination, out int charsWritten)
{
// Fast path for default format with a non-negative value
if (value >= 0 && format.Length == 0)
}
}
- public static unsafe string FormatUInt64(ulong value, ReadOnlySpan<char> format, IFormatProvider provider)
+ public static unsafe string FormatUInt64(ulong value, ReadOnlySpan<char> format, IFormatProvider? provider)
{
// Fast path for default format
if (format.Length == 0)
}
}
- public static unsafe bool TryFormatUInt64(ulong value, ReadOnlySpan<char> format, IFormatProvider provider, Span<char> destination, out int charsWritten)
+ public static unsafe bool TryFormatUInt64(ulong value, ReadOnlySpan<char> format, IFormatProvider? provider, Span<char> destination, out int charsWritten)
{
// Fast path for default format
if (format.Length == 0)
}
}
- private static unsafe void FormatFixed(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo info, int[] groupDigits, string sDecimal, string sGroup)
+ private static unsafe void FormatFixed(ref ValueStringBuilder sb, ref NumberBuffer number, int nMaxDigits, NumberFormatInfo? info, int[]? groupDigits, string? sDecimal, string? sGroup)
{
int digPos = number.Scale;
byte* dig = number.GetDigitsPointer();
{
if (groupDigits != null)
{
+ Debug.Assert(sGroup != null, "Must be nulll when groupDigits != null");
int groupSizeIndex = 0; // Index into the groupDigits array.
int bufferSize = digPos; // The length of the result buffer string.
int groupSize = 0; // The current group size.