using System; using System.IO; using System.Runtime.CompilerServices; using System.Text; namespace NHSE.Core; /// /// Logic for manipulating strings /// public static class StringUtil { /// /// Trims a string at the first instance of a 0x0000 terminator. /// /// String to trim. /// Trimmed string. public static string TrimFromZero(string input) => TrimFromFirst(input, '\0'); [MethodImpl(MethodImplOptions.AggressiveInlining)] private static string TrimFromFirst(string input, char c) { int index = input.IndexOf(c); return index < 0 ? input : input[..index]; } public static string GetString(ReadOnlySpan data, int offset, int maxLength) { var slice = data.Slice(offset, maxLength * 2); var str = Encoding.Unicode.GetString(slice); return TrimFromZero(str); } public static byte[] GetBytes(string value, int maxLength) { if (value.Length > maxLength) value = value[..maxLength]; else if (value.Length < maxLength) value = value.PadRight(maxLength, '\0'); return Encoding.Unicode.GetBytes(value); } public static string CleanFileName(string fileName) { return string.Concat(fileName.Split(Path.GetInvalidFileNameChars())); } /// /// Parses the hex string into a , skipping all characters except for valid digits. /// /// Hex String to parse /// Parsed value public static uint GetHexValue(ReadOnlySpan value) { uint result = 0; if (value.Length == 0) return result; foreach (var c in value) { if (char.IsAsciiDigit(c)) { result <<= 4; result |= (uint)(c - '0'); } else if (char.IsAsciiHexDigitUpper(c)) { result <<= 4; result |= (uint)(c - 'A' + 10); } else if (char.IsAsciiHexDigitLower(c)) { result <<= 4; result |= (uint)(c - 'a' + 10); } } return result; } }