/// <summary>
        /// Decodes a BEncodedList from the given StreamReader
        /// </summary>
        /// <param name="reader"></param>
        internal override void DecodeInternal(RawReader reader)
        {
            try
            {
                if (reader.ReadByte() != 'l')                            // Remove the leading 'l'
                {
                    throw new BEncodingException("Invalid data found. Aborting");
                }

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

                if (reader.ReadByte() != 'e')                            // Remove the trailing 'e'
                {
                    throw new BEncodingException("Invalid data found. Aborting");
                }
            }
            catch (BEncodingException ex)
            {
                throw new BEncodingException("Couldn't decode list", ex);
            }
            catch
            {
                throw new BEncodingException("Couldn't decode list");
            }
        }
예제 #2
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)
        {
            var sign = 1;

            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }

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

                if (reader.PeekChar() == '-')
                {
                    sign = -1;
                    reader.ReadChar();
                }

                int letter;
                while (((letter = reader.PeekChar()) != -1) && letter != 'e')
                {
                    if (letter < '0' || letter > '9')
                    {
                        throw new BEncodingException("Invalid number found.");
                    }
                    number = number * 10 + (letter - '0');
                    reader.ReadChar();
                }
                if (reader.ReadByte() != 'e')                 //remove the trailing 'e'
                {
                    throw new BEncodingException("Invalid data found. Aborting.");
                }

                number *= sign;
            }
            catch (BEncodingException ex)
            {
                throw new BEncodingException("Couldn't decode number", ex);
            }
            catch
            {
                throw new BEncodingException("Couldn't decode number");
            }
        }
예제 #3
0
        /// <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>
        /// <returns></returns>
        public static BEncodedDictionary DecodeTorrent(RawReader reader)
        {
            BEncodedString key     = null;
            BEncodedValue  value   = null;
            var            torrent = new BEncodedDictionary();

            try
            {
                if (reader.ReadByte() != 'd')
                {
                    throw new BEncodingException("Invalid data found. Aborting");                                           // Remove the leading 'd'
                }
                while ((reader.PeekChar() != -1) && ((char)reader.PeekChar() != 'e'))
                {
                    key = (BEncodedString)Decode(reader);                     // keys have to be BEncoded strings

                    if (reader.PeekChar() == 'd')
                    {
                        value = new BEncodedDictionary();
                        if (key.Text.ToLower().Equals("info"))
                        {
                            ((BEncodedDictionary)value).DecodeInternal(reader, true);
                        }
                        else
                        {
                            ((BEncodedDictionary)value).DecodeInternal(reader, false);
                        }
                    }
                    else
                    {
                        value = Decode(reader);                      // the value is a BEncoded value
                    }
                    torrent.dictionary.Add(key, value);
                }

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

                return(torrent);
            }
            catch (Exception ex)
            {
                throw new BEncodingException("Couldn't decode dictionary", ex);
            }
        }
예제 #4
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)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }

            int letterCount;
            var length = string.Empty;

            try
            {
                while ((reader.PeekChar() != -1) && (reader.PeekChar() != ':')) // read in how many characters
                {
                    length += (char)reader.ReadChar();                          // the string is
                }
                if (reader.ReadChar() != ':')                                   // remove the ':'
                {
                    throw new BEncodingException("Invalid data found. Aborting");
                }

                if (!int.TryParse(length, out letterCount))
                {
                    throw new BEncodingException(string.Format("Invalid BEncodedString. Length was '{0}' instead of a number", length));
                }

                textBytes = new byte[letterCount];
                if (reader.Read(textBytes, 0, letterCount) != letterCount)
                {
                    throw new BEncodingException("Couldn't decode string");
                }
            }
            catch (Exception ex)
            {
                if (ex is BEncodingException)
                {
                    throw;
                }
                else
                {
                    throw new BEncodingException("Couldn't decode string", ex);
                }
            }
        }
예제 #5
0
        void DecodeInternal(RawReader reader, bool strictDecoding)
        {
            BEncodedString key    = null;
            BEncodedValue  value  = null;
            BEncodedString oldkey = null;

            try
            {
                if (reader.ReadByte() != 'd')
                {
                    throw new BEncodingException("Invalid data found. Aborting");                                           // Remove the leading 'd'
                }
                while ((reader.PeekChar() != -1) && ((char)reader.PeekChar() != 'e'))
                {
                    key = (BEncodedString)Decode(reader);                     // keys have to be BEncoded strings

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

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

                if (reader.ReadByte() != 'e')                 // remove the trailing 'e'
                {
                    throw new BEncodingException("Invalid data found. Aborting");
                }
            }
            catch (Exception ex)
            {
                throw new BEncodingException("Couldn't decode dictionary", ex);
            }
        }
        /// <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)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }

            BEncodedValue data;

            switch ((char)reader.PeekChar())
            {
            case ('i'):                             // Integer
                data = new BEncodedNumber();
                break;

            case ('d'):                             // Dictionary
                data = new BEncodedDictionary();
                break;

            case ('l'):                             // List
                data = new BEncodedList();
                break;

            case ('1'):                             // String
            case ('2'):
            case ('3'):
            case ('4'):
            case ('5'):
            case ('6'):
            case ('7'):
            case ('8'):
            case ('9'):
            case ('0'):
                data = new BEncodedString();
                break;

            default:
                throw new BEncodingException("Could not find what value to decode");
            }

            data.DecodeInternal(reader);
            return(data);
        }