/// <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 DecodeMetadata(RawReader reader) { BEncodedDictionary metadata = new BEncodedDictionary(); if (reader.ReadByte() != 'd') { throw new BEncodingException("Invalid data found. Aborting"); // Remove the leading 'd' } while ((reader.PeekByte() != -1) && (reader.PeekByte() != 'e')) { BEncodedString key = (BEncodedString)Decode(reader); BEncodedValue value; if (reader.PeekByte() == 'd') { value = new BEncodedDictionary(); ((BEncodedDictionary)value).DecodeInternal(reader, key.Text.ToLower().Equals("info")); } else { value = Decode(reader); // the value is a BEncoded value } metadata._dictionary.Add(key, value); } if (reader.ReadByte() != 'e') // remove the trailing 'e' { throw new BEncodingException("Invalid data found. Aborting"); } return(metadata); }
private void DecodeInternal(RawReader reader, bool strictDecoding) { 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')) { BEncodedString key = (BEncodedString)Decode(reader); 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; BEncodedValue value = Decode(reader); _dictionary.Add(key, value); } if (reader.ReadByte() != 'e') // remove the trailing 'e' { throw new BEncodingException("Invalid data found. Aborting"); } }
/// <summary> /// Decodes a BEncodedString from the supplied StreamReader /// </summary> /// <param name="reader">The StreamReader containing the BEncodedString</param> protected override void DecodeInternal(RawReader reader) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } int letterCount; string length = string.Empty; while ((reader.PeekByte() != -1) && (reader.PeekByte() != ':')) // read in how many characters { length += (char)reader.ReadByte(); // the string is } if (reader.ReadByte() != ':') // 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"); } }
/// <summary> /// Decodes a BEncodedList from the given StreamReader /// </summary> /// <param name="reader"></param> protected override void DecodeInternal(RawReader reader) { if (reader.ReadByte() != 'l') // Remove the leading 'l' { throw new BEncodingException("Invalid data found. Aborting"); } while ((reader.PeekByte() != -1) && (reader.PeekByte() != 'e')) { _list.Add(Decode(reader)); } if (reader.ReadByte() != 'e') // Remove the trailing 'e' { throw new BEncodingException("Invalid data found. Aborting"); } }
/// <summary> /// Decodes a BEncoded number from the supplied RawReader /// </summary> /// <param name="reader">RawReader containing a BEncoded Number</param> protected override void DecodeInternal(RawReader reader) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } if (reader.ReadByte() != 'i') // remove the leading 'i' { throw new BEncodingException("Invalid data found. Aborting."); } int sign = 1; if (reader.PeekByte() == '-') { sign = -1; reader.ReadByte(); } int letter; while (((letter = reader.PeekByte()) != -1) && (letter != 'e')) { if ((letter < '0') || (letter > '9')) { throw new BEncodingException("Invalid number found."); } Number = Number * 10 + (letter - '0'); reader.ReadByte(); } if (reader.ReadByte() != 'e') //remove the trailing 'e' { throw new BEncodingException("Invalid data found. Aborting."); } Number *= sign; }