1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/mm/mmplugins/lib3gp/impl/src/file.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1905 @@
1.4 +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include "mp4file.h"
1.20 +#include "mp4memwrap.h"
1.21 +#include "mp4atom.h"
1.22 +#include <stdio.h>
1.23 +#include <string.h>
1.24 +#include <sys/unistd.h>
1.25 +#include <sys/reent.h>
1.26 +#include <f32file.h>
1.27 +#include <f32file64.h>
1.28 +#include <e32des16.h>
1.29 +#include <caf/caf.h>
1.30 +
1.31 +using namespace ContentAccess;
1.32 +
1.33 +// Debug print macro
1.34 +#ifdef _DEBUG
1.35 +#include <e32svr.h>
1.36 +#define PRINT(x) //comment this line and uncomment the line below to enable logging for this file
1.37 +//#define PRINT(x) RDebug::Print x
1.38 +#else
1.39 +#define PRINT(x)
1.40 +#endif
1.41 +
1.42 +_LIT(KTmpDirectoryName, "\\System\\Temp\\3GPLibTmpDir\\"); // Temporary output directory name
1.43 +
1.44 +
1.45 +/*
1.46 + * Function:
1.47 + *
1.48 + * mp4_i32 saveFileName(MP4FileName filename,
1.49 + * MP4HandleImp handle)
1.50 + *
1.51 + * Description:
1.52 + *
1.53 + * Save file name for later use.
1.54 + *
1.55 + * Parameters:
1.56 + *
1.57 + * filename Filename
1.58 + * handle MP4 library handle
1.59 + *
1.60 + * Return value:
1.61 + *
1.62 + * 0 Success
1.63 + * -1 Error
1.64 + *
1.65 + */
1.66 +mp4_i32 saveFileName(MP4FileName filename, MP4HandleImp handle)
1.67 +{
1.68 + handle->fileName = (MP4FileName)mp4malloc(2 * wcslen(filename) + 2);
1.69 + if (handle->fileName == NULL)
1.70 + return -1;
1.71 +
1.72 + wcscat(handle->fileName, filename);
1.73 +
1.74 + return 0;
1.75 +}
1.76 +
1.77 +
1.78 +/*
1.79 + * Function:
1.80 + *
1.81 + * mp4_i32 initFileRead(MP4FileName filename,
1.82 + * MP4HandleImp handle)
1.83 + *
1.84 + * Description:
1.85 + *
1.86 + * Open a file for reading.
1.87 + *
1.88 + * Note: filename is a Unicode string in Symbian OS.
1.89 + *
1.90 + * Parameters:
1.91 + *
1.92 + * filename Filename
1.93 + * handle MP4 library handle
1.94 + *
1.95 + * Return value:
1.96 + *
1.97 + * 0 Success
1.98 + * -1 Error
1.99 + *
1.100 + */
1.101 +mp4_i32 initFileRead(MP4FileName filename, MP4HandleImp handle)
1.102 +{
1.103 + RFs *fs;
1.104 + RFile64 *file;
1.105 +
1.106 +
1.107 + fs = new(RFs);
1.108 + handle->fs = (void *)fs;
1.109 + if (fs == NULL)
1.110 + return -1;
1.111 +
1.112 + if (fs->Connect() != KErrNone)
1.113 + return -1;
1.114 +
1.115 + file = new(RFile64);
1.116 + handle->rfile = (void *)file;
1.117 + if (file == NULL)
1.118 + return -1;
1.119 +
1.120 + if (file->Open(*fs, TPtrC((const TUint16 *)filename), EFileRead | EFileShareAny) != KErrNone)
1.121 + {
1.122 + // for compatibility, if opening in Any mode fails try more restrictive approach.
1.123 + if (file->Open(*fs, TPtrC((const TUint16 *)filename), EFileRead | EFileShareReadersOnly) != KErrNone)
1.124 + {
1.125 + return -1;
1.126 + }
1.127 + }
1.128 + handle->file = handle->rfile;
1.129 + return 0;
1.130 +}
1.131 +
1.132 +
1.133 +/*
1.134 + * Function:
1.135 + *
1.136 + * mp4_i32 initFileWrite(MP4FileName filename,
1.137 + * MP4HandleImp handle)
1.138 + *
1.139 + * Description:
1.140 + *
1.141 + * Open a file for writing.
1.142 + *
1.143 + * Note: filename is a Unicode string in Symbian OS.
1.144 + *
1.145 + * Parameters:
1.146 + *
1.147 + * filename Filename
1.148 + * handle MP4 library handle
1.149 + *
1.150 + * Return value:
1.151 + *
1.152 + * 0 Success
1.153 + * -1 Error
1.154 + *
1.155 + */
1.156 +mp4_i32 initFileWrite(MP4FileName filename, MP4HandleImp handle)
1.157 +{
1.158 + RFs *fs;
1.159 + RFile64 *file;
1.160 + TParse fp;
1.161 + TFileName path;
1.162 + TInt error;
1.163 +
1.164 +
1.165 + fs = new(RFs);
1.166 + handle->fs = (void *)fs;
1.167 + if (fs == NULL)
1.168 + return -1;
1.169 +
1.170 + if (fs->Connect() != KErrNone)
1.171 + return -1;
1.172 +
1.173 + file = new(RFile64);
1.174 + handle->rfile = (void *)file;
1.175 + if (file == NULL)
1.176 + return -1;
1.177 +
1.178 + if (((RFs *)(handle->fs))->Parse(TPtrC((const TUint16 *)filename), fp) != KErrNone)
1.179 + return -1;
1.180 +
1.181 + path.Insert(0, fp.DriveAndPath() );
1.182 + error = ((RFs *)(handle->fs))->MkDirAll(path);
1.183 + if (error != KErrNone && error != KErrAlreadyExists)
1.184 + return -1;
1.185 +
1.186 + if (file->Replace(*fs, TPtrC((const TUint16 *)filename), EFileWrite|EFileShareExclusive|EFileWriteDirectIO ) != KErrNone)
1.187 + {
1.188 + return -1;
1.189 + }
1.190 +
1.191 + TBuf8<16> buf;
1.192 + buf.Copy(fp.Drive());
1.193 + buf.LowerCase();
1.194 + TInt drvNum = (*buf.Ptr()) - 'a';
1.195 + PRINT((_L("drvNum = %d"), drvNum));
1.196 +
1.197 + TVolumeInfo volInfo;
1.198 + error = fs->Volume(volInfo, drvNum);
1.199 + if (error != KErrNone)
1.200 + {
1.201 + return -1;
1.202 + }
1.203 +
1.204 + PRINT((_L("volInfo.iFree = %Ld"), volInfo.iFree));
1.205 + PRINT((_L("volInfo.iSize = %Ld"), volInfo.iSize));
1.206 +
1.207 + TVolumeIOParamInfo ioInfo;
1.208 + error = fs->VolumeIOParam(drvNum, ioInfo);
1.209 + if (error != KErrNone)
1.210 + {
1.211 + return -1;
1.212 + }
1.213 +
1.214 + PRINT((_L("ioInfo.iBlockSize = %d"), ioInfo.iBlockSize));
1.215 + PRINT((_L("ioInfo.iClusterSize = %d"), ioInfo.iClusterSize));
1.216 +
1.217 + if (ioInfo.iClusterSize <= 0 || (ioInfo.iClusterSize & 0x1)) // if for some reason we got wrong value for the cluster - ignore it
1.218 + {
1.219 + PRINT(_L("Wrong cluster size, set 0x8000"));
1.220 + ioInfo.iClusterSize = 0x8000;
1.221 + }
1.222 +
1.223 + // 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.
1.224 + TInt writeBufferSizeSmall = ioInfo.iClusterSize;
1.225 + TInt writeBufferSizeLarge = ioInfo.iClusterSize * 8;
1.226 +
1.227 + // Now need to make sure that writeBufferSizeLarge is not too small (<128K) or too big (>256K) whilst keeping it a multiple of cluster size
1.228 + if (writeBufferSizeLarge < KFileWriterBufferSizeLarge/2)
1.229 + {
1.230 + writeBufferSizeLarge = KFileWriterBufferSizeLarge/2;
1.231 + }
1.232 +
1.233 + if (writeBufferSizeLarge > KFileWriterBufferSizeLarge)
1.234 + {
1.235 + writeBufferSizeLarge = (KFileWriterBufferSizeLarge / ioInfo.iClusterSize) * ioInfo.iClusterSize;
1.236 + }
1.237 +
1.238 + if (writeBufferSizeLarge < ioInfo.iClusterSize)
1.239 + {
1.240 + writeBufferSizeLarge = ioInfo.iClusterSize;
1.241 + }
1.242 +
1.243 + PRINT((_L("writeBufferSizeLarge = %d"), writeBufferSizeLarge));
1.244 +
1.245 + TInt incSetSize = writeBufferSizeLarge * (KFileWriterHardBufLimit >> 1); // 2Mb if cluster size if 32767
1.246 + TInt initSetSize = incSetSize * 1; // set initial set size for 2Mb
1.247 +
1.248 + if (initSetSize > volInfo.iFree)
1.249 + {
1.250 + initSetSize = (volInfo.iFree / incSetSize) * incSetSize;
1.251 + }
1.252 +
1.253 + PRINT((_L("initSetSize = %d"), initSetSize));
1.254 +
1.255 + PRINT((_L("e_SetSize 1")));
1.256 + file->SetSize(initSetSize);
1.257 + PRINT((_L("e_SetSize 0")));
1.258 +
1.259 + handle->file = handle->rfile;
1.260 +
1.261 + TRAP(error, handle->filewriter = CFileWriter::NewL( *file, initSetSize, writeBufferSizeSmall, writeBufferSizeLarge));
1.262 + if ( error != KErrNone )
1.263 + {
1.264 + return -1;
1.265 + }
1.266 +
1.267 + return 0;
1.268 +}
1.269 +
1.270 +
1.271 +/*
1.272 + * Function:
1.273 + *
1.274 + * mp4_i32 initTmpFileWrite(MP4FileName filename,
1.275 + * MP4HandleImp handle)
1.276 + *
1.277 + * Description:
1.278 + *
1.279 + * Open a temporary file for writing.
1.280 + *
1.281 + * Note: filename is a Unicode string in Symbian OS.
1.282 + *
1.283 + * Parameters:
1.284 + *
1.285 + * filename Filename
1.286 + * handle MP4 library handle
1.287 + *
1.288 + * Return value:
1.289 + *
1.290 + * 0 Success
1.291 + * -1 Error
1.292 + *
1.293 + */
1.294 +mp4_i32 initTmpFileWrite(MP4FileName filename, MP4HandleImp handle)
1.295 +{
1.296 + TInt err;
1.297 + RFile64 * file = new RFile64;
1.298 + TBuf16<KMaxFileName> name(reinterpret_cast<const TUint16*>(filename));
1.299 + ASSERT(handle->fs != NULL);
1.300 + err = file->Replace(*(RFs*)(handle->fs), name, EFileStream | EFileRead | EFileWrite | EFileWriteDirectIO);
1.301 + if (err != KErrNone)
1.302 + {
1.303 + delete file;
1.304 + return -1;
1.305 + }
1.306 +
1.307 + handle->tmpfile = (void *)file;
1.308 + return 0;
1.309 +}
1.310 +
1.311 +
1.312 +/*
1.313 + * Function:
1.314 + *
1.315 + * mp4_i32 closeFile(MP4HandleImp handle)
1.316 + *
1.317 + * Description:
1.318 + *
1.319 + * Close a file.
1.320 + *
1.321 + * Parameters:
1.322 + *
1.323 + * handle MP4 library handle
1.324 + *
1.325 + * Return value:
1.326 + *
1.327 + * 0 Success
1.328 + *
1.329 + */
1.330 +mp4_i32 closeFile(MP4HandleImp handle)
1.331 +{
1.332 + PRINT((_L("e_closefile 1")));
1.333 + if (handle->rfile)
1.334 + {
1.335 + if (handle->filewriter)
1.336 + {
1.337 + PRINT((_L("e_closefile_flush_filewriter 1")));
1.338 + (handle->filewriter)->Flush(KNullDesC8);
1.339 + PRINT((_L("e_closefile_flush_filewriter 0")));
1.340 + PRINT((_L("e_SetSize 1")));
1.341 + ((RFile64 *)(handle->file))->SetSize((handle->filewriter)->OutputFileSize());
1.342 + PRINT((_L("e_SetSize 0: iOutputFileSize = %Ld"), (handle->filewriter)->OutputFileSize()));
1.343 +
1.344 + delete handle->filewriter;
1.345 + handle->filewriter = NULL;
1.346 + }
1.347 + }
1.348 +
1.349 + if (handle->asyncReader)
1.350 + {
1.351 + delete handle->asyncReader;
1.352 + handle->asyncReader = NULL;
1.353 + }
1.354 +
1.355 + if (handle->rfile)
1.356 + {
1.357 + if ( !handle->FileHandleFromOutside )
1.358 + {
1.359 + PRINT((_L("e_closefile_close_file 1")));
1.360 + ((RFile64 *)(handle->rfile))->Close();
1.361 + PRINT((_L("e_closefile_close_file 0")));
1.362 + PRINT((_L("e_closefile_delete_fileptr 1")));
1.363 + delete(handle->rfile);
1.364 + PRINT((_L("e_closefile_delete_fileptr 0")));
1.365 + }
1.366 + handle->rfile = NULL;
1.367 + }
1.368 +
1.369 + if (handle->cfile)
1.370 + {
1.371 + if ( !handle->FileHandleFromOutside )
1.372 + {
1.373 + delete(handle->cfile);
1.374 + }
1.375 + handle->cfile = NULL;
1.376 + }
1.377 +
1.378 + PRINT((_L("e_closefile_close_rfs 1")));
1.379 + if (handle->fs)
1.380 + {
1.381 + ((RFs *)(handle->fs))->Close();
1.382 +
1.383 + delete(handle->fs);
1.384 +
1.385 + handle->fs = NULL;
1.386 + }
1.387 + PRINT((_L("e_closefile_close_rfs 0")));
1.388 +
1.389 + handle->file = NULL;
1.390 + PRINT((_L("e_closefile 0")));
1.391 + return 0;
1.392 +}
1.393 +
1.394 +
1.395 +/*
1.396 + * Function:
1.397 + *
1.398 + * mp4_i32 closeTmpFile(MP4HandleImp handle)
1.399 + *
1.400 + * Description:
1.401 + *
1.402 + * Close a temporary file.
1.403 + *
1.404 + * Parameters:
1.405 + *
1.406 + * handle MP4 library handle
1.407 + *
1.408 + * Return value:
1.409 + *
1.410 + * 0 Success
1.411 + *
1.412 + */
1.413 +mp4_i32 closeTmpFile(MP4HandleImp handle)
1.414 +{
1.415 + if (handle->tmpfile)
1.416 + ((RFile64*)handle->tmpfile)->Close();
1.417 +
1.418 + handle->tmpfile = NULL;
1.419 +
1.420 + return 0;
1.421 +}
1.422 +
1.423 +
1.424 +/*
1.425 + * Function:
1.426 + *
1.427 + * mp4_i32 deleteTmpFile(MP4HandleImp handle)
1.428 + *
1.429 + * Description:
1.430 + *
1.431 + * Remove a temporary file.
1.432 + *
1.433 + * Parameters:
1.434 + *
1.435 + * handle MP4 library handle
1.436 + *
1.437 + * Return value:
1.438 + *
1.439 + * 0 Success
1.440 + * -1 Error
1.441 + *
1.442 + */
1.443 +mp4_i32 deleteTmpFile(MP4HandleImp handle)
1.444 +{
1.445 + if (handle->tmpFileName)
1.446 + {
1.447 + TInt err;
1.448 + TBuf<KMaxFileName> name(reinterpret_cast<const TUint16*>(handle->tmpFileName));
1.449 + ASSERT(handle->fs != NULL);
1.450 + err = ((RFs*)handle->fs)->Delete(name);
1.451 + if (err != KErrNone)
1.452 + return -1;
1.453 + }
1.454 +
1.455 + return 0;
1.456 +}
1.457 +
1.458 +
1.459 +/*
1.460 + * Function:
1.461 + *
1.462 + * mp4_i32 readFile(MP4HandleImp handle,
1.463 + * mp4_u8 *buffer,
1.464 + * mp4_u32 bytestoread)
1.465 + *
1.466 + * Description:
1.467 + *
1.468 + * Read data from a file.
1.469 + *
1.470 + * Parameters:
1.471 + *
1.472 + * handle MP4 library handle
1.473 + * buffer Buffer to read data into
1.474 + * bytestoread Number of bytes to read from file
1.475 + *
1.476 + * Return value:
1.477 + *
1.478 + * 0 Success
1.479 + * -1 File has not been opened
1.480 + * -2 Requested number of bytes could not be read
1.481 + *
1.482 + */
1.483 +mp4_i32 readFile(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestoread)
1.484 +{
1.485 + return bufferedRead(handle, buffer, bytestoread);
1.486 +}
1.487 +
1.488 +/*
1.489 + * Function:
1.490 + *
1.491 + * mp4_i32 readTmpFile(MP4HandleImp handle,
1.492 + * mp4_u8 *buffer,
1.493 + * mp4_u32 bytestoread)
1.494 + *
1.495 + * Description:
1.496 + *
1.497 + * Read data from a temporary file.
1.498 + *
1.499 + * Parameters:
1.500 + *
1.501 + * handle MP4 library handle
1.502 + * buffer Buffer to read data into
1.503 + * bytestoread Number of bytes to read from file
1.504 + *
1.505 + * Return value:
1.506 + *
1.507 + * 0 Success
1.508 + * -1 File has not been opened
1.509 + * -2 Requested number of bytes could not be read
1.510 + *
1.511 + */
1.512 +mp4_i32 readTmpFile(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestoread)
1.513 +{
1.514 + if (!handle->tmpfile)
1.515 + return -1;
1.516 +
1.517 + TInt err;
1.518 + TPtr8 ptrBuffer(buffer, bytestoread);
1.519 + err = ((RFile64*)handle->tmpfile)->Read(ptrBuffer, bytestoread);
1.520 + if (err != KErrNone)
1.521 + return -2;
1.522 +
1.523 + if (ptrBuffer.Length() != bytestoread)
1.524 + return -2;
1.525 +
1.526 + return 0;
1.527 +}
1.528 +
1.529 +
1.530 +/*
1.531 + * Function:
1.532 + *
1.533 + * mp4_i32 peekFile(MP4HandleImp handle,
1.534 + * mp4_u8 *buffer,
1.535 + * mp4_u32 bytestoread)
1.536 + *
1.537 + * Description:
1.538 + *
1.539 + * Read data from a file but don't move the current position in the file
1.540 + * forward.
1.541 + *
1.542 + * Parameters:
1.543 + *
1.544 + * handle MP4 library handle
1.545 + * buffer Buffer to read data into
1.546 + * bytestoread Number of bytes to read from file
1.547 + *
1.548 + * Return value:
1.549 + *
1.550 + * 0 Success
1.551 + * -1 File has not been opened
1.552 + * -2 Requested number of bytes could not be read
1.553 + * -3 Current position in the file could not be set to original
1.554 + * value
1.555 + *
1.556 + */
1.557 +mp4_i32 peekFile(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestoread)
1.558 +{
1.559 + mp4_i32 ret;
1.560 + mp4_i32 amount;
1.561 +
1.562 +
1.563 + ret = bufferedRead(handle, buffer, bytestoread);
1.564 + if (ret != 0)
1.565 + return ret;
1.566 +
1.567 + amount = -(mp4_i32)bytestoread;
1.568 +
1.569 + ret = bufferedSeek(handle, amount);
1.570 + if (ret != 0)
1.571 + return ret;
1.572 +
1.573 + return 0;
1.574 +}
1.575 +
1.576 +
1.577 +/*
1.578 + * Function:
1.579 + *
1.580 + * mp4_i32 seekFile(MP4HandleImp handle,
1.581 + * mp4_i32 amount)
1.582 + *
1.583 + * Description:
1.584 + *
1.585 + * Seek in a file.
1.586 + *
1.587 + * Parameters:
1.588 + *
1.589 + * handle MP4 library handle
1.590 + * amount Amount to seek from current position
1.591 + *
1.592 + * Return value:
1.593 + *
1.594 + * 0 Success
1.595 + * -1 File has not been opened
1.596 + * -3 Current position in the file could not be set
1.597 + *
1.598 + */
1.599 +mp4_i32 seekFile(MP4HandleImp handle, mp4_i64 amount)
1.600 +{
1.601 + return bufferedSeek(handle, amount);
1.602 +}
1.603 +
1.604 +
1.605 +/*
1.606 + * Function:
1.607 + *
1.608 + * mp4_i32 seekFileAbs(MP4HandleImp handle,
1.609 + * mp4_i32 amount)
1.610 + *
1.611 + * Description:
1.612 + *
1.613 + * Seek from the beginning of a file.
1.614 + *
1.615 + * Parameters:
1.616 + *
1.617 + * handle MP4 library handle
1.618 + * amount Amount to seek from the beginning of the file
1.619 + *
1.620 + * Return value:
1.621 + *
1.622 + * 0 Success
1.623 + * -1 File has not been opened
1.624 + * -3 Current position in the file could not be set
1.625 + *
1.626 + */
1.627 +mp4_i32 seekFileAbs(MP4HandleImp handle, mp4_i64 amount)
1.628 +{
1.629 + return bufferedSeekAbs(handle, amount);
1.630 +}
1.631 +
1.632 +
1.633 +/*
1.634 + * Function:
1.635 + *
1.636 + * mp4_i32 seekFileWrite(MP4HandleImp handle,
1.637 + * mp4_i64 amount)
1.638 + *
1.639 + * Description:
1.640 + *
1.641 + * Seek in a file that has been opened for writing.
1.642 + *
1.643 + * Parameters:
1.644 + *
1.645 + * handle MP4 library handle
1.646 + * amount Amount to seek from current position
1.647 + *
1.648 + * Return value:
1.649 + *
1.650 + * 0 Success
1.651 + * -1 File has not been opened
1.652 + * -2 Can't write buffers to file
1.653 + * -3 Current position in the file could not be set
1.654 + *
1.655 + */
1.656 +mp4_i32 seekFileWrite(MP4HandleImp handle, mp4_i64 amount)
1.657 +{
1.658 +
1.659 + if (!handle->rfile)
1.660 + return -1;
1.661 +
1.662 + if ( handle->filewriter )
1.663 + {
1.664 + PRINT((_L("e_seekfilewrite_flush_filewriter 1")));
1.665 + if ( (handle->filewriter)->Flush(KNullDesC8) != KErrNone )
1.666 + {
1.667 + PRINT((_L("e_seekfilewrite_flush_filewriter 0")));
1.668 + return -2;
1.669 + }
1.670 + PRINT((_L("e_seekfilewrite_flush_filewriter 0")));
1.671 + }
1.672 + else
1.673 + {
1.674 + return -1;
1.675 + }
1.676 +
1.677 + PRINT((_L("e_seekfilewrite_seek_rfile 1")));
1.678 + if (((RFile64 *)(handle->rfile))->Seek(ESeekCurrent,amount) != KErrNone)
1.679 + {
1.680 + return -3;
1.681 + }
1.682 +
1.683 + PRINT((_L("e_seekfilewrite_seek_rfile 0")));
1.684 +
1.685 + return 0;
1.686 +}
1.687 +
1.688 +
1.689 +/*
1.690 + * Function:
1.691 + *
1.692 + * mp4_i32 seekFileAbsWrite(MP4HandleImp handle,
1.693 + * mp4_i32 amount)
1.694 + *
1.695 + * Description:
1.696 + *
1.697 + * Seek from the beginning of a file that has been opened for writing.
1.698 + *
1.699 + * Parameters:
1.700 + *
1.701 + * handle MP4 library handle
1.702 + * amount Amount to seek from the beginning of the file
1.703 + *
1.704 + * Return value:
1.705 + *
1.706 + * 0 Success
1.707 + * -1 File has not been opened
1.708 + * -2 Can't write buffers to file
1.709 + * -3 Current position in the file could not be set
1.710 + *
1.711 + */
1.712 +mp4_i32 seekFileAbsWrite(MP4HandleImp handle, mp4_i64 amount)
1.713 +{
1.714 + if (!handle->rfile)
1.715 + return -1;
1.716 +
1.717 + if ( handle->filewriter )
1.718 + {
1.719 + PRINT((_L("e_seekfileabswrite_flush 1")));
1.720 + if ( (handle->filewriter)->Flush(KNullDesC8) != KErrNone )
1.721 + {
1.722 + PRINT((_L("e_seekfileabswrite_flush 0")));
1.723 + return -2;
1.724 + }
1.725 + PRINT((_L("e_seekfileabswrite_flush 0")));
1.726 + }
1.727 + else
1.728 + {
1.729 + return -1;
1.730 + }
1.731 +
1.732 + PRINT((_L("e_seekfileabswrite_seek 1")));
1.733 + if (((RFile64 *)(handle->rfile))->Seek(ESeekStart, amount) != KErrNone)
1.734 + {
1.735 + return -3;
1.736 + }
1.737 + PRINT((_L("e_seekfileabswrite_seek 0")));
1.738 +
1.739 + return 0;
1.740 +}
1.741 +
1.742 +
1.743 +/*
1.744 + * Function:
1.745 + *
1.746 + * mp4_i32 seekTmpFileAbs(MP4HandleImp handle,
1.747 + * mp4_i32 amount)
1.748 + *
1.749 + * Description:
1.750 + *
1.751 + * Seek from the beginning of a temporary file.
1.752 + *
1.753 + * Parameters:
1.754 + *
1.755 + * handle MP4 library handle
1.756 + * amount Amount to seek from the beginning of the file
1.757 + *
1.758 + * Return value:
1.759 + *
1.760 + * 0 Success
1.761 + * -1 File has not been opened
1.762 + * -3 Current position in the file could not be set
1.763 + *
1.764 + */
1.765 +mp4_i32 seekTmpFileAbs(MP4HandleImp handle, mp4_i64 amount)
1.766 +{
1.767 + if (!handle->tmpfile)
1.768 + return -1;
1.769 +
1.770 + TInt err;
1.771 + TInt64 amount64 = amount;
1.772 + err = ((RFile64*)handle->tmpfile)->Seek(ESeekStart, amount64);
1.773 + if (err != KErrNone)
1.774 + return -3;
1.775 +
1.776 + return 0;
1.777 +}
1.778 +
1.779 +
1.780 +/*
1.781 + * Function:
1.782 + *
1.783 + * mp4_i32 writeFile(MP4HandleImp handle,
1.784 + * mp4_u8 *buffer,
1.785 + * mp4_u32 bytestowrite)
1.786 + *
1.787 + * Description:
1.788 + *
1.789 + * Write data into a file.
1.790 + *
1.791 + * Parameters:
1.792 + *
1.793 + * handle MP4 library handle
1.794 + * buffer Buffer containing the data
1.795 + * bytestowrite Number of bytes to write
1.796 + *
1.797 + * Return value:
1.798 + *
1.799 + * 0 Success
1.800 + * -1 File has not been opened
1.801 + * -2 Number of bytes written is not equal to bytestowrite
1.802 + *
1.803 + */
1.804 +mp4_i32 writeFile(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestowrite)
1.805 +{
1.806 + return bufferedWrite(handle, buffer, bytestowrite);
1.807 +}
1.808 +
1.809 +
1.810 +/*
1.811 + * Function:
1.812 + *
1.813 + * mp4_i32 writeFileUnbuffered(MP4HandleImp handle,
1.814 + * mp4_u8 *buffer,
1.815 + * mp4_u32 bytestowrite)
1.816 + *
1.817 + * Description:
1.818 + *
1.819 + * Write data into a file without buffering.
1.820 + *
1.821 + * Parameters:
1.822 + *
1.823 + * handle MP4 library handle
1.824 + * buffer Buffer containing the data
1.825 + * bytestowrite Number of bytes to write
1.826 + *
1.827 + * Return value:
1.828 + *
1.829 + * 0 Success
1.830 + * -1 File has not been opened
1.831 + * -2 Number of bytes written is not equal to bytestowrite
1.832 + *
1.833 + */
1.834 +mp4_i32 writeFileUnbuffered(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestowrite)
1.835 +{
1.836 + if(handle->bufferWrite)
1.837 + {
1.838 + mp4memcpy(handle->composeBuffer+FTYP_SIZE + handle->ftypdelta,buffer,bytestowrite);
1.839 + return 0;
1.840 + }
1.841 + if (!handle->rfile)
1.842 + return -1;
1.843 +
1.844 + if ( handle->filewriter )
1.845 + {
1.846 + TPtrC8 buf = TPtrC8((TUint8 *)(buffer), bytestowrite);
1.847 + PRINT((_L("e_writefileunbuffered_flush 1")));
1.848 + if ( (handle->filewriter)->Flush( buf ) != KErrNone )
1.849 + {
1.850 + PRINT((_L("e_writefileunbuffered_flush 0")));
1.851 + return -2;
1.852 + }
1.853 + PRINT((_L("e_writefileunbuffered_flush 0")));
1.854 + }
1.855 + else
1.856 + {
1.857 + return -1;
1.858 + }
1.859 +
1.860 + return 0;
1.861 +}
1.862 +
1.863 +
1.864 +/*
1.865 + * Function:
1.866 + *
1.867 + * mp4_i32 writeTmpFile(MP4HandleImp handle,
1.868 + * mp4_u8 *buffer,
1.869 + * mp4_u32 bytestowrite)
1.870 + *
1.871 + * Description:
1.872 + *
1.873 + * Write data into a temporary file.
1.874 + *
1.875 + * Parameters:
1.876 + *
1.877 + * handle MP4 library handle
1.878 + * buffer Buffer containing the data
1.879 + * bytestowrite Number of bytes to write
1.880 + *
1.881 + * Return value:
1.882 + *
1.883 + * 0 Success
1.884 + * -1 File has not been opened
1.885 + * -2 Number of bytes written is not equal to bytestowrite
1.886 + *
1.887 + */
1.888 +mp4_i32 writeTmpFile(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestowrite)
1.889 +{
1.890 + if (!handle->tmpfile)
1.891 + return -1;
1.892 +
1.893 + TInt err;
1.894 + TPtrC8 ptrBuffer(buffer, bytestowrite);
1.895 + err = ((RFile64*)handle->tmpfile)->Write(ptrBuffer, bytestowrite);
1.896 + if (err != KErrNone)
1.897 + return -2;
1.898 +
1.899 + if (ptrBuffer.Length() != bytestowrite)
1.900 + return -2;
1.901 +
1.902 + handle->bytesInTmpFile += bytestowrite;
1.903 +
1.904 + return 0;
1.905 +}
1.906 +
1.907 +
1.908 +/*
1.909 + * Function:
1.910 + *
1.911 + * mp4_i32 createTmpFileName(MP4FileName filename,
1.912 + * MP4FileName *tmpfilename)
1.913 + *
1.914 + * Description:
1.915 + *
1.916 + * Create a temporary file name by adding .tmp to the end of a file name.
1.917 + *
1.918 + * Parameters:
1.919 + *
1.920 + * filename Original file name
1.921 + * tmpfilename Temporary file name is returned here
1.922 + *
1.923 + * Return value:
1.924 + *
1.925 + * 0 Success
1.926 + * -1 Memory could not be allocated for the new name
1.927 + *
1.928 + */
1.929 +mp4_i32 createTmpFileName(MP4FileName filename, MP4FileName *tmpfilename)
1.930 +{
1.931 + *tmpfilename = (MP4FileName)mp4malloc(2 * wcslen(filename) + 10);
1.932 + if (*tmpfilename == NULL)
1.933 + return -1;
1.934 +
1.935 + wcscat(*tmpfilename, filename);
1.936 + wcscat(*tmpfilename, L".tmp");
1.937 +
1.938 + return 0;
1.939 +}
1.940 +
1.941 +
1.942 +/*
1.943 + * Function:
1.944 + *
1.945 + * mp4_i32 freeTmpFileName(MP4FileName filename)
1.946 + *
1.947 + * Description:
1.948 + *
1.949 + * Free memory allocated for the temporary file name.
1.950 + *
1.951 + * Parameters:
1.952 + *
1.953 + * filename Buffer containing file name
1.954 + *
1.955 + * Return value:
1.956 + *
1.957 + * 0 Success
1.958 + *
1.959 + */
1.960 +mp4_i32 freeTmpFileName(MP4FileName filename)
1.961 +{
1.962 + if (filename)
1.963 + mp4free(filename);
1.964 +
1.965 + return 0;
1.966 +}
1.967 +
1.968 +
1.969 +/*
1.970 + * Function:
1.971 + *
1.972 + * void closeStdlib()
1.973 + *
1.974 + * Description:
1.975 + *
1.976 + * Free memory allocated by stdlib wrapper functions (Symbian OS only).
1.977 + *
1.978 + * Parameters:
1.979 + *
1.980 + * None
1.981 + *
1.982 + * Return value:
1.983 + *
1.984 + * None
1.985 + *
1.986 + */
1.987 +void closeStdlib()
1.988 + {
1.989 + // retrieves the TLS which stores the number of currently active instances of
1.990 + // composer/parser
1.991 + TInt p = (TInt) Dll::Tls();
1.992 +
1.993 + // decrement the counter as one instance is being closed at this point
1.994 + p--;
1.995 + Dll::SetTls((TAny*) p);
1.996 +
1.997 + if (p == 0)
1.998 + {
1.999 + // Since memory allocated for stdlib is shared amongst all composers and/or parsers
1.1000 + // within a thread, stdlib close should ONLY be called for the last instance of
1.1001 + // composer / parser.
1.1002 + //
1.1003 + // If there are no other active instances other than this,
1.1004 + // the memory allocated for stdlib for this thread can now be released.
1.1005 + Dll::FreeTls();
1.1006 + CloseSTDLIB();
1.1007 + }
1.1008 + }
1.1009 +
1.1010 +/*
1.1011 + * Function:
1.1012 + *
1.1013 + * void openStdlib()
1.1014 + *
1.1015 + * Description:
1.1016 + *
1.1017 + * Register the use of stdlib.
1.1018 + *
1.1019 + * Parameters:
1.1020 + *
1.1021 + * None
1.1022 + *
1.1023 + * Return value:
1.1024 + *
1.1025 + * 0 Success
1.1026 + *
1.1027 + */
1.1028 +mp4_i32 openStdlib()
1.1029 + {
1.1030 + // retrieve the the value stored in TLS for this DLL
1.1031 + TInt p = (TInt) Dll::Tls();
1.1032 +
1.1033 + // increment it. This becomes a reference counter of
1.1034 + // how many instances of the composer/parser is currently active
1.1035 + p++;
1.1036 + return (Dll::SetTls((TAny*) p));
1.1037 + }
1.1038 +
1.1039 +/*
1.1040 + * Function:
1.1041 + *
1.1042 + * mp4_i32 bufferedRead(MP4HandleImp handle,
1.1043 + * mp4_u8 *buffer,
1.1044 + * mp4_u32 bytestoread)
1.1045 + *
1.1046 + * Description:
1.1047 + *
1.1048 + * Read data from a file in a buffered manner.
1.1049 + *
1.1050 + * Parameters:
1.1051 + *
1.1052 + * handle MP4 library handle
1.1053 + * buffer Buffer to read data into
1.1054 + * bytestoread Number of bytes to read from file
1.1055 + *
1.1056 + * Return value:
1.1057 + *
1.1058 + * 0 Success
1.1059 + * -1 File has not been opened
1.1060 + * -2 Requested number of bytes could not be read
1.1061 + *
1.1062 + */
1.1063 +mp4_i32 bufferedRead(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestoread)
1.1064 +{
1.1065 + mp4_u32 bytesread = 0;
1.1066 +
1.1067 + if (!handle->file)
1.1068 + return -1;
1.1069 +
1.1070 + while (bytesread < bytestoread)
1.1071 + {
1.1072 + mp4_u32 available;
1.1073 +
1.1074 +
1.1075 + available = handle->diskReadSize - handle->diskReadBufPos;
1.1076 + if (available > bytestoread - bytesread)
1.1077 + available = bytestoread - bytesread;
1.1078 +
1.1079 + if (available > 0) /* Copy data from memory buffer */
1.1080 + {
1.1081 + mp4memcpy(buffer + bytesread, handle->diskReadBuf + handle->diskReadBufPos, available);
1.1082 + handle->diskReadBufPos += available;
1.1083 + bytesread += available;
1.1084 + }
1.1085 + else /* Read more data from file into memory buffer */
1.1086 + {
1.1087 + TInt readBufferSize = 0;
1.1088 + if ( handle->readBufferSize == 0)
1.1089 + {
1.1090 + readBufferSize = READBUFSIZE;
1.1091 + }
1.1092 + else
1.1093 + {
1.1094 + readBufferSize = handle->readBufferSize;
1.1095 + }
1.1096 +
1.1097 + TPtr8 buf = TPtr8((TUint8 *)(handle->diskReadBuf), readBufferSize);
1.1098 +
1.1099 + switch (handle->sourceType)
1.1100 + {
1.1101 + case MP4_SOURCE_RFILE:
1.1102 + if (((RFile64 *)(handle->rfile))->Read(buf, readBufferSize) != KErrNone)
1.1103 + return -2;
1.1104 + break;
1.1105 + case MP4_SOURCE_CAF:
1.1106 + handle->cafError = handle->cfile->Read(buf, readBufferSize);
1.1107 + if ( handle->cafError != KErrNone)
1.1108 + return -2;
1.1109 + break;
1.1110 + default:
1.1111 + return -1;
1.1112 + }
1.1113 +
1.1114 + if ((mp4_u32)buf.Length() == 0) /* EOF or error */
1.1115 + return -2;
1.1116 +
1.1117 + handle->diskReadBufPos = 0;
1.1118 + handle->diskReadSize = (mp4_u32)buf.Length();
1.1119 + handle->diskReadBufStart = handle->diskReadPos;
1.1120 + handle->diskReadPos += handle->diskReadSize;
1.1121 + }
1.1122 + }
1.1123 +
1.1124 + return 0;
1.1125 +}
1.1126 +
1.1127 +/*
1.1128 + * Function:
1.1129 + *
1.1130 + * mp4_i32 bufferedSeek(MP4HandleImp handle,
1.1131 + * mp4_i32 amount)
1.1132 + *
1.1133 + * Description:
1.1134 + *
1.1135 + * Seek in a buffered file.
1.1136 + *
1.1137 + * Parameters:
1.1138 + *
1.1139 + * handle MP4 library handle
1.1140 + * amount Amount to seek from current position
1.1141 + *
1.1142 + * Return value:
1.1143 + *
1.1144 + * 0 Success
1.1145 + * -1 File has not been opened
1.1146 + * -3 Current position in the file could not be set
1.1147 + *
1.1148 + */
1.1149 +mp4_i32 bufferedSeek(MP4HandleImp handle, mp4_i64 amount)
1.1150 +{
1.1151 + if (!handle->file)
1.1152 + return -1;
1.1153 +
1.1154 + /* Is the new seek point inside the current memory buffer? */
1.1155 + if ((mp4_i32)handle->diskReadBufPos + amount >= 0 &&
1.1156 + handle->diskReadBufPos + amount < handle->diskReadSize)
1.1157 + {
1.1158 + /* Yes */
1.1159 +
1.1160 + handle->diskReadBufPos += amount;
1.1161 + }
1.1162 + else
1.1163 + {
1.1164 + /* No */
1.1165 +
1.1166 + TInt64 am;
1.1167 +
1.1168 +
1.1169 + am = amount - ((mp4_i32)handle->diskReadSize - (mp4_i32)handle->diskReadBufPos);
1.1170 +
1.1171 + if ( handle->rfile )
1.1172 + {
1.1173 + mp4_i64 maxsize = 0;
1.1174 + ((RFile64 *)(handle->rfile))->Size(maxsize);
1.1175 + maxsize -= (mp4_i64)handle->diskReadPos;
1.1176 +
1.1177 + if (am > maxsize)
1.1178 + {
1.1179 + return -3;
1.1180 + }
1.1181 + }
1.1182 + // 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
1.1183 + //coverity[var_compare_op]
1.1184 + else if ( handle->cfile )
1.1185 + {
1.1186 + mp4_i64 maxsize = 0;
1.1187 + TRAPD(caferr, handle->cfile->DataSize64L(maxsize));
1.1188 + maxsize -= (mp4_i64)handle->diskReadPos;
1.1189 +
1.1190 + if (!caferr && am > maxsize)
1.1191 + {
1.1192 + return -3;
1.1193 + }
1.1194 + }
1.1195 +
1.1196 + switch (handle->sourceType)
1.1197 + {
1.1198 + case MP4_SOURCE_RFILE:
1.1199 + {
1.1200 + PRINT((_L("e_bufferedseek_seek_rfile 1")));
1.1201 + if (((RFile64 *)(handle->rfile))->Seek(ESeekCurrent, am) != KErrNone)
1.1202 + {
1.1203 + return -3;
1.1204 + }
1.1205 + PRINT((_L("e_bufferedseek_seek_rfile 0")));
1.1206 + break;
1.1207 + }
1.1208 + case MP4_SOURCE_CAF:
1.1209 + PRINT((_L("e_bufferedseek_seek_cfile 1")));
1.1210 + // See comment on handle->cfile dereference above on why the coverity[] comment below is needed
1.1211 + //coverity[var_deref_model]
1.1212 + handle->cafError = handle->cfile->Seek64(ESeekCurrent, am);
1.1213 + if ( handle->cafError != KErrNone)
1.1214 + return -3;
1.1215 + PRINT((_L("e_bufferedseek_seek_cfile 0")));
1.1216 + break;
1.1217 + default:
1.1218 + return -1;
1.1219 + }
1.1220 +
1.1221 + handle->diskReadPos = handle->diskReadBufStart + handle->diskReadBufPos + amount;
1.1222 + handle->diskReadBufPos = 0;
1.1223 + handle->diskReadBufStart = 0;
1.1224 + handle->diskReadSize = 0;
1.1225 + }
1.1226 +
1.1227 + return 0;
1.1228 +}
1.1229 +
1.1230 +
1.1231 +/*
1.1232 + * Function:
1.1233 + *
1.1234 + * mp4_i32 bufferedSeekAbs(MP4HandleImp handle,
1.1235 + * mp4_i32 amount)
1.1236 + *
1.1237 + * Description:
1.1238 + *
1.1239 + * Seek in a buffered file from the start of the file.
1.1240 + *
1.1241 + * Parameters:
1.1242 + *
1.1243 + * handle MP4 library handle
1.1244 + * amount Amount to seek from start of the file
1.1245 + *
1.1246 + * Return value:
1.1247 + *
1.1248 + * 0 Success
1.1249 + * -1 File has not been opened
1.1250 + * -3 Current position in the file could not be set
1.1251 + *
1.1252 + */
1.1253 +mp4_i32 bufferedSeekAbs(MP4HandleImp handle, mp4_i64 amount)
1.1254 +{
1.1255 + if (!handle->file)
1.1256 + return -1;
1.1257 +
1.1258 + /* Is the new seek point inside the current memory buffer? */
1.1259 + if (handle->diskReadBufStart <= (mp4_u64)amount &&
1.1260 + handle->diskReadBufStart + handle->diskReadSize > (mp4_u64)amount)
1.1261 + {
1.1262 + /* Yes */
1.1263 +
1.1264 + handle->diskReadBufPos = amount - handle->diskReadBufStart;
1.1265 + }
1.1266 + else
1.1267 + {
1.1268 + /* No */
1.1269 +
1.1270 + mp4_i64 am = amount;
1.1271 +
1.1272 + switch (handle->sourceType)
1.1273 + {
1.1274 + case MP4_SOURCE_RFILE:
1.1275 + {
1.1276 + PRINT((_L("e_bufferedseekabs_seek_rfile 1")));
1.1277 + if (((RFile64 *)(handle->rfile))->Seek(ESeekStart, am) != KErrNone)
1.1278 + {
1.1279 + return -3;
1.1280 + }
1.1281 + PRINT((_L("e_bufferedseekabs_seek_rfile 0")));
1.1282 + break;
1.1283 + }
1.1284 + case MP4_SOURCE_CAF:
1.1285 + PRINT((_L("e_bufferedseekabs_seek_cfile 1")));
1.1286 + handle->cafError = handle->cfile->Seek64(ESeekStart, am);
1.1287 + PRINT((_L("e_bufferedseekabs_seek_cfile 0")));
1.1288 + if ( handle->cafError != KErrNone)
1.1289 + return -3;
1.1290 + break;
1.1291 + default:
1.1292 + return -1;
1.1293 + }
1.1294 +
1.1295 + handle->diskReadPos = (mp4_u64)amount;
1.1296 + handle->diskReadBufPos = 0;
1.1297 + handle->diskReadBufStart = 0;
1.1298 + handle->diskReadSize = 0;
1.1299 + }
1.1300 +
1.1301 + return 0;
1.1302 +}
1.1303 +
1.1304 +
1.1305 +/*
1.1306 + * Function:
1.1307 + *
1.1308 + * mp4_i32 bufferedWrite(MP4HandleImp handle,
1.1309 + * mp4_u8 *buffer,
1.1310 + * mp4_u32 bytestowrite)
1.1311 + *
1.1312 + * Description:
1.1313 + *
1.1314 + * Write data into a file in a buffered manner.
1.1315 + *
1.1316 + * Parameters:
1.1317 + *
1.1318 + * handle MP4 library handle
1.1319 + * buffer Buffer containing the data
1.1320 + * bytestowrite Number of bytes to write
1.1321 + *
1.1322 + * Return value:
1.1323 + *
1.1324 + * 0 Success
1.1325 + * -1 File has not been opened
1.1326 + * -2 Number of bytes written is not equal to bytestowrite
1.1327 + *
1.1328 + */
1.1329 +mp4_i32 bufferedWrite(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestowrite)
1.1330 +{
1.1331 + if(handle->bufferWrite)
1.1332 + {
1.1333 + if(handle->bytesProgressed+bytestowrite > *(handle->composedSize))
1.1334 + {
1.1335 + return MP4_OUTPUT_BUFFER_TOO_SMALL; //-1;
1.1336 + }
1.1337 + else
1.1338 + {
1.1339 + mp4memcpy(handle->composeBuffer+handle->bytesProgressed,buffer,bytestowrite);
1.1340 + handle->bytesProgressed+=bytestowrite;
1.1341 + return 0;
1.1342 + }
1.1343 + }
1.1344 +
1.1345 + if (!handle->rfile)
1.1346 + return -1;
1.1347 +
1.1348 + if ( handle->filewriter )
1.1349 + {
1.1350 + TPtrC8 buf = TPtrC8((TUint8 *)(buffer), bytestowrite);
1.1351 + PRINT((_L("e_file_bufferedwrite_write 1")));
1.1352 + if ( (handle->filewriter)->Write( buf ) != KErrNone )
1.1353 + {
1.1354 + return -2;
1.1355 + }
1.1356 + PRINT((_L("e_file_bufferedwrite_write 0")));
1.1357 + }
1.1358 + else
1.1359 + {
1.1360 + return -1;
1.1361 + }
1.1362 +
1.1363 + return 0;
1.1364 +}
1.1365 +
1.1366 +
1.1367 +/*
1.1368 + * Function:
1.1369 + *
1.1370 + * mp4_i32 initMetaDataFiles(MP4HandleImp handle)
1.1371 + *
1.1372 + * Description:
1.1373 + *
1.1374 + * Open temporary files for writing.
1.1375 + *
1.1376 + * Parameters:
1.1377 + *
1.1378 + * handle MP4 library handle
1.1379 + *
1.1380 + * Return value:
1.1381 + *
1.1382 + * 0 Success
1.1383 + * -1 General Error
1.1384 + * MP4_OUT_OF_MEMORY Out of memory
1.1385 + *
1.1386 + */
1.1387 +mp4_i32 initMetaDataFiles(MP4HandleImp handle)
1.1388 +{
1.1389 + PRINT(_L("3GPLib::initMetaDataFiles() in"));
1.1390 + TFileName filename;
1.1391 + TFileName path;
1.1392 + TInt error;
1.1393 +
1.1394 + TDriveList driveList;
1.1395 + TBool pathSet = EFalse;
1.1396 +
1.1397 + // As ram drive access is faster, try to set temp file directory to available ram drive.
1.1398 + if (((RFs *)(handle->fs))->DriveList(driveList) == KErrNone)
1.1399 + {
1.1400 + for ( TInt i = 0; i < driveList.Length(); i++ )
1.1401 + {
1.1402 + TDriveInfo driveInfo;
1.1403 + if (((RFs *)(handle->fs))->Drive(driveInfo, i) == KErrNone)
1.1404 + {
1.1405 + if (driveInfo.iType == EMediaRam)
1.1406 + {
1.1407 + TChar driveLetter;
1.1408 + ((RFs *)(handle->fs))->DriveToChar(i, driveLetter);
1.1409 + path.Append(driveLetter);
1.1410 + path.Append(_L(":"));
1.1411 + path.Append(KTmpDirectoryName);
1.1412 + pathSet = ETrue;
1.1413 + break;
1.1414 + }
1.1415 + }
1.1416 + }
1.1417 + }
1.1418 +
1.1419 + // If no ram drive was found create a directory for the files on current drive
1.1420 + if (!pathSet)
1.1421 + {
1.1422 + if ( handle->fileName )
1.1423 + {
1.1424 + filename = (TText *)handle->fileName;
1.1425 +
1.1426 + TParse fp;
1.1427 + path = KTmpDirectoryName;
1.1428 + if (((RFs *)(handle->fs))->Parse(filename, fp) != KErrNone)
1.1429 + return -1;
1.1430 + path.Insert(0, fp.Drive());
1.1431 + }
1.1432 + else
1.1433 + {
1.1434 + TChar drive;
1.1435 + if (((RFs *)(handle->fs))->DriveToChar(handle->fileHandleDrive, drive ) != KErrNone )
1.1436 + return -1;
1.1437 + path.Append( drive );
1.1438 + path.Append( _L(":") );
1.1439 + path.Append( KTmpDirectoryName );
1.1440 + }
1.1441 + }
1.1442 +
1.1443 + // Try to delete the temp folder from leftovers
1.1444 + // If other instance is using it then delete will just fail
1.1445 + PRINT((_L("e_initmetadatafiles_newl_fileman 1")));
1.1446 + CFileMan* fileMan = 0;
1.1447 + TRAP( error, fileMan = CFileMan::NewL(*(RFs *)(handle->fs)));
1.1448 + if ( error )
1.1449 + {
1.1450 + return -1;
1.1451 + }
1.1452 + PRINT((_L("e_initmetadatafiles_newl_fileman 0")));
1.1453 +
1.1454 + PRINT((_L("e_initmetadatafiles_deletedirectory 1")));
1.1455 + error = fileMan->RmDir( path ); // Delete directory + all files
1.1456 + delete( fileMan );
1.1457 + PRINT((_L("e_initmetadatafiles_deletedirectory 0")));
1.1458 +
1.1459 + error = ((RFs *)(handle->fs))->MkDirAll(path);
1.1460 + if (error != KErrNone && error != KErrAlreadyExists)
1.1461 + return -1;
1.1462 +
1.1463 + ((RFs *)(handle->fs))->SetEntry(path, TTime(0), KEntryAttHidden, NULL);
1.1464 +
1.1465 + // Create files
1.1466 + TFileName metadatafilename;
1.1467 +
1.1468 + for (TUint i = 0; i < NUM_MDF; i++)
1.1469 + {
1.1470 + handle->metaDataFile[i] = (void *)new(RFile64);
1.1471 + if (handle->metaDataFile[i] == NULL)
1.1472 + return MP4_OUT_OF_MEMORY;
1.1473 +
1.1474 + if (((RFile64 *)(handle->metaDataFile[i]))->Temp(*((RFs *)(handle->fs)), path, metadatafilename, EFileWrite | EFileShareExclusive) != KErrNone)
1.1475 + return -1;
1.1476 +
1.1477 + handle->metaDataFileEmpty[i] = EFalse;
1.1478 +
1.1479 + // save file name, used later for deleting
1.1480 + handle->metaDataFileName[i] = (MP4FileName)mp4malloc(2 * wcslen((MP4FileName)metadatafilename.Ptr()) + 2);
1.1481 + if (handle->metaDataFileName[i] == NULL)
1.1482 + return -1;
1.1483 +
1.1484 + wcscat(handle->metaDataFileName[i], (MP4FileName)metadatafilename.Ptr());
1.1485 + handle->metaDataFileName[i][metadatafilename.Length()] = 0;
1.1486 + PRINT((_L("3GPLib::initMetaDataFiles() handle->metaDataFileName[%d]=%s, length=%d "),i, handle->metaDataFileName[i], metadatafilename.Length()));
1.1487 +
1.1488 + }
1.1489 +
1.1490 + PRINT(_L("3GPLib::initMetaDataFiles() creating MetaDataWriter"));
1.1491 + TRAPD(err, handle->metadatafilewriter = CMetaDataFileWriter::NewL());
1.1492 + if ( err != KErrNone )
1.1493 + {
1.1494 + PRINT((_L("3GPLib::initMetaDataFiles() MetaDataWriter creation error: %d"), err));
1.1495 + if ( err == KErrNoMemory )
1.1496 + {
1.1497 + return MP4_OUT_OF_MEMORY;
1.1498 + }
1.1499 + else
1.1500 + {
1.1501 + return -1;
1.1502 + }
1.1503 + }
1.1504 +
1.1505 + PRINT(_L("3GPLib::initMetaDataFiles() MetaDataWriter created"));
1.1506 + PRINT(_L("3GPLib::initMetaDataFiles() out"));
1.1507 + return 0;
1.1508 +}
1.1509 +
1.1510 +
1.1511 +/*
1.1512 + * Function:
1.1513 + *
1.1514 + * mp4_i32 writeMetaDataFileNum(MP4HandleImp handle,
1.1515 + * mp4_u8 *buffer,
1.1516 + * mp4_u32 bytestowrite,
1.1517 + * mp4_u32 filenumber)
1.1518 + *
1.1519 + * Description:
1.1520 + *
1.1521 + * Write data into a numbered file.
1.1522 + *
1.1523 + * Parameters:
1.1524 + *
1.1525 + * handle MP4 library handle
1.1526 + * buffer Buffer containing the data
1.1527 + * bytestowrite Number of bytes to write
1.1528 + * filenumber Index of temporary file
1.1529 + *
1.1530 + * Return value:
1.1531 + *
1.1532 + * 0 Success
1.1533 + * -1 File has not been opened
1.1534 + * -2 Number of bytes written is not equal to bytestowrite
1.1535 + *
1.1536 + */
1.1537 +mp4_i32 writeMetaDataFileNum(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestowrite, mp4_u32 filenumber)
1.1538 +{
1.1539 + PRINT(_L("3GPLib::writeMetaDataFileNum() in"));
1.1540 +
1.1541 + if (!handle->metaDataFile[filenumber])
1.1542 + return -1;
1.1543 +
1.1544 + if ( handle->metadatafilewriter )
1.1545 + {
1.1546 + TPtrC8 buf = TPtrC8((TUint8 *)(buffer), bytestowrite);
1.1547 + PRINT((_L("e_file_writeMetaDataFileNum_write 1")));
1.1548 + if ( (handle->metadatafilewriter)->Write( *((RFile64 *)(handle->metaDataFile[filenumber])),
1.1549 + filenumber,
1.1550 + buf ) != KErrNone )
1.1551 + {
1.1552 + return -2;
1.1553 + }
1.1554 + PRINT((_L("e_file_writeMetaDataFileNum_write 0")));
1.1555 + }
1.1556 + else
1.1557 + {
1.1558 + return -1;
1.1559 + }
1.1560 +
1.1561 + PRINT(_L("3GPLib::writeMetaDataFileNum() out"));
1.1562 + return 0;
1.1563 +}
1.1564 +
1.1565 +
1.1566 +/*
1.1567 + * Function:
1.1568 + *
1.1569 + * mp4_i32 seekMetaDataFileNumAbs(MP4HandleImp handle,
1.1570 + * mp4_i32 amount,
1.1571 + * mp4_u32 filenumber)
1.1572 + *
1.1573 + * Description:
1.1574 + *
1.1575 + * Seek from the beginning of a numbered file.
1.1576 + *
1.1577 + * Parameters:
1.1578 + *
1.1579 + * handle MP4 library handle
1.1580 + * amount Amount to seek from the beginning of the file
1.1581 + * filenumber Index of temporary file
1.1582 + *
1.1583 + * Return value:
1.1584 + *
1.1585 + * 0 Success
1.1586 + * -1 File has not been opened
1.1587 + * -3 Current position in the file could not be set
1.1588 + *
1.1589 + */
1.1590 +mp4_i32 seekMetaDataFileNumAbs(MP4HandleImp handle, mp4_i64 amount, mp4_u32 filenumber)
1.1591 +{
1.1592 + PRINT(_L("3GPLib::seekMetaDataFileNumAbs() in"));
1.1593 +
1.1594 + if (!handle->metaDataFile[filenumber])
1.1595 + return -1;
1.1596 +
1.1597 +
1.1598 + if ( handle->metadatafilewriter )
1.1599 + {
1.1600 + PRINT((_L("e_seekmetadatafilenumabs_flush 1")));
1.1601 + if ( (handle->metadatafilewriter)->Flush() != KErrNone )
1.1602 + {
1.1603 + PRINT((_L("e_seekmetadatafilenumabs_flush 0")));
1.1604 + return -2;
1.1605 + }
1.1606 + PRINT((_L("e_seekmetadatafilenumabs_flush 0")));
1.1607 + }
1.1608 +
1.1609 + PRINT((_L("e_seekmetadatafilenumabs_seek 1")));
1.1610 + if (((RFile64 *)(handle->metaDataFile[filenumber]))->Seek(ESeekStart, amount) != KErrNone)
1.1611 + {
1.1612 + return -3;
1.1613 + }
1.1614 + PRINT((_L("e_seekmetadatafilenumabs_seek 0")));
1.1615 +
1.1616 + PRINT(_L("3GPLib::seekMetaDataFileNumAbs() out"));
1.1617 + return 0;
1.1618 +}
1.1619 +
1.1620 +
1.1621 +/*
1.1622 + * Function:
1.1623 + *
1.1624 + * mp4_i32 readMetaDataFileNum(MP4HandleImp handle,
1.1625 + * mp4_u8 *buffer,
1.1626 + * mp4_u32 bytestoread,
1.1627 + * mp4_u32 filenumber)
1.1628 + *
1.1629 + * Description:
1.1630 + *
1.1631 + * Read data from a numbered file.
1.1632 + *
1.1633 + * Parameters:
1.1634 + *
1.1635 + * handle MP4 library handle
1.1636 + * buffer Buffer to read data into
1.1637 + * bytestoread Number of bytes to read from file
1.1638 + * filenumber Index of temporary file
1.1639 + *
1.1640 + * Return value:
1.1641 + *
1.1642 + * 0 Success
1.1643 + * -1 File has not been opened
1.1644 + * -2 Requested number of bytes could not be read
1.1645 + *
1.1646 + */
1.1647 +mp4_i32 readMetaDataFileNum(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestoread, mp4_u32 filenumber)
1.1648 +{
1.1649 + PRINT(_L("3GPLib::readMetaDataFileNum() in"));
1.1650 + PRINT((_L("e_readmetadatafiles 1")));
1.1651 +
1.1652 + mp4_u32 bytesread = 0;
1.1653 + TPtr8 buf = TPtr8((TUint8 *)buffer, bytestoread);
1.1654 +
1.1655 + if (!handle->metaDataFile[filenumber])
1.1656 + return -1;
1.1657 +
1.1658 + if ( handle->metadatafilewriter )
1.1659 + {
1.1660 + PRINT((_L("e_readmetadatafiles_flush 1")));
1.1661 + if ( (handle->metadatafilewriter)->Flush() != KErrNone )
1.1662 + {
1.1663 + return -2;
1.1664 + }
1.1665 + PRINT((_L("e_readmetadatafiles_flush 0")));
1.1666 + }
1.1667 +
1.1668 + PRINT((_L("e_readmetadatafiles_read 1")));
1.1669 +
1.1670 + if (handle->metaDataFileEmpty[filenumber])
1.1671 + {
1.1672 + if (handle->metadatafilewriter)
1.1673 + {
1.1674 + // if the file is empty, then read the data from temp buffer
1.1675 + bytesread = (handle->metadatafilewriter)->ReadBuffer( filenumber, buf, bytestoread);
1.1676 + }
1.1677 + if ( bytesread != bytestoread )
1.1678 + return -2;
1.1679 + }
1.1680 + else if (((RFile64 *)(handle->metaDataFile[filenumber]))->Read(buf, bytestoread) != KErrNone)
1.1681 + {
1.1682 + handle->metaDataFileEmpty[filenumber] = ETrue;
1.1683 + // if the file is empty, then read the data from temp buffer
1.1684 + if (handle->metadatafilewriter)
1.1685 + {
1.1686 + bytesread = (handle->metadatafilewriter)->ReadBuffer( filenumber, buf, bytestoread);
1.1687 + }
1.1688 + if ( bytesread != bytestoread )
1.1689 + return -2;
1.1690 + }
1.1691 + else if ( buf.Length() < bytestoread ) // Got only part of data from file, rest is in buffer
1.1692 + {
1.1693 + handle->metaDataFileEmpty[filenumber] = ETrue;
1.1694 + // if the file is empty, then read the data from temp buffer
1.1695 + if (handle->metadatafilewriter)
1.1696 + {
1.1697 + bytesread = (handle->metadatafilewriter)->ReadBuffer( filenumber, buf, bytestoread - buf.Length());
1.1698 + }
1.1699 + if ( buf.Length() != bytestoread )
1.1700 + return -2;
1.1701 + }
1.1702 +
1.1703 + PRINT((_L("e_readmetadatafiles_read 0")));
1.1704 +
1.1705 + if ((mp4_u32)buf.Length() == 0) /* EOF or error */
1.1706 + return -2;
1.1707 +
1.1708 + PRINT(_L("3GPLib::readMetaDataFileNum() out"));
1.1709 + PRINT((_L("e_readmetadatafiles 0")));
1.1710 + return 0;
1.1711 +}
1.1712 +
1.1713 +
1.1714 +/*
1.1715 + * Function:
1.1716 + *
1.1717 + * mp4_i32 deleteMetaDataFiles(MP4HandleImp handle)
1.1718 + *
1.1719 + * Description:
1.1720 + *
1.1721 + * Remove a numbered temporary file.
1.1722 + *
1.1723 + * Parameters:
1.1724 + *
1.1725 + * handle MP4 library handle
1.1726 + *
1.1727 + * Return value:
1.1728 + *
1.1729 + * 0 Success
1.1730 + * -1 Error
1.1731 + *
1.1732 + */
1.1733 +mp4_i32 deleteMetaDataFiles(MP4HandleImp handle)
1.1734 +{
1.1735 + PRINT(_L("3GPLib::deleteMetaDataFiles() in"));
1.1736 + PRINT((_L("e_deletemetadatafiles 1")));
1.1737 +
1.1738 + TFileName filename;
1.1739 + TFileName path;
1.1740 + TInt err;
1.1741 +
1.1742 + if ( handle->metadatafilewriter )
1.1743 + {
1.1744 + PRINT((_L("e_deletemetadatafiles_flush 1")));
1.1745 + if ( (handle->metadatafilewriter)->Flush() != KErrNone )
1.1746 + {
1.1747 + PRINT((_L("e_deletemetadatafiles_flush 0")));
1.1748 + return -2;
1.1749 + }
1.1750 + PRINT((_L("e_deletemetadatafiles_flush 0")));
1.1751 + delete handle->metadatafilewriter;
1.1752 + handle->metadatafilewriter = NULL;
1.1753 + }
1.1754 +
1.1755 + /* Determine file names */
1.1756 + PRINT((_L("e_deletemetadatafiles_determinenames 1")));
1.1757 + if ( handle->fileName )
1.1758 + {
1.1759 + filename = (TText *)handle->fileName;
1.1760 + path = KTmpDirectoryName;
1.1761 +
1.1762 + TParse fp;
1.1763 + if (((RFs *)(handle->fs))->Parse(filename, fp) != KErrNone)
1.1764 + return -1;
1.1765 + path.Insert(0, fp.Drive());
1.1766 + }
1.1767 + else
1.1768 + {
1.1769 + TChar drive;
1.1770 + if (((RFs *)(handle->fs))->DriveToChar(handle->fileHandleDrive, drive ) != KErrNone )
1.1771 + return -1;
1.1772 + path.Append( drive );
1.1773 + path.Append( _L(":") );
1.1774 + path.Append( KTmpDirectoryName );
1.1775 + }
1.1776 + PRINT((_L("e_deletemetadatafiles_determinenames 0")));
1.1777 +
1.1778 + PRINT((_L("e_deletemetadatafiles_deletemetadatafilenames 1")));
1.1779 + for (TUint i = 0; i < NUM_MDF; i++)
1.1780 + {
1.1781 + if (handle->metaDataFileName[i])
1.1782 + {
1.1783 + // check if client has defined async delete observer
1.1784 + if ( handle->tempFileRemoverObserver )
1.1785 + {
1.1786 + PRINT((_L("3GPLib::deleteMetaDataFiles() nro=%d sending %x to observer: %s"), i,handle->metaDataFileName[i], handle->metaDataFileName[i]));
1.1787 + handle->tempFileRemoverObserver->M3GPMP4LibDeleteTempFileName( handle->metaDataFileName[i] );
1.1788 + }
1.1789 + else // no observer, delete right here, ignore errors
1.1790 + {
1.1791 + PRINT((_L("3GPLib::deleteMetaDataFiles() nro=%d wremove: %s"), i, handle->metaDataFileName[i]));
1.1792 + err = wremove(handle->metaDataFileName[i]);
1.1793 + PRINT((_L("3GPLib::deleteMetaDataFiles() wremove err=%d"), err));
1.1794 + err++; // to remove compile warnings
1.1795 + mp4free(handle->metaDataFileName[i]);
1.1796 + }
1.1797 + handle->metaDataFileName[i] = 0;
1.1798 + }
1.1799 + PRINT((_L("e_deletemetadatafiles_deletemetadatafilenames 0")));
1.1800 +
1.1801 + }
1.1802 +
1.1803 + PRINT(_L("3GPLib::deleteMetaDataFiles() out"));
1.1804 + PRINT((_L("e_deletemetadatafiles 0")));
1.1805 + return 0;
1.1806 +}
1.1807 +
1.1808 +
1.1809 +/*
1.1810 + * Function:
1.1811 + *
1.1812 + * mp4_i32 closeMetaDataFiles(MP4HandleImp handle)
1.1813 + *
1.1814 + * Description:
1.1815 + *
1.1816 + * Close numbered tmp files.
1.1817 + *
1.1818 + * Parameters:
1.1819 + *
1.1820 + * handle MP4 library handle
1.1821 + *
1.1822 + * Return value:
1.1823 + *
1.1824 + * 0 Success
1.1825 + *
1.1826 + */
1.1827 +mp4_i32 closeMetaDataFiles(MP4HandleImp handle)
1.1828 +{
1.1829 + PRINT(_L("3GPLib::closeMetaDataFiles() in"));
1.1830 + PRINT((_L("e_close_metadatafiles 1")));
1.1831 +
1.1832 + if ( handle->metadatafilewriter )
1.1833 + {
1.1834 + PRINT((_L("e_close_metadatafiles_flush 1")));
1.1835 + if ( (handle->metadatafilewriter)->Flush() != KErrNone )
1.1836 + {
1.1837 + PRINT((_L("e_close_metadatafiles_flush 0")));
1.1838 + return -2;
1.1839 + }
1.1840 + PRINT((_L("e_close_metadatafiles_flush 0")));
1.1841 + }
1.1842 +
1.1843 + for (TUint i = 0; i < NUM_MDF; i++)
1.1844 + {
1.1845 + if (handle->metaDataFile[i])
1.1846 + {
1.1847 + PRINT((_L("e_close_metadatafiles_closefile 1")));
1.1848 + ((RFile64 *)(handle->metaDataFile[i]))->Close();
1.1849 + PRINT((_L("e_close_metadatafiles_closefile 0")));
1.1850 +
1.1851 + PRINT((_L("e_close_metadatafiles_delfile 1")));
1.1852 + delete((RFile64 *)(handle->metaDataFile[i]));
1.1853 + PRINT((_L("e_close_metadatafiles_delfile 0")));
1.1854 + handle->metaDataFile[i] = NULL;
1.1855 + }
1.1856 + }
1.1857 +
1.1858 + PRINT(_L("3GPLib::closeMetaDataFiles() out"));
1.1859 + PRINT((_L("e_close_metadatafiles 0")));
1.1860 + return 0;
1.1861 +}
1.1862 +
1.1863 +
1.1864 +TInt RecommendedBufferSize(MP4HandleImp aHandle)
1.1865 + {
1.1866 + TInt recommendedSize = READBUFSIZE;
1.1867 +
1.1868 + MP4HandleImp handle = (MP4HandleImp)aHandle;
1.1869 + if (handle)
1.1870 + {
1.1871 + // handle->rfile will be set in the cases of
1.1872 + // - MP4ParseOpen(MP4FileName) <if the filename is set>
1.1873 + // - MP4ParseOpenFileHandle64(RFile64)
1.1874 + // - MP4ParseOpenFileHandle(RFile) <via MP4ParseOpenFileHandle64()>
1.1875 + //
1.1876 + // It will not be set by MP4ParseOpenCAF()
1.1877 +
1.1878 + RFs* fs = (RFs*)handle->fs;
1.1879 + RFile64* file64 = (RFile64*)handle->rfile;
1.1880 +
1.1881 + if (fs && file64)
1.1882 + {
1.1883 + TInt driveNumber = 0;
1.1884 + TDriveInfo driveInfo;
1.1885 + TVolumeIOParamInfo volumeInfo;
1.1886 +
1.1887 + TInt err = file64->Drive(driveNumber, driveInfo);
1.1888 + if (err == KErrNone)
1.1889 + {
1.1890 + err = fs->VolumeIOParam(driveNumber, volumeInfo);
1.1891 + }
1.1892 +
1.1893 + if (err == KErrNone)
1.1894 + {
1.1895 + if (volumeInfo.iRecReadBufSize != KErrNotSupported)
1.1896 + {
1.1897 + recommendedSize = Max(recommendedSize, volumeInfo.iRecReadBufSize);
1.1898 + }
1.1899 + }
1.1900 +
1.1901 + }
1.1902 + }
1.1903 +
1.1904 + return recommendedSize;
1.1905 + }
1.1906 +
1.1907 +
1.1908 +// End of File