mtptransports/mtpptpiptransport/ptpipdatatypes/src/cptpipdatacontainer.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 01:11:40 +0200
changeset 0 d0791faffa3f
permissions -rw-r--r--
Revision: 201003 Kit: 201005

// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
//

/**
 @internalComponent
*/

#include "ptpipdatatypes.h"
#include "cptpipdatacontainer.h"

// Dataset constants
const TUint CPTPIPDataContainer::KFlatChunkSize(12);

// Dataset element metadata.
const CMTPTypeCompoundBase::TElementInfo CPTPIPDataContainer::iElementMetaData[CPTPIPDataContainer::ENumElements] = 
    {
		{EIdFlatChunk,      EMTPTypeFlat,       {EMTPTypeUINT32,    0,                  KMTPTypeUINT32Size}},   // EContainerLength
        {EIdFlatChunk,      EMTPTypeFlat,       {EMTPTypeUINT32,    4,                  KMTPTypeUINT32Size}},   // EContainerType
        {EIdFlatChunk,      EMTPTypeFlat,       {EMTPTypeUINT32,    8,                  KMTPTypeUINT32Size}},   // ETransactionId
		{EIdPayloadChunk,   EMTPTypeUndefined,  {EMTPTypeUndefined, KMTPNotApplicable,  KMTPNotApplicable}}     // EPayload
    };

/**
 Generic Container's factory method. 
 This is used to create an empty MTP PTPIP data container dataset type. 
 @return  Ownership IS transfered.
 @leave One of the system wide error codes, if unsuccessful.
 */
EXPORT_C CPTPIPDataContainer* CPTPIPDataContainer::NewL()
	{
	CPTPIPDataContainer* self = new (ELeave) CPTPIPDataContainer();
	CleanupStack::PushL(self);
	self->ConstructL();
	CleanupStack::Pop(self);
	return self;
	}

/**
 Destructor.
 */
EXPORT_C CPTPIPDataContainer::~CPTPIPDataContainer()
	{
	iChunkHeader.Close();
	}

/**
 Constructor.
 */
CPTPIPDataContainer::CPTPIPDataContainer( ) :
	CMTPTypeCompoundBase((!KJustInTimeConstruction), EIdNumChunks), iChunkHeader(
			KFlatChunkSize, *this),
			iElementInfo(iElementMetaData, ENumElements),iIsNextHeader(EFalse)
	{
	
	}

/**
 Second phase constructor.
 */
void CPTPIPDataContainer::ConstructL( )
	{
	iChunkHeader.OpenL ( );
	ChunkAppendL (iChunkHeader );
	}

/**
 Provides the bulk container payload.
 @return The bulk container payload.
 */
EXPORT_C MMTPType* CPTPIPDataContainer::Payload() const
	{
	return iPayload;
	}

/**
 Sets the bulk container payload.
 @param aPayload The new bulk container payload.
 */
EXPORT_C void CPTPIPDataContainer::SetPayloadL(MMTPType* aPayload)
	{
	if (iPayload)
		{
		// Remove the existing payload from the super class.
		ChunkRemove(iElementMetaData[EPayload].iChunkId);
		}

	if (aPayload)
		{
		// Pass the payload to the super class for management.
		ChunkAppendL(*aPayload);
		}
	iPayload = aPayload;
	iIsNextHeader = EFalse; 
	}

EXPORT_C TUint CPTPIPDataContainer::Type() const
	{
	return EPTPIPTypeDataContainer;
	}

const CMTPTypeCompoundBase::TElementInfo& CPTPIPDataContainer::ElementInfo(
		TInt aElementId ) const
	{
	__ASSERT_DEBUG((aElementId < ENumElements), User::Invariant());
	return iElementInfo[aElementId];
	}
	
/**
  Over-ridden implementation of FirstWriteChunk() derived from CMTPTypeCompoundBase.
  This sets the Write Sequence-State to EInProgressNext, forcing the headers, from the second 
  PTP/IP packet onwards,to be ignored
  @param aChunk The data that is currently given by Initiator
 **/
EXPORT_C TInt CPTPIPDataContainer::FirstWriteChunk(TPtr8& aChunk)
	        {
	        TInt err(KErrNone);	        
	        
	        aChunk.Set(NULL, 0, 0);
	        
	        
	        if (iChunks.Count() == 0)
	            {
	            err = KErrNotFound;            
	            }
	        else
	            {
	            iWriteChunk = 0;
	            
	            TInt iWriteErr = iChunks[iWriteChunk]->FirstWriteChunk(aChunk);
	            
	            if ((iIsNextHeader) && (iWriteErr == KMTPChunkSequenceCompletion))
	            	iWriteErr = KErrNone;
	            
		        switch (iWriteErr)
		            {
		        case KMTPChunkSequenceCompletion:
		            if ((iWriteChunk + 1) < iChunks.Count()) 
		                {
		                iWriteSequenceState = EInProgressFirst;
		                err = KErrNone;
		                }
		            else
		                {
		                iWriteSequenceState = EIdle;                 
		                }
		            break;
		            
		        case KErrNone:
		            iWriteSequenceState = EInProgressNext;
		            break;
		            
		        default:
		            break;                      
	           } 
	            } 
	        
	        iIsNextHeader = ETrue;
	        
	        return err;
	        }

/**
  Over-ridden implementation of CommitChunkL() derived from CMTPTypeCompoundBase.
  This increments the number of chunks read only after, the first header is read
  @param aChunk The data that is currently given by Initiator
 **/
EXPORT_C MMTPType* CPTPIPDataContainer::CommitChunkL(TPtr8& aChunk)
	    {       
	    MMTPType *chunk(iChunks[iWriteChunk]);
	    MMTPType* res = NULL;
	    if (chunk->CommitRequired())
	        {
	        res = chunk->CommitChunkL(aChunk);
	        }
	        
	    
	    if (iWriteChunk == 0)
	        {
	        iWriteChunk++;            
	        }

	    return res;
	    }