internal IEnumerable<CsvLexeme> Scan(TextReader reader) { ValidateSettings(); char rowSeparatorFirstChar = Settings.RowDelimiter.First(); char? rowSeparatorSecondChar = Settings.RowDelimiter.Length > 1 ? Settings.RowDelimiter.Skip(1).FirstOrDefault() : (char?)null; int current; StringBuilder currentLexemeValue = new StringBuilder(50); while ((current = reader.Read()) != -1) { CsvLexeme specialSyntaxItem = new CsvLexeme(); if (current == Settings.FieldDelimiter) { specialSyntaxItem = this.FieldDelimiter; } else if (current == Settings.QuotingCharacter) { specialSyntaxItem = this.Quote; } else if (current == rowSeparatorFirstChar) { if (rowSeparatorSecondChar == null) // single char line separator { specialSyntaxItem = this.LineSeparator; } else if (reader.Peek() == rowSeparatorSecondChar) // double char line separator { reader.Read();//just consume, since matching with rowSeparatorSecondChar is verified specialSyntaxItem = this.LineSeparator; } } if (specialSyntaxItem.Type != CsvSyntaxItem.NotSet) { //finish ongoing lexeme if present: if (currentLexemeValue.Length > 0) { yield return new CsvLexeme(CsvSyntaxItem.Text, currentLexemeValue.ToString()); currentLexemeValue.Length = 0; } // yield current lexeme: yield return specialSyntaxItem; } else { currentLexemeValue.Append((char)current); } } if (currentLexemeValue.Length > 0) { yield return new CsvLexeme(CsvSyntaxItem.Text, currentLexemeValue.ToString()); } yield return new CsvLexeme(CsvSyntaxItem.EndOfFile, null); }
internal IEnumerable<CsvLexeme> Scan(TextReader reader) { ValidateSettings(); char rowSeparatorFirstChar = Settings.RowDelimiter.First(); char? rowSeparatorSecondChar = Settings.RowDelimiter.Skip(1).FirstOrDefault(); int current; StringBuilder currentLexemeValue = new StringBuilder(50); while ((current = reader.Read()) != -1) { CsvLexeme specialSyntaxItem = new CsvLexeme(); if (current == Settings.FieldDelimiter) { specialSyntaxItem = this.FieldDelimiter; } else if (current == Settings.QuotingCharacter) { specialSyntaxItem = this.Quote; } else if (current == rowSeparatorFirstChar && rowSeparatorSecondChar != null && reader.Peek() == rowSeparatorSecondChar && reader.Read() > 0) //just read, always succeeds since rowSeparatorSecondChar >=0 { specialSyntaxItem = this.LineSeparator; } if (specialSyntaxItem.Type != CsvSyntaxItem.NotSet) { //finish ongoing lexeme if present: if (currentLexemeValue.Length > 0) { yield return new CsvLexeme(CsvSyntaxItem.Text, currentLexemeValue.ToString()); currentLexemeValue.Length = 0; } // yield current lexeme: yield return specialSyntaxItem; } else { currentLexemeValue.Append((char)current); } } if (currentLexemeValue.Length > 0) { yield return new CsvLexeme(CsvSyntaxItem.Text, currentLexemeValue.ToString()); } yield return new CsvLexeme(CsvSyntaxItem.EndOfFile, null); }