Home | History | Annotate | Download | only in src
      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