📄 weatherinfo.cpp
字号:
// weatherinfo.cpp
//
// Copyright (c) Symbian Software Ltd 1999 - 2007. All rights reserved.
//
/*===========================================================================
This file contains the active object for collecting the weather info
from the network.
The sequence of events to collect the temparature is started by the
GetTemperature() method and issueing the host resolve. When that is complete
RunL() is invoked and the next network call in the sequence and is called and so on
until temperature is retrieved.
============================================================================*/
#include "weatherinfo.h"
CWeatherInfo* CWeatherInfo::NewL(MWeatherObserver& aObserver)
{
CWeatherInfo* self = new(ELeave) CWeatherInfo(aObserver);
CActiveScheduler::Add(self);
return self;
}
// This isn't a UI object, but is performing background network retrieval so
// doesn't need user input priority...or does it?
CWeatherInfo::CWeatherInfo(MWeatherObserver& aObserver)
: CActive(CActive::EPriorityStandard), iObserver(aObserver)
{}
void CWeatherInfo::GetTemperature(const TDesC& aCity)
{
// if we are already in the middle of getting the temperature, then
// return.
if (IsActive())
return;
iCommState=EInitializing;
TInt res =iSocketSrv.Connect();
if (res != KErrNone)
{
Cleanup(res);
return;
}
iCityCode.Copy(aCity);
/*-------------------------------------------------------------------------------------
Use the RConnection API to start the network connection if not already started.
------------------------------------------------------------------------------------- */
res = iConnection.Open(iSocketSrv);
if (res != KErrNone)
{
Cleanup(res);
return;
}
res = iConnection.Start();
if (res != KErrNone)
{
Cleanup(res);
return;
}
/*------------------------------------------------------------------------------------
Open the socket.
------------------------------------------------------------------------------------*/
iSocket.Open(iSocketSrv,KAfInet,KSockStream,KProtocolInetTcp,iConnection);
if (res != KErrNone)
{
Cleanup(res);
return;
}
/* Resolve name, rest handled by RunL() */
res = iResolver.Open(iSocketSrv, KAfInet, KProtocolInetTcp,iConnection);
if (res != KErrNone)
{
Cleanup(res);
return;
}
iCommState=EResolvingName;
_LIT(KWeatherServerName,"rainmaker.wunderground.com");
iResolver.GetByName(KWeatherServerName, iNameEntry, iStatus);
SetActive();
}
CWeatherInfo::~CWeatherInfo()
{
// Make sure we're cancelled
Cancel();
}
void CWeatherInfo::RunL()
{
if (iStatus != KErrNone)
{
Cleanup(iStatus.Int());
}
else
{
switch(iCommState)
{
case EResolvingName:
{
TInetAddr destAddr;
destAddr=iNameEntry().iAddr;
destAddr.SetPort(3000);
// Connect to the remote host
iCommState=EConnecting;
iSocket.Connect(destAddr,iStatus);
SetActive();
break;
}
case EConnecting:
{
_LIT(KCRLF,"\xD\xA");
TBuf8<300> getBuff;
getBuff.Copy(KCRLF);
getBuff.Append(iCityCode);
getBuff.Append(KCRLF);
iCommState=ESending;
iSocket.Send(getBuff,0,iStatus);
SetActive();
break;
}
case ESending:
{
// Start receiving
iCommState=EReceiving;
iSocket.RecvOneOrMore(iNetBuff,0,iStatus,iLen);
SetActive();
break;
}
case EReceiving:
{
/*-------------------------------------------------------------------
The rainmaker.wunderground.com line with the temperature starts
after a line filled with '='s.
-------------------------------------------------------------------*/
_LIT8(KFileTok,"=\xA");
TInt pos = iNetBuff.FindF(KFileTok);
TBuf<100> temp;
if (pos != KErrNotFound)
{
temp.Copy(iNetBuff.Mid(pos+2,10));
temp.Trim();
iObserver.TemperatureReport(iCityCode,temp);
Cleanup(KErrNone);
}
else
{
iSocket.RecvOneOrMore(iNetBuff,0,iStatus,iLen);
SetActive();
}
break;
}
default:
ASSERT(EFalse); // Should never get here
}
}
}
void CWeatherInfo::DoCancel()
{
iSocket.CancelAll();
Cleanup(KErrCancel);
}
void CWeatherInfo::Cleanup(TInt aError)
{
iSocket.Close();
iResolver.Close();
iConnection.Close();
iSocketSrv.Close();
TBuf<50> errStr;
if (aError!=KErrNone)
{
switch (iCommState)
{
case EInitializing:
{
_LIT(KErrStr,"Error initializing communications");
errStr.Copy(KErrStr);
break;
}
case EResolvingName:
{
_LIT(KErrStr,"Error resolving name");
errStr.Copy(KErrStr);
break;
}
case EConnecting:
{
_LIT(KErrStr,"Error connecting to server");
errStr.Copy(KErrStr);
break;
}
case ESending:
{
_LIT(KErrStr,"Error sending request");
errStr.Copy(KErrStr);
break;
}
case EReceiving:
{
_LIT(KErrStr,"Error receiving data");
errStr.Copy(KErrStr);
break;
}
default:
{
_LIT(KErrStr,"Unknown error");
errStr.Copy(KErrStr);
break;
}
}
iObserver.TemperatureError(errStr,aError);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -