private void DecodeInternal(RawReader reader, bool strictDecoding) { 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(String.Format( // "Illegal BEncodedDictionary. The attributes are not ordered correctly. Old key: {0}, New key: {1}", // oldkey, key)); //oldkey = key; value = BEncodedValue.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"); } }
/// <summary> /// Decodes a BEncodedList from the given StreamReader /// </summary> /// <param name="reader"></param> internal 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(BEncodedValue.Decode(reader)); } if (reader.ReadByte() != 'e') // Remove the trailing 'e' { throw new BEncodingException("Invalid data found. Aborting"); } }
/// <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; 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') // remove the trailing 'e' { throw new BEncodingException("Invalid data found. Aborting"); } return(torrent); }
/// <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 (reader.PeekByte()) { 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(string.Format("Could not find what value to decode at {0}", reader.Position)); } data.DecodeInternal(reader); return data; }