public bool Parse (SafeUri uri)
{
ThreadAssist.AssertNotInMainThread ();
lock (this) {
elements = null;
HttpWebResponse response = null;
Stream stream = null;
Stream web_stream = null;
bool partial_read = false;
long saved_position = 0;
if (uri.Scheme == "file") {
stream = Banshee.IO.File.OpenRead (uri);
} else if (uri.Scheme == "http") {
HttpWebRequest request = (HttpWebRequest)WebRequest.Create (uri.AbsoluteUri);
request.UserAgent = Banshee.Web.Browser.UserAgent;
request.KeepAlive = false;
request.Timeout = 5 * 1000;
request.AllowAutoRedirect = true;
// Parse out and set credentials, if any
string user_info = new Uri (uri.AbsoluteUri).UserInfo;
if (!String.IsNullOrEmpty (user_info)) {
string username = String.Empty;
string password = String.Empty;
int cIndex = user_info.IndexOf (":");
if (cIndex != -1) {
username = user_info.Substring (0, cIndex);
password = user_info.Substring (cIndex + 1);
} else {
username = user_info;
}
request.Credentials = new NetworkCredential (username, password);
}
response = (HttpWebResponse)request.GetResponse ();
web_stream = response.GetResponseStream ();
try {
stream = new MemoryStream ();
byte [] buffer = new byte[4096];
int read;
// If we haven't read the whole stream and if
// it turns out to be a playlist, we'll read the rest
read = web_stream.Read (buffer, 0, buffer.Length);
stream.Write (buffer, 0, read);
if ((read = web_stream.Read (buffer, 0, buffer.Length)) > 0) {
partial_read = true;
stream.Write (buffer, 0, read);
saved_position = stream.Position;
}
stream.Position = 0;
} finally {
if (!partial_read) {
web_stream.Close ();
response.Close ();
}
}
} else {
Hyena.Log.DebugFormat ("Not able to parse playlist at {0}", uri);
return false;
}
PlaylistFormatDescription matching_format = null;
foreach (PlaylistFormatDescription format in playlist_formats) {
stream.Position = 0;
if (format.MagicHandler (new StreamReader (stream))) {
matching_format = format;
break;
}
}
if (matching_format == null) {
return false;
}
if (partial_read) {
try {
stream.Position = saved_position;
Banshee.IO.StreamAssist.Save (web_stream, stream, false);
} finally {
web_stream.Close ();
response.Close ();
}
}
stream.Position = 0;
IPlaylistFormat playlist = (IPlaylistFormat)Activator.CreateInstance (matching_format.Type);
playlist.BaseUri = BaseUri;
playlist.Load (stream, false);
stream.Dispose ();
elements = playlist.Elements;
Title = playlist.Title ?? Path.GetFileNameWithoutExtension (uri.LocalPath);
return true;
}
}