Backport `string.Contains(char)` and `string.EndsWith(char)`

This commit is contained in:
YoshiRulz 2024-07-03 19:27:47 +10:00
parent ad8b4653d4
commit 43d16473d8
No known key found for this signature in database
GPG Key ID: C4DE31C245353FB7
13 changed files with 53 additions and 26 deletions

View File

@ -8,6 +8,7 @@ using System.Text;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Common.CollectionExtensions; using BizHawk.Common.CollectionExtensions;
using BizHawk.Common.StringExtensions;
namespace BizHawk.BizInvoke namespace BizHawk.BizInvoke
{ {
@ -534,7 +535,7 @@ namespace BizHawk.BizInvoke
throw new NotImplementedException("Multidimensional arrays are not supported!"); throw new NotImplementedException("Multidimensional arrays are not supported!");
} }
if (type.Name.Contains('*')) if (type.Name.ContainsOrdinal('*'))
{ {
throw new NotImplementedException("Only 0-based 1-dimensional arrays are supported!"); throw new NotImplementedException("Only 0-based 1-dimensional arrays are supported!");
} }

View File

@ -3,6 +3,7 @@ using System.IO;
using System.Security.Principal; using System.Security.Principal;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Common.StringExtensions;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
@ -15,7 +16,7 @@ namespace BizHawk.Client.EmuHawk
/// <remarks>http://stackoverflow.com/questions/139010/how-to-resolve-a-lnk-in-c-sharp</remarks> /// <remarks>http://stackoverflow.com/questions/139010/how-to-resolve-a-lnk-in-c-sharp</remarks>
public static string ResolveShortcut(string filename) public static string ResolveShortcut(string filename)
{ {
if (OSTailoredCode.IsUnixHost || filename.Contains("|") if (OSTailoredCode.IsUnixHost || filename.ContainsOrdinal('|')
|| !".lnk".Equals(Path.GetExtension(filename), StringComparison.OrdinalIgnoreCase)) || !".lnk".Equals(Path.GetExtension(filename), StringComparison.OrdinalIgnoreCase))
{ {
return filename; // archive internal files are never shortcuts (and choke when analyzing any further) return filename; // archive internal files are never shortcuts (and choke when analyzing any further)

View File

@ -8,6 +8,7 @@ using System.Windows.Forms;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Common.PathExtensions; using BizHawk.Common.PathExtensions;
using BizHawk.Common.StringExtensions;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Arcades.MAME; using BizHawk.Emulation.Cores.Arcades.MAME;
using BizHawk.Emulation.DiscSystem; using BizHawk.Emulation.DiscSystem;
@ -310,7 +311,7 @@ namespace BizHawk.Client.EmuHawk
{ {
static string ResolvePath(string path) static string ResolvePath(string path)
{ {
if (path.IndexOf('|') == -1 && Disc.IsValidExtension(Path.GetExtension(path))) if (!path.ContainsOrdinal('|') && Disc.IsValidExtension(Path.GetExtension(path)))
{ {
return path; // nothing to do in this case return path; // nothing to do in this case
} }
@ -342,7 +343,7 @@ namespace BizHawk.Client.EmuHawk
static ConsoleID IdentifyConsole(string path) static ConsoleID IdentifyConsole(string path)
{ {
if (path.IndexOf('|') == -1 && Disc.IsValidExtension(Path.GetExtension(path))) if (!path.ContainsOrdinal('|') && Disc.IsValidExtension(Path.GetExtension(path)))
{ {
using var disc = DiscExtensions.CreateAnyType(path, Console.WriteLine); using var disc = DiscExtensions.CreateAnyType(path, Console.WriteLine);
if (disc is null) if (disc is null)

View File

@ -61,7 +61,7 @@ namespace BizHawk.Client.EmuHawk
if (!Game.IsNullInstance()) if (!Game.IsNullInstance())
{ {
if (MainForm.CurrentlyOpenRom.Contains("|")) if (MainForm.CurrentlyOpenRom.ContainsOrdinal('|'))
{ {
var pieces = MainForm.CurrentlyOpenRom.Split('|'); var pieces = MainForm.CurrentlyOpenRom.Split('|');

View File

@ -1,8 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Reflection; using System.Reflection;
using BizHawk.Common.StringExtensions;
namespace BizHawk.Common namespace BizHawk.Common
{ {
/// <summary>Annotated fields will not be used by <see cref="DeepEquality"/> for comparison.</summary> /// <summary>Annotated fields will not be used by <see cref="DeepEquality"/> for comparison.</summary>
@ -24,7 +25,7 @@ namespace BizHawk.Common
} }
// is there a better way to do this? i couldn't find any documentation... // is there a better way to do this? i couldn't find any documentation...
return t.ToString().Contains('*'); return t.ToString().ContainsOrdinal('*');
} }
/// <summary> /// <summary>

View File

@ -13,9 +13,31 @@ namespace BizHawk.Common.StringExtensions
return new(a); return new(a);
} }
#if !(NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER)
public static bool Contains(this string haystack, char needle)
=> haystack.IndexOf(needle) >= 0;
#endif
public static bool Contains(this string haystack, string needle, StringComparison comparisonType) public static bool Contains(this string haystack, string needle, StringComparison comparisonType)
=> haystack.IndexOf(needle, comparisonType) != -1; => haystack.IndexOf(needle, comparisonType) != -1;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool ContainsOrdinal(this string haystack, char needle)
=> haystack.Contains(needle); // already ordinal
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool ContainsOrdinal(this string haystack, string needle)
=> haystack.Contains(needle); // already ordinal
#if !(NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER)
public static bool EndsWith(this string haystack, char needle)
=> haystack.Length >= 1 && haystack[^1] == needle;
#endif
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool EndsWithOrdinal(this string haystack, char needle)
=> haystack.EndsWith(needle); // already ordinal
/// <returns> /// <returns>
/// <see langword="true"/> if <paramref name="str"/> appears in <paramref name="options"/> (case-insensitive) /// <see langword="true"/> if <paramref name="str"/> appears in <paramref name="options"/> (case-insensitive)
/// </returns> /// </returns>

View File

@ -8,6 +8,7 @@ using System.Text.RegularExpressions;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using BizHawk.Common.PathExtensions; using BizHawk.Common.PathExtensions;
using BizHawk.Common.StringExtensions;
namespace BizHawk.Common namespace BizHawk.Common
{ {
@ -29,9 +30,7 @@ namespace BizHawk.Common
} }
private static string[] Escape(IEnumerable<string> args) private static string[] Escape(IEnumerable<string> args)
{ => args.Select(static s => s.ContainsOrdinal(' ') ? $"\"{s}\"" : s).ToArray();
return args.Select(s => s.Contains(" ") ? $"\"{s}\"" : s).ToArray();
}
//note: accepts . or : in the stream stream/substream separator in the stream ID format, since that changed at some point in FFMPEG history //note: accepts . or : in the stream stream/substream separator in the stream ID format, since that changed at some point in FFMPEG history
//if someone has a better idea how to make the determination of whether an audio stream is available, I'm all ears //if someone has a better idea how to make the determination of whether an audio stream is available, I'm all ears

View File

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Common.StringExtensions; using BizHawk.Common.StringExtensions;
@ -47,7 +46,7 @@ namespace BizHawk.Emulation.Cores.Arcades.MAME
foreach (var buttonField in buttonFields) foreach (var buttonField in buttonFields)
{ {
if (buttonField != string.Empty && !buttonField.Contains('%')) if (buttonField.Length is not 0 && !buttonField.ContainsOrdinal('%'))
{ {
var tag = buttonField.SubstringBefore(','); var tag = buttonField.SubstringBefore(',');
var field = buttonField.SubstringAfterLast(','); var field = buttonField.SubstringAfterLast(',');
@ -66,7 +65,7 @@ namespace BizHawk.Emulation.Cores.Arcades.MAME
foreach (var analogField in analogFields) foreach (var analogField in analogFields)
{ {
if (analogField != string.Empty && !analogField.Contains('%')) if (analogField.Length is not 0 && !analogField.ContainsOrdinal('%'))
{ {
var keys = analogField.Split(','); var keys = analogField.Split(',');
var tag = keys[0]; var tag = keys[0];

View File

@ -166,7 +166,7 @@ namespace BizHawk.Emulation.Cores.Arcades.MAME
} }
else else
{ {
if (hashdata.Contains("^")) if (hashdata.EndsWithOrdinal('^'))
{ {
hashdata = hashdata.RemoveSuffix("^"); hashdata = hashdata.RemoveSuffix("^");
name += " (BAD DUMP)"; name += " (BAD DUMP)";

View File

@ -2,10 +2,10 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq;
using System.Threading; using System.Threading;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Common.StringExtensions;
namespace BizHawk.Emulation.Cores.Arcades.MAME namespace BizHawk.Emulation.Cores.Arcades.MAME
{ {
@ -54,7 +54,7 @@ namespace BizHawk.Emulation.Cores.Arcades.MAME
public static bool IsMAMEMachine(string path) public static bool IsMAMEMachine(string path)
{ {
if (_acquire == null) throw new InvalidOperationException("MAME Machine DB not initialized. It's a client responsibility because only a client knows where the database is located."); if (_acquire == null) throw new InvalidOperationException("MAME Machine DB not initialized. It's a client responsibility because only a client knows where the database is located.");
if (path.Contains('|')) return false; // binded archive, can't be a mame zip (note | is not a legal filesystem char, at least on windows) if (path.ContainsOrdinal('|')) return false; // binded archive, can't be a mame zip (note | is not a legal filesystem char, at least on windows)
if (Path.GetExtension(path).ToLowerInvariant() is not ".zip" and not ".7z") return false; if (Path.GetExtension(path).ToLowerInvariant() is not ".zip" and not ".7z") return false;
_acquire.WaitOne(); _acquire.WaitOne();
return Instance.MachineDB.Contains(Path.GetFileNameWithoutExtension(path).ToLowerInvariant()); return Instance.MachineDB.Contains(Path.GetFileNameWithoutExtension(path).ToLowerInvariant());

View File

@ -1,5 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using BizHawk.Common.StringExtensions;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Components.FairchildF8 namespace BizHawk.Emulation.Cores.Components.FairchildF8
@ -15,17 +17,16 @@ namespace BizHawk.Emulation.Cores.Components.FairchildF8
//n immediate succeeds the opcode and the displacement (if present) //n immediate succeeds the opcode and the displacement (if present)
//nn immediately succeeds the opcode and the displacement (if present) //nn immediately succeeds the opcode and the displacement (if present)
if (format.IndexOf("nn", StringComparison.Ordinal) != -1) if (format.ContainsOrdinal("nn"))
{ {
format = format.Replace("nn", read(addr++) format = format.Replace("nn", read(addr++)
.ToString("X2") + read(addr++) .ToString("X2") + read(addr++)
.ToString("X2") + "h"); // MSB is read first .ToString("X2") + "h"); // MSB is read first
} }
if (format.ContainsOrdinal('n')) format = format.Replace("n", $"{read(addr++):X2}h");
if (format.IndexOf("n", StringComparison.Ordinal) != -1) format = format.Replace("n", $"{read(addr++):X2}h"); format = format.Replace("+d", "d");
if (format.ContainsOrdinal('d'))
if (format.IndexOf("+d", StringComparison.Ordinal) != -1) format = format.Replace("+d", "d");
if (format.IndexOf("d", StringComparison.Ordinal) != -1)
{ {
var b = unchecked((sbyte)read(addr++)); var b = unchecked((sbyte)read(addr++));
format = format.Replace("d", $"{(b < 0 ? '-' : '+')}{(b < 0 ? -b : b):X2}h"); format = format.Replace("d", $"{(b < 0 ? '-' : '+')}{(b < 0 ? -b : b):X2}h");

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using BizHawk.Common.StringExtensions;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Components.Z80A namespace BizHawk.Emulation.Cores.Components.Z80A
@ -13,11 +14,11 @@ namespace BizHawk.Emulation.Cores.Components.Z80A
//n immediate succeeds the opcode and the displacement (if present) //n immediate succeeds the opcode and the displacement (if present)
//nn immediately succeeds the opcode and the displacement (if present) //nn immediately succeeds the opcode and the displacement (if present)
if (format.IndexOf("nn", StringComparison.Ordinal) != -1) format = format.Replace("nn", $"{read(addr++) + (read(addr++) << 8):X4}h"); // LSB is read first if (format.ContainsOrdinal("nn")) format = format.Replace("nn", $"{read(addr++) + (read(addr++) << 8):X4}h"); // LSB is read first
if (format.IndexOf("n", StringComparison.Ordinal) != -1) format = format.Replace("n", $"{read(addr++):X2}h"); if (format.ContainsOrdinal('n')) format = format.Replace("n", $"{read(addr++):X2}h");
if (format.IndexOf("+d", StringComparison.Ordinal) != -1) format = format.Replace("+d", "d"); format = format.Replace("+d", "d");
if (format.IndexOf("d", StringComparison.Ordinal) != -1) if (format.ContainsOrdinal('d'))
{ {
var b = unchecked ((sbyte) read(addr++)); var b = unchecked ((sbyte) read(addr++));
format = format.Replace("d", $"{(b < 0 ? '-' : '+')}{(b < 0 ? -b : b):X2}h"); format = format.Replace("d", $"{(b < 0 ? '-' : '+')}{(b < 0 ? -b : b):X2}h");

View File

@ -7,6 +7,7 @@ using System.Text;
using BizHawk.BizInvoke; using BizHawk.BizInvoke;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Common.StringExtensions;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Consoles.Nintendo.N3DS namespace BizHawk.Emulation.Cores.Consoles.Nintendo.N3DS
@ -46,7 +47,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.N3DS
[CoreConstructor(VSystemID.Raw.N3DS)] [CoreConstructor(VSystemID.Raw.N3DS)]
public Encore(CoreLoadParameters<EncoreSettings, EncoreSyncSettings> lp) public Encore(CoreLoadParameters<EncoreSettings, EncoreSyncSettings> lp)
{ {
if (lp.Roms.Exists(r => r.RomPath.Contains("|"))) if (lp.Roms.Exists(static r => r.RomPath.ContainsOrdinal('|')))
{ {
throw new InvalidOperationException("3DS does not support compressed ROMs"); throw new InvalidOperationException("3DS does not support compressed ROMs");
} }