Every Pnyx works on an input, typically from Stream, but can be any thing that implements IProcessor. All input done for a Pnyx is done during the process state (see State Machine for details). Some of the details for reading input are documented below.


Pnyx uses the file's "Byte Order Mark" (BOM) to determine its encoding. If file does not contain BOM, then encoding defaults to Settings.defaultEncoding. Use the Settings, either globally or for specific Pnyx to control how files are decoded. The following example shows reading UTF-8 files.

Specific Encoding
using (Pnyx p = new Pnyx())
        defaultEncoding: Encoding.UTF8, 
        detectEncodingFromByteOrderMarks: false
// Reads a UTF-8 file regardless of BOM (or lack thereof)


When reading from a Stream, newlines can be either in Unix or Windows format, or even mixed together in the same file. Stream parsing uses the first newline character(s) to write to output, in an attempt to maintain the source's original newlines. Finally, parsing keeps track of whether the file is terminated by a newline or not. If so, then the output will also be terminated by a newline.
Newline Parsing
const String input = "1\n2\r\n3\r4";
using (Pnyx p = new Pnyx())
// outputs: 1\n2\n3\n4

Custom Sources

To build a custom source, implement IProcessor and at least one of ILinePart or IRowPart. The process method should read or generate all data in one call. Data is pushed to the next IProcessor as it is available. On every loop, should be checked, to determine if process should finish. Finally, any clean up of resources should be handled by implementing IDisposable. The following example illustrates these points with a custom source to generate Row data.
public class CustomRowSource : IProcessor, IRowPart
    private StreamInformation streamInformation;
    private int countDown;
    private IRowProcessor next;

    public CustomRowSource(StreamInformation streamInformation, int countDown)
        this.streamInformation = streamInformation;
        this.countDown = countDown;

    public void process()
        DateTime date = new DateTime(2013, 4, 2);
        while (countDown >= 0 &&
            String columnA = countDown.ToString();
            String columnB = date.ToString(DateUtil.FORMAT_MDYYYY);
            List<String> row = new List<String> { columnA, columnB };
            date = date.AddDays(-7);
        next.endOfFile();  // flushes buffering and output 

    public void setNextRowProcessor(IRowProcessor next)
    { = next;
using (Pnyx p = new Pnyx())
    p.readLine(new CustomRowSource(p.streamInformation, 40), new CsvRowConverter());
// outputs:
// 40,4/2/2013
// 39,3/26/2013
// 38,3/19/2013


Suggested next steps:
  • Line, learn more about Line operations
  • Row, learn more about Row operations
  • Output, learn more about Output operations
  • Settings, learn more about settings