Advertisement
HAR1F

CSV

Mar 16th, 2019
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.36 KB | None | 0 0
  1. public class CSVConfig
  2.     {
  3.         public char Delimiter { get; }
  4.         public char QuotationMark { get; }
  5.         public string NewLineMark { get; }
  6.  
  7.         public CSVConfig(char delimiter, char quotationMark, string newLineMark)
  8.         {
  9.             this.Delimiter = delimiter;
  10.             this.QuotationMark = quotationMark;
  11.             this.NewLineMark = newLineMark;
  12.         }
  13.  
  14.         public static CSVConfig Default
  15.         {
  16.             get => new CSVConfig(';', '\"', "\r\n");
  17.         }
  18.     }
  19. public class CsvReader
  20.     {
  21.         public CSVConfig CsvConfig { get; }
  22.         public string Path { get; }
  23.  
  24.         public CsvReader(string path, CSVConfig config)
  25.         {
  26.             Path = path;
  27.             CsvConfig = config ?? CSVConfig.Default;
  28.         }
  29.  
  30.         public IEnumerable<string[]> Read()
  31.         {
  32.             var data = File.ReadAllText(Path, Encoding.Default);
  33.             using (StringReader reader = new StringReader(data))
  34.             {
  35.                 while (true)
  36.                 {
  37.                     string line = reader.ReadLine();
  38.                     if (line == null)
  39.                         break;
  40.                     yield return ParseLine(line);
  41.                 }
  42.             }
  43.         }
  44.  
  45.         private string[] ParseLine(string line)
  46.         {
  47.             Stack<string> result = new Stack<string>();
  48.  
  49.             int i = 0;
  50.             while (true)
  51.             {
  52.                 string cell = ParseNextCell(line, ref i);
  53.                 if (cell == null)
  54.                     break;
  55.                 result.Push(cell);
  56.             }
  57.  
  58.             // remove last elements if they're empty
  59.             while (string.IsNullOrEmpty(result.Peek()))
  60.             {
  61.                 result.Pop();
  62.             }
  63.  
  64.             var resultAsArray = result.ToArray();
  65.             Array.Reverse(resultAsArray);
  66.             return resultAsArray;
  67.         }
  68.  
  69.         // returns iterator after delimiter or after end of string
  70.         private string ParseNextCell(string line, ref int i)
  71.         {
  72.             if (i >= line.Length)
  73.                 return null;
  74.  
  75.             if (line[i] != CsvConfig.QuotationMark)
  76.                 return ParseNotEscapedCell(line, ref i);
  77.             else
  78.                 return ParseEscapedCell(line, ref i);
  79.         }
  80.  
  81.         // returns iterator after delimiter or after end of string
  82.         private string ParseNotEscapedCell(string line, ref int i)
  83.         {
  84.             StringBuilder sb = new StringBuilder();
  85.             while (true)
  86.             {
  87.                 if (i >= line.Length) // return iterator after end of string
  88.                     break;
  89.                 if (line[i] == CsvConfig.Delimiter)
  90.                 {
  91.                     i++; // return iterator after delimiter
  92.                     break;
  93.                 }
  94.                 sb.Append(line[i]);
  95.                 i++;
  96.             }
  97.             return sb.ToString();
  98.         }
  99.  
  100.         // returns iterator after delimiter or after end of string
  101.         private string ParseEscapedCell(string line, ref int i)
  102.         {
  103.             i++; // omit first character (quotation mark)
  104.             StringBuilder sb = new StringBuilder();
  105.             while (true)
  106.             {
  107.                 if (i >= line.Length)
  108.                     break;
  109.                 if (line[i] == CsvConfig.QuotationMark)
  110.                 {
  111.                     i++; // we're more interested in the next character
  112.                     if (i >= line.Length)
  113.                     {
  114.                         // quotation mark was closing cell;
  115.                         // return iterator after end of string
  116.                         break;
  117.                     }
  118.                     if (line[i] == CsvConfig.Delimiter)
  119.                     {
  120.                         // quotation mark was closing cell;
  121.                         // return iterator after delimiter
  122.                         i++;
  123.                         break;
  124.                     }
  125.                     if (line[i] == CsvConfig.QuotationMark)
  126.                     {
  127.                         // it was doubled (escaped) quotation mark;
  128.                         // do nothing -- we've already skipped first quotation mark
  129.                     }
  130.  
  131.                 }
  132.                 sb.Append(line[i]);
  133.                 i++;
  134.             }
  135.  
  136.             return sb.ToString();
  137.         }
  138.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement