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 MemoryExtensions.Split #79048

Merged
merged 7 commits into from
Dec 8, 2022
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 @@ -316,12 +316,12 @@ internal static bool TryFindCGroupPathForSubsystem(CGroupVersion cgroupVersion,
{
using (var reader = new StreamReader(procCGroupFilePath))
{
Span<Range> lineParts = stackalloc Range[4];
string? line;
while ((line = reader.ReadLine()) != null)
{
string[] lineParts = line.Split(':');

if (lineParts.Length != 3)
ReadOnlySpan<char> lineSpan = line;
if (lineSpan.Split(lineParts, ':') != 3)
{
// Malformed line.
continue;
Expand All @@ -333,23 +333,23 @@ internal static bool TryFindCGroupPathForSubsystem(CGroupVersion cgroupVersion,
// list. See man page for cgroups for /proc/[pid]/cgroups format, e.g:
// hierarchy-ID:controller-list:cgroup-path
// 5:cpuacct,cpu,cpuset:/daemons
if (Array.IndexOf(lineParts[1].Split(','), subsystem) < 0)
if (Array.IndexOf(line[lineParts[1]].Split(','), subsystem) < 0)
{
// Not the relevant entry.
continue;
}

path = lineParts[2];
path = line[lineParts[2]];
return true;
}
else if (cgroupVersion == CGroupVersion.CGroup2)
{
// cgroup v2: Find the first entry that matches the cgroup v2 hierarchy:
// 0::$PATH

if ((lineParts[0] == "0") && (lineParts[1].Length == 0))
if (lineSpan[lineParts[0]] is "0" && lineSpan[lineParts[1]].IsEmpty)
{
path = lineParts[2];
path = line[lineParts[2]];
return true;
}
}
Expand Down
45 changes: 12 additions & 33 deletions src/libraries/Common/src/System/Drawing/ColorConverterCommon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,27 +53,17 @@ public static Color ConvertFromString(string strValue, CultureInfo culture)
}
}

// Nope. Parse the RGBA from the text.
//
string[] tokens = text.Split(sep);
int[] values = new int[tokens.Length];
for (int i = 0; i < values.Length; i++)
{
values[i] = unchecked(IntFromString(tokens[i], culture));
}

// We should now have a number of parsed integer values.
// We support 1, 3, or 4 arguments:
//
// 1 -- full ARGB encoded
// 3 -- RGB
// 4 -- ARGB
//
return values.Length switch
ReadOnlySpan<char> textSpan = text;
Span<Range> tokens = stackalloc Range[5];
return textSpan.Split(tokens, sep) switch
{
1 => PossibleKnownColor(Color.FromArgb(values[0])),
3 => PossibleKnownColor(Color.FromArgb(values[0], values[1], values[2])),
4 => PossibleKnownColor(Color.FromArgb(values[0], values[1], values[2], values[3])),
1 => PossibleKnownColor(Color.FromArgb(IntFromString(textSpan[tokens[0]], culture))),
3 => PossibleKnownColor(Color.FromArgb(IntFromString(textSpan[tokens[0]], culture), IntFromString(textSpan[tokens[1]], culture), IntFromString(textSpan[tokens[2]], culture))),
4 => PossibleKnownColor(Color.FromArgb(IntFromString(textSpan[tokens[0]], culture), IntFromString(textSpan[tokens[1]], culture), IntFromString(textSpan[tokens[2]], culture), IntFromString(textSpan[tokens[3]], culture))),
dakersnar marked this conversation as resolved.
Show resolved Hide resolved
_ => throw new ArgumentException(SR.Format(SR.InvalidColor, text)),
};
}
Expand All @@ -96,42 +86,31 @@ private static Color PossibleKnownColor(Color color)
return color;
}

private static int IntFromString(string text, CultureInfo culture)
private static int IntFromString(ReadOnlySpan<char> text, CultureInfo culture)
{
text = text.Trim();

try
{
if (text[0] == '#')
{
return IntFromString(text.Substring(1), 16);
return Convert.ToInt32(text.Slice(1).ToString(), 16);
}
else if (text.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
|| text.StartsWith("&h", StringComparison.OrdinalIgnoreCase))
else if (text.StartsWith("0x", StringComparison.OrdinalIgnoreCase) || text.StartsWith("&h", StringComparison.OrdinalIgnoreCase))
{
return IntFromString(text.Substring(2), 16);
return Convert.ToInt32(text.Slice(2).ToString(), 16);
}
else
{
Debug.Assert(culture != null);
var formatInfo = (NumberFormatInfo?)culture.GetFormat(typeof(NumberFormatInfo));
return IntFromString(text, formatInfo);
return int.Parse(text, provider: formatInfo);
}
}
catch (Exception e)
{
throw new ArgumentException(SR.Format(SR.ConvertInvalidPrimitive, text, nameof(Int32)), e);
throw new ArgumentException(SR.Format(SR.ConvertInvalidPrimitive, text.ToString(), nameof(Int32)), e);
}
}

private static int IntFromString(string value, int radix)
{
return Convert.ToInt32(value, radix);
}

private static int IntFromString(string value, NumberFormatInfo? formatInfo)
{
return int.Parse(value, NumberStyles.Integer, formatInfo);
}
}
}
17 changes: 9 additions & 8 deletions src/libraries/System.Data.Common/src/System/Data/XDRSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -297,16 +297,17 @@ private static NameType FindNameType(string name)
private static Type ParseDataType(string dt, string dtValues)
{
string strType = dt;
string[] parts = dt.Split(':');

if (parts.Length > 2)
Span<System.Range> parts = stackalloc System.Range[3];
switch (dt.AsSpan().Split(parts, ':'))
{
throw ExceptionBuilder.InvalidAttributeValue("type", dt);
}
else if (parts.Length == 2)
{
// CONSIDER: check that we have valid prefix
strType = parts[1];
case 2:
// CONSIDER: check that we have valid prefix
strType = dt[parts[1]];
break;

case > 2:
throw ExceptionBuilder.InvalidAttributeValue("type", dt);
}

NameType nt = FindNameType(strType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,22 +199,23 @@ private static void ParseVersion(string? versionString, out int major, out int m

major = minor = build = priv = 0;

if (versionString != null)
ReadOnlySpan<char> versionSpan = versionString;

Span<Range> parts = stackalloc Range[5];
parts = parts.Slice(0, versionSpan.Split(parts, '.'));

if (parts.Length <= 4 && parts.Length > 0)
{
string[] parts = versionString.Split('.');
if (parts.Length <= 4 && parts.Length > 0)
major = ParseUInt16UntilNonDigit(versionSpan[parts[0]], out bool endedEarly);
if (!endedEarly && parts.Length > 1)
{
major = ParseUInt16UntilNonDigit(parts[0], out bool endedEarly);
if (!endedEarly && parts.Length > 1)
minor = ParseUInt16UntilNonDigit(versionSpan[parts[1]], out endedEarly);
if (!endedEarly && parts.Length > 2)
{
minor = ParseUInt16UntilNonDigit(parts[1], out endedEarly);
if (!endedEarly && parts.Length > 2)
build = ParseUInt16UntilNonDigit(versionSpan[parts[2]], out endedEarly);
if (!endedEarly && parts.Length > 3)
{
build = ParseUInt16UntilNonDigit(parts[2], out endedEarly);
if (!endedEarly && parts.Length > 3)
{
priv = ParseUInt16UntilNonDigit(parts[3], out _);
}
priv = ParseUInt16UntilNonDigit(versionSpan[parts[3]], out _);
}
}
}
Expand All @@ -225,7 +226,7 @@ private static void ParseVersion(string? versionString, out int major, out int m
/// <param name="s">The string to parse.</param>
/// <param name="endedEarly">Whether parsing ended prior to reaching the end of the input.</param>
/// <returns>The parsed value.</returns>
private static ushort ParseUInt16UntilNonDigit(string s, out bool endedEarly)
private static ushort ParseUInt16UntilNonDigit(ReadOnlySpan<char> s, out bool endedEarly)
{
endedEarly = false;
ushort result = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ private static bool IsRemoteMachineCore(string machineName)
{
ReadOnlySpan<char> baseName = machineName.AsSpan(machineName.StartsWith('\\') ? 2 : 0);
return
!baseName.Equals(".", StringComparison.Ordinal) &&
baseName is not "." &&
!baseName.Equals(Interop.Kernel32.GetComputerName(), StringComparison.OrdinalIgnoreCase);
}

Expand Down Expand Up @@ -499,7 +499,7 @@ private static ProcessInfo[] GetProcessInfos(PerformanceCounterLib library, int

ReadOnlySpan<char> instanceName = PERF_INSTANCE_DEFINITION.GetName(in instance, data.Slice(instancePos));

if (instanceName.Equals("_Total", StringComparison.Ordinal))
if (instanceName is "_Total")
{
// continue
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>System.Drawing</RootNamespace>
<TargetFrameworks>$(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)</TargetFrameworks>
Expand Down Expand Up @@ -37,6 +37,7 @@
<ItemGroup>
<Reference Include="System.Collections" />
<Reference Include="System.ComponentModel.Primitives" />
<Reference Include="System.Memory" />
<Reference Include="System.Numerics.Vectors" />
<Reference Include="System.ObjectModel" />
<Reference Include="System.Runtime" />
Expand Down
4 changes: 4 additions & 0 deletions src/libraries/System.Memory/ref/System.Memory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,10 @@ public static void Sort<TKey, TValue>(this System.Span<TKey> keys, System.Span<T
public static void Sort<TKey, TValue>(this System.Span<TKey> keys, System.Span<TValue> items, System.Comparison<TKey> comparison) { }
public static void Sort<T, TComparer>(this System.Span<T> span, TComparer comparer) where TComparer : System.Collections.Generic.IComparer<T>? { }
public static void Sort<TKey, TValue, TComparer>(this System.Span<TKey> keys, System.Span<TValue> items, TComparer comparer) where TComparer : System.Collections.Generic.IComparer<TKey>? { }
public static int Split(this System.ReadOnlySpan<char> source, System.Span<System.Range> destination, char separator, System.StringSplitOptions options = System.StringSplitOptions.None) { throw null; }
public static int Split(this System.ReadOnlySpan<char> source, System.Span<System.Range> destination, System.ReadOnlySpan<char> separator, System.StringSplitOptions options = System.StringSplitOptions.None) { throw null; }
public static int SplitAny(this System.ReadOnlySpan<char> source, System.Span<System.Range> destination, System.ReadOnlySpan<char> separators, System.StringSplitOptions options = System.StringSplitOptions.None) { throw null; }
public static int SplitAny(this System.ReadOnlySpan<char> source, System.Span<System.Range> destination, System.ReadOnlySpan<string> separators, System.StringSplitOptions options = System.StringSplitOptions.None) { throw null; }
public static bool StartsWith(this System.ReadOnlySpan<char> span, System.ReadOnlySpan<char> value, System.StringComparison comparisonType) { throw null; }
public static bool StartsWith<T>(this System.ReadOnlySpan<T> span, System.ReadOnlySpan<T> value) where T : System.IEquatable<T>? { throw null; }
public static bool StartsWith<T>(this System.Span<T> span, System.ReadOnlySpan<T> value) where T : System.IEquatable<T>? { throw null; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ private static bool TryReadPercentEncodedAlpnProtocolName(string value, int star
}
break;
case 5:
if (span.SequenceEqual("clear"))
if (span is "clear")
{
result = "clear";
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -470,9 +470,13 @@ private static bool TryDecodeMime(string? input, [NotNullWhen(true)] out string?
return false;
}

string[] parts = processedInput.Split('?');
Span<Range> parts = stackalloc Range[6];
ReadOnlySpan<char> processedInputSpan = processedInput;
// "=, encodingName, encodingType, encodedData, ="
if (parts.Length != 5 || parts[0] != "\"=" || parts[4] != "=\"" || parts[2].ToLowerInvariant() != "b")
if (processedInputSpan.Split(parts, '?') != 5 ||
processedInputSpan[parts[0]] is not "\"=" ||
processedInputSpan[parts[4]] is not "=\"" ||
!processedInputSpan[parts[2]].Equals("b", StringComparison.OrdinalIgnoreCase))
{
// Not encoded.
// This does not support multi-line encoding.
Expand All @@ -482,8 +486,8 @@ private static bool TryDecodeMime(string? input, [NotNullWhen(true)] out string?

try
{
Encoding encoding = Encoding.GetEncoding(parts[1]);
byte[] bytes = Convert.FromBase64String(parts[3]);
Encoding encoding = Encoding.GetEncoding(processedInput[parts[1]]);
byte[] bytes = Convert.FromBase64String(processedInput[parts[3]]);
output = encoding.GetString(bytes, 0, bytes.Length);
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,10 +234,11 @@ private HttpEnvironmentProxy(Uri? httpProxy, Uri? httpsProxy, string? bypassList
// UriBuilder does not handle that now e.g. does not distinguish between empty and missing.
if (user == "" && password == "")
{
string[] tokens = uri.ToString().Split('/', 3);
if (tokens.Length == 3)
Span<Range> tokens = stackalloc Range[3];
ReadOnlySpan<char> uriSpan = uri.ToString();
if (uriSpan.Split(tokens, '/') == 3)
{
uri = new Uri($"{tokens[0]}//:@{tokens[2]}");
uri = new Uri($"{uriSpan[tokens[0]]}//:@{uriSpan[tokens[2]]}");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -614,13 +614,15 @@ internal bool IsLocalDomain(string host)
}

// Test for "127.###.###.###" without using regex.
string[] ipParts = host.Split('.');
if (ipParts != null && ipParts.Length == 4 && ipParts[0] == "127")
ReadOnlySpan<char> hostSpan = host;
Span<Range> ipParts = stackalloc Range[5];
ipParts = ipParts.Slice(0, hostSpan.Split(ipParts, '.'));
if (ipParts.Length == 4 && hostSpan[ipParts[0]] is "127")
{
int i;
for (i = 1; i < ipParts.Length; i++)
{
string part = ipParts[i];
ReadOnlySpan<char> part = hostSpan[ipParts[i]];
switch (part.Length)
{
case 3:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ public virtual CultureInfo Parent
parentName = "zh-Hant";
}
}
else if (_name.Length > 8 && _name.AsSpan(2, 4).Equals("-Han", StringComparison.Ordinal) && _name[7] == '-') // cultures like zh-Hant-* and zh-Hans-*
else if (_name.Length > 8 && _name.AsSpan(2, 4) is "-Han" && _name[7] == '-') // cultures like zh-Hant-* and zh-Hans-*
{
if (_name[6] == 't') // zh-Hant-*
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,29 +184,32 @@ private static int CompareEraRanges(EraInfo a, EraInfo b)
// Get Strings
//
// Needs to be a certain length e_a_E_A at least (7 chars, exactly 4 groups)
string[] names = data.Split('_');

// Should have exactly 4 parts
// 0 - Era Name
// 1 - Abbreviated Era Name
// 2 - English Era Name
// 3 - Abbreviated English Era Name
if (names.Length != 4) return null;
Span<Range> names = stackalloc Range[5];
ReadOnlySpan<char> dataSpan = data;
if (dataSpan.Split(names, '_') == 4)
{
ReadOnlySpan<char> eraName = dataSpan[names[0]];
ReadOnlySpan<char> abbreviatedEraName = dataSpan[names[1]];
ReadOnlySpan<char> englishEraName = dataSpan[names[2]];
ReadOnlySpan<char> abbreviatedEnglishEraName = dataSpan[names[3]];
stephentoub marked this conversation as resolved.
Show resolved Hide resolved

// Each part should have data in it
if (names[0].Length == 0 ||
names[1].Length == 0 ||
names[2].Length == 0 ||
names[3].Length == 0)
return null;
// Each part should have data in it
if (!eraName.IsEmpty && !abbreviatedEraName.IsEmpty && !englishEraName.IsEmpty && !abbreviatedEnglishEraName.IsEmpty)
{
// Now we have an era we can build
// Note that the era # and max era year need cleaned up after sorting
// Don't use the full English Era Name (names[2])
return new EraInfo(0, year, month, day, year - 1, 1, 0,
eraName.ToString(), abbreviatedEraName.ToString(), abbreviatedEnglishEraName.ToString());
}
}

//
// Now we have an era we can build
// Note that the era # and max era year need cleaned up after sorting
// Don't use the full English Era Name (names[2])
//
return new EraInfo(0, year, month, day, year - 1, 1, 0,
names[0], names[1], names[3]);
return null;
}
}
}
Loading