⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 queuectrl.cpp

📁 一个FTP下载的源代码。代码质量非常高
💻 CPP
📖 第 1 页 / 共 5 页
字号:
				COptions::SetKey(key2, "Localfile", queueData.transferFile.localfile);
				COptions::SetKey(key2, "Size", queueData.transferFile.size);
				COptions::SetKey(key2, "Remotefile", queueData.transferFile.remotefile);
				COptions::SetKey(key2, "Remotepath", queueData.transferFile.remotepath.GetSafePath());
				COptions::SetKey(key2, "Transfer mode", queueData.transferFile.nType);
				COptions::SetKey(key2, "Get", queueData.transferFile.get);
				COptions::SetKey(key2, "Retry Count", queueData.retrycount);
				COptions::SetKey(key2, "Open", queueData.nOpen);
				
				COptions::SaveServer(key2, queueData.transferFile.server);

				RegCloseKey(key2);
			}
			j++;
		}
	}

	m_nActiveCount = 0;
	m_QueueItems.clear();
	DeleteAllItems();
	
	CListCtrl::OnDestroy();	
}

void CQueueCtrl::ProcessReply(int nReplyCode, int nApiIndex /*=-1*/)
{
	CMainFrame *pMainFrame = DYNAMIC_DOWNCAST(CMainFrame, GetParentFrame());
	m_bMayUsePrimaryConnection = FALSE;

	while (TRUE)
	{
		ASSERT(Validate());
		
		//Make sure pFileZillaApi is either NULL or in the active list. If not, stop processing
		t_TransferApi api={0};
		if (nApiIndex > -1)
		{
			ASSERT(static_cast<unsigned int>(nApiIndex) < m_TransferApiArray.size());
			if (static_cast<unsigned int>(nApiIndex) >= m_TransferApiArray.size())
				return;
			api = m_TransferApiArray[nApiIndex];
		}
		
		//Find the item
		unsigned int nIndex;
		CQueueData queueData;
		for (nIndex = 0; nIndex < m_QueueItems.size(); nIndex++)
		{
			queueData = m_QueueItems[nIndex];
			if (!queueData.bActive)
				return;
			if (queueData.pTransferApi == api.pTransferApi)
				break;
		}
		if (nIndex == m_QueueItems.size())
			return;

		//Initialize all required data variables
		t_transferfile &transferFile = queueData.transferFile;
		
		t_ServerDataMapIter ServerDataMapIter = m_ServerDataMap.find(transferFile.server);
		ASSERT(ServerDataMapIter!=m_ServerDataMap.end());
		if (ServerDataMapIter == m_ServerDataMap.end())
			return;
			
		BOOL bConnectError = FALSE;
		
		int nState = queueData.nState;
		
		if (nReplyCode&FZ_REPLY_DISCONNECTED && nState==QUEUESTATE_DISCONNECT)
		{
			ASSERT(api.pTransferApi);
			if (!api.pTransferApi)
				return;
			queueData.nState = QUEUESTATE_CONNECT;
			if (api.pTransferApi->Connect(transferFile.server)==FZ_REPLY_WOULDBLOCK)
			{
				queueData.status.Format(IDS_STATUSMSG_CONNECTING, (transferFile.server.name!="")?transferFile.server.name:transferFile.server.host);
				m_QueueItems[nIndex] = queueData;
				return;
			}
			else
				nReplyCode |= FZ_REPLY_ERROR | FZ_REPLY_CRITICALERROR;
		}
		else if (nState==QUEUESTATE_CONNECT)
		{
			ASSERT(api.pTransferApi);
			if (!api.pTransferApi)
				return;
			if (nReplyCode == FZ_REPLY_OK)
			{
				ServerDataMapIter->second.nCurrentActive++;
				if (ServerDataMapIter->second.nCurrentActive > ServerDataMapIter->second.nActiveMax)
					ServerDataMapIter->second.nActiveMax++;
				queueData.nState = QUEUESTATE_TRANSFER;
				int res = api.pTransferApi->FileTransfer(transferFile);
				if (res==FZ_REPLY_WOULDBLOCK)
				{
					queueData.status.Format(IDS_QUEUESTATUS_TRANSFERRING);
					m_QueueItems[nIndex] = queueData;
					return;
				}
				else
					nReplyCode|=FZ_REPLY_ERROR;
			}
			else
			{
				if (ServerDataMapIter->second.nFailedConnections < 5)
					ServerDataMapIter->second.nFailedConnections++;
				if (ServerDataMapIter->second.nFailedConnections==5 && ServerDataMapIter->second.nActiveMax)
				{
					if (ServerDataMapIter->second.nCurrentActive<ServerDataMapIter->second.nActiveMax)
						ServerDataMapIter->second.nActiveMax--;
					ServerDataMapIter->second.nFailedConnections = 3;
				}
				if (ServerDataMapIter->second.nCurrentActive)
					bConnectError = TRUE;
				
				nReplyCode |= FZ_REPLY_ERROR;
				
				//Check if primary connection is connected to the same server
				//and increase nAutoUsePrimary if necessary

				CMainFrame *pMainFrame=DYNAMIC_DOWNCAST(CMainFrame,GetParentFrame());
				if (pMainFrame->m_pCommandQueue->IsConnected())
				{
					t_server server;
					CServerPath path;
					if (pMainFrame->m_pCommandQueue->GetLastServer(server, path) && 
						server==transferFile.server)
					{
						if (!ServerDataMapIter->second.nActiveMax)
						{
							queueData.nAutoUsePrimary = 3;
							//Increase nAutoUsePrimary on all other items which use the same server
							for (t_QueueVector::iterator iter = m_QueueItems.begin(); iter != m_QueueItems.end(); iter++)
							{
								if (!iter->bActive &&
									iter->transferFile.server == transferFile.server && iter->nAutoUsePrimary<3)
									iter->nAutoUsePrimary ++;
							}
						}
					}
				}

				m_RetryServerList.AddServer(transferFile.server);
			}
		}

		if (nApiIndex == -1)
			m_bPrimaryConnectionTransferInProgress = FALSE;
	
		if (transferFile.get)
			pMainFrame->GetLocalPane2()->RefreshFile(transferFile.localfile);
	
		ASSERT(nIndex < static_cast<unsigned int>(m_nActiveCount));

		m_nActiveCount--;

		if (nApiIndex!=-1 && nState==QUEUESTATE_TRANSFER)
			ServerDataMapIter->second.nCurrentActive--;

		queueData.pTransferApi=0;
		delete queueData.pTransferStatus;
		queueData.pTransferStatus = 0;
		delete queueData.pProgressControl;
		queueData.pProgressControl = 0;
		
		if (api.pTransferApi)
		{
			api.bActive = FALSE;
			api.pLastActiveTime=new CTime;
			*api.pLastActiveTime=CTime::GetCurrentTime();
			m_TransferApiArray[nApiIndex]=api;
		}
		
		if (nReplyCode==FZ_REPLY_OK)
		{
			m_QueueItems.erase(m_QueueItems.begin() + nIndex);
			SetItemCount(m_QueueItems.size() + m_nActiveCount);

			if (queueData.nOpen)
				EditFile(queueData);
					
			if (FindValidIndex(1) == m_QueueItems.begin())
				StopProcessing();
			else if (m_nProcessQueue==2 && FindValidIndex(2) == m_QueueItems.begin())
				StopProcessing();
		}
		else if ( ((nReplyCode&FZ_REPLY_ABORTED || nReplyCode&FZ_REPLY_CANCEL) && queueData.bStop) || queueData.nAutoUsePrimary==3 || bConnectError)
		{
			queueData.bActive = FALSE;
			
			m_QueueItems.erase(m_QueueItems.begin() + nIndex);
			
			if (!queueData.nAutoUsePrimary && !bConnectError)
				queueData.priority=1;
			
			if (queueData.bPaused)
			{
				queueData.priority = 0;
				queueData.action.LoadString(IDS_QUEUESTATUS_PAUSED);
			}
			else
				queueData.action = _T("");
			
			if (queueData.priority == 2)
				m_QueueItems.insert(m_QueueItems.begin() + m_nActiveCount, queueData);
			else if (queueData.bPaused)
				m_QueueItems.insert(FindValidIndex(1), queueData);
			else
				m_QueueItems.insert(FindValidIndex(2), queueData);
			SetItemCount(m_QueueItems.size() + m_nActiveCount);
		}
		else if (nReplyCode&FZ_REPLY_CRITICALERROR || nReplyCode&FZ_REPLY_ABORTED || nReplyCode&FZ_REPLY_CANCEL)
		{
			queueData.bActive = FALSE;

			m_QueueItems.erase(m_QueueItems.begin() + nIndex);
			SetItemCount(m_QueueItems.size() + m_nActiveCount);
			
			queueData.priority = 0;
			if (!queueData.bPaused)
				queueData.retrycount = -1;
			
			if (FindValidIndex(1) == m_QueueItems.begin())
				StopProcessing();
			else if (m_nProcessQueue==2 && FindValidIndex(2) == m_QueueItems.begin())
				StopProcessing();
			
			if (!queueData.bAbort)
			{
				if (queueData.bPaused)
					queueData.action.LoadString(IDS_QUEUESTATUS_PAUSED);
				else
					queueData.action.LoadString((nReplyCode&FZ_REPLY_CRITICALERROR)?IDS_QUEUESTATUS_CRITICALERROR:IDS_QUEUESTATUS_ABORTED);

				m_QueueItems.insert(FindValidIndex(queueData.bPaused?1:0), queueData);
				SetItemCount(m_QueueItems.size() + m_nActiveCount);
			}
		}
		else if (nReplyCode&FZ_REPLY_ERROR)
		{
			queueData.bActive = FALSE;

			queueData.retrycount++;
			if (queueData.retrycount>=COptions::GetOptionVal(OPTION_NUMRETRIES))
			{
				m_QueueItems.erase(m_QueueItems.begin() + nIndex);
				SetItemCount(m_QueueItems.size() + m_nActiveCount);
				
				queueData.retrycount = -1;
				queueData.priority = 0;
				
				if (FindValidIndex(1) == m_QueueItems.begin())
					StopProcessing();
				else if (m_nProcessQueue==2 && FindValidIndex(2) == m_QueueItems.begin())
					StopProcessing();
				
				queueData.action.LoadString(IDS_QUEUESTATUS_TOOMANYERTREIS);

				m_QueueItems.insert(FindValidIndex(0), queueData);
			}
			else
			{
				m_QueueItems.erase(m_QueueItems.begin() + nIndex);
				
				queueData.action.Format(IDS_QUEUESTATUS_ERROR, queueData.retrycount);

				if (queueData.priority==2)
					m_QueueItems.insert(m_QueueItems.begin() + m_nActiveCount, queueData);
				else
					m_QueueItems.insert(FindValidIndex(2), queueData);
				SetItemCount(m_QueueItems.size() + m_nActiveCount);
			}
		}
		else
			ASSERT(FALSE);
	
		if (queueData.bStop)
			queueData.bTransferStarted = FALSE;
		queueData.bStop = FALSE;
		queueData.nState = 0;
	
		SetItemCount(m_QueueItems.size() + m_nActiveCount);
		
		UpdateStatusbar();
		int res = 0;
		if (DoProcessQueue())
		{
			do
			{
				res = TransferNextFile(nApiIndex);
				if (res==-1)
				{
					nReplyCode = FZ_REPLY_ERROR;
					continue;
				}
				else if (res==-2)
				{
					nReplyCode = FZ_REPLY_CRITICALERROR;
					continue;
				}
			}
			while (res==1);
		}
		else if (m_QueueItems.empty())
			m_nActiveCount = 0;
		if (res >= 0)
			break;
	}
	SetItemCount(m_QueueItems.size() + m_nActiveCount);
}

