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

📄 hxcloakedtcp.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    m_pTCPResponse->WriteReady(HXR_OK);

    return HXR_OK;
}

STDMETHODIMP HXClientCloakedTCPSocket::GetLocalAddress(ULONG32& lAddress)
{
    return HXR_NOTIMPL;
}

STDMETHODIMP HXClientCloakedTCPSocket::GetForeignAddress(ULONG32& lAddress)
{
    if(m_bConnected && m_lForeignAddress)
    {
	lAddress = m_lForeignAddress;
	return HXR_OK;
    }
    return HXR_FAIL;
}

STDMETHODIMP HXClientCloakedTCPSocket::GetLocalPort(UINT16& port)
{
    return HXR_NOTIMPL;
}

STDMETHODIMP HXClientCloakedTCPSocket::GetForeignPort(UINT16& port)
{
    if(m_bConnected)
    {
	port = m_nForeignPort;
	return HXR_OK;
    }
    return HXR_FAIL;
}

/*
 *	IHXHTTPProxy methods
 *
 *  Network addresses and ports are in native byte order
 *  
 */

STDMETHODIMP HXClientCloakedTCPSocket::SetProxy(
				    const char*	    /*IN*/  pProxyHostName,
				    UINT16	    /*IN*/  nPort)
{
    if(pProxyHostName == 0 || *pProxyHostName == 0) 
    {
	return HXR_FAILED;
    }
    
    HX_VECTOR_DELETE(m_pProxyHostName);
    m_pProxyHostName = new char[::strlen(pProxyHostName) + 1];
    if (!m_pProxyHostName)
    {
	return HXR_OUTOFMEMORY;
    }

    ::strcpy(m_pProxyHostName, pProxyHostName); /* Flawfinder: ignore */
    m_nProxyPortNumber = nPort;

    return HXR_OK;
}

/************************************************************************
 *	Method:
 *	    IHXCloakedTCPSocket::InitCloak
 */
STDMETHODIMP
HXClientCloakedTCPSocket::InitCloak(IHXValues* /*IN*/  pValues, IUnknown* pUnknown)
{
    HX_RESULT	rc = HXR_OK;

    if (pValues)
    {
	m_pCloakValues = pValues;
	m_pCloakValues->AddRef();
    }
    if (pUnknown)
    {
	m_pCloakContext = pUnknown;
	m_pCloakContext->AddRef();
    }

    return rc;
}

HX_RESULT
HXClientCloakedTCPSocket::DoRead()
{
    HX_RESULT theErr = HXR_OK;
    char*   pStartAfterDoubleReturn = 0;
    UINT16 count = 0;

    if(m_bInDoRead)
    {
	return HXR_OK;
    }

    m_bInDoRead = TRUE;

    if (m_LastError)
    {
	goto exit;
    }

    // m_pReceivePutTCP is only initialized if we receive POST response
    // from the server
    if (m_pReceivePutTCP)
    {
	count = m_pReceivePutTCP->GetMaxAvailableElements();
    }
    else
    {
	count = TCP_BUF_SIZE;
    }

    // attempt to read from PUT if:
    // * we haven't initiated PUT read already AND
    // * we haven't received the complete POST response header AND
    // * we are not in multi-POST mode
    if (count > 0		    && 
	!m_bPutReadPending	    && 
	!m_bHTTPPutHeaderReadDone   &&
	!m_bMustCloseHTTP)
    {
	// attempt to read data from TCP link
	m_bPutReadPending = TRUE;
	theErr = m_pPutCtrl->Read(count);
    }

    // check how much room we have in TCP receive queue
    count = m_pReceiveGetTCP->GetMaxAvailableElements();
    if (count > 0 && !m_bGetReadPending)
    {
	// attempt to read data from TCP link
	m_bGetReadPending = TRUE;
	theErr = m_pGetCtrl->Read(count);
	switch(theErr)
	{
	    case HXR_AT_INTERRUPT:			
	    case HXR_WOULD_BLOCK:
	    case HXR_OK:
		// mask out these errors
		theErr = HXR_OK;
		break;

	    default:
		theErr = ConvertNetworkError(theErr);
		break;
	}
    }

exit:
    if (theErr && !m_LastError)
    {
	m_LastError = theErr;
    }

    if (m_LastError)
    {
	if (m_bReadPending)
	{
	    if (IsSafe())
	    {
		m_bReadPending = FALSE;
		m_pTCPResponse->ReadDone(m_LastError, 0);
	    }
	}
    }
    else
    {
	count = m_pReceiveGetTCP->GetQueuedItemCount();

	if (m_bReadPending && count > 0 && m_bOptionsReceived 
	    && m_bHTTPGetHeaderReadDone)
	{
	    /* mask any kind of errors */
	    theErr = HXR_OK;

	    if (IsSafe())
	    {
		m_bReadPending = FALSE;
		if (m_nRequired < count)
		{
		    count = m_nRequired;
		}

		CHXBuffer* pBuffer = new CHXBuffer;
		pBuffer->AddRef();
		m_pReceiveGetTCP->DeQueue(m_pInBuf, count);
		pBuffer->Set((UCHAR*) m_pInBuf, count);
		
		m_pTCPResponse->ReadDone(HXR_OK, pBuffer);
		pBuffer->Release();
	    }
	}

	if (m_pSchedulerCallback && m_bReadPending)
	{
	    m_pSchedulerCallback->ScheduleCallback(CLOAKED_TCP_READ_COMMAND, m_pScheduler, SCHED_GRANULARITY);
	}
    }
 
    m_bInDoRead = FALSE;
    return theErr;
}

HX_RESULT
HXClientCloakedTCPSocket::DoGetWrite()
{
    HX_RESULT theErr = HXR_OK;

    if (m_bInDoGetWrite)
    {
	return HXR_OK;
    }

    m_bInDoGetWrite = TRUE;

    // check how data we have in TCP send queue
    UINT16 count    = m_pSendTCP->GetQueuedItemCount();
    UINT16 actual   = count;
    
    if(count > 0) 
    {
	m_pSendTCP->DeQueue(m_pOutBuf,count);
	CHXBuffer* pBuffer = new CHXBuffer;
	pBuffer->AddRef();
	pBuffer->Set((UCHAR*) m_pOutBuf, (ULONG32) count);
	theErr = m_pGetCtrl->Write(pBuffer);
	pBuffer->Release();
    }
    
    if (theErr)
    {
	switch(theErr)
	{
	    case HXR_AT_INTERRUPT:			
	    case HXR_WOULD_BLOCK:
		m_pSendTCP->EnQueue(m_pOutBuf, count);
		// mask out these errors
		theErr = HXR_OK;
		break;

	    default:
		theErr = ConvertNetworkError(theErr);
		break;
	}
    }

    if (!theErr && !m_bInDestructor &&
	m_pSendTCP->GetQueuedItemCount() > 0 ) {
	    m_pSchedulerCallback->ScheduleCallback(CLOAKED_TCP_GETWRITE_COMMAND, m_pScheduler, SCHED_GRANULARITY);
    }

    m_bInDoGetWrite = FALSE;
    return theErr;
}

HX_RESULT
HXClientCloakedTCPSocket::DoPutWrite()
{
    HX_RESULT theErr = HXR_OK;

    if (m_bInDoPutWrite)
    {
	return HXR_OK;
    }

    m_bInDoPutWrite = TRUE;

    /* Transfer pending buffers to TCP send queue */
    if (m_bOptionsReceived && m_pPostEncodedSendHTTP->GetQueuedItemCount() == 0 && !m_bPutWantWritePending)
    {
	TransferBuffers();
    }

    if (!m_bPutConnectDone)
    {
	goto exit;
    }

    // check how data we have in TCP send queue
    UINT16 count;
    UINT16 actual;
    
    count    = m_pPostEncodedSendHTTP->GetQueuedItemCount();
    actual   = count;

    if(count > 0) 
    {
	m_pPostEncodedSendHTTP->DeQueue(m_pOutEncodedBuf,count);
	CHXBuffer* pBuffer = new CHXBuffer;
	pBuffer->AddRef();
	pBuffer->Set((UCHAR*) m_pOutEncodedBuf, (ULONG32) count);
	theErr = m_pPutCtrl->Write(pBuffer);
	pBuffer->Release();
	m_bPutWantWritePending	= TRUE;
	m_pPutCtrl->WantWrite();
    }
    
    if (theErr)
    {
	switch(theErr)
	{
	    case HXR_AT_INTERRUPT:			
	    case HXR_WOULD_BLOCK:
		m_pPostEncodedSendHTTP->EnQueue(m_pOutEncodedBuf, count);
		// mask out these errors
		theErr = HXR_OK;
		break;

	    default:
		theErr = ConvertNetworkError(theErr);
		break;
	}
    }

exit:

    if (!theErr && !m_bInDestructor &&
	(m_pPostEncodedSendHTTP->GetQueuedItemCount() > 0 ||
	 m_PendingWriteBuffers.GetCount() > 0)){
	    m_pSchedulerCallback->ScheduleCallback(CLOAKED_TCP_PUTWRITE_COMMAND, m_pScheduler, SCHED_GRANULARITY);
    }

    if (!theErr)
    {
	theErr = DoGetWrite();
    }

    m_bInDoPutWrite = FALSE;

    return theErr;
}

