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); }
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); }
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); }
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); }
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); }