public static ContentCodeBag ParseCodes(byte[] buffer) { ContentCodeBag bag = new ContentCodeBag(); // add some codes to bootstrap us bag.AddCode("mccr", "dmap.contentcodesresponse", ContentType.Container); bag.AddCode("mdcl", "dmap.dictionary", ContentType.Container); bag.AddCode("mcnm", "dmap.contentcodesnumber", ContentType.Long); bag.AddCode("mcna", "dmap.contentcodesname", ContentType.String); bag.AddCode("mcty", "dmap.contentcodestype", ContentType.Short); bag.AddCode("mstt", "dmap.status", ContentType.Long); // some photo-specific codes bag.AddCode("ppro", "dpap.protocolversion", ContentType.Long); bag.AddCode("pret", "dpap.blah", ContentType.Container); // Artwork bag.AddCode("asac", "daap.songartworkcount", ContentType.Short); bag.AddCode("ased", "daap.songextradata", ContentType.Short); bag.AddCode("ated", "daap.supportsextradata", ContentType.Short); ContentNode node = ContentParser.Parse(bag, buffer); foreach (ContentNode dictNode in (node.Value as ContentNode[])) { if (dictNode.Name != "dmap.dictionary") { continue; } ContentCode code = new ContentCode(); foreach (ContentNode item in (dictNode.Value as ContentNode[])) { switch (item.Name) { case "dmap.contentcodesnumber": code.Number = (int)item.Value; break; case "dmap.contentcodesname": code.Name = (string)item.Value; break; case "dmap.contentcodestype": code.Type = (ContentType)Enum.ToObject(typeof(ContentType), (short)item.Value); break; } } bag.codes[code.Number] = code; } return(bag); }
private static ContentNode[] ParseChildren(ContentCodeBag bag, byte[] buffer, int offset, int length) { ArrayList children = new ArrayList(); int position = offset; while (position < offset + length) { children.Add(Parse(bag, buffer, null, ref position)); } return((ContentNode[])children.ToArray(typeof(ContentNode))); }
public static byte[] Write(ContentCodeBag bag, ContentNode node) { MemoryStream stream = new MemoryStream (); BinaryWriter writer = new BinaryWriter (stream); Write (bag, node, writer); writer.Flush (); byte[] buf = stream.GetBuffer (); long len = stream.Length; writer.Close (); byte[] ret = new byte[len]; Array.Copy (buf, ret, len); return ret; }
public static byte[] Write(ContentCodeBag bag, ContentNode node) { MemoryStream stream = new MemoryStream(); BinaryWriter writer = new BinaryWriter(stream); Write(bag, node, writer); writer.Flush(); byte[] buf = stream.GetBuffer(); long len = stream.Length; writer.Close(); byte[] ret = new byte[len]; Array.Copy(buf, ret, len); return(ret); }
public static ContentNode Parse(ContentCodeBag bag, byte[] buffer) { return(Parse(bag, buffer, null)); }
public static ContentNode Parse(ContentCodeBag bag, byte[] buffer, string root) { int offset = 0; return(Parse(bag, buffer, root, ref offset)); }
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)) { throw new ContentException(String.Format("Failed to find content code for '{0}'. Data length is {1}", ContentCodeBag.GetStringFormat(num), length)); } 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); } }
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) { Write (bag, child, childWriter); } 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; } }
private static ContentNode[] ParseChildren(ContentCodeBag bag, byte[] buffer, int offset, int length) { ArrayList children = new ArrayList (); int position = offset; while (position < offset + length) { children.Add (Parse (bag, buffer, null, ref position)); } return (ContentNode[]) children.ToArray (typeof (ContentNode)); }
public static ContentNode Parse(ContentCodeBag bag, byte[] buffer) { return Parse (bag, buffer, null); }
public static ContentNode Parse(ContentCodeBag bag, byte[] buffer, string root) { int offset = 0; return Parse (bag, buffer, root, ref offset); }
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)) { throw new ContentException (String.Format ("Failed to find content code for '{0}'. Data length is {1}", ContentCodeBag.GetStringFormat (num), length)); } 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; } }
public static ContentCodeBag ParseCodes(byte[] buffer) { ContentCodeBag bag = new ContentCodeBag(); // add some codes to bootstrap us bag.AddCode("mccr", "dmap.contentcodesresponse", ContentType.Container); bag.AddCode("mdcl", "dmap.dictionary", ContentType.Container); bag.AddCode("mcnm", "dmap.contentcodesnumber", ContentType.Long); bag.AddCode("mcna", "dmap.contentcodesname", ContentType.String); bag.AddCode("mcty", "dmap.contentcodestype", ContentType.Short); bag.AddCode("mstt", "dmap.status", ContentType.Long); // some photo-specific codes bag.AddCode("ppro", "dpap.protocolversion", ContentType.Long); bag.AddCode("pret", "dpap.blah", ContentType.Container); bag.AddCode("cmst", "tune.root", ContentType.Container); bag.AddCode("cmsr", "tune.rev", ContentType.Long); bag.AddCode("caps", "tune.status", ContentType.Char); bag.AddCode("cash", "tune.shuffle", ContentType.Char); bag.AddCode("carp", "tune.repeat", ContentType.Char); bag.AddCode("cavc", "tune.xxx", ContentType.Char); bag.AddCode("caas", "tune.xxx", ContentType.Long); bag.AddCode("caar", "tune.xxx", ContentType.Long); bag.AddCode("canp", "tune.xxx", ContentType.String); bag.AddCode("cann", "tune.track", ContentType.String); bag.AddCode("cana", "tune.artist", ContentType.String); bag.AddCode("canl", "tune.album", ContentType.String); bag.AddCode("cang", "tune.xxx", ContentType.Short); bag.AddCode("cmmk", "tune.xxx", ContentType.Long); bag.AddCode("cant", "tune.remaining", ContentType.Long); bag.AddCode("cast", "tune.total", ContentType.Long); bag.AddCode("cmgt", "vol.root", ContentType.Container); bag.AddCode("cmvo", "tune.volume", ContentType.Long); bag.AddCode("ceGS", "tune.xxx", ContentType.String); bag.AddCode("mdbk", "db.xxx", ContentType.Long); bag.AddCode("aeIM", "db.xxx", ContentType.LongLong); bag.AddCode("cacr", "cue.xxx", ContentType.Container); ContentNode node = ContentParser.Parse(bag, buffer); foreach (ContentNode dictNode in (node.Value as ContentNode[])) { if (dictNode.Name != "dmap.dictionary") { continue; } ContentCode code = new ContentCode(); foreach (ContentNode item in (dictNode.Value as ContentNode[])) { switch (item.Name) { case "dmap.contentcodesnumber": code.Number = (int)item.Value; break; case "dmap.contentcodesname": code.Name = (string)item.Value; break; case "dmap.contentcodestype": code.Type = (ContentType)Enum.ToObject(typeof(ContentType), (short)item.Value); break; } } bag.codes[code.Number] = code; } return bag; }
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) { Write(bag, child, childWriter); } 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; } }
public void Login(string username, string password) { fetcher.Username = username; fetcher.Password = password; try { bag = ContentCodeBag.ParseCodes (fetcher.Fetch ("/content-codes")); ContentNode node = ContentParser.Parse (bag, fetcher.Fetch ("/login")); ParseSessionId (node); FetchDatabases (); Refresh (); if (serverInfo.SupportsUpdate) { updateRunning = true; Thread thread = new Thread (UpdateLoop); thread.IsBackground = true; thread.Start (); } } catch (WebException e) { if (e.Response != null && (e.Response as HttpWebResponse).StatusCode == HttpStatusCode.Unauthorized) throw new AuthenticationException ("Username or password incorrect"); else throw new LoginException ("Failed to login", e); } catch (Exception e) { throw new LoginException ("Failed to login", e); } }
public static ContentCodeBag ParseCodes(byte[] buffer) { ContentCodeBag bag = new ContentCodeBag (); // add some codes to bootstrap us bag.AddCode ("mccr", "dmap.contentcodesresponse", ContentType.Container); bag.AddCode ("mdcl", "dmap.dictionary", ContentType.Container); bag.AddCode ("mcnm", "dmap.contentcodesnumber", ContentType.Long); bag.AddCode ("mcna", "dmap.contentcodesname", ContentType.String); bag.AddCode ("mcty", "dmap.contentcodestype", ContentType.Short); bag.AddCode ("mstt", "dmap.status", ContentType.Long); // some photo-specific codes bag.AddCode ("ppro", "dpap.protocolversion", ContentType.Long); bag.AddCode ("pret", "dpap.blah", ContentType.Container); ContentNode node = ContentParser.Parse (bag, buffer); foreach (ContentNode dictNode in (node.Value as ContentNode[])) { if (dictNode.Name != "dmap.dictionary") { continue; } ContentCode code = new ContentCode (); foreach (ContentNode item in (dictNode.Value as ContentNode[])) { switch (item.Name) { case "dmap.contentcodesnumber": code.Number = (int) item.Value; break; case "dmap.contentcodesname": code.Name = (string) item.Value; break; case "dmap.contentcodestype": code.Type = (ContentType) Enum.ToObject (typeof (ContentType), (short) item.Value); break; } } bag.codes[code.Number] = code; } return bag; }