hxsymbiantcpsock.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 900 行 · 第 1/2 页
CPP
900 行
/* ***** BEGIN LICENSE BLOCK *****
* Source last modified: $Id: hxsymbiantcpsock.cpp,v 1.6.2.3 2004/07/09 02:08:48 hubbe Exp $
*
* Portions Copyright (c) 1995-2004 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 (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the current version of the RealNetworks Community
* Source License (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.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL") in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your version of
* this file only under the terms of the GPL, and not to allow others
* to use your version of this file under the terms of either the RPSL
* or RCSL, indicate your decision by deleting the provisions above
* and replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient may
* use your version of this file under the terms of any one of the
* RPSL, the RCSL or the GPL.
*
* 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)
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?