/// <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); }
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; } }
/// <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); }
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"; } }
/// <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); }