Esempio n. 1
0
        /// <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);
        }