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