Пример #1
0
 public static bool TryDecode(byte[] value, out BEncodedDictionary bencodedDictionary)
 {
     try
     {
         bencodedDictionary = Decode(value);
     }
     catch (Exception e)
     {
         bencodedDictionary = null;
         return false;
     }
     return true;
 }
Пример #2
0
        /// <summary>
        /// Decodes the specified reader.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="encoding">The encoding.</param>
        /// <returns></returns>
        internal static BEncodedDictionary Decode(BinaryReader reader, Encoding encoding)
        {
            if (encoding == null) throw new ArgumentNullException("encoding");
            if (!reader.BaseStream.CanSeek) throw new NotSupportedException("Cannot decode non-seekable streams");

            // Decoded key
            BEncodedString key;
            // Buffer for key decoding
            BEncodedString keyBuffer;
            // Decoded Value
            IBEncodedValue value;
            // BEncodedDictionary containing KeyValueParis
            BEncodedDictionary dictionary = new BEncodedDictionary(encoding);
            // Preview next character in the stream

            int peek = reader.PeekChar();

            if (peek == -1)
                throw BEncodedFormatDecodeException.CreateTraced("Unexpected end of dictionary", reader.BaseStream);

            char peekChar = (char)peek;

            // Ensure the current stream position represents a BEncodedDictionary
            if (peekChar == BEncodingSettings.DictionaryStart)
            {
                // Seek past the BEncoded.DictionaryStart field
                reader.ReadChar();
                // Preview the next character in the stream, this should represent a constituent IBEncodedValue
                peekChar = (char)reader.PeekChar();
                // Set the key to null before the first key value pair is decoded, necessary for lexographical comparison
                key = null;

                // Decode all constituent IBEncodedValues until the BEncoded.DictionaryEnd field is reached
                while (peekChar != BEncodingSettings.DictionaryEnd)
                {
                    try
                    {
                        // Try to parse a BEncodedString key
                        keyBuffer = BEncodedString.Decode(reader, encoding);
                    }
                    catch (BEncodedFormatDecodeException e)
                    {
                        throw BEncodedFormatDecodeException.CreateTraced("Failed to read dictionary key", e, reader.BaseStream);
                    }

                    // Check whether the key has appeared in lexographical order by comparing keyBuffer with the previous key, if present
                    if (key == null || keyBuffer.Value.CompareTo(key.Value) >= 0)
                    {
                        // keyBuffer has appeared in valid lexical order
                        key = keyBuffer;
                    }
                    else if (BEncodingSettings.ParserMode == BEncodingParserMode.Loose)
                    {
                        // The key, keyBuffer is not in lexographical order, ie. belongs somewhere before the former key
                        key = keyBuffer;
                    }
                    else
                    {
                        throw BEncodedFormatDecodeException.CreateTraced("Dictionary keys must be ordered lexographically in strict mode", reader.BaseStream);
                    }

                    // Preview next character in the stream, this should represent an IBEncodedValue following the key
                    peekChar = (char)reader.PeekChar();

                    // Attempt to decode the value
                    try
                    {
                        switch (peekChar)
                        {
                            case BEncodingSettings.DictionaryStart:
                                value = BEncodedDictionary.Decode(reader, (Encoding)encoding.Clone());
                                break;
                            case BEncodingSettings.ListStart:
                                value = BEncodedList.Decode(reader, (Encoding)encoding.Clone());
                                break;
                            case BEncodingSettings.IntegerStart:
                                value = BEncodedInteger.Decode(reader);
                                break;
                            default:
                                // Capture BEncodedStrigns beginning with numeric characters
                                if (Array.IndexOf(BEncodingSettings.NumericMask, peekChar) != -1)
                                {
                                    value = BEncodedString.Decode(reader, (Encoding)encoding.Clone());
                                }
                                else
                                {
                                    // Unrecognised token encountered
                                    throw BEncodedFormatDecodeException.CreateTraced("Unrecognised dictionary element encountered", reader.BaseStream);
                                }
                                break;
                        }

                        // Add key and value to the dictionary

                        if (BEncodingSettings.ParserMode == BEncodingParserMode.Loose)
                        {
                            if(!dictionary.ContainsKey(key))
                                dictionary.Add(key, value);

                            // Discard duplicate key in loose mode
                        }
                        else
                        {
                            dictionary.Add(key, value);
                        }
                    }
                    catch (ArgumentException e)
                    {
                        // Decoding the value has failed
                        throw BEncodedFormatDecodeException.CreateTraced("Failed to decode dictionary value", e, reader.BaseStream);
                    }

                    // Preview next character in the stream
                    peekChar = (char)reader.PeekChar();
                }

                // Stream position is currently at the BEncoded.DictionaryEnd field, seek past the field in order to complete decoding
                reader.ReadChar();
                // Return the decoded dictionary
                return dictionary;
            }
            else
            {
                // The stream does not contain a valid BEncodedDictionary at the current position
                throw BEncodedFormatDecodeException.CreateTraced("Expected dictionary start token", reader.BaseStream);
            }
        }
Пример #3
0
        /// <summary>
        /// Tries to decode the specified reader.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="encoding">The encoding.</param>
        /// <param name="bencodedDictionary">The bencoded dictionary.</param>
        /// <returns></returns>
        internal static bool TryDecode(BinaryReader reader, Encoding encoding, out BEncodedDictionary bencodedDictionary)
        {
            bencodedDictionary = null;

            try
            {
                bencodedDictionary = Decode(reader, encoding);
            }
            catch (Exception e)
            {
                return false;
            }

            return true;
        }
Пример #4
0
 public static bool TryDecode(Stream value, Encoding encoding, out BEncodedDictionary bencodedDictionary)
 {
     try
     {
         bencodedDictionary = Decode(value, encoding);
     }
     catch (Exception e)
     {
         bencodedDictionary = null;
         return false;
     }
     return true;
 }