mtpfws/mtpfw/datatypes/interface/cmtptypefile.h
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 01:11:40 +0200
changeset 0 d0791faffa3f
child 1 f8e15b44d440
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:
//

/**
 @file
 @publishedPartner
 @released
*/

#ifndef CMTPTYPEFILE_H
#define CMTPTYPEFILE_H

#include <e32base.h>
#include <f32file.h>
#include <mtp/mmtptype.h>
    
/**
Defines the MTP file object data type. 
@publishedPartner
@released 
*/
class CMTPTypeFile : public CActive, public MMTPType
    {
public:

    IMPORT_C static CMTPTypeFile* NewL(RFs& aFs, const TDesC& aFileName, TFileMode aFileMode);
    IMPORT_C static CMTPTypeFile* NewLC(RFs& aFs, const TDesC& aFileName, TFileMode aFileMode);
	IMPORT_C static CMTPTypeFile* NewL(RFs& aFs, const TDesC& aFileName, TFileMode aFileMode, TInt64 aRequiredSize, TInt64 aOffSet = 0);
	IMPORT_C static CMTPTypeFile* NewLC(RFs& aFs, const TDesC& aFileName, TFileMode aFileMode, TInt64 aRequiredSize, TInt64 aOffSet = 0);
    IMPORT_C ~CMTPTypeFile();
    IMPORT_C void SetSizeL(TUint64 aSize);
#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
    IMPORT_C RFile64& File();
#else
    IMPORT_C RFile& File();
#endif

public: // From MMTPType
    IMPORT_C TInt FirstReadChunk(TPtrC8& aChunk) const;
    IMPORT_C TInt NextReadChunk(TPtrC8& aChunk) const;
    IMPORT_C TInt FirstWriteChunk(TPtr8& aChunk);
    IMPORT_C TInt NextWriteChunk(TPtr8& aChunk);
    IMPORT_C TUint64 Size() const;
    IMPORT_C TUint Type() const;
    IMPORT_C TBool CommitRequired() const;
	IMPORT_C MMTPType* CommitChunkL(TPtr8& aChunk);
	IMPORT_C TInt64 GetByteSent();
    
private:
    CMTPTypeFile();
    void ConstructL(RFs& aFs, const TDesC& aName, TFileMode aMode);
	void ConstructL(RFs& aFs, const TDesC& aName, TFileMode aMode, TInt64 aRequiredSize, TInt64 aOffSet);
    void ToggleRdWrBuffer();

protected: // From CActive
    void DoCancel();

private: // From CActive
	
    TInt RunError(TInt aError);
    void RunL();
private:

    /**
    The read and write data stream states.
    */
    enum TReadWriteSequenceState
        {
        /**
        Data stream is inactive.
        */
        EIdle,
        
        /**
        Data stream is in progress.
        */
        EInProgress            
        };

    /**
    The intermediate data buffer. Note that this is declared mutable to allow 
    state updates while processing a read data stream.
    */
    mutable RBuf8 iBuffer1;

	
    /**
    The intermediate data buffer. Note that this is declared mutable to allow 
    state updates while processing a read data stream.
    Used for double-buffering, the 2 buffers(buffer1 and buffer2) will be switched between reading data
    from USB to buffer and writting data from Buffer into File System.
    */
    mutable RBuf8 iBuffer2;

    /**
    The flag indicate if this buffer is avaiable for writting data into, if true, it is ready for
    USB-SIC to write file data into it, if false, it already contains file data, and is waiting
    for writting the file data into file system.
    The two buffer must be used in strict sequence, if both buffer is available, the buffer1 must
    be firstly used by USB driver. 
    */
    mutable TBool  iBuffer1AvailForWrite; 

    //If there occurs error during writting/reading data into/from this file, mark this flag as true, this will abort
    //all further writting/reading and set the file size to 0 if needed.
    mutable TBool  iFileRdWrError;

    //This point to the current chunk which is waiting for being commit into File system. it might point to
    //either of the 2 buffers.
    mutable TPtr8  iCurrentCommitChunk;

    //true if the file is opened for reading; false if it is opened for Writting.
    TBool          iFileOpenForRead;

    //For file reading, used to indicate how much bytes are waiting to be read, for file writting, indicate how much
    //byte are wating to be received by USB and writting to file.
    mutable TInt64 iRemainingDataSize;

    //The RFile::SetSize() method may take over 40 seconds if we create a file and set its size
    //to a very large value, and this will cause timeout in MTP protocol layer. To avoid this 
    //timeout, when creating a large file(over 512MB), instead of setting its size directly to
    //the target size by one singile RFile::SetSize() call, we'll call RFile::SetSize() multiple
    //times and set the file size step by step acumulately. For example, for a 2GB file, its
    //size will be set to 0.5G first, and then 1G, 1.5G and at last 2G.
    
    //For file reading, used to indicate the target size to be transfered to initiator, for file writting, used to 
    //incicate the target size for a file that being transfering to device.
    TInt64         iTargetFileSize;
    
    //This is the acumulated received size for the file represented by this object.
    TInt64         iTotalReceivedSize;

    //This represent the current size we call SetSize() to the file.
    TInt64         iCurrentFileSetSize;
    /**
    The data file. Note that this is declared mutable to allow state updates
    while processing a read data stream.
    */
#ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API
    mutable RFile64 iFile;
#else
    mutable RFile   iFile;
#endif
    /**
    The read data stream state variable. Note that this is declared mutable 
    to allow state updates while processing a read data stream.
    */
    mutable TUint   iReadSequenceState;
    
    /**
    The write data stream state variable.
    */
    TUint           iWriteSequenceState;

	TInt64          iOffSet;
    
    mutable TInt64          iByteSent;

    };
    
#endif // CMTPTYPEFILE_H