int CQueueCtrl::TransferNextFile(int &nApiIndex)
{
	ASSERT(Validate());
	
	if (!m_nProcessQueue)
		return 0;
	if (FindValidIndex(1) == m_QueueItems.begin())
	{
		StopProcessing();
		return 0;
	}

	if (!m_bUseMultiple && m_nActiveCount)
		return 0;

	if (static_cast<UINT>(m_nActiveCount) >= m_nMaxApiCount)
		return 0;

	//Search for the first idle item
	t_QueueVector::iterator iter;	
	for (iter = m_QueueItems.begin(); iter != m_QueueItems.end(); iter++)
	{
		if (iter->bActive)
			continue;
		if (iter->nAutoUsePrimary>=3 && m_bPrimaryConnectionTransferInProgress)
			continue;
		if (iter->bPaused)
			continue;
		if (!iter->priority)
			return 0;
		if (iter->priority < m_nProcessQueue)
			return 0;

		t_ServerDataMapIter ServerDataMapIter = m_ServerDataMap.find(iter->transferFile.server);
		if (ServerDataMapIter == m_ServerDataMap.end())
		{
			t_ServerData ServerData;
			ServerData.nActiveMax = ServerData.nCurrentActive = ServerData.nFailedConnections = 0;
			m_ServerDataMap[iter->transferFile.server] = ServerData;
			ServerDataMapIter = m_ServerDataMap.find(iter->transferFile.server);
			ASSERT(ServerDataMapIter != m_ServerDataMap.end());
		}
			
		if (ServerDataMapIter->second.nFailedConnections>=3 && ServerDataMapIter->second.nActiveMax && ServerDataMapIter->second.nCurrentActive>=ServerDataMapIter->second.nActiveMax)
			continue;

		if (m_nProcessQueue!=1)
			m_nProcessQueue = iter->priority;
		
		int maxsize = COptions::GetOptionVal(OPTION_TRANSFERPRIMARYMAXSIZE);
		if (iter->nAutoUsePrimary==3 || 
			(m_bMayUsePrimaryConnection && iter->transferFile.size>=0 && iter->transferFile.size < maxsize) ||
			!m_bUseMultiple )
		{
			m_bMayUsePrimaryConnection = FALSE;
			CMainFrame *pMainFrame = DYNAMIC_DOWNCAST(CMainFrame, GetParentFrame());
			if (pMainFrame->m_pCommandQueue->IsConnected())
			{
				t_server server;
				CServerPath path;
				if (pMainFrame->m_pCommandQueue->GetLastServer(server, path) && 
					server==iter->transferFile.server)
				{
					if (!pMainFrame->m_pCommandQueue->IsLocked() && !pMainFrame->m_pCommandQueue->IsBusy())
					{
						iter->nAutoUsePrimary=4;
						m_bPrimaryConnectionTransferInProgress=TRUE;
						iter->action.Format(IDS_QUEUESTATUS_TRANSFERRING);
						
						iter->bActive = TRUE;
						iter->nState = QUEUESTATE_TRANSFER;
						
						//Create the progress control
						iter->pProgressControl = new CTextProgressCtrl;
						if (iter->pProgressControl->Create(WS_VISIBLE|WS_CHILD|WS_BORDER, CRect(1, 1, 1, 1), this, 0))
						{
							iter->pProgressControl->SetRange(0,100); //Set the range to between 0 and 100
							iter->pProgressControl->SetStep(1); // Set the step amount
							iter->pProgressControl->ShowWindow(SW_HIDE);
						}
						else
						{
							delete iter->pProgressControl;
							iter->pProgressControl = NULL;
						}
						
						CQueueData queueData = *iter;
						m_QueueItems.erase(iter);
						iter = m_QueueItems.insert(m_QueueItems.begin() + m_nActiveCount, queueData);
						
						m_nActiveCount++;
						SetItemCount(m_QueueItems.size() + m_nActiveCount);
						
						nApiIndex=-1;
						iter->pTransferApi=0;
						if (!pMainFrame->m_pCommandQueue->FileTransfer(iter->transferFile))
							return -1;
						else
							iter->status.Format(IDS_QUEUESTATUS_TRANSFERRING);

						return 1;
					}
					else if (iter->nAutoUsePrimary)
					{
						continue;
					}
				}
				else
					iter->nAutoUsePrimary=0;
			}
			else
				iter->nAutoUsePrimary=0;
	
		}
		
		iter->nAutoUsePrimary=0;
		
		//Chose one api instance
		t_TransferApi api;
		
		int nMatchingApiIndex=-1, nUnconnectedApiIndex=-1, nConnectedApiIndex=-1;
		
		for (std::vector<t_TransferApi>::const_iterator apiiter = m_TransferApiArray.begin(); apiiter != m_TransferApiArray.end(); apiiter++)
			//Find a matching api instance. The best would be an instance already
			//connected to the right server. If no one can be found, use an unconnected
			//instance and if this fails, too, use an instance connected to another server
		{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -