public static Tuple <DataStreamHeader, string> Factory(InputByteArray InputArray) { DataStreamHeader dsh = null; string errmsg = null; int rcdLgth = 0; byte[] buf = null; DataStreamCode dataStreamCode = DataStreamCode.Terminal; if (InputArray.RemainingLength < 10) { errmsg = "Not enough bytes for data stream header"; } if (errmsg == null) { buf = InputArray.PeekBytesLenient(20); // the first 6 bytes are logical record length, 2 byte marker and 2 bytes // DataStreamCode. rcdLgth = buf.BigEndianBytesToShort(0); var rcdType = buf.SubArray(2, 2); if ((rcdType[0] != 0x12) || (rcdType[1] != 0xa0)) { errmsg = "Invalid record type"; } else if (rcdLgth < 10) { errmsg = "Invalid record length"; } } // isolate the data stream code. if (errmsg == null) { var nullableCode = buf.SubArray(4, 2).ToDataStreamCode(); if (nullableCode == null) { errmsg = "not valid data stream code"; } else { dataStreamCode = nullableCode.Value; } } if (errmsg == null) { if (dataStreamCode == DataStreamCode.Terminal) { dsh = new TerminalDataStreamHeader(InputArray); } else if (dataStreamCode == DataStreamCode.PrinterStartup) { dsh = new PrinterStartupDataStreamHeader(InputArray); } else if (dataStreamCode == DataStreamCode.PrinterPrint) { var payloadBx = InputArray.PeekDataStreamHeaderLength(); var payloadBuf = InputArray.PeekBytesLenient(payloadBx, 3); if (payloadBuf.CompareEqual(StartPrinterFileMarkerBytes) == true) { dsh = new StartPrinterFileDataStreamHeader(InputArray); } else { dsh = new PrinterDataStreamHeader(InputArray, "Printer"); } } else if (dataStreamCode == DataStreamCode.PrinterResponse) { dsh = new PrinterDataStreamHeader(InputArray, "PrintResponse"); } } return(new Tuple <DataStreamHeader, string>(dsh, errmsg)); }