diff --git a/RecordParser/Engines/Reader/TextFindHelper.cs b/RecordParser/Engines/Reader/TextFindHelper.cs index 1927b86..2cd052e 100644 --- a/RecordParser/Engines/Reader/TextFindHelper.cs +++ b/RecordParser/Engines/Reader/TextFindHelper.cs @@ -6,26 +6,45 @@ namespace RecordParser.Engines.Reader internal ref struct TextFindHelper { private readonly ReadOnlySpan line; + private ReadOnlySpan currentValue; + private TextFindHelperCore core; + + public TextFindHelper(ReadOnlySpan source, string delimiter, (char ch, string str) quote) + { + line = source; + currentValue = default; + core = new TextFindHelperCore(delimiter, quote); + } + + public ReadOnlySpan GetValue(int index) + { + currentValue = core.GetValue(index, currentValue, line); + + return currentValue; + } + + public void Dispose() => core.Dispose(); + } + + internal struct TextFindHelperCore + { private readonly string delimiter; private readonly (char ch, string str) quote; private int scanned; private int position; private int currentIndex; - private ReadOnlySpan currentValue; private char[] buffer; - public TextFindHelper(ReadOnlySpan source, string delimiter, (char ch, string str) quote) + public TextFindHelperCore(string delimiter, (char ch, string str) quote) { - this.line = source; this.delimiter = delimiter; this.quote = quote; scanned = -delimiter.Length; position = 0; currentIndex = -1; - currentValue = default; buffer = null; } @@ -38,7 +57,7 @@ public void Dispose() } } - public ReadOnlySpan GetValue(int index) + public ReadOnlySpan GetValue(int index, ReadOnlySpan currentValue, ReadOnlySpan line) { if (index <= currentIndex) { @@ -51,7 +70,7 @@ public ReadOnlySpan GetValue(int index) while (currentIndex <= index) { var match = index == ++currentIndex; - currentValue = ParseChunk(match); + currentValue = ParseChunk(match, line); if (match) { @@ -62,7 +81,7 @@ public ReadOnlySpan GetValue(int index) throw new Exception("invalid index for line"); } - private ReadOnlySpan ParseChunk(bool match) + private ReadOnlySpan ParseChunk(bool match, ReadOnlySpan line) { scanned += position + delimiter.Length; @@ -71,7 +90,7 @@ private ReadOnlySpan ParseChunk(bool match) if (isQuotedField) { - return ParseQuotedChuck(match); + return ParseQuotedChuck(match, line); } position = unlook.IndexOf(delimiter); @@ -83,7 +102,7 @@ private ReadOnlySpan ParseChunk(bool match) return line.Slice(scanned, position); } - private ReadOnlySpan ParseQuotedChuck(bool match) + private ReadOnlySpan ParseQuotedChuck(bool match, ReadOnlySpan line) { const string corruptFieldError = "Double quote is not escaped or there is extra data after a quoted field.";