Exemplo n.º 1
0
/////////////////////////////////////////////////////////////////////////////
// Member-Funktion CTransferSocket
void CTransferSocket::OnReceive(int nErrorCode)
{
  if (GetState() != connected && GetState() != attached && GetState() != closed)
    return;
  if (m_nTransferState == STATE_WAITING)
  {
    m_nNotifyWaiting |= FD_READ;
    return;
  }

  if (m_bSentClose)
    return;
  if (m_bListening)
    return;

  if (m_nMode&CSMODE_LIST)
  {
    if (m_nTransferState == STATE_STARTING)
      OnConnect(0);

    char *buffer = nb::chcalloc(BUFSIZE);
    int numread = CAsyncSocketEx::Receive(buffer, BUFSIZE);
    if (numread != SOCKET_ERROR && numread)
    {
      m_LastActiveTime = CTime::GetCurrentTime();

#ifndef MPEXT_NO_ZLIB
      if (m_useZlib)
      {
        m_zlibStream.next_in = (Bytef *)buffer;
        m_zlibStream.avail_in = numread;
        char *out = nb::calloc(BUFSIZE);
        m_zlibStream.next_out = (Bytef *)out;
        m_zlibStream.avail_out = BUFSIZE;
        int res = inflate(&m_zlibStream, 0);
        while (res == Z_OK)
        {
          m_pListResult->AddData(out, BUFSIZE - m_zlibStream.avail_out);
          out = nb::calloc(BUFSIZE);
          m_zlibStream.next_out = (Bytef *)out;
          m_zlibStream.avail_out = BUFSIZE;
          res = inflate(&m_zlibStream, 0);
        }
        nb_free(buffer);
        if (res == Z_STREAM_END)
          m_pListResult->AddData(out, BUFSIZE - m_zlibStream.avail_out);
        else if (res != Z_OK && res != Z_BUF_ERROR)
        {
          nb_free(out);
          CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
          return;
        }
        else
          nb_free(out);
      }
      else
#endif
        m_pListResult->AddData(buffer, numread);
      m_transferdata.transfersize += numread;
      t_ffam_transferstatus *status = new t_ffam_transferstatus();
      status->bFileTransfer = FALSE;
      status->transfersize = -1;
      status->bytes = m_transferdata.transfersize;
      GetIntern()->FZPostMessage(FZ_MSG_MAKEMSG(FZ_MSG_TRANSFERSTATUS, 0), (LPARAM)status);
    }
    else
      nb_free(buffer);
    if (!numread)
    {
      CloseAndEnsureSendClose(0);
    }
    if (numread == SOCKET_ERROR)
    {
      int nError = GetLastError();
      if (nError == WSAENOTCONN)
      {
        //Not yet connected
        return;
      }
      else if (m_pSslLayer && nError == WSAESHUTDOWN)
      {
        // Do nothing, wait for shutdown complete notification.
        return;
      }
      else if (nError != WSAEWOULDBLOCK)
      {
        LogError(nError);
        CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
      }
    }
  }
  else if (m_nMode & CSMODE_DOWNLOAD)
  {
    if (m_nTransferState == STATE_STARTING)
      OnConnect(0);

    bool beenWaiting = false;
    _int64 ableToRead;
    if (GetState() != closed)
      ableToRead = m_pOwner->GetAbleToTransferSize(CFtpControlSocket::download, beenWaiting);
    else
      ableToRead = BUFSIZE;

    if (!beenWaiting)
      DebugAssert(ableToRead);
    else if (!ableToRead)
    {
      TriggerEvent(FD_READ);
      return;
    }

    if (!m_pBuffer)
      m_pBuffer = nb::chcalloc(BUFSIZE);

    int numread = CAsyncSocketEx::Receive(m_pBuffer, static_cast<int>(ableToRead));
    if (numread!=SOCKET_ERROR)
    {
      m_pOwner->SpeedLimitAddTransferredBytes(CFtpControlSocket::download, numread);
    }

    if (!numread)
    {
      CloseAndEnsureSendClose(0);
      return;
    }

    if (numread == SOCKET_ERROR)
    {
      int nError = GetLastError();
      if (nError == WSAENOTCONN)
      {
        //Not yet connected
        return;
      }
      else if (m_pSslLayer && nError == WSAESHUTDOWN)
      {
        // Do nothing, wait for shutdown complete notification.
        return;
      }
      else if (nError != WSAEWOULDBLOCK)
      {
        LogError(nError);
        CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
      }

      UpdateStatusBar(false);
      return;
    }

    int written = 0;
    m_LastActiveTime = CTime::GetCurrentTime();
    TRY
    {
#ifndef MPEXT_NO_ZLIB
      if (m_useZlib)
      {
        if (!m_pBuffer2)
          m_pBuffer2 = nb::calloc(BUFSIZE);

        m_zlibStream.next_in = (Bytef *)m_pBuffer;
        m_zlibStream.avail_in = numread;
        m_zlibStream.next_out = (Bytef *)m_pBuffer2;
        m_zlibStream.avail_out = BUFSIZE;
        int res = inflate(&m_zlibStream, 0);
        while (res == Z_OK)
        {
          m_pFile->Write(m_pBuffer2, BUFSIZE - m_zlibStream.avail_out);
          written += BUFSIZE - m_zlibStream.avail_out;
          m_zlibStream.next_out = (Bytef *)m_pBuffer2;
          m_zlibStream.avail_out = BUFSIZE;
          res = inflate(&m_zlibStream, 0);
        }
        if (res == Z_STREAM_END)
        {
          m_pFile->Write(m_pBuffer2, BUFSIZE - m_zlibStream.avail_out);
          written += BUFSIZE - m_zlibStream.avail_out;
        }
        else if (res != Z_OK && res != Z_BUF_ERROR)
        {
          m_pOwner->ShowStatus(L"Compression error", FZ_LOG_ERROR);
          CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
          return;
        }
      }
      else
#endif
      {
        m_pFile->Write(m_pBuffer, numread);
        written = numread;
      }
    }
    CATCH(CFileException,e)
    {
      LPTSTR msg = nb::wchcalloc(BUFSIZE);
      if (e->GetErrorMessage(msg, BUFSIZE))
        m_pOwner->ShowStatus(msg, FZ_LOG_ERROR);
      nb_free(msg);
      CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
      return;
    }
    END_CATCH;
    m_transferdata.transferleft -= written;

    UpdateStatusBar(false);
  }
Exemplo n.º 2
0
/////////////////////////////////////////////////////////////////////////////
// Member-Funktion CTransferSocket
void CTransferSocket::OnReceive(int nErrorCode)
{
	if (GetState() != connected && GetState() != attached && GetState() != closed)
		return;
	if (m_nTransferState == STATE_WAITING)
	{
		m_nNotifyWaiting |= FD_READ;
		return;
	}

	if (m_bSentClose)
		return;
	if (m_bListening)
		return;

	if (m_nMode&CSMODE_LIST)
	{
		if (m_nTransferState == STATE_STARTING)
			OnConnect(0);

		char *buffer = static_cast<char *>(nb_calloc(1, BUFSIZE));
		int numread = CAsyncSocketEx::Receive(buffer, BUFSIZE);
		if (numread != SOCKET_ERROR && numread)
		{
			m_LastActiveTime = CTime::GetCurrentTime();
			UpdateRecvLed();

#ifndef MPEXT_NO_ZLIB
			if (m_useZlib)
			{
				m_zlibStream.next_in = (Bytef *)buffer;
				m_zlibStream.avail_in = numread;
				char *out = static_cast<char *>(nb_calloc(1, BUFSIZE));
				m_zlibStream.next_out = (Bytef *)out;
				m_zlibStream.avail_out = BUFSIZE;
				int res = inflate(&m_zlibStream, 0);
				while (res == Z_OK)
				{
					m_pListResult->AddData(out, BUFSIZE - m_zlibStream.avail_out);
					out = static_cast<char *>(nb_calloc(1, BUFSIZE));
					m_zlibStream.next_out = (Bytef *)out;
					m_zlibStream.avail_out = BUFSIZE;
					res = inflate(&m_zlibStream, 0);
				}
				nb_free(buffer);
				if (res == Z_STREAM_END)
					m_pListResult->AddData(out, BUFSIZE - m_zlibStream.avail_out);
				else if (res != Z_OK && res != Z_BUF_ERROR)
				{
					nb_free(out);
					CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
					return;
				}
				else
					nb_free(out);
			}
			else
#endif
				m_pListResult->AddData(buffer, numread);
			m_transferdata.transfersize += numread;
			CTimeSpan timespan = CTime::GetCurrentTime() - m_StartTime;
			int elapsed = (int)timespan.GetTotalSeconds();
			//TODO
			//There are servers which report the total number of
			//bytes in the list response message, but yet it is not supported by FZ.
			/*double leftmodifier=(transfersize-transferstart-transferleft);
			leftmodifier*=100;
			leftmodifier/=(transfersize-transferstart);
			if (leftmodifier==0)
				leftmodifier=1;
			double leftmodifier2=100-leftmodifier;
			int left=(int)((elapsed/leftmodifier)*leftmodifier2);
			int percent=MulDiv(100,transfersize-transferleft,transfersize);*/
			int transferrate=static_cast<int>( (elapsed && m_transferdata.transfersize)?m_transferdata.transfersize/elapsed:0 );
			t_ffam_transferstatus *status = new t_ffam_transferstatus;
			status->bFileTransfer = FALSE;
#ifdef MPEXT
			status->transfersize = -1;
#endif
			status->bytes = m_transferdata.transfersize;
			status->percent = -1;
			status->timeelapsed = elapsed;
			status->timeleft = -1;
			status->transferrate = transferrate;
			PostMessage(m_pOwner->m_pOwner->m_hOwnerWnd, m_pOwner->m_pOwner->m_nReplyMessageID, FZ_MSG_MAKEMSG(FZ_MSG_TRANSFERSTATUS, 0), (LPARAM)status);
		}
		else
			nb_free(buffer);
		if (!numread)
		{
			CloseAndEnsureSendClose(0);
		}
		if (numread == SOCKET_ERROR)
		{
			int nError = GetLastError();
			if (nError == WSAENOTCONN)
			{
				//Not yet connected
				return;
			}
#ifndef MPEXT_NO_SSL
			else if (m_pSslLayer && nError == WSAESHUTDOWN)
			{
				// Do nothing, wait for shutdown complete notification.
				return;
			}
#endif
			else if (nError != WSAEWOULDBLOCK)
			{
				LogError(nError);
				CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
			}
		}
	}
	else if (m_nMode & CSMODE_DOWNLOAD)
	{
		if (m_nTransferState == STATE_STARTING)
			OnConnect(0);

		bool beenWaiting = false;
		_int64 ableToRead;
		if (GetState() != closed)
			ableToRead = m_pOwner->GetAbleToTransferSize(CControlSocket::download, beenWaiting);
		else
			ableToRead = BUFSIZE;

		if (!beenWaiting)
			ASSERT(ableToRead);
		else if (!ableToRead)
		{
			TriggerEvent(FD_READ);
			return;
		}

		if (!m_pBuffer)
			m_pBuffer = static_cast<char *>(nb_calloc(1, BUFSIZE));

		int numread = CAsyncSocketEx::Receive(m_pBuffer, static_cast<int>(ableToRead));
		if (numread!=SOCKET_ERROR)
		{
			Transfered( numread, CTime::GetCurrentTime());
			m_pOwner->SpeedLimitAddTransferredBytes(CControlSocket::download, numread);
		}

		if (!numread)
		{
			CloseAndEnsureSendClose(0);
			return;
		}

		if (numread == SOCKET_ERROR)
		{
			int nError = GetLastError();
			if (nError == WSAENOTCONN)
			{
				//Not yet connected
				return;
			}
#ifndef MPEXT_NO_SSL
			else if (m_pSslLayer && nError == WSAESHUTDOWN)
			{
				// Do nothing, wait for shutdown complete notification.
				return;
			}
#endif
			else if (nError != WSAEWOULDBLOCK)
			{
				LogError(nError);
				CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
			}

			UpdateStatusBar(false);
			return;
		}

		int written = 0;
		m_LastActiveTime = CTime::GetCurrentTime();
		UpdateRecvLed();
		TRY
		{
#ifndef MPEXT_NO_ZLIB
			if (m_useZlib)
			{
				if (!m_pBuffer2)
					m_pBuffer2 = static_cast<char *>(nb_calloc(1, BUFSIZE));

				m_zlibStream.next_in = (Bytef *)m_pBuffer;
				m_zlibStream.avail_in = numread;
				m_zlibStream.next_out = (Bytef *)m_pBuffer2;
				m_zlibStream.avail_out = BUFSIZE;
				int res = inflate(&m_zlibStream, 0);
				while (res == Z_OK)
				{
					m_pFile->Write(m_pBuffer2, BUFSIZE - m_zlibStream.avail_out);
					written += BUFSIZE - m_zlibStream.avail_out;
					m_zlibStream.next_out = (Bytef *)m_pBuffer2;
					m_zlibStream.avail_out = BUFSIZE;
					res = inflate(&m_zlibStream, 0);
				}
				if (res == Z_STREAM_END)
				{
					m_pFile->Write(m_pBuffer2, BUFSIZE - m_zlibStream.avail_out);
					written += BUFSIZE - m_zlibStream.avail_out;
				}
				else if (res != Z_OK && res != Z_BUF_ERROR)
				{
					m_pOwner->ShowStatus(L"Compression error", FZ_LOG_ERROR);
					CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
					return;
				}
			}
			else
#endif
			{
				m_pFile->Write(m_pBuffer, numread);
				written = numread;
			}
		}
		CATCH(CFileException,e)
		{
			LPTSTR msg = static_cast<TCHAR *>(nb_calloc(BUFSIZE, sizeof(TCHAR)));
			if (e->GetErrorMessage(msg, BUFSIZE))
				m_pOwner->ShowStatus(msg, FZ_LOG_ERROR);
			nb_free(msg);
			CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
			return;
		}
		END_CATCH;
		m_transferdata.transferleft -= written;

		UpdateStatusBar(false);
	}