blob: 4a6a447a40309503d810fede0a3f0f18470c42e6 [file] [log] [blame]
/* ------------------------------------------------------------------
* Copyright (C) 1998-2009 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied.
* See the License for the specific language governing permissions
* and limitations under the License.
* -------------------------------------------------------------------
*/
// -*- c++ -*-
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// P V F I L E
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
/**
* @file pvfile.cpp
* @brief This include file contains the methods to access a file either
* through Oscl Fil I/O or CPM.
*/
#include "pvfile.h"
#include "pvmf_cpmplugin_access_interface_factory.h"
#include "pvmi_data_stream_interface.h"
OSCL_EXPORT_REF int32 PVFile::Seek(int32 offset, Oscl_File::seek_type origin)
{
if (iFile)
return iFile->Seek(offset, origin);
else if (iFilePtr)
return iFilePtr->Seek(offset, origin);
else if (iDataStreamAccess)
{
PvmiDataStreamSeekType seekType = PVDS_SEEK_CUR;
if (origin == Oscl_File::SEEKSET)
{
seekType = PVDS_SEEK_SET;
}
if (origin == Oscl_File::SEEKCUR)
{
seekType = PVDS_SEEK_CUR;
}
if (origin == Oscl_File::SEEKEND)
{
seekType = PVDS_SEEK_END;
}
PvmiDataStreamStatus status =
iDataStreamAccess->Seek(iDataStreamSession,
offset,
seekType);
if (status == PVDS_SUCCESS) return 0;
}
return(-1);//error
}
OSCL_EXPORT_REF int32 PVFile::Tell()
{
if (iFile)
return (TOsclFileOffsetInt32)iFile->Tell();
else if (iFilePtr)
return (TOsclFileOffsetInt32)iFilePtr->Tell();
else if (iDataStreamAccess)
return (int32)(iDataStreamAccess->GetCurrentPointerPosition(iDataStreamSession));
return (-1);//error
}
OSCL_EXPORT_REF uint32 PVFile::Read(OsclAny *buffer,
uint32 size,
uint32 numelements)
{
if (iFile)
return iFile->Read(buffer, size, numelements);
else if (iFilePtr)
return iFilePtr->Read(buffer, size, numelements);
else if (iDataStreamAccess)
{
PvmiDataStreamStatus status =
iDataStreamAccess->Read(iDataStreamSession,
(uint8*)(buffer),
size,
numelements);
if (status == PVDS_SUCCESS)
return (numelements);
}
return 0; //error
}
OSCL_EXPORT_REF int32 PVFile::Flush()
{
if (iFile)
return iFile->Flush();
else if (iFilePtr)
return iFilePtr->Flush();
else if (iDataStreamAccess)
{
PvmiDataStreamStatus status =
iDataStreamAccess->Flush(iDataStreamSession);
if (status == PVDS_SUCCESS)
return 0;
}
return (-1); //error
}
OSCL_EXPORT_REF int32 PVFile::Close()
{
int32 result = -1;
if (iFilePtr)
{
result = -1;//Close should not be called for filePtr access.
}
else if (iDataStreamAccess)
{
iDataStreamAccess->CloseSession(iDataStreamSession);
PVUuid uuid = PVMIDataStreamSyncInterfaceUuid;
iCPMAccessFactory->DestroyPVMFCPMPluginAccessInterface(uuid, iDataStreamAccess);
iDataStreamAccess = NULL;
result = 0;
}
else if (iFile)
{
//if using a file handle, don't actually close the
//file, just flush it.
if (iFileHandle)
result = iFile->Flush();
// call Close in either case.
result = iFile->Close();
//delete the file object.
OSCL_DELETE(iFile);
iFile = NULL;
}
Reset(); // Reset all the internal flags
return result;
}
OSCL_EXPORT_REF int32 PVFile::Open(const oscl_wchar *filename,
uint32 mode,
Oscl_FileServer& fileserv)
{
if (iFilePtr)
{
return -1;//Open should not be called for filePtr access.
}
else if (iCPMAccessFactory)
{
if (iDataStreamAccess)
return (-1);//already open!
//Create an access interface.
PVUuid uuid = PVMIDataStreamSyncInterfaceUuid;
iDataStreamAccess = (PVMIDataStreamSyncInterface*)iCPMAccessFactory->CreatePVMFCPMPluginAccessInterface(uuid);
if (iDataStreamAccess == NULL)
{
return (-1);//error, no access.
}
else
{
// PVFile will have a DataStream Session on one-to-one basis.
// For each DataStream Session we need to have a different PVFile Instance.
PvmiDataStreamRandomAccessType randomAccessType =
iDataStreamAccess->QueryRandomAccessCapability();
if (randomAccessType == PVDS_FULL_RANDOM_ACCESS)
{
PvmiDataStreamStatus status = PVDS_FAILURE;
if (mode & Oscl_File::MODE_READWRITE)
{
status =
iDataStreamAccess->OpenSession(iDataStreamSession,
PVDS_READ_WRITE);
}
else if (mode & Oscl_File::MODE_READ)
{
status =
iDataStreamAccess->OpenSession(iDataStreamSession,
PVDS_READ_ONLY);
}
else if (mode & Oscl_File::MODE_APPEND)
{
status =
iDataStreamAccess->OpenSession(iDataStreamSession,
PVDS_APPEND);
}
if (status == PVDS_SUCCESS)
{
return 0;
}
}
iCPMAccessFactory->DestroyPVMFCPMPluginAccessInterface(uuid, OSCL_STATIC_CAST(PVInterface*, iDataStreamAccess));
iDataStreamAccess = NULL;
return -1;
}
}
//otherwise open the content using Oscl File I/O.
else
{
if (iFile)
return (-1); //already open!
//Create an Oscl_File object for accessing the file, using
//the optional external file handle.
iFile = OSCL_NEW(Oscl_File, (iOsclFileCacheParams.iCacheSize, iFileHandle));
if (!iFile)
return (-1);//nonzero indicates error.
// If a filehandle is provided, assume the file is already opened
// (but still call Oscl_File::Open() with an arbitrary filename, since
// otherwise it won't be initialized correctly. This filename will
// be ignored and the handle will be used instead),
// Otherwise, open it using its filename.
int32 result;
if (iFileHandle)
result = iFile->Open("", mode, fileserv);
else
{
iFile->SetAsyncReadBufferSize(iOsclFileCacheParams.iAsyncReadBuffSize);
iFile->SetLoggingEnable(iOsclFileCacheParams.iPVLoggerEnableFlag);
iFile->SetPVCacheSize(iOsclFileCacheParams.iCacheSize);
iFile->SetSummaryStatsLoggingEnable(iOsclFileCacheParams.iPVLoggerStateEnableFlag);
result = iFile->Open(filename, mode, fileserv);
}
//If open failed, cleanup the file object
if (result != 0)
{
OSCL_DELETE(iFile);
iFile = NULL;
}
return result;
}
}
OSCL_EXPORT_REF bool PVFile::GetRemainingBytes(uint32& aNumBytes)
{
bool result = false;
if (iFile)
{
uint32 currPos = (uint32)(iFile->Tell());
if (iFileSizeAvailable == false)
{
iFile->Seek(0, Oscl_File::SEEKEND);
iFileSize = (uint32)(iFile->Tell());
iFile->Seek(currPos, Oscl_File::SEEKSET);
iFileSizeAvailable = true;
}
if (currPos <= iFileSize)
{
aNumBytes = (iFileSize - currPos);
result = true;
}
}
else if (iFilePtr)
{
uint32 currPos = (uint32)(iFilePtr->Tell());
if (iFileSizeAvailable == false)
{
iFilePtr->Seek(currPos, Oscl_File::SEEKSET);
iFileSize = (uint32)(iFilePtr->Size());
iFileSizeAvailable = true;
}
if (currPos <= iFileSize)
{
aNumBytes = (iFileSize - currPos);
result = true;
}
}
else if (iDataStreamAccess)
{
PvmiDataStreamStatus status =
iDataStreamAccess->QueryReadCapacity(iDataStreamSession, aNumBytes);
if ((status == PVDS_SUCCESS) || (status == PVDS_END_OF_STREAM))
{
result = true;
}
}
return result;
}
OSCL_EXPORT_REF bool
PVFile::RequestReadCapacityNotification(PvmiDataStreamObserver& aObserver,
uint32 aCapacity,
OsclAny* aContextData)
{
if (iDataStreamAccess)
{
int32 errcode = 0;
OSCL_TRY(errcode,
iRequestReadCapacityNotificationID =
iDataStreamAccess->RequestReadCapacityNotification(iDataStreamSession,
aObserver,
aCapacity,
aContextData)
);
OSCL_FIRST_CATCH_ANY(errcode, return false);
return true;
}
return false;
}
OSCL_EXPORT_REF uint32
PVFile::GetContentLength()
{
// content length
uint32 fileSize = 0;
if (iDataStreamAccess)
{
fileSize = iDataStreamAccess->GetContentLength();
}
return fileSize;
}
OSCL_EXPORT_REF uint32
PVFile::GetFileBufferingCapacity()
{
// size of cache
uint32 bufferSize = 0;
if (iDataStreamAccess)
{
bufferSize = iDataStreamAccess->QueryBufferingCapacity();
}
return bufferSize;
}
OSCL_EXPORT_REF bool
PVFile::MakePersistent(int32 offset, uint32 size)
{
PvmiDataStreamStatus status = PVDS_FAILURE;
if (iDataStreamAccess)
{
status = iDataStreamAccess->MakePersistent(offset, size);
}
if (PVDS_SUCCESS == status)
{
return true;
}
return false;
}
OSCL_EXPORT_REF bool
PVFile::CancelNotificationSync()
{
if (iDataStreamAccess)
{
PvmiDataStreamStatus status = iDataStreamAccess->CancelNotificationSync(iDataStreamSession);
if (status == PVDS_SUCCESS)
return true;
}
return false;
}
OSCL_EXPORT_REF int32
PVFile::Skip(int32 offset, Oscl_File::seek_type origin)
{
if (iDataStreamAccess)
{
PvmiDataStreamSeekType seekType = PVDS_SEEK_CUR;
if (origin == Oscl_File::SEEKSET)
{
seekType = PVDS_SKIP_SET;
}
if (origin == Oscl_File::SEEKCUR)
{
seekType = PVDS_SKIP_CUR;
}
if (origin == Oscl_File::SEEKEND)
{
seekType = PVDS_SKIP_END;
}
PvmiDataStreamStatus status = iDataStreamAccess->Seek(iDataStreamSession,
offset, seekType);
if (status == PVDS_SUCCESS) return 0;
}
return (-1);//error
}
OSCL_EXPORT_REF void
PVFile::GetCurrentByteRange(uint32& aCurrentFirstByteOffset, uint32& aCurrentLastByteOffset)
{
aCurrentFirstByteOffset = 0;
aCurrentLastByteOffset = 0;
if (iDataStreamAccess)
{
iDataStreamAccess->GetCurrentByteRange(aCurrentFirstByteOffset, aCurrentLastByteOffset);
}
}