📄 hxsymbiantcpsock.cpp
字号:
/* ***** BEGIN LICENSE BLOCK *****
* Version: RCSL 1.0/RPSL 1.0
*
* Portions Copyright (c) 1995-2003 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file, are
* subject to the current version of the RealNetworks Public Source License
* Version 1.0 (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the RealNetworks Community Source License Version 1.0
* (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
* in which case the RCSL will apply. You may also obtain the license terms
* directly from RealNetworks. You may not use this file except in
* compliance with the RPSL or, if you have a valid RCSL with RealNetworks
* applicable to this file, the RCSL. Please see the applicable RPSL or
* RCSL for the rights, obligations and limitations governing use of the
* contents of the file.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the portions
* it created.
*
* This file, and the files included with this file, is distributed and made
* available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#include "platform/symbian/hxsymbiantcpsock.h"
#include "hxsymbiansockhlp.h"
#include "debug.h"
#include "hxassert.h"
#include "ihxpckts.h"
#include "smartptr.h"
#include <in_sock.h>
#define D_TCPSOCKET 0x10000000
class HXSymbianTCPResolvResp : public IHXResolverResponse
{
public:
HXSymbianTCPResolvResp(HXSymbianTCPSocket* pParent);
~HXSymbianTCPResolvResp();
/*
* IUnknown methods
*/
STDMETHOD(QueryInterface) (THIS_
REFIID riid,
void** ppvObj);
STDMETHOD_(ULONG32,AddRef) (THIS);
STDMETHOD_(ULONG32,Release) (THIS);
/*
* IHXResolverResponse methods
*/
STDMETHOD(GetHostByNameDone) (THIS_
HX_RESULT status,
ULONG32 ulAddr);
private:
ULONG32 m_lRefCount;
HXSymbianTCPSocket* m_pParent;
};
HXSymbianTCPResolvResp::HXSymbianTCPResolvResp(HXSymbianTCPSocket* pParent) :
m_lRefCount(0),
m_pParent(pParent)
{}
HXSymbianTCPResolvResp::~HXSymbianTCPResolvResp()
{}
/*
* IUnknown methods
*/
STDMETHODIMP HXSymbianTCPResolvResp::QueryInterface(THIS_
REFIID riid,
void** ppvObj)
{
QInterfaceList qiList[] =
{
{ GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXResolverResponse*)this },
{ GET_IIDHANDLE(IID_IHXResolverResponse), (IHXResolverResponse*) this },
};
return QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
}
STDMETHODIMP_(ULONG32) HXSymbianTCPResolvResp::AddRef(THIS)
{
return InterlockedIncrement(&m_lRefCount);
}
STDMETHODIMP_(ULONG32) HXSymbianTCPResolvResp::Release(THIS)
{
if (InterlockedDecrement(&m_lRefCount) > 0)
{
return m_lRefCount;
}
delete this;
return 0;
}
/*
* IHXResolverResponse methods
*/
STDMETHODIMP HXSymbianTCPResolvResp::GetHostByNameDone(THIS_
HX_RESULT status,
ULONG32 ulAddr)
{
return m_pParent->GetHostByNameDone(status, ulAddr);
}
class HXSymbianTCPConnector : public CActive
{
public:
HXSymbianTCPConnector(HXSymbianTCPSocket* pParent);
~HXSymbianTCPConnector();
void Connect(RSocket& socket, ULONG32 ulAddr, UINT16 nPort);
private:
void RunL();
void DoCancel();
HXSymbianTCPSocket* m_pParent;
TInetAddr m_addr;
};
HXSymbianTCPConnector::HXSymbianTCPConnector(HXSymbianTCPSocket* pParent) :
CActive(EPriorityStandard),
m_pParent(pParent)
{
CActiveScheduler::Add(this);
}
HXSymbianTCPConnector::~HXSymbianTCPConnector()
{
if (IsActive())
Cancel();
m_pParent = 0;
}
void HXSymbianTCPConnector::Connect(RSocket& socket,
ULONG32 ulAddr, UINT16 nPort)
{
m_addr.SetAddress(ulAddr);
m_addr.SetPort(nPort);
iStatus = KRequestPending;
socket.Connect(m_addr, iStatus);
SetActive();
}
void HXSymbianTCPConnector::RunL()
{
m_pParent->OnConnect((iStatus == KErrNone) ? HXR_OK : HXR_NET_CONNECT);
}
void HXSymbianTCPConnector::DoCancel()
{}
class HXSymbianTCPWriter : public CActive
{
public:
HXSymbianTCPWriter(HXSymbianTCPSocket* pParent);
~HXSymbianTCPWriter();
void Write(RSocket& socket, IHXBuffer* pBuffer);
private:
void RunL();
void DoCancel();
HXSymbianTCPSocket* m_pParent;
IHXBuffer* m_pBuffer;
TPtrC8 m_bufDes;
};
HXSymbianTCPWriter::HXSymbianTCPWriter(HXSymbianTCPSocket* pParent) :
CActive(EPriorityStandard),
m_pParent(pParent),
m_pBuffer(0)
{
CActiveScheduler::Add(this);
}
HXSymbianTCPWriter::~HXSymbianTCPWriter()
{
if (IsActive())
Cancel();
HX_RELEASE(m_pBuffer);
m_pParent = 0;
}
void HXSymbianTCPWriter::Write(RSocket& socket, IHXBuffer* pBuffer)
{
HX_RELEASE(m_pBuffer);
m_pBuffer = pBuffer;
if (m_pBuffer)
{
m_pBuffer->AddRef();
m_bufDes.Set(m_pBuffer->GetBuffer(), m_pBuffer->GetSize());
iStatus = KRequestPending;
socket.Write(m_bufDes, iStatus);
SetActive();
}
}
void HXSymbianTCPWriter::RunL()
{
HX_RESULT res = HXR_FAILED;
if (iStatus == KErrNone)
{
res = HXR_OK;
}
else if(iStatus == KErrEof)
{
res = HXR_STREAM_DONE;
}
else if(iStatus == KErrNoMemory)
{
res = HXR_OUTOFMEMORY;
}
HX_RELEASE(m_pBuffer);
m_pParent->OnWriteDone(res);
}
void HXSymbianTCPWriter::DoCancel()
{}
class HXSymbianTCPReader : public CActive
{
public:
HXSymbianTCPReader(HXSymbianTCPSocket* pParent,
IHXCommonClassFactory* pCCF);
~HXSymbianTCPReader();
HX_RESULT Read(RSocket& socket, UINT16 uSize);
private:
void RunL();
void DoCancel();
HXSymbianTCPSocket* m_pParent;
IHXBuffer* m_pBuffer;
TPtr8 m_bufDes;
TSockXfrLength m_amountRead;
IHXCommonClassFactory* m_pCCF;
};
HXSymbianTCPReader::HXSymbianTCPReader(HXSymbianTCPSocket* pParent,
IHXCommonClassFactory* pCCF) :
CActive(EPriorityStandard),
m_pParent(pParent),
m_pBuffer(0),
m_bufDes(0, 0),
m_pCCF(pCCF)
{
CActiveScheduler::Add(this);
if (m_pCCF)
{
m_pCCF->AddRef();
}
}
HXSymbianTCPReader::~HXSymbianTCPReader()
{
if (IsActive())
Cancel();
HX_RELEASE(m_pBuffer);
HX_RELEASE(m_pCCF);
m_pParent = 0;
}
HX_RESULT HXSymbianTCPReader::Read(RSocket& socket, UINT16 uSize)
{
HX_RESULT res = HXR_FAILED;
if (m_pParent)
{
res = HXSymbianSocketHelper::ResizeOrCreate(m_pCCF, uSize, m_pBuffer);
if (HXR_OK == res)
{
m_bufDes.Set(m_pBuffer->GetBuffer(), 0, m_pBuffer->GetSize());
iStatus = KRequestPending;
socket.RecvOneOrMore(m_bufDes, 0, iStatus, m_amountRead);
SetActive();
}
}
return res;
}
void HXSymbianTCPReader::RunL()
{
HX_RESULT res = HXR_FAILED;
if (iStatus == KErrNone)
{
res = HXR_OK;
}
else if(iStatus == KErrEof)
{
res = HXR_STREAM_DONE;
}
else if(iStatus == KErrNoMemory)
{
res = HXR_OUTOFMEMORY;
}
IHXBuffer* pBuffer = 0;
if(res == KErrNone)
{
HXSymbianSocketHelper::CopyOrTransfer(m_pCCF, m_amountRead(),
m_pBuffer, pBuffer);
}
m_pParent->OnReadDone(res, pBuffer);
HX_RELEASE(pBuffer);
}
void HXSymbianTCPReader::DoCancel()
{}
HXSymbianTCPSocket::HXSymbianTCPSocket(IHXCommonClassFactory* pCCF,
IHXResolver* pResolver) :
m_lRefCount(0),
m_pResponse(0),
m_pResolver(0),
m_state(tcpNotInitialized),
m_pConnector(0),
m_nConnectPort(0),
m_pWriter(0),
m_bWantWrite(FALSE),
m_pReader(0)
{
IHXResolverResponse* pResolvResp = new HXSymbianTCPResolvResp(this);
m_pConnector = new HXSymbianTCPConnector(this);
m_pWriter = new HXSymbianTCPWriter(this);
m_pReader = new HXSymbianTCPReader(this, pCCF);
if (pResolvResp)
{
pResolvResp->AddRef();
}
if (pCCF && pResolver && m_pConnector && m_pWriter && m_pReader &&
(pResolvResp) &&
(pResolver->Init(pResolvResp) == HXR_OK) &&
(m_socketServ.Connect() == KErrNone) &&
(m_socket.Open(m_socketServ, KAfInet,
KSockStream, KProtocolInetTcp) == KErrNone))
{
m_pResolver = pResolver;
m_pResolver->AddRef();
m_state = tcpInitialized;
}
HX_RELEASE(pResolvResp);
}
HXSymbianTCPSocket::~HXSymbianTCPSocket()
{
DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::~HXSymbianTCPSocket()\n"));
HX_RELEASE(m_pResponse);
HX_RELEASE(m_pResolver);
if (m_state != tcpNotInitialized)
{
CloseConnection(HXR_OK);
m_socket.Close();
m_socketServ.Close();
}
HX_DELETE(m_pConnector);
HX_DELETE(m_pWriter);
HX_DELETE(m_pReader);
}
/*
* IUnknown methods
*/
STDMETHODIMP HXSymbianTCPSocket::QueryInterface(THIS_
REFIID riid,
void** ppvObj)
{
DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::QueryInterface()\n"));
QInterfaceList qiList[] =
{
{ GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXTCPSocket*)this },
{ GET_IIDHANDLE(IID_IHXTCPSocket), (IHXTCPSocket*) this },
{ GET_IIDHANDLE(IID_IHXSetSocketOption), (IHXSetSocketOption*) this },
};
return QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
}
STDMETHODIMP_(ULONG32) HXSymbianTCPSocket::AddRef(THIS)
{
return InterlockedIncrement(&m_lRefCount);
}
STDMETHODIMP_(ULONG32)HXSymbianTCPSocket::Release(THIS)
{
if (InterlockedDecrement(&m_lRefCount) > 0)
{
return m_lRefCount;
}
delete this;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -