private void PushEscapedQualifier(FakeStack stack) { stack.Push(_escapedQualifier); }
/// <summary> /// Reads one row in the stream. Does not care whether there are carriage returns or not. /// </summary> /// <returns></returns> private string[] ReadRow() { if (PeekChar() < 0) { return(null); } List <string> columns = null; var stack = new FakeStack(); char c = '\0'; bool qualifierStart = false; bool qualifierEnd = false; bool newCell = true; // common operations anonymous helper method // for a better readability of the algorithm // Line parsing while (PeekChar() >= 0) { c = (char)ReadChar(); if (newCell) { // starting new cell newCell = false; if (IsNewLine(c)) { // empty row stack.Push(string.Empty); break; } else if (IsCarriageReturn(c)) { // empty row if (PeekNewLine()) { //discard ReadChar(); } stack.Push(string.Empty); break; } else if (IsQualifier(c)) { // text qualified cell qualifierStart = true; } else if (!IsSeparator(c)) { // first character stack.Push(c); } else { // empty cell AddCell(stack, ref columns, ref newCell, ref qualifierStart, ref qualifierEnd); } } // Text qualifier else if (IsQualifier(c)) { // process text qualifier if (PeekQualifier(stack) && IsQualifierStarted(qualifierStart, qualifierEnd)) { // needs escaping // escaped quotes will be resolved when the cell is assembled stack.Pop(); PushEscapedQualifier(stack); } else { // add qualifier on the stack stack.Push(c); } } // Other characters else { // process regular characters if (PeekQualifier(stack) && IsQualifierStarted(qualifierStart, qualifierEnd)) { // last qualifier is the closing qualifier stack.Pop(); stack.Push(string.Empty); qualifierEnd = true; } // old mac or windows EOL if (IsCarriageReturn(c) && !IsQualifierStarted(qualifierStart, qualifierEnd)) { if (PeekNewLine()) { //discard ReadChar(); } break; } // unix EOL else if (IsNewLine(c) && !IsQualifierStarted(qualifierStart, qualifierEnd)) { // end of row break; } else if (IsSeparator(c) && !IsQualifierStarted(qualifierStart, qualifierEnd)) { // end of cell AddCell(stack, ref columns, ref newCell, ref qualifierStart, ref qualifierEnd); } else { // add character on the stack stack.Push(c); } } } // left over cell if (stack.Count > 0 || IsSeparator(c)) { // last cell AddCell(stack, ref columns, ref newCell, ref qualifierStart, ref qualifierEnd); } string[] arr = null; if (columns.Count > 0) { arr = new string[columns.Count]; columns.CopyTo(arr); } return(arr); //return columns == null ? null : columns.ToArray(); }