⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 response.cpp

📁 symbian s60 end to end socket程序源码 基于第二版何第三版的sdk
💻 CPP
字号:
/*
* ============================================================================
*  Name     : CResponse from Response.cpp
*  Part of  : TaskManager
*  Created  : 08/31/2005 by Forum Nokia
*  Version  : 1.0
*  Copyright: Nokia Corporation
* ============================================================================
*/

// INCLUDE FILES
#include "Response.h"
#include "TaskManager.pan"

// CONSTANTS
_LIT(KError, "#Error:");
_LIT(KOkMessage, "#OK");
_LIT(KTab, "\t");
_LIT(KSeparator, "#");

// ================= MEMBER FUNCTIONS =======================

// constructor
CResponse::CResponse()
: iMessageBuffer( NULL ), iExpectedPackageSize( 0 ), iState( ENotComplete )
	{
	}
	
// destructor	
CResponse::~CResponse()
	{
	iIds.Close();
	delete iDescriptions;
	delete iMessageBuffer;
	}

// ----------------------------------------------------
// CResponse::NewL()
// Two-phased constructor.
// ----------------------------------------------------
//	
CResponse* CResponse::NewL()
	{
	CResponse* self = CResponse::NewLC();
	CleanupStack::Pop(self);
	return self;
	}

// ----------------------------------------------------
// CResponse::NewLC()
// Two-phased constructor.
// ----------------------------------------------------
//	
CResponse* CResponse::NewLC()
	{
	CResponse* self = new (ELeave) CResponse;
	CleanupStack::PushL(self);
	self->ConstructL();
	return self;
	}

// ----------------------------------------------------
// CResponse::ConstructL()
// Symbian OS default constructor can leave.
// ----------------------------------------------------
//	
void CResponse::ConstructL()
	{
	iDescriptions = new (ELeave) CDesCArrayFlat(1);
    iMessageBuffer = HBufC::NewL(0);
	}

// ----------------------------------------------------
// CResponse::InputDataL()
// This functions constructs a response object from the 
// data received from the server. E.g. if aData contains 
// tasks, tasks are parsed to arrays, where they can be 
// easily fetched. 
// ----------------------------------------------------
//	
void CResponse::ParseDataL( TDesC& aData )
	{
	// error occurred in the server side (i.e. the aData begins #Error: ).
	if (KError() == aData.Left(7))
		{
		iState = EError;
		// remove the #-character.
		iError = aData.Mid(1);
		return;
		}
	
	// response for completing task.
	if (aData.Find(KOkMessage) != KErrNotFound)
		{
		iResponseType = ETaskComplete;
		return;
		}
		
	TLex lex(aData);
	TTaskReadStatus status = EStart;
	
	// Tasks are in form: #id#description#id#description#
	while (!lex.Eos())
		{
		if (lex.Peek() == TChar(KSeparator()[0]))
			{
			switch (status)
				{
				// first #-character found
				case EStart:
					{
					status = EReadId;
					break;
					}
				// read the id of the tasks.
				case EReadId:
					{
					status = EReadTask;
					TInt id;
					TLex tmp(lex.MarkedToken());
					User::LeaveIfError(tmp.Val(id));
					User::LeaveIfError(iIds.Append(id));
					break;
					}
				// read the description of the task.
				case EReadTask:
					{
					status = EReadId;
					TPtrC task = lex.MarkedToken();
					iDescriptions->AppendL(task);
					break;
					}
				}
			lex.Inc();
			lex.Mark();
			}
		else
			{
			lex.Inc();	
			}
		}	
	}

// ----------------------------------------------------
// CResponse::HasError()
// Returns whether errors occurred in the server side 
// or not.
// ----------------------------------------------------
//	
TBool CResponse::HasError() const
	{
	TBool retval = EFalse;
	if (iError.Length() > 0)
		{
		retval = ETrue;
		}
	return retval;
	}

// ----------------------------------------------------
// CResponse::Error()
// Returns the error description. 
// ----------------------------------------------------
//	
TBuf<KMaxError> CResponse::Error() const
	{
	return iError;
	}

// ----------------------------------------------------
// CResponse::TaskCount()
// Returns the amount of tasks received from the server. 
// ----------------------------------------------------
//	
TInt CResponse::TaskCount() const
	{
	return iIds.Count();
	}

// ----------------------------------------------------
// CResponse::TaskDescription()
// Returns a task description. 
// ----------------------------------------------------
//	
TBuf<KMaxTaskLength> CResponse::TaskDescription(const TInt& aIndex) const
	{
	if (aIndex >= iDescriptions->Count() || 0 > aIndex)
		{
		Panic(ETaskManagerInvalidTaskIndex);
		}
		
	return (*iDescriptions)[aIndex];
	}

// ----------------------------------------------------
// CResponse::TaskId()
// Returns a task id. 
// ----------------------------------------------------
//	
TInt CResponse::TaskId(const TInt& aIndex) const
	{
	if (aIndex >= iDescriptions->Count() || 0 > aIndex)
		{
		Panic(ETaskManagerInvalidTaskIndex);
		}

	return iIds[aIndex];
	}

// ----------------------------------------------------
// CResponse::ResponseType()
// Returns the type of this response. 
// ----------------------------------------------------
//	
CResponse::TResponseType CResponse::ResponseType() const
	{
	return iResponseType;
	}

// ----------------------------------------------------
// CResponse::InputDataL()
// Makes it possible to store a part of the data into the
// CResponse class.
// ----------------------------------------------------
//	
void CResponse::InputDataL( const TDesC8& aData )
    {
    iMessageBuffer = iMessageBuffer->ReAllocL(iMessageBuffer->Length() + aData.Length());
    HBufC* newData = HBufC::NewLC(aData.Length());
    newData->Des().Copy(aData);
    iMessageBuffer->Des() += newData->Des();
    CleanupStack::PopAndDestroy(newData);
    
    DoCheck();
    }

// ----------------------------------------------------
// CResponse::DoCheck()
// Does a check on the received package and sets the state
// that determines what the engine should do next.
// ----------------------------------------------------
//	
void CResponse::DoCheck()
    {
	if( iExpectedPackageSize == 0 )
		{
		// We try to extract the size of the package, which should be found in the beginning
		// of the package, before the first separator character
		TInt separatorIndex = iMessageBuffer->Find( KSeparator );

		if( separatorIndex == KErrNotFound )
			{ // The size of the package can't be read before the first separator sign is found
            iState = ENotComplete;
            return;
			}

        // Extracted size is converted into TInt
		TPtrC sizePtr = iMessageBuffer->Left( separatorIndex );

		TLex converter( sizePtr );
		if( converter.Val( iExpectedPackageSize ) != KErrNone )
			{ // conversion failed
            iState = EError;
            return;
			}
		}

    TBuf<6> asciiSize;
    asciiSize.Num( iExpectedPackageSize );

    if( iMessageBuffer->Length() - asciiSize.Length() < iExpectedPackageSize )
        { // The entire package hasn't been received
        iState = ENotComplete;
        return;
        }

    iExpectedPackageSize = 0;

    // The size component is cut from the message
    TPtrC data = iMessageBuffer->Right( iMessageBuffer->Length() -
                                        iMessageBuffer->Find( KSeparator ) );
    
	TRAPD(error, ParseDataL( data );)
	PanicIfError(error);
	
	iState = EComplete;
    }

// ----------------------------------------------------
// CResponse::GetState()
// Returns the state to the engine.
// ----------------------------------------------------
//	
CResponse::TResponseState CResponse::GetState() const
    {
    return iState;
    }

// End of file

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -