public void Unmarshal(TransportPacket input, ITransportDeliveryCharacteristics tdc, EventHandler<MessageEventArgs> messageAvailable) { // <item>Message fits within the transport packet length, so sent unmodified // <pre>[byte:message-type] [byte:channelId] [uint32:packet-size] // [bytes:content]</pre> // </item> // <item> if the message is the first fragment, then the high-bit is // set on the message-type; the number of fragments is encoded using // the adaptive <see cref="ByteUtils.EncodeLength(int)"/> format. // <pre>[byte:message-type'] [byte:channelId] [uint32:packet-size] // [byte:seqno] [bytes:encoded-#-fragments] [bytes:frag]</pre> // </item> // <item> for all subsequent fragments; seqno' = seqno | 128; // the number of fragments is encoded using the adaptive // <see cref="ByteUtils.EncodeLength(int)"/> format. // <pre>[byte:message-type'] [byte:channelId] [uint32:packet-size] // [byte:seqno'] [bytes:encoded-fragment-#] [bytes:frag]</pre> // Fastpath: if the message-type doesn't have the high-bit set, // then this is a non-fragmented message if ((input.ByteAt(0) & 128) == 0) { // If the submarshaller uses LWMCFv1.1 then we would have just // sent the packet as-is; if not, then we'll have prefixed a // LWMCFv1.1 header which must be first removed if (!subMarshallerIsLwmcf11) { input.RemoveBytes(0, (int)LWMCFv11.HeaderSize); } subMarshaller.Unmarshal(input, tdc, messageAvailable); return; } MessageType type; byte channelId; uint contentLength; Stream s = input.AsReadStream(); LWMCFv11.DecodeHeader(out type, out channelId, out contentLength, s); byte seqNo = (byte)s.ReadByte(); TransportPacket subPacket; if ((seqNo & 128) == 0) { // This starts a new message uint numFrags = (uint)ByteUtils.DecodeLength(s); subPacket = UnmarshalFirstFragment(seqNo, numFrags, input.SplitOut((int)(s.Length - s.Position)), tdc); } else { // This is a message in progress seqNo = (byte)(seqNo & ~128); uint fragNo = (uint)ByteUtils.DecodeLength(s); subPacket = UnmarshalFragInProgress(seqNo, fragNo, input.SplitOut((int)(s.Length - s.Position)), tdc); } if (subPacket != null) { subMarshaller.Unmarshal(subPacket, tdc, messageAvailable); subPacket.Dispose(); } }