1 /* 2 * Copyright (C) 2011 The Android Open Source Project 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 express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 /** 17 ************************************************************************ 18 * @file M4OSA_FileCommon.c 19 * @brief File common for Android 20 * @note This file implements functions used by both the file writer 21 * and file reader. 22 ************************************************************************ 23 */ 24 25 #ifndef USE_STAGEFRIGHT_CODECS 26 #error "USE_STAGEFRIGHT_CODECS is not defined" 27 #endif /*USE_STAGEFRIGHT_CODECS*/ 28 29 #ifdef UTF_CONVERSION 30 #include <string.h> 31 #endif /*UTF_CONVERSION*/ 32 33 #include <sys/stat.h> 34 #include <errno.h> 35 36 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE 37 #include "M4OSA_Semaphore.h" 38 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */ 39 40 41 #include "M4OSA_Debug.h" 42 #include "M4OSA_FileCommon.h" 43 #include "M4OSA_FileCommon_priv.h" 44 #include "M4OSA_Memory.h" 45 #include "M4OSA_CharStar.h" 46 47 /** 48 ************************************************************************ 49 * @brief This function opens the provided URL and returns its context. 50 * If an error occured, the context is set to NULL. 51 * @param core_id: (IN) Core ID of the caller (M4OSA_FILE_READER or M4OSA_FILE_WRITER) 52 * @param context: (OUT) Context of the core file reader 53 * @param url: (IN) URL of the input file 54 * @param fileModeAccess: (IN) File mode access 55 * @return M4NO_ERROR: there is no error 56 * @return M4ERR_PARAMETER: at least one parameter is NULL 57 * @return M4ERR_ALLOC: there is no more memory available 58 * @return M4ERR_NOT_IMPLEMENTED: the URL does not match with the supported 59 * file 60 * @return M4ERR_FILE_NOT_FOUND: the file cannot be found 61 * @return M4ERR_FILE_LOCKED: the file is locked by an other 62 * application/process 63 * @return M4ERR_FILE_BAD_MODE_ACCESS: the file mode access is not correct 64 ************************************************************************ 65 */ 66 M4OSA_ERR M4OSA_fileCommonOpen(M4OSA_UInt16 core_id, M4OSA_Context* pContext, 67 M4OSA_Char* pUrl, M4OSA_FileModeAccess fileModeAccess) 68 { 69 70 M4OSA_Int32 i = 0; 71 M4OSA_Int32 iMode = 0; 72 M4OSA_Int32 iSize = 0; 73 M4OSA_Int32 iSavePos = 0; 74 75 M4OSA_Char mode[4] = ""; 76 M4OSA_Char* pReadString = (M4OSA_Char*)"r"; 77 M4OSA_Char* pWriteString = (M4OSA_Char*)"w"; 78 M4OSA_Char* pAppendString = (M4OSA_Char*)"a"; 79 M4OSA_Char* pBinaryString = (M4OSA_Char*)"b"; 80 M4OSA_Char* pPlusString = (M4OSA_Char*)"+"; 81 82 M4OSA_ERR err = M4NO_ERROR; 83 84 FILE* pFileHandler = M4OSA_NULL; 85 M4OSA_FileContext *pFileContext = M4OSA_NULL; 86 87 88 #ifdef UTF_CONVERSION 89 /*FB: to test the UTF16->UTF8 conversion into Video Artist*/ 90 /*Convert the URL from UTF16 to UTF8*/ 91 M4OSA_Void* tempConversionBuf; 92 M4OSA_UInt32 tempConversionSize = 1000; 93 94 tempConversionBuf = (M4OSA_Char*)M4OSA_32bitAlignedMalloc(tempConversionSize +1, 0, "conversion buf"); 95 if(tempConversionBuf == M4OSA_NULL) 96 { 97 M4OSA_TRACE1_0("Error when allocating conversion buffer\n"); 98 return M4ERR_PARAMETER; 99 } 100 M4OSA_ToUTF8_OSAL(pUrl, tempConversionBuf, &tempConversionSize); 101 ((M4OSA_Char*)tempConversionBuf)[tempConversionSize ] = '\0'; 102 103 printf("file open %s\n", tempConversionBuf); 104 #endif /*UTF CONVERSION*/ 105 106 M4OSA_TRACE3_4("M4OSA_fileCommonOpen\t\tM4OSA_UInt16 %d\tM4OSA_Context* 0x%x\t" 107 "M4OSA_Char* %s\tfileModeAccess %d", core_id, pContext, pUrl, fileModeAccess); 108 109 M4OSA_DEBUG_IF2(M4OSA_NULL == pContext, M4ERR_PARAMETER, "M4OSA_fileCommonOpen: pContext is M4OSA_NULL"); 110 M4OSA_DEBUG_IF2(M4OSA_NULL == pUrl, M4ERR_PARAMETER, "M4OSA_fileCommonOpen: pUrl is M4OSA_NULL"); 111 M4OSA_DEBUG_IF2(0 == fileModeAccess, M4ERR_PARAMETER, "M4OSA_fileCommonOpen: fileModeAccess is 0"); 112 113 /* Read mode not set for the reader */ 114 M4OSA_DEBUG_IF1((M4OSA_FILE_READER == core_id) && !(fileModeAccess & M4OSA_kFileRead), 115 M4ERR_FILE_BAD_MODE_ACCESS, "M4OSA_fileCommonOpen: M4OSA_kFileRead"); 116 117 /* Read mode not set for the reader */ 118 M4OSA_DEBUG_IF1((M4OSA_FILE_READER == core_id) && !(fileModeAccess & M4OSA_kFileRead), 119 M4ERR_FILE_BAD_MODE_ACCESS, "M4OSA_fileCommonOpen: M4OSA_kFileRead"); 120 121 /* M4OSAfileReadOpen cannot be used with Write file mode access */ 122 M4OSA_DEBUG_IF1((M4OSA_FILE_READER == core_id) && (fileModeAccess & M4OSA_kFileWrite), 123 M4ERR_FILE_BAD_MODE_ACCESS, "M4OSA_fileCommonOpen: M4OSA_kFileWrite"); 124 125 /* Append and Create flags cannot be used with Read */ 126 M4OSA_DEBUG_IF1((M4OSA_FILE_READER == core_id) && (fileModeAccess & M4OSA_kFileAppend), 127 M4ERR_FILE_BAD_MODE_ACCESS, "M4OSA_fileCommonOpen: M4OSA_kFileAppend"); 128 129 M4OSA_DEBUG_IF1((M4OSA_FILE_READER == core_id) && (fileModeAccess & M4OSA_kFileCreate), 130 M4ERR_FILE_BAD_MODE_ACCESS, "M4OSA_fileCommonOpen: M4OSA_kFileCreate"); 131 132 /* Write mode not set for the writer */ 133 M4OSA_DEBUG_IF1((M4OSA_FILE_WRITER == core_id) && !(fileModeAccess & M4OSA_kFileWrite), 134 M4ERR_FILE_BAD_MODE_ACCESS, "M4OSA_fileCommonOpen: M4OSA_kFileWrite"); 135 136 /* Create flag necessary for opening file */ 137 if ((fileModeAccess & M4OSA_kFileRead) && 138 (fileModeAccess & M4OSA_kFileWrite)&&(fileModeAccess & M4OSA_kFileCreate)) 139 { 140 strncat((char *)mode, (const char *)pWriteString, (size_t)1); 141 strncat((char *)mode, (const char *)pPlusString, (size_t)1); 142 } 143 else 144 { 145 if(fileModeAccess & M4OSA_kFileAppend) 146 { 147 strncat((char *)mode, (const char *)pAppendString, (size_t)1); 148 } 149 else if(fileModeAccess & M4OSA_kFileRead) 150 { 151 strncat((char *)mode, (const char *)pReadString, (size_t)1); 152 } 153 else if(fileModeAccess & M4OSA_kFileWrite) 154 { 155 strncat((char *)mode, (const char *)pWriteString, (size_t)1); 156 } 157 158 if((fileModeAccess & M4OSA_kFileRead)&&(fileModeAccess & M4OSA_kFileWrite)) 159 { 160 strncat((char *)mode,(const char *)pPlusString, (size_t)1); 161 } 162 } 163 164 if(!(fileModeAccess & M4OSA_kFileIsTextMode)) 165 { 166 strncat((char *)mode, (const char *)pBinaryString,(size_t)1); 167 } 168 169 /*Open the file*/ 170 171 #ifdef UTF_CONVERSION 172 /*Open the converted path*/ 173 pFileHandler = fopen((const char *)tempConversionBuf, (const char *)mode); 174 /*Free the temporary decoded buffer*/ 175 free(tempConversionBuf); 176 #else /* UTF_CONVERSION */ 177 pFileHandler = fopen((const char *)pUrl, (const char *)mode); 178 #endif /* UTF_CONVERSION */ 179 180 if (M4OSA_NULL == pFileHandler) 181 { 182 switch(errno) 183 { 184 case ENOENT: 185 { 186 M4OSA_DEBUG(M4ERR_FILE_NOT_FOUND, "M4OSA_fileCommonOpen: No such file or directory"); 187 M4OSA_TRACE1_1("File not found: %s", pUrl); 188 return M4ERR_FILE_NOT_FOUND; 189 } 190 case EACCES: 191 { 192 M4OSA_DEBUG(M4ERR_FILE_LOCKED, "M4OSA_fileCommonOpen: Permission denied"); 193 return M4ERR_FILE_LOCKED; 194 } 195 case EINVAL: 196 { 197 M4OSA_DEBUG(M4ERR_FILE_BAD_MODE_ACCESS, "M4OSA_fileCommonOpen: Invalid Argument"); 198 return M4ERR_FILE_BAD_MODE_ACCESS; 199 } 200 case EMFILE: 201 case ENOSPC: 202 case ENOMEM: 203 { 204 M4OSA_DEBUG(M4ERR_ALLOC, "M4OSA_fileCommonOpen: Too many open files"); 205 return M4ERR_ALLOC; 206 } 207 default: 208 { 209 M4OSA_DEBUG(M4ERR_NOT_IMPLEMENTED, "M4OSA_fileCommonOpen"); 210 return M4ERR_NOT_IMPLEMENTED; 211 } 212 } 213 } 214 215 /* Allocate the file context */ 216 pFileContext = (M4OSA_FileContext*) M4OSA_32bitAlignedMalloc(sizeof(M4OSA_FileContext), 217 core_id, (M4OSA_Char*)"M4OSA_fileCommonOpen: file context"); 218 if (M4OSA_NULL == pFileContext) 219 { 220 fclose(pFileHandler); 221 M4OSA_DEBUG(M4ERR_ALLOC, "M4OSA_fileCommonOpen"); 222 return M4ERR_ALLOC; 223 } 224 225 pFileContext->file_desc = pFileHandler; 226 pFileContext->access_mode = fileModeAccess; 227 pFileContext->current_seek = SeekNone; 228 pFileContext->b_is_end_of_file = M4OSA_FALSE; 229 230 /** 231 * Note: Never use this expression "i = (value1 == value2) ? x: y;" 232 * because that doens't compile on other platforms (ADS for example) 233 * Use: if(value1 == value2) 234 * { i= x; ..etc 235 */ 236 pFileContext->coreID_write = 0; 237 pFileContext->coreID_read = 0; 238 pFileContext->m_DescrModeAccess = M4OSA_kDescNoneAccess; 239 240 if (M4OSA_FILE_READER == core_id) 241 { 242 pFileContext->coreID_read = core_id; 243 pFileContext->m_DescrModeAccess = M4OSA_kDescReadAccess; 244 } 245 else if (M4OSA_FILE_WRITER == core_id) 246 { 247 pFileContext->coreID_write = core_id; 248 pFileContext->m_DescrModeAccess = M4OSA_kDescWriteAccess; 249 } 250 251 pFileContext->read_position = 0; 252 pFileContext->write_position = 0; 253 254 /* Allocate the memory to store the URL string */ 255 pFileContext->url_name = (M4OSA_Char*) M4OSA_32bitAlignedMalloc(strlen((const char *)pUrl)+1, 256 core_id, (M4OSA_Char*)"M4OSA_fileCommonOpen: URL name"); 257 if (M4OSA_NULL == pFileContext->url_name) 258 { 259 fclose(pFileHandler); 260 free(pFileContext); 261 M4OSA_DEBUG(M4ERR_ALLOC, "M4OSA_fileCommonOpen"); 262 return M4ERR_ALLOC; 263 } 264 M4OSA_chrNCopy(pFileContext->url_name, pUrl, strlen((const char *)pUrl)+1); 265 266 /* Get the file name */ 267 err = M4OSA_fileCommonGetFilename(pUrl, &pFileContext->file_name); 268 if(M4NO_ERROR != err) 269 { 270 fclose(pFileHandler); 271 free(pFileContext->url_name); 272 free(pFileContext); 273 M4OSA_DEBUG(err, "M4OSA_fileCommonOpen"); 274 return err; 275 } 276 277 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE 278 M4OSA_semaphoreOpen(&(pFileContext->semaphore_context), 1); /* Allocate the semaphore */ 279 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */ 280 281 282 283 #ifdef USE_STAGEFRIGHT_CODECS 284 // Workaround for file system bug on Stingray/Honeycomb where a file re-created will keep 285 // the original file's size filled with 0s. Do not seek to the end to avoid ill effects 286 if(fileModeAccess & M4OSA_kFileAppend) { 287 /* Get the file size */ 288 iSavePos = ftell(pFileHandler); /* 1- Check the first position */ 289 fseek(pFileHandler, 0, SEEK_END); /* 2- Go to the end of the file*/ 290 iSize = ftell(pFileHandler); /* 3- Check the file size */ 291 fseek(pFileHandler, iSavePos, SEEK_SET);/* 4- go to the first position */ 292 } else { 293 iSize = 0; 294 } 295 #else /* USE_STAGEFRIGHT_CODECS */ 296 /* Get the file size */ 297 iSavePos = ftell(pFileHandler); /* 1- Check the first position */ 298 fseek(pFileHandler, 0, SEEK_END); /* 2- Go to the end of the file*/ 299 iSize = ftell(pFileHandler); /* 3- Check the file size */ 300 fseek(pFileHandler, iSavePos, SEEK_SET);/* 4- go to the first position */ 301 #endif /* USE_STAGEFRIGHT_CODECS */ 302 303 304 305 /* Warning possible overflow if the file is higher than 2GBytes */ 306 pFileContext->file_size = iSize; 307 308 *pContext = pFileContext; 309 310 return M4NO_ERROR; 311 } 312 313 314 /** 315 ************************************************************************ 316 * @brief This function convert from UTF16 to UTF8 317 * @param pBufferIn: (IN) UTF16 input path 318 * @param pBufferOut: (OUT) UTF8 output path 319 * @param bufferOutSize: (IN/OUT) size of the output path 320 * @return M4NO_ERROR: there is no error 321 * @return M4ERR_PARAMETER: the output path size is not enough to contain 322 * the decoded path 323 ************************************************************************ 324 */ 325 #ifdef UTF_CONVERSION 326 M4OSA_ERR M4OSA_ToUTF8_OSAL (M4OSA_Void *pBufferIn, M4OSA_UInt8 *pBufferOut, 327 M4OSA_UInt32 *bufferOutSize) 328 { 329 M4OSA_UInt16 i; 330 wchar_t *w_str = (wchar_t *) pBufferIn; 331 M4OSA_UInt32 len, size_needed, size_given; 332 if (pBufferIn == NULL) 333 { 334 *pBufferOut=NULL; 335 *bufferOutSize=1; 336 } 337 else 338 { 339 len = wcslen(w_str); 340 size_needed = len+1; 341 size_given = *bufferOutSize; 342 343 *bufferOutSize=size_needed; 344 if (size_given < size_needed ) 345 { 346 return M4ERR_PARAMETER; 347 } 348 else 349 { 350 for (i=0; i<len; i++) 351 { 352 pBufferOut[i]=(M4OSA_UInt8)w_str[i]; 353 } 354 pBufferOut[len]=0; 355 } 356 } 357 return M4NO_ERROR; 358 } 359 #endif /*UTF CONVERSION*/ 360 361 /** 362 ************************************************************************ 363 * @brief This function seeks at the provided position. 364 * @param context: (IN/OUT) Context of the core file reader 365 * @param seekMode: (IN) Seek access mode 366 * @param position: (IN/OUT) Position in the file 367 * @return M4NO_ERROR: there is no error 368 * @return M4ERR_PARAMETER: at least one parameter is NULL 369 * @return M4ERR_BAD_CONTEXT: provided context is not a valid one 370 * @return M4ERR_ALLOC: there is no more memory available 371 * @return M4ERR_FILE_INVALID_POSITION: the position cannot be reached 372 ************************************************************************ 373 */ 374 M4OSA_ERR M4OSA_fileCommonSeek(M4OSA_Context pContext, 375 M4OSA_FileSeekAccessMode seekMode, 376 M4OSA_FilePosition* pFilePos) 377 { 378 M4OSA_FileContext* pFileContext = pContext; 379 M4OSA_FilePosition fpos_current; 380 M4OSA_FilePosition fpos_seek; 381 M4OSA_FilePosition fpos_null = 0; 382 M4OSA_FilePosition fpos_neg_un = -1; 383 M4OSA_FilePosition fpos_file_size; 384 M4OSA_FilePosition fpos_seek_from_beginning; 385 386 M4OSA_TRACE3_3("M4OSA_fileCommonSeek\t\tM4OSA_Context 0x%x\t M4OSA_FileSeekAccessMode %d\tM4OSA_FilePosition* 0x%x", 387 pContext, seekMode, pFilePos); 388 389 M4OSA_DEBUG_IF2(M4OSA_NULL == pContext, M4ERR_PARAMETER, "M4OSA_fileCommonSeek"); 390 M4OSA_DEBUG_IF2(0 == seekMode, M4ERR_PARAMETER, "M4OSA_fileCommonSeek"); 391 M4OSA_DEBUG_IF2(M4OSA_NULL == pFilePos, M4ERR_PARAMETER, "M4OSA_fileCommonSeek"); 392 393 fpos_file_size = pFileContext->file_size; 394 395 if(SeekRead == pFileContext->current_seek) 396 { 397 fpos_current = pFileContext->read_position; 398 } 399 else if(SeekWrite == pFileContext->current_seek) 400 { 401 fpos_current = pFileContext->write_position; 402 } 403 else 404 { 405 fpos_current = 0; 406 } 407 408 switch(seekMode) 409 { 410 case M4OSA_kFileSeekCurrent: 411 { 412 fpos_seek = *pFilePos; 413 break; 414 } 415 case M4OSA_kFileSeekBeginning: 416 { 417 fpos_seek = *pFilePos - fpos_current; 418 break; 419 } 420 case M4OSA_kFileSeekEnd: 421 { 422 fpos_seek = *pFilePos + fpos_file_size - fpos_current; 423 break; 424 } 425 default: 426 { 427 return M4ERR_PARAMETER; 428 } 429 } 430 431 fpos_seek_from_beginning = fpos_current + fpos_seek; 432 433 if(fseek(pFileContext->file_desc, fpos_seek, SEEK_CUR) != 0) 434 { 435 switch(errno) 436 { 437 case EINVAL: 438 { 439 /* meaning the value for origin is invalid or the position 440 specified by offset is before the beginning of the file */ 441 return M4ERR_FILE_INVALID_POSITION; 442 } 443 444 case EBADF: 445 default: 446 { 447 return M4ERR_BAD_CONTEXT;/* file handle is invalid */ 448 } 449 } 450 } 451 452 /* Set the returned position from the beginning of the file */ 453 *pFilePos = fpos_seek_from_beginning; 454 455 /* SEEK done, reset end of file value */ 456 pFileContext->b_is_end_of_file = M4OSA_FALSE; 457 458 return M4NO_ERROR; 459 } 460 461 462 /** 463 ************************************************************************ 464 * @brief This function asks to close the file (associated to the context) 465 * @note The context of the core file reader/writer is freed. 466 * @param context: (IN/OUT) Context of the core file reader 467 * @return M4NO_ERROR: there is no error 468 * @return M4ERR_PARAMETER: at least one parameter is NULL 469 * @return M4ERR_BAD_CONTEXT: provided context is not a valid one 470 * @return M4ERR_ALLOC: there is no more memory available 471 ************************************************************************ 472 */ 473 474 M4OSA_ERR M4OSA_fileCommonClose(M4OSA_UInt16 core_id, M4OSA_Context pContext) 475 { 476 M4OSA_FileContext* pFileContext = pContext; 477 M4OSA_Int32 i32_err_code=0; 478 479 M4OSA_TRACE3_2("M4OSA_fileCommonClose\tM4OSA_UInt16 %d\tM4OSA_Context 0x%x", 480 core_id, pContext); 481 M4OSA_DEBUG_IF2(M4OSA_NULL == pContext, 482 M4ERR_PARAMETER, "M4OSA_fileCommonClose: pContext is M4OSA_NULL"); 483 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE 484 M4OSA_DEBUG_IF2(M4OSA_NULL == pFileContext->semaphore_context, M4ERR_BAD_CONTEXT, 485 "M4OSA_fileCommonClose: semaphore_context is M4OSA_NULL"); 486 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */ 487 488 free(pFileContext->url_name); 489 pFileContext->url_name = M4OSA_NULL; 490 491 free(pFileContext->file_name); 492 pFileContext->file_name = M4OSA_NULL; 493 494 i32_err_code = fclose(pFileContext->file_desc); 495 496 pFileContext->file_desc = M4OSA_NULL; 497 498 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE 499 M4OSA_semaphoreClose(pFileContext->semaphore_context);/* free the semaphore */ 500 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */ 501 502 free(pFileContext); 503 504 if (i32_err_code != 0) 505 { 506 M4OSA_DEBUG(M4ERR_BAD_CONTEXT, "M4OSA_fileCommonClose"); 507 return M4ERR_BAD_CONTEXT; 508 } 509 510 return M4NO_ERROR; 511 } 512 513 514 /** 515 ************************************************************************ 516 * @brief This function gets the file attributes (associated to the 517 * context) 518 * @param context: (IN) Context of the core file reader 519 * @param attribute: (OUT) The file attribute (allocated by the caller) 520 * @return M4NO_ERROR: there is no error 521 * @return M4ERR_PARAMETER: at least one parameter is NULL 522 * @return M4ERR_BAD_CONTEXT: provided context is not a valid one 523 ************************************************************************ 524 */ 525 M4OSA_ERR M4OSA_fileCommonGetAttribute(M4OSA_Context pContext, M4OSA_FileAttribute* pAttribute) 526 { 527 528 M4OSA_FileContext* fileContext = pContext; 529 530 struct stat TheStat; 531 532 M4OSA_TRACE3_2("M4OSA_fileCommonGetAttribute\tM4OSA_Context 0x%x\t" 533 "M4OSA_FileAttribute* 0x%x", pContext, pAttribute); 534 535 M4OSA_DEBUG_IF2(M4OSA_NULL == pContext, M4ERR_PARAMETER, "M4OSA_fileCommonGetAttribute"); 536 M4OSA_DEBUG_IF2(M4OSA_NULL == pAttribute, M4ERR_PARAMETER, "M4OSA_fileCommonGetAttribute"); 537 538 if(stat((char*)fileContext->url_name, &TheStat) != 0) 539 { 540 M4OSA_DEBUG(M4ERR_BAD_CONTEXT, "M4OSA_fileCommonGetAttribute"); 541 return M4ERR_BAD_CONTEXT; 542 } 543 544 pAttribute->creationDate.time = (M4OSA_Time)TheStat.st_ctime; 545 pAttribute->lastAccessDate.time = (M4OSA_Time)TheStat.st_atime; 546 pAttribute->modifiedDate.time = (M4OSA_Time)TheStat.st_mtime; 547 548 pAttribute->creationDate.timeScale = 1; 549 pAttribute->lastAccessDate.timeScale = 1; 550 pAttribute->modifiedDate.timeScale = 1; 551 552 pAttribute->creationDate.referenceYear = 1970; 553 pAttribute->lastAccessDate.referenceYear = 1970; 554 pAttribute->modifiedDate.referenceYear = 1970; 555 556 pAttribute->modeAccess = fileContext->access_mode; 557 558 return M4NO_ERROR; 559 } 560 561 /** 562 ************************************************************************ 563 * @brief This function gets the file URL (associated to the context). 564 * @note 565 * @param context: (IN) Context of the core file reader 566 * @param url: (OUT) The buffer containing the URL (allocated by 567 * M4OSA_fileCommonGetURL) 568 * @return M4NO_ERROR: there is no error 569 * @return M4ERR_PARAMETER: at least one parameter is NULL 570 * @return M4ERR_BAD_CONTEXT: provided context is not a valid one 571 * @return M4ERR_ALLOC: there is no more memory available 572 ************************************************************************ 573 */ 574 M4OSA_ERR M4OSA_fileCommonGetURL(M4OSA_Context pContext, M4OSA_Char** pUrl) 575 { 576 M4OSA_FileContext* pFileContext = pContext; 577 M4OSA_UInt32 uiLength; 578 579 M4OSA_TRACE3_2("M4OSA_fileCommonGetURL\tM4OSA_Context 0x%x\tM4OSA_Char** 0x%x", 580 pContext, pUrl); 581 582 M4OSA_DEBUG_IF2(M4OSA_NULL == pContext, M4ERR_PARAMETER, 583 "M4OSA_fileCommonGetURL: pContext is M4OSA_NULL"); 584 M4OSA_DEBUG_IF2(M4OSA_NULL == pUrl, M4ERR_PARAMETER, 585 "M4OSA_fileCommonGetURL: pUrl is M4OSA_NULL"); 586 587 uiLength = strlen((const char *)pFileContext->url_name)+1; 588 589 /* Allocate the memory to store the url_name */ 590 *pUrl = (M4OSA_Char*)M4OSA_32bitAlignedMalloc(uiLength, M4OSA_FILE_COMMON, 591 (M4OSA_Char*)"M4OSA_fileCommonGetURL: url"); 592 if(M4OSA_NULL == *pUrl) 593 { 594 M4OSA_DEBUG(M4ERR_ALLOC, "M4OSA_fileCommonGetURL"); 595 return M4ERR_ALLOC; 596 } 597 598 M4OSA_chrNCopy(*pUrl, pFileContext->url_name, uiLength); 599 600 return M4NO_ERROR; 601 } 602 603 604 /** 605 ************************************************************************ 606 * @brief This function gets a string containing the file name associated 607 * to the input URL. 608 * @note The user should not forget to delete the output string using 609 * M4OSA_strDestroy 610 * @param pUrl: (IN) The buffer containing the URL 611 * @param pFileName: (OUT) The string containing the URL. It is 612 * allocated inside this function 613 * @return M4NO_ERROR: there is no error 614 * @return M4ERR_NOT_IMPLEMENTED: the URL does not match with the supported 615 * file 616 * @return M4ERR_ALLOC: there is no more memory available 617 ************************************************************************ 618 */ 619 M4OSA_ERR M4OSA_fileCommonGetFilename(M4OSA_Char* pUrl, M4OSA_Char** pFileName) 620 { 621 M4OSA_Int32 i = 0; 622 M4OSA_Int32 iUrlLen = 0; 623 M4OSA_Int32 FileNameLen = 0; 624 625 M4OSA_Char* ptrUrl = M4OSA_NULL; 626 M4OSA_Char* ptrFilename = M4OSA_NULL; 627 628 M4OSA_TRACE3_2("M4OSA_fileCommonGetURL\tM4OSA_Char* %s\tM4OSA_Char** 0x%x", 629 pUrl, pFileName); 630 631 M4OSA_DEBUG_IF2(M4OSA_NULL == pUrl, M4ERR_PARAMETER, 632 "M4OSA_fileCommonGetFilename: pUrl is M4OSA_NULL"); 633 M4OSA_DEBUG_IF2(M4OSA_NULL == pFileName, M4ERR_PARAMETER, 634 "M4OSA_fileCommonGetFilename: pFileName is M4OSA_NULL"); 635 636 *pFileName = M4OSA_NULL; 637 638 /*Parse URL*/ 639 iUrlLen = strlen((const char *)pUrl); 640 for(i=iUrlLen-1; i>=0; i--) 641 { 642 if (pUrl[i] != '\\' && pUrl[i] != '/') 643 { 644 FileNameLen++; 645 } 646 else 647 { 648 break; /* find the beginning of the file name */ 649 } 650 } 651 652 ptrFilename = (M4OSA_Char*) M4OSA_32bitAlignedMalloc(FileNameLen+1, M4OSA_FILE_COMMON, 653 (M4OSA_Char*)"M4OSA_fileCommonGetFilename: Filename string"); 654 if (ptrFilename == M4OSA_NULL) 655 { 656 M4OSA_DEBUG(M4ERR_ALLOC, "M4OSA_fileCommonGetFilename"); 657 return M4ERR_ALLOC; 658 } 659 660 ptrUrl = pUrl + (iUrlLen - FileNameLen); 661 M4OSA_chrNCopy(ptrFilename, ptrUrl, FileNameLen+1); 662 663 *pFileName = ptrFilename; 664 665 return M4NO_ERROR; 666 } 667 668