mmfenh/enhancedmediaclient/Plugins/FileSource/src/FileSource.cpp
changeset 0 71ca22bcf22a
equal deleted inserted replaced
-1:000000000000 0:71ca22bcf22a
       
     1 /*
       
     2 * Copyright (c) 2006 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:  Implementation of FileSource.
       
    15 *  Version     : %version: bh1mmcf#5.1.7 %
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 #include <f32file.h>
       
    21 #include <e32std.h>
       
    22 #include <mmfdatabuffer.h>
       
    23 #include <mmfutilities.h>
       
    24 #include <mmf/common/mmfcontroller.h>
       
    25 #include <mmfpaniccodes.h>
       
    26 #include "FileMultimediaSource.h"
       
    27 #include "FileDataSource.h"
       
    28 #include "MmffilePriv.h"
       
    29 #include "FileAccess.h"
       
    30 #include "SinkQueueItem.h"
       
    31 #include "FileDataSourceCommon.h"
       
    32 #include <MultimediaDataSourceEvents.h>
       
    33 #include "FileSourceUid.h"
       
    34 
       
    35 
       
    36 #ifdef _DEBUG
       
    37 #define DEBPRN1(str)        RDebug::Print(str);
       
    38 #define DEBPRN2(str, val1)   RDebug::Print(str, val1);
       
    39 #define DEBPRN3(str, val1, val2)   RDebug::Print(str, val1, val2);
       
    40 #define DEBPRN4(str, val1, val2, val3)   RDebug::Print(str, val1, val2, val3);
       
    41 #define DEBPRN5(str, val1, val2, val3, val4)   RDebug::Print(str, val1, val2, val3, val4);
       
    42 #else
       
    43 #define DEBPRN1(str)
       
    44 #define DEBPRN2(str, val1)
       
    45 #define DEBPRN3(str, val1, val2)
       
    46 #define DEBPRN4(str, val1, val2, val3)
       
    47 #define DEBPRN5(str, val1, val2, val3, val4)
       
    48 #endif // _DEBUG
       
    49 
       
    50 void Panic(TMMFFilePanicCode aPanicCode)
       
    51     {
       
    52     _LIT(KMMFFilePanicCategory, "MMFFile");
       
    53     User::Panic(KMMFFilePanicCategory, aPanicCode);
       
    54     }
       
    55 
       
    56 /**
       
    57 * Constructs a CTransferBufferCopy
       
    58 *
       
    59 * @return CTransferBufferCopy*
       
    60 */
       
    61 CTransferBufferCopy* CTransferBufferCopy::NewL(TInt aMaxLength)
       
    62     {
       
    63     CTransferBufferCopy* self = new (ELeave) CTransferBufferCopy(aMaxLength);
       
    64     CleanupStack::PushL(self);
       
    65     self->ConstructL();
       
    66     CleanupStack::Pop(self);
       
    67     return self;
       
    68     }
       
    69 
       
    70 /**
       
    71 * Second phase constructor for CTransferBufferCopy
       
    72 *
       
    73 * @return void
       
    74 */
       
    75 void CTransferBufferCopy::ConstructL()
       
    76     {
       
    77     iBuffer = static_cast<TUint8*>(User::AllocL(iMaxLength));
       
    78     iBufferDes.Set(iBuffer,0,iMaxLength);
       
    79     }
       
    80 
       
    81 
       
    82 
       
    83 CFileSource* CFileSource::NewL(TUid aType )
       
    84     {
       
    85     DEBPRN1(_L("CFileSource::NewL"));
       
    86     CFileSource* self = new (ELeave) CFileSource(aType);
       
    87     CleanupStack::PushL(self);
       
    88     self->ConstructL();
       
    89     CleanupStack::Pop(self);
       
    90     return self;
       
    91     }
       
    92 
       
    93 CFileSource::CFileSource(TUid aType)
       
    94 : MDataSource(aType)
       
    95     {
       
    96     iInitData = NULL;
       
    97     }
       
    98 
       
    99 CFileSource::~CFileSource(void)
       
   100     {
       
   101     delete iInitData;
       
   102     iInitData = NULL;        
       
   103     }
       
   104 
       
   105 void CFileSource::ConstructL (void)
       
   106     {
       
   107     }
       
   108 
       
   109 // From MDataSource begins
       
   110 TUid CFileSource::DataSourceType() const
       
   111     {
       
   112     return KMmfFileSource;
       
   113     }
       
   114 
       
   115 
       
   116 TFourCC CFileSource::SourceDataTypeCode(TMediaId /*aMediaId*/ )
       
   117     {
       
   118     TFourCC fourCC;        
       
   119     return iMultiMediaSource->GetDataTypeCode(fourCC);
       
   120     }
       
   121 
       
   122 TInt CFileSource::SetSourceDataTypeCode(TFourCC aSourceFourCC,
       
   123                                                   TMediaId /*aMediaId*/ )
       
   124     {
       
   125     iMultiMediaSource->SetDataTypeCode(aSourceFourCC);
       
   126     return KErrNone;
       
   127     }
       
   128 
       
   129 void CFileSource::FillBufferL(CMMFBuffer* aBuffer,
       
   130                                         MDataSink* aConsumer,
       
   131                                         TMediaId /*aMediaId*/ )
       
   132     {
       
   133     // Requires that iFile is open for read.
       
   134     // Reads data from iFile into aBuffer
       
   135     //TInt status(KErrNone);
       
   136     if ((!aConsumer) || (!aBuffer))
       
   137         User::Leave(KErrArgument);
       
   138     
       
   139     iMultiMediaSource->AppendBufferToSinkQueue(aBuffer,NULL,aConsumer,EFalse);
       
   140     iMultiMediaSource->ServiceFillBuffer();
       
   141     }
       
   142 
       
   143 void CFileSource::BufferEmptiedL(CMMFBuffer* /*aBuffer*/ )
       
   144     {
       
   145     User::Leave(KErrUnknown);
       
   146     }
       
   147 
       
   148 TBool CFileSource::CanCreateSourceBuffer()
       
   149     {
       
   150     return EFalse;
       
   151     }
       
   152 
       
   153 CMMFBuffer* CFileSource::CreateSourceBufferL(TMediaId /*aMediaId*/,
       
   154                                                        TBool &/*aReference*/ )
       
   155     {
       
   156     return NULL;
       
   157     }
       
   158 
       
   159 TInt CFileSource::SourceThreadLogon( MAsyncEventHandler& /*aEventHandler*/ )
       
   160     {
       
   161     return iMultiMediaSource->Open();
       
   162     }
       
   163 
       
   164 void CFileSource::SourceThreadLogoff()
       
   165     {
       
   166     iMultiMediaSource->Close();
       
   167     }
       
   168 
       
   169 void CFileSource::SourcePrimeL()
       
   170     {
       
   171     DEBPRN1(_L("CFileSource::SourcePrimeL"));
       
   172     User::LeaveIfError(iMultiMediaSource->Prime());
       
   173     }
       
   174 
       
   175 void CFileSource::SourcePlayL()
       
   176     {
       
   177     DEBPRN1(_L("CFileSource::SourcePlayL"));
       
   178     User::LeaveIfError(iMultiMediaSource->Play());
       
   179     }
       
   180 
       
   181 void CFileSource::SourceStopL()
       
   182     {
       
   183     DEBPRN1(_L("CFileSource::SourceStopL"));
       
   184     User::LeaveIfError(iMultiMediaSource->Stop());
       
   185     }
       
   186 
       
   187 
       
   188 void CFileSource::ConstructSourceL(const TDesC8& aInitData )
       
   189     {
       
   190     if(iInitData)
       
   191         {
       
   192         delete iInitData;
       
   193         iInitData = NULL;        
       
   194         }
       
   195     iInitData = aInitData.AllocL();        
       
   196     }
       
   197 
       
   198 void CFileSource::SourceCustomCommand(TMMFMessage& aMessage)
       
   199     {
       
   200     iMultiMediaSource->SourceCustomCommand(aMessage);        
       
   201     }
       
   202 
       
   203 void CFileSource::SetMultimediaSource(CFileMultimediaSource& aMultimediaSource)
       
   204     {
       
   205     iMultiMediaSource = &aMultimediaSource;   
       
   206     }
       
   207 
       
   208 TDesC8& CFileSource::GetInitData()
       
   209     {
       
   210     return *iInitData;    
       
   211     }
       
   212 
       
   213 
       
   214 
       
   215 
       
   216 EXPORT_C CFileMultimediaSource* CFileMultimediaSource::NewL(MDataSource& aDataSource)
       
   217     {
       
   218     DEBPRN1(_L("CFileMultimediaSource::NewL"));
       
   219     CFileMultimediaSource* self = new (ELeave) CFileMultimediaSource(aDataSource);
       
   220     CleanupStack::PushL(self);
       
   221     self->ConstructL();
       
   222     CleanupStack::Pop(self);
       
   223     return self;
       
   224     }
       
   225 
       
   226 
       
   227 
       
   228 /**
       
   229 Destructor.
       
   230 */
       
   231 CFileMultimediaSource::~CFileMultimediaSource() 
       
   232     {
       
   233     DEBPRN1(_L("CFileMultimediaSource::~CFileMultimediaSource() "));    
       
   234     
       
   235     delete iInitData;
       
   236     
       
   237     delete iFile;
       
   238     EmptySinkQueue();
       
   239     iHandle.Close();
       
   240     iFsSession.Close();
       
   241     delete iFileName;
       
   242     delete iFileExt;
       
   243     delete iFilePath;
       
   244     delete iFileDrive;
       
   245     
       
   246     
       
   247     delete iCAFParameters;
       
   248     delete iSinkQueue;
       
   249     
       
   250     if(iMessage)
       
   251         {
       
   252         if(!iMessage->IsCompleted())
       
   253             {
       
   254             iMessage->Complete(KErrDied);
       
   255             delete iMessage;
       
   256             iMessage = NULL;
       
   257             }
       
   258         }
       
   259     // Get rid of everything in RArray's & close them.
       
   260     iRequests.ResetAndDestroy();
       
   261     iTransferBufferCopies.ResetAndDestroy();
       
   262     DEBPRN1(_L("CFileMultimediaSource::~CFileMultimediaSource() exit"));   
       
   263     }
       
   264 
       
   265 /**
       
   266 Protected constructor.
       
   267 
       
   268 The default implementation is empty.
       
   269 */
       
   270 CFileMultimediaSource::CFileMultimediaSource(
       
   271                                        MDataSource& aDataSource )
       
   272                                        : iSnkItemsCount(0),
       
   273                                        iSnkBytes(0),
       
   274                                        iDownloadSize(0),
       
   275                                        iTransferRate(0),
       
   276                                        //iConsumer(NULL),
       
   277                                        iBufferedDataSize(0),
       
   278                                        iDLFileSize(0),
       
   279                                        isDownloadComplete(EFalse),
       
   280                                        iFileSize(0),
       
   281                                        iParentDataSource(&aDataSource)
       
   282     {
       
   283     iMessage = NULL;
       
   284     iFile = NULL;
       
   285     iState = ECLOSED;
       
   286     iObserver = NULL;    
       
   287     iInitData = NULL;
       
   288     }
       
   289 
       
   290 /**
       
   291 Constructs an CFileMultimediaSource MDataSource.
       
   292 
       
   293 @return A pointer to the new CFileMultimediaSource data source.
       
   294 */
       
   295 /*MDataSource* CFileMultimediaSource::NewSourceL() 
       
   296     {
       
   297     CFileMultimediaSource* self = new (ELeave) CFileMultimediaSource( KMmfFileSource ) ;
       
   298     return STATIC_CAST( MDataSource*, self ) ;
       
   299     }*/
       
   300 
       
   301 
       
   302 /**
       
   303 Perform source construction dependant on the source construction
       
   304 initialisation data aInitData.
       
   305 
       
   306 @param  aInitData
       
   307 The TPckg<TMMFFileParams> descriptor package containing the file name and full path.
       
   308 */
       
   309 void CFileMultimediaSource::ConstructL()
       
   310     {
       
   311     CFileSource* fileSource = static_cast<CFileSource*>(iParentDataSource);    
       
   312     iInitData = (fileSource->GetInitData()).AllocL();
       
   313     fileSource->SetMultimediaSource(*this);
       
   314     ConstructL(*iInitData, ESourceMode);
       
   315     iSinkQueue = new(ELeave) TSglQue<CSinkQueueItem>(_FOFF(CSinkQueueItem, iLink));
       
   316     }
       
   317 
       
   318 
       
   319 /**
       
   320 Protected constructor.
       
   321 
       
   322 Extracts the initialisation data provided by the calling functions: ConstructSourceL() and 
       
   323 ConstructSinkL(). Creates a file server session and sets up file name. If there is a file name and 
       
   324 it cannot be found this function leaves. If there is no file name the function leaves. Does not 
       
   325 attempt to open the file or check whether the file exists.
       
   326 
       
   327 If aInitData contains a TMMFFileHandleParams instead of TMMFFileParams, the source/sink is constructed from 
       
   328 the file handle provided by the caller
       
   329 
       
   330 @param  aInitData
       
   331 Initialisation data packaged in a TMMFFileParams or in a TMMFFileHandleParams (File Handle)
       
   332 */
       
   333 void CFileMultimediaSource::ConstructL(const TDesC8& aInitData,TMMFileMode aFileMode)
       
   334     {
       
   335     User::LeaveIfError(iFsSession.Connect());
       
   336     // on IPCv2 we auto attach
       
   337     User::LeaveIfError(iFsSession.ShareAuto());
       
   338     
       
   339     User::LeaveIfError(iFsSession.ShareProtected());
       
   340     
       
   341     TBool fileInit = EFalse;
       
   342     HBufC* filename = NULL; 
       
   343     TBool filenamePushed = EFalse;
       
   344     
       
   345     iCAFParameters = new (ELeave) CCAFParameters;
       
   346     TBool drmContent = EFalse;
       
   347     RDesReadStream stream(aInitData);
       
   348     CleanupClosePushL(stream);
       
   349 
       
   350     TUid initUid;
       
   351     
       
   352     initUid = TUid::Uid(stream.ReadInt32L());
       
   353     
       
   354     if (initUid == KMMFileHandleSourceUid)
       
   355         {
       
   356         TPckgBuf<RFile*> fileptr;
       
   357         stream.ReadL(fileptr);
       
   358         
       
   359         iHandle.Duplicate(*fileptr());
       
   360         
       
   361         TInt length;
       
   362         length = stream.ReadInt32L();
       
   363         if (length>0)
       
   364             {
       
   365             iCAFParameters->iUniqueId = HBufC::NewL(length);
       
   366             TPtr16 ptr = iCAFParameters->iUniqueId->Des();
       
   367             stream.ReadL(ptr, length);
       
   368             }
       
   369         iFileHandle = ETrue;
       
   370         filename = HBufC::NewMaxL(KMaxFileName);
       
   371         TPtr ptr = filename->Des();
       
   372         iHandle.Name(ptr);
       
   373         fileInit = ETrue;
       
   374         drmContent = ETrue;
       
   375         
       
   376         iCAFParameters->iEnableUI = stream.ReadInt32L();
       
   377         }
       
   378     
       
   379     else if (initUid == KMMFileSourceUid)
       
   380         {
       
   381         TInt length;
       
   382         length = stream.ReadInt32L();
       
   383         filename = HBufC::NewMaxLC(length);
       
   384         TPtr ptr = filename->Des();
       
   385         stream.ReadL(ptr, length);
       
   386         
       
   387         length = stream.ReadInt32L();
       
   388         if (length>0)
       
   389             {
       
   390             iCAFParameters->iUniqueId = HBufC::NewMaxL(length);
       
   391             ptr.Set(iCAFParameters->iUniqueId->Des());
       
   392             stream.ReadL(ptr, length);
       
   393             }
       
   394         CleanupStack::Pop(filename);
       
   395         
       
   396         fileInit = ETrue;
       
   397         drmContent = ETrue;
       
   398         iFileHandle = EFalse; 
       
   399         iCAFParameters->iEnableUI = stream.ReadInt32L();
       
   400         }
       
   401     else
       
   402         {
       
   403         //		TODO If the UID is unknown we should reject, but  currently
       
   404         //		code also used for older calls that just supply filename.
       
   405         //		User::Leave(KErrNotSupported);
       
   406         }
       
   407     
       
   408     CleanupStack::PopAndDestroy(&stream);
       
   409     
       
   410     if (!fileInit && aInitData.Length() == sizeof(TMMFFileHandleParams))
       
   411         {
       
   412         TMMFFileHandleParams params;
       
   413         TPckgC<TMMFFileHandleParams> config(params);
       
   414         config.Set(aInitData);
       
   415         params = config();
       
   416         
       
   417         
       
   418         if (params.iUid == KFileHandleUid)
       
   419             {
       
   420             fileInit = ETrue;
       
   421             User::LeaveIfError(iHandle.Duplicate(*params.iFile));
       
   422             TInt pos = 0;
       
   423             // make sure the duplicate handle is at the start of the file - the usage of the file handle really requires this
       
   424             User::LeaveIfError(iHandle.Seek(ESeekStart, pos));
       
   425             iFileHandle = ETrue;
       
   426             filename = HBufC::NewMaxLC(KMaxFileName);
       
   427             filenamePushed = ETrue;
       
   428             TPtr ptr = filename->Des();
       
   429             User::LeaveIfError(iHandle.Name(ptr));
       
   430             }
       
   431         }
       
   432     
       
   433     if (!fileInit) // do old case as last resort
       
   434         {
       
   435         TMMFFileParams params;
       
   436         TPckgC<TMMFFileParams> config(params);
       
   437         config.Set(aInitData);
       
   438         params = config();
       
   439         
       
   440         filename = params.iPath.AllocL();
       
   441         fileInit = ETrue;
       
   442         }
       
   443     
       
   444     if (!filenamePushed)
       
   445         {
       
   446         // from now on it is assumed pushed.
       
   447         CleanupStack::PushL(filename);
       
   448         }
       
   449     
       
   450     TParse parser ;
       
   451     User::LeaveIfError(parser.Set(*filename, NULL, NULL));
       
   452     CleanupStack::PopAndDestroy(filename);
       
   453     if ( !( parser.NamePresent() ) && !( parser.ExtPresent() ) )
       
   454         User::Leave( KErrBadName ) ;
       
   455     
       
   456     iFullFileName.Copy( parser.FullName() ) ;	
       
   457     iFileName = parser.Name().AllocL() ;
       
   458     iFileExt = parser.Ext().AllocL() ;
       
   459     iFilePath = parser.Path().AllocL() ;
       
   460     iFileDrive = parser.Drive().AllocL() ;
       
   461     
       
   462     // in order to simulate old behaviour we are not passing error out
       
   463     // but will try to create Content again during PrimeL()
       
   464     if (fileInit && drmContent && aFileMode==ESourceMode)
       
   465         {
       
   466         TInt contentError;
       
   467         if (iFileHandle)
       
   468             {
       
   469             TRAP(contentError, 
       
   470                 iFile = CContentFile::NewL(iHandle, UniqueId(), iCAFParameters->iEnableUI);
       
   471             );
       
   472             }
       
   473         else
       
   474             {
       
   475             // Open for read-only access
       
   476             TRAP(contentError,
       
   477                 iFile = CContentFile::NewL(iFsSession, iFullFileName, UniqueId(), EFileShareAny, iCAFParameters->iEnableUI);
       
   478             );
       
   479             }
       
   480         }
       
   481     }
       
   482     
       
   483     
       
   484 /**
       
   485 @deprecated
       
   486 
       
   487 Returns an RFile handle to the current file.
       
   488 
       
   489 If there is no current file, one is created. If the file exists then it is opened with read access 
       
   490 if it is read only, write access otherwise. If the file does not exist then it is opened with
       
   491 write access.
       
   492 
       
   493 @leave KErrNotReady
       
   494 The file is not open.
       
   495 
       
   496 @return A handle to the current file.
       
   497 */
       
   498 RFile& CFileMultimediaSource::FileL()
       
   499     {
       
   500     if (!iFile)
       
   501         User::Leave(KErrNotReady);
       
   502     if (iFileHandle)
       
   503         return iHandle;
       
   504     else
       
   505         return iFile->FileL();
       
   506     }
       
   507             
       
   508 /** 
       
   509 Returns the file name of the current file.
       
   510 
       
   511 Note: This will give the wrong answer if the file is renamed!
       
   512 
       
   513 @return The FileName (without extension).
       
   514 */
       
   515 const TDesC& CFileMultimediaSource::FileName() const
       
   516     {
       
   517     return *iFileName ;
       
   518     }
       
   519             
       
   520 /**
       
   521 Returns the extension of the current file.
       
   522 
       
   523 Note: This will give the wrong answer if the file is renamed!
       
   524 
       
   525 @return The File Extension.
       
   526 */
       
   527 const TDesC& CFileMultimediaSource::Extension() const 
       
   528     {
       
   529     return *iFileExt ;
       
   530     }
       
   531             
       
   532 /** 
       
   533 Returns the path of the current file.
       
   534 
       
   535 Note: This will give the wrong answer if the file is renamed!
       
   536 
       
   537 @return The FilePath (without filename and extension)
       
   538 */
       
   539 const TDesC& CFileMultimediaSource::FilePath() const 
       
   540     {
       
   541     return *iFilePath ;
       
   542     }
       
   543 
       
   544 /** 
       
   545 Returns the drive on which the current file is located.
       
   546 
       
   547 Note: This will give the wrong answer if the file is renamed!
       
   548 
       
   549 @return The FileDrive (drive letter only, without path, filename and extension).
       
   550 */
       
   551 const TDesC& CFileMultimediaSource::FileDrive() const 
       
   552     {
       
   553     return *iFileDrive ;
       
   554     }
       
   555 
       
   556 /** 
       
   557 Returns the full name of the current file.
       
   558 
       
   559 Note: This will give the wrong answer if the file is renamed!
       
   560 
       
   561 @return The file name (full filename including drive letter, without path, filename and extension).
       
   562 */
       
   563 const TFileName CFileMultimediaSource::FullName() const
       
   564     {
       
   565     return iFullFileName;
       
   566     }
       
   567             
       
   568 /** 
       
   569 Returns the uniqueID associated with this content. If no uniqueID has been provided, a null
       
   570 descriptor will be provided
       
   571 
       
   572 @return The UniqueID
       
   573 */
       
   574 const TDesC& CFileMultimediaSource::UniqueId() const
       
   575     {
       
   576     if (iCAFParameters->iUniqueId)
       
   577         return *(iCAFParameters->iUniqueId);
       
   578     else
       
   579         return KNullDesC;
       
   580     }
       
   581             
       
   582 /**
       
   583 Obtains a CTransferBufferCopy from iTransferBufferCopies that is
       
   584 at least as big as that required.
       
   585 
       
   586 There is no need to put the pointer returned by this method onto the CleanupStack
       
   587 as it will have already been placed into iTransferBufferCopies.
       
   588 
       
   589 @param  aMaxLength
       
   590 The size required.
       
   591 
       
   592 @return A pointer to a valid CTransferBufferCopy.
       
   593 */
       
   594 CTransferBufferCopy* CFileMultimediaSource::ObtainCopyOfTransferBufferL(TInt aMaxLength)
       
   595     {
       
   596     //find a free transfer buffer copy of the right size
       
   597     TInt firstFree = -1;
       
   598     CTransferBufferCopy* transBufCopyToUse = NULL;
       
   599     
       
   600     for(TInt cnt=0; cnt < iTransferBufferCopies.Count(); cnt++)
       
   601         {
       
   602         if(!iTransferBufferCopies[cnt]->InUse())
       
   603             {
       
   604             //record the first free entry, we may remove this
       
   605             //if entries in iTransferBufferCopies > KAcceptableTransferBufferCopiesSize
       
   606             if(firstFree == -1) 
       
   607                 firstFree = cnt;
       
   608             
       
   609             if(iTransferBufferCopies[cnt]->MaxLength() >= aMaxLength)
       
   610                 {
       
   611                 transBufCopyToUse = iTransferBufferCopies[cnt];
       
   612                 
       
   613                 //Set the MaxLength. This will ensure that the copy acts the same as
       
   614                 //the original Transfer buffer, eg. file server will throw KErrOverflow
       
   615                 transBufCopyToUse->ReUse(aMaxLength);
       
   616                 break;
       
   617                 }
       
   618             }
       
   619         }
       
   620     
       
   621     //If we failed to find a suitable entry, we need to create a new one
       
   622     if(!transBufCopyToUse)
       
   623         {
       
   624         //Firstly, should we re-cycle an existing entry?
       
   625         //There must be entries in the array, a free entry must have been found,
       
   626         //the size of the array must be beyond the water mark where we want to start
       
   627         //cycling free entries.
       
   628         if((iTransferBufferCopies.Count() > 0) &&
       
   629             (firstFree != -1) &&
       
   630             (iTransferBufferCopies.Count() > KAcceptableTransferBufferCopiesSize))
       
   631             {
       
   632             delete iTransferBufferCopies[firstFree];
       
   633             iTransferBufferCopies.Remove(firstFree);
       
   634             
       
   635             transBufCopyToUse = CTransferBufferCopy::NewL(aMaxLength);
       
   636             CleanupStack::PushL(transBufCopyToUse);
       
   637             User::LeaveIfError(iTransferBufferCopies.Insert(transBufCopyToUse,firstFree));
       
   638             
       
   639             CleanupStack::Pop();
       
   640             }
       
   641         else
       
   642             {
       
   643     #ifdef _DEBUG
       
   644             if(iTransferBufferCopies.Count() > KMaximumTransferBufferCopiesSize)
       
   645                 {
       
   646                 User::Panic(_L("iTransferBufferCopies grew too large in CFileMultimediaSource"),KErrTooBig);
       
   647                 }
       
   648     #endif
       
   649             
       
   650             transBufCopyToUse = CTransferBufferCopy::NewL(aMaxLength);
       
   651             CleanupStack::PushL(transBufCopyToUse);
       
   652             User::LeaveIfError(iTransferBufferCopies.Append(transBufCopyToUse));
       
   653             
       
   654             CleanupStack::Pop();
       
   655             }
       
   656         }
       
   657     
       
   658     return transBufCopyToUse;
       
   659     }
       
   660 
       
   661 
       
   662 /**
       
   663 Stores a request in an array.
       
   664 
       
   665 CReadWriteRequests are stored in the array iRequests.
       
   666 This function takes ownership and places the request in the array.
       
   667 It also checks the array for completed requests and removes them.
       
   668 
       
   669 @param  aRequest
       
   670 The request to store.
       
   671 */
       
   672 void CFileMultimediaSource::StoreRequestL( CReadWriteRequest* aRequest )
       
   673     {
       
   674     // add aRequest to iRequests
       
   675     User::LeaveIfError( iRequests.Append( aRequest ) ) ;
       
   676     
       
   677     // Clear out any completed requests
       
   678     for ( TInt ii = 0 ; ii < iRequests.Count() ; ii++ )
       
   679         {
       
   680         if (iRequests[ii]->Completed())
       
   681             {
       
   682             CReadWriteRequest* request = iRequests[ii];
       
   683             delete request;
       
   684             
       
   685             iRequests.Remove(ii);
       
   686             ii--;
       
   687             }
       
   688         }
       
   689     }
       
   690 
       
   691 
       
   692 /**
       
   693 Cancels outstanding requests.
       
   694 
       
   695 CReadWriteRequests are stored in the array iRequests.
       
   696 This function cancels any outstanding requests and removes them
       
   697 from iRequests.
       
   698 */
       
   699 void CFileMultimediaSource::CancelRequests()
       
   700     {
       
   701     // Clear out any completed requests
       
   702     for ( TInt ii = 0 ; ii < iRequests.Count() ; ii++ )
       
   703         {
       
   704         CReadWriteRequest* request = iRequests[ii];
       
   705         delete request;
       
   706         iRequests.Remove(ii);
       
   707         ii--;
       
   708         }
       
   709     }
       
   710             
       
   711 /**
       
   712 Evaluates a given intent against the rights associated with the file.
       
   713 
       
   714 The rights are not updated by this function call.
       
   715 
       
   716 @param  aIntent
       
   717 The intent to evaluate.
       
   718 
       
   719 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
       
   720 another of the system-wide error codes.
       
   721 */
       
   722 TInt CFileMultimediaSource::EvaluateIntent(ContentAccess::TIntent aIntent) 
       
   723     {
       
   724     if (!iFile)
       
   725         {
       
   726         return KErrNotReady;
       
   727         }
       
   728     
       
   729     return iFile->EvaluateIntent(aIntent);
       
   730     }
       
   731             
       
   732 /**
       
   733 Evaluates and executes a given intent against the rights associated with the file.
       
   734 
       
   735 The rights object is updated after calling this function.
       
   736 
       
   737 @param  aIntent
       
   738 The intent to evaluate.
       
   739 
       
   740 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
       
   741 another of the system-wide error codes.
       
   742 */
       
   743 TInt CFileMultimediaSource::ExecuteIntent(ContentAccess::TIntent aIntent)
       
   744     {
       
   745     if (!iFile)
       
   746         {
       
   747         return KErrNotReady;
       
   748         }
       
   749     
       
   750     return iFile->ExecuteIntent(aIntent);
       
   751     }
       
   752             
       
   753 /**
       
   754 Returns whether the file is protected.
       
   755 
       
   756 @return A boolean indicating if the file is protected. ETrue if the file is protected.
       
   757 */
       
   758 TInt CFileMultimediaSource::GetDRMProtection(TBool& aIsProtected)
       
   759     {
       
   760     TInt err(KErrNone);	
       
   761     if (!iFile)
       
   762         {
       
   763         return KErrNotReady;
       
   764         }
       
   765     
       
   766     TRAP(err,aIsProtected = iFile->IsProtected());
       
   767     return err;
       
   768     }
       
   769             
       
   770 TInt CFileMultimediaSource::SetAgentProperty(ContentAccess::TAgentProperty aProperty, TInt aValue)
       
   771     {
       
   772     if (!iFile)
       
   773         {
       
   774         return KErrNotReady;
       
   775         }
       
   776     
       
   777     return iFile->SetAgentProperty(aProperty, aValue);
       
   778     }
       
   779             
       
   780             
       
   781 TInt CFileMultimediaSource::GetSeekingSupport( TBool& aSeekSupport )
       
   782     {
       
   783     aSeekSupport = ETrue;
       
   784     return KErrNone;
       
   785     };
       
   786 
       
   787 TInt CFileMultimediaSource::GetRandomSeekingSupport(TBool& aSeekSupport )
       
   788     {
       
   789     aSeekSupport = ETrue;
       
   790     return KErrNone;
       
   791     };
       
   792 
       
   793 TInt CFileMultimediaSource::Seek(TUint aPosInBytes)
       
   794     {
       
   795     if (!iFile)
       
   796         {
       
   797         return KErrNotReady;
       
   798         }
       
   799     
       
   800     return iFile->Seek(ESeekStart, aPosInBytes);
       
   801     };
       
   802             
       
   803 /*
       
   804 *	Returns ETrue if the request can safely be deleted.
       
   805 */
       
   806 
       
   807 TBool CReadWriteRequest::Completed() 
       
   808     {
       
   809     return iCompleted ;
       
   810     }
       
   811             
       
   812 TInt CReadWriteRequest::SetStatus(TBool aStatus)
       
   813     {
       
   814     iCompleted = aStatus;
       
   815     return KErrNone;
       
   816     }
       
   817 
       
   818 TBool CReadWriteRequest::SourceType() 
       
   819     {
       
   820     return iSourceType ;
       
   821     }
       
   822 
       
   823 
       
   824 /*
       
   825 *	Returns the data member of CMMFDataBuffer or CMMFTransferBuffer (as TPtr8)
       
   826 *  
       
   827 */
       
   828 TDes8& CReadWriteRequest::BufferDes()
       
   829     {
       
   830     if(iTransferBufferCopy)
       
   831         return iTransferBufferCopy->Des();
       
   832     else
       
   833         {
       
   834         //reset iBufferDes in case iBuffer has changed...
       
   835         iBufferDes = &(STATIC_CAST(CMMFDataBuffer*, iBuffer)->Data());
       
   836         return *iBufferDes;
       
   837         }
       
   838     }
       
   839 
       
   840 const TDesC8& CReadWriteRequest::BufferDesC()
       
   841     {
       
   842     if(iTransferBufferCopy)
       
   843         return iTransferBufferCopy->Des();
       
   844     else
       
   845         return BufferDes();
       
   846     }
       
   847 
       
   848 CMMFBuffer* CReadWriteRequest::Buffer()
       
   849     {
       
   850     return iBuffer;
       
   851     }
       
   852 
       
   853 TAny* CReadWriteRequest::GetSinkOrSource()
       
   854     {
       
   855     return iSinkOrSource;
       
   856     }
       
   857 
       
   858 /*
       
   859 *	Destructor.
       
   860 */
       
   861 CReadWriteRequest::~CReadWriteRequest() 
       
   862     {
       
   863     Cancel();
       
   864     if(iTransferBufferCopy)
       
   865         iTransferBufferCopy->SetInUse(EFalse);
       
   866     }
       
   867 
       
   868 /*
       
   869 *	Allows owning class access to SetActive()
       
   870 */
       
   871 void CReadWriteRequest::SetActive() 
       
   872     {
       
   873     CActive::SetActive() ;
       
   874     }
       
   875         
       
   876 /*
       
   877 *  For the moment at least...    Canceled requests may be deleted
       
   878 */
       
   879 void CReadWriteRequest::DoCancel() 
       
   880     {
       
   881     iCompleted = ETrue ;
       
   882     }
       
   883             
       
   884 /*
       
   885 *	Called when errors in RunL force Leave.  For the moment just mark the request deletable
       
   886 */
       
   887 TInt CReadWriteRequest::RunError( TInt aError ) 
       
   888     {
       
   889     //RunL can leave.
       
   890     iCompleted = ETrue ;
       
   891     iError = aError; //keep this error internally for now
       
   892     return KErrNone ;
       
   893     }
       
   894         
       
   895 /*
       
   896 *	On completion of read request call back to the MDataSink
       
   897 */
       
   898 void CReadRequest::RunL() 
       
   899     {
       
   900     //Copy the data from the normal buffer into the Transfer buffer
       
   901     if(iTransferBufferCopy)
       
   902         {
       
   903         //must specify the size here as the dest may be smaller than the source.
       
   904         TDes8& destDesc = STATIC_CAST(CMMFDataBuffer*, iBuffer)->Data();
       
   905         destDesc.Copy(iTransferBufferCopy->Des().Left(destDesc.MaxLength()));
       
   906     
       
   907         iTransferBufferCopy->SetInUse(EFalse);
       
   908         }
       
   909 
       
   910         STATIC_CAST(CFileMultimediaSource*,iParent)->ReadRequestStatus(STATIC_CAST(CReadWriteRequest*,this),iStatus);
       
   911     }
       
   912 
       
   913         // From CMultimediaDataSource begins
       
   914 TInt CFileMultimediaSource::SetObserver( MMultimediaDataSourceObserver& aObserver )
       
   915     {
       
   916     TInt status(KErrNone);
       
   917     iObserver = &aObserver;
       
   918     return status;
       
   919     }
       
   920         
       
   921 TInt CFileMultimediaSource::GetObserver( MMultimediaDataSourceObserver*& aObserver )
       
   922     {
       
   923     TInt status(KErrNone);
       
   924     aObserver = iObserver;
       
   925     return status;
       
   926     }
       
   927         
       
   928 void CFileMultimediaSource::Event( TUid aEvent )
       
   929     {
       
   930     if( aEvent == KMultimediaDataSourceEventBitRateChanged )
       
   931         {
       
   932         if(iObserver)
       
   933             {
       
   934             iObserver->GetBitRate( iObserverBitRate ); 
       
   935             }
       
   936         TPckgBuf<TFileDataSourceEvent> bitRatePckg;	
       
   937         bitRatePckg().iBitRate = iObserverBitRate;
       
   938         bitRatePckg().iType = EFileBitRateChanged;
       
   939                 
       
   940         if(iMessage)
       
   941             {
       
   942             iMessage->WriteDataToClient(bitRatePckg);
       
   943             iMessage->Complete(KErrNone);
       
   944             }
       
   945         }    
       
   946     }
       
   947         
       
   948 TInt CFileMultimediaSource::SetDataTypeCode(TFourCC aSourceFourCC )
       
   949     {
       
   950     TInt status(KErrNone);
       
   951     iSourceFourCC = aSourceFourCC;
       
   952     return status;
       
   953     }
       
   954         
       
   955 TInt CFileMultimediaSource::GetDataTypeCode(TFourCC& aSourceFourCC )
       
   956     {
       
   957     TInt status(KErrNone);
       
   958     aSourceFourCC = iSourceFourCC;
       
   959     return status;
       
   960     }
       
   961 
       
   962 TInt CFileMultimediaSource::GetSize( TUint& aSize )
       
   963     {
       
   964     TInt err = KErrNone;
       
   965     aSize = iFileSize;
       
   966     return err;
       
   967     }
       
   968 
       
   969 TInt CFileMultimediaSource::Open()
       
   970     {
       
   971     TInt status(KErrNotReady);
       
   972     DEBPRN1(_L("CFileMultimediaSource::Open"));
       
   973     switch ( iState )
       
   974         {
       
   975         case ECLOSED:
       
   976             StateChanged(ESTOPPED);
       
   977             status = KErrNone;
       
   978             break;
       
   979         case ESTOPPED:
       
   980         case EPRIMED:
       
   981         case EEXECUTING:
       
   982         case EBUFFERING:
       
   983         default:
       
   984             DEBPRN2(_L("CFileMultimediaSource::Open[Illegal cmd on state[%d]]"), iState );
       
   985             break;
       
   986         };
       
   987     return status;
       
   988     }
       
   989 
       
   990 TInt CFileMultimediaSource::Close()
       
   991     {
       
   992     TInt status(KErrNone);
       
   993     iHandle.Close();
       
   994     iFsSession.Close();
       
   995 
       
   996     StateChanged(ECLOSED);
       
   997     // Clear app buffers
       
   998     EmptySinkQueue();
       
   999     iSnkBytes = 0;
       
  1000     // Clear observer buffers
       
  1001     return status;
       
  1002     }
       
  1003 
       
  1004 TInt CFileMultimediaSource::Prime()
       
  1005     {
       
  1006     TInt status(KErrNotReady);
       
  1007     DEBPRN1(_L("CFileMultimediaSource::Prime"));
       
  1008     switch ( iState )
       
  1009         {
       
  1010         case ESTOPPED:
       
  1011             
       
  1012             // don't reopen file if already open
       
  1013             if (!iFile)
       
  1014                 {
       
  1015                 if (iFileHandle)
       
  1016                     {
       
  1017                     TRAPD(err,iFile = CContentFile::NewL(iHandle, UniqueId(), iCAFParameters->iEnableUI));
       
  1018                     if(err)
       
  1019                         return err;
       
  1020                     }
       
  1021                 else
       
  1022                     {
       
  1023                     // Open for read-only access
       
  1024                     TRAPD(err,iFile = CContentFile::NewL(iFsSession, iFullFileName, UniqueId(), EFileShareAny, iCAFParameters->iEnableUI));
       
  1025                     if(err)
       
  1026                         return err;                    
       
  1027                     }
       
  1028                 }
       
  1029             
       
  1030             if(iFile)
       
  1031                 {
       
  1032                 iFile->Size(iFileSize);
       
  1033                 }												
       
  1034             
       
  1035             StateChanged(EPRIMED);
       
  1036             status = KErrNone;
       
  1037             break;
       
  1038         case EPRIMED:
       
  1039             status = KErrNone;
       
  1040             break;
       
  1041         case ECLOSED:
       
  1042         case EEXECUTING:
       
  1043         case EBUFFERING:
       
  1044         default:
       
  1045             DEBPRN2(_L("CFileMultimediaSource::Prime[Illegal cmd on state[%d]]"), iState );
       
  1046             break;
       
  1047         }
       
  1048     return status;
       
  1049     }
       
  1050 
       
  1051 TInt CFileMultimediaSource::Play()
       
  1052     {
       
  1053     TInt status(KErrNotReady);
       
  1054     DEBPRN1(_L("CFileMultimediaSource::Play"));
       
  1055     switch ( iState )
       
  1056         {
       
  1057         case EPRIMED:
       
  1058             StateChanged(EEXECUTING);
       
  1059             
       
  1060             while ( !iSinkQueue->IsEmpty() )
       
  1061                 {
       
  1062                 status = ServiceFillBuffer();
       
  1063                 }
       
  1064             
       
  1065             status = KErrNone;	
       
  1066             break;
       
  1067         case EEXECUTING:
       
  1068         case EBUFFERING:
       
  1069             status = KErrNone;
       
  1070             // No op
       
  1071             break;
       
  1072         case ECLOSED:
       
  1073         case ESTOPPED:
       
  1074         default:
       
  1075             DEBPRN2(_L("CFileMultimediaSource::Play[Illegal cmd on state[%d]]"), iState );
       
  1076             break;
       
  1077         };
       
  1078     return status;
       
  1079     }
       
  1080         
       
  1081 TInt CFileMultimediaSource::Stop()
       
  1082     {
       
  1083     TInt status(KErrNotReady);
       
  1084     DEBPRN1(_L("CFileMultimediaSource::Stop"));
       
  1085     switch ( iState )
       
  1086         {
       
  1087         case EPRIMED:
       
  1088         case EEXECUTING:
       
  1089         case EBUFFERING:
       
  1090             {
       
  1091             TInt pos = 0;
       
  1092             CancelRequests();
       
  1093             delete iFile;
       
  1094             iFile = NULL;
       
  1095             iSnkBytes=pos;
       
  1096             EmptySinkQueue();
       
  1097             StateChanged(ESTOPPED);
       
  1098             status = KErrNone;
       
  1099             }
       
  1100             break;
       
  1101         case ESTOPPED:
       
  1102         case ECLOSED:
       
  1103         default:
       
  1104             DEBPRN2(_L("CFileMultimediaSource::Stop[Illegal cmd on state[%d]]"), iState );
       
  1105             status = KErrNone;
       
  1106             break;
       
  1107         };
       
  1108     return status;
       
  1109     }
       
  1110     
       
  1111 TInt CFileMultimediaSource::FillBuffer( CMMFBuffer* aBuffer )
       
  1112     {
       
  1113     // Requires that iFile is open for read.
       
  1114     // Reads data from iFile into aBuffer
       
  1115     TInt status(KErrNone);
       
  1116     if (!aBuffer)
       
  1117         return KErrArgument;
       
  1118     
       
  1119     if (!iFile)
       
  1120         return KErrNotReady;
       
  1121     
       
  1122     AppendBufferToSinkQueue(aBuffer,iObserver,NULL,EFalse);
       
  1123     
       
  1124     status = ServiceFillBuffer();
       
  1125     
       
  1126     return status; 	
       
  1127     }
       
  1128 
       
  1129     
       
  1130 TAny* CFileMultimediaSource::CustomInterface( TUid /*aInterfaceUid*/ )
       
  1131     {
       
  1132     return NULL;
       
  1133     }
       
  1134     
       
  1135 TInt CFileMultimediaSource::AppendBufferToSinkQueue( CMMFBuffer* aBuffer,
       
  1136                                                     MMultimediaDataSourceObserver* aObserver,
       
  1137                                                     MDataSink* aConsumer,TBool aTop )  
       
  1138     {
       
  1139     TInt status(KErrNone);
       
  1140     
       
  1141     DEBPRN2(_L("CFileMultimediaSource::AppendBufferToSinkQueue() Buffer[%x]"), aBuffer );				    
       
  1142     // Add observer buffer to queue
       
  1143     CMMFDataBuffer* dest = static_cast<CMMFDataBuffer*>( aBuffer );
       
  1144     TDes8& destBufferDes = dest->Data();
       
  1145     
       
  1146     CSinkQueueItem* request(NULL);
       
  1147     
       
  1148     TRAP( status, request = CSinkQueueItem::NewL( aBuffer, aObserver,aConsumer) );
       
  1149     if ( status == KErrNone )
       
  1150         {
       
  1151         if(aTop)
       
  1152             iSinkQueue->AddFirst(*request);
       
  1153         else  
       
  1154             iSinkQueue->AddLast(*request);
       
  1155         
       
  1156         iSnkItemsCount++;
       
  1157         
       
  1158         DEBPRN3(_L("CFileMultimediaSource::AppendBufferToQueue[ReqSize[%d]SnkItems[%d]]"), \
       
  1159             aBuffer->RequestSize(), iSnkItemsCount );
       
  1160         }
       
  1161     return status;
       
  1162     }
       
  1163     
       
  1164 void CFileMultimediaSource::SourceCustomCommand(TMMFMessage& aMessage)
       
  1165     {
       
  1166     //TInt err(KErrNone);
       
  1167     switch ( aMessage.Function() )
       
  1168         {
       
  1169         case EGetFileSourceEvent:
       
  1170             {
       
  1171             TPckgBuf<TFileDataSourceEvent> statePckg;	
       
  1172             aMessage.ReadData1FromClient(statePckg);
       
  1173             DEBPRN3(_L("CFileMultimediaSource::SourceCustomCommand() Client State[%d] SourceState[%d]"), statePckg().iState, iState);
       
  1174             
       
  1175             if(statePckg().iType == EFileBitRateChanged)
       
  1176                 {
       
  1177                 if(iObserver)
       
  1178                     {
       
  1179                     iObserver->GetBitRate( iObserverBitRate ); 
       
  1180                     }
       
  1181                 statePckg().iBitRate = iObserverBitRate;
       
  1182                 aMessage.WriteDataToClient(statePckg);
       
  1183                 aMessage.Complete(KErrNone);
       
  1184                 }
       
  1185             else if(statePckg().iType == EFileSize)
       
  1186                 {
       
  1187                 TUint size = 0;
       
  1188                 GetSize(size);
       
  1189                 statePckg().iFileSize = size;
       
  1190                 aMessage.WriteDataToClient(statePckg);
       
  1191                 aMessage.Complete(KErrNone);
       
  1192                 }
       
  1193             else if(statePckg().iType == EFileSourceStateChanged)
       
  1194                 {
       
  1195                 if(iState != statePckg().iState)
       
  1196                     {
       
  1197                     statePckg().iState = iState;	
       
  1198                     aMessage.WriteDataToClient(statePckg);
       
  1199                     aMessage.Complete(KErrNone);
       
  1200                     }
       
  1201                 else
       
  1202                     iMessage = new(ELeave) TMMFMessage(aMessage);
       
  1203                 }                
       
  1204              }   
       
  1205             break;   
       
  1206                 
       
  1207         default:
       
  1208             //err = KErrArgument;
       
  1209             break;
       
  1210         }
       
  1211     }        
       
  1212 
       
  1213 TInt CFileMultimediaSource::ServiceFillBuffer()
       
  1214     {
       
  1215     
       
  1216     DEBPRN3(_L("CFileMultimediaSource::ServiceFillBuffer() state[%d] Download Size[%d]"), iState ,iDownloadSize );
       
  1217     
       
  1218     TInt status(KErrNone);
       
  1219     if ( iSinkQueue->IsEmpty() )
       
  1220     return KErrNone;
       
  1221     
       
  1222     CSinkQueueItem* snkItem = iSinkQueue->First();
       
  1223     iSinkQueue->Remove(*snkItem);
       
  1224     iSnkItemsCount--;
       
  1225     CMMFBuffer* buffer = snkItem->Buffer();
       
  1226     DEBPRN2(_L("CFileMultimediaSource::ServiceFillBuffer() Buffer[%x]"), buffer );				    
       
  1227     MMultimediaDataSourceObserver* observer = snkItem->Observer();
       
  1228     MDataSink* consumer = snkItem->Consumer();
       
  1229     delete snkItem;
       
  1230     
       
  1231     if (CMMFBuffer::IsSupportedDataBuffer(buffer->Type()))
       
  1232         {
       
  1233         CTransferBufferCopy* transBufCopy = NULL;
       
  1234         CReadRequest* request = NULL;
       
  1235         
       
  1236         TDes8& bufferDes = STATIC_CAST( CMMFDataBuffer*, buffer )->Data();
       
  1237         
       
  1238         TInt requestSize;
       
  1239         if(buffer->RequestSize())
       
  1240             requestSize = buffer->RequestSize();
       
  1241         else
       
  1242             requestSize = bufferDes.MaxLength();
       
  1243         
       
  1244         //check whether buffer is safe to send to file server
       
  1245         //if not, eg for a transfer buffer, then it needs to be copied
       
  1246         if (!CMMFBuffer::IsFileServerSafe(buffer->Type()))
       
  1247             {
       
  1248             //NB: failure in this method will NOT cause transBufCopy to leak as it will be 
       
  1249             //inserted into iTransferBufferCopies by ObtainCopyOfTransferBufferL.
       
  1250             TRAP(status,transBufCopy = ObtainCopyOfTransferBufferL(bufferDes.MaxLength()));
       
  1251             
       
  1252             if(consumer && !observer)
       
  1253                 request = new(ELeave) CReadRequest(this,STATIC_CAST(TAny*, consumer), buffer, transBufCopy, iSnkBytes, iDownloadSize, ETrue);
       
  1254             else
       
  1255                 request = new(ELeave) CReadRequest(this,STATIC_CAST(TAny*, observer), buffer, transBufCopy, iSnkBytes, iDownloadSize, EFalse);					
       
  1256             
       
  1257             }
       
  1258         else
       
  1259             {
       
  1260             if(consumer && !observer)
       
  1261                 request = new(ELeave) CReadRequest(this,STATIC_CAST(TAny*, consumer), buffer, iSnkBytes, iDownloadSize, ETrue);
       
  1262             else
       
  1263                 request = new(ELeave) CReadRequest(this,STATIC_CAST(TAny*, observer), buffer, iSnkBytes, iDownloadSize, EFalse);					
       
  1264             }
       
  1265         
       
  1266         CleanupStack::PushL( request );
       
  1267         
       
  1268         TRAP_IGNORE(StoreRequestL(request)); // transfers ownership
       
  1269         CleanupStack::Pop() ; // request
       
  1270         
       
  1271         request->SetActive();
       
  1272         
       
  1273         if ((iSnkBytes + request->Buffer()->RequestSize()) > iFileSize)
       
  1274             {
       
  1275             request->Buffer()->SetLastBuffer(ETrue);
       
  1276             DEBPRN1(_L("CFileMultimediaSource::ServiceFillBuffer() LastBuffer$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"));
       
  1277             }
       
  1278         
       
  1279         iFile->Read(request->BufferDes(), requestSize, request->iStatus);
       
  1280         
       
  1281         }
       
  1282     else // if (CMMFBuffer::IsSupportedDataBuffer(buffer->Type()))
       
  1283         return KErrNotSupported;
       
  1284     
       
  1285 
       
  1286     return status;
       
  1287     }
       
  1288 
       
  1289 TInt CFileMultimediaSource::EmptySinkQueue()
       
  1290     {
       
  1291     TInt status(KErrNone);
       
  1292     // Empty sink queue
       
  1293     CSinkQueueItem* snkItem;
       
  1294     while ( !iSinkQueue->IsEmpty() )
       
  1295         {
       
  1296         snkItem = iSinkQueue->First();
       
  1297         iSinkQueue->Remove(*snkItem);
       
  1298         delete snkItem;
       
  1299         }
       
  1300     
       
  1301     iSnkItemsCount = 0;
       
  1302     return status;
       
  1303     }
       
  1304 
       
  1305 void CFileMultimediaSource::StateChanged(TState newState)
       
  1306     {
       
  1307     DEBPRN3(_L("CFileMultimediaSource::StateChanged OLD[%d] NEW[%d]"),iState, newState);        
       
  1308     if(iState != newState)
       
  1309         {
       
  1310         if(iMessage)
       
  1311             {
       
  1312             if(!iMessage->IsCompleted())
       
  1313                 {
       
  1314                 TPckgBuf<TFileDataSourceEvent> statePckg;
       
  1315                 statePckg().iState = newState;
       
  1316                 statePckg().iType = EFileSourceStateChanged;                	
       
  1317                 iMessage->WriteDataToClient(statePckg);
       
  1318                 iMessage->Complete(KErrNone);
       
  1319                 delete iMessage;
       
  1320                 iMessage = NULL;
       
  1321                 }
       
  1322             }
       
  1323         iState = newState;
       
  1324         }
       
  1325     }
       
  1326 
       
  1327 TInt CFileMultimediaSource::ReadRequestStatus(CReadWriteRequest* aRequest, TRequestStatus& aStatus)
       
  1328     {
       
  1329     
       
  1330     if(aStatus != KErrNone)
       
  1331         {
       
  1332         TMMFEvent event(KMMFErrorCategoryControllerGeneralError, aStatus.Int());
       
  1333         iEventHandler->SendEventToClient(event);
       
  1334         return KErrNone;
       
  1335         }
       
  1336     else
       
  1337         {
       
  1338         
       
  1339         DEBPRN4(_L("CFileMultimediaSource::ReadRequestStatus Buffer[%x] BufferSize[%d] RequestSize[%d]"),aRequest->Buffer(),aRequest->Buffer()->BufferSize(),aRequest->Buffer()->RequestSize());
       
  1340         DEBPRN3(_L("CFileMultimediaSource::ReadRequestStatus Buffer[%x] LastBuffer[%d]"),aRequest->Buffer(),aRequest->Buffer()->LastBuffer());
       
  1341         
       
  1342         TBool lastBuffer = aRequest->Buffer()->LastBuffer();
       
  1343         
       
  1344         if((aRequest->Buffer()->BufferSize() != aRequest->Buffer()->RequestSize()) && !lastBuffer)
       
  1345             {
       
  1346             if(aRequest->SourceType())
       
  1347                 {
       
  1348                 MDataSink* sinkOrSource = REINTERPRET_CAST(MDataSink*,aRequest->GetSinkOrSource());
       
  1349                 AppendBufferToSinkQueue(aRequest->Buffer(),(MMultimediaDataSourceObserver*)NULL,sinkOrSource,ETrue);
       
  1350                 iSnkBytes -= aRequest->Buffer()->BufferSize();
       
  1351                 iFile->Seek(ESeekStart,iSnkBytes);
       
  1352                 StateChanged(EBUFFERING);
       
  1353                 }
       
  1354             else
       
  1355                 {
       
  1356                 MMultimediaDataSourceObserver* sinkOrSource = REINTERPRET_CAST(MMultimediaDataSourceObserver*,aRequest->GetSinkOrSource());
       
  1357                 AppendBufferToSinkQueue(aRequest->Buffer(),sinkOrSource,(MDataSink*)NULL,ETrue);
       
  1358                 iSnkBytes -= aRequest->Buffer()->BufferSize();
       
  1359                 iFile->Seek(ESeekStart,iSnkBytes);
       
  1360                 StateChanged(EBUFFERING);
       
  1361                 }
       
  1362             }
       
  1363         else
       
  1364             {	
       
  1365             iSnkBytes += aRequest->Buffer()->BufferSize();
       
  1366             
       
  1367             
       
  1368             if(aRequest->SourceType())
       
  1369                     REINTERPRET_CAST(MDataSink*, aRequest->GetSinkOrSource())->BufferFilledL(aRequest->Buffer()) ; // callback to MDataSource/Sink
       
  1370             else
       
  1371                     REINTERPRET_CAST(MMultimediaDataSourceObserver*, aRequest->GetSinkOrSource())->BufferFilled(aRequest->Buffer()) ; // callback to MDataSource/Sink			
       
  1372                 
       
  1373             }
       
  1374             
       
  1375             aRequest->SetStatus(ETrue);
       
  1376             return KErrNone;		
       
  1377         }
       
  1378     }
       
  1379 
       
  1380 //End of File
       
  1381