private bool Read()
        {
            if (!_isHeaderReaded)
            {
                ReadHeaderRow();
                _isHeaderReaded = true;
            }
            if (Reader.EndOfStream)
            {
                return(false);
            }
            var fields = ReadRow();

            if (fields.Length != _headers.Count)
            {
                throw new CsvReadingException("Invalid row. Fields are not accepts to headers");
            }
            CurrentRecord = new CsvRecord();
            for (var i = 0; i < _headers.Count; i++)
            {
                CurrentRecord.Add(_headers.ElementAt(i), fields[i]);
            }
            return(true);
        }
Exemple #2
0
    /// <summary>
    /// Parses the line into a list of strings.
    /// </summary>
    /// <param name="line">The line.</param>
    /// <returns></returns>
    public static CsvRecord ParseLine(string line)
    {
        var             values       = new CsvRecord();
        var             currentValue = new StringBuilder(1024);
        char            currentChar;
        Nullable <char> nextChar     = null;
        var             currentState = ReadState.WaitingForNewField;

        for (var charIndex = 0; charIndex < line.Length; charIndex++)
        {
            // Get the current and next character
            currentChar = line[charIndex];
            nextChar    = charIndex < line.Length - 1 ? line[charIndex + 1] : new Nullable <char>();

            // Perform logic based on state and decide on next state
            switch (currentState)
            {
            case ReadState.WaitingForNewField:
            {
                currentValue.Clear();
                if (currentChar == DoubleQuote)
                {
                    currentState = ReadState.PushingQuoted;
                    continue;
                }
                else if (currentChar == Comma)
                {
                    values.Add(currentValue.ToString());
                    currentState = ReadState.WaitingForNewField;
                    continue;
                }
                else
                {
                    currentValue.Append(currentChar);
                    currentState = ReadState.PushingNormal;
                    continue;
                }
            }

            case ReadState.PushingNormal:
            {
                // Handle field content delimiter by comma
                if (currentChar == Comma)
                {
                    currentState = ReadState.WaitingForNewField;
                    values.Add(currentValue.ToString().Trim());
                    currentValue.Clear();
                    continue;
                }

                // Handle double quote escaping
                if (currentChar == DoubleQuote && nextChar == DoubleQuote)
                {
                    // advance 1 character now. The loop will advance one more.
                    currentValue.Append(currentChar);
                    charIndex++;
                    continue;
                }

                currentValue.Append(currentChar);
                break;
            }

            case ReadState.PushingQuoted:
            {
                // Handle field content delimiter by ending double quotes
                if (currentChar == DoubleQuote && nextChar != DoubleQuote)
                {
                    currentState = ReadState.PushingNormal;
                    continue;
                }

                // Handle double quote escaping
                if (currentChar == DoubleQuote && nextChar == DoubleQuote)
                {
                    // advance 1 character now. The loop will advance one more.
                    currentValue.Append(currentChar);
                    charIndex++;
                    continue;
                }

                currentValue.Append(currentChar);
                break;
            }
            }
        }

        // push anything that has not been pushed (flush)
        values.Add(currentValue.ToString().Trim());
        return(values);
    }
Exemple #3
0
        public static CsvRecord[] GetRecords(string content, string delimiter)
        {
            List <CsvRecord> records = new List <CsvRecord>();

            //List<string> fields = new List<string>();
            content = content + "\n";
            var charArray = content.ToArray();

            //the following variables are used in the for loop.
            var currentField         = string.Empty;
            var concatenating        = true; //meaning we are concatenating a field. or to say, we find the start but we are not at the end of a field yet.
            var startWithDoubleQuote = false;
            var startRecord          = true;
            var currentRecord        = new CsvRecord();

            records.Add(currentRecord);
            for (int i = 0; i < charArray.Length; i++)
            {
                var currentChar = charArray[i];
                var nextChar    = i + 1 < charArray.Length? charArray[i + 1] : '\0';

                if (startRecord)
                {
                    switch (currentChar)
                    {
                    case '\r':
                        continue;

                    case '\n':
                        continue;

                    case ',':
                        currentRecord.Add(string.Empty);
                        concatenating = false;
                        break;

                    case '"':
                        startWithDoubleQuote = true;
                        concatenating        = true;
                        break;

                    default:
                        currentField        += currentChar;
                        startWithDoubleQuote = false;
                        concatenating        = true;
                        break;
                    }
                    startRecord = false;
                }
                else if (concatenating)
                {
                    if (startWithDoubleQuote)
                    {
                        if (currentChar == '"')
                        {
                            //if this is the last char
                            if (i + 1 == charArray.Length)
                            {
                                currentField += currentChar;
                                AddField(currentRecord, ref currentField, ref concatenating);

                                continue;
                            }

                            if (nextChar == '"')
                            {
                                currentField += currentChar;
                                i++;
                            }
                            else //nextChar != '"'
                            {
                                AddField(currentRecord, ref currentField, ref concatenating);
                                if (nextChar == ',')
                                {
                                    i++;
                                }
                            }
                        }
                        else // currentChar!='"'
                        {
                            if (i + 1 == charArray.Length)
                            {
                                throw new CsvFormatException();
                            }
                            currentField += currentChar;
                        }
                    }
                    else //not startWithDoubleQuote
                    {
                        //if this is the last char
                        if (i + 1 == charArray.Length)
                        {
                            currentField += currentChar;
                            currentField  = currentField.Trim();
                            currentRecord.Add(currentField);
                            continue;
                        }

                        switch (currentChar)
                        {
                        case '\r':
                        case '\n':
                            currentRecord.Add(currentField);
                            currentRecord = new CsvRecord();
                            currentField  = string.Empty;
                            records.Add(currentRecord);
                            startRecord = true;
                            continue;

                        case ',':
                            AddField(currentRecord, ref currentField, ref concatenating);
                            break;

                        default:
                            currentField += currentChar;
                            break;
                        }
                    }
                }
                else // not concatenating
                {
                    switch (currentChar)
                    {
                    case '\r':
                    case '\n':
                        var previousChar = i > 0? charArray[i - 1]:'\0';
                        if (previousChar == ',')
                        {
                            currentRecord.Add(string.Empty);
                            currentRecord = new CsvRecord();
                            records.Add(currentRecord);
                            startRecord = true;
                        }
                        else
                        {
                            currentRecord = new CsvRecord();
                            records.Add(currentRecord);
                            startRecord = true;
                        }

                        continue;

                    case ',':
                        currentRecord.Add(string.Empty);
                        break;

                    case '"':
                        startWithDoubleQuote = true;
                        concatenating        = true;
                        break;

                    default:
                        startWithDoubleQuote = false;
                        concatenating        = true;
                        currentField        += currentChar;
                        break;
                    }
                }
            }

            //checked if the last record is empty
            var last    = records.Last();
            var isEmpty = false;

            if (last.Count == 0)
            {
                isEmpty = true;
            }
            else
            {
                foreach (string s in last)
                {
                    if (string.IsNullOrEmpty(s))
                    {
                        isEmpty = true;
                        break;
                    }
                }
            }


            if (isEmpty)
            {
                records.Remove(last);
            }

            return(records.ToArray());
        }
Exemple #4
0
 private static void AddField(CsvRecord currentRecord, ref string currentField, ref bool concatenating)
 {
     currentRecord.Add(currentField.Trim());
     currentField  = string.Empty;
     concatenating = false;
 }