您的位置:首页 > 理论基础 > 计算机网络

Symbian中Http下载文件引擎,支持进度显示

2010-08-15 15:19 941 查看
CHttpDownLoadEngine.h文件

/*

============================================================================

Name : HttpDownLoadEngine.h

Author : Neil

Version : 1.0

Copyright : Your copyright notice

Description : CHttpDownLoadEngine declaration

============================================================================

*/

#ifndef HTTPDOWNLOADENGINE_H

#define HTTPDOWNLOADENGINE_H

// INCLUDES

#include <e32std.h>

#include <e32base.h>

#include "http/rhttpsession.h" // http.lib

#include "es_sock.h" // esock.lib

#include "http/mhttpdatasupplier.h"

#include "http/mhttptransactioncallback.h"

#include "http/rhttpheaders.h"

// CLASS DECLARATION

// Used user agent for requests

_LIT8(KUserAgent, "SimpleClient 1.0");

// This client accepts all content types.

// (change to e.g. "text/plain" for plain text only)

_LIT8(KAccept, "*/*");

_LIT(KCMNET, "CMNET");

_LIT(KCMWAP, "CMWAP");

_LIT8(KCMWAP1, "移动梦网");

/**

* 下载观察者

*/

class MDownLoadObserver

{

public:

enum TDownLoadEvent

{

ESuccess,/**下载成功*/

EFail,/**下载失败*/

EDownLoading,/**下载中*/

EStartDownLoad/**开始下载*/

};

/**

* 处理下载事件

* @param[in] aEvent 事件

* @param[in] aPersent 百分比,当aEvent==EDownLoading时有效

*/

virtual void HandleDownLoadEvent(TDownLoadEvent aEvent,TInt aPersent) =0;

};

/**

* CHttpDownLoadEngine

*

*/

class CHttpDownLoadEngine : public CBase,

public MHTTPDataSupplier,

public MHTTPTransactionCallback

{

public:

// Constructors and destructor

/**

* Destructor.

*/

~CHttpDownLoadEngine();

/**

* Two-phased constructor.

*/

static CHttpDownLoadEngine* NewL(MDownLoadObserver& aObserver);

/**

* Two-phased constructor.

*/

static CHttpDownLoadEngine* NewLC(MDownLoadObserver& aObserver);

private:

/**

* Constructor for performing 1st stage construction

*/

CHttpDownLoadEngine(MDownLoadObserver& aObserver);

/**

* EPOC default constructor for performing 2nd stage construction

*/

void ConstructL();

void CHttpDownLoadEngine::SetHeaderL(RHTTPHeaders aHeaders,

TInt aHdrField,

const TDesC8& aHdrValue);

protected:

virtual TBool GetNextDataPart(TPtrC8& aDataPart);

virtual void ReleaseData();

virtual TInt OverallDataSize();

virtual TInt Reset();

protected:

virtual void MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent);

virtual TInt MHFRunError(TInt aError, RHTTPTransaction aTransaction, const THTTPEvent& aEvent);

public:

/**

* 开始下载

* @param[in] aUrl 下载地址

* @param[in] aPostData post 请求的数据 可以为KNullDesC

* @param[in] aFileName 下载文件的保存路径

*/

TInt StartDownLoadL(const TDesC8& aUrl,const TDesC8& aPostData,const TDesC& aFileName);

private:

RHTTPSession iSession;

RSocketServ iSocketServ;

RConnection iConnection;

RHTTPTransaction iTransaction;

HBufC8* iPostData;

TFileName iFileName;

TInt iTotalSize;

TInt iCurSize;

RFs iFs;

RFile iFile;

MDownLoadObserver& iObserver;

};

#endif // HTTPDOWNLOADENGINE_H

复制代码

HttpDownLoadEngine.cpp 文件

/*

============================================================================

Name : HttpDownLoadEngine.cpp

Author : Neil

Version : 1.0

Copyright : Your copyright notice

Description : CHttpDownLoadEngine implementation

============================================================================

*/

#include "HttpDownLoadEngine.h"

#include "commdbconnpref.h" // commdb.lib

#include "httpstringconstants.h"

#include "http/thttphdrval.h"

#include "bautils.h" // bafl.lib

#include "commdb.h"

#include "utf.h"

CHttpDownLoadEngine::CHttpDownLoadEngine(MDownLoadObserver& aObserver)

:iObserver(aObserver)

{

// No implementation required

}

