using System; using System.Collections.Generic; using System.Text; namespace NHSE.Core; /// /// Processes input of strings into a list of valid Filters and Instructions. /// public sealed class StringInstructionSet { /// /// Filters to check if the object should be modified. /// public readonly IReadOnlyList Filters; /// /// Instructions to modify the object. /// public readonly IReadOnlyList Instructions; private const char SetSeparatorChar = ';'; public StringInstructionSet(IReadOnlyList filters, IReadOnlyList instructions) { Filters = filters; Instructions = instructions; } public StringInstructionSet(ReadOnlySpan text) { var set = text.EnumerateLines(); Filters = StringInstruction.GetFilters(set); Instructions = StringInstruction.GetInstructions(set); } public StringInstructionSet(SpanLineEnumerator set) { Filters = StringInstruction.GetFilters(set); Instructions = StringInstruction.GetInstructions(set); } public StringInstructionSet(ReadOnlySpan set) { Filters = StringInstruction.GetFilters(set); Instructions = StringInstruction.GetInstructions(set); } /// /// Gets a list of s from the input . /// public static StringInstructionSet[] GetBatchSets(ReadOnlySpan lines) { int ctr = 0; int start = 0; while (start < lines.Length) { var slice = lines[start..]; var count = GetInstructionSetLength(slice); ctr++; start += count + 1; } var result = new StringInstructionSet[ctr]; ctr = 0; start = 0; while (start < lines.Length) { var slice = lines[start..]; var count = GetInstructionSetLength(slice); var set = slice[..count]; result[ctr++] = new StringInstructionSet(set); start += count + 1; } return result; } /// /// Gets a list of s from the input . /// public static StringInstructionSet[] GetBatchSets(ReadOnlySpan text) { int ctr = 0; int start = 0; while (start < text.Length) { var slice = text[start..]; var count = GetInstructionSetLength(slice); ctr++; start += count + 1; } var result = new StringInstructionSet[ctr]; ctr = 0; start = 0; while (start < text.Length) { var slice = text[start..]; var count = GetInstructionSetLength(slice); var set = slice[..count]; result[ctr++] = new StringInstructionSet(set); start += count + 1; } return result; } /// /// Scans through the to count the amount of characters to consume. /// /// Multi line string /// Amount of characters comprising a set of instructions public static int GetInstructionSetLength(ReadOnlySpan text) { int start = 0; while (start < text.Length) { var line = text[start..]; if (line.Length != 0 && line[0] == SetSeparatorChar) return start; var next = line.IndexOf('\n'); if (next == -1) return text.Length; start += next + 1; } return start; } /// /// Scans through the to count the amount of valid lines to consume. /// /// Amount of lines comprising a set of instructions. public static int GetInstructionSetLength(ReadOnlySpan lines) { int start = 0; while (start < lines.Length) { var line = lines[start++]; if (line.StartsWith(SetSeparatorChar)) return start; } return start; } }