os/mm/mmplugins/lib3gp/impl/src/file.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include "mp4file.h"
    17 #include "mp4memwrap.h"
    18 #include "mp4atom.h"
    19 #include <stdio.h>
    20 #include <string.h>
    21 #include <sys/unistd.h>
    22 #include <sys/reent.h>
    23 #include <f32file.h>
    24 #include <f32file64.h>
    25 #include <e32des16.h>
    26 #include <caf/caf.h>
    27 
    28 using namespace ContentAccess;
    29 
    30 // Debug print macro
    31 #ifdef _DEBUG
    32 #include <e32svr.h>
    33 #define PRINT(x)     //comment this line and uncomment the line below to enable logging for this file
    34 //#define PRINT(x) RDebug::Print x
    35 #else
    36 #define PRINT(x)
    37 #endif
    38 
    39 _LIT(KTmpDirectoryName, "\\System\\Temp\\3GPLibTmpDir\\"); // Temporary output directory name
    40 
    41 
    42 /*
    43  * Function:
    44  *
    45  *   mp4_i32 saveFileName(MP4FileName filename,
    46  *                        MP4HandleImp handle)
    47  *
    48  * Description:
    49  *
    50  *   Save file name for later use.
    51  *
    52  * Parameters:
    53  *
    54  *   filename   Filename
    55  *   handle     MP4 library handle
    56  *
    57  * Return value:
    58  *
    59  *   0          Success
    60  *   -1         Error
    61  *
    62  */
    63 mp4_i32 saveFileName(MP4FileName filename, MP4HandleImp handle)
    64 {
    65   handle->fileName = (MP4FileName)mp4malloc(2 * wcslen(filename) + 2);
    66   if (handle->fileName == NULL)
    67     return -1;
    68 
    69   wcscat(handle->fileName, filename);
    70 
    71   return 0;
    72 }
    73 
    74 
    75 /*
    76  * Function:
    77  *
    78  *   mp4_i32 initFileRead(MP4FileName filename,
    79  *                        MP4HandleImp handle)
    80  *
    81  * Description:
    82  *
    83  *   Open a file for reading.
    84  *
    85  *   Note: filename is a Unicode string in Symbian OS.
    86  *
    87  * Parameters:
    88  *
    89  *   filename   Filename
    90  *   handle     MP4 library handle
    91  *
    92  * Return value:
    93  *
    94  *   0          Success
    95  *   -1         Error
    96  *
    97  */
    98 mp4_i32 initFileRead(MP4FileName filename, MP4HandleImp handle)
    99 {
   100   RFs   *fs;
   101   RFile64 *file;
   102 
   103 
   104   fs = new(RFs);
   105   handle->fs = (void *)fs;
   106   if (fs == NULL)
   107     return -1;
   108 
   109   if (fs->Connect() != KErrNone)
   110     return -1;
   111 
   112   file = new(RFile64);
   113   handle->rfile = (void *)file;
   114   if (file == NULL)
   115     return -1;
   116 
   117   if (file->Open(*fs, TPtrC((const TUint16 *)filename), EFileRead | EFileShareAny) != KErrNone)
   118   {
   119     // for compatibility, if opening in Any mode fails try more restrictive approach.
   120     if (file->Open(*fs, TPtrC((const TUint16 *)filename), EFileRead | EFileShareReadersOnly) != KErrNone)
   121     {
   122         return -1;
   123     }
   124   }
   125   handle->file = handle->rfile;
   126   return 0;
   127 }
   128 
   129 
   130 /*
   131  * Function:
   132  *
   133  *   mp4_i32 initFileWrite(MP4FileName filename,
   134  *                         MP4HandleImp handle)
   135  *
   136  * Description:
   137  *
   138  *   Open a file for writing.
   139  *
   140  *   Note: filename is a Unicode string in Symbian OS.
   141  *
   142  * Parameters:
   143  *
   144  *   filename   Filename
   145  *   handle     MP4 library handle
   146  *
   147  * Return value:
   148  *
   149  *   0          Success
   150  *   -1         Error
   151  *
   152  */
   153 mp4_i32 initFileWrite(MP4FileName filename, MP4HandleImp handle)
   154 {
   155   RFs   *fs;
   156   RFile64 *file;
   157   TParse fp;
   158   TFileName path;
   159   TInt error;
   160 
   161 
   162   fs = new(RFs);
   163   handle->fs = (void *)fs;
   164   if (fs == NULL)
   165     return -1;
   166 
   167   if (fs->Connect() != KErrNone)
   168     return -1;
   169 
   170   file = new(RFile64);
   171   handle->rfile = (void *)file;
   172   if (file == NULL)
   173     return -1;
   174 
   175   if (((RFs *)(handle->fs))->Parse(TPtrC((const TUint16 *)filename), fp) != KErrNone)
   176     return -1;
   177 
   178   path.Insert(0, fp.DriveAndPath() );
   179   error = ((RFs *)(handle->fs))->MkDirAll(path);
   180   if (error != KErrNone && error != KErrAlreadyExists)
   181     return -1;
   182 
   183   if (file->Replace(*fs, TPtrC((const TUint16 *)filename), EFileWrite|EFileShareExclusive|EFileWriteDirectIO ) != KErrNone)
   184   {
   185     return -1;
   186   }
   187 
   188   TBuf8<16> buf;
   189   buf.Copy(fp.Drive());
   190   buf.LowerCase();
   191   TInt drvNum = (*buf.Ptr()) - 'a';
   192   PRINT((_L("drvNum = %d"), drvNum));
   193   
   194   TVolumeInfo volInfo;
   195   error = fs->Volume(volInfo, drvNum);
   196   if (error != KErrNone) 
   197       {
   198       return -1;
   199       }
   200   
   201   PRINT((_L("volInfo.iFree = %Ld"), volInfo.iFree));
   202   PRINT((_L("volInfo.iSize = %Ld"), volInfo.iSize));    
   203 
   204   TVolumeIOParamInfo ioInfo;
   205   error = fs->VolumeIOParam(drvNum, ioInfo);
   206   if (error != KErrNone) 
   207       {
   208       return -1;
   209       }
   210   
   211   PRINT((_L("ioInfo.iBlockSize = %d"), ioInfo.iBlockSize));
   212   PRINT((_L("ioInfo.iClusterSize = %d"), ioInfo.iClusterSize));
   213   
   214   if (ioInfo.iClusterSize <= 0 || (ioInfo.iClusterSize & 0x1)) // if for some reason we got wrong value for the cluster - ignore it 
   215      {
   216      PRINT(_L("Wrong cluster size, set 0x8000"));
   217      ioInfo.iClusterSize = 0x8000;
   218      }
   219   
   220   // We want to have size of writing buffer to be a multiple of cluster size. Small buffer should be 1 cluster, large buffer should be 8 clusters.
   221   TInt writeBufferSizeSmall = ioInfo.iClusterSize;
   222   TInt writeBufferSizeLarge = ioInfo.iClusterSize * 8;
   223   
   224   // Now need to make sure that writeBufferSizeLarge is not too small (<128K) or too big (>256K) whilst keeping it a multiple of cluster size
   225   if (writeBufferSizeLarge < KFileWriterBufferSizeLarge/2)
   226       {
   227       writeBufferSizeLarge = KFileWriterBufferSizeLarge/2;
   228       }
   229     
   230   if (writeBufferSizeLarge > KFileWriterBufferSizeLarge)
   231 	  {
   232 	  writeBufferSizeLarge = (KFileWriterBufferSizeLarge / ioInfo.iClusterSize) * ioInfo.iClusterSize;
   233   	  }
   234 
   235   if (writeBufferSizeLarge < ioInfo.iClusterSize) 
   236       {
   237       writeBufferSizeLarge = ioInfo.iClusterSize;
   238       }
   239     
   240   PRINT((_L("writeBufferSizeLarge = %d"), writeBufferSizeLarge));
   241 
   242   TInt incSetSize = writeBufferSizeLarge * (KFileWriterHardBufLimit >> 1); // 2Mb if cluster size if 32767
   243   TInt initSetSize = incSetSize * 1; // set initial set size for 2Mb
   244   
   245   if (initSetSize > volInfo.iFree) 
   246       {
   247       initSetSize = (volInfo.iFree / incSetSize) * incSetSize;
   248       }
   249 
   250   PRINT((_L("initSetSize = %d"), initSetSize));
   251     
   252   PRINT((_L("e_SetSize 1")));  
   253   file->SetSize(initSetSize);
   254   PRINT((_L("e_SetSize 0")));  
   255 
   256   handle->file = handle->rfile;
   257 
   258   TRAP(error, handle->filewriter = CFileWriter::NewL( *file, initSetSize, writeBufferSizeSmall, writeBufferSizeLarge));
   259   if ( error != KErrNone )
   260   {
   261     return -1;    
   262   }
   263 
   264   return 0;
   265 }
   266 
   267 
   268 /*
   269  * Function:
   270  *
   271  *   mp4_i32 initTmpFileWrite(MP4FileName filename,
   272  *                            MP4HandleImp handle)
   273  *
   274  * Description:
   275  *
   276  *   Open a temporary file for writing.
   277  *
   278  *   Note: filename is a Unicode string in Symbian OS.
   279  *
   280  * Parameters:
   281  *
   282  *   filename   Filename
   283  *   handle     MP4 library handle
   284  *
   285  * Return value:
   286  *
   287  *   0          Success
   288  *   -1         Error
   289  *
   290  */
   291 mp4_i32 initTmpFileWrite(MP4FileName filename, MP4HandleImp handle)
   292 {
   293   TInt err;
   294   RFile64 * file = new RFile64;
   295   TBuf16<KMaxFileName> name(reinterpret_cast<const TUint16*>(filename));
   296   ASSERT(handle->fs != NULL);
   297   err = file->Replace(*(RFs*)(handle->fs), name, EFileStream | EFileRead | EFileWrite | EFileWriteDirectIO);
   298   if (err != KErrNone)
   299   {
   300 	delete file;
   301 	return -1;
   302   }
   303 
   304   handle->tmpfile = (void *)file;
   305   return 0;
   306 }
   307  
   308 
   309 /*
   310  * Function:
   311  *
   312  *   mp4_i32 closeFile(MP4HandleImp handle)
   313  *
   314  * Description:
   315  *
   316  *   Close a file.
   317  *
   318  * Parameters:
   319  *
   320  *   handle   MP4 library handle
   321  *
   322  * Return value:
   323  *
   324  *   0        Success
   325  *
   326  */
   327 mp4_i32 closeFile(MP4HandleImp handle)
   328 {
   329   PRINT((_L("e_closefile 1")));
   330   if (handle->rfile)
   331   {
   332     if (handle->filewriter)
   333     {
   334       PRINT((_L("e_closefile_flush_filewriter 1")));        
   335       (handle->filewriter)->Flush(KNullDesC8);
   336       PRINT((_L("e_closefile_flush_filewriter 0")));        
   337       PRINT((_L("e_SetSize 1")));  
   338       ((RFile64 *)(handle->file))->SetSize((handle->filewriter)->OutputFileSize());
   339       PRINT((_L("e_SetSize 0: iOutputFileSize = %Ld"), (handle->filewriter)->OutputFileSize()));  
   340 	  
   341 	  delete handle->filewriter;
   342       handle->filewriter = NULL;
   343     }
   344   }
   345 
   346   if (handle->asyncReader)
   347   {
   348 	delete handle->asyncReader;
   349 	handle->asyncReader = NULL;
   350   }
   351 
   352   if (handle->rfile)
   353   {
   354     if ( !handle->FileHandleFromOutside )
   355         {
   356   		PRINT((_L("e_closefile_close_file 1")));        
   357         ((RFile64 *)(handle->rfile))->Close();
   358   		PRINT((_L("e_closefile_close_file 0"))); 
   359 		PRINT((_L("e_closefile_delete_fileptr 1")));  		
   360         delete(handle->rfile);
   361 		PRINT((_L("e_closefile_delete_fileptr 0")));        
   362         }
   363     handle->rfile = NULL;
   364   }
   365 
   366   if (handle->cfile)
   367   {
   368     if ( !handle->FileHandleFromOutside )
   369         {
   370         delete(handle->cfile);
   371         }
   372     handle->cfile = NULL;
   373   }
   374 
   375   PRINT((_L("e_closefile_close_rfs 1")));
   376   if (handle->fs)
   377   {
   378     ((RFs *)(handle->fs))->Close();
   379 
   380     delete(handle->fs);
   381 
   382     handle->fs = NULL;
   383   }
   384   PRINT((_L("e_closefile_close_rfs 0")));  
   385 
   386   handle->file = NULL;
   387   PRINT((_L("e_closefile 0")));
   388   return 0;
   389 }
   390 
   391 
   392 /*
   393  * Function:
   394  *
   395  *   mp4_i32 closeTmpFile(MP4HandleImp handle)
   396  *
   397  * Description:
   398  *
   399  *   Close a temporary file.
   400  *
   401  * Parameters:
   402  *
   403  *   handle   MP4 library handle
   404  *
   405  * Return value:
   406  *
   407  *   0        Success
   408  *
   409  */
   410 mp4_i32 closeTmpFile(MP4HandleImp handle)
   411 {
   412   if (handle->tmpfile)
   413 	((RFile64*)handle->tmpfile)->Close();
   414 
   415   handle->tmpfile = NULL;
   416 
   417   return 0;
   418 }
   419 
   420 
   421 /*
   422  * Function:
   423  *
   424  *   mp4_i32 deleteTmpFile(MP4HandleImp handle)
   425  *
   426  * Description:
   427  *
   428  *   Remove a temporary file.
   429  *
   430  * Parameters:
   431  *
   432  *   handle   MP4 library handle
   433  *
   434  * Return value:
   435  *
   436  *   0        Success
   437  *   -1       Error
   438  *
   439  */
   440 mp4_i32 deleteTmpFile(MP4HandleImp handle)
   441 {
   442   if (handle->tmpFileName)
   443 	{
   444 	  TInt err;
   445 	  TBuf<KMaxFileName> name(reinterpret_cast<const TUint16*>(handle->tmpFileName));
   446 	  ASSERT(handle->fs != NULL);
   447 	  err = ((RFs*)handle->fs)->Delete(name);
   448 	  if (err != KErrNone)
   449 		return -1;
   450 	}
   451 
   452   return 0;
   453 }
   454 
   455 
   456 /*
   457  * Function:
   458  *
   459  *   mp4_i32 readFile(MP4HandleImp handle,
   460  *                    mp4_u8 *buffer,
   461  *                    mp4_u32 bytestoread)
   462  *
   463  * Description:
   464  *
   465  *   Read data from a file.
   466  *
   467  * Parameters:
   468  *
   469  *   handle       MP4 library handle
   470  *   buffer       Buffer to read data into
   471  *   bytestoread  Number of bytes to read from file
   472  *
   473  * Return value:
   474  *
   475  *   0            Success
   476  *   -1           File has not been opened
   477  *   -2           Requested number of bytes could not be read
   478  *
   479  */
   480 mp4_i32 readFile(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestoread)
   481 {
   482   return bufferedRead(handle, buffer, bytestoread);
   483 }
   484 
   485 /*
   486  * Function:
   487  *
   488  *   mp4_i32 readTmpFile(MP4HandleImp handle,
   489  *                       mp4_u8 *buffer,
   490  *                       mp4_u32 bytestoread)
   491  *
   492  * Description:
   493  *
   494  *   Read data from a temporary file.
   495  *
   496  * Parameters:
   497  *
   498  *   handle       MP4 library handle
   499  *   buffer       Buffer to read data into
   500  *   bytestoread  Number of bytes to read from file
   501  *
   502  * Return value:
   503  *
   504  *   0            Success
   505  *   -1           File has not been opened
   506  *   -2           Requested number of bytes could not be read
   507  *
   508  */
   509 mp4_i32 readTmpFile(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestoread)
   510 {
   511   if (!handle->tmpfile)
   512     return -1;
   513 
   514   TInt err;
   515   TPtr8 ptrBuffer(buffer, bytestoread);
   516   err = ((RFile64*)handle->tmpfile)->Read(ptrBuffer, bytestoread);
   517   if (err != KErrNone)
   518 	return -2;
   519 
   520   if (ptrBuffer.Length() != bytestoread)
   521 	return -2;
   522 
   523   return 0;
   524 }
   525 
   526 
   527 /*
   528  * Function:
   529  *
   530  *   mp4_i32 peekFile(MP4HandleImp handle,
   531  *                    mp4_u8 *buffer,
   532  *                    mp4_u32 bytestoread)
   533  *
   534  * Description:
   535  *
   536  *   Read data from a file but don't move the current position in the file
   537  *   forward.
   538  *
   539  * Parameters:
   540  *
   541  *   handle       MP4 library handle
   542  *   buffer       Buffer to read data into
   543  *   bytestoread  Number of bytes to read from file
   544  *
   545  * Return value:
   546  *
   547  *   0            Success
   548  *   -1           File has not been opened
   549  *   -2           Requested number of bytes could not be read
   550  *   -3           Current position in the file could not be set to original
   551  *                value
   552  *
   553  */
   554 mp4_i32 peekFile(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestoread)
   555 {
   556   mp4_i32 ret;
   557   mp4_i32 amount;
   558 
   559 
   560   ret = bufferedRead(handle, buffer, bytestoread);
   561   if (ret != 0)
   562     return ret;
   563 
   564   amount = -(mp4_i32)bytestoread;
   565 
   566   ret = bufferedSeek(handle, amount);
   567   if (ret != 0)
   568     return ret;
   569 
   570   return 0;
   571 }
   572 
   573 
   574 /*
   575  * Function:
   576  *
   577  *   mp4_i32 seekFile(MP4HandleImp handle,
   578  *                    mp4_i32 amount)
   579  *
   580  * Description:
   581  *
   582  *   Seek in a file.
   583  *
   584  * Parameters:
   585  *
   586  *   handle   MP4 library handle
   587  *   amount   Amount to seek from current position
   588  *
   589  * Return value:
   590  *
   591  *   0        Success
   592  *   -1       File has not been opened
   593  *   -3       Current position in the file could not be set
   594  *
   595  */
   596 mp4_i32 seekFile(MP4HandleImp handle, mp4_i64 amount)
   597 {
   598   return bufferedSeek(handle, amount);
   599 }
   600 
   601 
   602 /*
   603  * Function:
   604  *
   605  *   mp4_i32 seekFileAbs(MP4HandleImp handle,
   606  *                       mp4_i32 amount)
   607  *
   608  * Description:
   609  *
   610  *   Seek from the beginning of a file.
   611  *
   612  * Parameters:
   613  *
   614  *   handle   MP4 library handle
   615  *   amount   Amount to seek from the beginning of the file
   616  *
   617  * Return value:
   618  *
   619  *   0        Success
   620  *   -1       File has not been opened
   621  *   -3       Current position in the file could not be set
   622  *
   623  */
   624 mp4_i32 seekFileAbs(MP4HandleImp handle, mp4_i64 amount)
   625 {
   626   return bufferedSeekAbs(handle, amount);
   627 }
   628 
   629 
   630 /*
   631  * Function:
   632  *
   633  *   mp4_i32 seekFileWrite(MP4HandleImp handle,
   634  *                         mp4_i64 amount)
   635  *
   636  * Description:
   637  *
   638  *   Seek in a file that has been opened for writing.
   639  *
   640  * Parameters:
   641  *
   642  *   handle   MP4 library handle
   643  *   amount   Amount to seek from current position
   644  *
   645  * Return value:
   646  *
   647  *   0        Success
   648  *   -1       File has not been opened
   649  *   -2       Can't write buffers to file
   650  *   -3       Current position in the file could not be set
   651  *
   652  */
   653 mp4_i32 seekFileWrite(MP4HandleImp handle, mp4_i64 amount)
   654 {
   655 
   656   if (!handle->rfile)
   657     return -1;
   658 
   659   if ( handle->filewriter )
   660   {
   661     PRINT((_L("e_seekfilewrite_flush_filewriter 1")));        
   662     if ( (handle->filewriter)->Flush(KNullDesC8) != KErrNone )
   663     {
   664       PRINT((_L("e_seekfilewrite_flush_filewriter 0")));        
   665       return -2;
   666     }
   667     PRINT((_L("e_seekfilewrite_flush_filewriter 0")));        
   668   }
   669   else
   670   {
   671     return -1;
   672   }
   673 
   674   PRINT((_L("e_seekfilewrite_seek_rfile 1")));        
   675   if (((RFile64 *)(handle->rfile))->Seek(ESeekCurrent,amount) != KErrNone)
   676   {
   677     return -3;
   678   }
   679   
   680   PRINT((_L("e_seekfilewrite_seek_rfile 0")));        
   681 
   682   return 0;
   683 }
   684 
   685 
   686 /*
   687  * Function:
   688  *
   689  *   mp4_i32 seekFileAbsWrite(MP4HandleImp handle,
   690  *                            mp4_i32 amount)
   691  *
   692  * Description:
   693  *
   694  *   Seek from the beginning of a file that has been opened for writing.
   695  *
   696  * Parameters:
   697  *
   698  *   handle   MP4 library handle
   699  *   amount   Amount to seek from the beginning of the file
   700  *
   701  * Return value:
   702  *
   703  *   0        Success
   704  *   -1       File has not been opened
   705  *   -2       Can't write buffers to file
   706  *   -3       Current position in the file could not be set
   707  *
   708  */
   709 mp4_i32 seekFileAbsWrite(MP4HandleImp handle, mp4_i64 amount)
   710 {
   711   if (!handle->rfile)
   712     return -1;
   713 
   714   if ( handle->filewriter )
   715   {
   716     PRINT((_L("e_seekfileabswrite_flush 1")));        
   717     if ( (handle->filewriter)->Flush(KNullDesC8) != KErrNone )
   718     {
   719       PRINT((_L("e_seekfileabswrite_flush 0")));        
   720       return -2;
   721     }
   722     PRINT((_L("e_seekfileabswrite_flush 0")));        
   723   }
   724   else
   725   {
   726     return -1;
   727   }
   728 
   729   PRINT((_L("e_seekfileabswrite_seek 1")));  
   730   if (((RFile64 *)(handle->rfile))->Seek(ESeekStart, amount) != KErrNone)
   731   {
   732     return -3;
   733   }
   734   PRINT((_L("e_seekfileabswrite_seek 0")));        
   735 
   736   return 0;
   737 }
   738 
   739 
   740 /*
   741  * Function:
   742  *
   743  *   mp4_i32 seekTmpFileAbs(MP4HandleImp handle,
   744  *                          mp4_i32 amount)
   745  *
   746  * Description:
   747  *
   748  *   Seek from the beginning of a temporary file.
   749  *
   750  * Parameters:
   751  *
   752  *   handle   MP4 library handle
   753  *   amount   Amount to seek from the beginning of the file
   754  *
   755  * Return value:
   756  *
   757  *   0        Success
   758  *   -1       File has not been opened
   759  *   -3       Current position in the file could not be set
   760  *
   761  */
   762 mp4_i32 seekTmpFileAbs(MP4HandleImp handle, mp4_i64 amount)
   763 {
   764   if (!handle->tmpfile)
   765     return -1;
   766 
   767   TInt err;
   768   TInt64 amount64 = amount;
   769   err = ((RFile64*)handle->tmpfile)->Seek(ESeekStart, amount64);
   770   if (err != KErrNone)
   771 	return -3;
   772 
   773   return 0;
   774 }
   775 
   776 
   777 /*
   778  * Function:
   779  *
   780  *   mp4_i32 writeFile(MP4HandleImp handle,
   781  *                     mp4_u8 *buffer,
   782  *                     mp4_u32 bytestowrite)
   783  *
   784  * Description:
   785  *
   786  *   Write data into a file.
   787  *
   788  * Parameters:
   789  *
   790  *   handle        MP4 library handle
   791  *   buffer        Buffer containing the data
   792  *   bytestowrite  Number of bytes to write
   793  *
   794  * Return value:
   795  *
   796  *   0             Success
   797  *   -1            File has not been opened
   798  *   -2            Number of bytes written is not equal to bytestowrite
   799  *
   800  */
   801 mp4_i32 writeFile(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestowrite)
   802 {
   803   return bufferedWrite(handle, buffer, bytestowrite);
   804 }
   805 
   806 
   807 /*
   808  * Function:
   809  *
   810  *   mp4_i32 writeFileUnbuffered(MP4HandleImp handle,
   811  *                               mp4_u8 *buffer,
   812  *                               mp4_u32 bytestowrite)
   813  *
   814  * Description:
   815  *
   816  *   Write data into a file without buffering.
   817  *
   818  * Parameters:
   819  *
   820  *   handle        MP4 library handle
   821  *   buffer        Buffer containing the data
   822  *   bytestowrite  Number of bytes to write
   823  *
   824  * Return value:
   825  *
   826  *   0             Success
   827  *   -1            File has not been opened
   828  *   -2            Number of bytes written is not equal to bytestowrite
   829  *
   830  */
   831 mp4_i32 writeFileUnbuffered(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestowrite)
   832 {
   833   if(handle->bufferWrite)
   834   {
   835 	mp4memcpy(handle->composeBuffer+FTYP_SIZE + handle->ftypdelta,buffer,bytestowrite);
   836 	return 0;
   837   }
   838   if (!handle->rfile)
   839     return -1;
   840 
   841   if ( handle->filewriter )
   842   {
   843     TPtrC8 buf = TPtrC8((TUint8 *)(buffer), bytestowrite);
   844     PRINT((_L("e_writefileunbuffered_flush 1")));        
   845     if ( (handle->filewriter)->Flush( buf ) != KErrNone )
   846     {
   847       PRINT((_L("e_writefileunbuffered_flush 0")));        
   848       return -2;
   849     }
   850     PRINT((_L("e_writefileunbuffered_flush 0")));        
   851   }
   852   else
   853   {
   854     return -1;
   855   }
   856 
   857   return 0;
   858 }
   859 
   860 
   861 /*
   862  * Function:
   863  *
   864  *   mp4_i32 writeTmpFile(MP4HandleImp handle,
   865  *                        mp4_u8 *buffer,
   866  *                        mp4_u32 bytestowrite)
   867  *
   868  * Description:
   869  *
   870  *   Write data into a temporary file.
   871  *
   872  * Parameters:
   873  *
   874  *   handle        MP4 library handle
   875  *   buffer        Buffer containing the data
   876  *   bytestowrite  Number of bytes to write
   877  *
   878  * Return value:
   879  *
   880  *   0             Success
   881  *   -1            File has not been opened
   882  *   -2            Number of bytes written is not equal to bytestowrite
   883  *
   884  */
   885 mp4_i32 writeTmpFile(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestowrite)
   886 {
   887   if (!handle->tmpfile)
   888     return -1;
   889 
   890   TInt err;
   891   TPtrC8 ptrBuffer(buffer, bytestowrite);
   892   err = ((RFile64*)handle->tmpfile)->Write(ptrBuffer, bytestowrite);
   893   if (err != KErrNone)
   894 	return -2;
   895 
   896   if (ptrBuffer.Length() != bytestowrite)
   897 	return -2;
   898 
   899   handle->bytesInTmpFile += bytestowrite;
   900 
   901   return 0;
   902 }
   903 
   904 
   905 /*
   906  * Function:
   907  *
   908  *   mp4_i32 createTmpFileName(MP4FileName filename,
   909  *                             MP4FileName *tmpfilename)
   910  *
   911  * Description:
   912  *
   913  *   Create a temporary file name by adding .tmp to the end of a file name.
   914  *
   915  * Parameters:
   916  *
   917  *   filename     Original file name
   918  *   tmpfilename  Temporary file name is returned here
   919  *
   920  * Return value:
   921  *
   922  *   0            Success
   923  *   -1           Memory could not be allocated for the new name
   924  *
   925  */
   926 mp4_i32 createTmpFileName(MP4FileName filename, MP4FileName *tmpfilename)
   927 {
   928   *tmpfilename = (MP4FileName)mp4malloc(2 * wcslen(filename) + 10);
   929   if (*tmpfilename == NULL)
   930     return -1;
   931 
   932   wcscat(*tmpfilename, filename);
   933   wcscat(*tmpfilename, L".tmp");
   934 
   935   return 0;
   936 }
   937 
   938 
   939 /*
   940  * Function:
   941  *
   942  *   mp4_i32 freeTmpFileName(MP4FileName filename)
   943  *
   944  * Description:
   945  *
   946  *   Free memory allocated for the temporary file name.
   947  *
   948  * Parameters:
   949  *
   950  *   filename   Buffer containing file name
   951  *
   952  * Return value:
   953  *
   954  *   0          Success
   955  *
   956  */
   957 mp4_i32 freeTmpFileName(MP4FileName filename)
   958 {
   959   if (filename)
   960     mp4free(filename);
   961 
   962   return 0;
   963 }
   964 
   965 
   966 /*
   967  * Function:
   968  *
   969  *   void closeStdlib()
   970  *
   971  * Description:
   972  *
   973  *   Free memory allocated by stdlib wrapper functions (Symbian OS only).
   974  *
   975  * Parameters:
   976  *
   977  *   None
   978  *
   979  * Return value:
   980  *
   981  *   None
   982  *
   983  */
   984 void closeStdlib()
   985 	{
   986 	// retrieves the TLS which stores the number of currently active instances of 
   987 	// composer/parser
   988 	TInt p = (TInt) Dll::Tls();
   989 	
   990 	// decrement the counter as one instance is being closed at this point
   991 	p--;
   992 	Dll::SetTls((TAny*) p);		
   993 
   994 	if (p == 0)
   995 		{
   996 		// Since memory allocated for stdlib is shared amongst all composers and/or parsers  
   997 		// within a thread, stdlib close should ONLY be called for the last instance of   
   998 		// composer / parser.
   999 		//
  1000 		// If there are no other active instances other than this,
  1001 		// the memory allocated for stdlib for this thread can now be released.
  1002 		Dll::FreeTls();
  1003 		CloseSTDLIB();
  1004 		}
  1005 	}
  1006 
  1007 /*
  1008  * Function:
  1009  *
  1010  *   void openStdlib()
  1011  *
  1012  * Description:
  1013  *
  1014  *   Register the use of stdlib.  
  1015  *
  1016  * Parameters:
  1017  *
  1018  *   None
  1019  *
  1020  * Return value:
  1021  *
  1022  *   0 			Success
  1023  *
  1024  */
  1025 mp4_i32 openStdlib()
  1026 	{
  1027 	// retrieve the the value stored in TLS for this DLL 
  1028 	TInt p = (TInt) Dll::Tls();
  1029 	
  1030 	// increment it.  This becomes a reference counter of 
  1031 	// how many instances of the composer/parser is currently active 
  1032 	p++;
  1033 	return (Dll::SetTls((TAny*) p));		
  1034 	}
  1035 
  1036 /*
  1037  * Function:
  1038  *
  1039  *   mp4_i32 bufferedRead(MP4HandleImp handle,
  1040  *                        mp4_u8 *buffer,
  1041  *                        mp4_u32 bytestoread)
  1042  *
  1043  * Description:
  1044  *
  1045  *   Read data from a file in a buffered manner.
  1046  *
  1047  * Parameters:
  1048  *
  1049  *   handle       MP4 library handle
  1050  *   buffer       Buffer to read data into
  1051  *   bytestoread  Number of bytes to read from file
  1052  *
  1053  * Return value:
  1054  *
  1055  *   0            Success
  1056  *   -1           File has not been opened
  1057  *   -2           Requested number of bytes could not be read
  1058  *
  1059  */
  1060 mp4_i32 bufferedRead(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestoread)
  1061 {
  1062   mp4_u32 bytesread = 0;
  1063 
  1064   if (!handle->file)
  1065     return -1;
  1066 
  1067   while (bytesread < bytestoread)
  1068   {
  1069     mp4_u32 available;
  1070 
  1071 
  1072     available = handle->diskReadSize - handle->diskReadBufPos;
  1073     if (available > bytestoread - bytesread)
  1074       available = bytestoread - bytesread;
  1075 
  1076     if (available > 0) /* Copy data from memory buffer */
  1077     {
  1078       mp4memcpy(buffer + bytesread, handle->diskReadBuf + handle->diskReadBufPos, available);
  1079       handle->diskReadBufPos += available;
  1080       bytesread += available;
  1081     }
  1082     else /* Read more data from file into memory buffer */
  1083     {
  1084       TInt readBufferSize = 0;
  1085       if ( handle->readBufferSize == 0)
  1086         {
  1087         readBufferSize = READBUFSIZE;
  1088         }
  1089       else
  1090         {
  1091         readBufferSize = handle->readBufferSize;
  1092         }
  1093 
  1094       TPtr8 buf = TPtr8((TUint8 *)(handle->diskReadBuf), readBufferSize);
  1095 
  1096       switch (handle->sourceType)
  1097       {
  1098         case MP4_SOURCE_RFILE:
  1099           if (((RFile64 *)(handle->rfile))->Read(buf, readBufferSize) != KErrNone)
  1100             return -2;
  1101           break;
  1102         case MP4_SOURCE_CAF:
  1103           handle->cafError = handle->cfile->Read(buf, readBufferSize);
  1104           if ( handle->cafError != KErrNone)
  1105             return -2;
  1106           break;
  1107         default:
  1108           return -1;
  1109       }
  1110 
  1111       if ((mp4_u32)buf.Length() == 0) /* EOF or error */
  1112         return -2;
  1113 
  1114       handle->diskReadBufPos = 0;
  1115       handle->diskReadSize = (mp4_u32)buf.Length();
  1116       handle->diskReadBufStart = handle->diskReadPos;
  1117       handle->diskReadPos += handle->diskReadSize;
  1118     }
  1119   }
  1120 
  1121   return 0;
  1122 }
  1123 
  1124 /*
  1125  * Function:
  1126  *
  1127  *   mp4_i32 bufferedSeek(MP4HandleImp handle,
  1128  *                        mp4_i32 amount)
  1129  *
  1130  * Description:
  1131  *
  1132  *   Seek in a buffered file.
  1133  *
  1134  * Parameters:
  1135  *
  1136  *   handle   MP4 library handle
  1137  *   amount   Amount to seek from current position
  1138  *
  1139  * Return value:
  1140  *
  1141  *   0        Success
  1142  *   -1       File has not been opened
  1143  *   -3       Current position in the file could not be set
  1144  *
  1145  */
  1146 mp4_i32 bufferedSeek(MP4HandleImp handle, mp4_i64 amount)
  1147 {
  1148   if (!handle->file)
  1149     return -1;
  1150 
  1151   /* Is the new seek point inside the current memory buffer? */
  1152   if ((mp4_i32)handle->diskReadBufPos + amount >= 0 &&
  1153       handle->diskReadBufPos + amount < handle->diskReadSize)
  1154   {
  1155     /* Yes */
  1156 
  1157     handle->diskReadBufPos += amount;
  1158   }
  1159   else
  1160   {
  1161     /* No */
  1162 
  1163     TInt64 am;
  1164 
  1165 
  1166     am = amount - ((mp4_i32)handle->diskReadSize - (mp4_i32)handle->diskReadBufPos);
  1167 
  1168     if ( handle->rfile )
  1169         {
  1170         mp4_i64 maxsize = 0;
  1171         ((RFile64 *)(handle->rfile))->Size(maxsize);
  1172         maxsize -= (mp4_i64)handle->diskReadPos;
  1173         
  1174         if (am > maxsize)
  1175             {
  1176             return -3;
  1177             }
  1178         }
  1179 	// Coverity thinks that cfile can never be not NULL, which is incorrect; it can be a proper value. The comment below silences the Coverity warning
  1180 	//coverity[var_compare_op]
  1181     else if ( handle->cfile )
  1182         {
  1183         mp4_i64 maxsize = 0;
  1184         TRAPD(caferr, handle->cfile->DataSize64L(maxsize));
  1185         maxsize -= (mp4_i64)handle->diskReadPos;
  1186         
  1187         if (!caferr && am > maxsize)
  1188             {
  1189             return -3;
  1190             }
  1191         }
  1192 
  1193     switch (handle->sourceType)
  1194     {
  1195       case MP4_SOURCE_RFILE:
  1196 		{
  1197         PRINT((_L("e_bufferedseek_seek_rfile 1")));        
  1198         if (((RFile64 *)(handle->rfile))->Seek(ESeekCurrent, am) != KErrNone)
  1199 		  {
  1200 		    return -3;
  1201 		  }
  1202         PRINT((_L("e_bufferedseek_seek_rfile 0")));        
  1203         break;
  1204 		}
  1205       case MP4_SOURCE_CAF:
  1206         PRINT((_L("e_bufferedseek_seek_cfile 1")));        
  1207 		// See comment on handle->cfile dereference above on why the coverity[] comment below is needed
  1208 		//coverity[var_deref_model]
  1209       	handle->cafError = handle->cfile->Seek64(ESeekCurrent, am);
  1210         if ( handle->cafError != KErrNone)
  1211           return -3;
  1212         PRINT((_L("e_bufferedseek_seek_cfile 0")));        
  1213         break;
  1214       default:
  1215         return -1;
  1216     }
  1217 
  1218     handle->diskReadPos = handle->diskReadBufStart + handle->diskReadBufPos + amount;
  1219     handle->diskReadBufPos = 0;
  1220     handle->diskReadBufStart = 0;
  1221     handle->diskReadSize = 0;
  1222   }
  1223 
  1224   return 0;
  1225 }
  1226 
  1227 
  1228 /*
  1229  * Function:
  1230  *
  1231  *   mp4_i32 bufferedSeekAbs(MP4HandleImp handle,
  1232  *                           mp4_i32 amount)
  1233  *
  1234  * Description:
  1235  *
  1236  *   Seek in a buffered file from the start of the file.
  1237  *
  1238  * Parameters:
  1239  *
  1240  *   handle   MP4 library handle
  1241  *   amount   Amount to seek from start of the file
  1242  *
  1243  * Return value:
  1244  *
  1245  *   0        Success
  1246  *   -1       File has not been opened
  1247  *   -3       Current position in the file could not be set
  1248  *
  1249  */
  1250 mp4_i32 bufferedSeekAbs(MP4HandleImp handle, mp4_i64 amount)
  1251 {
  1252   if (!handle->file)
  1253     return -1;
  1254 
  1255   /* Is the new seek point inside the current memory buffer? */
  1256   if (handle->diskReadBufStart <= (mp4_u64)amount &&
  1257       handle->diskReadBufStart + handle->diskReadSize > (mp4_u64)amount)
  1258   {
  1259     /* Yes */
  1260 
  1261     handle->diskReadBufPos = amount - handle->diskReadBufStart;
  1262   }
  1263   else
  1264   {
  1265     /* No */
  1266 
  1267     mp4_i64 am = amount;
  1268 
  1269     switch (handle->sourceType)
  1270     {
  1271       case MP4_SOURCE_RFILE:
  1272 		{
  1273         PRINT((_L("e_bufferedseekabs_seek_rfile 1")));
  1274         if (((RFile64 *)(handle->rfile))->Seek(ESeekStart, am) != KErrNone)
  1275 		  {
  1276 		    return -3;
  1277 		  }
  1278         PRINT((_L("e_bufferedseekabs_seek_rfile 0")));        
  1279         break;
  1280 		}
  1281       case MP4_SOURCE_CAF:
  1282         PRINT((_L("e_bufferedseekabs_seek_cfile 1")));
  1283       	handle->cafError = handle->cfile->Seek64(ESeekStart, am);
  1284         PRINT((_L("e_bufferedseekabs_seek_cfile 0")));
  1285         if ( handle->cafError != KErrNone)
  1286           return -3;
  1287         break;
  1288       default:
  1289         return -1;
  1290     }
  1291 
  1292     handle->diskReadPos = (mp4_u64)amount;
  1293     handle->diskReadBufPos = 0;
  1294     handle->diskReadBufStart = 0;
  1295     handle->diskReadSize = 0;
  1296   }
  1297 
  1298   return 0;
  1299 }
  1300 
  1301 
  1302 /*
  1303  * Function:
  1304  *
  1305  *   mp4_i32 bufferedWrite(MP4HandleImp handle,
  1306  *                         mp4_u8 *buffer,
  1307  *                         mp4_u32 bytestowrite)
  1308  *
  1309  * Description:
  1310  *
  1311  *   Write data into a file in a buffered manner.
  1312  *
  1313  * Parameters:
  1314  *
  1315  *   handle        MP4 library handle
  1316  *   buffer        Buffer containing the data
  1317  *   bytestowrite  Number of bytes to write
  1318  *
  1319  * Return value:
  1320  *
  1321  *   0             Success
  1322  *   -1            File has not been opened
  1323  *   -2            Number of bytes written is not equal to bytestowrite
  1324  *
  1325  */
  1326 mp4_i32 bufferedWrite(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestowrite)
  1327 {
  1328 	if(handle->bufferWrite)
  1329 	{
  1330 		if(handle->bytesProgressed+bytestowrite > *(handle->composedSize))
  1331 		{
  1332 			return MP4_OUTPUT_BUFFER_TOO_SMALL; //-1;
  1333 		}
  1334 		else
  1335 		{
  1336 			mp4memcpy(handle->composeBuffer+handle->bytesProgressed,buffer,bytestowrite);
  1337 			handle->bytesProgressed+=bytestowrite;
  1338 			return 0;
  1339 		}
  1340 	}
  1341 
  1342   if (!handle->rfile)
  1343     return -1;
  1344 
  1345   if ( handle->filewriter )
  1346   {
  1347     TPtrC8 buf = TPtrC8((TUint8 *)(buffer), bytestowrite);
  1348     PRINT((_L("e_file_bufferedwrite_write 1")));
  1349     if ( (handle->filewriter)->Write( buf ) != KErrNone )
  1350     {
  1351       return -2;
  1352     }
  1353     PRINT((_L("e_file_bufferedwrite_write 0")));
  1354   }
  1355   else
  1356   {
  1357     return -1;    
  1358   }
  1359 
  1360   return 0;
  1361 }
  1362 
  1363 
  1364 /*
  1365  * Function:
  1366  *
  1367  *   mp4_i32 initMetaDataFiles(MP4HandleImp handle)
  1368  *
  1369  * Description:
  1370  *
  1371  *   Open temporary files for writing.
  1372  *
  1373  * Parameters:
  1374  *
  1375  *   handle     MP4 library handle
  1376  *
  1377  * Return value:
  1378  *
  1379  *   0          		Success
  1380  *   -1         		General Error
  1381  *	 MP4_OUT_OF_MEMORY	Out of memory
  1382  *
  1383  */
  1384 mp4_i32 initMetaDataFiles(MP4HandleImp handle)
  1385 {
  1386   PRINT(_L("3GPLib::initMetaDataFiles() in"));
  1387   TFileName filename;
  1388   TFileName path;
  1389   TInt error;
  1390 
  1391   TDriveList driveList;
  1392   TBool pathSet = EFalse;
  1393   
  1394   // As ram drive access is faster, try to set temp file directory to available ram drive.
  1395   if (((RFs *)(handle->fs))->DriveList(driveList) == KErrNone)
  1396 	{
  1397 	for ( TInt i = 0; i < driveList.Length(); i++ )
  1398 		{
  1399 		TDriveInfo driveInfo;
  1400 		if (((RFs *)(handle->fs))->Drive(driveInfo, i) == KErrNone)
  1401 			{
  1402 			if (driveInfo.iType == EMediaRam)
  1403 				{
  1404 				TChar driveLetter;
  1405 				((RFs *)(handle->fs))->DriveToChar(i, driveLetter);
  1406 				path.Append(driveLetter);
  1407 				path.Append(_L(":"));
  1408 				path.Append(KTmpDirectoryName);
  1409 				pathSet = ETrue;
  1410 				break;
  1411 				}
  1412 			}
  1413 		}
  1414 	}
  1415 	  
  1416   // If no ram drive was found create a directory for the files on current drive
  1417   if (!pathSet)
  1418 	{
  1419 	if ( handle->fileName )
  1420 		{
  1421 		filename = (TText *)handle->fileName;
  1422     
  1423 		TParse fp;
  1424 		path = KTmpDirectoryName;
  1425 		if (((RFs *)(handle->fs))->Parse(filename, fp) != KErrNone)
  1426 			return -1;
  1427 		path.Insert(0, fp.Drive());
  1428 		}
  1429 	else
  1430 		{
  1431 		TChar drive;
  1432 		if (((RFs *)(handle->fs))->DriveToChar(handle->fileHandleDrive, drive ) != KErrNone )
  1433 			return -1;
  1434 		path.Append( drive );
  1435 		path.Append( _L(":") );
  1436 		path.Append( KTmpDirectoryName );
  1437 		}
  1438 	}
  1439     
  1440   // Try to delete the temp folder from leftovers
  1441   // If other instance is using it then delete will just fail
  1442   PRINT((_L("e_initmetadatafiles_newl_fileman 1")));
  1443   CFileMan* fileMan = 0;
  1444   TRAP( error, fileMan = CFileMan::NewL(*(RFs *)(handle->fs)));
  1445   if ( error )
  1446     {
  1447         return -1;
  1448     }
  1449   PRINT((_L("e_initmetadatafiles_newl_fileman 0")));
  1450 
  1451   PRINT((_L("e_initmetadatafiles_deletedirectory 1")));  
  1452   error = fileMan->RmDir( path ); // Delete directory + all files
  1453   delete( fileMan );
  1454   PRINT((_L("e_initmetadatafiles_deletedirectory 0")));  
  1455 
  1456   error = ((RFs *)(handle->fs))->MkDirAll(path);
  1457   if (error != KErrNone && error != KErrAlreadyExists)
  1458     return -1;
  1459 
  1460   ((RFs *)(handle->fs))->SetEntry(path, TTime(0), KEntryAttHidden, NULL);
  1461 
  1462   // Create files
  1463   TFileName metadatafilename;
  1464 
  1465   for (TUint i = 0; i < NUM_MDF; i++)
  1466   {
  1467     handle->metaDataFile[i] = (void *)new(RFile64);
  1468     if (handle->metaDataFile[i] == NULL)
  1469       return MP4_OUT_OF_MEMORY;
  1470 
  1471     if (((RFile64 *)(handle->metaDataFile[i]))->Temp(*((RFs *)(handle->fs)), path, metadatafilename, EFileWrite | EFileShareExclusive) != KErrNone)
  1472       return -1;
  1473 
  1474     handle->metaDataFileEmpty[i] = EFalse;
  1475     
  1476     // save file name, used later for deleting
  1477     handle->metaDataFileName[i] = (MP4FileName)mp4malloc(2 * wcslen((MP4FileName)metadatafilename.Ptr()) + 2);
  1478     if (handle->metaDataFileName[i] == NULL)
  1479       return -1;
  1480     
  1481     wcscat(handle->metaDataFileName[i], (MP4FileName)metadatafilename.Ptr());
  1482     handle->metaDataFileName[i][metadatafilename.Length()] = 0;
  1483     PRINT((_L("3GPLib::initMetaDataFiles() handle->metaDataFileName[%d]=%s, length=%d "),i,  handle->metaDataFileName[i], metadatafilename.Length()));
  1484     
  1485   }
  1486 
  1487   PRINT(_L("3GPLib::initMetaDataFiles() creating MetaDataWriter"));
  1488   TRAPD(err,   handle->metadatafilewriter = CMetaDataFileWriter::NewL());
  1489   if ( err != KErrNone )
  1490   	{
  1491     PRINT((_L("3GPLib::initMetaDataFiles() MetaDataWriter creation error: %d"), err));
  1492     if ( err == KErrNoMemory )
  1493     	{
  1494     	return MP4_OUT_OF_MEMORY;    
  1495     	}
  1496     else
  1497     	{
  1498     	return -1;    
  1499 	    }
  1500   	}
  1501 
  1502   PRINT(_L("3GPLib::initMetaDataFiles() MetaDataWriter created"));
  1503   PRINT(_L("3GPLib::initMetaDataFiles() out"));
  1504   return 0;
  1505 }
  1506 
  1507 
  1508 /*
  1509  * Function:
  1510  *
  1511  *   mp4_i32 writeMetaDataFileNum(MP4HandleImp handle,
  1512  *                                mp4_u8 *buffer,
  1513  *                                mp4_u32 bytestowrite,
  1514  *                                mp4_u32 filenumber)
  1515  *
  1516  * Description:
  1517  *
  1518  *   Write data into a numbered file.
  1519  *
  1520  * Parameters:
  1521  *
  1522  *   handle        MP4 library handle
  1523  *   buffer        Buffer containing the data
  1524  *   bytestowrite  Number of bytes to write
  1525  *   filenumber    Index of temporary file
  1526  *
  1527  * Return value:
  1528  *
  1529  *   0             Success
  1530  *   -1            File has not been opened
  1531  *   -2            Number of bytes written is not equal to bytestowrite
  1532  *
  1533  */
  1534 mp4_i32 writeMetaDataFileNum(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestowrite, mp4_u32 filenumber)
  1535 {
  1536   PRINT(_L("3GPLib::writeMetaDataFileNum() in"));
  1537 
  1538   if (!handle->metaDataFile[filenumber])
  1539     return -1;
  1540 
  1541   if ( handle->metadatafilewriter )
  1542   {
  1543     TPtrC8 buf = TPtrC8((TUint8 *)(buffer), bytestowrite);
  1544     PRINT((_L("e_file_writeMetaDataFileNum_write 1")));
  1545     if ( (handle->metadatafilewriter)->Write( *((RFile64 *)(handle->metaDataFile[filenumber])),
  1546                                               filenumber,
  1547                                               buf ) != KErrNone )
  1548     {
  1549       return -2;
  1550     }
  1551     PRINT((_L("e_file_writeMetaDataFileNum_write 0")));
  1552   }
  1553   else
  1554   {
  1555     return -1;
  1556   } 
  1557 
  1558   PRINT(_L("3GPLib::writeMetaDataFileNum() out"));
  1559   return 0;
  1560 }
  1561 
  1562 
  1563 /*
  1564  * Function:
  1565  *
  1566  *   mp4_i32 seekMetaDataFileNumAbs(MP4HandleImp handle,
  1567  *                                  mp4_i32 amount,
  1568  *                                  mp4_u32 filenumber)
  1569  *
  1570  * Description:
  1571  *
  1572  *   Seek from the beginning of a numbered file.
  1573  *
  1574  * Parameters:
  1575  *
  1576  *   handle        MP4 library handle
  1577  *   amount        Amount to seek from the beginning of the file
  1578  *   filenumber    Index of temporary file
  1579  *
  1580  * Return value:
  1581  *
  1582  *   0        Success
  1583  *   -1       File has not been opened
  1584  *   -3       Current position in the file could not be set
  1585  *
  1586  */
  1587 mp4_i32 seekMetaDataFileNumAbs(MP4HandleImp handle, mp4_i64 amount, mp4_u32 filenumber)
  1588 {
  1589   PRINT(_L("3GPLib::seekMetaDataFileNumAbs() in"));
  1590 
  1591   if (!handle->metaDataFile[filenumber])
  1592     return -1;
  1593 
  1594 
  1595   if ( handle->metadatafilewriter )
  1596   {
  1597     PRINT((_L("e_seekmetadatafilenumabs_flush 1")));        
  1598     if ( (handle->metadatafilewriter)->Flush() != KErrNone )
  1599     {
  1600       PRINT((_L("e_seekmetadatafilenumabs_flush 0")));        
  1601       return -2;
  1602     }
  1603     PRINT((_L("e_seekmetadatafilenumabs_flush 0")));        
  1604   }
  1605 
  1606   PRINT((_L("e_seekmetadatafilenumabs_seek 1")));
  1607   if (((RFile64 *)(handle->metaDataFile[filenumber]))->Seek(ESeekStart, amount) != KErrNone)
  1608   {
  1609     return -3;
  1610   }
  1611   PRINT((_L("e_seekmetadatafilenumabs_seek 0")));        
  1612 
  1613   PRINT(_L("3GPLib::seekMetaDataFileNumAbs() out"));
  1614   return 0;
  1615 }
  1616 
  1617 
  1618 /*
  1619  * Function:
  1620  *
  1621  *   mp4_i32 readMetaDataFileNum(MP4HandleImp handle,
  1622  *                               mp4_u8 *buffer,
  1623  *                               mp4_u32 bytestoread,
  1624  *                               mp4_u32 filenumber)
  1625  *
  1626  * Description:
  1627  *
  1628  *   Read data from a numbered file.
  1629  *
  1630  * Parameters:
  1631  *
  1632  *   handle       MP4 library handle
  1633  *   buffer       Buffer to read data into
  1634  *   bytestoread  Number of bytes to read from file
  1635  *   filenumber   Index of temporary file
  1636  *
  1637  * Return value:
  1638  *
  1639  *   0            Success
  1640  *   -1           File has not been opened
  1641  *   -2           Requested number of bytes could not be read
  1642  *
  1643  */
  1644 mp4_i32 readMetaDataFileNum(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestoread, mp4_u32 filenumber)
  1645 {
  1646   PRINT(_L("3GPLib::readMetaDataFileNum() in"));
  1647   PRINT((_L("e_readmetadatafiles 1")));
  1648 
  1649   mp4_u32 bytesread = 0;
  1650   TPtr8 buf = TPtr8((TUint8 *)buffer, bytestoread);
  1651 
  1652   if (!handle->metaDataFile[filenumber])
  1653     return -1;
  1654 
  1655   if ( handle->metadatafilewriter )
  1656   {
  1657     PRINT((_L("e_readmetadatafiles_flush 1")));
  1658     if ( (handle->metadatafilewriter)->Flush() != KErrNone )
  1659     {
  1660       return -2;
  1661     }
  1662     PRINT((_L("e_readmetadatafiles_flush 0")));
  1663   }
  1664 
  1665   PRINT((_L("e_readmetadatafiles_read 1")));
  1666   
  1667   if (handle->metaDataFileEmpty[filenumber])
  1668     {
  1669     if (handle->metadatafilewriter)
  1670     	{	
  1671     	// if the file is empty, then read the data from temp buffer
  1672     	bytesread = (handle->metadatafilewriter)->ReadBuffer( filenumber, buf, bytestoread);    	
  1673     	}
  1674     if ( bytesread != bytestoread )
  1675         return -2;
  1676     }
  1677   else if (((RFile64 *)(handle->metaDataFile[filenumber]))->Read(buf, bytestoread) != KErrNone)
  1678     {
  1679     handle->metaDataFileEmpty[filenumber] = ETrue;
  1680     // if the file is empty, then read the data from temp buffer
  1681     if (handle->metadatafilewriter)
  1682     	{	
  1683     	bytesread = (handle->metadatafilewriter)->ReadBuffer( filenumber, buf, bytestoread);    	
  1684     	}
  1685     if ( bytesread != bytestoread )
  1686         return -2;
  1687     }
  1688   else if ( buf.Length() < bytestoread ) // Got only part of data from file, rest is in buffer
  1689     {
  1690     handle->metaDataFileEmpty[filenumber] = ETrue;
  1691     // if the file is empty, then read the data from temp buffer
  1692     if (handle->metadatafilewriter)
  1693     	{
  1694     	bytesread = (handle->metadatafilewriter)->ReadBuffer( filenumber, buf, bytestoread - buf.Length());    	
  1695     	}
  1696     if ( buf.Length() != bytestoread )
  1697         return -2;
  1698     }
  1699     
  1700   PRINT((_L("e_readmetadatafiles_read 0")));
  1701 
  1702   if ((mp4_u32)buf.Length() == 0) /* EOF or error */
  1703     return -2;
  1704 
  1705   PRINT(_L("3GPLib::readMetaDataFileNum() out"));
  1706   PRINT((_L("e_readmetadatafiles 0")));
  1707   return 0;
  1708 }
  1709 
  1710 
  1711 /*
  1712  * Function:
  1713  *
  1714  *   mp4_i32 deleteMetaDataFiles(MP4HandleImp handle)
  1715  *
  1716  * Description:
  1717  *
  1718  *   Remove a numbered temporary file.
  1719  *
  1720  * Parameters:
  1721  *
  1722  *   handle   MP4 library handle
  1723  *
  1724  * Return value:
  1725  *
  1726  *   0        Success
  1727  *   -1       Error
  1728  *
  1729  */
  1730 mp4_i32 deleteMetaDataFiles(MP4HandleImp handle)
  1731 {
  1732   PRINT(_L("3GPLib::deleteMetaDataFiles() in"));
  1733   PRINT((_L("e_deletemetadatafiles 1")));
  1734 
  1735   TFileName filename;
  1736   TFileName path;
  1737   TInt err;
  1738 
  1739   if ( handle->metadatafilewriter )
  1740   {
  1741     PRINT((_L("e_deletemetadatafiles_flush 1")));
  1742     if ( (handle->metadatafilewriter)->Flush() != KErrNone )
  1743     {
  1744       PRINT((_L("e_deletemetadatafiles_flush 0")));
  1745       return -2;
  1746     }
  1747     PRINT((_L("e_deletemetadatafiles_flush 0")));
  1748     delete handle->metadatafilewriter;
  1749     handle->metadatafilewriter = NULL;
  1750   }
  1751     
  1752   /* Determine file names */
  1753   PRINT((_L("e_deletemetadatafiles_determinenames 1")));
  1754   if ( handle->fileName )
  1755     {  
  1756      filename = (TText *)handle->fileName;
  1757      path = KTmpDirectoryName;
  1758 
  1759     TParse fp;
  1760     if (((RFs *)(handle->fs))->Parse(filename, fp) != KErrNone)
  1761         return -1;
  1762     path.Insert(0, fp.Drive());
  1763     }
  1764   else
  1765     {
  1766     TChar drive;
  1767     if (((RFs *)(handle->fs))->DriveToChar(handle->fileHandleDrive, drive ) != KErrNone )
  1768         return -1;
  1769     path.Append( drive );
  1770     path.Append( _L(":") );
  1771     path.Append( KTmpDirectoryName );    
  1772     }
  1773   PRINT((_L("e_deletemetadatafiles_determinenames 0")));    
  1774     
  1775   PRINT((_L("e_deletemetadatafiles_deletemetadatafilenames 1")));    
  1776   for (TUint i = 0; i < NUM_MDF; i++)
  1777   {
  1778     if (handle->metaDataFileName[i])
  1779       {
  1780       // check if client has defined async delete observer
  1781       if ( handle->tempFileRemoverObserver )
  1782         {
  1783         PRINT((_L("3GPLib::deleteMetaDataFiles() nro=%d sending %x to observer: %s"), i,handle->metaDataFileName[i], handle->metaDataFileName[i]));
  1784         handle->tempFileRemoverObserver->M3GPMP4LibDeleteTempFileName( handle->metaDataFileName[i] );
  1785         }
  1786       else // no observer, delete right here, ignore errors
  1787         {
  1788         PRINT((_L("3GPLib::deleteMetaDataFiles() nro=%d wremove: %s"), i, handle->metaDataFileName[i]));
  1789         err = wremove(handle->metaDataFileName[i]);
  1790         PRINT((_L("3GPLib::deleteMetaDataFiles() wremove err=%d"), err));
  1791         err++; // to remove compile warnings
  1792         mp4free(handle->metaDataFileName[i]);
  1793         }
  1794       handle->metaDataFileName[i] = 0;
  1795       }
  1796   PRINT((_L("e_deletemetadatafiles_deletemetadatafilenames 0")));    
  1797 
  1798   }
  1799 
  1800   PRINT(_L("3GPLib::deleteMetaDataFiles() out"));
  1801   PRINT((_L("e_deletemetadatafiles 0")));
  1802   return 0;
  1803 }
  1804 
  1805 
  1806 /*
  1807  * Function:
  1808  *
  1809  *   mp4_i32 closeMetaDataFiles(MP4HandleImp handle)
  1810  *
  1811  * Description:
  1812  *
  1813  *   Close numbered tmp files.
  1814  *
  1815  * Parameters:
  1816  *
  1817  *   handle   MP4 library handle
  1818  *
  1819  * Return value:
  1820  *
  1821  *   0        Success
  1822  *
  1823  */
  1824 mp4_i32 closeMetaDataFiles(MP4HandleImp handle)
  1825 {
  1826   PRINT(_L("3GPLib::closeMetaDataFiles() in"));
  1827   PRINT((_L("e_close_metadatafiles 1")));
  1828 
  1829   if ( handle->metadatafilewriter )
  1830   {
  1831     PRINT((_L("e_close_metadatafiles_flush 1")));
  1832     if ( (handle->metadatafilewriter)->Flush() != KErrNone )
  1833     {
  1834       PRINT((_L("e_close_metadatafiles_flush 0")));
  1835       return -2;
  1836     }
  1837     PRINT((_L("e_close_metadatafiles_flush 0")));
  1838   }
  1839 
  1840   for (TUint i = 0; i < NUM_MDF; i++)
  1841   {
  1842     if (handle->metaDataFile[i])
  1843     {
  1844 	  PRINT((_L("e_close_metadatafiles_closefile 1")));    
  1845       ((RFile64 *)(handle->metaDataFile[i]))->Close();
  1846       PRINT((_L("e_close_metadatafiles_closefile 0")));
  1847 
  1848       PRINT((_L("e_close_metadatafiles_delfile 1")));
  1849       delete((RFile64 *)(handle->metaDataFile[i]));
  1850       PRINT((_L("e_close_metadatafiles_delfile 0")));
  1851       handle->metaDataFile[i] = NULL;
  1852     }
  1853   }
  1854 
  1855   PRINT(_L("3GPLib::closeMetaDataFiles() out"));
  1856   PRINT((_L("e_close_metadatafiles 0")));
  1857   return 0;
  1858 }
  1859 
  1860 
  1861 TInt RecommendedBufferSize(MP4HandleImp aHandle)
  1862 	{
  1863 	TInt recommendedSize = READBUFSIZE;
  1864 	
  1865     MP4HandleImp handle = (MP4HandleImp)aHandle;
  1866     if (handle)
  1867     	{
  1868 		// handle->rfile will be set in the cases of
  1869 		// - MP4ParseOpen(MP4FileName) <if the filename is set>
  1870 		// - MP4ParseOpenFileHandle64(RFile64)
  1871 		// - MP4ParseOpenFileHandle(RFile) <via MP4ParseOpenFileHandle64()>
  1872 		//
  1873 		// It will not be set by MP4ParseOpenCAF()
  1874 
  1875 		RFs* fs = (RFs*)handle->fs;
  1876 		RFile64* file64 = (RFile64*)handle->rfile;
  1877 		
  1878 		if (fs && file64)
  1879 			{
  1880 			TInt driveNumber = 0;
  1881 			TDriveInfo driveInfo;
  1882 			TVolumeIOParamInfo volumeInfo;
  1883 			
  1884 			TInt err = file64->Drive(driveNumber, driveInfo);
  1885 			if (err == KErrNone)
  1886 				{
  1887 				err = fs->VolumeIOParam(driveNumber, volumeInfo);
  1888 				}
  1889 			
  1890 			if (err == KErrNone)
  1891 				{
  1892 				if (volumeInfo.iRecReadBufSize != KErrNotSupported)
  1893 					{
  1894 					recommendedSize = Max(recommendedSize, volumeInfo.iRecReadBufSize);
  1895 					}
  1896 				}
  1897 				
  1898 			}
  1899     	}
  1900 
  1901     return recommendedSize;
  1902 	}
  1903 	
  1904 
  1905 // End of File