Ejemplo n.º 1
0
        private void TrimEnd(ValueBuilder value, char[] buffer, int start, int end)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }
            if (start < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(start));
            }
            if (end >= buffer.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(end));
            }

            for (int i = end; i >= start; i--)
            {
                if (!IsWhiteSpace(buffer[i]))
                {
                    value.Append(buffer, start, i - start + 1);
                    return;
                }
            }

            _valueBuilder.TrimEnd(IsWhiteSpace);
        }
Ejemplo n.º 2
0
        private string ParseField(Buffer <char> buffer, bool keepValue, out bool endsWithDelimiter, out bool parsingErrorOccurred)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            _valueBuilder.Clear();

            endsWithDelimiter    = false;
            parsingErrorOccurred = false;

            if (this.TrimWhiteSpaces)
            {
                if (!SkipWhiteSpaces(buffer))
                {
                    return(string.Empty);
                }
            }

            if (buffer.Current == this.QuoteCharacter)
            {
                #region Quoted field

                // skip initial quote
                buffer.Position++;

                bool quoted = true;

                for (;;)
                {
                    int start = buffer.Position;

                    while (buffer.Position < buffer.Length)
                    {
                        char c = buffer.Current;

                        if (c == this.QuoteCharacter)
                        {
                            // if next char is a quote, then the quote is escaped
                            if (this.DoubleQuoteEscapingEnabled &&
                                (
                                    (buffer.Position + 1 < buffer.Length && buffer.RawData[buffer.Position + 1] == this.QuoteCharacter) ||
                                    (buffer.Position + 1 == buffer.Length && this.BaseReader.Peek() == (int)this.QuoteCharacter)))
                            {
                                if (keepValue)
                                {
                                    _valueBuilder.Append(buffer.RawData, start, buffer.Position - start + 1);
                                }

                                if (buffer.Position + 1 == buffer.Length)
                                {
                                    buffer.Fill();
                                    buffer.Position++;
                                }
                                else
                                {
                                    buffer.Position += 2;
                                    buffer.EnsureHasData();
                                }

                                start = buffer.Position;
                            }
                            else
                            {
                                quoted = false;
                                break;
                            }
                        }
                        else if (keepValue && this.AdvancedEscapingEnabled && c == EscapedStringParser.EscapeCharacter)
                        {
                            char escapedValue;
                            int  currentValueLength = buffer.Position - start;

                            if (EscapedStringParser.TryParseEscapedChar(buffer, out escapedValue))
                            {
                                _valueBuilder.Append(buffer.RawData, start, currentValueLength);
                                _valueBuilder.Append(escapedValue);

                                start = buffer.Position;
                            }
                            else
                            {
                                buffer.Position++;
                            }
                        }
                        else
                        {
                            buffer.Position++;
                        }
                    }

                    if (keepValue && buffer.Position > start)
                    {
                        _valueBuilder.Append(buffer.RawData, start, buffer.Position - start);
                    }

                    if (!quoted)
                    {
                        break;
                    }
                    else
                    {
                        // still expecting a quote, try to get more data
                        if (!buffer.Fill())
                        {
                            parsingErrorOccurred = true;
                            return(_valueBuilder.ToString());
                        }
                    }
                }

                // skip final quote
                buffer.Position++;

                if (this.TrimWhiteSpaces)
                {
                    SkipWhiteSpaces(buffer);
                }

                // skip delimiter if present
                if (buffer.EnsureHasData())
                {
                    if (buffer.Current == this.DelimiterCharacter)
                    {
                        buffer.Position++;
                        endsWithDelimiter = true;
                    }
                    else if (!base.IsNewLine(buffer.Current))
                    {
                        parsingErrorOccurred = true;
                        return(_valueBuilder.ToString());
                    }
                }

                #endregion
            }
            else
            {
                #region Unquoted field

                int start = buffer.Position;

                for (;;)
                {
                    char c = buffer.Current;

                    if (c == this.DelimiterCharacter || base.IsNewLine(c))
                    {
                        if (keepValue)
                        {
                            if (this.TrimWhiteSpaces)
                            {
                                TrimEnd(_valueBuilder, buffer.RawData, start, buffer.Position - 1);
                            }
                            else
                            {
                                _valueBuilder.Append(buffer.RawData, start, buffer.Position - start);
                            }
                        }

                        // only skip delimiter, new line will be parsed by main loop
                        if (c == this.DelimiterCharacter)
                        {
                            buffer.Position++;
                            endsWithDelimiter = true;
                        }

                        break;
                    }
                    else if (keepValue && this.AdvancedEscapingEnabled && c == EscapedStringParser.EscapeCharacter)
                    {
                        char escapedValue;
                        int  currentValueLength = buffer.Position - start;

                        if (EscapedStringParser.TryParseEscapedChar(buffer, out escapedValue))
                        {
                            _valueBuilder.Append(buffer.RawData, start, currentValueLength);
                            _valueBuilder.Append(escapedValue);

                            start = buffer.Position;
                        }
                        else
                        {
                            buffer.Position++;
                        }
                    }
                    else
                    {
                        buffer.Position++;
                    }

                    if (buffer.Position >= buffer.Length)
                    {
                        // if start = 0, the field length is bigger than the buffer length
                        // so concatenate the buffer content and flush it
                        if (start == 0)
                        {
                            if (keepValue)
                            {
                                _valueBuilder.Append(buffer.RawData, 0, buffer.Position);
                            }

                            start = buffer.Length;
                        }

                        if (!buffer.Fill(buffer.Length - start))
                        {
                            // concatenate remaining buffer content
                            if (keepValue && buffer.Length > 0)
                            {
                                if (this.TrimWhiteSpaces)
                                {
                                    TrimEnd(_valueBuilder, buffer.RawData, 0, buffer.Position - 1);
                                }
                                else
                                {
                                    _valueBuilder.Append(buffer.RawData, 0, buffer.Position);
                                }
                            }

                            buffer.Position = buffer.Length;

                            break;
                        }

                        start = 0;
                    }
                }

                #endregion
            }

            return(_valueBuilder.ToString());
        }