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; }
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.FileData: // after "pfdt" we should send the file size and then immediately the file's contents // DEBUG //Console.WriteLine ("ContentWriter FileData!"); ContentNode [] nodes = (ContentNode []) node.Value; //Console.WriteLine (nodes [0].Value); writer.Write (IPAddress.HostToNetworkOrder ( (int)nodes [0].Value)); FileInfo info = new FileInfo ( (string)nodes [1].Value); //Console.WriteLine ("reading file " + nodes [1].Value + ", length=" +info.Length); FileStream stream = info.Open (FileMode.Open, FileAccess.Read, FileShare.Read); int offset = -1; using (BinaryReader reader = new BinaryReader (stream)) { if (offset > 0) { reader.BaseStream.Seek (offset, SeekOrigin.Begin); } long count = 0; long len = info.Length; while (count < len) { byte [] buf = reader.ReadBytes (Math.Min (8192, (int) len - (int) count)); if (buf.Length == 0) { break; } writer.Write (buf); count += buf.Length; } } break; case ContentType.Container: MemoryStream child_stream = new MemoryStream (); BinaryWriter child_writer = new BinaryWriter (child_stream); foreach (ContentNode child in (ContentNode []) node.Value) { Write (bag, child, child_writer); } child_writer.Flush (); byte [] bytes = child_stream.GetBuffer (); int len = (int) child_stream.Length; writer.Write (IPAddress.HostToNetworkOrder (len)); writer.Write (bytes, 0, len); child_writer.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.Name = "DAAP"; 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); } }
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; // This is a fix for iPhoto '08 which gives wrong content-type for dpap.databasecontainers (aply) if (num == 1634757753) { code = new ContentCode (); code.Name = "dpap.databasecontainers"; code.Type = ContentType.Container; } else code = bag.Lookup (num); if (code.Name.Equals ("dpap.filedata")) code.Type = ContentType.FileData; if (code.Equals (ContentCode.Zero)) { // probably a buggy server. fallback to our internal code bag Console.WriteLine ("fallback to internal code bag"); Console.WriteLine ("Code number: "+num); throw new Exception ("Content code not found!"); } 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; Console.WriteLine ("name = " + node.Name + "Code=" +code.Type.ToString () + " num=" +num); 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; case ContentType.FileData: node.Value = offset+8; break; default: throw new ContentException (String.Format ("Unknown content type '{0}' for '{1}'", code.Type, code.Name)); } offset += length + 8; if (root != null) { ContentNode root_node = node.GetChild (root); if (root_node == null) throw new ContentException (String.Format ("Could not find root node '{0}'", root)); return root_node; } else return node; }