CHttpDownLoadEngine::~CHttpDownLoadEngine()

{

iSession.Close();

iConnection.Close();

iSocketServ.Close();

delete iPostData;

}

CHttpDownLoadEngine* CHttpDownLoadEngine::NewLC(MDownLoadObserver& aObserver)

{

CHttpDownLoadEngine* self = new (ELeave) CHttpDownLoadEngine(aObserver);

CleanupStack::PushL(self);

self->ConstructL();

return self;

}

CHttpDownLoadEngine* CHttpDownLoadEngine::NewL(MDownLoadObserver& aObserver)

{

CHttpDownLoadEngine* self = CHttpDownLoadEngine::NewLC(aObserver);

CleanupStack::Pop(); // self;

return self;

}

void CHttpDownLoadEngine::ConstructL()

{

TUint32 m_Iap=0;

TInt Err;

TFileName iapName;

TUint32 iapID;

TInt err; // open the IAP communications database

CCommsDatabase* commDB = CCommsDatabase::NewL();

CleanupStack::PushL(commDB); // Open the IAP table

CCommsDbTableView* view = commDB->OpenTableLC(TPtrC(IAP)); // Point to the first entry

Err = view->GotoFirstRecord();

if (Err == KErrNone)

{

do

{

view->ReadTextL(TPtrC(COMMDB_NAME), iapName);

view->ReadUintL(TPtrC(COMMDB_ID), iapID); // Store name and ID to where you want to

iapName.UpperCase();

TBuf<32> buf;

CnvUtfConverter::ConvertToUnicodeFromUtf8(buf,KCMWAP1);

if (/*iapName.Find(KCMNET) >= 0 || */iapName.Find(KCMWAP) >= 0)

{

m_Iap = iapID;

break;

}

}

while (err = view->GotoNextRecord(), err == KErrNone);

}

CleanupStack::PopAndDestroy(); // view

CleanupStack::PopAndDestroy(); // commDB

iSession.OpenL();

User::LeaveIfError(iSocketServ.Connect());

User::LeaveIfError(iConnection.Open(iSocketServ)); //

TCommDbConnPref pref;

pref.SetIapId(m_Iap);

pref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);

User::LeaveIfError(iConnection.Start(pref));

RStringPool strP = iSession.StringPool();

RHTTPConnectionInfo connInfo = iSession.ConnectionInfo();

connInfo.SetPropertyL ( strP.StringF(HTTP::EHttpSocketServ, RHTTPSession::GetTable() ), THTTPHdrVal (iSocketServ.Handle()) );

TInt connPtr = REINTERPRET_CAST(TInt, &iConnection);

connInfo.SetPropertyL ( strP.StringF(HTTP::EHttpSocketConnection, RHTTPSession::GetTable() ), THTTPHdrVal (connPtr) );

iCurSize = 0;

iTotalSize = 0;

}

void CHttpDownLoadEngine::SetHeaderL(RHTTPHeaders aHeaders,

TInt aHdrField,

const TDesC8& aHdrValue)

{

RStringF valStr = iSession.StringPool().OpenFStringL(aHdrValue);

CleanupClosePushL(valStr);

THTTPHdrVal val(valStr);

aHeaders.SetFieldL(iSession.StringPool().StringF(aHdrField,RHTTPSession::GetTable()), val);

CleanupStack::PopAndDestroy(); // valStr

}

TBool CHttpDownLoadEngine::GetNextDataPart(TPtrC8& aDataPart)

{

aDataPart.Set(iPostData->Des());

return ETrue;

}

void CHttpDownLoadEngine::ReleaseData()

{

delete iPostData;

iPostData = NULL;

}

TInt CHttpDownLoadEngine::OverallDataSize()

{

return iPostData->Length();

}

TInt CHttpDownLoadEngine::Reset()

{

return KErrNone;

}

void CHttpDownLoadEngine::MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent)

