5
\$\begingroup\$

In reply to previous question I rewrote ColumnReader and would like more suggestions

using System;

namespace R2D.IO
{
    public sealed class LineReader
    {
        public string NewLine { get; set; }

        string _buffer = "";

        public void Parse(string text)
        {
            _buffer += text;

            var lastline = _buffer.LastIndexOf(NewLine);
            if (lastline == -1)
                return;

            var lines = _buffer.Substring(0, lastline).Split(NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
            _buffer = _buffer.Substring(lastline);

            foreach (var line in lines)
                Receive(line);
        }

        public event Action<string> Receive = (line) => { };
    }

    public sealed class ColumnReader
    {
        public string Delimiter { get; set; }
        public string NewLine
        {
            get { return reader.NewLine; }
            set { reader.NewLine = value; }
        }

        private LineReader reader = new LineReader();

        public ColumnReader()
        {
            reader.Receive += (line) => Receive(line.Split(Delimiter.ToCharArray()));
        }

        public event Action<string[]> Receive = (columns) => { };
    }
}

My main use-case is reading lines from a SerialPort:

var parser = new IO.LineReader { NewLine = port.NewLine };
port.DataReceived += (o, e) => parser.Parse(port.ReadExisting());
parser.Receive += (line) => { };
\$\endgroup\$

2 Answers 2

1
\$\begingroup\$
Split(NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries)

If NewLine is "\r\n", then this will split the input on every \r and every \n. You then take care of the resulting empty strings by specifying RemoveEmptyEntries. But this means that if the input actually contains an empty line, you won't receive it.

To fix that, you can instead use:

Split(new[] { NewLine }, StringSplitOptions.None)
\$\endgroup\$
2
  • \$\begingroup\$ Is that passing an array of strings? \$\endgroup\$
    – fbstj
    Commented Mar 13, 2015 at 8:24
  • \$\begingroup\$ @FallingBullets Yeah, it is. \$\endgroup\$
    – svick
    Commented Mar 13, 2015 at 9:51
1
\$\begingroup\$

You can use the Microsoft.VisualBasic.FileIO.TextFieldParser and attach the serial port to a StreamReader and use that as input for the TextFieldParser.

\$\endgroup\$
1
  • \$\begingroup\$ Indeed TextFeldParser is a more sensible way of doing this for CSV files. I came across it a few weeks ago and then promptly forgot about it and developed this. Thank's for reminding me. I would still like comments on my code though more than a solution to the problem. \$\endgroup\$
    – fbstj
    Commented Feb 26, 2015 at 11:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.