void 
HXClientCloakedTCPSocket::GetConnectDone(BOOL bResult)
{
    m_bGetConnectDone = TRUE;

    if (!m_bInDestructor)
    {
	AddRef();
    }

    if (bResult == TRUE)
    {
	m_bGetConnectSuccessful = TRUE;
	m_pGetCtrl->GetForeignAddress(m_lForeignAddress);
    }
    else
    {
	m_bGetConnectSuccessful = FALSE;
    }

    // PUT connection has to been done at this point
    if (m_bPutConnectDone && m_bConnectResponsePending)
    {
	m_bConnectResponsePending = FALSE;

	// either its HTTP-NG server or we are in re-GET mode
	// where we send GET to the same serverIP returned from
	// POST response
	if (m_bConnectToSameServerIP || m_bReconnectToSameServerIP)
	{
	    if (m_bPutConnectSuccessful && m_bGetConnectSuccessful)
	    {
		m_bConnected = TRUE;
		m_pMutex->Lock();
		PrepareGetMessage();
		DoGetWrite();
		Read(TCP_BUF_SIZE);
		m_pMutex->Unlock();
		if (m_bConnectToSameServerIP)
		{
		    // we haven't call ConnectDone yet
		    m_pTCPResponse->ConnectDone(HXR_OK);
		}
		else if (m_bReconnectToSameServerIP)
		{
		    // we already called ConnectDone upon the initial
		    // GET/POST connect done
		    Read(TCP_BUF_SIZE);
		}
	    }
	    else
	    {
		m_pTCPResponse->ConnectDone(HXR_NET_CONNECT);
	    }
	}
	// don't know the server type yet, keep the old behavior
	// where we send both GET and POST
	else
	{
	    if (m_bPutConnectSuccessful && m_bGetConnectSuccessful)
	    {
		m_bConnected = TRUE;
		m_pMutex->Lock();
		PreparePostMessage(NULL, 0);
		DoPutWrite();
		PrepareGetMessage();
		DoGetWrite();
		m_pMutex->Unlock();
		m_pTCPResponse->ConnectDone(HXR_OK);
	    }
	    else
	    {
		m_pTCPResponse->ConnectDone(HXR_NET_CONNECT);
	    }

	}
    }
	
    if (!m_bInDestructor)
    {
        Release();
    }
}

void 
HXClientCloakedTCPSocket::PutConnectDone(BOOL bResult)
{
    HX_RESULT theErr = HXR_OK;
    m_bPutConnectDone = TRUE;

    if (!m_bInDestructor)
    {
	AddRef();
    }

    if (bResult == TRUE)
    {
	m_bPutConnectSuccessful = TRUE;
    }
    else
    {
	m_bPutConnectSuccessful = FALSE;
    }

    // it's HTTP-NG server, we send POST first
    if (m_bConnectToSameServerIP)
    {
	if (m_bPutConnectSuccessful)
	{
	    m_pMutex->Lock();
	    PreparePostMessage(NULL, 0);
	    DoPutWrite();
	    if (!m_bPutReadPending)
	    {
		m_bPutReadPending = TRUE;
		m_pPutCtrl->Read(TCP_BUF_SIZE);
	    }
	    m_pMutex->Unlock();
	}
	else
	{
	    m_pTCPResponse->ConnectDone(HXR_NET_CONNECT);
	}
    }
    // don't know the server type yet, so we send both POST
    // and GET
    else if (m_bGetConnectDone && m_bConnectResponsePending)
    {
	m_bConnectResponsePending = FALSE;
	if (m_bPutConnectSuccessful && m_bGetConnectSuccessful)
	{
	    m_bConnected = TRUE;
	    m_pMutex->Lock();
	    PreparePostMessage(NULL, 0);
	    DoPutWrite();
	    PrepareGetMessage();
	    theErr = DoGetWrite();
	    m_pMutex->Unlock();
	    m_pTCPResponse->ConnectDone(HXR_OK);
	}
	else
	{
	    m_pTCPResponse->ConnectDone(HXR_NET_CONNECT);
	}
    }

    if (!m_bInDestructor)
    {
	Release();
    }

    if (m_bConnected && m_pPostEncodedSendHTTP->GetQueuedItemCount() > 0)
    {
	m_pMutex->Lock();
	DoPutWrite();
	m_pMutex->Unlock();
    }
}

HX_RESULT			
HXClientCloakedTCPSocket::DoGetReadDone(HX_RESULT   status, IHXBuffer* pInBuffer)
{
    HX_RESULT	theErr			= HXR_OK;
    char*	pStartAfterDoubleReturn = 0;
    UINT16	count = 0;

    if (AuthenticationRequired(status, pInBuffer))
    {
	return HXR_OK;
    }

    m_pMutex->Lock();

    m_bGetReadPending = FALSE;
    if (status != HXR_OK && m_LastError == HXR_OK)
    {
	m_LastError = status;
    }

    if (m_LastError)
    {
	goto exit;
    }

    if (pInBuffer)
    {
	m_pReceiveGetTCP->EnQueue(pInBuffer->GetBuffer(), (UINT16) pInBuffer->GetSize());
    }

    count = m_pReceiveGetTCP->GetQueuedItemCount();

    /*

⌨️ 快捷键说明

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