?? aoexampleengine.cpp
字號:
/*
* ==============================================================================
* Name : CAOExampleEngine
* Part of : AOExample
* Created : 3.5.2004
* Implementation notes: See detailed documentation from the file
* "AOExampleEngine.h"
* Version :
* Copyright: Nokia
* ==============================================================================
*/
#include <es_sock.h>
#include "AOExampleEngine.h"
#include "Debug.h"
enum TLeaveCodes
{
EAlreadyFetching,
EInvalidProtocol,
EURLDocumentMissing,
};
// -----------------------------------------------------------------------------
CAOExampleEngine* CAOExampleEngine::NewLC()
{
CAOExampleEngine* result = new (ELeave) CAOExampleEngine();
CleanupStack::PushL( result );
result->ConstructL();
return result;
}
// -----------------------------------------------------------------------------
CAOExampleEngine::CAOExampleEngine()
: CActive( CActive::EPriorityStandard )
{
}
// -----------------------------------------------------------------------------
void CAOExampleEngine::ConstructL()
{
User::LeaveIfError( iSocketServ.Connect() );
// connect to host resolver server
User::LeaveIfError(iHostResolver.Open( iSocketServ, KAfInet,
KProtocolInetUdp ) );
CActiveScheduler::Add(this); // add to AS queue
DEBUG( iFileLogger = CFileLogger::NewL() );
}
// -----------------------------------------------------------------------------
CAOExampleEngine::~CAOExampleEngine()
{
if( IsAdded() )
{
Deque(); // calls also Cancel()
}
iHostResolver.Close();
iSocketServ.Close();
DEBUG( delete iFileLogger );
}
// -----------------------------------------------------------------------------
void CAOExampleEngine::FetchFileL( const TDesC& anURL,
CBufBase* aBuffer,
MEngineObserver* anObserver )
{
if( iState != ENotConnected )
{
_LIT( KError, "Engine is already fetching a file (it is now cancelled)" );
iObserver->Cancelled(KError);
Reset();
User::Leave(EAlreadyFetching);
}
iObserver = anObserver;
iOutputBuffer = aBuffer;
ParseURLL( anURL, *anObserver, iServerName, iPort, iDocument );
/*DEBUGLOG( iFileLogger,
Format( _L( "Parsed URL: server=%S, iPort=%d, doc=%S\n" ),
&iServerName,
iPort,
&iDocument
)
);*/
ResolveIP();
}
// -----------------------------------------------------------------------------
void CAOExampleEngine::ParseURLL( const TDesC& anURL,
MEngineObserver& anObserver,
TDes& aServerName,
TInt& aPort,
TDes& aDocument )
{
// check that protocol is http
TBuf<7> buf;
_LIT( KHTTPProtocol, "http://" );
buf.Copy( anURL.Left(7) );
buf.LowerCase();
if( buf.Compare( KHTTPProtocol ) != 0 )
{
_LIT( KError, "Invalid protocol. The URL must start with http://" );
anObserver.Cancelled( KError );
User::Leave( EInvalidProtocol );
}
// skip the starting chars: "http://"
TPtrC rest = anURL.Right(anURL.Length() - 7);
TInt aPortIndex = rest.Locate( TChar(':') );
TInt aDocIndex = rest.Locate( TChar('/') );
if( aDocIndex == KErrNotFound )
{
_LIT( KError, "No document specified in URL" );
anObserver.Cancelled( KError );
User::Leave(EURLDocumentMissing);
}
// server name ends either to port or document part since port is optional
aServerName.Copy( rest.Left( aPortIndex != KErrNotFound ?
aPortIndex : aDocIndex ) );
aPort = 80;
if( aPortIndex != KErrNotFound )
{
TLex lex( rest.Mid(aPortIndex+1, aDocIndex - aPortIndex ) );
lex.Val( aPort );
}
aDocument.Copy( rest.Right( rest.Length() - aDocIndex ) );
}
// -----------------------------------------------------------------------------
void CAOExampleEngine::RunL()
{
DEBUGLOG( iFileLogger,Format( _L("RunL():%d,%d\n"), iStatus, iState) );
switch( iState )
{
case ELookingUpIP:
if( iStatus == KErrNone )
{
// convert socket address to inet address
TInetAddr addr( iNameEntry().iAddr );
addr.SetPort( iPort );
Connect( addr );
}
else
{
_LIT( KFormat,
"Failed to obtain IP for \"%S\" (error %d)." );
iMsgBuf.Format( KFormat, &iServerName, iStatus );
iObserver->Cancelled( iMsgBuf );
Reset();
}
break;
case EConnecting:
{
if( iStatus == KErrNone )
{
MakeHTTPRequest();
}
else
{
_LIT( KFormat,
"Failed to connect to port %d on \"%S\" (error %d)." );
iMsgBuf.Format( KFormat, iPort, &iServerName, iStatus );
iObserver->Cancelled( iMsgBuf );
Reset();
}
break;
}
case EWriting:
if( iStatus == KErrNone )
{
iSocketBuf.Zero(); //reset buffer (remove http request).
ReadHTTPResponse(TRUE);
}
else
{
_LIT( KFormat, "Failed to write HTTP request (error %d)." );
iMsgBuf.Format( KFormat, iStatus );
iObserver->Cancelled( iMsgBuf );
Reset();
}
break;
case EReading:
if( iStatus == KErrNone )
{
ReadHTTPResponse(TRUE);
}
else if( iStatus == KErrEof )
{
ReadHTTPResponse(FALSE);
iObserver->FileFetched( iOutputBuffer );
Reset();
}
else
{
_LIT( KFormat, "Failed to read HTTP response (error %d)." );
iMsgBuf.Format( KFormat, iStatus );
iObserver->Cancelled( iMsgBuf );
Reset();
}
break;
}
}
// -----------------------------------------------------------------------------
void CAOExampleEngine::ResolveIP()
{
iState = ELookingUpIP;
iObserver->ToState( ELookingUpIP );
// make an asynchronous call to get the IP of the host
iHostResolver.GetByName(iServerName, iNameEntry, iStatus);
SetActive();
}
// -----------------------------------------------------------------------------
void CAOExampleEngine::Connect(TInetAddr& aInetAddr)
{
iState = EConnecting;
iObserver->ToState( EConnecting );
TInt err = iSocket.Open( iSocketServ, KAfInet, KSockStream,
KProtocolInetTcp );
if( err != KErrNone )
{
_LIT( KMsg, "Failed to open socket: %d." );
iMsgBuf.Format( KMsg, err );
iObserver->Cancelled( iMsgBuf );
Reset();
}
iSocket.Connect(aInetAddr, iStatus);
SetActive();
}
// -----------------------------------------------------------------------------
void CAOExampleEngine::MakeHTTPRequest()
{
iState = EWriting;
iObserver->ToState( EWriting );
// Construct an HTTP request, e.g. "GET /docs/index.html HTTP/1.0\n\n"
_LIT(K1, "GET ");
_LIT(K2, " HTTP/1.0\n\n");
iSocketBuf.Copy( K1 );
iSocketBuf.Append( iDocument );
iSocketBuf.Append( K2 );
iSocket.Write( iSocketBuf, iStatus );
SetActive();
}
// -----------------------------------------------------------------------------
void CAOExampleEngine::ReadHTTPResponse(TBool aContinue)
{
iState = EReading;
iObserver->ToState( EReading );
// append data read from the socket to the end of the output buffer
// todo: L-method called from non-L method
iOutputBuffer->InsertL( iOutputBuffer->Size(), iSocketBuf );
iSocketBuf.Zero();
if( aContinue )
{
iSocket.RecvOneOrMore( iSocketBuf, 0, iStatus, iStupid );
SetActive();
}
}
// -----------------------------------------------------------------------------
void CAOExampleEngine::Reset()
{
switch (iState)
{
case EWriting:
case EReading:
case EConnecting:
iSocket.CancelAll();
iSocket.Close();
break;
case ELookingUpIP:
iHostResolver.Cancel();
break;
}
iState = ENotConnected;
}
// -----------------------------------------------------------------------------
void CAOExampleEngine::DoCancel()
{
Reset();
}
// -----------------------------------------------------------------------------
DEBUG(
void CAOExampleEngine::Log(const TDesC& msg)
{
DEBUGLOG( iFileLogger,Copy(msg) );
}
)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -