예제 #1
0
        /// <summary>
        /// Decodes a BEncodedString from the supplied StreamReader
        /// </summary>
        /// <param name="reader">The StreamReader containing the BEncodedString</param>
        internal override void DecodeInternal(RawReader reader)
        {
            reader.CannotBeNull();

            int    letterCount;
            string length = string.Empty;

            // read in how many characters the string is long
            while (reader.PeekByte() != -1 &&
                   reader.PeekByte() != ':')
            {
                length += (char)reader.ReadByte();
            }

            if (reader.ReadByte() != ':')
            {
                throw new BEncodingException("Invalid data found. Aborting");
            }

            if (!int.TryParse(length, out letterCount))
            {
                throw new BEncodingException("Invalid BEncodedString. Could not read the string length.");
            }

            this.textBytes = new byte[letterCount];

            if (reader.Read(this.textBytes, 0, letterCount) != letterCount)
            {
                throw new BEncodingException("Invalid BEncodedString. The string does not match the specified length.");
            }
        }
        /// <summary>
        /// Special decoding method for torrent files - allows dictionary attributes to be out of order for the
        /// overall torrent file, but imposes strict rules on the info dictionary.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <value>
        /// The BEncoded dictionary.
        /// </value>
        public static BEncodedDictionary DecodeTorrent(RawReader reader)
        {
            reader.CannotBeNull();

            BEncodedString     key     = null;
            BEncodedValue      value   = null;
            BEncodedDictionary torrent = new BEncodedDictionary();

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

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

                if (reader.PeekByte() == 'd')
                {
                    value = new BEncodedDictionary();

                    if (key.Text.ToLower().Equals("info"))
                    {
                        ((BEncodedDictionary)value).DecodeInternal(reader, true);
                    }
                    else
                    {
                        ((BEncodedDictionary)value).DecodeInternal(reader, false);
                    }
                }
                else
                {
                    value = BEncodedValue.Decode(reader);                     // the value is a BEncoded value
                }

                torrent.dictionary.Add(key, value);
            }

            if (reader.ReadByte() != 'e')
            {
                throw new BEncodingException("Invalid data found. Aborting");
            }

            return(torrent);
        }
        /// <summary>
        /// Decodes a BEncodedList from the given StreamReader
        /// </summary>
        /// <param name="reader">The reader.</param>
        internal override void DecodeInternal(RawReader reader)
        {
            reader.CannotBeNull();

            if (reader.ReadByte() != 'l')
            {
                throw new BEncodingException("Invalid data found. Aborting");
            }

            while (reader.PeekByte() != -1 &&
                   reader.PeekByte() != 'e')
            {
                this.list.Add(BEncodedValue.Decode(reader));
            }

            if (reader.ReadByte() != 'e')
            {
                throw new BEncodingException("Invalid data found. Aborting");
            }
        }
예제 #4
0
        /// <summary>
        /// Decode BEncoded data in the given RawReader
        /// </summary>
        /// <param name="reader">The RawReader containing the BEncoded data</param>
        /// <returns>BEncodedValue containing the data that was in the stream</returns>
        public static BEncodedValue Decode(RawReader reader)
        {
            reader.CannotBeNull();

            BEncodedValue data;
            int           peekByte = reader.PeekByte();

            if (peekByte == 'i')
            {
                // integer
                data = new BEncodedNumber();
                data.DecodeInternal(reader);

                return(data);
            }
            else if (peekByte == 'd')
            {
                // dictionary
                data = new BEncodedDictionary();
                data.DecodeInternal(reader);

                return(data);
            }
            else if (peekByte == 'l')
            {
                // list
                data = new BEncodedList();
                data.DecodeInternal(reader);

                return(data);
            }
            else if (peekByte == '0' ||
                     peekByte == '1' ||
                     peekByte == '2' ||
                     peekByte == '3' ||
                     peekByte == '4' ||
                     peekByte == '5' ||
                     peekByte == '6' ||
                     peekByte == '7' ||
                     peekByte == '8' ||
                     peekByte == '9')
            {
                // string
                data = new BEncodedString();
                data.DecodeInternal(reader);

                return(data);
            }
            else
            {
                throw new BEncodingException("Could not find what value to decode.");
            }
        }
예제 #5
0
        /// <summary>
        /// Decodes a BEncoded number from the supplied RawReader
        /// </summary>
        /// <param name="reader">RawReader containing a BEncoded Number</param>
        internal override void DecodeInternal(RawReader reader)
        {
            reader.CannotBeNull();

            int sign = 1;
            int letter;

            if (reader.ReadByte() != 'i')
            {
                throw new BEncodingException("Invalid data found. Aborting.");
            }

            if (reader.PeekByte() == '-')
            {
                sign = -1;
                reader.ReadByte();
            }

            while ((letter = reader.PeekByte()) != -1 &&
                   letter != 'e')
            {
                if (letter < '0' ||
                    letter > '9')
                {
                    throw new BEncodingException("Invalid number found.");
                }

                this.number = (this.number * 10) + (letter - '0');

                reader.ReadByte();
            }

            if (reader.ReadByte() != 'e')
            {
                throw new BEncodingException("Invalid data found. Aborting.");
            }

            this.number *= sign;
        }
        /// <summary>
        /// Decodes the internal.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="strictDecoding">if set to <c>true</c> [strict decoding].</param>
        /// <exception cref="TorrentClient.BEncoding.BEncodingException">
        /// Invalid data found. Aborting
        /// or
        /// or
        /// Invalid data found. Aborting
        /// </exception>
        private void DecodeInternal(RawReader reader, bool strictDecoding)
        {
            reader.CannotBeNull();

            BEncodedString key    = null;
            BEncodedValue  value  = null;
            BEncodedString oldkey = null;

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

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

                if (oldkey != null &&
                    oldkey.CompareTo(key) > 0)
                {
                    if (strictDecoding)
                    {
                        throw new BEncodingException($"Illegal BEncodedDictionary. The attributes are not ordered correctly. Old key: {oldkey}, New key: {key}");
                    }
                }

                oldkey = key;
                value  = BEncodedValue.Decode(reader);                    // the value is a BEncoded value
                this.dictionary.Add(key, value);
            }

            if (reader.ReadByte() != 'e')
            {
                throw new BEncodingException("Invalid data found. Aborting");
            }
        }