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