{

switch (aEvent.iStatus)

{

case THTTPEvent::EGotResponseHeaders:

{

RHTTPResponse resp = aTransaction.Response();

TInt status = resp.StatusCode();

RHTTPHeaders headers = resp.GetHeaderCollection ();

THTTPHdrVal aHeaderValue;



TRAPD(Err,

RStringPool string_pool = iSession.StringPool ();

RStringF contLength = string_pool.OpenFStringL (_L8("Content-Length") );

headers.GetField (contLength, 0, aHeaderValue );

contLength.Close ();

);

iTotalSize = aHeaderValue.Int();



iFs.Connect();

BaflUtils::EnsurePathExistsL(iFs,iFileName);

iFile.Replace(iFs,iFileName,EFileWrite);



iObserver.HandleDownLoadEvent(MDownLoadObserver::EStartDownLoad,0);

}

break;

case THTTPEvent::EGotResponseBodyData:

{

// Get the body data supplier

MHTTPDataSupplier* body = aTransaction.Response().Body();

TPtrC8 dataChunk;



// GetNextDataPart() returns ETrue, if the received part is the last

// one.

TBool isLast = body->GetNextDataPart(dataChunk);



iCurSize += dataChunk.Length();



TInt persent = iCurSize * 100 / iTotalSize;



iObserver.HandleDownLoadEvent(MDownLoadObserver::EDownLoading,persent);



iFile.Write(dataChunk);



body->ReleaseData();

}

break;

case THTTPEvent::EResponseComplete:

{

iFile.Close();

iFs.Close();

iObserver.HandleDownLoadEvent(MDownLoadObserver::ESuccess,0);

}

break;

case THTTPEvent::ESucceeded:

{

//iObserver.HandleDownLoadEvent(MDownLoadObserver::ESuccess,0);

}

break;

case THTTPEvent::EFailed:

{

iFile.Close();

BaflUtils::DeleteFile(iFs,iFileName);

iFs.Close();

iObserver.HandleDownLoadEvent(MDownLoadObserver::EFail,0);

}

break;

default:

// There are more events in THTTPEvent, but they are not usually

// needed. However, event status smaller than zero should be handled

// correctly since it's error.

{

if (aEvent.iStatus < 0)

{

// HBufC* resNoInternetConnection = StringLoader::LoadLC(

// R_HTTP_NO_INTERNET_CONNECTION, aEvent.iStatus);

// iObserver.ClientEvent(*resNoInternetConnection);

// CleanupStack::PopAndDestroy(resNoInternetConnection);

//

// // Close the transaction on errors

// aTransaction.Close();

// iRunning = EFalse;

}

else

{

// Other events are not errors (e.g. permanent and temporary

// // redirections)

// HBufC* resUnrecognisedEvent = StringLoader::LoadLC(

// R_HTTP_UNRECOGNISED_EVENT, aEvent.iStatus);

// iObserver.ClientEvent(*resUnrecognisedEvent);

// CleanupStack::PopAndDestroy(resUnrecognisedEvent);

}

}

break;

}

}

TInt CHttpDownLoadEngine::MHFRunError(TInt /*aError*/, RHTTPTransaction /*aTransaction*/, const THTTPEvent& /*aEvent*/)

{

iObserver.HandleDownLoadEvent(MDownLoadObserver::EFail,0);

}

TInt CHttpDownLoadEngine::StartDownLoadL(const TDesC8& aUrl,const TDesC8& aPostData,const TDesC& aFileName)

{

iFileName.Copy(aFileName);

iPostData = HBufC8::New(aPostData.Length());

TPtr8 postPtr = iPostData->Des();

postPtr.Copy(aPostData);

TBuf8<256> url;

url.Copy(aUrl);

TUriParser8 uri;

uri.Parse(url);

// Get request method string for HTTP POST

RStringF method = iSession.StringPool().StringF(HTTP::EPOST,RHTTPSession::GetTable());

// Open transaction with previous method and parsed uri. This class will

// receive transaction events in MHFRunL and MHFRunError.

iTransaction = iSession.OpenTransactionL(uri, *this, method);

// Set headers for request; user agent, accepted content type and body's

// content type.

RHTTPHeaders hdr = iTransaction.Request().GetHeaderCollection();

SetHeaderL(hdr, HTTP::EUserAgent, KUserAgent);

SetHeaderL(hdr, HTTP::EAccept, KAccept);

SetHeaderL(hdr, HTTP::EContentType, _L8("application/octet-stream"));

// Set this class as an data supplier. Inherited MHTTPDataSupplier methods

// are called when framework needs to send body data.

MHTTPDataSupplier* dataSupplier = this;

iTransaction.Request().SetBody(*dataSupplier);

// Submit the transaction. After this the framework will give transaction

// events via MHFRunL and MHFRunError.

iTransaction.SubmitL();

}

使用方法,实例化之后调用StartDownLoadL函数就可以了!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: