/// <summary>
        /// peek at current location in input array for a 5250 data stream header. If is
        /// a valid header, return a DataStreamHeader. Otherwise, return null.
        /// </summary>
        /// <param name="InputArray"></param>
        /// <returns></returns>
        public static DataStreamHeader PeekDataStreamHeader(this InputByteArray InputArray)
        {
            DataStreamHeader dsh = null;

            if (InputArray.IsDataStreamHeader( ) == true)
            {
                var buf = new InputByteArray(InputArray.PeekBytesLenient(100));
                var rv  = DataStreamHeader.Factory(buf);
                dsh = rv.Item1;
            }

            return(dsh);
        }
        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));
        }