/// <summary> /// Parses the next <see cref="BList"/> from the stream. /// </summary> /// <param name="stream">The stream to parse from.</param> /// <returns>The parsed <see cref="BList"/>.</returns> /// <exception cref="InvalidBencodeException{BList}">Invalid bencode</exception> public override BList Parse(BencodeStream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } if (stream.Length < MinimumLength) { throw InvalidBencodeException <BList> .BelowMinimumLength(MinimumLength, stream.Length, stream.Position); } // Lists must start with 'l' if (stream.ReadChar() != 'l') { throw InvalidBencodeException <BList> .UnexpectedChar('l', stream.ReadPreviousChar(), stream.Position); } var list = new BList(); // Loop until next character is the end character 'e' or end of stream while (stream.Peek() != 'e' && stream.Peek() != -1) { // Decode next object in stream var bObject = BencodeParser.Parse(stream); list.Add(bObject); } if (stream.ReadChar() != 'e') { if (stream.EndOfStream) { throw InvalidBencodeException <BList> .MissingEndChar(); } throw InvalidBencodeException <BList> .InvalidEndChar(stream.ReadPreviousChar(), stream.Position); } return(list); }
/// <summary> /// Parses the next <see cref="BDictionary"/> from the stream and its contained keys and values. /// </summary> /// <param name="stream">The stream to parse from.</param> /// <returns>The parsed <see cref="BDictionary"/>.</returns> /// <exception cref="InvalidBencodeException{BDictionary}">Invalid bencode</exception> public override BDictionary Parse(BencodeStream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } var startPosition = stream.Position; if (stream.Length < MinimumLength) { throw InvalidBencodeException <BDictionary> .BelowMinimumLength(MinimumLength, stream.Length, startPosition); } // Dictionaries must start with 'd' if (stream.ReadChar() != 'd') { throw InvalidBencodeException <BDictionary> .UnexpectedChar('d', stream.ReadPreviousChar(), startPosition); } var dictionary = new BDictionary(); // Loop until next character is the end character 'e' or end of stream while (stream.Peek() != 'e' && stream.Peek() != -1) { BString key; try { // Decode next string in stream as the key key = BencodeParser.Parse <BString>(stream); } catch (BencodeException <BString> ex) { throw InvalidException("Could not parse dictionary key. Keys must be strings.", ex, startPosition); } IBObject value; try { // Decode next object in stream as the value value = BencodeParser.Parse(stream); } catch (BencodeException ex) { throw InvalidException( string.Format("Could not parse dictionary value for the key '{0}'. There needs to be a value for each key.", key), ex, startPosition); } if (dictionary.ContainsKey(key)) { throw InvalidException( string.Format("The dictionary already contains the key '{0}'. Duplicate keys are not supported.", key), startPosition); } dictionary.Add(key, value); } if (stream.ReadChar() != 'e') { if (stream.EndOfStream) { throw InvalidBencodeException <BDictionary> .MissingEndChar(); } throw InvalidBencodeException <BDictionary> .InvalidEndChar(stream.ReadPreviousChar(), stream.Position); } return(dictionary); }