private Error ParseError(TftpStreamReader reader)
        {
            ushort errorCode = reader.ReadUInt16();
            String message   = ParseNullTerminatedString(reader);

            return(new Error(errorCode, message));
        }
        private Data ParseData(TftpStreamReader reader)
        {
            ushort blockNumber = reader.ReadUInt16();

            byte[] data = reader.ReadBytes(10000);
            return(new Data(blockNumber, data));
        }
        private ITftpCommand ParseInternal(byte[] message)
        {
            TftpStreamReader reader = new TftpStreamReader(new MemoryStream(message));

            ushort opcode = reader.ReadUInt16();

            switch (opcode)
            {
            case ReadRequest.OpCode:
                return(ParseReadRequest(reader));

            case WriteRequest.OpCode:
                return(ParseWriteRequest(reader));

            case Data.OpCode:
                return(ParseData(reader));

            case Acknowledgement.OpCode:
                return(ParseAcknowledgement(reader));

            case Error.OpCode:
                return(ParseError(reader));

            case OptionAcknowledgement.OpCode:
                return(ParseOptionAcknowledgement(reader));

            default:
                throw new TftpParserException("Invalid opcode");
            }
        }
        private List <TransferOption> ParseTransferOptions(TftpStreamReader reader)
        {
            List <TransferOption> options = new List <TransferOption>();

            while (true)
            {
                String name;

                try
                {
                    name = ParseNullTerminatedString(reader);
                }
                catch (IOException)
                {
                    name = "";
                }

                if (name.Length == 0)
                {
                    break;
                }

                string value = ParseNullTerminatedString(reader);
                options.Add(new TransferOption(name, value));
            }
            return(options);
        }
        private WriteRequest ParseWriteRequest(TftpStreamReader reader)
        {
            String                       filename = ParseNullTerminatedString(reader);
            TftpTransferMode             mode     = ParseModeType(ParseNullTerminatedString(reader));
            IEnumerable <TransferOption> options  = ParseTransferOptions(reader);

            return(new WriteRequest(filename, mode, options));
        }
        private String ParseNullTerminatedString(TftpStreamReader reader)
        {
            byte          b;
            StringBuilder str = new StringBuilder();

            while ((b = reader.ReadByte()) > 0)
            {
                str.Append((char)b);
            }

            return(str.ToString());
        }
        private Acknowledgement ParseAcknowledgement(TftpStreamReader reader)
        {
            ushort blockNumber = reader.ReadUInt16();

            return(new Acknowledgement(blockNumber));
        }
        private OptionAcknowledgement ParseOptionAcknowledgement(TftpStreamReader reader)
        {
            IEnumerable <TransferOption> options = ParseTransferOptions(reader);

            return(new OptionAcknowledgement(options));
        }