Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 // -*- c++ -*-
     19 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
     20 
     21 //           P V F I L E
     22 
     23 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
     24 
     25 
     26 /**
     27  * @file pvfile.cpp
     28  * @brief This include file contains the methods to access a file either
     29  *    through Oscl Fil I/O or CPM.
     30  */
     31 
     32 #include "pvfile.h"
     33 #include "pvmf_cpmplugin_access_interface_factory.h"
     34 #include "pvmi_data_stream_interface.h"
     35 
     36 OSCL_EXPORT_REF int32 PVFile::Seek(int32 offset, Oscl_File::seek_type origin)
     37 {
     38     if (iFile)
     39         return iFile->Seek(offset, origin);
     40     else if (iFilePtr)
     41         return iFilePtr->Seek(offset, origin);
     42     else if (iDataStreamAccess)
     43     {
     44         PvmiDataStreamSeekType seekType = PVDS_SEEK_CUR;
     45         if (origin == Oscl_File::SEEKSET)
     46         {
     47             seekType = PVDS_SEEK_SET;
     48         }
     49         if (origin == Oscl_File::SEEKCUR)
     50         {
     51             seekType = PVDS_SEEK_CUR;
     52         }
     53         if (origin == Oscl_File::SEEKEND)
     54         {
     55             seekType = PVDS_SEEK_END;
     56         }
     57         PvmiDataStreamStatus status =
     58             iDataStreamAccess->Seek(iDataStreamSession,
     59                                     offset,
     60                                     seekType);
     61         if (status == PVDS_SUCCESS) return 0;
     62     }
     63     return(-1);//error
     64 }
     65 
     66 OSCL_EXPORT_REF int32 PVFile::Tell()
     67 {
     68     if (iFile)
     69         return (TOsclFileOffsetInt32)iFile->Tell();
     70     else if (iFilePtr)
     71         return (TOsclFileOffsetInt32)iFilePtr->Tell();
     72     else if (iDataStreamAccess)
     73         return (int32)(iDataStreamAccess->GetCurrentPointerPosition(iDataStreamSession));
     74     return (-1);//error
     75 }
     76 
     77 OSCL_EXPORT_REF uint32 PVFile::Read(OsclAny *buffer,
     78                                     uint32 size,
     79                                     uint32 numelements)
     80 {
     81     if (iFile)
     82         return iFile->Read(buffer, size, numelements);
     83     else if (iFilePtr)
     84         return iFilePtr->Read(buffer, size, numelements);
     85     else if (iDataStreamAccess)
     86     {
     87         PvmiDataStreamStatus status =
     88             iDataStreamAccess->Read(iDataStreamSession,
     89                                     (uint8*)(buffer),
     90                                     size,
     91                                     numelements);
     92         if (status == PVDS_SUCCESS)
     93             return (numelements);
     94     }
     95     return 0; //error
     96 }
     97 
     98 OSCL_EXPORT_REF int32 PVFile::Flush()
     99 {
    100     if (iFile)
    101         return iFile->Flush();
    102     else if (iFilePtr)
    103         return iFilePtr->Flush();
    104     else if (iDataStreamAccess)
    105     {
    106         PvmiDataStreamStatus status =
    107             iDataStreamAccess->Flush(iDataStreamSession);
    108 
    109         if (status == PVDS_SUCCESS)
    110             return 0;
    111     }
    112     return (-1); //error
    113 }
    114 
    115 OSCL_EXPORT_REF int32 PVFile::Close()
    116 {
    117     int32 result = -1;
    118     if (iFilePtr)
    119     {
    120         result = -1;//Close should not be called for filePtr access.
    121     }
    122     else if (iDataStreamAccess)
    123     {
    124         iDataStreamAccess->CloseSession(iDataStreamSession);
    125         PVUuid uuid = PVMIDataStreamSyncInterfaceUuid;
    126         iCPMAccessFactory->DestroyPVMFCPMPluginAccessInterface(uuid, iDataStreamAccess);
    127         iDataStreamAccess = NULL;
    128         result = 0;
    129     }
    130     else if (iFile)
    131     {
    132         //if using a file handle, don't actually close the
    133         //file, just flush it.
    134         if (iFileHandle)
    135             result = iFile->Flush();
    136 
    137         // call Close in either case.
    138         result = iFile->Close();
    139 
    140         //delete the file object.
    141         OSCL_DELETE(iFile);
    142         iFile = NULL;
    143     }
    144     Reset(); // Reset all the internal flags
    145     return result;
    146 }
    147 
    148 
    149 OSCL_EXPORT_REF int32 PVFile::Open(const oscl_wchar *filename,
    150                                    uint32 mode,
    151                                    Oscl_FileServer& fileserv)
    152 {
    153     if (iFilePtr)
    154     {
    155         return -1;//Open should not be called for filePtr access.
    156     }
    157     else if (iCPMAccessFactory)
    158     {
    159         if (iDataStreamAccess)
    160             return (-1);//already open!
    161 
    162         //Create an access interface.
    163         PVUuid uuid = PVMIDataStreamSyncInterfaceUuid;
    164         iDataStreamAccess = (PVMIDataStreamSyncInterface*)iCPMAccessFactory->CreatePVMFCPMPluginAccessInterface(uuid);
    165         if (iDataStreamAccess == NULL)
    166         {
    167             return (-1);//error, no access.
    168         }
    169         else
    170         {
    171             // PVFile will have a DataStream Session on one-to-one basis.
    172             // For each DataStream Session we need to have a different PVFile Instance.
    173             PvmiDataStreamRandomAccessType randomAccessType =
    174                 iDataStreamAccess->QueryRandomAccessCapability();
    175             if (randomAccessType == PVDS_FULL_RANDOM_ACCESS)
    176             {
    177                 PvmiDataStreamStatus status = PVDS_FAILURE;
    178                 if (mode & Oscl_File::MODE_READWRITE)
    179                 {
    180                     status =
    181                         iDataStreamAccess->OpenSession(iDataStreamSession,
    182                                                        PVDS_READ_WRITE);
    183                 }
    184                 else if (mode & Oscl_File::MODE_READ)
    185                 {
    186                     status =
    187                         iDataStreamAccess->OpenSession(iDataStreamSession,
    188                                                        PVDS_READ_ONLY);
    189                 }
    190                 else if (mode & Oscl_File::MODE_APPEND)
    191                 {
    192                     status =
    193                         iDataStreamAccess->OpenSession(iDataStreamSession,
    194                                                        PVDS_APPEND);
    195                 }
    196 
    197                 if (status == PVDS_SUCCESS)
    198                 {
    199                     return 0;
    200                 }
    201             }
    202             iCPMAccessFactory->DestroyPVMFCPMPluginAccessInterface(uuid, OSCL_STATIC_CAST(PVInterface*, iDataStreamAccess));
    203             iDataStreamAccess = NULL;
    204             return -1;
    205         }
    206     }
    207     //otherwise open the content using Oscl File I/O.
    208     else
    209     {
    210         if (iFile)
    211             return (-1); //already open!
    212 
    213         //Create an Oscl_File object for accessing the file, using
    214         //the optional external file handle.
    215 
    216         iFile = OSCL_NEW(Oscl_File, (iOsclFileCacheParams.iCacheSize, iFileHandle));
    217         if (!iFile)
    218             return (-1);//nonzero indicates error.
    219 
    220         // If a filehandle is provided, assume the file is already opened
    221         // (but still call Oscl_File::Open() with an arbitrary filename, since
    222         // otherwise it won't be initialized correctly. This filename will
    223         // be ignored and the handle will be used instead),
    224         // Otherwise, open it using its filename.
    225 
    226         int32 result;
    227         if (iFileHandle)
    228             result =  iFile->Open("", mode, fileserv);
    229         else
    230         {
    231             iFile->SetAsyncReadBufferSize(iOsclFileCacheParams.iAsyncReadBuffSize);
    232             iFile->SetLoggingEnable(iOsclFileCacheParams.iPVLoggerEnableFlag);
    233 
    234 
    235             iFile->SetPVCacheSize(iOsclFileCacheParams.iCacheSize);
    236 
    237 
    238             iFile->SetSummaryStatsLoggingEnable(iOsclFileCacheParams.iPVLoggerStateEnableFlag);
    239             result = iFile->Open(filename, mode, fileserv);
    240         }
    241 
    242         //If open failed, cleanup the file object
    243         if (result != 0)
    244         {
    245             OSCL_DELETE(iFile);
    246             iFile = NULL;
    247         }
    248         return result;
    249     }
    250 }
    251 
    252 OSCL_EXPORT_REF bool PVFile::GetRemainingBytes(uint32& aNumBytes)
    253 {
    254     bool result = false;
    255     if (iFile)
    256     {
    257         uint32 currPos = (uint32)(iFile->Tell());
    258 
    259         if (iFileSizeAvailable == false)
    260         {
    261             iFile->Seek(0, Oscl_File::SEEKEND);
    262             iFileSize = (uint32)(iFile->Tell());
    263             iFile->Seek(currPos, Oscl_File::SEEKSET);
    264             iFileSizeAvailable = true;
    265         }
    266         if (currPos <= iFileSize)
    267         {
    268             aNumBytes = (iFileSize - currPos);
    269             result = true;
    270         }
    271     }
    272     else if (iFilePtr)
    273     {
    274         uint32 currPos = (uint32)(iFilePtr->Tell());
    275 
    276         if (iFileSizeAvailable == false)
    277         {
    278             iFilePtr->Seek(currPos, Oscl_File::SEEKSET);
    279             iFileSize = (uint32)(iFilePtr->Size());
    280             iFileSizeAvailable = true;
    281         }
    282         if (currPos <= iFileSize)
    283         {
    284             aNumBytes = (iFileSize - currPos);
    285             result = true;
    286         }
    287     }
    288     else if (iDataStreamAccess)
    289     {
    290         PvmiDataStreamStatus status =
    291             iDataStreamAccess->QueryReadCapacity(iDataStreamSession, aNumBytes);
    292         if ((status == PVDS_SUCCESS) || (status == PVDS_END_OF_STREAM))
    293         {
    294             result = true;
    295         }
    296     }
    297     return result;
    298 }
    299 
    300 OSCL_EXPORT_REF bool
    301 PVFile::RequestReadCapacityNotification(PvmiDataStreamObserver& aObserver,
    302                                         uint32 aCapacity,
    303                                         OsclAny* aContextData)
    304 {
    305     if (iDataStreamAccess)
    306     {
    307         int32 errcode = 0;
    308         OSCL_TRY(errcode,
    309                  iRequestReadCapacityNotificationID =
    310                      iDataStreamAccess->RequestReadCapacityNotification(iDataStreamSession,
    311                              aObserver,
    312                              aCapacity,
    313                              aContextData)
    314                 );
    315         OSCL_FIRST_CATCH_ANY(errcode, return false);
    316 
    317         return true;
    318     }
    319     return false;
    320 }
    321 
    322 OSCL_EXPORT_REF uint32
    323 PVFile::GetContentLength()
    324 {
    325     // content length
    326     uint32 fileSize = 0;
    327     if (iDataStreamAccess)
    328     {
    329         fileSize = iDataStreamAccess->GetContentLength();
    330     }
    331 
    332     return fileSize;
    333 }
    334 
    335 
    336 OSCL_EXPORT_REF uint32
    337 PVFile::GetFileBufferingCapacity()
    338 {
    339     // size of cache
    340     uint32 bufferSize = 0;
    341     if (iDataStreamAccess)
    342     {
    343         bufferSize = iDataStreamAccess->QueryBufferingCapacity();
    344     }
    345 
    346     return bufferSize;
    347 }
    348 
    349 OSCL_EXPORT_REF bool
    350 PVFile::MakePersistent(int32 offset, uint32 size)
    351 {
    352     PvmiDataStreamStatus status = PVDS_FAILURE;
    353     if (iDataStreamAccess)
    354     {
    355         status = iDataStreamAccess->MakePersistent(offset, size);
    356     }
    357 
    358     if (PVDS_SUCCESS == status)
    359     {
    360         return true;
    361     }
    362 
    363     return false;
    364 }
    365 
    366 OSCL_EXPORT_REF bool
    367 PVFile::CancelNotificationSync()
    368 {
    369     if (iDataStreamAccess)
    370     {
    371         PvmiDataStreamStatus status = iDataStreamAccess->CancelNotificationSync(iDataStreamSession);
    372 
    373         if (status == PVDS_SUCCESS)
    374             return true;
    375     }
    376     return false;
    377 }
    378 
    379 OSCL_EXPORT_REF int32
    380 PVFile::Skip(int32 offset, Oscl_File::seek_type origin)
    381 {
    382     if (iDataStreamAccess)
    383     {
    384         PvmiDataStreamSeekType seekType = PVDS_SEEK_CUR;
    385         if (origin == Oscl_File::SEEKSET)
    386         {
    387             seekType = PVDS_SKIP_SET;
    388         }
    389         if (origin == Oscl_File::SEEKCUR)
    390         {
    391             seekType = PVDS_SKIP_CUR;
    392         }
    393         if (origin == Oscl_File::SEEKEND)
    394         {
    395             seekType = PVDS_SKIP_END;
    396         }
    397         PvmiDataStreamStatus status = iDataStreamAccess->Seek(iDataStreamSession,
    398                                       offset, seekType);
    399         if (status == PVDS_SUCCESS) return 0;
    400     }
    401     return (-1);//error
    402 }
    403 
    404 
    405 OSCL_EXPORT_REF void
    406 PVFile::GetCurrentByteRange(uint32& aCurrentFirstByteOffset, uint32& aCurrentLastByteOffset)
    407 {
    408     aCurrentFirstByteOffset = 0;
    409     aCurrentLastByteOffset = 0;
    410 
    411     if (iDataStreamAccess)
    412     {
    413         iDataStreamAccess->GetCurrentByteRange(aCurrentFirstByteOffset, aCurrentLastByteOffset);
    414     }
    415 }
    416 
    417