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