protected void LoadInternal(BEncodedDictionary torrentInformation) { Check.TorrentInformation(torrentInformation); torrentPath = ""; try { foreach (KeyValuePair <BEncodedString, BEncodedValue> keypair in torrentInformation) { switch (keypair.Key.Text) { case ("announce"): // Ignore this if we have an announce-list if (torrentInformation.ContainsKey("announce-list")) { break; } announceUrls.Add(new MonoTorrentCollection <string>()); announceUrls[0].Add(keypair.Value.ToString()); break; case ("creation date"): try { try { creationDate = creationDate.AddSeconds(long.Parse(keypair.Value.ToString())); } catch (Exception e) { if (e is ArgumentOutOfRangeException) { creationDate = creationDate.AddMilliseconds(long.Parse(keypair.Value.ToString())); } else { throw; } } } catch (Exception e) { if (e is ArgumentOutOfRangeException) { throw new BEncodingException("Argument out of range exception when adding seconds to creation date.", e); } else if (e is FormatException) { throw new BEncodingException(String.Format("Could not parse {0} into a number", keypair.Value), e); } else { throw; } } break; case ("nodes"): nodes = (BEncodedList)keypair.Value; break; case ("comment.utf-8"): if (keypair.Value.ToString().Length != 0) { comment = keypair.Value.ToString(); // Always take the UTF-8 version } break; // even if there's an existing value case ("comment"): if (String.IsNullOrEmpty(comment)) { comment = keypair.Value.ToString(); } break; case ("publisher-url.utf-8"): // Always take the UTF-8 version publisherUrl = keypair.Value.ToString(); // even if there's an existing value break; case ("publisher-url"): if (String.IsNullOrEmpty(publisherUrl)) { publisherUrl = keypair.Value.ToString(); } break; case ("azureus_properties"): azureusProperties = keypair.Value; break; case ("created by"): createdBy = keypair.Value.ToString(); break; case ("encoding"): encoding = keypair.Value.ToString(); break; case ("info"): using (SHA1 s = HashAlgoFactory.Create <SHA1>()) infoHash = new InfoHash(s.ComputeHash(keypair.Value.Encode())); ProcessInfo(((BEncodedDictionary)keypair.Value)); break; case ("name"): // Handled elsewhere break; case ("announce-list"): if (keypair.Value is BEncodedString) { break; } BEncodedList announces = (BEncodedList)keypair.Value; for (int j = 0; j < announces.Count; j++) { if (announces[j] is BEncodedList) { BEncodedList bencodedTier = (BEncodedList)announces[j]; List <string> tier = new List <string>(bencodedTier.Count); for (int k = 0; k < bencodedTier.Count; k++) { tier.Add(bencodedTier[k].ToString()); } Toolbox.Randomize <string>(tier); MonoTorrentCollection <string> collection = new MonoTorrentCollection <string>(tier.Count); for (int k = 0; k < tier.Count; k++) { collection.Add(tier[k]); } if (collection.Count != 0) { announceUrls.Add(collection); } } else { throw new BEncodingException(String.Format("Non-BEncodedList found in announce-list (found {0})", announces[j].GetType())); } } break; case ("httpseeds"): // This form of web-seeding is not supported. break; case ("url-list"): if (keypair.Value is BEncodedString) { getRightHttpSeeds.Add(((BEncodedString)keypair.Value).Text); } else if (keypair.Value is BEncodedList) { foreach (BEncodedString str in (BEncodedList)keypair.Value) { GetRightHttpSeeds.Add(str.Text); } } break; default: break; } } } catch (Exception e) { if (e is BEncodingException) { throw; } else { throw new BEncodingException("", e); } } }
/// <summary> /// This method is called internally to load in all the files found within the "Files" section /// of the .torrents infohash /// </summary> /// <param name="list">The list containing the files available to download</param> private void LoadTorrentFiles(BEncodedList list) { List <TorrentFile> files = new List <TorrentFile>(); int endIndex; long length; string path; byte[] md5sum; byte[] ed2k; byte[] sha1; int startIndex; StringBuilder sb = new StringBuilder(32); foreach (BEncodedDictionary dict in list) { length = 0; path = null; md5sum = null; ed2k = null; sha1 = null; foreach (KeyValuePair <BEncodedString, BEncodedValue> keypair in dict) { switch (keypair.Key.Text) { case ("sha1"): sha1 = ((BEncodedString)keypair.Value).TextBytes; break; case ("ed2k"): ed2k = ((BEncodedString)keypair.Value).TextBytes; break; case ("length"): length = long.Parse(keypair.Value.ToString()); break; case ("path.utf-8"): foreach (BEncodedString str in ((BEncodedList)keypair.Value)) { sb.Append(str.Text); sb.Append(Path.DirectorySeparatorChar); } path = sb.ToString(0, sb.Length - 1); sb.Remove(0, sb.Length); break; case ("path"): if (string.IsNullOrEmpty(path)) { foreach (BEncodedString str in ((BEncodedList)keypair.Value)) { sb.Append(str.Text); sb.Append(Path.DirectorySeparatorChar); } path = sb.ToString(0, sb.Length - 1); sb.Remove(0, sb.Length); } break; case ("md5sum"): md5sum = ((BEncodedString)keypair.Value).TextBytes; break; default: break; //FIXME: Log unknown values } } // A zero length file always belongs to the same piece as the previous file if (length == 0) { if (files.Count > 0) { startIndex = files[files.Count - 1].EndPieceIndex; endIndex = files[files.Count - 1].EndPieceIndex; } else { startIndex = 0; endIndex = 0; } } else { startIndex = (int)(size / pieceLength); endIndex = (int)((size + length) / pieceLength); if ((size + length) % pieceLength == 0) { endIndex--; } } size += length; files.Add(new TorrentFile(path, length, startIndex, endIndex, md5sum, ed2k, sha1)); } torrentFiles = files.ToArray(); }