00001 /* 00002 * ============================================================================ 00003 * Name : CResponse from Response.cpp 00004 * Part of : TaskManager 00005 * Created : 15/03/2006 by Forum Nokia 00006 * Version : 1.2 00007 * Copyright: Nokia Corporation 00008 * ============================================================================ 00009 */ 00010 00011 // INCLUDE FILES 00012 #include "Response.h" 00013 #include "TaskManager.pan" 00014 00015 // CONSTANTS 00016 _LIT(KError, "#Error:"); 00017 _LIT(KOkMessage, "#OK"); 00018 _LIT(KTab, "\t"); 00019 _LIT(KSeparator, "#"); 00020 00021 // ================= MEMBER FUNCTIONS ======================= 00022 00023 // constructor 00024 CResponse::CResponse() 00025 : iMessageBuffer( NULL ), iExpectedPackageSize( 0 ), iState( ENotComplete ) 00026 { 00027 } 00028 00029 // destructor 00030 CResponse::~CResponse() 00031 { 00032 iIds.Close(); 00033 delete iDescriptions; 00034 delete iMessageBuffer; 00035 } 00036 00037 // ---------------------------------------------------- 00038 // CResponse::NewL() 00039 // Two-phased constructor. 00040 // ---------------------------------------------------- 00041 // 00042 CResponse* CResponse::NewL() 00043 { 00044 CResponse* self = CResponse::NewLC(); 00045 CleanupStack::Pop(self); 00046 return self; 00047 } 00048 00049 // ---------------------------------------------------- 00050 // CResponse::NewLC() 00051 // Two-phased constructor. 00052 // ---------------------------------------------------- 00053 // 00054 CResponse* CResponse::NewLC() 00055 { 00056 CResponse* self = new (ELeave) CResponse; 00057 CleanupStack::PushL(self); 00058 self->ConstructL(); 00059 return self; 00060 } 00061 00062 // ---------------------------------------------------- 00063 // CResponse::ConstructL() 00064 // Symbian OS default constructor can leave. 00065 // ---------------------------------------------------- 00066 // 00067 void CResponse::ConstructL() 00068 { 00069 iDescriptions = new (ELeave) CDesCArrayFlat(1); 00070 iMessageBuffer = HBufC::NewL(0); 00071 } 00072 00073 // ---------------------------------------------------- 00074 // CResponse::InputDataL() 00075 // This functions constructs a response object from the 00076 // data received from the server. E.g. if aData contains 00077 // tasks, tasks are parsed to arrays, where they can be 00078 // easily fetched. 00079 // ---------------------------------------------------- 00080 // 00081 void CResponse::ParseDataL( TDesC& aData ) 00082 { 00083 // error occurred in the server side (i.e. the aData begins #Error: ). 00084 if (KError() == aData.Left(7)) 00085 { 00086 iState = EError; 00087 // remove the #-character. 00088 iError = aData.Mid(1); 00089 return; 00090 } 00091 00092 // response for completing task. 00093 if (aData.Find(KOkMessage) != KErrNotFound) 00094 { 00095 iResponseType = ETaskComplete; 00096 return; 00097 } 00098 00099 TLex lex(aData); 00100 TTaskReadStatus status = EStart; 00101 00102 // Tasks are in form: #id#description#id#description# 00103 while (!lex.Eos()) 00104 { 00105 if (lex.Peek() == TChar(KSeparator()[0])) 00106 { 00107 switch (status) 00108 { 00109 // first #-character found 00110 case EStart: 00111 { 00112 status = EReadId; 00113 break; 00114 } 00115 // read the id of the tasks. 00116 case EReadId: 00117 { 00118 status = EReadTask; 00119 TInt id; 00120 TLex tmp(lex.MarkedToken()); 00121 User::LeaveIfError(tmp.Val(id)); 00122 User::LeaveIfError(iIds.Append(id)); 00123 break; 00124 } 00125 // read the description of the task. 00126 case EReadTask: 00127 { 00128 status = EReadId; 00129 TPtrC task = lex.MarkedToken(); 00130 iDescriptions->AppendL(task); 00131 break; 00132 } 00133 } 00134 lex.Inc(); 00135 lex.Mark(); 00136 } 00137 else 00138 { 00139 lex.Inc(); 00140 } 00141 } 00142 } 00143 00144 // ---------------------------------------------------- 00145 // CResponse::HasError() 00146 // Returns whether errors occurred in the server side 00147 // or not. 00148 // ---------------------------------------------------- 00149 // 00150 TBool CResponse::HasError() const 00151 { 00152 TBool retval = EFalse; 00153 if (iError.Length() > 0) 00154 { 00155 retval = ETrue; 00156 } 00157 return retval; 00158 } 00159 00160 // ---------------------------------------------------- 00161 // CResponse::Error() 00162 // Returns the error description. 00163 // ---------------------------------------------------- 00164 // 00165 TBuf<KMaxError> CResponse::Error() const 00166 { 00167 return iError; 00168 } 00169 00170 // ---------------------------------------------------- 00171 // CResponse::TaskCount() 00172 // Returns the amount of tasks received from the server. 00173 // ---------------------------------------------------- 00174 // 00175 TInt CResponse::TaskCount() const 00176 { 00177 return iIds.Count(); 00178 } 00179 00180 // ---------------------------------------------------- 00181 // CResponse::TaskDescription() 00182 // Returns a task description. 00183 // ---------------------------------------------------- 00184 // 00185 TBuf<KMaxTaskLength> CResponse::TaskDescription(const TInt& aIndex) const 00186 { 00187 if (aIndex >= iDescriptions->Count() || 0 > aIndex) 00188 { 00189 Panic(ETaskManagerInvalidTaskIndex); 00190 } 00191 00192 return (*iDescriptions)[aIndex]; 00193 } 00194 00195 // ---------------------------------------------------- 00196 // CResponse::TaskId() 00197 // Returns a task id. 00198 // ---------------------------------------------------- 00199 // 00200 TInt CResponse::TaskId(const TInt& aIndex) const 00201 { 00202 if (aIndex >= iDescriptions->Count() || 0 > aIndex) 00203 { 00204 Panic(ETaskManagerInvalidTaskIndex); 00205 } 00206 00207 return iIds[aIndex]; 00208 } 00209 00210 // ---------------------------------------------------- 00211 // CResponse::ResponseType() 00212 // Returns the type of this response. 00213 // ---------------------------------------------------- 00214 // 00215 CResponse::TResponseType CResponse::ResponseType() const 00216 { 00217 return iResponseType; 00218 } 00219 00220 // ---------------------------------------------------- 00221 // CResponse::InputDataL() 00222 // Makes it possible to store a part of the data into the 00223 // CResponse class. 00224 // ---------------------------------------------------- 00225 // 00226 void CResponse::InputDataL( const TDesC8& aData ) 00227 { 00228 iMessageBuffer = iMessageBuffer->ReAllocL(iMessageBuffer->Length() + aData.Length()); 00229 HBufC* newData = HBufC::NewLC(aData.Length()); 00230 newData->Des().Copy(aData); 00231 iMessageBuffer->Des() += newData->Des(); 00232 CleanupStack::PopAndDestroy(newData); 00233 00234 DoCheck(); 00235 } 00236 00237 // ---------------------------------------------------- 00238 // CResponse::DoCheck() 00239 // Does a check on the received package and sets the state 00240 // that determines what the engine should do next. 00241 // ---------------------------------------------------- 00242 // 00243 void CResponse::DoCheck() 00244 { 00245 if( iExpectedPackageSize == 0 ) 00246 { 00247 // We try to extract the size of the package, which should be found in the beginning 00248 // of the package, before the first separator character 00249 TInt separatorIndex = iMessageBuffer->Find( KSeparator ); 00250 00251 if( separatorIndex == KErrNotFound ) 00252 { // The size of the package can't be read before the first separator sign is found 00253 iState = ENotComplete; 00254 return; 00255 } 00256 00257 // Extracted size is converted into TInt 00258 TPtrC sizePtr = iMessageBuffer->Left( separatorIndex ); 00259 00260 TLex converter( sizePtr ); 00261 if( converter.Val( iExpectedPackageSize ) != KErrNone ) 00262 { // conversion failed 00263 iState = EError; 00264 return; 00265 } 00266 } 00267 00268 TBuf<6> asciiSize; 00269 asciiSize.Num( iExpectedPackageSize ); 00270 00271 if( iMessageBuffer->Length() - asciiSize.Length() < iExpectedPackageSize ) 00272 { // The entire package hasn't been received 00273 iState = ENotComplete; 00274 return; 00275 } 00276 00277 iExpectedPackageSize = 0; 00278 00279 // The size component is cut from the message 00280 TPtrC data = iMessageBuffer->Right( iMessageBuffer->Length() - 00281 iMessageBuffer->Find( KSeparator ) ); 00282 00283 TRAPD(error, ParseDataL( data );) 00284 PanicIfError(error); 00285 00286 iState = EComplete; 00287 } 00288 00289 // ---------------------------------------------------- 00290 // CResponse::GetState() 00291 // Returns the state to the engine. 00292 // ---------------------------------------------------- 00293 // 00294 CResponse::TResponseState CResponse::GetState() const 00295 { 00296 return iState; 00297 } 00298 00299 // End of file
Copyright ©2010 Nokia Corporation and/or its subsidiary(-ies).
All rights
reserved. Unless otherwise stated, these materials are provided under the terms of the Eclipse Public License
v1.0.