/// <summary>Constructs a MetainfoFile</summary> /// <param name="istream">Stream to read data from</param> public MetainfoFile(IO.Stream istream) { BEncode.Dictionary mainDictionary = (BEncode.Dictionary)BEncode.NextElement(istream); this.announceUrl = mainDictionary.GetString(new BEncode.String("announce")); if (mainDictionary.Contains("comment")) this.comment = mainDictionary.GetString("comment"); if (mainDictionary.Contains("created by")) this.createdBy = mainDictionary.GetString("created by"); if (mainDictionary.Contains("creation date")) { int creation = mainDictionary.GetInteger("creation date"); this.creationDate = new System.DateTime(1970, 1, 1, 0, 0, 0); this.creationDate = this.creationDate.AddSeconds(creation); } BEncode.Dictionary infoDictionary = mainDictionary.GetDictionary("info"); this.name = infoDictionary.GetString("name"); this.pieceLength = infoDictionary.GetInteger("piece length"); this.pieceFileName = this.name.ToLower().Replace(' ', '_'); // Get SHA digests byte[] pieces = infoDictionary.GetBytes("pieces"); int numPieces = pieces.Length / 20; this.shaDigestList.Capacity = numPieces; for (int i=0; i<numPieces; ++i) { this.shaDigestList.Add( new ByteField20(pieces, i*20) ); } // Get filenames and lengths if (infoDictionary.Contains("length")) { // one file this.fileList.Add(name); int fileLength = infoDictionary.GetInteger("length"); this.fileLengthList.Add(fileLength); this.totalSize = fileLength; } else { // multiple files - a list of dictionaries containing the filename and length BEncode.List files = infoDictionary.GetList("files"); this.fileList.Capacity = this.fileLengthList.Capacity = files.Count; this.totalSize = 0; foreach (BEncode.Dictionary fileDic in files) { BEncode.List pathList = fileDic.GetList("path"); string path = this.name + IO.Path.DirectorySeparatorChar; for (int i=0; i<pathList.Count-1; ++i) { path += pathList[i].ToString() + IO.Path.DirectorySeparatorChar; } path += pathList[ pathList.Count-1 ]; this.fileList.Add(path); int fileLength = fileDic.GetInteger("length"); this.fileLengthList.Add(fileLength); this.totalSize += fileLength; } } // calculate the SHA-1 digest of the info dictionary - this is required for the tracker protocol istream.Seek(infoDictionary.Position, IO.SeekOrigin.Begin); byte[] infoData = new byte[ infoDictionary.Length ]; istream.Read(infoData, 0, infoData.Length); this.infoDigest = ByteField20.ComputeSHAHash(infoData); }