Example #1
0
 public static IBObject GetInstance(IDictionary<String, String> attributes)
 {
     IBObject obj;
     switch (attributes["class"])
     {
         case "NSArray":
         case "NSMutableArray":
             obj = new IBArray(attributes);
             break;
         case "NSDictionary":
         case "NSMutableDictionary":
             obj = new IBDictionary(attributes);
             break;
         case "IBClassDescriber":
             obj = new IBClassDescriber(attributes);
             break;
         case "IBPartialClassDescription":
             obj = new IBPartialClassDescription(attributes);
             break;
         case "NSSet":
         case "NSMutableSet":
             obj = new IBSet(attributes);
             break;
         default:
             obj = new IBObject(attributes);
             break;
     }
     return obj;
 }
        private static void SetupBencodeParser(IBencodeParser bparser, string bencode, BString key, IBObject value, bool hasEndChar)
        {
            bparser.Parse<BString>(Arg.Any<BencodeStream>())
                .Returns(key);

            bparser.Parse(Arg.Any<BencodeStream>())
                .Returns(value)
                .AndDoes(x =>
                {
                    // Set stream position to end of list, skipping all "parsed" content
                    var stream = x.Arg<BencodeStream>();
                    stream.Position += Math.Max(1, bencode.Length - 1);

                    if (hasEndChar) stream.Position--;
                });
        }
Example #3
0
 public void WriteObject(int indentLevel, IBObject obj)
 {
     switch(obj.BType)
     {
         case BObjectType.Integer:
             WriteInteger(indentLevel, (BInteger)obj);
             break;
         case BObjectType.ByteString:
             WriteByteString(indentLevel, (BByteString)obj);
             break;
         case BObjectType.List:
             WriteList(indentLevel, (BList)obj);
             break;
         case BObjectType.Dictionary:
             WriteDictionary(indentLevel, (BDictionary)obj);
             break;
     }
 }
Example #4
0
        internal TrackerResponse(BDictionary dictionary)
        {
            FailureReason  = ((BString)dictionary["failure reason"])?.ToString();
            WarningMessage = ((BString)dictionary["warning message"])?.ToString();
            Interval       = (int?)((BNumber)dictionary["interval"])?.Value;
            MinInterval    = (int?)((BNumber)dictionary["min interval"])?.Value;
            TrackerId      = ((BString)dictionary["tracker id"])?.ToString();
            Complete       = (int?)((BNumber)dictionary["complete"])?.Value;
            InComplete     = (int?)((BNumber)dictionary["incomplete"])?.Value;

            IBObject peersObject = dictionary["peers"];

            if (peersObject == null)
            {
                return;
            }

            List <PeerInfo> peers = new List <PeerInfo>();

            Peers = peers;

            if (peersObject is BString)
            {
                IReadOnlyList <byte> data = ((BString)peersObject).Value;

                for (int i = 0; i < data.Count; i += 6)
                {
                    string ip   = $"{data[i]}.{data[i + 1]}.{data[i + 2]}.{data[i + 3]}";
                    int    port = (data[i + 5] << 8) + data[i + 4];
                    peers.Add(new PeerInfo(null, ip, port));
                }
            }
            else
            {
                BList <BDictionary> data = (BList <BDictionary>)peersObject;
                foreach (BDictionary obj in data)
                {
                    string id   = ((BString)obj["peer id"]).ToString();
                    string ip   = ((BString)obj["ip"]).ToString();
                    int    port = (int)((BNumber)obj["port"]).Value;
                    peers.Add(new PeerInfo(id, ip, port));
                }
            }
        }
        public void Test_BencodeParser_class()
        {
            BencodeParser parser = new BencodeParser();

            Assert.IsNotNull(parser);

            IBObject bObj = parser.Parse("i12345e");

            Assert.IsInstanceOf <BNumber>(bObj);
            Assert.AreEqual(12345, ((BNumber)bObj).Value);

            bObj = parser.Parse("4:test");
            Assert.IsInstanceOf <BString>(bObj);
            Assert.AreEqual("test", ((BString)bObj).ToString());

            bObj = parser.Parse("l4:testi1234ee");
            Assert.IsInstanceOf <BList>(bObj);

            bObj = parser.Parse("d6:numberi1234e3:str4:teste");
            Assert.IsInstanceOf <BDictionary>(bObj);
        }
Example #6
0
        // TODO: Unit tests
        private void FixEncoding(IBObject bobject, Encoding encoding)
        {
            var dictionary = bobject as BDictionary;

            if (dictionary != null)
            {
                FixEncodingInDictionary(dictionary, encoding);
            }

            var list = bobject as BList;

            if (list != null)
            {
                FixEncodingInList(list, encoding);
            }

            var value = bobject as BString;

            if (value != null)
            {
                value.Encoding = encoding;
            }
        }
Example #7
0
        static string GetTypeName(Dictionary <int, string> customTypeNames, IBObject obj)
        {
            string name = null;

            // First resolve custom classes. Seems Apple also uses these for some framework classes,
            // maybe for classes without direct desktop equivalents?
            if (obj != null && obj.Id.HasValue && customTypeNames != null)
            {
                customTypeNames.TryGetValue(obj.Id.Value, out name);
            }

            //else, try to handle the interface builder built-in types
            if (name == null && obj is UnknownIBObject)
            {
                string ibType = ((UnknownIBObject)obj).Class;
                if (ibType.StartsWith("NS"))
                {
                    name = ibType;
                }
                else if (ibType.StartsWith("IB") && ibType.Length > 2 && ibType != "IBUICustomObject")
                {
                    name = ibType.Substring(2);
                }
            }

            //now try to resolve the obj-c name to a fully qualified class
            if (name != null)
            {
                string resolvedName;
                if (typeNameMap.TryGetValue(name, out resolvedName))
                {
                    return(resolvedName);
                }
            }

            return(name);
        }
Example #8
0
 public void EncodeObject(IBObject obj, Stream outputStream)
 {
     if (obj.BType == BObjectType.Integer)
     {
         integerTransform.Encode((BInteger)obj, outputStream);
     }
     else if (obj.BType == BObjectType.ByteString)
     {
         byteStringTransform.Encode((BByteString)obj, outputStream);
     }
     else if (obj.BType == BObjectType.List)
     {
         listTransform.Encode((BList)obj, outputStream);
     }
     else if (obj.BType == BObjectType.Dictionary)
     {
         dictionaryTransform.Encode((BDictionary)obj, outputStream);
     }
 }
Example #9
0
        public void MissingEndChar_ThrowsInvalidBencodeExceptionAsync(string bencode, IBencodeParser bparser, IBObject something)
        {
            // Arrange
            bparser.ParseAsync(Arg.Any <PipeBencodeReader>())
            .Returns(something)
            .AndSkipsAheadAsync(bencode.Length - 1);

            // Act
            var         parser = new BListParser(bparser);
            Func <Task> action = async() => await parser.ParseStringAsync(bencode);

            // Assert
            action.Should().Throw <InvalidBencodeException <BList> >().WithMessage("*Missing end character of object*");
        }
        public void MissingEndChar_ThrowsInvalidBencodeException(string bencode, IBencodeParser bparser, BString someKey, IBObject someValue)
        {
            // Arrange
            bparser.Parse <BString>(Arg.Any <BencodeReader>())
            .Returns(someKey);

            bparser.Parse(Arg.Any <BencodeReader>())
            .Returns(someValue)
            .AndSkipsAhead(bencode.Length - 1);

            // Act
            var    parser = new BDictionaryParser(bparser);
            Action action = () => parser.ParseString(bencode);

            // Assert
            action.Should().Throw <InvalidBencodeException <BDictionary> >().WithMessage("*Missing end character of object*");
        }
 /// <summary>
 ///   Visits the specified item.
 /// </summary>
 /// <param Name = "item">The item.</param>
 public void Visit(IBObject item)
 {
 }
        private static void ExtractInfo(IBObject obj, TorrentMetadata file)
        {
            var  dict       = (BDictionary)obj;
            bool?singleFile = null;

            foreach (var item in dict)
            {
                var key = item.Key.ToString();
                switch (key)
                {
                case "length":
                    if (singleFile == false)
                    {
                        throw new DataMisalignedException("Torrent already have key \"files\" key");
                    }
                    singleFile = true;
                    var fname = string.Empty;
                    if (dict.TryGetValue("name", out IBObject nameVal))
                    {
                        fname = ((BString)nameVal).ToString();
                    }
                    file.Files.Add(fname, (BNumber)item.Value);
                    break;

                case "name":
                    break;

                case "files":
                    if (singleFile == true)
                    {
                        throw new DataMisalignedException("Torrent already have \"length\" key");
                    }
                    singleFile = false;
                    var dicLst = (BList)item.Value;
                    foreach (var dicListItem in dicLst)
                    {
                        var sdic = (BDictionary)dicListItem;
                        file.Files.Add(((BString)sdic["path"]).ToString(), (BNumber)sdic["length"]);
                    }
                    break;

                case "piece length":
                    file.PieceLength = (BNumber)item.Value;
                    break;

                case "pieces":
                    var shas = (BString)item.Value;
                    if (shas.Value.Count % 20 > 0)
                    {
                        throw new DataMisalignedException("SHA1 hash section is invalid");
                    }
                    var arr = shas.Value.ToArray();
                    for (var i = 0; i < shas.Value.Count / 20; i++)
                    {
                        var chunk = new byte[20];
                        Array.Copy(arr, i * 20, chunk, 0, 20);
                        file.SHAs.Add(chunk);
                    }
                    break;

                default:
                    file.Extensions.Add($"info.{item.Key}", item.Value);
                    break;
                }
            }
            if (singleFile == null)
            {
                throw new DataMisalignedException("Information about torrent contents was not found");
            }
        }
 /// <summary>
 ///   Visits the specified item.
 /// </summary>
 /// <param Name = "item">The item.</param>
 public void Visit(IBObject item)
 {
 }
