Update contrib.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
17 #include "mp4memwrap.h"
21 #include <sys/unistd.h>
22 #include <sys/reent.h>
24 #include <f32file64.h>
28 using namespace ContentAccess;
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
39 _LIT(KTmpDirectoryName, "\\System\\Temp\\3GPLibTmpDir\\"); // Temporary output directory name
45 * mp4_i32 saveFileName(MP4FileName filename,
46 * MP4HandleImp handle)
50 * Save file name for later use.
55 * handle MP4 library handle
63 mp4_i32 saveFileName(MP4FileName filename, MP4HandleImp handle)
65 handle->fileName = (MP4FileName)mp4malloc(2 * wcslen(filename) + 2);
66 if (handle->fileName == NULL)
69 wcscat(handle->fileName, filename);
78 * mp4_i32 initFileRead(MP4FileName filename,
79 * MP4HandleImp handle)
83 * Open a file for reading.
85 * Note: filename is a Unicode string in Symbian OS.
90 * handle MP4 library handle
98 mp4_i32 initFileRead(MP4FileName filename, MP4HandleImp handle)
105 handle->fs = (void *)fs;
109 if (fs->Connect() != KErrNone)
113 handle->rfile = (void *)file;
117 if (file->Open(*fs, TPtrC((const TUint16 *)filename), EFileRead | EFileShareAny) != KErrNone)
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)
125 handle->file = handle->rfile;
133 * mp4_i32 initFileWrite(MP4FileName filename,
134 * MP4HandleImp handle)
138 * Open a file for writing.
140 * Note: filename is a Unicode string in Symbian OS.
145 * handle MP4 library handle
153 mp4_i32 initFileWrite(MP4FileName filename, MP4HandleImp handle)
163 handle->fs = (void *)fs;
167 if (fs->Connect() != KErrNone)
171 handle->rfile = (void *)file;
175 if (((RFs *)(handle->fs))->Parse(TPtrC((const TUint16 *)filename), fp) != KErrNone)
178 path.Insert(0, fp.DriveAndPath() );
179 error = ((RFs *)(handle->fs))->MkDirAll(path);
180 if (error != KErrNone && error != KErrAlreadyExists)
183 if (file->Replace(*fs, TPtrC((const TUint16 *)filename), EFileWrite|EFileShareExclusive|EFileWriteDirectIO ) != KErrNone)
189 buf.Copy(fp.Drive());
191 TInt drvNum = (*buf.Ptr()) - 'a';
192 PRINT((_L("drvNum = %d"), drvNum));
195 error = fs->Volume(volInfo, drvNum);
196 if (error != KErrNone)
201 PRINT((_L("volInfo.iFree = %Ld"), volInfo.iFree));
202 PRINT((_L("volInfo.iSize = %Ld"), volInfo.iSize));
204 TVolumeIOParamInfo ioInfo;
205 error = fs->VolumeIOParam(drvNum, ioInfo);
206 if (error != KErrNone)
211 PRINT((_L("ioInfo.iBlockSize = %d"), ioInfo.iBlockSize));
212 PRINT((_L("ioInfo.iClusterSize = %d"), ioInfo.iClusterSize));
214 if (ioInfo.iClusterSize <= 0 || (ioInfo.iClusterSize & 0x1)) // if for some reason we got wrong value for the cluster - ignore it
216 PRINT(_L("Wrong cluster size, set 0x8000"));
217 ioInfo.iClusterSize = 0x8000;
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;
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)
227 writeBufferSizeLarge = KFileWriterBufferSizeLarge/2;
230 if (writeBufferSizeLarge > KFileWriterBufferSizeLarge)
232 writeBufferSizeLarge = (KFileWriterBufferSizeLarge / ioInfo.iClusterSize) * ioInfo.iClusterSize;
235 if (writeBufferSizeLarge < ioInfo.iClusterSize)
237 writeBufferSizeLarge = ioInfo.iClusterSize;
240 PRINT((_L("writeBufferSizeLarge = %d"), writeBufferSizeLarge));
242 TInt incSetSize = writeBufferSizeLarge * (KFileWriterHardBufLimit >> 1); // 2Mb if cluster size if 32767
243 TInt initSetSize = incSetSize * 1; // set initial set size for 2Mb
245 if (initSetSize > volInfo.iFree)
247 initSetSize = (volInfo.iFree / incSetSize) * incSetSize;
250 PRINT((_L("initSetSize = %d"), initSetSize));
252 PRINT((_L("e_SetSize 1")));
253 file->SetSize(initSetSize);
254 PRINT((_L("e_SetSize 0")));
256 handle->file = handle->rfile;
258 TRAP(error, handle->filewriter = CFileWriter::NewL( *file, initSetSize, writeBufferSizeSmall, writeBufferSizeLarge));
259 if ( error != KErrNone )
271 * mp4_i32 initTmpFileWrite(MP4FileName filename,
272 * MP4HandleImp handle)
276 * Open a temporary file for writing.
278 * Note: filename is a Unicode string in Symbian OS.
283 * handle MP4 library handle
291 mp4_i32 initTmpFileWrite(MP4FileName filename, MP4HandleImp handle)
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);
304 handle->tmpfile = (void *)file;
312 * mp4_i32 closeFile(MP4HandleImp handle)
320 * handle MP4 library handle
327 mp4_i32 closeFile(MP4HandleImp handle)
329 PRINT((_L("e_closefile 1")));
332 if (handle->filewriter)
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()));
341 delete handle->filewriter;
342 handle->filewriter = NULL;
346 if (handle->asyncReader)
348 delete handle->asyncReader;
349 handle->asyncReader = NULL;
354 if ( !handle->FileHandleFromOutside )
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")));
363 handle->rfile = NULL;
368 if ( !handle->FileHandleFromOutside )
370 delete(handle->cfile);
372 handle->cfile = NULL;
375 PRINT((_L("e_closefile_close_rfs 1")));
378 ((RFs *)(handle->fs))->Close();
384 PRINT((_L("e_closefile_close_rfs 0")));
387 PRINT((_L("e_closefile 0")));
395 * mp4_i32 closeTmpFile(MP4HandleImp handle)
399 * Close a temporary file.
403 * handle MP4 library handle
410 mp4_i32 closeTmpFile(MP4HandleImp handle)
413 ((RFile64*)handle->tmpfile)->Close();
415 handle->tmpfile = NULL;
424 * mp4_i32 deleteTmpFile(MP4HandleImp handle)
428 * Remove a temporary file.
432 * handle MP4 library handle
440 mp4_i32 deleteTmpFile(MP4HandleImp handle)
442 if (handle->tmpFileName)
445 TBuf<KMaxFileName> name(reinterpret_cast<const TUint16*>(handle->tmpFileName));
446 ASSERT(handle->fs != NULL);
447 err = ((RFs*)handle->fs)->Delete(name);
459 * mp4_i32 readFile(MP4HandleImp handle,
461 * mp4_u32 bytestoread)
465 * Read data from a file.
469 * handle MP4 library handle
470 * buffer Buffer to read data into
471 * bytestoread Number of bytes to read from file
476 * -1 File has not been opened
477 * -2 Requested number of bytes could not be read
480 mp4_i32 readFile(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestoread)
482 return bufferedRead(handle, buffer, bytestoread);
488 * mp4_i32 readTmpFile(MP4HandleImp handle,
490 * mp4_u32 bytestoread)
494 * Read data from a temporary file.
498 * handle MP4 library handle
499 * buffer Buffer to read data into
500 * bytestoread Number of bytes to read from file
505 * -1 File has not been opened
506 * -2 Requested number of bytes could not be read
509 mp4_i32 readTmpFile(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestoread)
511 if (!handle->tmpfile)
515 TPtr8 ptrBuffer(buffer, bytestoread);
516 err = ((RFile64*)handle->tmpfile)->Read(ptrBuffer, bytestoread);
520 if (ptrBuffer.Length() != bytestoread)
530 * mp4_i32 peekFile(MP4HandleImp handle,
532 * mp4_u32 bytestoread)
536 * Read data from a file but don't move the current position in the file
541 * handle MP4 library handle
542 * buffer Buffer to read data into
543 * bytestoread Number of bytes to read from file
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
554 mp4_i32 peekFile(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestoread)
560 ret = bufferedRead(handle, buffer, bytestoread);
564 amount = -(mp4_i32)bytestoread;
566 ret = bufferedSeek(handle, amount);
577 * mp4_i32 seekFile(MP4HandleImp handle,
586 * handle MP4 library handle
587 * amount Amount to seek from current position
592 * -1 File has not been opened
593 * -3 Current position in the file could not be set
596 mp4_i32 seekFile(MP4HandleImp handle, mp4_i64 amount)
598 return bufferedSeek(handle, amount);
605 * mp4_i32 seekFileAbs(MP4HandleImp handle,
610 * Seek from the beginning of a file.
614 * handle MP4 library handle
615 * amount Amount to seek from the beginning of the file
620 * -1 File has not been opened
621 * -3 Current position in the file could not be set
624 mp4_i32 seekFileAbs(MP4HandleImp handle, mp4_i64 amount)
626 return bufferedSeekAbs(handle, amount);
633 * mp4_i32 seekFileWrite(MP4HandleImp handle,
638 * Seek in a file that has been opened for writing.
642 * handle MP4 library handle
643 * amount Amount to seek from current position
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
653 mp4_i32 seekFileWrite(MP4HandleImp handle, mp4_i64 amount)
659 if ( handle->filewriter )
661 PRINT((_L("e_seekfilewrite_flush_filewriter 1")));
662 if ( (handle->filewriter)->Flush(KNullDesC8) != KErrNone )
664 PRINT((_L("e_seekfilewrite_flush_filewriter 0")));
667 PRINT((_L("e_seekfilewrite_flush_filewriter 0")));
674 PRINT((_L("e_seekfilewrite_seek_rfile 1")));
675 if (((RFile64 *)(handle->rfile))->Seek(ESeekCurrent,amount) != KErrNone)
680 PRINT((_L("e_seekfilewrite_seek_rfile 0")));
689 * mp4_i32 seekFileAbsWrite(MP4HandleImp handle,
694 * Seek from the beginning of a file that has been opened for writing.
698 * handle MP4 library handle
699 * amount Amount to seek from the beginning of the file
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
709 mp4_i32 seekFileAbsWrite(MP4HandleImp handle, mp4_i64 amount)
714 if ( handle->filewriter )
716 PRINT((_L("e_seekfileabswrite_flush 1")));
717 if ( (handle->filewriter)->Flush(KNullDesC8) != KErrNone )
719 PRINT((_L("e_seekfileabswrite_flush 0")));
722 PRINT((_L("e_seekfileabswrite_flush 0")));
729 PRINT((_L("e_seekfileabswrite_seek 1")));
730 if (((RFile64 *)(handle->rfile))->Seek(ESeekStart, amount) != KErrNone)
734 PRINT((_L("e_seekfileabswrite_seek 0")));
743 * mp4_i32 seekTmpFileAbs(MP4HandleImp handle,
748 * Seek from the beginning of a temporary file.
752 * handle MP4 library handle
753 * amount Amount to seek from the beginning of the file
758 * -1 File has not been opened
759 * -3 Current position in the file could not be set
762 mp4_i32 seekTmpFileAbs(MP4HandleImp handle, mp4_i64 amount)
764 if (!handle->tmpfile)
768 TInt64 amount64 = amount;
769 err = ((RFile64*)handle->tmpfile)->Seek(ESeekStart, amount64);
780 * mp4_i32 writeFile(MP4HandleImp handle,
782 * mp4_u32 bytestowrite)
786 * Write data into a file.
790 * handle MP4 library handle
791 * buffer Buffer containing the data
792 * bytestowrite Number of bytes to write
797 * -1 File has not been opened
798 * -2 Number of bytes written is not equal to bytestowrite
801 mp4_i32 writeFile(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestowrite)
803 return bufferedWrite(handle, buffer, bytestowrite);
810 * mp4_i32 writeFileUnbuffered(MP4HandleImp handle,
812 * mp4_u32 bytestowrite)
816 * Write data into a file without buffering.
820 * handle MP4 library handle
821 * buffer Buffer containing the data
822 * bytestowrite Number of bytes to write
827 * -1 File has not been opened
828 * -2 Number of bytes written is not equal to bytestowrite
831 mp4_i32 writeFileUnbuffered(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestowrite)
833 if(handle->bufferWrite)
835 mp4memcpy(handle->composeBuffer+FTYP_SIZE + handle->ftypdelta,buffer,bytestowrite);
841 if ( handle->filewriter )
843 TPtrC8 buf = TPtrC8((TUint8 *)(buffer), bytestowrite);
844 PRINT((_L("e_writefileunbuffered_flush 1")));
845 if ( (handle->filewriter)->Flush( buf ) != KErrNone )
847 PRINT((_L("e_writefileunbuffered_flush 0")));
850 PRINT((_L("e_writefileunbuffered_flush 0")));
864 * mp4_i32 writeTmpFile(MP4HandleImp handle,
866 * mp4_u32 bytestowrite)
870 * Write data into a temporary file.
874 * handle MP4 library handle
875 * buffer Buffer containing the data
876 * bytestowrite Number of bytes to write
881 * -1 File has not been opened
882 * -2 Number of bytes written is not equal to bytestowrite
885 mp4_i32 writeTmpFile(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestowrite)
887 if (!handle->tmpfile)
891 TPtrC8 ptrBuffer(buffer, bytestowrite);
892 err = ((RFile64*)handle->tmpfile)->Write(ptrBuffer, bytestowrite);
896 if (ptrBuffer.Length() != bytestowrite)
899 handle->bytesInTmpFile += bytestowrite;
908 * mp4_i32 createTmpFileName(MP4FileName filename,
909 * MP4FileName *tmpfilename)
913 * Create a temporary file name by adding .tmp to the end of a file name.
917 * filename Original file name
918 * tmpfilename Temporary file name is returned here
923 * -1 Memory could not be allocated for the new name
926 mp4_i32 createTmpFileName(MP4FileName filename, MP4FileName *tmpfilename)
928 *tmpfilename = (MP4FileName)mp4malloc(2 * wcslen(filename) + 10);
929 if (*tmpfilename == NULL)
932 wcscat(*tmpfilename, filename);
933 wcscat(*tmpfilename, L".tmp");
942 * mp4_i32 freeTmpFileName(MP4FileName filename)
946 * Free memory allocated for the temporary file name.
950 * filename Buffer containing file name
957 mp4_i32 freeTmpFileName(MP4FileName filename)
973 * Free memory allocated by stdlib wrapper functions (Symbian OS only).
986 // retrieves the TLS which stores the number of currently active instances of
988 TInt p = (TInt) Dll::Tls();
990 // decrement the counter as one instance is being closed at this point
992 Dll::SetTls((TAny*) p);
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.
1000 // If there are no other active instances other than this,
1001 // the memory allocated for stdlib for this thread can now be released.
1014 * Register the use of stdlib.
1025 mp4_i32 openStdlib()
1027 // retrieve the the value stored in TLS for this DLL
1028 TInt p = (TInt) Dll::Tls();
1030 // increment it. This becomes a reference counter of
1031 // how many instances of the composer/parser is currently active
1033 return (Dll::SetTls((TAny*) p));
1039 * mp4_i32 bufferedRead(MP4HandleImp handle,
1041 * mp4_u32 bytestoread)
1045 * Read data from a file in a buffered manner.
1049 * handle MP4 library handle
1050 * buffer Buffer to read data into
1051 * bytestoread Number of bytes to read from file
1056 * -1 File has not been opened
1057 * -2 Requested number of bytes could not be read
1060 mp4_i32 bufferedRead(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestoread)
1062 mp4_u32 bytesread = 0;
1067 while (bytesread < bytestoread)
1072 available = handle->diskReadSize - handle->diskReadBufPos;
1073 if (available > bytestoread - bytesread)
1074 available = bytestoread - bytesread;
1076 if (available > 0) /* Copy data from memory buffer */
1078 mp4memcpy(buffer + bytesread, handle->diskReadBuf + handle->diskReadBufPos, available);
1079 handle->diskReadBufPos += available;
1080 bytesread += available;
1082 else /* Read more data from file into memory buffer */
1084 TInt readBufferSize = 0;
1085 if ( handle->readBufferSize == 0)
1087 readBufferSize = READBUFSIZE;
1091 readBufferSize = handle->readBufferSize;
1094 TPtr8 buf = TPtr8((TUint8 *)(handle->diskReadBuf), readBufferSize);
1096 switch (handle->sourceType)
1098 case MP4_SOURCE_RFILE:
1099 if (((RFile64 *)(handle->rfile))->Read(buf, readBufferSize) != KErrNone)
1102 case MP4_SOURCE_CAF:
1103 handle->cafError = handle->cfile->Read(buf, readBufferSize);
1104 if ( handle->cafError != KErrNone)
1111 if ((mp4_u32)buf.Length() == 0) /* EOF or error */
1114 handle->diskReadBufPos = 0;
1115 handle->diskReadSize = (mp4_u32)buf.Length();
1116 handle->diskReadBufStart = handle->diskReadPos;
1117 handle->diskReadPos += handle->diskReadSize;
1127 * mp4_i32 bufferedSeek(MP4HandleImp handle,
1132 * Seek in a buffered file.
1136 * handle MP4 library handle
1137 * amount Amount to seek from current position
1142 * -1 File has not been opened
1143 * -3 Current position in the file could not be set
1146 mp4_i32 bufferedSeek(MP4HandleImp handle, mp4_i64 amount)
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)
1157 handle->diskReadBufPos += amount;
1166 am = amount - ((mp4_i32)handle->diskReadSize - (mp4_i32)handle->diskReadBufPos);
1168 if ( handle->rfile )
1170 mp4_i64 maxsize = 0;
1171 ((RFile64 *)(handle->rfile))->Size(maxsize);
1172 maxsize -= (mp4_i64)handle->diskReadPos;
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 )
1183 mp4_i64 maxsize = 0;
1184 TRAPD(caferr, handle->cfile->DataSize64L(maxsize));
1185 maxsize -= (mp4_i64)handle->diskReadPos;
1187 if (!caferr && am > maxsize)
1193 switch (handle->sourceType)
1195 case MP4_SOURCE_RFILE:
1197 PRINT((_L("e_bufferedseek_seek_rfile 1")));
1198 if (((RFile64 *)(handle->rfile))->Seek(ESeekCurrent, am) != KErrNone)
1202 PRINT((_L("e_bufferedseek_seek_rfile 0")));
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)
1212 PRINT((_L("e_bufferedseek_seek_cfile 0")));
1218 handle->diskReadPos = handle->diskReadBufStart + handle->diskReadBufPos + amount;
1219 handle->diskReadBufPos = 0;
1220 handle->diskReadBufStart = 0;
1221 handle->diskReadSize = 0;
1231 * mp4_i32 bufferedSeekAbs(MP4HandleImp handle,
1236 * Seek in a buffered file from the start of the file.
1240 * handle MP4 library handle
1241 * amount Amount to seek from start of the file
1246 * -1 File has not been opened
1247 * -3 Current position in the file could not be set
1250 mp4_i32 bufferedSeekAbs(MP4HandleImp handle, mp4_i64 amount)
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)
1261 handle->diskReadBufPos = amount - handle->diskReadBufStart;
1267 mp4_i64 am = amount;
1269 switch (handle->sourceType)
1271 case MP4_SOURCE_RFILE:
1273 PRINT((_L("e_bufferedseekabs_seek_rfile 1")));
1274 if (((RFile64 *)(handle->rfile))->Seek(ESeekStart, am) != KErrNone)
1278 PRINT((_L("e_bufferedseekabs_seek_rfile 0")));
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)
1292 handle->diskReadPos = (mp4_u64)amount;
1293 handle->diskReadBufPos = 0;
1294 handle->diskReadBufStart = 0;
1295 handle->diskReadSize = 0;
1305 * mp4_i32 bufferedWrite(MP4HandleImp handle,
1307 * mp4_u32 bytestowrite)
1311 * Write data into a file in a buffered manner.
1315 * handle MP4 library handle
1316 * buffer Buffer containing the data
1317 * bytestowrite Number of bytes to write
1322 * -1 File has not been opened
1323 * -2 Number of bytes written is not equal to bytestowrite
1326 mp4_i32 bufferedWrite(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestowrite)
1328 if(handle->bufferWrite)
1330 if(handle->bytesProgressed+bytestowrite > *(handle->composedSize))
1332 return MP4_OUTPUT_BUFFER_TOO_SMALL; //-1;
1336 mp4memcpy(handle->composeBuffer+handle->bytesProgressed,buffer,bytestowrite);
1337 handle->bytesProgressed+=bytestowrite;
1345 if ( handle->filewriter )
1347 TPtrC8 buf = TPtrC8((TUint8 *)(buffer), bytestowrite);
1348 PRINT((_L("e_file_bufferedwrite_write 1")));
1349 if ( (handle->filewriter)->Write( buf ) != KErrNone )
1353 PRINT((_L("e_file_bufferedwrite_write 0")));
1367 * mp4_i32 initMetaDataFiles(MP4HandleImp handle)
1371 * Open temporary files for writing.
1375 * handle MP4 library handle
1381 * MP4_OUT_OF_MEMORY Out of memory
1384 mp4_i32 initMetaDataFiles(MP4HandleImp handle)
1386 PRINT(_L("3GPLib::initMetaDataFiles() in"));
1391 TDriveList driveList;
1392 TBool pathSet = EFalse;
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)
1397 for ( TInt i = 0; i < driveList.Length(); i++ )
1399 TDriveInfo driveInfo;
1400 if (((RFs *)(handle->fs))->Drive(driveInfo, i) == KErrNone)
1402 if (driveInfo.iType == EMediaRam)
1405 ((RFs *)(handle->fs))->DriveToChar(i, driveLetter);
1406 path.Append(driveLetter);
1407 path.Append(_L(":"));
1408 path.Append(KTmpDirectoryName);
1416 // If no ram drive was found create a directory for the files on current drive
1419 if ( handle->fileName )
1421 filename = (TText *)handle->fileName;
1424 path = KTmpDirectoryName;
1425 if (((RFs *)(handle->fs))->Parse(filename, fp) != KErrNone)
1427 path.Insert(0, fp.Drive());
1432 if (((RFs *)(handle->fs))->DriveToChar(handle->fileHandleDrive, drive ) != KErrNone )
1434 path.Append( drive );
1435 path.Append( _L(":") );
1436 path.Append( KTmpDirectoryName );
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)));
1449 PRINT((_L("e_initmetadatafiles_newl_fileman 0")));
1451 PRINT((_L("e_initmetadatafiles_deletedirectory 1")));
1452 error = fileMan->RmDir( path ); // Delete directory + all files
1454 PRINT((_L("e_initmetadatafiles_deletedirectory 0")));
1456 error = ((RFs *)(handle->fs))->MkDirAll(path);
1457 if (error != KErrNone && error != KErrAlreadyExists)
1460 ((RFs *)(handle->fs))->SetEntry(path, TTime(0), KEntryAttHidden, NULL);
1463 TFileName metadatafilename;
1465 for (TUint i = 0; i < NUM_MDF; i++)
1467 handle->metaDataFile[i] = (void *)new(RFile64);
1468 if (handle->metaDataFile[i] == NULL)
1469 return MP4_OUT_OF_MEMORY;
1471 if (((RFile64 *)(handle->metaDataFile[i]))->Temp(*((RFs *)(handle->fs)), path, metadatafilename, EFileWrite | EFileShareExclusive) != KErrNone)
1474 handle->metaDataFileEmpty[i] = EFalse;
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)
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()));
1487 PRINT(_L("3GPLib::initMetaDataFiles() creating MetaDataWriter"));
1488 TRAPD(err, handle->metadatafilewriter = CMetaDataFileWriter::NewL());
1489 if ( err != KErrNone )
1491 PRINT((_L("3GPLib::initMetaDataFiles() MetaDataWriter creation error: %d"), err));
1492 if ( err == KErrNoMemory )
1494 return MP4_OUT_OF_MEMORY;
1502 PRINT(_L("3GPLib::initMetaDataFiles() MetaDataWriter created"));
1503 PRINT(_L("3GPLib::initMetaDataFiles() out"));
1511 * mp4_i32 writeMetaDataFileNum(MP4HandleImp handle,
1513 * mp4_u32 bytestowrite,
1514 * mp4_u32 filenumber)
1518 * Write data into a numbered file.
1522 * handle MP4 library handle
1523 * buffer Buffer containing the data
1524 * bytestowrite Number of bytes to write
1525 * filenumber Index of temporary file
1530 * -1 File has not been opened
1531 * -2 Number of bytes written is not equal to bytestowrite
1534 mp4_i32 writeMetaDataFileNum(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestowrite, mp4_u32 filenumber)
1536 PRINT(_L("3GPLib::writeMetaDataFileNum() in"));
1538 if (!handle->metaDataFile[filenumber])
1541 if ( handle->metadatafilewriter )
1543 TPtrC8 buf = TPtrC8((TUint8 *)(buffer), bytestowrite);
1544 PRINT((_L("e_file_writeMetaDataFileNum_write 1")));
1545 if ( (handle->metadatafilewriter)->Write( *((RFile64 *)(handle->metaDataFile[filenumber])),
1551 PRINT((_L("e_file_writeMetaDataFileNum_write 0")));
1558 PRINT(_L("3GPLib::writeMetaDataFileNum() out"));
1566 * mp4_i32 seekMetaDataFileNumAbs(MP4HandleImp handle,
1568 * mp4_u32 filenumber)
1572 * Seek from the beginning of a numbered file.
1576 * handle MP4 library handle
1577 * amount Amount to seek from the beginning of the file
1578 * filenumber Index of temporary file
1583 * -1 File has not been opened
1584 * -3 Current position in the file could not be set
1587 mp4_i32 seekMetaDataFileNumAbs(MP4HandleImp handle, mp4_i64 amount, mp4_u32 filenumber)
1589 PRINT(_L("3GPLib::seekMetaDataFileNumAbs() in"));
1591 if (!handle->metaDataFile[filenumber])
1595 if ( handle->metadatafilewriter )
1597 PRINT((_L("e_seekmetadatafilenumabs_flush 1")));
1598 if ( (handle->metadatafilewriter)->Flush() != KErrNone )
1600 PRINT((_L("e_seekmetadatafilenumabs_flush 0")));
1603 PRINT((_L("e_seekmetadatafilenumabs_flush 0")));
1606 PRINT((_L("e_seekmetadatafilenumabs_seek 1")));
1607 if (((RFile64 *)(handle->metaDataFile[filenumber]))->Seek(ESeekStart, amount) != KErrNone)
1611 PRINT((_L("e_seekmetadatafilenumabs_seek 0")));
1613 PRINT(_L("3GPLib::seekMetaDataFileNumAbs() out"));
1621 * mp4_i32 readMetaDataFileNum(MP4HandleImp handle,
1623 * mp4_u32 bytestoread,
1624 * mp4_u32 filenumber)
1628 * Read data from a numbered file.
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
1640 * -1 File has not been opened
1641 * -2 Requested number of bytes could not be read
1644 mp4_i32 readMetaDataFileNum(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestoread, mp4_u32 filenumber)
1646 PRINT(_L("3GPLib::readMetaDataFileNum() in"));
1647 PRINT((_L("e_readmetadatafiles 1")));
1649 mp4_u32 bytesread = 0;
1650 TPtr8 buf = TPtr8((TUint8 *)buffer, bytestoread);
1652 if (!handle->metaDataFile[filenumber])
1655 if ( handle->metadatafilewriter )
1657 PRINT((_L("e_readmetadatafiles_flush 1")));
1658 if ( (handle->metadatafilewriter)->Flush() != KErrNone )
1662 PRINT((_L("e_readmetadatafiles_flush 0")));
1665 PRINT((_L("e_readmetadatafiles_read 1")));
1667 if (handle->metaDataFileEmpty[filenumber])
1669 if (handle->metadatafilewriter)
1671 // if the file is empty, then read the data from temp buffer
1672 bytesread = (handle->metadatafilewriter)->ReadBuffer( filenumber, buf, bytestoread);
1674 if ( bytesread != bytestoread )
1677 else if (((RFile64 *)(handle->metaDataFile[filenumber]))->Read(buf, bytestoread) != KErrNone)
1679 handle->metaDataFileEmpty[filenumber] = ETrue;
1680 // if the file is empty, then read the data from temp buffer
1681 if (handle->metadatafilewriter)
1683 bytesread = (handle->metadatafilewriter)->ReadBuffer( filenumber, buf, bytestoread);
1685 if ( bytesread != bytestoread )
1688 else if ( buf.Length() < bytestoread ) // Got only part of data from file, rest is in buffer
1690 handle->metaDataFileEmpty[filenumber] = ETrue;
1691 // if the file is empty, then read the data from temp buffer
1692 if (handle->metadatafilewriter)
1694 bytesread = (handle->metadatafilewriter)->ReadBuffer( filenumber, buf, bytestoread - buf.Length());
1696 if ( buf.Length() != bytestoread )
1700 PRINT((_L("e_readmetadatafiles_read 0")));
1702 if ((mp4_u32)buf.Length() == 0) /* EOF or error */
1705 PRINT(_L("3GPLib::readMetaDataFileNum() out"));
1706 PRINT((_L("e_readmetadatafiles 0")));
1714 * mp4_i32 deleteMetaDataFiles(MP4HandleImp handle)
1718 * Remove a numbered temporary file.
1722 * handle MP4 library handle
1730 mp4_i32 deleteMetaDataFiles(MP4HandleImp handle)
1732 PRINT(_L("3GPLib::deleteMetaDataFiles() in"));
1733 PRINT((_L("e_deletemetadatafiles 1")));
1739 if ( handle->metadatafilewriter )
1741 PRINT((_L("e_deletemetadatafiles_flush 1")));
1742 if ( (handle->metadatafilewriter)->Flush() != KErrNone )
1744 PRINT((_L("e_deletemetadatafiles_flush 0")));
1747 PRINT((_L("e_deletemetadatafiles_flush 0")));
1748 delete handle->metadatafilewriter;
1749 handle->metadatafilewriter = NULL;
1752 /* Determine file names */
1753 PRINT((_L("e_deletemetadatafiles_determinenames 1")));
1754 if ( handle->fileName )
1756 filename = (TText *)handle->fileName;
1757 path = KTmpDirectoryName;
1760 if (((RFs *)(handle->fs))->Parse(filename, fp) != KErrNone)
1762 path.Insert(0, fp.Drive());
1767 if (((RFs *)(handle->fs))->DriveToChar(handle->fileHandleDrive, drive ) != KErrNone )
1769 path.Append( drive );
1770 path.Append( _L(":") );
1771 path.Append( KTmpDirectoryName );
1773 PRINT((_L("e_deletemetadatafiles_determinenames 0")));
1775 PRINT((_L("e_deletemetadatafiles_deletemetadatafilenames 1")));
1776 for (TUint i = 0; i < NUM_MDF; i++)
1778 if (handle->metaDataFileName[i])
1780 // check if client has defined async delete observer
1781 if ( handle->tempFileRemoverObserver )
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] );
1786 else // no observer, delete right here, ignore errors
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]);
1794 handle->metaDataFileName[i] = 0;
1796 PRINT((_L("e_deletemetadatafiles_deletemetadatafilenames 0")));
1800 PRINT(_L("3GPLib::deleteMetaDataFiles() out"));
1801 PRINT((_L("e_deletemetadatafiles 0")));
1809 * mp4_i32 closeMetaDataFiles(MP4HandleImp handle)
1813 * Close numbered tmp files.
1817 * handle MP4 library handle
1824 mp4_i32 closeMetaDataFiles(MP4HandleImp handle)
1826 PRINT(_L("3GPLib::closeMetaDataFiles() in"));
1827 PRINT((_L("e_close_metadatafiles 1")));
1829 if ( handle->metadatafilewriter )
1831 PRINT((_L("e_close_metadatafiles_flush 1")));
1832 if ( (handle->metadatafilewriter)->Flush() != KErrNone )
1834 PRINT((_L("e_close_metadatafiles_flush 0")));
1837 PRINT((_L("e_close_metadatafiles_flush 0")));
1840 for (TUint i = 0; i < NUM_MDF; i++)
1842 if (handle->metaDataFile[i])
1844 PRINT((_L("e_close_metadatafiles_closefile 1")));
1845 ((RFile64 *)(handle->metaDataFile[i]))->Close();
1846 PRINT((_L("e_close_metadatafiles_closefile 0")));
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;
1855 PRINT(_L("3GPLib::closeMetaDataFiles() out"));
1856 PRINT((_L("e_close_metadatafiles 0")));
1861 TInt RecommendedBufferSize(MP4HandleImp aHandle)
1863 TInt recommendedSize = READBUFSIZE;
1865 MP4HandleImp handle = (MP4HandleImp)aHandle;
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()>
1873 // It will not be set by MP4ParseOpenCAF()
1875 RFs* fs = (RFs*)handle->fs;
1876 RFile64* file64 = (RFile64*)handle->rfile;
1880 TInt driveNumber = 0;
1881 TDriveInfo driveInfo;
1882 TVolumeIOParamInfo volumeInfo;
1884 TInt err = file64->Drive(driveNumber, driveInfo);
1885 if (err == KErrNone)
1887 err = fs->VolumeIOParam(driveNumber, volumeInfo);
1890 if (err == KErrNone)
1892 if (volumeInfo.iRecReadBufSize != KErrNotSupported)
1894 recommendedSize = Max(recommendedSize, volumeInfo.iRecReadBufSize);
1901 return recommendedSize;