mmplugins/lib3gp/impl/src/file.cpp
changeset 0 40261b775718
child 7 94dbab0a2133
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmplugins/lib3gp/impl/src/file.cpp	Tue Feb 02 01:56:55 2010 +0200
@@ -0,0 +1,1763 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "mp4file.h"
+#include "mp4memwrap.h"
+#include "mp4atom.h"
+#include <stdio.h>
+#include <string.h>
+#include <sys/unistd.h>
+#include <sys/reent.h>
+#include <f32file.h>
+#include <f32file64.h>
+#include <e32des16.h>
+#include <caf/caf.h>
+
+using namespace ContentAccess;
+
+// Debug print macro
+#ifdef _DEBUG
+#include <e32svr.h>
+#define PRINT(x)     //comment this line and uncomment the line below to enable logging for this file
+//#define PRINT(x) RDebug::Print x
+#else
+#define PRINT(x)
+#endif
+
+_LIT(KTmpDirectoryName, "\\System\\Temp\\3GPLibTmpDir\\"); // Temporary output directory name
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 saveFileName(MP4FileName filename,
+ *                        MP4HandleImp handle)
+ *
+ * Description:
+ *
+ *   Save file name for later use.
+ *
+ * Parameters:
+ *
+ *   filename   Filename
+ *   handle     MP4 library handle
+ *
+ * Return value:
+ *
+ *   0          Success
+ *   -1         Error
+ *
+ */
+mp4_i32 saveFileName(MP4FileName filename, MP4HandleImp handle)
+{
+  handle->fileName = (MP4FileName)mp4malloc(2 * wcslen(filename) + 2);
+  if (handle->fileName == NULL)
+    return -1;
+
+  wcscat(handle->fileName, filename);
+
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 initFileRead(MP4FileName filename,
+ *                        MP4HandleImp handle)
+ *
+ * Description:
+ *
+ *   Open a file for reading.
+ *
+ *   Note: filename is a Unicode string in Symbian OS.
+ *
+ * Parameters:
+ *
+ *   filename   Filename
+ *   handle     MP4 library handle
+ *
+ * Return value:
+ *
+ *   0          Success
+ *   -1         Error
+ *
+ */
+mp4_i32 initFileRead(MP4FileName filename, MP4HandleImp handle)
+{
+  RFs   *fs;
+  RFile64 *file;
+
+
+  fs = new(RFs);
+  handle->fs = (void *)fs;
+  if (fs == NULL)
+    return -1;
+
+  if (fs->Connect() != KErrNone)
+    return -1;
+
+  file = new(RFile64);
+  handle->rfile = (void *)file;
+  if (file == NULL)
+    return -1;
+
+  if (file->Open(*fs, TPtrC((const TUint16 *)filename), EFileRead | EFileShareAny) != KErrNone)
+  {
+    // for compatibility, if opening in Any mode fails try more restrictive approach.
+    if (file->Open(*fs, TPtrC((const TUint16 *)filename), EFileRead | EFileShareReadersOnly) != KErrNone)
+    {
+        fs->Close();
+        return -1;
+    }
+  }
+  handle->file = handle->rfile;
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 initFileWrite(MP4FileName filename,
+ *                         MP4HandleImp handle)
+ *
+ * Description:
+ *
+ *   Open a file for writing.
+ *
+ *   Note: filename is a Unicode string in Symbian OS.
+ *
+ * Parameters:
+ *
+ *   filename   Filename
+ *   handle     MP4 library handle
+ *
+ * Return value:
+ *
+ *   0          Success
+ *   -1         Error
+ *
+ */
+mp4_i32 initFileWrite(MP4FileName filename, MP4HandleImp handle)
+{
+  RFs   *fs;
+  RFile64 *file;
+  TParse fp;
+  TFileName path;
+  TInt error;
+
+
+  fs = new(RFs);
+  handle->fs = (void *)fs;
+  if (fs == NULL)
+    return -1;
+
+  if (fs->Connect() != KErrNone)
+    return -1;
+
+  file = new(RFile64);
+  handle->rfile = (void *)file;
+  if (file == NULL)
+    return -1;
+
+  if (((RFs *)(handle->fs))->Parse(TPtrC((const TUint16 *)filename), fp) != KErrNone)
+    return -1;
+
+  path.Insert(0, fp.DriveAndPath() );
+  error = ((RFs *)(handle->fs))->MkDirAll(path);
+  if (error != KErrNone && error != KErrAlreadyExists)
+    return -1;
+
+  if (file->Replace(*fs, TPtrC((const TUint16 *)filename), EFileWrite|EFileShareExclusive ) != KErrNone)
+  {
+    fs->Close();
+    return -1;
+  }
+
+  handle->file = handle->rfile;
+
+  TRAP(error, handle->filewriter = CFileWriter::NewL( *file ));
+  if ( error != KErrNone )
+  {
+    return -1;    
+  }
+
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 initTmpFileWrite(MP4FileName filename,
+ *                            MP4HandleImp handle)
+ *
+ * Description:
+ *
+ *   Open a temporary file for writing.
+ *
+ *   Note: filename is a Unicode string in Symbian OS.
+ *
+ * Parameters:
+ *
+ *   filename   Filename
+ *   handle     MP4 library handle
+ *
+ * Return value:
+ *
+ *   0          Success
+ *   -1         Error
+ *
+ */
+mp4_i32 initTmpFileWrite(MP4FileName filename, MP4HandleImp handle)
+{
+  TInt err;
+  RFile64 * file = new RFile64;
+  TBuf16<KMaxFileName> name(reinterpret_cast<const TUint16*>(filename));
+  ASSERT(handle->fs != NULL);
+  err = file->Replace(*(RFs*)(handle->fs), name, EFileStream | EFileRead | EFileWrite);
+  if (err != KErrNone)
+  {
+	delete file;
+	return -1;
+  }
+
+  handle->tmpfile = (void *)file;
+  return 0;
+}
+ 
+
+/*
+ * Function:
+ *
+ *   mp4_i32 closeFile(MP4HandleImp handle)
+ *
+ * Description:
+ *
+ *   Close a file.
+ *
+ * Parameters:
+ *
+ *   handle   MP4 library handle
+ *
+ * Return value:
+ *
+ *   0        Success
+ *
+ */
+mp4_i32 closeFile(MP4HandleImp handle)
+{
+  PRINT((_L("e_closefile 1")));
+  if (handle->rfile)
+  {
+    if (handle->filewriter)
+    {
+      PRINT((_L("e_closefile_flush_filewriter 1")));        
+      (handle->filewriter)->Flush(KNullDesC8);
+      PRINT((_L("e_closefile_flush_filewriter 0")));        
+      delete handle->filewriter;
+      handle->filewriter = NULL;
+    }
+  }
+
+  if (handle->asyncReader)
+  {
+	delete handle->asyncReader;
+	handle->asyncReader = NULL;
+  }
+
+  if (handle->rfile)
+  {
+    if ( !handle->FileHandleFromOutside )
+        {
+  		PRINT((_L("e_closefile_close_file 1")));        
+        ((RFile64 *)(handle->rfile))->Close();
+  		PRINT((_L("e_closefile_close_file 0"))); 
+		PRINT((_L("e_closefile_delete_fileptr 1")));  		
+        delete(handle->rfile);
+		PRINT((_L("e_closefile_delete_fileptr 0")));        
+        }
+    handle->rfile = NULL;
+  }
+
+  if (handle->cfile)
+  {
+    if ( !handle->FileHandleFromOutside )
+        {
+        delete(handle->cfile);
+        }
+    handle->cfile = NULL;
+  }
+
+  PRINT((_L("e_closefile_close_rfs 1")));
+  if (handle->fs)
+  {
+    ((RFs *)(handle->fs))->Close();
+
+    delete(handle->fs);
+
+    handle->fs = NULL;
+  }
+  PRINT((_L("e_closefile_close_rfs 0")));  
+
+  handle->file = NULL;
+  PRINT((_L("e_closefile 0")));
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 closeTmpFile(MP4HandleImp handle)
+ *
+ * Description:
+ *
+ *   Close a temporary file.
+ *
+ * Parameters:
+ *
+ *   handle   MP4 library handle
+ *
+ * Return value:
+ *
+ *   0        Success
+ *
+ */
+mp4_i32 closeTmpFile(MP4HandleImp handle)
+{
+  if (handle->tmpfile)
+	((RFile64*)handle->tmpfile)->Close();
+
+  handle->tmpfile = NULL;
+
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 deleteTmpFile(MP4HandleImp handle)
+ *
+ * Description:
+ *
+ *   Remove a temporary file.
+ *
+ * Parameters:
+ *
+ *   handle   MP4 library handle
+ *
+ * Return value:
+ *
+ *   0        Success
+ *   -1       Error
+ *
+ */
+mp4_i32 deleteTmpFile(MP4HandleImp handle)
+{
+  if (handle->tmpFileName)
+	{
+	  TInt err;
+	  TBuf<KMaxFileName> name(reinterpret_cast<const TUint16*>(handle->tmpFileName));
+	  ASSERT(handle->fs != NULL);
+	  err = ((RFs*)handle->fs)->Delete(name);
+	  if (err != KErrNone)
+		return -1;
+	}
+
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 readFile(MP4HandleImp handle,
+ *                    mp4_u8 *buffer,
+ *                    mp4_u32 bytestoread)
+ *
+ * Description:
+ *
+ *   Read data from a file.
+ *
+ * Parameters:
+ *
+ *   handle       MP4 library handle
+ *   buffer       Buffer to read data into
+ *   bytestoread  Number of bytes to read from file
+ *
+ * Return value:
+ *
+ *   0            Success
+ *   -1           File has not been opened
+ *   -2           Requested number of bytes could not be read
+ *
+ */
+mp4_i32 readFile(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestoread)
+{
+  return bufferedRead(handle, buffer, bytestoread);
+}
+
+/*
+ * Function:
+ *
+ *   mp4_i32 readTmpFile(MP4HandleImp handle,
+ *                       mp4_u8 *buffer,
+ *                       mp4_u32 bytestoread)
+ *
+ * Description:
+ *
+ *   Read data from a temporary file.
+ *
+ * Parameters:
+ *
+ *   handle       MP4 library handle
+ *   buffer       Buffer to read data into
+ *   bytestoread  Number of bytes to read from file
+ *
+ * Return value:
+ *
+ *   0            Success
+ *   -1           File has not been opened
+ *   -2           Requested number of bytes could not be read
+ *
+ */
+mp4_i32 readTmpFile(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestoread)
+{
+  if (!handle->tmpfile)
+    return -1;
+
+  TInt err;
+  TPtr8 ptrBuffer(buffer, bytestoread);
+  err = ((RFile64*)handle->tmpfile)->Read(ptrBuffer, bytestoread);
+  if (err != KErrNone)
+	return -2;
+
+  if (ptrBuffer.Length() != bytestoread)
+	return -2;
+
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 peekFile(MP4HandleImp handle,
+ *                    mp4_u8 *buffer,
+ *                    mp4_u32 bytestoread)
+ *
+ * Description:
+ *
+ *   Read data from a file but don't move the current position in the file
+ *   forward.
+ *
+ * Parameters:
+ *
+ *   handle       MP4 library handle
+ *   buffer       Buffer to read data into
+ *   bytestoread  Number of bytes to read from file
+ *
+ * Return value:
+ *
+ *   0            Success
+ *   -1           File has not been opened
+ *   -2           Requested number of bytes could not be read
+ *   -3           Current position in the file could not be set to original
+ *                value
+ *
+ */
+mp4_i32 peekFile(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestoread)
+{
+  mp4_i32 ret;
+  mp4_i32 amount;
+
+
+  ret = bufferedRead(handle, buffer, bytestoread);
+  if (ret != 0)
+    return ret;
+
+  amount = -(mp4_i32)bytestoread;
+
+  ret = bufferedSeek(handle, amount);
+  if (ret != 0)
+    return ret;
+
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 seekFile(MP4HandleImp handle,
+ *                    mp4_i32 amount)
+ *
+ * Description:
+ *
+ *   Seek in a file.
+ *
+ * Parameters:
+ *
+ *   handle   MP4 library handle
+ *   amount   Amount to seek from current position
+ *
+ * Return value:
+ *
+ *   0        Success
+ *   -1       File has not been opened
+ *   -3       Current position in the file could not be set
+ *
+ */
+mp4_i32 seekFile(MP4HandleImp handle, mp4_i64 amount)
+{
+  return bufferedSeek(handle, amount);
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 seekFileAbs(MP4HandleImp handle,
+ *                       mp4_i32 amount)
+ *
+ * Description:
+ *
+ *   Seek from the beginning of a file.
+ *
+ * Parameters:
+ *
+ *   handle   MP4 library handle
+ *   amount   Amount to seek from the beginning of the file
+ *
+ * Return value:
+ *
+ *   0        Success
+ *   -1       File has not been opened
+ *   -3       Current position in the file could not be set
+ *
+ */
+mp4_i32 seekFileAbs(MP4HandleImp handle, mp4_i64 amount)
+{
+  return bufferedSeekAbs(handle, amount);
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 seekFileWrite(MP4HandleImp handle,
+ *                         mp4_i64 amount)
+ *
+ * Description:
+ *
+ *   Seek in a file that has been opened for writing.
+ *
+ * Parameters:
+ *
+ *   handle   MP4 library handle
+ *   amount   Amount to seek from current position
+ *
+ * Return value:
+ *
+ *   0        Success
+ *   -1       File has not been opened
+ *   -2       Can't write buffers to file
+ *   -3       Current position in the file could not be set
+ *
+ */
+mp4_i32 seekFileWrite(MP4HandleImp handle, mp4_i64 amount)
+{
+
+  if (!handle->rfile)
+    return -1;
+
+  if ( handle->filewriter )
+  {
+    PRINT((_L("e_seekfilewrite_flush_filewriter 1")));        
+    if ( (handle->filewriter)->Flush(KNullDesC8) != KErrNone )
+    {
+      PRINT((_L("e_seekfilewrite_flush_filewriter 0")));        
+      return -2;
+    }
+    PRINT((_L("e_seekfilewrite_flush_filewriter 0")));        
+  }
+  else
+  {
+    return -1;
+  }
+
+  PRINT((_L("e_seekfilewrite_seek_rfile 1")));        
+  if (((RFile64 *)(handle->rfile))->Seek(ESeekCurrent,amount) != KErrNone)
+  {
+    return -3;
+  }
+  
+  PRINT((_L("e_seekfilewrite_seek_rfile 0")));        
+
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 seekFileAbsWrite(MP4HandleImp handle,
+ *                            mp4_i32 amount)
+ *
+ * Description:
+ *
+ *   Seek from the beginning of a file that has been opened for writing.
+ *
+ * Parameters:
+ *
+ *   handle   MP4 library handle
+ *   amount   Amount to seek from the beginning of the file
+ *
+ * Return value:
+ *
+ *   0        Success
+ *   -1       File has not been opened
+ *   -2       Can't write buffers to file
+ *   -3       Current position in the file could not be set
+ *
+ */
+mp4_i32 seekFileAbsWrite(MP4HandleImp handle, mp4_i64 amount)
+{
+  if (!handle->rfile)
+    return -1;
+
+  if ( handle->filewriter )
+  {
+    PRINT((_L("e_seekfileabswrite_flush 1")));        
+    if ( (handle->filewriter)->Flush(KNullDesC8) != KErrNone )
+    {
+      PRINT((_L("e_seekfileabswrite_flush 0")));        
+      return -2;
+    }
+    PRINT((_L("e_seekfileabswrite_flush 0")));        
+  }
+  else
+  {
+    return -1;
+  }
+
+  PRINT((_L("e_seekfileabswrite_seek 1")));  
+  if (((RFile64 *)(handle->rfile))->Seek(ESeekStart, amount) != KErrNone)
+  {
+    return -3;
+  }
+  PRINT((_L("e_seekfileabswrite_seek 0")));        
+
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 seekTmpFileAbs(MP4HandleImp handle,
+ *                          mp4_i32 amount)
+ *
+ * Description:
+ *
+ *   Seek from the beginning of a temporary file.
+ *
+ * Parameters:
+ *
+ *   handle   MP4 library handle
+ *   amount   Amount to seek from the beginning of the file
+ *
+ * Return value:
+ *
+ *   0        Success
+ *   -1       File has not been opened
+ *   -3       Current position in the file could not be set
+ *
+ */
+mp4_i32 seekTmpFileAbs(MP4HandleImp handle, mp4_i64 amount)
+{
+  if (!handle->tmpfile)
+    return -1;
+
+  TInt err;
+  TInt64 amount64 = amount;
+  err = ((RFile64*)handle->tmpfile)->Seek(ESeekStart, amount64);
+  if (err != KErrNone)
+	return -3;
+
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 writeFile(MP4HandleImp handle,
+ *                     mp4_u8 *buffer,
+ *                     mp4_u32 bytestowrite)
+ *
+ * Description:
+ *
+ *   Write data into a file.
+ *
+ * Parameters:
+ *
+ *   handle        MP4 library handle
+ *   buffer        Buffer containing the data
+ *   bytestowrite  Number of bytes to write
+ *
+ * Return value:
+ *
+ *   0             Success
+ *   -1            File has not been opened
+ *   -2            Number of bytes written is not equal to bytestowrite
+ *
+ */
+mp4_i32 writeFile(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestowrite)
+{
+  return bufferedWrite(handle, buffer, bytestowrite);
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 writeFileUnbuffered(MP4HandleImp handle,
+ *                               mp4_u8 *buffer,
+ *                               mp4_u32 bytestowrite)
+ *
+ * Description:
+ *
+ *   Write data into a file without buffering.
+ *
+ * Parameters:
+ *
+ *   handle        MP4 library handle
+ *   buffer        Buffer containing the data
+ *   bytestowrite  Number of bytes to write
+ *
+ * Return value:
+ *
+ *   0             Success
+ *   -1            File has not been opened
+ *   -2            Number of bytes written is not equal to bytestowrite
+ *
+ */
+mp4_i32 writeFileUnbuffered(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestowrite)
+{
+  if(handle->bufferWrite)
+  {
+	mp4memcpy(handle->composeBuffer+FTYP_SIZE + handle->ftypdelta,buffer,bytestowrite);
+	return 0;
+  }
+  if (!handle->rfile)
+    return -1;
+
+  if ( handle->filewriter )
+  {
+    TPtrC8 buf = TPtrC8((TUint8 *)(buffer), bytestowrite);
+    PRINT((_L("e_writefileunbuffered_flush 1")));        
+    if ( (handle->filewriter)->Flush( buf ) != KErrNone )
+    {
+      PRINT((_L("e_writefileunbuffered_flush 0")));        
+      return -2;
+    }
+    PRINT((_L("e_writefileunbuffered_flush 0")));        
+  }
+  else
+  {
+    return -1;
+  }
+
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 writeTmpFile(MP4HandleImp handle,
+ *                        mp4_u8 *buffer,
+ *                        mp4_u32 bytestowrite)
+ *
+ * Description:
+ *
+ *   Write data into a temporary file.
+ *
+ * Parameters:
+ *
+ *   handle        MP4 library handle
+ *   buffer        Buffer containing the data
+ *   bytestowrite  Number of bytes to write
+ *
+ * Return value:
+ *
+ *   0             Success
+ *   -1            File has not been opened
+ *   -2            Number of bytes written is not equal to bytestowrite
+ *
+ */
+mp4_i32 writeTmpFile(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestowrite)
+{
+  if (!handle->tmpfile)
+    return -1;
+
+  TInt err;
+  TPtrC8 ptrBuffer(buffer, bytestowrite);
+  err = ((RFile64*)handle->tmpfile)->Write(ptrBuffer, bytestowrite);
+  if (err != KErrNone)
+	return -2;
+
+  if (ptrBuffer.Length() != bytestowrite)
+	return -2;
+
+  handle->bytesInTmpFile += bytestowrite;
+
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 createTmpFileName(MP4FileName filename,
+ *                             MP4FileName *tmpfilename)
+ *
+ * Description:
+ *
+ *   Create a temporary file name by adding .tmp to the end of a file name.
+ *
+ * Parameters:
+ *
+ *   filename     Original file name
+ *   tmpfilename  Temporary file name is returned here
+ *
+ * Return value:
+ *
+ *   0            Success
+ *   -1           Memory could not be allocated for the new name
+ *
+ */
+mp4_i32 createTmpFileName(MP4FileName filename, MP4FileName *tmpfilename)
+{
+  *tmpfilename = (MP4FileName)mp4malloc(2 * wcslen(filename) + 10);
+  if (*tmpfilename == NULL)
+    return -1;
+
+  wcscat(*tmpfilename, filename);
+  wcscat(*tmpfilename, L".tmp");
+
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 freeTmpFileName(MP4FileName filename)
+ *
+ * Description:
+ *
+ *   Free memory allocated for the temporary file name.
+ *
+ * Parameters:
+ *
+ *   filename   Buffer containing file name
+ *
+ * Return value:
+ *
+ *   0          Success
+ *
+ */
+mp4_i32 freeTmpFileName(MP4FileName filename)
+{
+  if (filename)
+    mp4free(filename);
+
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   void closeStdlib()
+ *
+ * Description:
+ *
+ *   Free memory allocated by stdlib wrapper functions (Symbian OS only).
+ *
+ * Parameters:
+ *
+ *   None
+ *
+ * Return value:
+ *
+ *   None
+ *
+ */
+void closeStdlib()
+	{
+	// retrieves the TLS which stores the number of currently active instances of 
+	// composer/parser
+	TInt p = (TInt) Dll::Tls();
+	
+	// decrement the counter as one instance is being closed at this point
+	p--;
+	Dll::SetTls((TAny*) p);		
+
+	if (p == 0)
+		{
+		// Since memory allocated for stdlib is shared amongst all composers and/or parsers  
+		// within a thread, stdlib close should ONLY be called for the last instance of   
+		// composer / parser.
+		//
+		// If there are no other active instances other than this,
+		// the memory allocated for stdlib for this thread can now be released.
+		Dll::FreeTls();
+		CloseSTDLIB();
+		}
+	}
+
+/*
+ * Function:
+ *
+ *   void openStdlib()
+ *
+ * Description:
+ *
+ *   Register the use of stdlib.  
+ *
+ * Parameters:
+ *
+ *   None
+ *
+ * Return value:
+ *
+ *   0 			Success
+ *
+ */
+mp4_i32 openStdlib()
+	{
+	// retrieve the the value stored in TLS for this DLL 
+	TInt p = (TInt) Dll::Tls();
+	
+	// increment it.  This becomes a reference counter of 
+	// how many instances of the composer/parser is currently active 
+	p++;
+	return (Dll::SetTls((TAny*) p));		
+	}
+
+/*
+ * Function:
+ *
+ *   mp4_i32 bufferedRead(MP4HandleImp handle,
+ *                        mp4_u8 *buffer,
+ *                        mp4_u32 bytestoread)
+ *
+ * Description:
+ *
+ *   Read data from a file in a buffered manner.
+ *
+ * Parameters:
+ *
+ *   handle       MP4 library handle
+ *   buffer       Buffer to read data into
+ *   bytestoread  Number of bytes to read from file
+ *
+ * Return value:
+ *
+ *   0            Success
+ *   -1           File has not been opened
+ *   -2           Requested number of bytes could not be read
+ *
+ */
+mp4_i32 bufferedRead(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestoread)
+{
+  mp4_u32 bytesread = 0;
+
+  if (!handle->file)
+    return -1;
+
+  while (bytesread < bytestoread)
+  {
+    mp4_u32 available;
+
+
+    available = handle->diskReadSize - handle->diskReadBufPos;
+    if (available > bytestoread - bytesread)
+      available = bytestoread - bytesread;
+
+    if (available > 0) /* Copy data from memory buffer */
+    {
+      mp4memcpy(buffer + bytesread, handle->diskReadBuf + handle->diskReadBufPos, available);
+      handle->diskReadBufPos += available;
+      bytesread += available;
+    }
+    else /* Read more data from file into memory buffer */
+    {
+      TInt readBufferSize = 0;
+      if ( handle->readBufferSize == 0)
+        {
+        readBufferSize = READBUFSIZE;
+        }
+      else
+        {
+        readBufferSize = handle->readBufferSize;
+        }
+
+      TPtr8 buf = TPtr8((TUint8 *)(handle->diskReadBuf), readBufferSize);
+
+      switch (handle->sourceType)
+      {
+        case MP4_SOURCE_RFILE:
+          if (((RFile64 *)(handle->rfile))->Read(buf, readBufferSize) != KErrNone)
+            return -2;
+          break;
+        case MP4_SOURCE_CAF:
+          handle->cafError = handle->cfile->Read(buf, readBufferSize);
+          if ( handle->cafError != KErrNone)
+            return -2;
+          break;
+        default:
+          return -1;
+      }
+
+      if ((mp4_u32)buf.Length() == 0) /* EOF or error */
+        return -2;
+
+      handle->diskReadBufPos = 0;
+      handle->diskReadSize = (mp4_u32)buf.Length();
+      handle->diskReadBufStart = handle->diskReadPos;
+      handle->diskReadPos += handle->diskReadSize;
+    }
+  }
+
+  return 0;
+}
+
+/*
+ * Function:
+ *
+ *   mp4_i32 bufferedSeek(MP4HandleImp handle,
+ *                        mp4_i32 amount)
+ *
+ * Description:
+ *
+ *   Seek in a buffered file.
+ *
+ * Parameters:
+ *
+ *   handle   MP4 library handle
+ *   amount   Amount to seek from current position
+ *
+ * Return value:
+ *
+ *   0        Success
+ *   -1       File has not been opened
+ *   -3       Current position in the file could not be set
+ *
+ */
+mp4_i32 bufferedSeek(MP4HandleImp handle, mp4_i64 amount)
+{
+  if (!handle->file)
+    return -1;
+
+  /* Is the new seek point inside the current memory buffer? */
+  if ((mp4_i32)handle->diskReadBufPos + amount >= 0 &&
+      handle->diskReadBufPos + amount < handle->diskReadSize)
+  {
+    /* Yes */
+
+    handle->diskReadBufPos += amount;
+  }
+  else
+  {
+    /* No */
+
+    TInt64 am;
+
+
+    am = amount - ((mp4_i32)handle->diskReadSize - (mp4_i32)handle->diskReadBufPos);
+
+    if ( handle->rfile )
+        {
+        mp4_i64 maxsize = 0;
+        ((RFile64 *)(handle->rfile))->Size(maxsize);
+        maxsize -= (mp4_i64)handle->diskReadPos;
+        
+        if (am > maxsize)
+            {
+            return -3;
+            }
+        }
+	// 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
+	//coverity[var_compare_op]
+    else if ( handle->cfile )
+        {
+        mp4_i64 maxsize = 0;
+        TRAPD(caferr, handle->cfile->DataSize64L(maxsize));
+        maxsize -= (mp4_i64)handle->diskReadPos;
+        
+        if (!caferr && am > maxsize)
+            {
+            return -3;
+            }
+        }
+
+    switch (handle->sourceType)
+    {
+      case MP4_SOURCE_RFILE:
+		{
+        PRINT((_L("e_bufferedseek_seek_rfile 1")));        
+        if (((RFile64 *)(handle->rfile))->Seek(ESeekCurrent, am) != KErrNone)
+		  {
+		    return -3;
+		  }
+        PRINT((_L("e_bufferedseek_seek_rfile 0")));        
+        break;
+		}
+      case MP4_SOURCE_CAF:
+        PRINT((_L("e_bufferedseek_seek_cfile 1")));        
+		// See comment on handle->cfile dereference above on why the coverity[] comment below is needed
+		//coverity[var_deref_model]
+      	handle->cafError = handle->cfile->Seek64(ESeekCurrent, am);
+        if ( handle->cafError != KErrNone)
+          return -3;
+        PRINT((_L("e_bufferedseek_seek_cfile 0")));        
+        break;
+      default:
+        return -1;
+    }
+
+    handle->diskReadPos = handle->diskReadBufStart + handle->diskReadBufPos + amount;
+    handle->diskReadBufPos = 0;
+    handle->diskReadBufStart = 0;
+    handle->diskReadSize = 0;
+  }
+
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 bufferedSeekAbs(MP4HandleImp handle,
+ *                           mp4_i32 amount)
+ *
+ * Description:
+ *
+ *   Seek in a buffered file from the start of the file.
+ *
+ * Parameters:
+ *
+ *   handle   MP4 library handle
+ *   amount   Amount to seek from start of the file
+ *
+ * Return value:
+ *
+ *   0        Success
+ *   -1       File has not been opened
+ *   -3       Current position in the file could not be set
+ *
+ */
+mp4_i32 bufferedSeekAbs(MP4HandleImp handle, mp4_i64 amount)
+{
+  if (!handle->file)
+    return -1;
+
+  /* Is the new seek point inside the current memory buffer? */
+  if (handle->diskReadBufStart <= (mp4_u64)amount &&
+      handle->diskReadBufStart + handle->diskReadSize > (mp4_u64)amount)
+  {
+    /* Yes */
+
+    handle->diskReadBufPos = amount - handle->diskReadBufStart;
+  }
+  else
+  {
+    /* No */
+
+    mp4_i64 am = amount;
+
+    switch (handle->sourceType)
+    {
+      case MP4_SOURCE_RFILE:
+		{
+        PRINT((_L("e_bufferedseekabs_seek_rfile 1")));
+        if (((RFile64 *)(handle->rfile))->Seek(ESeekStart, am) != KErrNone)
+		  {
+		    return -3;
+		  }
+        PRINT((_L("e_bufferedseekabs_seek_rfile 0")));        
+        break;
+		}
+      case MP4_SOURCE_CAF:
+        PRINT((_L("e_bufferedseekabs_seek_cfile 1")));
+      	handle->cafError = handle->cfile->Seek64(ESeekStart, am);
+        PRINT((_L("e_bufferedseekabs_seek_cfile 0")));
+        if ( handle->cafError != KErrNone)
+          return -3;
+        break;
+      default:
+        return -1;
+    }
+
+    handle->diskReadPos = (mp4_u64)amount;
+    handle->diskReadBufPos = 0;
+    handle->diskReadBufStart = 0;
+    handle->diskReadSize = 0;
+  }
+
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 bufferedWrite(MP4HandleImp handle,
+ *                         mp4_u8 *buffer,
+ *                         mp4_u32 bytestowrite)
+ *
+ * Description:
+ *
+ *   Write data into a file in a buffered manner.
+ *
+ * Parameters:
+ *
+ *   handle        MP4 library handle
+ *   buffer        Buffer containing the data
+ *   bytestowrite  Number of bytes to write
+ *
+ * Return value:
+ *
+ *   0             Success
+ *   -1            File has not been opened
+ *   -2            Number of bytes written is not equal to bytestowrite
+ *
+ */
+mp4_i32 bufferedWrite(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestowrite)
+{
+	if(handle->bufferWrite)
+	{
+		if(handle->bytesProgressed+bytestowrite > *(handle->composedSize))
+		{
+			return MP4_OUTPUT_BUFFER_TOO_SMALL; //-1;
+		}
+		else
+		{
+			mp4memcpy(handle->composeBuffer+handle->bytesProgressed,buffer,bytestowrite);
+			handle->bytesProgressed+=bytestowrite;
+			return 0;
+		}
+	}
+
+  if (!handle->rfile)
+    return -1;
+
+  if ( handle->filewriter )
+  {
+    TPtrC8 buf = TPtrC8((TUint8 *)(buffer), bytestowrite);
+    PRINT((_L("e_file_bufferedwrite_write 1")));
+    if ( (handle->filewriter)->Write( buf ) != KErrNone )
+    {
+      return -2;
+    }
+    PRINT((_L("e_file_bufferedwrite_write 0")));
+  }
+  else
+  {
+    return -1;    
+  }
+
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 initMetaDataFiles(MP4HandleImp handle)
+ *
+ * Description:
+ *
+ *   Open temporary files for writing.
+ *
+ * Parameters:
+ *
+ *   handle     MP4 library handle
+ *
+ * Return value:
+ *
+ *   0          		Success
+ *   -1         		General Error
+ *	 MP4_OUT_OF_MEMORY	Out of memory
+ *
+ */
+mp4_i32 initMetaDataFiles(MP4HandleImp handle)
+{
+  PRINT(_L("3GPLib::initMetaDataFiles() in"));
+  TFileName filename;
+  TFileName path;
+  TInt error;
+
+  // Create a directory for the files
+  if ( handle->fileName )
+    {
+    filename = (TText *)handle->fileName;
+    
+    TParse fp;
+    path = KTmpDirectoryName;
+    if (((RFs *)(handle->fs))->Parse(filename, fp) != KErrNone)
+        return -1;
+    path.Insert(0, fp.Drive());
+    }
+  else
+    {
+    TChar drive;
+    if (((RFs *)(handle->fs))->DriveToChar(handle->fileHandleDrive, drive ) != KErrNone )
+        return -1;
+    path.Append( drive );
+    path.Append( _L(":") );
+    path.Append( KTmpDirectoryName );
+    }
+    
+  // Try to delete the temp folder from leftovers
+  // If other instance is using it then delete will just fail
+  PRINT((_L("e_initmetadatafiles_newl_fileman 1")));
+  CFileMan* fileMan = 0;
+  TRAP( error, fileMan = CFileMan::NewL(*(RFs *)(handle->fs)));
+  if ( error )
+    {
+        return -1;
+    }
+  PRINT((_L("e_initmetadatafiles_newl_fileman 0")));
+
+  PRINT((_L("e_initmetadatafiles_deletedirectory 1")));  
+  error = fileMan->RmDir( path ); // Delete directory + all files
+  delete( fileMan );
+  PRINT((_L("e_initmetadatafiles_deletedirectory 0")));  
+
+  error = ((RFs *)(handle->fs))->MkDirAll(path);
+  if (error != KErrNone && error != KErrAlreadyExists)
+    return -1;
+
+  ((RFs *)(handle->fs))->SetEntry(path, TTime(0), KEntryAttHidden, NULL);
+
+  // Create files
+  TFileName metadatafilename;
+
+  for (TUint i = 0; i < NUM_MDF; i++)
+  {
+    handle->metaDataFile[i] = (void *)new(RFile64);
+    if (handle->metaDataFile[i] == NULL)
+      return MP4_OUT_OF_MEMORY;
+
+    if (((RFile64 *)(handle->metaDataFile[i]))->Temp(*((RFs *)(handle->fs)), path, metadatafilename, EFileWrite | EFileShareExclusive) != KErrNone)
+      return -1;
+
+    handle->metaDataFileEmpty[i] = EFalse;
+    
+    // save file name, used later for deleting
+    handle->metaDataFileName[i] = (MP4FileName)mp4malloc(2 * wcslen((MP4FileName)metadatafilename.Ptr()) + 2);
+    if (handle->metaDataFileName[i] == NULL)
+      return -1;
+    
+    wcscat(handle->metaDataFileName[i], (MP4FileName)metadatafilename.Ptr());
+    handle->metaDataFileName[i][metadatafilename.Length()] = 0;
+    PRINT((_L("3GPLib::initMetaDataFiles() handle->metaDataFileName[%d]=%s, length=%d "),i,  handle->metaDataFileName[i], metadatafilename.Length()));
+    
+  }
+
+  PRINT(_L("3GPLib::initMetaDataFiles() creating MetaDataWriter"));
+  TRAPD(err,   handle->metadatafilewriter = CMetaDataFileWriter::NewL());
+  if ( err != KErrNone )
+  	{
+    PRINT((_L("3GPLib::initMetaDataFiles() MetaDataWriter creation error: %d"), err));
+    if ( err == KErrNoMemory )
+    	{
+    	return MP4_OUT_OF_MEMORY;    
+    	}
+    else
+    	{
+    	return -1;    
+	    }
+  	}
+
+  PRINT(_L("3GPLib::initMetaDataFiles() MetaDataWriter created"));
+  PRINT(_L("3GPLib::initMetaDataFiles() out"));
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 writeMetaDataFileNum(MP4HandleImp handle,
+ *                                mp4_u8 *buffer,
+ *                                mp4_u32 bytestowrite,
+ *                                mp4_u32 filenumber)
+ *
+ * Description:
+ *
+ *   Write data into a numbered file.
+ *
+ * Parameters:
+ *
+ *   handle        MP4 library handle
+ *   buffer        Buffer containing the data
+ *   bytestowrite  Number of bytes to write
+ *   filenumber    Index of temporary file
+ *
+ * Return value:
+ *
+ *   0             Success
+ *   -1            File has not been opened
+ *   -2            Number of bytes written is not equal to bytestowrite
+ *
+ */
+mp4_i32 writeMetaDataFileNum(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestowrite, mp4_u32 filenumber)
+{
+  PRINT(_L("3GPLib::writeMetaDataFileNum() in"));
+
+  if (!handle->metaDataFile[filenumber])
+    return -1;
+
+  if ( handle->metadatafilewriter )
+  {
+    TPtrC8 buf = TPtrC8((TUint8 *)(buffer), bytestowrite);
+    PRINT((_L("e_file_writeMetaDataFileNum_write 1")));
+    if ( (handle->metadatafilewriter)->Write( *((RFile64 *)(handle->metaDataFile[filenumber])),
+                                              filenumber,
+                                              buf ) != KErrNone )
+    {
+      return -2;
+    }
+    PRINT((_L("e_file_writeMetaDataFileNum_write 0")));
+  }
+  else
+  {
+    return -1;
+  } 
+
+  PRINT(_L("3GPLib::writeMetaDataFileNum() out"));
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 seekMetaDataFileNumAbs(MP4HandleImp handle,
+ *                                  mp4_i32 amount,
+ *                                  mp4_u32 filenumber)
+ *
+ * Description:
+ *
+ *   Seek from the beginning of a numbered file.
+ *
+ * Parameters:
+ *
+ *   handle        MP4 library handle
+ *   amount        Amount to seek from the beginning of the file
+ *   filenumber    Index of temporary file
+ *
+ * Return value:
+ *
+ *   0        Success
+ *   -1       File has not been opened
+ *   -3       Current position in the file could not be set
+ *
+ */
+mp4_i32 seekMetaDataFileNumAbs(MP4HandleImp handle, mp4_i64 amount, mp4_u32 filenumber)
+{
+  PRINT(_L("3GPLib::seekMetaDataFileNumAbs() in"));
+
+  if (!handle->metaDataFile[filenumber])
+    return -1;
+
+
+  if ( handle->metadatafilewriter )
+  {
+    PRINT((_L("e_seekmetadatafilenumabs_flush 1")));        
+    if ( (handle->metadatafilewriter)->Flush() != KErrNone )
+    {
+      PRINT((_L("e_seekmetadatafilenumabs_flush 0")));        
+      return -2;
+    }
+    PRINT((_L("e_seekmetadatafilenumabs_flush 0")));        
+  }
+
+  PRINT((_L("e_seekmetadatafilenumabs_seek 1")));
+  if (((RFile64 *)(handle->metaDataFile[filenumber]))->Seek(ESeekStart, amount) != KErrNone)
+  {
+    return -3;
+  }
+  PRINT((_L("e_seekmetadatafilenumabs_seek 0")));        
+
+  PRINT(_L("3GPLib::seekMetaDataFileNumAbs() out"));
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 readMetaDataFileNum(MP4HandleImp handle,
+ *                               mp4_u8 *buffer,
+ *                               mp4_u32 bytestoread,
+ *                               mp4_u32 filenumber)
+ *
+ * Description:
+ *
+ *   Read data from a numbered file.
+ *
+ * Parameters:
+ *
+ *   handle       MP4 library handle
+ *   buffer       Buffer to read data into
+ *   bytestoread  Number of bytes to read from file
+ *   filenumber   Index of temporary file
+ *
+ * Return value:
+ *
+ *   0            Success
+ *   -1           File has not been opened
+ *   -2           Requested number of bytes could not be read
+ *
+ */
+mp4_i32 readMetaDataFileNum(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestoread, mp4_u32 filenumber)
+{
+  PRINT(_L("3GPLib::readMetaDataFileNum() in"));
+  PRINT((_L("e_readmetadatafiles 1")));
+
+  mp4_u32 bytesread = 0;
+  TPtr8 buf = TPtr8((TUint8 *)buffer, bytestoread);
+
+  if (!handle->metaDataFile[filenumber])
+    return -1;
+
+  if ( handle->metadatafilewriter )
+  {
+    PRINT((_L("e_readmetadatafiles_flush 1")));
+    if ( (handle->metadatafilewriter)->Flush() != KErrNone )
+    {
+      return -2;
+    }
+    PRINT((_L("e_readmetadatafiles_flush 0")));
+  }
+
+  PRINT((_L("e_readmetadatafiles_read 1")));
+  
+  if (handle->metaDataFileEmpty[filenumber])
+    {
+    if (handle->metadatafilewriter)
+    	{	
+    	// if the file is empty, then read the data from temp buffer
+    	bytesread = (handle->metadatafilewriter)->ReadBuffer( filenumber, buf, bytestoread);    	
+    	}
+    if ( bytesread != bytestoread )
+        return -2;
+    }
+  else if (((RFile64 *)(handle->metaDataFile[filenumber]))->Read(buf, bytestoread) != KErrNone)
+    {
+    handle->metaDataFileEmpty[filenumber] = ETrue;
+    // if the file is empty, then read the data from temp buffer
+    if (handle->metadatafilewriter)
+    	{	
+    	bytesread = (handle->metadatafilewriter)->ReadBuffer( filenumber, buf, bytestoread);    	
+    	}
+    if ( bytesread != bytestoread )
+        return -2;
+    }
+  else if ( buf.Length() < bytestoread ) // Got only part of data from file, rest is in buffer
+    {
+    handle->metaDataFileEmpty[filenumber] = ETrue;
+    // if the file is empty, then read the data from temp buffer
+    if (handle->metadatafilewriter)
+    	{
+    	bytesread = (handle->metadatafilewriter)->ReadBuffer( filenumber, buf, bytestoread - buf.Length());    	
+    	}
+    if ( buf.Length() != bytestoread )
+        return -2;
+    }
+    
+  PRINT((_L("e_readmetadatafiles_read 0")));
+
+  if ((mp4_u32)buf.Length() == 0) /* EOF or error */
+    return -2;
+
+  PRINT(_L("3GPLib::readMetaDataFileNum() out"));
+  PRINT((_L("e_readmetadatafiles 0")));
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 deleteMetaDataFiles(MP4HandleImp handle)
+ *
+ * Description:
+ *
+ *   Remove a numbered temporary file.
+ *
+ * Parameters:
+ *
+ *   handle   MP4 library handle
+ *
+ * Return value:
+ *
+ *   0        Success
+ *   -1       Error
+ *
+ */
+mp4_i32 deleteMetaDataFiles(MP4HandleImp handle)
+{
+  PRINT(_L("3GPLib::deleteMetaDataFiles() in"));
+  PRINT((_L("e_deletemetadatafiles 1")));
+
+  TFileName filename;
+  TFileName path;
+  TInt err;
+
+  if ( handle->metadatafilewriter )
+  {
+    PRINT((_L("e_deletemetadatafiles_flush 1")));
+    if ( (handle->metadatafilewriter)->Flush() != KErrNone )
+    {
+      PRINT((_L("e_deletemetadatafiles_flush 0")));
+      return -2;
+    }
+    PRINT((_L("e_deletemetadatafiles_flush 0")));
+    delete handle->metadatafilewriter;
+    handle->metadatafilewriter = NULL;
+  }
+    
+  /* Determine file names */
+  PRINT((_L("e_deletemetadatafiles_determinenames 1")));
+  if ( handle->fileName )
+    {  
+     filename = (TText *)handle->fileName;
+     path = KTmpDirectoryName;
+
+    TParse fp;
+    if (((RFs *)(handle->fs))->Parse(filename, fp) != KErrNone)
+        return -1;
+    path.Insert(0, fp.Drive());
+    }
+  else
+    {
+    TChar drive;
+    if (((RFs *)(handle->fs))->DriveToChar(handle->fileHandleDrive, drive ) != KErrNone )
+        return -1;
+    path.Append( drive );
+    path.Append( _L(":") );
+    path.Append( KTmpDirectoryName );    
+    }
+  PRINT((_L("e_deletemetadatafiles_determinenames 0")));    
+    
+  PRINT((_L("e_deletemetadatafiles_deletemetadatafilenames 1")));    
+  for (TUint i = 0; i < NUM_MDF; i++)
+  {
+    if (handle->metaDataFileName[i])
+      {
+      // check if client has defined async delete observer
+      if ( handle->tempFileRemoverObserver )
+        {
+        PRINT((_L("3GPLib::deleteMetaDataFiles() nro=%d sending %x to observer: %s"), i,handle->metaDataFileName[i], handle->metaDataFileName[i]));
+        handle->tempFileRemoverObserver->M3GPMP4LibDeleteTempFileName( handle->metaDataFileName[i] );
+        }
+      else // no observer, delete right here, ignore errors
+        {
+        PRINT((_L("3GPLib::deleteMetaDataFiles() nro=%d wremove: %s"), i, handle->metaDataFileName[i]));
+        err = wremove(handle->metaDataFileName[i]);
+        PRINT((_L("3GPLib::deleteMetaDataFiles() wremove err=%d"), err));
+        err++; // to remove compile warnings
+        mp4free(handle->metaDataFileName[i]);
+        }
+      handle->metaDataFileName[i] = 0;
+      }
+  PRINT((_L("e_deletemetadatafiles_deletemetadatafilenames 0")));    
+
+  }
+
+  PRINT(_L("3GPLib::deleteMetaDataFiles() out"));
+  PRINT((_L("e_deletemetadatafiles 0")));
+  return 0;
+}
+
+
+/*
+ * Function:
+ *
+ *   mp4_i32 closeMetaDataFiles(MP4HandleImp handle)
+ *
+ * Description:
+ *
+ *   Close numbered tmp files.
+ *
+ * Parameters:
+ *
+ *   handle   MP4 library handle
+ *
+ * Return value:
+ *
+ *   0        Success
+ *
+ */
+mp4_i32 closeMetaDataFiles(MP4HandleImp handle)
+{
+  PRINT(_L("3GPLib::closeMetaDataFiles() in"));
+  PRINT((_L("e_close_metadatafiles 1")));
+
+  if ( handle->metadatafilewriter )
+  {
+    PRINT((_L("e_close_metadatafiles_flush 1")));
+    if ( (handle->metadatafilewriter)->Flush() != KErrNone )
+    {
+      PRINT((_L("e_close_metadatafiles_flush 0")));
+      return -2;
+    }
+    PRINT((_L("e_close_metadatafiles_flush 0")));
+  }
+
+  for (TUint i = 0; i < NUM_MDF; i++)
+  {
+    if (handle->metaDataFile[i])
+    {
+	  PRINT((_L("e_close_metadatafiles_closefile 1")));    
+      ((RFile64 *)(handle->metaDataFile[i]))->Close();
+      PRINT((_L("e_close_metadatafiles_closefile 0")));
+
+      PRINT((_L("e_close_metadatafiles_delfile 1")));
+      delete((RFile64 *)(handle->metaDataFile[i]));
+      PRINT((_L("e_close_metadatafiles_delfile 0")));
+      handle->metaDataFile[i] = NULL;
+    }
+  }
+
+  PRINT(_L("3GPLib::closeMetaDataFiles() out"));
+  PRINT((_L("e_close_metadatafiles 0")));
+  return 0;
+}
+
+
+// End of File