Exemplo n.º 1
0
        public virtual Message Deserialize(byte[] bytes)
        {
            var reader  = new DatagramReader(bytes);
            var factory = new MessageFactory();
            var version = reader.Read(Message.VersionBits);

            if (version != Message.Version)
            {
                throw new SerializationException("incorrect version");
            }

            var type          = (MessageType)reader.Read(Message.TypeBits);
            var optionCount   = reader.Read(Message.OptionCountBits);
            var code          = (CodeRegistry)reader.Read(Message.CodeBits);
            var id            = reader.Read(Message.IdBits);
            var message       = factory.Create(type, code, id);
            var currentOption = 0;

            for (var i = 0; i < optionCount; i++)
            {
                var delta  = reader.Read(Message.OptionDeltaBits);
                var length = reader.Read(Message.OptionLengthBits);
                currentOption += delta;
                var option = new Option((OptionNumber)currentOption)
                {
                    Value = reader.ReadBytes(length)
                };
                message.AddOption(option);
            }

            message.Payload = reader.ReadAllBytes();
            return(message);
        }
Exemplo n.º 2
0
        public void TestUnalignedBytes7()
        {
            Int32 bitCount = 7;
            Int32 bitsIn   = 0x69;

            Byte[] bytesIn = System.Text.Encoding.UTF8.GetBytes("Some aligned bytes");

            DatagramWriter writer = new DatagramWriter();

            writer.Write(bitsIn, bitCount);
            writer.WriteBytes(bytesIn);

            DatagramReader reader  = new DatagramReader(writer.ToByteArray());
            Int32          bitsOut = reader.Read(bitCount);

            Byte[] bytesOut = reader.ReadBytes(bytesIn.Length);

            Assert.IsEqualTo(bitsIn, bitsOut);
            Assert.IsSequenceEqualTo(bytesIn, bytesOut);
        }
Exemplo n.º 3
0
        public Message Decode(Byte[] bytes)
#endif
        {
            DatagramReader datagram = new DatagramReader(bytes);

            // read headers
            Int32 version = datagram.Read(VersionBits);

            if (version != SupportedVersion)
            {
                return(null);
            }

            MessageType type        = (MessageType)datagram.Read(TypeBits);
            Int32       tokenLength = datagram.Read(TokenLengthBits);
            Int32       code        = datagram.Read(CodeBits);

            // create new message with subtype according to code number
            Message msg = Message.Create(code);

            msg.Type = type;
            msg.ID   = datagram.Read(IDBits);

            // read token
            if (tokenLength > 0)
            {
                msg.Token = datagram.ReadBytes(tokenLength);
            }
            else
            {
                msg.RequiresToken = false;
            }

            // read options
            Int32 currentOption = 0;

            while (datagram.BytesAvailable)
            {
                Byte nextByte = datagram.ReadNextByte();
                if (nextByte == PayloadMarker)
                {
                    if (!datagram.BytesAvailable)
                    {
                        // the presence of a marker followed by a zero-length payload
                        // must be processed as a message format error
                        return(null);
                    }

                    msg.Payload = datagram.ReadBytesLeft();
                }
                else
                {
                    // the first 4 bits of the byte represent the option delta
                    Int32 optionDeltaNibble = (0xF0 & nextByte) >> 4;
                    currentOption += GetValueFromOptionNibble(optionDeltaNibble, datagram);

                    // the second 4 bits represent the option length
                    Int32 optionLengthNibble = (0x0F & nextByte);
                    Int32 optionLength       = GetValueFromOptionNibble(optionLengthNibble, datagram);

                    // read option
                    OptionType currentOptionType = GetOptionType(currentOption);
                    Option     opt = Option.Create(currentOptionType);
                    opt.RawValue = datagram.ReadBytes(optionLength);

                    msg.AddOption(opt);
                }
            }

            return(msg);
        }
Exemplo n.º 4
0
        public Message Decode(Byte[] bytes)
