internal DynamicBoundConfiguration(
     char valueSeparator,
     char escapedValueStartAndStop,
     char escapeValueEscapeChar,
     RowEndings rowEndings,
     ReadHeaders readHeader,
     WriteHeaders writeHeaders,
     WriteTrailingNewLines writeTrailingNewLine,
     MemoryPool <char> memoryPool,
     char?commentChar,
     int?writeBufferSizeHint,
     int readBufferSizeHint,
     IDynamicTypeConverter dynamicTypeConverter,
     DynamicRowDisposal dynamicRowDisposal
     ) :
     base(
         valueSeparator,
         escapedValueStartAndStop,
         escapeValueEscapeChar,
         rowEndings,
         readHeader,
         writeHeaders,
         writeTrailingNewLine,
         memoryPool,
         commentChar,
         writeBufferSizeHint,
         readBufferSizeHint,
         dynamicTypeConverter,
         dynamicRowDisposal
         )
 {
 }
Exemple #2
0
 internal ConcreteBoundConfiguration(
     InstanceBuilderDelegate <T> newCons,
     Column[] deserializeColumns,
     Column[] serializeColumns,
     bool[] serializeColumnsNeedEscape,
     char valueSeparator,
     char escapedValueStartAndStop,
     char escapeValueEscapeChar,
     RowEndings rowEndings,
     ReadHeaders readHeader,
     WriteHeaders writeHeaders,
     WriteTrailingNewLines writeTrailingNewLine,
     MemoryPool <char> memoryPool,
     char?commentChar,
     int?writeBufferSizeHint,
     int readBufferSizeHint) : base(
         newCons,
         deserializeColumns,
         serializeColumns,
         serializeColumnsNeedEscape,
         valueSeparator,
         escapedValueStartAndStop,
         escapeValueEscapeChar,
         rowEndings,
         readHeader,
         writeHeaders,
         writeTrailingNewLine,
         memoryPool,
         commentChar,
         writeBufferSizeHint,
         readBufferSizeHint
         )
 {
 }
        internal ReaderStateMachine(
            MemoryPool <char> memoryPool,
            char escapeStartChar,
            char valueSeparatorChar,
            char escapeChar,
            RowEndings rowEndings,
            ReadHeaders hasHeaders,
            char?commentChar
            )
        {
            RowEndings = rowEndings;
            HasHeaders = hasHeaders;

            switch (HasHeaders)
            {
            case ReadHeaders.Always:
                CurrentState = State.Header_Start;
                break;

            case ReadHeaders.Never:
                CurrentState = State.Record_Start;
                break;

            default:
                Throw.InvalidOperationException($"Unexpected {nameof(ReadHeaders)}: {HasHeaders}");
                break;
            }

            TransitionMatrixHandle = GetTransitionMatrix(RowEndings, escapeStartChar == escapeChar).Pin();
            TransitionMatrix       = (TransitionRule *)TransitionMatrixHandle.Pointer;

            SuppressCharLookupDispose = false;
            (MinimumCharacter, CharLookupOffset, CharLookupOwner, CharLookupPin, CharLookup) =
                MakeCharacterLookup(memoryPool, escapeStartChar, valueSeparatorChar, escapeChar, commentChar);
        }
        internal ReaderStateMachine(
            CharacterLookup preAllocLookup,
            char escapeStartChar,
            char escapeChar,
            RowEndings rowEndings,
            ReadHeaders hasHeaders
            )
        {
            RowEndings = rowEndings;
            HasHeaders = hasHeaders;

            switch (HasHeaders)
            {
            case ReadHeaders.Always:
                CurrentState = State.Header_Start;
                break;

            case ReadHeaders.Never:
                CurrentState = State.Record_Start;
                break;

            default:
                Throw.InvalidOperationException($"Unexpected {nameof(ReadHeaders)}: {HasHeaders}");
                break;
            }

            TransitionMatrixHandle = GetTransitionMatrix(RowEndings, escapeStartChar == escapeChar).Pin();
            TransitionMatrix       = (TransitionRule *)TransitionMatrixHandle.Pointer;

            SuppressCharLookupDispose = true;
            (MinimumCharacter, CharLookupOffset, _, _, CharLookup) = preAllocLookup;
        }
        /// <summary>
        /// For working with concrete types.
        /// </summary>
        protected BoundConfigurationBase(
            InstanceBuilderDelegate <T> newCons,
            Column[] deserializeColumns,
            Column[] serializeColumns,
            bool[] serializeColumnsNeedEscape,
            char valueSeparator,
            char escapedValueStartAndStop,
            char escapeValueEscapeChar,
            RowEndings rowEndings,
            ReadHeaders readHeader,
            WriteHeaders writeHeaders,
            WriteTrailingNewLines writeTrailingNewLine,
            MemoryPool <char> memoryPool,
            char?commentChar,
            int?writeBufferSizeHint,
            int readBufferSizeHint
            )
        {
            NewCons                    = newCons;
            DeserializeColumns         = deserializeColumns;
            SerializeColumns           = serializeColumns;
            SerializeColumnsNeedEscape = serializeColumnsNeedEscape;
            ValueSeparator             = valueSeparator;
            ValueSeparatorMemory       = ValueSeparator.ToString().AsMemory();
            EscapedValueStartAndStop   = escapedValueStartAndStop;
            EscapeValueEscapeChar      = escapeValueEscapeChar;
            RowEnding                  = rowEndings;
            WriteBufferSizeHint        = writeBufferSizeHint;
            ReadBufferSizeHint         = readBufferSizeHint;

            switch (RowEnding)
            {
            case RowEndings.CarriageReturn:
                RowEndingMemory = CarriageReturn;
                break;

            case RowEndings.CarriageReturnLineFeed:
                RowEndingMemory = CarriageReturnLineFeed;
                break;

            case RowEndings.LineFeed:
                RowEndingMemory = LineFeed;
                break;

            default:
                // for cases like detecting headers, actually trying to write is NO GOOD...
                //     but construction is fine
                RowEndingMemory = default;
                break;
            }

            ReadHeader           = readHeader;
            WriteHeader          = writeHeaders;
            WriteTrailingNewLine = writeTrailingNewLine;
            MemoryPool           = memoryPool;
            CommentChar          = commentChar;
            DynamicTypeConverter = null;
        }
Exemple #6
0
        /// <summary>
        /// Set the sequence of characters that will end a row.
        /// </summary>
        public OptionsBuilder WithRowEnding(RowEndings l)
        {
            if (!Enum.IsDefined(Types.RowEndingsType, l))
            {
                Throw.ArgumentException($"Unexpected {nameof(RowEndings)} value: {l}", nameof(l));
            }

            return(WithRowEndingInternal(l));
        }
        public void Sync(string csv, RowEndings expected)
        {
            var config = (ConcreteBoundConfiguration <_Test>)Configuration.For <_Test>(Options.Default.NewBuilder().WithReadHeader(ReadHeaders.None).WithRowEnding(RowEndings.Detect).BuildInternal());

            using (var str = new StringReader(csv))
            {
                using (var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar))
                {
                    var detector = new RowEndingDetector <_Test>(config, charLookup, str);
                    var detect   = detector.Detect();
                    Assert.True(detect.HasValue);
                    Assert.Equal(expected, detect.Value.Ending);
                }
            }
        }
        public async Task Async(string csv, RowEndings expected)
        {
            var config = (ConcreteBoundConfiguration <_Test>)Configuration.For <_Test>(Options.Default.NewBuilder().WithReadHeader(ReadHeaders.None).WithRowEnding(RowEndings.Detect).BuildInternal());

            await RunAsyncReaderVariants <_Foo>(
                Options.Default,
                async (_, getReader) =>
            {
                using (var str = getReader(csv))
                {
                    using (var charLookup = ReaderStateMachine.MakeCharacterLookup(config.MemoryPool, config.EscapedValueStartAndStop, config.ValueSeparator, config.EscapeValueEscapeChar, config.CommentChar))
                    {
                        var detector = new RowEndingDetector <_Test>(config, charLookup, str);
                        var detect   = await detector.DetectAsync(CancellationToken.None);
                        Assert.True(detect.HasValue);
                        Assert.Equal(expected, detect.Value.Ending);
                    }
                }
            }
                );
        }
Exemple #9
0
 // sometimes we want to skip validation in tests
 internal OptionsBuilder WithRowEndingInternal(RowEndings l)
 {
     RowEnding = l;
     return(this);
 }
Exemple #10
0
        internal ValueTask <(RowEndings Ending, Memory <char> PushBack)?> DetectAsync(CancellationToken cancel)
        {
            var continueScan = true;

            while (continueScan)
            {
                var mem     = BufferOwner.Memory.Slice(BufferStart, BufferOwner.Memory.Length - BufferStart);
                var endTask = Inner.ReadAsync(mem, cancel);

                int end;
                if (endTask.IsCompletedSuccessfully)
                {
                    end = endTask.Result;
                }
                else
                {
                    return(DetectAsync_ContinueAfterReadAsync(this, endTask, cancel));
                }

                var buffSpan = BufferOwner.Memory.Span;

                if (end == 0)
                {
                    if (BufferStart > 0)
                    {
                        switch (buffSpan[0])
                        {
                        case '\r': Ending = RowEndings.CarriageReturn; break;

                        case '\n': Ending = RowEndings.LineFeed; break;
                        }
                    }
                    break;
                }
                else
                {
                    AddToPushback(buffSpan.Slice(BufferStart, end));

                    var len = end + BufferStart;
                    var res = Advance(buffSpan.Slice(0, len));
                    switch (res)
                    {
                    case AdvanceResult.Continue:
                        BufferStart = 0;
                        continue;

                    case AdvanceResult.Finished:
                        continueScan = false;
                        continue;

                    case AdvanceResult.Continue_PushBackOne:
                        buffSpan[0] = buffSpan[len - 1];
                        BufferStart = 1;
                        continue;

                    default:
                        return(new ValueTask <(RowEndings Ending, Memory <char> PushBack)?>(default((RowEndings Ending, Memory <char> PushBack)?)));
                    }
                }
            }

            // this implies we're only gonna read a row... so whatever
            if (Ending == RowEndings.None)
            {
                Ending = RowEndings.CarriageReturnLineFeed;
            }

            return(new ValueTask <(RowEndings Ending, Memory <char> PushBack)?>((Ending, Pushback.Slice(0, PushbackLength))));