Пример #1
0
        /// <summary>
        /// Get the single file mode meta information
        /// </summary>
        /// <param name="rootNode">the root node of torrent</param>
        /// <param name="infoNode">the info node of torrent</param>
        /// <returns>Return the single file mode meta information</returns>
        private static SingleFileMetaInfo GetSingleFileMetaInfo(DictNode rootNode, DictNode infoNode)
        {
            SingleFileMetaInfo result = new SingleFileMetaInfo();

            DecodeRootNode(result, rootNode);
            DecodeInfoNode(result, infoNode);

            BytesNode nameNode = infoNode["name"] as BytesNode;

            Debug.Assert(nameNode != null);
            result.Name = nameNode.StringText;

            IntNode lengthNode = infoNode["length"] as IntNode;

            Debug.Assert(lengthNode != null);
            result.Length = lengthNode.Value;

            if (infoNode.ContainsKey("md5sum"))
            {
                BytesNode md5SumNode = infoNode["md5sum"] as BytesNode;
                Debug.Assert(md5SumNode != null);
                result.Md5Sum = md5SumNode.StringText;
            }
            else
            {
                result.Md5Sum = String.Empty;
            }

            return(result);
        }
Пример #2
0
        /// <summary>
        /// Node字典类的解码函数
        /// </summary>
        /// <param name="source">待解码的字节数组</param>
        /// <param name="index">字节数组的解码位置</param>
        /// <returns>解码的字节数组长度</returns>
        public override int Decode(byte[] source, ref int index)
        {
            //保存初始位置
            int start = index;

            //跳过字符'd'
            index++;

            try
            {
                //当遇到'e'(ASCII码为101),解析结束
                while (source[index] != 101)
                {
                    //解析字符串
                    BytesNode keyNode = new BytesNode();
                    keyNode.Decode(source, ref index);
                    if (keyNode.ByteArray.LongLength == 0)
                    {
                        throw new BitTorrentException("待添加的字符串长度为0");
                    }

                    //解析Handler
                    BEncodedNode valueNode = BEncodingFactory.Decode(source, ref index);

                    //'e'(ASCII码为101),解析结束
                    if (valueNode == null)
                    {
                        throw new BitTorrentException("待添加的Handler节点为空");
                    }

                    //字典添加key和value
                    _dict.Add(keyNode.StringText, valueNode);
                }
            }

            //当捕捉IndexOutOfRangeException,抛出BitTorrentException
            catch (IndexOutOfRangeException)
            {
                throw new BitTorrentException("BEncode字典类的字符串长度异常");
            }

            //当捕捉ArgumentException,抛出BitTorrentException
            catch (ArgumentException)
            {
                throw new BitTorrentException("BEncode字典类中包含相同的字符串关键字");
            }

            //跳过字符'e'
            index++;

            //返回所解析的数组长度
            return(index - start);
        }
Пример #3
0
        /// <summary>
        /// Handler字典类的编码函数
        /// </summary>
        /// <param name="ms">待编码的内存写入流</param>
        public override void Encode(MemoryStream ms)
        {
            //向内存流写入'd'(ASCII码为100)
            ms.WriteByte(100);

            //对于每一个node进行编码
            foreach (string key in _dict.Keys)
            {
                BytesNode keyNode = new BytesNode(key, Encoding.UTF8);
                keyNode.Encode(ms);
                _dict[key].Encode(ms);
            }

            //向内存流写入'e'(ASCII码为101)
            ms.WriteByte(101);
        }
Пример #4
0
        private static void DecodeInfoNode(MetaInfo metaInfo, DictNode infoNode)
        {
            IntNode pieceLengthNode = infoNode["piece length"] as IntNode;

            Debug.Assert(pieceLengthNode != null);
            metaInfo.PieceLength = pieceLengthNode.IntValue;

            BytesNode piecesNode = infoNode["pieces"] as BytesNode;

            Debug.Assert(piecesNode != null);
            metaInfo.SetFullHashValues(piecesNode.ByteArray);

            if (infoNode.ContainsKey("private"))
            {
                IntNode privateNode = infoNode["private"] as IntNode;
                Debug.Assert(privateNode != null);
                metaInfo.Private = privateNode.Value == 1;
            }
        }
Пример #5
0
        /// <summary>
        /// 解码函数,不带错误判断
        /// </summary>
        /// <param name="source">待解码的字节数组</param>
        /// <param name="position">字节数组的位置</param>
        /// <returns>返回Handler基类类型</returns>
        public static BEncodedNode Decode(byte[] source, ref int position)
        {
            byte b = source[position];

            BEncodedNode interpreter;

            //如果source[position]等于'l'(ASCII码为108),就返回ListHandler
            if (b == 108)
            {
                interpreter = new ListNode();
            }

            //如果source[position]等于'd'(ASCII码为100),就返回DictionaryHandler
            else if (b == 100)
            {
                interpreter = new DictNode();
            }

            //如果source[position]等于'index'(ASCII码为105),就返回IntHandler
            else if (b == 105)
            {
                interpreter = new IntNode();
            }

            //如果source[position]等于'0' - '9'(ASCII码为48 - 57),就返回ByteArrayHandler
            else if (b >= 48 && b <= 57)
            {
                interpreter = new BytesNode();
            }

            //其它的情况,抛出异常
            else
            {
                throw new BitTorrentException("待解码的字节数组的首位字节异常");
            }

            interpreter.Decode(source, ref position);
            return(interpreter);
        }
