예제 #1
0
        private void AddCell(FakeStack stack, ref List <string> columns, ref bool newCell, ref bool qualifierStart, ref bool qualifierEnd)
        {
            var parts = new List <string>();

            while (stack.Count > 0)
            {
                string txt = stack.Pop();
                if (txt != null)
                {
                    if (_enableQualification)
                    {
                        if (txt.Length == 2 && txt[0].Equals(Settings.TextQualifier) && txt[1].Equals(Settings.TextQualifier))
                        {
                            txt = _qualiferString;
                            parts.Add(txt);
                        }
                        else if (txt.Length != 1 || !txt[0].Equals(Settings.TextQualifier) || IsQualifierStarted(qualifierStart, qualifierEnd))
                        {
                            parts.Add(txt);
                        }
                    }
                    else
                    {
                        parts.Add(txt);
                    }
                }
            }

            if (columns == null)
            {
                columns = new List <string>();
            }

            string val = string.Empty;

            if (parts.Count > 2)
            {
                var sbuf = new StringBuilder();
                for (int i = parts.Count - 1; i >= 0; --i)
                {
                    sbuf.Append(parts[i]);
                }
                val = sbuf.ToString();
            }
            else
            {
                val = string.Concat(parts.Reverse <string>());
            }

            if (val.Equals(Settings.NullValue) && !IsQualifierEnded(qualifierStart, qualifierEnd))
            {
                val = null;
            }

            columns.Add(val);
            newCell      = true;
            qualifierEnd = qualifierStart = false;
        }
예제 #2
0
 private bool PeekQualifier(FakeStack stack)
 {
     return(stack.Count > 0 && _enableQualification && stack.Peek(Settings.TextQualifier));
 }
예제 #3
0
 private void PushEscapedQualifier(FakeStack stack)
 {
     stack.Push(_escapedQualifier);
 }
예제 #4
0
        /// <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();
        }