示例#1
0
        internal static (BEncodedDictionary torrent, InfoHash infohash) DecodeTorrent(RawReader reader)
        {
            var torrent = new BEncodedDictionary();

            if (reader.ReadByte() != 'd')
            {
                throw new BEncodingException("Invalid data found. Aborting");  // Remove the leading 'd'
            }
            int      read;
            InfoHash infoHash = null;

            // We can save a few resizes and array copies if we pre-allocate
            // a buffer and then get the memory stream to write to it. We
            // can trivially pass the final set of bytes to the hash function then.
            byte[]       capturedDataBytes  = null;
            MemoryStream capturedDataStream = null;

            while ((read = reader.ReadByte()) != -1 && read != 'e')
            {
                BEncodedValue value;
                var           key = (BEncodedString)Decode(reader, read); // keys have to be BEncoded strings

                if ((read = reader.ReadByte()) == 'd')
                {
                    if (InfoKey.Equals(key))
                    {
                        capturedDataBytes  = new byte[reader.Length - reader.Position];
                        capturedDataStream = new MemoryStream(capturedDataBytes, true);
                        capturedDataStream.WriteByte((byte)'d');
                        reader.BeginCaptureData(capturedDataStream);
                    }

                    value = DecodeDictionary(reader, reader.StrictDecoding);

                    if (InfoKey.Equals(key))
                    {
                        reader.EndCaptureData();
                        using var hasher = SHA1.Create();
                        infoHash         = new InfoHash(hasher.ComputeHash(capturedDataBytes, 0, (int)capturedDataStream.Position));
                    }
                }
                else
                {
                    value = Decode(reader, read);                      // the value is a BEncoded value
                }
                torrent.Add(key, value);
            }

            if (read != 'e')                                    // remove the trailing 'e'
            {
                throw new BEncodingException("Invalid data found. Aborting");
            }

            return(torrent, infoHash);
        }
示例#2
0
        internal static BEncodedDictionary DecodeTorrent(RawReader reader)
        {
            var torrent = new BEncodedDictionary();

            if (reader.ReadByte() != 'd')
            {
                throw new BEncodingException("Invalid data found. Aborting");  // Remove the leading 'd'
            }
            int read;

            while ((read = reader.ReadByte()) != -1 && read != 'e')
            {
                BEncodedValue value;
                var           key = (BEncodedString)Decode(reader, read); // keys have to be BEncoded strings

                if ((read = reader.ReadByte()) == 'd')
                {
                    value = DecodeDictionary(reader, InfoKey.Equals(key));
                }
                else
                {
                    value = Decode(reader, read);                      // the value is a BEncoded value
                }
                torrent.Add(key, value);
            }

            if (read != 'e')                                    // remove the trailing 'e'
            {
                throw new BEncodingException("Invalid data found. Aborting");
            }

            return(torrent);
        }
        public static (BEncodedDictionary torrent, RawInfoHashes infohashes) DecodeTorrent(Stream reader)
        {
            var torrent = new BEncodedDictionary();

            if (reader.ReadByte() != 'd')
            {
                throw new BEncodingException("Invalid data found. Aborting");  // Remove the leading 'd'
            }
            int read;

            byte[]? infohashSHA1   = null;
            byte[]? infohashSHA256 = null;
            while ((read = reader.ReadByte()) != -1)
            {
                if (read == 'e')
                {
                    return(torrent, new RawInfoHashes(infohashSHA1, infohashSHA256));
                }

                if (read < '0' || read > '9')
                {
                    throw new BEncodingException("Invalid key length");
                }

                BEncodedValue value;
                var           key = (BEncodedString)Decode(reader, false, read); // keys have to be BEncoded strings

                if ((read = reader.ReadByte()) == 'd')
                {
                    if (InfoKey.Equals(key))
                    {
                        using var sha1Reader   = new HashingReader(reader, (byte) 'd', SHA1.Create());
                        using var sha256Reader = new HashingReader(sha1Reader, (byte) 'd', SHA256.Create());
                        value          = DecodeDictionary(sha256Reader, false);
                        infohashSHA1   = sha1Reader.TransformFinalBlock();
                        infohashSHA256 = sha256Reader.TransformFinalBlock();
                    }
                    else
                    {
                        value = DecodeDictionary(reader, false);
                    }
                }
                else
                {
                    value = Decode(reader, false, read);
                }
                torrent.Add(key, value);
            }

            throw new BEncodingException("Invalid data found. Aborting");
        }