GParse/source/GParse/QuoteAwareParser.cs
2025-03-21 00:43:08 -06:00

53 lines
1.4 KiB
C#

namespace GParse;
public class QuoteAwareParser(string delimiter, string openQuote, string closeQuote) : ITextParser
{
public IEnumerable<string> Parse(ITextInputProvider textInputProvider) => Parse(textInputProvider.GetText());
public IEnumerable<string> Parse(string text)
{
if (delimiter == openQuote || delimiter == closeQuote)
throw new ArgumentException("Delimiter cannot be the same as the quotes.");
int size = text.Length;
int delimiterSize = delimiter.Length;
int openQuoteSize = openQuote.Length;
int closeQuoteSize = closeQuote.Length;
int index = 0;
bool inQuote = false;
int tokenStartIndex = 0;
while (index <= size - 1)
{
if (!inQuote && (text.SafeSubstring(index, openQuoteSize) == openQuote))
{
// Enter quotes.
inQuote = true;
index += openQuoteSize - 1;
}
else if (inQuote && (text.SafeSubstring(index, closeQuoteSize) == closeQuote))
{
inQuote = false;
index += closeQuoteSize - 1;
}
else if (!inQuote && (text.SafeSubstring(index, delimiterSize) == delimiter))
{
string token = text.SafeSubstring(tokenStartIndex, index - tokenStartIndex);
yield return token;
tokenStartIndex = index + delimiterSize;
index += delimiterSize - 1;
}
index++;
}
if (inQuote)
throw new ParseException("Unterminated quotation in input string.");
string lastToken = text.SafeSubstring(tokenStartIndex, index - tokenStartIndex);
yield return lastToken;
}
}