Example #14
0
        public static bool TryParse(ReadOnlySpan <byte> data, out IBObject bObject, bool strictDictionaryOrder = true)
        {
            var             reader = new Utf8BEncodingReader(data);
            List <IBObject> stack  = null;

            bObject = null;
            BString key = null;

            while (reader.Read())
            {
                IBObject value;
                switch (reader.TokenType)
                {
                case BEncodingTokenType.String:
                    value = new BString(reader.ValueSpan);
                    break;

                case BEncodingTokenType.Integer:
                    if (!reader.TryGet(out BigInteger integer))
                    {
                        return(false);
                    }

                    value = new BInteger(integer);
                    break;

                case BEncodingTokenType.End:
                    if (stack is null || !(key is null))
                    {
                        return(false);
                    }

                    stack[stack.Count - 1].SpanEnd = reader.Consumed;

                    if (stack.Count == 1)
                    {
                        return(reader.IsEmpty);
                    }

                    Debug.Assert(stack.Count != 0);

                    stack.RemoveAt(stack.Count - 1);
                    continue;

                default:
                    Debug.Assert(reader.TokenType == BEncodingTokenType.StartDictionary || reader.TokenType == BEncodingTokenType.StartList);
                    value = reader.TokenType == BEncodingTokenType.StartDictionary
                            ? (IBObject) new BDictionary()
                            : (IBObject) new BList();

                    if (stack is null)
                    {
                        Debug.Assert(key is null);
                        stack   = new List <IBObject>(4);
                        bObject = value;
                        stack.Add(bObject);
                        continue;
                    }
                    else
                    {
                        if (stack.Count == BEncodingConstants.DepthMax)
                        {
                            return(false);
                        }
                        break;
                    }
                }

                if (stack is null)
                {
                    Debug.Assert(bObject is null && key is null);
                    Debug.Assert(reader.TokenType != BEncodingTokenType.StartDictionary);
                    Debug.Assert(reader.TokenType != BEncodingTokenType.StartList);
                    bObject = value;
                    return(reader.IsEmpty);
                }

                if (stack.Count == 0)
                {
                    return(false);
                }

                var top = stack[^ 1];
Example #15
0
 public static bool TryParse(string data, out IBObject bObject, bool strictDictionaryOrder = true)
 => TryParse(BEncodingHelpers.UTF8.GetBytes(data), out bObject, strictDictionaryOrder);
Example #16
0
 /// <summary>
 /// Encodes the object and returns the result as a string using <see cref="Encoding.UTF8"/>.
 /// </summary>
 /// <returns>The object bencoded and converted to a string using <see cref="Encoding.UTF8"/>.</returns>
 public static string EncodeAsString(this IBObject bobject) => EncodeAsString(bobject, Encoding.UTF8);
Example #17
0
 /// <summary>
 ///   Visits the specified item.
 /// </summary>
 /// <param Name = "item">The item.</param>
 public void Visit(IBObject item)
 {
     Console.WriteLine(item.ToString());
 }
Example #18
0
        private static void SetupBencodeParser(IBencodeParser bparser, string bencode, BString key, IBObject value, bool hasEndChar)
        {
            bparser.Parse <BString>(Arg.Any <BencodeStream>())
            .Returns(key);

            bparser.Parse(Arg.Any <BencodeStream>())
            .Returns(value)
            .AndDoes(x =>
            {
                // Set stream position to end of list, skipping all "parsed" content
                var stream       = x.Arg <BencodeStream>();
                stream.Position += Math.Max(1, bencode.Length - 1);

                if (hasEndChar)
                {
                    stream.Position--;
                }
            });
        }
Example #19
0
 /// <summary>
 ///   Visits the specified item.
 /// </summary>
 /// <param Name = "item">The item.</param>
 public void Visit(IBObject item)
 {
     Console.WriteLine(item.ToString());
 }