public static byte[] Write(ContentCodeBag bag, ContentNode node) { MemoryStream stream = new MemoryStream (); BinaryWriter writer = new BinaryWriter (stream); try { Write (bag, node, writer); } catch (Exception) { Console.Error.WriteLine ("Error writing node {0}, val type is {1}", node.Name, node.Value.GetType ()); throw; } writer.Flush (); byte[] buf = stream.GetBuffer (); long len = stream.Length; writer.Close (); byte[] ret = new byte[len]; Array.Copy (buf, ret, len); return ret; }
internal static ServerInfo FromNode(ContentNode node) { ServerInfo info = new ServerInfo (); if (node.Name != "dmap.serverinforesponse") return null; foreach (ContentNode child in (node.Value as ContentNode[])) { switch (child.Name) { case "dmap.itemname": info.Name = (string) child.Value; break; case "dmap.authenticationmethod": info.AuthenticationMethod = (AuthenticationMethod) child.Value; break; case "dmap.supportsupdate": info.SupportsUpdate = (byte) child.Value == 1; break; } } return info; }
public void WriteResponse(Socket client, ContentNode node) { WriteResponse (client, HttpStatusCode.OK, ContentWriter.Write (ContentCodeBag.Default, node)); }
private static void Write(ContentCodeBag bag, ContentNode node, BinaryWriter writer) { ContentCode code = bag.Lookup (node.Name); if (code.Equals (ContentCode.Zero)) { throw new ContentException ("Failed to get content code for: " + node.Name); } writer.Write (IPAddress.HostToNetworkOrder (code.Number)); switch (code.Type) { case ContentType.Char: writer.Write (IPAddress.HostToNetworkOrder (1)); writer.Write ((byte) node.Value); break; case ContentType.Short: writer.Write (IPAddress.HostToNetworkOrder (2)); writer.Write (IPAddress.HostToNetworkOrder ((short) node.Value)); break; case ContentType.SignedLong: case ContentType.Long: writer.Write (IPAddress.HostToNetworkOrder (4)); writer.Write (IPAddress.HostToNetworkOrder ((int) node.Value)); break; case ContentType.LongLong: writer.Write (IPAddress.HostToNetworkOrder (8)); writer.Write (IPAddress.HostToNetworkOrder ((long) node.Value)); break; case ContentType.String: byte[] data = Encoding.UTF8.GetBytes ((string) node.Value); writer.Write (IPAddress.HostToNetworkOrder (data.Length)); writer.Write (data); break; case ContentType.Date: writer.Write (IPAddress.HostToNetworkOrder (4)); writer.Write (IPAddress.HostToNetworkOrder (Utility.FromDateTime ((DateTime) node.Value))); break; case ContentType.Version: Version version = (Version) node.Value; writer.Write (IPAddress.HostToNetworkOrder (4)); writer.Write ((short) IPAddress.HostToNetworkOrder ((short) version.Major)); writer.Write ((byte) version.Minor); writer.Write ((byte) version.Build); break; case ContentType.Container: MemoryStream childStream = new MemoryStream (); BinaryWriter childWriter = new BinaryWriter (childStream); foreach (ContentNode child in (ContentNode[]) node.Value) { try { Write (bag, child, childWriter); } catch (Exception) { Console.Error.WriteLine ("Error writing node {0}, val type is {1}", child.Name, child.Value.GetType ()); throw; } } childWriter.Flush (); byte[] bytes = childStream.GetBuffer (); int len = (int) childStream.Length; writer.Write (IPAddress.HostToNetworkOrder (len)); writer.Write (bytes, 0, len); childWriter.Close (); break; default: Console.Error.WriteLine ("Cannot write node of type: " + code.Type); break; } }
internal ContentNode ToNode() { List <ContentNode> nodes = new List <ContentNode> (); foreach (int number in codes_by_num.Keys) { ContentCode code = (ContentCode) codes_by_num[number]; List <ContentNode> contents = new List <ContentNode> (); contents.Add (new ContentNode ("dmap.contentcodesnumber", code.Number)); contents.Add (new ContentNode ("dmap.contentcodesname", code.Name)); contents.Add (new ContentNode ("dmap.contentcodestype", code.Type)); ContentNode dict = new ContentNode ("dmap.dictionary", contents); nodes.Add (dict); } ContentNode status = new ContentNode ("dmap.status", 200); return new ContentNode ("dmap.contentcodesresponse", status, nodes); }
public static ContentNode Parse(ContentCodeBag bag, byte[] buffer, string root, ref int offset) { ContentNode node = new ContentNode (); int num = IPAddress.NetworkToHostOrder (BitConverter.ToInt32 (buffer, offset)); ContentCode code = bag.Lookup (num); if (code.Equals (ContentCode.Zero)) { // probably a buggy server. fallback to our internal code bag code = ContentCodeBag.Default.Lookup (num); } int length = IPAddress.NetworkToHostOrder (BitConverter.ToInt32 (buffer, offset + 4)); if (code.Equals (ContentCode.Zero)) { string s = System.Text.ASCIIEncoding.ASCII.GetString (buffer); throw new ContentException (String.Format ("Failed to find content code for '{0}'. Data length is {1}; content is {2}", ContentCodeBag.GetStringFormat (num), length, s)); } node.Name = code.Name; switch (code.Type) { case ContentType.Char: node.Value = (byte) buffer[offset + 8]; break; case ContentType.Short: node.Value = IPAddress.NetworkToHostOrder (BitConverter.ToInt16 (buffer, offset + 8)); break; case ContentType.SignedLong: case ContentType.Long: node.Value = IPAddress.NetworkToHostOrder (BitConverter.ToInt32 (buffer, offset + 8)); break; case ContentType.LongLong: node.Value = IPAddress.NetworkToHostOrder (BitConverter.ToInt64 (buffer, offset + 8)); break; case ContentType.String: node.Value = Encoding.UTF8.GetString (buffer, offset + 8, length); break; case ContentType.Date: node.Value = Utility.ToDateTime (IPAddress.NetworkToHostOrder (BitConverter.ToInt32 (buffer, offset + 8))); break; case ContentType.Version: int major = IPAddress.NetworkToHostOrder (BitConverter.ToInt16 (buffer, offset + 8)); int minor = (int) buffer[offset + 10]; int micro = (int) buffer[offset + 11]; node.Value = new Version (major, minor, micro); break; case ContentType.Container: node.Value = ParseChildren (bag, buffer, offset + 8, length); break; default: throw new ContentException (String.Format ("Unknown content type '{0}' for '{1}'", code.Type, code.Name)); } offset += length + 8; if (root != null) { ContentNode rootNode = node.GetChild (root); if (rootNode == null) throw new ContentException (String.Format ("Could not find root node '{0}'", root)); return rootNode; } else { return node; } }