#endif
        {
            DatagramReader datagram = new DatagramReader(bytes);

            // read headers
            Int32 version = datagram.Read(VersionBits);

            if (version != SupportedVersion)
            {
                return(null);
            }

            MessageType type        = (MessageType)datagram.Read(TypeBits);
            Int32       optionCount = datagram.Read(OptionCountBits);
            Int32       code        = datagram.Read(CodeBits);

            // create new message with subtype according to code number
            Message msg = Message.Create(code);

            msg.Type = type;
            msg.ID   = datagram.Read(IDBits);

            // read options
            Int32 currentOption = 0;

            for (Int32 i = 0; i < optionCount; i++)
            {
                // read option delta bits
                Int32 optionDelta = datagram.Read(OptionDeltaBits);

                currentOption += optionDelta;
                OptionType currentOptionType = GetOptionType(currentOption);

                if (IsFencepost(currentOptionType))
                {
                    // read number of options
                    datagram.Read(OptionLengthBaseBits);
                }
                else
                {
                    // read option length
                    Int32 length = datagram.Read(OptionLengthBaseBits);
                    if (length > MaxOptionLengthBase)
                    {
                        // read extended option length
                        length += datagram.Read(OptionLengthExtendedBits);
                    }
                    // read option
                    Option opt = Option.Create(currentOptionType);
                    opt.RawValue = datagram.ReadBytes(length);

                    msg.AddOption(opt);
                }
            }

            msg.Payload = datagram.ReadBytesLeft();

            // incoming message already have a token,
            // including implicit empty token
            msg.RequiresToken = false;

            return(msg);
        }
Exemplo n.º 5
0
        public Message Decode(Byte[] bytes)
#endif
        {
            DatagramReader datagram = new DatagramReader(bytes);

            // read headers
            Int32 version = datagram.Read(VersionBits);

            if (version != SupportedVersion)
            {
                return(null);
            }

            MessageType type        = (MessageType)datagram.Read(TypeBits);
            Int32       optionCount = datagram.Read(OptionCountBits);
            Int32       code        = datagram.Read(CodeBits);

            // create new message with subtype according to code number
            Message msg = Message.Create(code);

            msg.Type = type;
            msg.ID   = datagram.Read(IDBits);

            // read options
            Int32   currentOption  = 0;
            Boolean hasMoreOptions = optionCount == 15;

            for (Int32 i = 0; (i < optionCount || hasMoreOptions) && datagram.BytesAvailable; i++)
            {
                // first 4 option bits: either option jump or option delta
                Int32 optionDelta = datagram.Read(OptionDeltaBits);

                if (optionDelta == 15)
                {
                    // option jump or end-of-options marker
                    Int32 bits = datagram.Read(4);
                    switch (bits)
                    {
                    case 0:
                        // end-of-options marker read (0xF0), payload follows
                        hasMoreOptions = false;
                        continue;

                    case 1:
                        // 0xF1 (Delta = 15)
                        optionDelta = 15 + datagram.Read(OptionDeltaBits);
                        break;

                    case 2:
                        // Delta = ((Option Jump Value) + 2) * 8
                        optionDelta = (datagram.Read(8) + 2) * 8 + datagram.Read(OptionDeltaBits);
                        break;

                    case 3:
                        // Delta = ((Option Jump Value) + 258) * 8
                        optionDelta = (datagram.Read(16) + 258) * 8 + datagram.Read(OptionDeltaBits);
                        break;

                    default:
                        break;
                    }
                }

                currentOption += optionDelta;
                OptionType currentOptionType = GetOptionType(currentOption);

                Int32 length = datagram.Read(OptionLengthBaseBits);
                if (length == 15)
                {
                    /*
                     * When the Length field is set to 15, another byte is added as
                     * an 8-bit unsigned integer whose value is added to the 15,
                     * allowing option value lengths of 15-270 bytes. For option
                     * lengths beyond 270 bytes, we reserve the value 255 of an
                     * extension byte to mean
                     * "add 255, read another extension byte".
                     */
                    Int32 additionalLength = 0;
                    do
                    {
                        additionalLength = datagram.Read(8);
                        length          += additionalLength;
                    } while (additionalLength >= 255);
                }

                // read option
                Option opt = Option.Create(currentOptionType);
                opt.RawValue = datagram.ReadBytes(length);

                msg.AddOption(opt);
            }

            msg.Payload = datagram.ReadBytesLeft();

            // incoming message already have a token, including implicit empty token
            msg.RequiresToken = false;

            return(msg);
        }