/// <summary> /// Decodes the specified discovery metadata packet. /// </summary> /// <param name="packet">The packet to decode.</param> public static DiscoveryMetadata Decode(byte[] packet) { // packet contains a length and a checksum at very least if (packet.Length < sizeof(Int32) * 2) { return null; } // check content length var contentLength = BitConverter.ToInt32(packet, 0); if (packet.Length != contentLength + sizeof(Int32) * 2) // content + length + checksum { return null; } // validate checksum var checksum = BitConverter.ToUInt32(packet, sizeof(Int32)); var crc = new Crc32Calculator(); crc.UpdateWithBlock(packet, sizeof(Int32) * 2, contentLength); if (checksum != crc.Crc32) { return null; } // decode contents var contents = packet.Skip(sizeof(Int32) * 2).ToArray(); var data = Encoding.UTF8.GetString(contents).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); if (data.Length < 1) { return null; } // extract signature and create the packet var signature = Unescape(data.First()); var dp = CreateDiscoveryMetadata(signature); if (dp == null) { return null; } // populate properties foreach (var pair in data.Skip(1)) { var entry = pair.Split('='); dp.Properties[Unescape(entry.First())] = Unescape(entry.Last()); } return dp; }
/// <summary> /// Encodes the specified discovery metadata packet into byte array. /// </summary> /// <param name="dp">The packet to encode.</param> public static byte[] Encode(DiscoveryMetadata dp) { // convert the packet into string var sb = new StringBuilder(); sb.AppendFormat("{0}|", Escape(dp.Signature)); foreach (var entry in dp.Properties) { sb.AppendFormat("{0}={1}|", Escape(entry.Key), Escape(entry.Value)); } // calculate checksum and merge var content = Encoding.UTF8.GetBytes(sb.ToString()); var crc = new Crc32Calculator(); crc.UpdateWithBlock(content, 0, content.Length); var checksum = BitConverter.GetBytes(crc.Crc32); var contentLength = BitConverter.GetBytes(content.Length); // packet contents: length, checksum, content return contentLength.Concat(checksum).Concat(content).ToArray(); }