Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class CSVConfig
- {
- public char Delimiter { get; }
- public char QuotationMark { get; }
- public string NewLineMark { get; }
- public CSVConfig(char delimiter, char quotationMark, string newLineMark)
- {
- this.Delimiter = delimiter;
- this.QuotationMark = quotationMark;
- this.NewLineMark = newLineMark;
- }
- public static CSVConfig Default
- {
- get => new CSVConfig(';', '\"', "\r\n");
- }
- }
- public class CsvReader
- {
- public CSVConfig CsvConfig { get; }
- public string Path { get; }
- public CsvReader(string path, CSVConfig config)
- {
- Path = path;
- CsvConfig = config ?? CSVConfig.Default;
- }
- public IEnumerable<string[]> Read()
- {
- var data = File.ReadAllText(Path, Encoding.Default);
- using (StringReader reader = new StringReader(data))
- {
- while (true)
- {
- string line = reader.ReadLine();
- if (line == null)
- break;
- yield return ParseLine(line);
- }
- }
- }
- private string[] ParseLine(string line)
- {
- Stack<string> result = new Stack<string>();
- int i = 0;
- while (true)
- {
- string cell = ParseNextCell(line, ref i);
- if (cell == null)
- break;
- result.Push(cell);
- }
- // remove last elements if they're empty
- while (string.IsNullOrEmpty(result.Peek()))
- {
- result.Pop();
- }
- var resultAsArray = result.ToArray();
- Array.Reverse(resultAsArray);
- return resultAsArray;
- }
- // returns iterator after delimiter or after end of string
- private string ParseNextCell(string line, ref int i)
- {
- if (i >= line.Length)
- return null;
- if (line[i] != CsvConfig.QuotationMark)
- return ParseNotEscapedCell(line, ref i);
- else
- return ParseEscapedCell(line, ref i);
- }
- // returns iterator after delimiter or after end of string
- private string ParseNotEscapedCell(string line, ref int i)
- {
- StringBuilder sb = new StringBuilder();
- while (true)
- {
- if (i >= line.Length) // return iterator after end of string
- break;
- if (line[i] == CsvConfig.Delimiter)
- {
- i++; // return iterator after delimiter
- break;
- }
- sb.Append(line[i]);
- i++;
- }
- return sb.ToString();
- }
- // returns iterator after delimiter or after end of string
- private string ParseEscapedCell(string line, ref int i)
- {
- i++; // omit first character (quotation mark)
- StringBuilder sb = new StringBuilder();
- while (true)
- {
- if (i >= line.Length)
- break;
- if (line[i] == CsvConfig.QuotationMark)
- {
- i++; // we're more interested in the next character
- if (i >= line.Length)
- {
- // quotation mark was closing cell;
- // return iterator after end of string
- break;
- }
- if (line[i] == CsvConfig.Delimiter)
- {
- // quotation mark was closing cell;
- // return iterator after delimiter
- i++;
- break;
- }
- if (line[i] == CsvConfig.QuotationMark)
- {
- // it was doubled (escaped) quotation mark;
- // do nothing -- we've already skipped first quotation mark
- }
- }
- sb.Append(line[i]);
- i++;
- }
- return sb.ToString();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement