syncmlfw/common/syncagent/src/nsmlstatuscontainer.cpp
changeset 0 b497e44ab2fc
child 42 490439ac0bd4
child 73 ae69c2e8bc34
equal deleted inserted replaced
-1:000000000000 0:b497e44ab2fc
       
     1 /*
       
     2 * Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Client's Status command buffering
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 //#include "nsmlcliagdefines.h"
       
    21 #include "NSmlStatusContainer.h"
       
    22 #include "nsmlcliagconstants.h"
       
    23 #include "nsmlerror.h"
       
    24 #include "smlmetinfdtd.h"
       
    25 
       
    26 // ---------------------------------------------------------
       
    27 // CNSmlStatusContainer::CNSmlStatusContainer
       
    28 // Constructor, nothing special in here.
       
    29 // ---------------------------------------------------------
       
    30 //
       
    31 CNSmlStatusContainer::CNSmlStatusContainer()
       
    32 	{
       
    33 	}
       
    34 
       
    35 // ---------------------------------------------------------
       
    36 // CNSmlStatusContainer::ConstructL()
       
    37 // Two-way construction. Constructor may leave in EPOC.
       
    38 // ---------------------------------------------------------
       
    39 //
       
    40 void CNSmlStatusContainer::ConstructL(TBool aClearText)
       
    41 	{
       
    42 	iClearText = aClearText;
       
    43 	iStatusArray = new( ELeave ) CArrayFixFlat<TStatusData>(KNSmlStatusArrayGranularity);
       
    44 	iArrayInd = -1;
       
    45 	}
       
    46 
       
    47 // ---------------------------------------------------------
       
    48 // CNSmlStatusContainer::~CNSmlStatusContainer()
       
    49 // Destructor
       
    50 // ---------------------------------------------------------
       
    51 //
       
    52 
       
    53 CNSmlStatusContainer::~CNSmlStatusContainer()
       
    54 	{
       
    55 	delete iMsgRef;
       
    56 	if ( !iStatusArray )
       
    57 		{
       
    58 		return;
       
    59 		}
       
    60 	TInt arrayCount = iStatusArray->Count();
       
    61 	for ( TInt i = 0; i < arrayCount ; i++ )
       
    62 		{
       
    63 		FreeResources( i );
       
    64 		}
       
    65 	delete iStatusArray; 
       
    66 	}
       
    67 // ---------------------------------------------------------
       
    68 // CNSmlStatusContainer::NewL()
       
    69 // Creates new instance of CNSmlStatusContainer. 
       
    70 // Does not leave instance pointer to CleanupStack.
       
    71 // ---------------------------------------------------------
       
    72 //
       
    73 CNSmlStatusContainer* CNSmlStatusContainer::NewL( TBool aClearText)
       
    74 	{
       
    75 	CNSmlStatusContainer* self = CNSmlStatusContainer::NewLC(aClearText);
       
    76 	CleanupStack::Pop();
       
    77 	return( self );
       
    78 	}
       
    79 
       
    80 // ---------------------------------------------------------
       
    81 // CNSmlStatusContainer::NewLC()
       
    82 // Creates new instance of CNSmlStatusContainer 
       
    83 // Leaves instance pointer to CleanupStack.
       
    84 // ---------------------------------------------------------
       
    85 //
       
    86 CNSmlStatusContainer* CNSmlStatusContainer::NewLC(TBool aClearText)
       
    87 	{
       
    88 	CNSmlStatusContainer* self = new (ELeave) CNSmlStatusContainer();
       
    89 	CleanupStack::PushL( self );
       
    90 	self->ConstructL(aClearText);
       
    91 	return( self );
       
    92 	}
       
    93 // ---------------------------------------------------------
       
    94 // CNSmlStatusContainer::InitMsgRefL
       
    95 // Creates new empty Status element and adds it to the array
       
    96 // ---------------------------------------------------------
       
    97 //
       
    98 void CNSmlStatusContainer::InitMsgRefL( const SmlPcdata_t* aMsgRef )
       
    99 	{
       
   100 	delete iMsgRef;
       
   101 	iMsgRef = NULL;
       
   102 	CopyPcdataL( aMsgRef, iMsgRef );
       
   103 	}
       
   104 // ---------------------------------------------------------
       
   105 // CNSmlStatusContainer::CreateNewStatusElementL()
       
   106 // Creates new empty Status element and adds it to the array
       
   107 // ---------------------------------------------------------
       
   108 //
       
   109 EXPORT_C TInt CNSmlStatusContainer::CreateNewStatusElementL()
       
   110 	{
       
   111 	TStatusData statusData;
       
   112 	statusData.status = NULL;
       
   113 	statusData.noResponse = EFalse;
       
   114 	statusData.wasWritten = EFalse;
       
   115 	statusData.atomicOrSequenceID = 0;
       
   116 	statusData.performedInAtomic = EFalse;
       
   117 	statusData.statusIsFixed = EFalse;
       
   118 	iStatusArray->AppendL( statusData );
       
   119 	TInt i = iStatusArray->Count() - 1;
       
   120 	(*iStatusArray)[i].status = new( ELeave ) SmlStatus_t;
       
   121 	(*iStatusArray)[i].status->elementType = SML_PE_STATUS;
       
   122 	CopyPcdataL( iMsgRef, (*iStatusArray)[i].status->msgRef );
       
   123 	return iStatusArray->Count();
       
   124 	}
       
   125 // ---------------------------------------------------------
       
   126 // CNSmlStatusContainer::SetCmdIDL()
       
   127 // Sets CmdID element
       
   128 // ---------------------------------------------------------
       
   129 //
       
   130 void CNSmlStatusContainer::SetCmdIDL( TInt aEntryID, const SmlPcdata_t* aCmdID )
       
   131 	{
       
   132 	delete (*iStatusArray)[aEntryID-1].status->cmdID;
       
   133 	(*iStatusArray)[aEntryID-1].status->cmdID = NULL;
       
   134 	CopyPcdataL( aCmdID, (*iStatusArray)[aEntryID-1].status->cmdID );
       
   135 	}
       
   136 // ---------------------------------------------------------
       
   137 // CNSmlStatusContainer::SetMsgRefL()
       
   138 // Sets MsgRef element
       
   139 // ---------------------------------------------------------
       
   140 //
       
   141 void CNSmlStatusContainer::SetMsgRefL( TInt aEntryID, const SmlPcdata_t* aMsgRef )
       
   142 	{
       
   143 	delete (*iStatusArray)[aEntryID-1].status->msgRef;
       
   144 	(*iStatusArray)[aEntryID-1].status->msgRef = NULL;
       
   145 	CopyPcdataL( aMsgRef, (*iStatusArray)[aEntryID-1].status->msgRef );
       
   146 	}
       
   147 // ---------------------------------------------------------
       
   148 // CNSmlStatusContainer::SetCmdRefL()
       
   149 // Sets CmdRef element
       
   150 // ---------------------------------------------------------
       
   151 //
       
   152 EXPORT_C void CNSmlStatusContainer::SetCmdRefL( TInt aEntryID, const SmlPcdata_t* aCmdRef )
       
   153 	{
       
   154 	delete (*iStatusArray)[aEntryID-1].status->cmdRef;
       
   155 	(*iStatusArray)[aEntryID-1].status->cmdRef = NULL;
       
   156 	CopyPcdataL( aCmdRef, (*iStatusArray)[aEntryID-1].status->cmdRef );
       
   157 	}
       
   158 
       
   159 // ---------------------------------------------------------
       
   160 // CNSmlStatusContainer::SetCmdL()
       
   161 // Sets CmdRef element
       
   162 // ---------------------------------------------------------
       
   163 //
       
   164 EXPORT_C void CNSmlStatusContainer::SetCmdL( TInt aEntryID, const TDesC8& aCmd )
       
   165 	{
       
   166 	delete (*iStatusArray)[aEntryID-1].status->cmd;
       
   167 	(*iStatusArray)[aEntryID-1].status->cmd = NULL;
       
   168 	CreatePcdataL( (*iStatusArray)[aEntryID-1].status->cmd, aCmd );
       
   169 	}
       
   170 	
       
   171 // ---------------------------------------------------------
       
   172 // CNSmlStatusContainer::SetStatusCodeL()
       
   173 // Sets Status code to Data element 
       
   174 // Created element is not pushed to Cleanup stack
       
   175 // ---------------------------------------------------------
       
   176 EXPORT_C void CNSmlStatusContainer::SetStatusCodeL( TInt aEntryID, TInt aStatusCode, TBool aFixStatus )
       
   177 	{
       
   178 	//status code in data element
       
   179 	if ( !(*iStatusArray)[aEntryID-1].statusIsFixed )
       
   180 		{
       
   181 		HBufC8* statusCode = HBufC8::NewLC( KNSmlAgentStatusCodeLength );	
       
   182 		statusCode->Des().Num( aStatusCode );
       
   183 		if ( !(*iStatusArray)[aEntryID-1].status->data )
       
   184 			{
       
   185 			CreatePcdataL( (*iStatusArray)[aEntryID-1].status->data, *statusCode );
       
   186 			}
       
   187 		else
       
   188 			{
       
   189 			// Don't overwrite status 213 with 200, otherwise replace 
       
   190 			// existing status
       
   191 			TInt existingStatus( TNSmlError::ESmlStatusOK );
       
   192 			TBool ok = StatusCodeVal ( (*iStatusArray)[aEntryID-1].status->data, existingStatus );
       
   193 			if ( !( ok &&  existingStatus == TNSmlError::ESmlStatusItemAccepted &&
       
   194 			        aStatusCode == TNSmlError::ESmlStatusOK ) )
       
   195 		        {
       
   196     			delete (*iStatusArray)[aEntryID-1].status->data;
       
   197 	    		(*iStatusArray)[aEntryID-1].status->data = NULL;
       
   198 		    	CreatePcdataL( (*iStatusArray)[aEntryID-1].status->data, *statusCode ); 			        
       
   199 			    }
       
   200 			}
       
   201 		if ( aFixStatus)
       
   202 			{
       
   203 			(*iStatusArray)[aEntryID-1].statusIsFixed = ETrue;
       
   204 			}
       
   205 		}
       
   206 	CleanupStack::PopAndDestroy(); //statusCode
       
   207 	}
       
   208 // ---------------------------------------------------------
       
   209 // CNSmlStatusContainer::SetChalL()
       
   210 // Creates Chal element 
       
   211 // ---------------------------------------------------------
       
   212 void CNSmlStatusContainer::SetChalL( TInt aEntryID, const TDesC8& aNonce )
       
   213 	{
       
   214 	(*iStatusArray)[aEntryID-1].status->chal = new( ELeave ) SmlChal_t;
       
   215 	SmlMetInfMetInf_t* metInf = new( ELeave ) SmlMetInfMetInf_t;
       
   216 	CleanupStack::PushL( metInf );
       
   217 	CreatePcdataL( metInf->type, KNSmlAgentAuthMD5 );
       
   218 	CreatePcdataL( metInf->format, KNSmlAgentBase64Format );
       
   219 	CreatePcdataL( metInf->nextnonce, aNonce );
       
   220 	(*iStatusArray)[aEntryID-1].status->chal->meta = new( ELeave ) SmlPcdata_t; 
       
   221 	(*iStatusArray)[aEntryID-1].status->chal->meta->length = 0;
       
   222 	(*iStatusArray)[aEntryID-1].status->chal->meta->content = ( TAny* ) metInf;
       
   223 	CleanupStack::Pop(); //metInf
       
   224 	(*iStatusArray)[aEntryID-1].status->chal->meta->contentType = SML_PCDATA_EXTENSION;
       
   225 	(*iStatusArray)[aEntryID-1].status->chal->meta->extension = SML_EXT_METINF;
       
   226 	}
       
   227 // ---------------------------------------------------------
       
   228 // CNSmlStatusContainer::SetNoResponse
       
   229 // Sets NoResponse flag 
       
   230 // ---------------------------------------------------------
       
   231 EXPORT_C void CNSmlStatusContainer::SetNoResponse( TInt aEntryID, TBool aNoResponse )
       
   232 	{
       
   233 	(*iStatusArray)[aEntryID-1].noResponse = aNoResponse;
       
   234 	}
       
   235 
       
   236 // ---------------------------------------------------------
       
   237 // CNSmlStatusContainer::SetAtomicOrSequenceId
       
   238 // Sets Atomic or Sequence Id  
       
   239 // ---------------------------------------------------------
       
   240 EXPORT_C void CNSmlStatusContainer::SetAtomicOrSequenceId( TInt aEntryID, TInt aAtomicOrSequenceID )
       
   241 	{
       
   242 	(*iStatusArray)[aEntryID-1].atomicOrSequenceID = aAtomicOrSequenceID;
       
   243 	}
       
   244 // ---------------------------------------------------------
       
   245 // CNSmlStatusContainer::SetPerformedInAtomic
       
   246 // Mark an item be performed inside Atomic 
       
   247 // ---------------------------------------------------------
       
   248 EXPORT_C void CNSmlStatusContainer::SetPerformedInAtomic( TInt aEntryID )
       
   249 	{
       
   250 	(*iStatusArray)[aEntryID-1].performedInAtomic = ETrue;
       
   251 	}
       
   252 
       
   253 // ---------------------------------------------------------
       
   254 // CNSmlStatusContainer::SetStatusCodeToAtomicOrSequenceCmdL
       
   255 // Change status code for Atomic command 
       
   256 // ---------------------------------------------------------
       
   257 EXPORT_C void CNSmlStatusContainer::SetStatusCodeToAtomicOrSequenceCmdL( TInt aAtomicOrSequenceID, TInt aStatusCode, const TDesC8& aCmd )
       
   258 	{
       
   259 	TInt arrayCount = iStatusArray->Count();
       
   260 	for ( TInt i = 0; i < arrayCount; i++ )
       
   261 		{
       
   262 		if ( (*iStatusArray)[i].atomicOrSequenceID == aAtomicOrSequenceID )
       
   263 			{
       
   264 			if ( (*iStatusArray)[i].status->cmd )
       
   265 				{
       
   266 				if ( (*iStatusArray)[i].status->cmd->content )
       
   267 					{
       
   268 					TPtrC8 cmd( (TUint8*) (*iStatusArray)[i].status->cmd->content, (*iStatusArray)[i].status->cmd->length );
       
   269 					if ( cmd == aCmd )
       
   270 						{
       
   271 						SetStatusCodeL( i + 1, aStatusCode );
       
   272 						break;
       
   273 						}
       
   274 					}
       
   275 				}
       
   276 			}
       
   277 		}
       
   278 	}
       
   279 // ---------------------------------------------------------
       
   280 // CNSmlStatusContainer::SetStatusCodesInAtomicL
       
   281 // Change status code to all items in Atomic or to items which 
       
   282 // have been already performed
       
   283 // ---------------------------------------------------------
       
   284 EXPORT_C void CNSmlStatusContainer::SetStatusCodesInAtomicL( TInt aAtomicID, TInt aStatusCode, TBool aOnlyForPerformed )
       
   285 	{
       
   286 	TInt arrayCount = iStatusArray->Count();
       
   287 	for ( TInt i = 0; i < arrayCount; i++ )
       
   288 		{
       
   289 		if ( !(*iStatusArray)[i].atomicOrSequenceID == aAtomicID )
       
   290 			{
       
   291 			continue;
       
   292 			}
       
   293 		if ( (!aOnlyForPerformed) || ( aOnlyForPerformed && (*iStatusArray)[i].performedInAtomic ) )
       
   294 			{
       
   295 			SetStatusCodeL( i + 1, aStatusCode );
       
   296 			}
       
   297 		}
       
   298 	}
       
   299 
       
   300 // ---------------------------------------------------------
       
   301 // CNSmlStatusContainer::AddTargetRefL
       
   302 // Adds TargetRef element
       
   303 // ---------------------------------------------------------
       
   304 EXPORT_C void CNSmlStatusContainer::AddTargetRefL( TInt aEntryID, const SmlTarget_t* aTarget )
       
   305 	{
       
   306 	if ( !aTarget )
       
   307 		{
       
   308 		return;
       
   309 		}
       
   310 	if ( !aTarget->locURI )
       
   311 		{
       
   312 		return;
       
   313 		}
       
   314 	if ( !aTarget->locURI->content )
       
   315 		{
       
   316 		return;
       
   317 		}
       
   318 	SmlTargetRefList_t** targetRefList;
       
   319 	targetRefList = &(*iStatusArray)[aEntryID-1].status->targetRefList;
       
   320 	while( *targetRefList )
       
   321 		{
       
   322 		targetRefList = &(*targetRefList)->next;
       
   323 		} 
       
   324 	*targetRefList = new( ELeave ) SmlTargetRefList_t;
       
   325 	CreateTargetRefL( aTarget, (*targetRefList)->targetRef ); 
       
   326 	}
       
   327 // ---------------------------------------------------------
       
   328 // CNSmlStatusContainer::AddSourceRefL
       
   329 // Adds SourceRef element
       
   330 // ---------------------------------------------------------
       
   331 EXPORT_C void CNSmlStatusContainer::AddSourceRefL( TInt aEntryID, const SmlSource_t* aSource )
       
   332 	{
       
   333 	if ( !aSource )
       
   334 		{
       
   335 		return;
       
   336 		}
       
   337 	if ( !aSource->locURI )
       
   338 		{
       
   339 		return;
       
   340 		}
       
   341 	if ( !aSource->locURI->content )
       
   342 		{
       
   343 		return;
       
   344 		}
       
   345 	SmlSourceRefList_t** sourceRefList;
       
   346 	sourceRefList = &(*iStatusArray)[aEntryID-1].status->sourceRefList;
       
   347 	while ( *sourceRefList )
       
   348 		{
       
   349 		sourceRefList = &(*sourceRefList)->next;
       
   350 		} 
       
   351 	*sourceRefList = new( ELeave ) SmlSourceRefList_t;
       
   352 	CreateSourceRefL( aSource, (*sourceRefList)->sourceRef ); 
       
   353 	}
       
   354 // ---------------------------------------------------------
       
   355 // CNSmlStatusContainer::AddItemDataL
       
   356 // Adds Item/Data element 
       
   357 // ---------------------------------------------------------
       
   358 EXPORT_C void CNSmlStatusContainer::AddItemDataL (TInt aEntryID, const SmlPcdata_t* aData )
       
   359 	{
       
   360 	SmlItemList_t* newItemList = new( ELeave ) SmlItemList_t;
       
   361 	CleanupStack::PushL( newItemList );
       
   362 	newItemList->item = new( ELeave ) SmlItem_t;
       
   363 	CopyPcdataL( aData, newItemList->item->data );
       
   364 	SmlItemList_t** itemList;
       
   365 	itemList = &(*iStatusArray)[aEntryID-1].status->itemList;
       
   366 	while ( *itemList )
       
   367 		{
       
   368 		itemList = &(*itemList)->next;
       
   369 		}
       
   370 	*itemList = newItemList;
       
   371 	CleanupStack::Pop(); //newItemList
       
   372 	}
       
   373 // ---------------------------------------------------------
       
   374 // CNSmlStatusContainer::RemoveWritten()
       
   375 // Marks Status command written in outgoing XML document  
       
   376 // ---------------------------------------------------------
       
   377 void CNSmlStatusContainer::RemoveWritten( TInt aEntryID )
       
   378 	{
       
   379 	(*iStatusArray)[aEntryID-1].wasWritten = ETrue;
       
   380 	}
       
   381 
       
   382 // ---------------------------------------------------------
       
   383 // CNSmlStatusContainer::Begin
       
   384 // Sets index for reading to starting value 
       
   385 // ---------------------------------------------------------
       
   386 EXPORT_C void CNSmlStatusContainer::Begin()
       
   387 	{
       
   388 	iArrayInd = -1;
       
   389 	}
       
   390 // ---------------------------------------------------------
       
   391 // CNSmlStatusContainer::NextStatusElement()
       
   392 // Returns pointer to the next Status element 
       
   393 // ---------------------------------------------------------
       
   394 EXPORT_C TBool CNSmlStatusContainer::NextStatusElement( SmlStatus_t*& aStatus, TBool aOnlyIfResponse )
       
   395 	{
       
   396 	TBool moreElements( ETrue );
       
   397 	while ( moreElements )
       
   398 		{
       
   399 		iArrayInd++;
       
   400 		if ( iArrayInd > iStatusArray->Count() - 1 )
       
   401 			{
       
   402 			RemoveAllWrittenOnes();
       
   403 			iArrayInd = -1;
       
   404 			moreElements = EFalse;
       
   405 			}
       
   406 		else
       
   407 			{
       
   408 			if ( aOnlyIfResponse && (*iStatusArray)[iArrayInd].noResponse )
       
   409 				{
       
   410 				}
       
   411 			else 
       
   412 			if ( !(*iStatusArray)[iArrayInd].wasWritten )
       
   413 				{
       
   414 				aStatus = (*iStatusArray)[iArrayInd].status;
       
   415 				return ETrue;
       
   416 				}
       
   417 			}
       
   418 		}
       
   419 	return moreElements;
       
   420 	}
       
   421 // ---------------------------------------------------------
       
   422 // CNSmlStatusContainer::CurrentEntryID()
       
   423 // Returns current status ID 
       
   424 // ---------------------------------------------------------
       
   425 TInt CNSmlStatusContainer::CurrentEntryID() const
       
   426 	{
       
   427 	return( iArrayInd + 1);
       
   428 	}
       
   429 // ---------------------------------------------------------
       
   430 // CNSmlStatusContainer::LastEntryID()
       
   431 // Returns last status ID 
       
   432 // ---------------------------------------------------------
       
   433 EXPORT_C TInt CNSmlStatusContainer::LastEntryID() const
       
   434 	{
       
   435 	return iStatusArray->Count();
       
   436 	}
       
   437 // ---------------------------------------------------------
       
   438 // CNSmlStatusContainer::AnyOtherThanSyncHdrStatus()
       
   439 // 
       
   440 // ---------------------------------------------------------
       
   441 TBool CNSmlStatusContainer::AnyOtherThanOkSyncHdrStatus() const
       
   442 	{
       
   443 	TBool statusPresents = EFalse;
       
   444 	TInt arrayCount = iStatusArray->Count();
       
   445 	for ( TInt i = 0; i < arrayCount; i++ )
       
   446 		{
       
   447 		if ( !(*iStatusArray)[i].noResponse )
       
   448 			{
       
   449 			if ( (*iStatusArray)[i].status->cmd )
       
   450 				{
       
   451 				if ( (*iStatusArray)[i].status->cmd->content )
       
   452 					{
       
   453 					TPtrC8 cmd( (TUint8*) (*iStatusArray)[i].status->cmd->content, (*iStatusArray)[i].status->cmd->length );
       
   454 					if ( cmd == KNSmlAgentSyncHdr )
       
   455 						{
       
   456 						if ( (*iStatusArray)[i].status->data )
       
   457 							{
       
   458 							if ( (*iStatusArray)[i].status->data->content )
       
   459 								{
       
   460 								TPtrC8 statusCode( (TUint8*) (*iStatusArray)[i].status->data->content, (*iStatusArray)[i].status->data->length );
       
   461 								TLex8 lexicalValue( statusCode );
       
   462 								TInt statusCodeNum;
       
   463 								if ( lexicalValue.Val( statusCodeNum ) != KErrNone )
       
   464 									{
       
   465 									if ( statusCodeNum != TNSmlError::ESmlStatusOK &&
       
   466 										 statusCodeNum != TNSmlError::ESmlStatusAuthenticationAccepted )
       
   467 										{
       
   468 										statusPresents = ETrue;
       
   469 										break;
       
   470 										}
       
   471 									}
       
   472 								}
       
   473 							}
       
   474 						}
       
   475 					else
       
   476 						{
       
   477 						statusPresents = ETrue;
       
   478 						break;
       
   479 						}
       
   480 					}
       
   481 				}
       
   482 			}
       
   483 		}	
       
   484 	return statusPresents;
       
   485 	}
       
   486 // ---------------------------------------------------------
       
   487 // CNSmlStatusContainer::CreatePcdataL()
       
   488 // Creates Pcdata 
       
   489 // Created element is not pushed to Cleanup stack
       
   490 // ---------------------------------------------------------
       
   491 void CNSmlStatusContainer::CreatePcdataL( SmlPcdata_t*& aPcdata, const TDesC8& aContent ) const
       
   492 	{
       
   493 	aPcdata = new( ELeave ) SmlPcdata_t;
       
   494 	aPcdata->SetDataL( aContent );
       
   495 	aPcdata->contentType = SML_PCDATA_OPAQUE;   
       
   496 	aPcdata->extension = SML_EXT_UNDEFINED; 
       
   497 	}
       
   498 // ---------------------------------------------------------
       
   499 // CNSmlStatusContainer::CopyPcdataL()
       
   500 // Deep copy to Pcdata element
       
   501 // Copied element is not pushed to Cleanup stack
       
   502 // ---------------------------------------------------------
       
   503 //
       
   504 void CNSmlStatusContainer::CopyPcdataL( const SmlPcdata_t* aFromPcdata, SmlPcdata_t*& aToPcdata ) const
       
   505 	{
       
   506 	aToPcdata = NULL;
       
   507 	if ( aFromPcdata )
       
   508 		{
       
   509 		SmlPcdata_t* newPcdata = new( ELeave ) SmlPcdata_t;
       
   510 		CleanupStack::PushL( newPcdata );
       
   511 		newPcdata->length = aFromPcdata->length;
       
   512 		if (iClearText)
       
   513 			{
       
   514 			newPcdata->contentType = SML_PCDATA_STRING;
       
   515 			}
       
   516 		else
       
   517 			{
       
   518 			newPcdata->contentType = SML_PCDATA_OPAQUE;
       
   519 			}   
       
   520 		newPcdata->extension = SML_EXT_UNDEFINED; 
       
   521 		if ( aFromPcdata->content )
       
   522 			{
       
   523 			if ( aFromPcdata->contentType == SML_PCDATA_EXTENSION && aFromPcdata->extension == SML_EXT_METINF )
       
   524 				{
       
   525 				newPcdata->contentType = SML_PCDATA_EXTENSION;
       
   526 				newPcdata->extension = aFromPcdata->extension;
       
   527 				newPcdata->length = 0;
       
   528 				CopyMetInfL( aFromPcdata->content, newPcdata->content );
       
   529 				}
       
   530 			else
       
   531 				{
       
   532 				newPcdata->content = User::AllocL( 	newPcdata->length );
       
   533 				TPtr8 fromPtr ( (TUint8*) aFromPcdata->content, aFromPcdata->length );
       
   534 				fromPtr.SetLength( fromPtr.MaxLength() );
       
   535 				TPtr8 toPtr ( (TUint8*) newPcdata->content, newPcdata->length );
       
   536 				toPtr.SetLength( toPtr.MaxLength() );
       
   537 				toPtr = fromPtr;
       
   538 				}
       
   539 			}	
       
   540 		CleanupStack::Pop();  //newPcdata 
       
   541 		aToPcdata = newPcdata;
       
   542 		}
       
   543 	}
       
   544 
       
   545 // ---------------------------------------------------------
       
   546 // CNSmlStatusContainer::CopyMetInfL()
       
   547 // Deep copy to Meta Info
       
   548 // ---------------------------------------------------------
       
   549 void CNSmlStatusContainer::CopyMetInfL ( const void* aFromMetInf, void*& aToMetInf ) const
       
   550 	{
       
   551 	if ( aFromMetInf )
       
   552 		{
       
   553 		SmlMetInfMetInf_t* fromMetInf = (SmlMetInfMetInf_t*) aFromMetInf;
       
   554 		SmlMetInfMetInf_t* toMetInf = new( ELeave ) SmlMetInfMetInf_t;
       
   555 		if ( fromMetInf->anchor )
       
   556 			{
       
   557 			toMetInf->anchor = new( ELeave ) SmlMetInfAnchor_t;
       
   558 			CopyPcdataL( fromMetInf->anchor->next, toMetInf->anchor->next );
       
   559 			}
       
   560 		aToMetInf = toMetInf;
       
   561 		}
       
   562 	}
       
   563 // ---------------------------------------------------------
       
   564 // CNSmlStatusContainer::CreateTargetOrSourceRefL()
       
   565 // Creates TargetRef or SourceRef element
       
   566 // ---------------------------------------------------------
       
   567 void CNSmlStatusContainer::CreateSourceRefL( const SmlSource_t* aSource, SmlPcdata_t*& aSourceRef ) const
       
   568 	{
       
   569 	CopyPcdataL( aSource->locURI, aSourceRef );
       
   570 	}
       
   571 
       
   572 
       
   573 // ---------------------------------------------------------
       
   574 // CNSmlStatusContainer::CreateTargetOrSourceRefL()
       
   575 // Creates TargetRef or SourceRef element
       
   576 // ---------------------------------------------------------
       
   577 void CNSmlStatusContainer::CreateTargetRefL( const SmlTarget_t* aTarget, SmlPcdata_t*& aTargetRef ) const
       
   578 	{
       
   579 	CopyPcdataL( aTarget->locURI, aTargetRef );
       
   580 	}
       
   581 
       
   582 // ---------------------------------------------------------
       
   583 // CNSmlStatusContainer::RemoveAllWrittenOnes()
       
   584 // Removes all written Status elements 
       
   585 // ---------------------------------------------------------
       
   586 void CNSmlStatusContainer::RemoveAllWrittenOnes()
       
   587 	{
       
   588 	for ( TInt i = iStatusArray->Count() - 1; i >= 0; i--)
       
   589 		{
       
   590 		if ( (*iStatusArray)[i].wasWritten )
       
   591 			{
       
   592 			FreeResources( i );
       
   593 			iStatusArray->Delete( i );
       
   594 			}
       
   595 		}
       
   596 	iStatusArray->Compress();
       
   597 	iArrayInd = -1;
       
   598 	}
       
   599 
       
   600 // ---------------------------------------------------------
       
   601 // CNSmlStatusContainer::FreeResources()
       
   602 // Frees resources of an item
       
   603 // ---------------------------------------------------------
       
   604 void CNSmlStatusContainer::FreeResources( TInt aI )
       
   605 	{
       
   606 	delete (*iStatusArray)[aI].status;
       
   607 	}
       
   608 
       
   609 // ---------------------------------------------------------
       
   610 // CNSmlStatusContainer::StatusCodeVal()
       
   611 // Converts status code to integer value
       
   612 // ---------------------------------------------------------
       
   613 TBool CNSmlStatusContainer::StatusCodeVal ( SmlPcdata_t*& aStatusCodeData, TInt& aVal ) const
       
   614     {
       
   615     TBool ret(EFalse);
       
   616 	if ( aStatusCodeData->content )
       
   617 	    {
       
   618 	    TPtrC8 statusCode( (TUint8*) aStatusCodeData->content, aStatusCodeData->length );
       
   619 	    TLex8 lexicalValue( statusCode );
       
   620 	    TInt statusCodeNum( TNSmlError::ESmlStatusOK );
       
   621         if ( lexicalValue.Val( statusCodeNum ) == KErrNone )
       
   622 		    {
       
   623 		    ret = ETrue;
       
   624 		    aVal = statusCodeNum;
       
   625 			}
       
   626 		else
       
   627 		    {
       
   628 		    aVal = 0;
       
   629 		    }
       
   630 	    }
       
   631 	return ret;
       
   632     }
       
   633     
       
   634