Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add public UTF8 TryFormat overloads to relevant types #84841

Merged
merged 2 commits into from
Apr 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ public IPAddress(System.ReadOnlySpan<byte> address, long scopeid) { }
public override string ToString() { throw null; }
string IFormattable.ToString(string? format, IFormatProvider? formatProvider) { throw null; }
public bool TryFormat(System.Span<char> destination, out int charsWritten) { throw null; }
public bool TryFormat(System.Span<byte> utf8Destination, out int bytesWritten) { throw null; }
bool ISpanFormattable.TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider? provider) { throw null; }
bool System.IUtf8SpanFormattable.TryFormat(System.Span<byte> utf8Destination, out int bytesWritten, System.ReadOnlySpan<char> format, System.IFormatProvider? provider) { throw null; }
public static bool TryParse(System.ReadOnlySpan<char> ipSpan, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Net.IPAddress? address) { throw null; }
Expand Down Expand Up @@ -316,6 +317,7 @@ public IPEndPoint(System.Net.IPAddress address, int port) { }
static bool System.ISpanParsable<System.Net.IPNetwork>.TryParse(System.ReadOnlySpan<char> s, System.IFormatProvider? provider, out System.Net.IPNetwork result) { throw null; }
public override string ToString() { throw null; }
public bool TryFormat(System.Span<char> destination, out int charsWritten) { throw null; }
public bool TryFormat(System.Span<byte> utf8Destination, out int bytesWritten) { throw null; }
public static bool TryParse(System.ReadOnlySpan<char> s, out System.Net.IPNetwork result) { throw null; }
public static bool TryParse(string? s, out System.Net.IPNetwork result) { throw null; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,13 @@ string IFormattable.ToString(string? format, IFormatProvider? formatProvider) =>
public bool TryFormat(Span<char> destination, out int charsWritten) =>
TryFormatCore(destination, out charsWritten);

/// <summary>Tries to format the current IP address into the provided span.</summary>
/// <param name="utf8Destination">When this method returns, the IP address as a span of UTF8 bytes.</param>
/// <param name="bytesWritten">When this method returns, the number of bytes written into the <paramref name="utf8Destination"/>.</param>
/// <returns><see langword="true" /> if the formatting was successful; otherwise, <see langword="false" />.</returns>
public bool TryFormat(Span<byte> utf8Destination, out int bytesWritten) =>
TryFormatCore(utf8Destination, out bytesWritten);

/// <inheritdoc/>
bool ISpanFormattable.TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider? provider) =>
// format and provider are explicitly ignored
Expand Down
13 changes: 12 additions & 1 deletion src/libraries/System.Net.Primitives/src/System/Net/IPNetwork.cs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,15 @@ public override string ToString() =>
public bool TryFormat(Span<char> destination, out int charsWritten) =>
destination.TryWrite(CultureInfo.InvariantCulture, $"{BaseAddress}/{(uint)PrefixLength}", out charsWritten);

/// <summary>
/// Attempts to write the <see cref="IPNetwork"/>'s CIDR notation to the given <paramref name="utf8Destination"/> UTF8 span and returns a value indicating whether the operation succeeded.
/// </summary>
/// <param name="utf8Destination">The destination span of UTF8 bytes.</param>
/// <param name="bytesWritten">When this method returns, contains the number of bytes that were written to <paramref name="utf8Destination"/>.</param>
/// <returns><see langword="true"/> if the formatting was succesful; otherwise <see langword="false"/>.</returns>
public bool TryFormat(Span<byte> utf8Destination, out int bytesWritten) =>
Utf8.TryWrite(utf8Destination, CultureInfo.InvariantCulture, $"{BaseAddress}/{(uint)PrefixLength}", out bytesWritten);

/// <summary>
/// Determines whether two <see cref="IPNetwork"/> instances are equal.
/// </summary>
Expand Down Expand Up @@ -298,11 +307,13 @@ obj is IPNetwork other &&

/// <inheritdoc />
bool ISpanFormattable.TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider? provider) =>
// format and provider are ignored
TryFormat(destination, out charsWritten);

/// <inheritdoc />
bool IUtf8SpanFormattable.TryFormat(Span<byte> utf8Destination, out int bytesWritten, ReadOnlySpan<char> format, IFormatProvider? provider) =>
Utf8.TryWrite(utf8Destination, CultureInfo.InvariantCulture, $"{BaseAddress}/{(uint)PrefixLength}", out bytesWritten);
// format and provider are ignored
TryFormat(utf8Destination, out bytesWritten);

/// <inheritdoc />
static IPNetwork IParsable<IPNetwork>.Parse([NotNull] string s, IFormatProvider? provider) => Parse(s);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public class IPAddressParsingFormatting_Span : IPAddressParsingFormatting
public override IPAddress Parse(string ipString) => IPAddress.Parse(ipString.AsSpan());
public override bool TryParse(string ipString, out IPAddress address) => IPAddress.TryParse(ipString.AsSpan(), out address);
public virtual bool TryFormat(IPAddress address, Span<char> destination, out int charsWritten) => address.TryFormat(destination, out charsWritten);
public virtual bool TryFormat(IPAddress address, Span<byte> utf8Destination, out int bytesWritten) => ((IUtf8SpanFormattable)address).TryFormat(utf8Destination, out bytesWritten, default, null);
public virtual bool TryFormat(IPAddress address, Span<byte> utf8Destination, out int bytesWritten) => address.TryFormat(utf8Destination, out bytesWritten);

[Theory]
[MemberData(nameof(ValidIpv4Addresses))]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ public void TryFormatSpan_NotEnoughLength_ReturnsFalse(string input)
// UTF8
{
Span<byte> span = stackalloc byte[input.Length - 1];
Assert.False(((IUtf8SpanFormattable)network).TryFormat(span, out int bytesWritten, default, null));
Assert.False(network.TryFormat(span, out int bytesWritten));
Assert.Equal(0, bytesWritten);
}
}
Expand All @@ -290,7 +290,7 @@ public void TryFormatSpan_EnoughLength_Succeeds(string input)
// UTF8
{
Span<byte> span = stackalloc byte[input.Length + additionalLength];
Assert.True(((IUtf8SpanFormattable)network).TryFormat(span, out int bytesWritten, default, null));
Assert.True(network.TryFormat(span, out int bytesWritten));
Assert.Equal(input.Length, bytesWritten);
Assert.Equal(input, Encoding.UTF8.GetString(span.Slice(0, bytesWritten)));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public static partial class Utf8Formatter
//
private static bool TryFormatDateTimeL(DateTime value, Span<byte> destination, out int bytesWritten)
{
if (((IUtf8SpanFormattable)value).TryFormat(destination, out bytesWritten, "r", CultureInfo.InvariantCulture))
if (value.TryFormat(destination, out bytesWritten, "r", CultureInfo.InvariantCulture))
{
Debug.Assert(bytesWritten == 29);
Ascii.ToLowerInPlace(destination.Slice(0, bytesWritten), out bytesWritten);
Expand Down
4 changes: 2 additions & 2 deletions src/libraries/System.Private.CoreLib/src/System/Byte.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,8 @@ public bool TryFormat(Span<char> destination, out int charsWritten, [StringSynta
return Number.TryFormatUInt32(m_value, format, provider, destination, out charsWritten);
}

/// <inheritdoc/>
bool IUtf8SpanFormattable.TryFormat(Span<byte> utf8Destination, out int bytesWritten, ReadOnlySpan<char> format, IFormatProvider? provider)
/// <inheritdoc cref="IUtf8SpanFormattable.TryFormat" />
public bool TryFormat(Span<byte> utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan<char> format = default, IFormatProvider? provider = null)
{
return Number.TryFormatUInt32(m_value, format, provider, utf8Destination, out bytesWritten);
}
Expand Down
1 change: 1 addition & 0 deletions src/libraries/System.Private.CoreLib/src/System/Char.cs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ bool ISpanFormattable.TryFormat(Span<char> destination, out int charsWritten, Re
return false;
}

/// <inheritdoc cref="IUtf8SpanFormattable.TryFormat" />
bool IUtf8SpanFormattable.TryFormat(Span<byte> utf8Destination, out int bytesWritten, ReadOnlySpan<char> format, IFormatProvider? provider) =>
new Rune(this).TryEncodeToUtf8(utf8Destination, out bytesWritten);

Expand Down
5 changes: 3 additions & 2 deletions src/libraries/System.Private.CoreLib/src/System/DateOnly.cs
Original file line number Diff line number Diff line change
Expand Up @@ -784,10 +784,11 @@ public string ToString([StringSyntax(StringSyntaxAttribute.DateOnlyFormat)] stri
/// <param name="format">A span containing the characters that represent a standard or custom format string that defines the acceptable format for destination.</param>
/// <param name="provider">An optional object that supplies culture-specific formatting information for destination.</param>
/// <returns>true if the formatting was successful; otherwise, false.</returns>
public bool TryFormat(Span<char> destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.DateOnlyFormat)] ReadOnlySpan<char> format = default(ReadOnlySpan<char>), IFormatProvider? provider = null) =>
public bool TryFormat(Span<char> destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.DateOnlyFormat)] ReadOnlySpan<char> format = default, IFormatProvider? provider = null) =>
TryFormatCore(destination, out charsWritten, format, provider);

bool IUtf8SpanFormattable.TryFormat(Span<byte> utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.DateOnlyFormat)] ReadOnlySpan<char> format, IFormatProvider? provider) =>
/// <inheritdoc cref="IUtf8SpanFormattable.TryFormat" />
public bool TryFormat(Span<byte> utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.DateOnlyFormat)] ReadOnlySpan<char> format = default, IFormatProvider? provider = null) =>
TryFormatCore(utf8Destination, out bytesWritten, format, provider);

private bool TryFormatCore<TChar>(Span<TChar> destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.DateOnlyFormat)] ReadOnlySpan<char> format, IFormatProvider? provider = null)
Expand Down
3 changes: 2 additions & 1 deletion src/libraries/System.Private.CoreLib/src/System/DateTime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1806,7 +1806,8 @@ public string ToString([StringSyntax(StringSyntaxAttribute.DateTimeFormat)] stri
public bool TryFormat(Span<char> destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.DateTimeFormat)] ReadOnlySpan<char> format = default, IFormatProvider? provider = null) =>
DateTimeFormat.TryFormat(this, destination, out charsWritten, format, provider);

bool IUtf8SpanFormattable.TryFormat(Span<byte> utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.DateTimeFormat)] ReadOnlySpan<char> format, IFormatProvider? provider) =>
/// <inheritdoc cref="IUtf8SpanFormattable.TryFormat" />
public bool TryFormat(Span<byte> utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.DateTimeFormat)] ReadOnlySpan<char> format = default, IFormatProvider? provider = null) =>
DateTimeFormat.TryFormat(this, utf8Destination, out bytesWritten, format, provider);

public DateTime ToUniversalTime()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,8 @@ public string ToString([StringSyntax(StringSyntaxAttribute.DateTimeFormat)] stri
public bool TryFormat(Span<char> destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.DateTimeFormat)] ReadOnlySpan<char> format = default, IFormatProvider? formatProvider = null) =>
DateTimeFormat.TryFormat(ClockDateTime, destination, out charsWritten, format, formatProvider, Offset);

bool IUtf8SpanFormattable.TryFormat(Span<byte> utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.DateTimeFormat)] ReadOnlySpan<char> format, IFormatProvider? formatProvider) =>
/// <inheritdoc cref="IUtf8SpanFormattable.TryFormat" />
public bool TryFormat(Span<byte> utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.DateTimeFormat)] ReadOnlySpan<char> format = default, IFormatProvider? formatProvider = null) =>
DateTimeFormat.TryFormat(ClockDateTime, utf8Destination, out bytesWritten, format, formatProvider, Offset);

public DateTimeOffset ToUniversalTime() =>
Expand Down
4 changes: 2 additions & 2 deletions src/libraries/System.Private.CoreLib/src/System/Decimal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -504,8 +504,8 @@ public bool TryFormat(Span<char> destination, out int charsWritten, [StringSynta
return Number.TryFormatDecimal(this, format, NumberFormatInfo.GetInstance(provider), destination, out charsWritten);
}

/// <inheritdoc/>
bool IUtf8SpanFormattable.TryFormat(Span<byte> utf8Destination, out int bytesWritten, ReadOnlySpan<char> format, IFormatProvider? provider)
/// <inheritdoc cref="IUtf8SpanFormattable.TryFormat" />
public bool TryFormat(Span<byte> utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan<char> format = default, IFormatProvider? provider = null)
{
return Number.TryFormatDecimal(this, format, NumberFormatInfo.GetInstance(provider), utf8Destination, out bytesWritten);
}
Expand Down
4 changes: 2 additions & 2 deletions src/libraries/System.Private.CoreLib/src/System/Double.cs
Original file line number Diff line number Diff line change
Expand Up @@ -366,8 +366,8 @@ public bool TryFormat(Span<char> destination, out int charsWritten, [StringSynta
return Number.TryFormatDouble(m_value, format, NumberFormatInfo.GetInstance(provider), destination, out charsWritten);
}

/// <inheritdoc/>
bool IUtf8SpanFormattable.TryFormat(Span<byte> utf8Destination, out int bytesWritten, ReadOnlySpan<char> format, IFormatProvider? provider)
/// <inheritdoc cref="IUtf8SpanFormattable.TryFormat" />
public bool TryFormat(Span<byte> utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan<char> format = default, IFormatProvider? provider = null)
{
return Number.TryFormatDouble(m_value, format, NumberFormatInfo.GetInstance(provider), utf8Destination, out bytesWritten);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -770,7 +770,7 @@ internal static void FormatFraction<TChar>(ref ValueListBuilder<TChar> result, i
int charCount;
bool formatted = typeof(TChar) == typeof(char) ?
fraction.TryFormat(MemoryMarshal.Cast<TChar, char>(chars), out charCount, fractionFormat, CultureInfo.InvariantCulture) :
((IUtf8SpanFormattable)fraction).TryFormat(MemoryMarshal.Cast<TChar, byte>(chars), out charCount, fractionFormat, CultureInfo.InvariantCulture);
fraction.TryFormat(MemoryMarshal.Cast<TChar, byte>(chars), out charCount, fractionFormat, CultureInfo.InvariantCulture);
Debug.Assert(charCount != 0);
result.Append(chars.Slice(0, charCount));
}
Expand Down
4 changes: 2 additions & 2 deletions src/libraries/System.Private.CoreLib/src/System/Half.cs
Original file line number Diff line number Diff line change
Expand Up @@ -540,8 +540,8 @@ public bool TryFormat(Span<char> destination, out int charsWritten, [StringSynta
return Number.TryFormatHalf(this, format, NumberFormatInfo.GetInstance(provider), destination, out charsWritten);
}

/// <inheritdoc/>
bool IUtf8SpanFormattable.TryFormat(Span<byte> utf8Destination, out int bytesWritten, ReadOnlySpan<char> format, IFormatProvider? provider)
/// <inheritdoc cref="IUtf8SpanFormattable.TryFormat" />
public bool TryFormat(Span<byte> utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan<char> format = default, IFormatProvider? provider = null)
{
return Number.TryFormatHalf(this, format, NumberFormatInfo.GetInstance(provider), utf8Destination, out bytesWritten);
}
Expand Down
4 changes: 2 additions & 2 deletions src/libraries/System.Private.CoreLib/src/System/Int128.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ public bool TryFormat(Span<char> destination, out int charsWritten, [StringSynta
return Number.TryFormatInt128(this, format, provider, destination, out charsWritten);
}

/// <inheritdoc/>
bool IUtf8SpanFormattable.TryFormat(Span<byte> utf8Destination, out int bytesWritten, ReadOnlySpan<char> format, IFormatProvider? provider)
/// <inheritdoc cref="IUtf8SpanFormattable.TryFormat" />
public bool TryFormat(Span<byte> utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan<char> format = default, IFormatProvider? provider = null)
{
return Number.TryFormatInt128(this, format, provider, utf8Destination, out bytesWritten);
}
Expand Down
4 changes: 2 additions & 2 deletions src/libraries/System.Private.CoreLib/src/System/Int16.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ public bool TryFormat(Span<char> destination, out int charsWritten, [StringSynta
return Number.TryFormatInt32(m_value, 0x0000FFFF, format, provider, destination, out charsWritten);
}

/// <inheritdoc/>
bool IUtf8SpanFormattable.TryFormat(Span<byte> utf8Destination, out int bytesWritten, ReadOnlySpan<char> format, IFormatProvider? provider)
/// <inheritdoc cref="IUtf8SpanFormattable.TryFormat" />
public bool TryFormat(Span<byte> utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan<char> format = default, IFormatProvider? provider = null)
{
return Number.TryFormatInt32(m_value, 0x0000FFFF, format, provider, utf8Destination, out bytesWritten);
}
Expand Down
4 changes: 2 additions & 2 deletions src/libraries/System.Private.CoreLib/src/System/Int32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ public bool TryFormat(Span<char> destination, out int charsWritten, [StringSynta
return Number.TryFormatInt32(m_value, ~0, format, provider, destination, out charsWritten);
}

/// <inheritdoc/>
bool IUtf8SpanFormattable.TryFormat(Span<byte> utf8Destination, out int bytesWritten, ReadOnlySpan<char> format, IFormatProvider? provider)
/// <inheritdoc cref="IUtf8SpanFormattable.TryFormat" />
public bool TryFormat(Span<byte> utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan<char> format = default, IFormatProvider? provider = null)
{
return Number.TryFormatInt32(m_value, ~0, format, provider, utf8Destination, out bytesWritten);
}
Expand Down
4 changes: 2 additions & 2 deletions src/libraries/System.Private.CoreLib/src/System/Int64.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ public bool TryFormat(Span<char> destination, out int charsWritten, [StringSynta
return Number.TryFormatInt64(m_value, format, provider, destination, out charsWritten);
}

/// <inheritdoc/>
bool IUtf8SpanFormattable.TryFormat(Span<byte> utf8Destination, out int bytesWritten, ReadOnlySpan<char> format, IFormatProvider? provider)
/// <inheritdoc cref="IUtf8SpanFormattable.TryFormat" />
public bool TryFormat(Span<byte> utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan<char> format = default, IFormatProvider? provider = null)
{
return Number.TryFormatInt64(m_value, format, provider, utf8Destination, out bytesWritten);
}
Expand Down
6 changes: 3 additions & 3 deletions src/libraries/System.Private.CoreLib/src/System/IntPtr.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,9 @@ public int CompareTo(nint value)
public bool TryFormat(Span<char> destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan<char> format = default, IFormatProvider? provider = null) =>
((nint_t)_value).TryFormat(destination, out charsWritten, format, provider);

/// <inheritdoc/>
bool IUtf8SpanFormattable.TryFormat(Span<byte> utf8Destination, out int bytesWritten, ReadOnlySpan<char> format, IFormatProvider? provider) =>
((IUtf8SpanFormattable)(nint_t)_value).TryFormat(utf8Destination, out bytesWritten, format, provider);
/// <inheritdoc cref="IUtf8SpanFormattable.TryFormat" />
public bool TryFormat(Span<byte> utf8Destination, out int bytesWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan<char> format = default, IFormatProvider? provider = null) =>
((nint_t)_value).TryFormat(utf8Destination, out bytesWritten, format, provider);

public static nint Parse(string s) => (nint)nint_t.Parse(s);
public static nint Parse(string s, NumberStyles style) => (nint)nint_t.Parse(s, style);
Expand Down
Loading