Пример #6
0
        private static void DecodeRootNode(MetaInfo metaInfo, DictNode rootNode)
        {
            BytesNode annouceNode = rootNode["announce"] as BytesNode;

            Debug.Assert(annouceNode != null);
            metaInfo.Announce = annouceNode.StringText;

            if (rootNode.ContainsKey("announce-list"))
            {
                ListNode announceListNode = rootNode["announce-list"] as ListNode;
                Debug.Assert(announceListNode != null);
                foreach (ListNode announceArrayNode in announceListNode)
                {
                    Debug.Assert(announceArrayNode != null);
                    IList <string> announceArray = new List <string>();
                    foreach (BytesNode node in announceArrayNode)
                    {
                        Debug.Assert(node != null);
                        announceArray.Add(node.StringText);
                    }
                    metaInfo.AddAnnounceArray(announceArray);
                }
            }

            if (rootNode.ContainsKey("creation date"))
            {
                IntNode creationDataNode = rootNode["creation date"] as IntNode;
                Debug.Assert(creationDataNode != null);
                metaInfo.CreationDate = creationDataNode.Value.FromUnixEpochFormat();
            }
            else
            {
                metaInfo.CreationDate = new DateTime(1970, 1, 1);
            }

            if (rootNode.ContainsKey("comment"))
            {
                BytesNode commentNode = rootNode["comment"] as BytesNode;
                Debug.Assert(commentNode != null);
                metaInfo.Comment = commentNode.StringText;
            }
            else
            {
                metaInfo.Comment = String.Empty;
            }

            if (rootNode.ContainsKey("created by"))
            {
                BytesNode createdByNode = rootNode["created by"] as BytesNode;
                Debug.Assert(createdByNode != null);
                metaInfo.CreatedBy = createdByNode.StringText;
            }
            else
            {
                metaInfo.CreatedBy = String.Empty;
            }

            if (rootNode.ContainsKey("encoding"))
            {
                BytesNode encodingNode = rootNode["encoding"] as BytesNode;
                Debug.Assert(encodingNode != null);
                metaInfo.Encoding = encodingNode.StringText;
            }
            else
            {
                metaInfo.Encoding = "ASCII";
            }
        }
Пример #7
0
        /// <summary>
        /// Get the multi file mode meta information
        /// </summary>
        /// <param name="rootNode">the root node of torrent</param>
        /// <param name="infoNode">the info node of torrent</param>
        /// <returns>Return the multi file mode meta information</returns>
        private static MultiFileMetaInfo GetMultiFileMetaInfo(DictNode rootNode, DictNode infoNode)
        {
            MultiFileMetaInfo result = new MultiFileMetaInfo();

            DecodeRootNode(result, rootNode);
            DecodeInfoNode(result, infoNode);

            BytesNode nameNode = infoNode["name"] as BytesNode;

            Debug.Assert(nameNode != null);
            result.Name = nameNode.StringText;

            ListNode filesNode = infoNode["files"] as ListNode;

            Debug.Assert(filesNode != null);
            long begin = 0;

            FileInfo[] fileInfoArray = new FileInfo[filesNode.Count];
            for (int i = 0; i < filesNode.Count; i++)
            {
                DictNode node = filesNode[i] as DictNode;

                IntNode lengthNode = node["length"] as IntNode;
                Debug.Assert(lengthNode != null);
                FileInfo fileInfo = new FileInfo();
                fileInfo.Length = lengthNode.Value;
                fileInfo.Begin  = begin;
                fileInfo.End    = begin + fileInfo.Length;
                begin           = fileInfo.End;

                ListNode pathNode = node["path"] as ListNode;
                Debug.Assert(pathNode != null);
                StringBuilder sb = new StringBuilder();

                BytesNode firstPathNode = pathNode[0] as BytesNode;
                Debug.Assert(firstPathNode != null);
                sb.Append(firstPathNode.StringText);

                for (int j = 1; j < pathNode.Count; j++)
                {
                    BytesNode subPathNode = pathNode[j] as BytesNode;
                    Debug.Assert(subPathNode != null);
                    sb.AppendFormat(@"\{0}", subPathNode.StringText);
                }

                fileInfo.Path = sb.ToString();

                if (!node.ContainsKey("md5sum"))
                {
                    fileInfo.Md5Sum = String.Empty;
                }
                else
                {
                    BytesNode md5SumNode = node["md5sum"] as BytesNode;
                    Debug.Assert(md5SumNode != null);
                    fileInfo.Md5Sum = md5SumNode.StringText;
                }

                fileInfoArray[i] = fileInfo;
            }

            result.SetFileInfoArray(fileInfoArray);

            return(result);
        }