mtpfws/mtpfw/datatypes/src/mmtptype.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) 2006-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:
//

#include <mtp/mmtptype.h>
#include <mtp/mtpdatatypeconstants.h>
#include <e32base.h> 

EXPORT_C TBool MMTPType::CommitRequired() const
    {
    return EFalse;
    }
	
EXPORT_C MMTPType* MMTPType::CommitChunkL(TPtr8& /*aChunk*/)
    {
    User::Leave(KErrNotSupported);
    return NULL;
    }
    
EXPORT_C TInt MMTPType::Validate() const
    {
    return KErrNone;
    }
    
EXPORT_C void MMTPType::CopyL(const MMTPType& aFrom, MMTPType& aTo)
    {
    TBool commit(aTo.CommitRequired());
    TBool complete(EFalse);
    TPtr8 dest(NULL, 0);
    TPtrC8 src;
    TBool useAoWrite = EFalse;
    if(EMTPTypeFile == aTo.Type()) //should change later use API to get the write type
        {
        useAoWrite = ETrue;
        }
    
    TInt readErr(KErrNone);
    TInt writeErr(KErrNone);
    
    // Obtain the initial read and write chunks.
    User::LeaveIfError(readErr = aFrom.FirstReadChunk(src));
    User::LeaveIfError(writeErr = aTo.FirstWriteChunk(dest));
    
    while (!complete)
        {
        TUint dataAvailable(src.Length());
        TUint writeCapacity(dest.MaxLength() - dest.Length());
        
        complete = 
            (((readErr == KMTPChunkSequenceCompletion) && !dataAvailable) || 
            (writeErr == KMTPChunkSequenceCompletion));
            
        if (writeCapacity < dataAvailable)
            {
            if (writeCapacity)
                {
                /* 
                Write chunk capacity is available, but not enough to accomodate
                the available read chunk data. Fill the available write chunk 
                capacity and adjust the read chunk pointer.
                */
                dest.Append(src.Left(writeCapacity));                    
                src.Set(src.Right(dataAvailable - writeCapacity));
                }
                
            if (commit)
                {
                /*
                Always commit write chunks which require it, even if the write
                chunk has no capacity.
                */
                aTo.CommitChunkL(dest);   
                if(useAoWrite)
                    {
                    TInt err = KErrNone;
                    while(CActiveScheduler::RunIfReady(err, CActive::EPriorityIdle))
                        {
                        //let the write ao run
                        }
                    User::LeaveIfError(err);
                    }
                }

            if (writeErr != KMTPChunkSequenceCompletion)
                {
                // Obtain the next write chunk
                User::LeaveIfError(writeErr = aTo.NextWriteChunk(dest));  
                }
            }
        else if (dataAvailable)
            {
            /* 
            Write chunk can accomodate the available read chunk data. Consume
            the available read chunk data, adjust the read chunk pointer, 
            and obtain the next write chunk.
            */
            dest.Append(src);
            if (commit && (dest.Length() == dest.MaxLength() || KMTPChunkSequenceCompletion == readErr)) //doesn't commit a half chunk unless it is the last chunk
                {
                aTo.CommitChunkL(dest);
                if(useAoWrite)
                    {
                    TInt err = KErrNone;
                    while(CActiveScheduler::RunIfReady(err, CActive::EPriorityIdle))
                        {
                        //let the write ao run
                        }
                    User::LeaveIfError(err);
                    }
                }

            if (readErr != KMTPChunkSequenceCompletion)
                {
                User::LeaveIfError(readErr = aFrom.NextReadChunk(src)); 
                }
            else
                {
                src.Set(KNullDesC8);   
                }

            /*
            If the write chunk is full, and more write chunks are available, 
            obtain the next write chunk.
            */
            if ((dest.Length() == dest.MaxLength()) && (writeErr != KMTPChunkSequenceCompletion))
                {
                User::LeaveIfError(writeErr = aTo.NextWriteChunk(dest));  
                }
            }
        }        
    }

EXPORT_C TAny* MMTPType::GetExtendedInterface(TUid /*aInterfaceUid*/)
    {
    return NULL;
    }

EXPORT_C TInt MMTPType::FirstWriteChunk(TPtr8& aChunk, TUint /*aDataLength*/ )
    {
    return FirstWriteChunk(aChunk);
    }

EXPORT_C TInt MMTPType::NextWriteChunk(TPtr8& aChunk, TUint /*aDataLength*/ )
    {
    return NextWriteChunk(aChunk);
    }

EXPORT_C TBool MMTPType::ReserveTransportHeader(TUint /* aHeaderLength */, TPtr8& /* aHeader */)
    {
    return EFalse;
    }