/* */ #ifndef _D_PEER_LIST_PROCESSOR_H_ #define _D_PEER_LIST_PROCESSOR_H_ #include "common.h" #include #include "a2netcompat.h" #include "bencode.h" #include "Peer.h" namespace aria2 { class PeerListProcessor { public: template void extractPeer(const BDE& peerData, OutputIterator dest) { if(peerData.isList()) { extractPeerFromList(peerData, dest); } else if(peerData.isString()) { extractPeerFromCompact(peerData, dest); } } template void extractPeerFromList(const BDE& peerData, OutputIterator dest) { for(BDE::List::const_iterator itr = peerData.listBegin(), eoi = peerData.listEnd(); itr != eoi; ++itr) { const BDE& peerDict = *itr; if(!peerDict.isDict()) { continue; } static const std::string IP = "ip"; static const std::string PORT = "port"; const BDE& ip = peerDict[IP]; const BDE& port = peerDict[PORT]; if(!ip.isString() || !port.isInteger() || !(0 < port.i() && port.i() < 65536)) { continue; } *dest = SharedHandle(new Peer(ip.s(), port.i())); ++dest; } } template void extractPeerFromCompact(const BDE& peerData, OutputIterator dest) { size_t length = peerData.s().size(); if(length%6 == 0) { for(size_t i = 0; i < length; i += 6) { struct in_addr in; memcpy(&in.s_addr, peerData.s().c_str()+i, sizeof(uint32_t)); std::string ipaddr = inet_ntoa(in); uint16_t port_nworder; memcpy(&port_nworder, peerData.s().c_str()+i+4, sizeof(uint16_t)); uint16_t port = ntohs(port_nworder); *dest = SharedHandle(new Peer(ipaddr, port)); ++dest; } } } }; } // namespace aria2 #endif // _D_PEER_LIST_PROCESSOR_H_