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);
        }
Example #2
0
        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)));
        }
Example #3
0
        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;
        }
Example #4
0
        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);
        }
Example #5
0
 public static ContentNode Parse(ContentCodeBag bag, byte[] buffer)
 {
     return(Parse(bag, buffer, null));
 }
Example #6
0
        public static ContentNode Parse(ContentCodeBag bag, byte[] buffer, string root)
        {
            int offset = 0;

            return(Parse(bag, buffer, root, ref offset));
        }
Example #7
0
        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);
            }
        }
Example #8
0
        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;
            }
        }
Example #9
0
        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));
        }
Example #10
0
 public static ContentNode Parse(ContentCodeBag bag, byte[] buffer)
 {
     return Parse (bag, buffer, null);
 }
Example #11
0
 public static ContentNode Parse(ContentCodeBag bag, byte[] buffer, string root)
 {
     int offset = 0;
     return Parse (bag, buffer, root, ref offset);
 }
Example #12
0
        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;
            }
        }
Example #13
0
        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;
        }
Example #14
0
        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;
            }
        }
Example #15
0
        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);
            }
        }
Example #16
0
        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;
        }