/* */ #include "TrackerUpdateCommand.h" #include "LogFactory.h" #include "DlAbortEx.h" #include "message.h" #include "PeerInitiateConnectionCommand.h" #include "SleepCommand.h" #include "Util.h" extern PeerHandle nullPeer; TrackerUpdateCommand::TrackerUpdateCommand(int cuid, TorrentDownloadEngine* e, const BtContextHandle& btContext): BtContextAwareCommand(cuid, btContext), e(e) { logger = LogFactory::getInstance(); } TrackerUpdateCommand::~TrackerUpdateCommand() {} bool TrackerUpdateCommand::prepareForRetry() { e->commands.push_back(this); return false; } char* TrackerUpdateCommand::getTrackerResponse(size_t& trackerResponseLength) { int maxBufLength = 2048; char* buf = new char[maxBufLength]; int bufLength = 0; char data[2048]; try { while(1) { int dataLength = e->segmentMan->diskWriter->readData(data, sizeof(data), bufLength); if(bufLength+dataLength >= maxBufLength) { maxBufLength = Util::expandBuffer(&buf, bufLength, bufLength+dataLength); } memcpy(buf+bufLength, data, dataLength); bufLength += dataLength; if(dataLength != sizeof(data)) { break; } } trackerResponseLength = bufLength; return buf; } catch(Exception* e) { delete [] buf; throw; } } bool TrackerUpdateCommand::execute() { if(e->segmentMan->errors > 0 && btRuntime->isHalt()) { return true; } if(!e->segmentMan->finished()) { return prepareForRetry(); } char* trackerResponse = NULL; size_t trackerResponseLength = 0; try { trackerResponse = getTrackerResponse(trackerResponseLength); btAnnounce->processAnnounceResponse(trackerResponse, trackerResponseLength); while(!btRuntime->isHalt() && btRuntime->lessThanMinPeer()) { PeerHandle peer = peerStorage->getUnusedPeer(); if(peer == nullPeer) { break; } int newCuid = btRuntime->getNewCuid(); peer->cuid = newCuid; PeerInitiateConnectionCommand* command = new PeerInitiateConnectionCommand(newCuid, peer, e, btContext); e->commands.push_back(command); logger->debug("CUID#%d - Adding new command CUID#%d", cuid, newCuid); } btAnnounce->announceSuccess(); btAnnounce->resetAnnounce(); e->segmentMan->init(); } catch(Exception* err) { logger->error("CUID#%d - Error occurred while processing tracker response.", cuid, err); e->segmentMan->errors++; delete err; } if(trackerResponse) { delete [] trackerResponse; } if(btRuntime->isHalt()) { return true; } else { return prepareForRetry(); } }