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_FileReader.c
     19  * @author       Cedric Lecoutre (cedric.lecoutre (at) philips.com)
     20  *               Laurent Fay (laurent.fay (at) philips.com)
     21  * @par Org:     Philips Digital Systems Laboratories - Paris (PDSL-P)
     22  * @brief        File reader for Android
     23  * @note         This file implements functions to read a file.
     24  ************************************************************************
     25 */
     26 
     27 
     28 #include "M4OSA_Debug.h"
     29 #include "M4OSA_FileCommon_priv.h"
     30 #include "M4OSA_FileReader.h"
     31 #include "M4OSA_FileReader_priv.h"
     32 #include "M4OSA_Memory.h"
     33 
     34 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE
     35 #include "M4OSA_Semaphore.h"
     36 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */
     37 
     38 
     39 /**
     40 ************************************************************************
     41 * @brief      This function opens the provided URL and returns its context.
     42 *             If an error occured, the context is set to NULL.
     43 * @param      context: (OUT) Context of the core file reader
     44 * @param      url: (IN) URL of the input file
     45 * @param      fileModeAccess: (IN) File mode access
     46 * @return     M4NO_ERROR: there is no error
     47 * @return     M4ERR_PARAMETER: at least one parameter is NULL
     48 * @return     M4ERR_ALLOC: there is no more memory available
     49 * @return     M4ERR_NOT_IMPLEMENTED: the URL does not match with the supported
     50 *             file
     51 * @return     M4ERR_FILE_NOT_FOUND: the file cannot be found
     52 * @return     M4ERR_FILE_LOCKED: the file is locked by an other
     53 *             application/process
     54 * @return     M4ERR_FILE_BAD_MODE_ACCESS: the file mode access is not correct
     55 ************************************************************************
     56 */
     57 M4OSA_ERR M4OSA_fileReadOpen(M4OSA_Context* pContext, M4OSA_Void* pFileDescriptor,
     58                              M4OSA_UInt32 fileModeAccess)
     59 {
     60     M4OSA_TRACE1_3("M4OSA_fileReadOpen : pC = 0x%p  fd = 0x%p  mode = %lu",
     61                                      pContext, pFileDescriptor, fileModeAccess);
     62 
     63     return M4OSA_fileCommonOpen(M4OSA_FILE_READER, pContext,
     64                                                pFileDescriptor, fileModeAccess);
     65 }
     66 
     67 /**
     68 ************************************************************************
     69 * @brief      This function reads the 'size' bytes in the core file reader
     70 *             (selected by its 'context') and writes the data to the 'data'
     71 *             pointer.
     72 * @note       If 'size' byte cannot be read in the core file reader, 'size'
     73 *             parameter is updated to match the correct
     74 * @note       number of read bytes.
     75 * @param      context: (IN/OUT) Context of the core file reader
     76 * @param      buffer: (OUT) Data pointer of the read data
     77 * @param      size: (IN/OUT) Size of the data to read (in bytes)
     78 * @return     M4NO_ERROR: there is no error
     79 * @return     M4ERR_PARAMETER: at least one parameter is NULL
     80 * @return     M4ERR_BAD_CONTEXT: provided context is not a valid one
     81 * @return     M4ERR_ALLOC: there is no more memory available
     82 * @return     M4WAR_NO_DATA_YET: there is no enough data to fill the 'data'
     83 *             buffer, so the size parameter has been updated.
     84 ************************************************************************
     85 */
     86 M4OSA_ERR M4OSA_fileReadData(M4OSA_Context pContext, M4OSA_MemAddr8 data,
     87                                                             M4OSA_UInt32* pSize)
     88 {
     89     M4OSA_FileContext* pFileContext = pContext;
     90     M4OSA_ERR    err = M4NO_ERROR;
     91     M4OSA_Int32    uiSizeRead;
     92 
     93     M4OSA_TRACE2_2("M4OSA_fileReadData : data = 0x%p  size = %lu",
     94                                     data, (M4OSA_NULL != pSize) ? (*pSize) : 0);
     95 
     96     M4OSA_DEBUG_IF2(M4OSA_NULL == pContext, M4ERR_PARAMETER,
     97                                   "M4OSA_fileReadData: pContext is M4OSA_NULL");
     98     M4OSA_DEBUG_IF2(M4OSA_NULL == data, M4ERR_PARAMETER,
     99                                       "M4OSA_fileReadData: data is M4OSA_NULL");
    100     M4OSA_DEBUG_IF2(M4OSA_NULL == pSize, M4ERR_PARAMETER,
    101                                      "M4OSA_fileReadData: pSize is M4OSA_NULL");
    102 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE
    103     M4OSA_DEBUG_IF2(M4OSA_NULL == pFileContext->semaphore_context,
    104       M4ERR_BAD_CONTEXT, "M4OSA_fileReadData: semaphore_context is M4OSA_NULL");
    105 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */
    106 
    107     if(M4OSA_kDescRWAccess == pFileContext->m_DescrModeAccess) /* read write */
    108     {
    109         uiSizeRead = fread(data, sizeof(M4OSA_Char), *pSize,
    110                                                        pFileContext->file_desc);
    111         if(-1 == uiSizeRead)
    112         {
    113             /* handle is invalid, or the file is not open for reading, or the file is locked */
    114             *pSize = 0;
    115             err = M4ERR_BAD_CONTEXT;
    116         }
    117         else
    118         {
    119             pFileContext->read_position = pFileContext->read_position + uiSizeRead;
    120             if ((M4OSA_UInt32)uiSizeRead < *pSize)
    121             {
    122                 *pSize = uiSizeRead;
    123                 /* This is the end of file */
    124                 pFileContext->b_is_end_of_file = M4OSA_TRUE;
    125                 err = M4WAR_NO_DATA_YET;
    126             }
    127             else
    128             {
    129                 *pSize = uiSizeRead;
    130             }
    131         }
    132 
    133         return err;
    134     }
    135 
    136 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE
    137     M4OSA_semaphoreWait(pFileContext->semaphore_context, M4OSA_WAIT_FOREVER);
    138 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */
    139 
    140     if(pFileContext->current_seek != SeekRead)
    141     {
    142         /* fseek to the last read position */
    143         err = M4OSA_fileCommonSeek(pContext, M4OSA_kFileSeekBeginning,
    144                                                 &(pFileContext->read_position));
    145         if(M4OSA_ERR_IS_ERROR(err))
    146         {
    147             M4OSA_DEBUG(err, "M4OSA_fileReadData: M4OSA_fileCommonSeek");
    148 
    149 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE
    150             M4OSA_semaphorePost(pFileContext->semaphore_context);
    151 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */
    152 
    153             return err;
    154         }
    155 
    156         pFileContext->current_seek = SeekRead;
    157     }
    158 
    159     /* Read data */
    160     uiSizeRead = fread(data, sizeof(M4OSA_Char), *pSize,
    161                                                        pFileContext->file_desc);
    162     if(-1 == uiSizeRead)
    163     {
    164         /* handle is invalid, or the file is not open for reading,
    165          or the file is locked */
    166         *pSize = 0;
    167         err = M4ERR_BAD_CONTEXT;
    168     }
    169     else
    170     {
    171         pFileContext->read_position = pFileContext->read_position + uiSizeRead;
    172         if ((M4OSA_UInt32)uiSizeRead < *pSize)
    173         {
    174             *pSize = uiSizeRead;
    175 
    176             /* This is the end of file */
    177             pFileContext->b_is_end_of_file = M4OSA_TRUE;
    178 
    179             err = M4WAR_NO_DATA_YET;
    180         }
    181         else
    182         {
    183             *pSize = uiSizeRead;
    184         }
    185     }
    186 
    187 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE
    188     M4OSA_semaphorePost(pFileContext->semaphore_context);
    189 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */
    190 
    191 
    192     return err;
    193 }
    194 
    195 
    196 /**
    197 ************************************************************************
    198  * @brief      This function seeks at the provided position in the core file
    199  *             reader (selected by its 'context'). The position is related to
    200  *             the seekMode parameter it can be either from the beginning, from
    201  *             the end or from the current postion. To support large file
    202  *             access (more than 2GBytes), the position is provided on a 64
    203  *             bits.
    204  * @note       If this function returns an error the current position pointer
    205  *             in the file must not change. Else the current
    206  *             position pointer must be updated.
    207  * @param      context: (IN/OUT) Context of the core file reader
    208  * @param      seekMode: (IN) Seek access mode
    209  * @param      position: (IN/OUT) Position in the file
    210  * @return     M4NO_ERROR: there is no error
    211  * @return     M4ERR_PARAMETER: at least one parameter is NULL
    212  * @return     M4ERR_BAD_CONTEXT: provided context is not a valid one
    213  * @return     M4ERR_ALLOC: there is no more memory available
    214  * @return     M4ERR_FILE_INVALID_POSITION: the position cannot be reached
    215  ************************************************************************
    216 */
    217 
    218 M4OSA_ERR M4OSA_fileReadSeek(M4OSA_Context pContext, M4OSA_FileSeekAccessMode seekMode,
    219                              M4OSA_FilePosition* pPosition)
    220 {
    221     M4OSA_FileContext* pFileContext = (M4OSA_FileContext*)pContext;
    222     M4OSA_ERR err;
    223 
    224     M4OSA_TRACE2_2("M4OSA_fileReadSeek : mode = %d  pos = %lu", seekMode,
    225                                   (pPosition != M4OSA_NULL) ? (*pPosition) : 0);
    226 
    227     M4OSA_DEBUG_IF2(M4OSA_NULL == pContext, M4ERR_PARAMETER,
    228                                   "M4OSA_fileReadSeek: pContext is M4OSA_NULL");
    229     M4OSA_DEBUG_IF2(0 == seekMode, M4ERR_PARAMETER,
    230                                            "M4OSA_fileReadSeek: seekMode is 0");
    231     M4OSA_DEBUG_IF2(M4OSA_NULL == pPosition, M4ERR_PARAMETER,
    232                                  "M4OSA_fileReadSeek: pPosition is M4OSA_NULL");
    233 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE
    234     M4OSA_DEBUG_IF2(M4OSA_NULL == pFileContext->semaphore_context,
    235       M4ERR_BAD_CONTEXT, "M4OSA_fileReadSeek: semaphore_context is M4OSA_NULL");
    236 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */
    237 
    238     if (M4OSA_kDescRWAccess == pFileContext->m_DescrModeAccess)
    239     {
    240          M4OSA_UInt32    SeekModeOption;
    241          /* Go to the desired position */
    242         if (M4OSA_kFileSeekBeginning == seekMode)
    243         {
    244             SeekModeOption = SEEK_SET;
    245         }
    246         else if (M4OSA_kFileSeekEnd == seekMode)
    247         {
    248             SeekModeOption = SEEK_END;
    249         }
    250         else if (M4OSA_kFileSeekCurrent == seekMode)
    251         {
    252             SeekModeOption = SEEK_CUR;
    253         }
    254         else
    255         {
    256             M4OSA_TRACE1_0("M4OSA_fileReadSeek: END WITH ERROR !!! (CONVERION ERROR FOR THE SEEK MODE)");
    257             return M4ERR_PARAMETER;
    258         }
    259 
    260         /**
    261          * Go to the desired position */
    262         err = fseek(pFileContext->file_desc, *pPosition, SeekModeOption);
    263         if(err != 0)
    264         {
    265             /* converts the error to PSW format*/
    266             err=((M4OSA_UInt32)(M4_ERR)<<30)+(((M4OSA_FILE_WRITER)&0x003FFF)<<16)+(M4OSA_Int16)(err);
    267             M4OSA_TRACE1_1("M4OSA_FileReadSeek error:%x",err);
    268         }
    269         else
    270         {
    271             return M4NO_ERROR;
    272         }
    273 
    274         /* Return without error */
    275         return err;
    276     }
    277 
    278 
    279 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE
    280     M4OSA_semaphoreWait(pFileContext->semaphore_context, M4OSA_WAIT_FOREVER);
    281 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */
    282 
    283     if(pFileContext->current_seek != SeekRead)
    284     {
    285 
    286         /* fseek to the last read position */
    287         err = M4OSA_fileCommonSeek(pContext, M4OSA_kFileSeekBeginning,
    288                                                 &(pFileContext->read_position));
    289         if(M4OSA_ERR_IS_ERROR(err))
    290         {
    291             M4OSA_DEBUG(err, "M4OSA_fileReadData: M4OSA_fileCommonSeek");
    292 
    293 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE
    294             M4OSA_semaphorePost(pFileContext->semaphore_context);
    295 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */
    296 
    297             return err;
    298         }
    299 
    300         pFileContext->current_seek = SeekRead;
    301     }
    302 
    303     err = M4OSA_fileCommonSeek(pContext, seekMode, pPosition);
    304     if(M4OSA_ERR_IS_ERROR(err))
    305     {
    306         M4OSA_DEBUG(err, "M4OSA_fileReadData: M4OSA_fileCommonSeek");
    307     }
    308     else
    309     {
    310         pFileContext->read_position = *pPosition;
    311     }
    312 
    313 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE
    314     M4OSA_semaphorePost(pFileContext->semaphore_context);
    315 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */
    316 
    317     return err;
    318 }
    319 
    320 
    321 /**
    322  ************************************************************************
    323  * @brief      This function asks the core file reader to close the file
    324  *             (associated to the context).
    325  * @note       The context of the core file reader is freed.
    326  * @param      pContext: (IN/OUT) Context of the core file reader
    327  * @return     M4NO_ERROR: there is no error
    328  * @return     M4ERR_PARAMETER: at least one parameter is NULL
    329  * @return     M4ERR_BAD_CONTEXT: provided context is not a valid one
    330  * @return     M4ERR_ALLOC: there is no more memory available
    331  ************************************************************************
    332 */
    333 M4OSA_ERR M4OSA_fileReadClose(M4OSA_Context pContext)
    334 {
    335     M4OSA_FileContext* pFileContext = (M4OSA_FileContext*)pContext;
    336 
    337     M4OSA_TRACE1_1("M4OSA_fileReadClose : pC = 0x%p", pContext);
    338 
    339     M4OSA_DEBUG_IF2(M4OSA_NULL == pContext, M4ERR_PARAMETER,
    340                                  "M4OSA_fileReadClose: pContext is M4OSA_NULL");
    341 
    342     if(M4OSA_FILE_WRITER == pFileContext->coreID_write)
    343     {
    344         return M4NO_ERROR;
    345     }
    346 
    347     return M4OSA_fileCommonClose(M4OSA_FILE_READER, pContext);
    348 }
    349 
    350 
    351 
    352 
    353 /**
    354  ************************************************************************
    355  * @brief      This function asks the core file reader to return the value
    356  *             associated with the optionID. The caller is responsible for
    357  *             allocating/de-allocating the memory of the value field.
    358  * @note       'value' must be cast according to the type related to the
    359  *             optionID As the caller is responsible for
    360  *             allocating/de-allocating the 'value' field, the callee must copy
    361  *             this field to its internal variable.
    362  * @param      pContext: (IN/OUT) Context of the core file reader
    363  * @param      pOptionID: (IN) ID of the option
    364  * @param      pOptionValue: (OUT) Value of the option
    365  * @return     M4NO_ERROR: there is no error
    366  * @return     M4ERR_PARAMETER: at least one parameter is NULL
    367  * @return     M4ERR_BAD_CONTEXT: provided context is not a valid one
    368  * @return     M4ERR_BAD_OPTION_ID: the optionID is not a valid one
    369  * @return     M4ERR_WRITE_ONLY: this option is a write only one
    370  * @return     M4ERR_NOT_IMPLEMENTED: this option is not implemented
    371  ************************************************************************
    372 */
    373 M4OSA_ERR M4OSA_fileReadGetOption(M4OSA_Context pContext, M4OSA_FileReadOptionID optionID,
    374                                   M4OSA_DataOption* pOptionValue)
    375 {
    376     M4OSA_FileContext* pFileContext = pContext;
    377 
    378     M4OSA_TRACE2_1("M4OSA_fileReadGetOption : option = 0x%x", optionID);
    379 
    380     M4OSA_DEBUG_IF2(M4OSA_NULL == pContext, M4ERR_PARAMETER,
    381                              "M4OSA_fileReadGetOption: pContext is M4OSA_NULL");
    382     M4OSA_DEBUG_IF2(optionID == 0, M4ERR_PARAMETER,
    383                                       "M4OSA_fileReadGetOption: optionID is 0");
    384     M4OSA_DEBUG_IF2(M4OSA_NULL == pOptionValue, M4ERR_PARAMETER,
    385                          "M4OSA_fileReadGetOption: pOptionValue is M4OSA_NULL");
    386 
    387     M4OSA_DEBUG_IF2(!M4OSA_OPTION_ID_IS_COREID(optionID, M4OSA_FILE_READER),
    388                                 M4ERR_BAD_OPTION_ID, "M4OSA_fileReadGetOption");
    389     M4OSA_DEBUG_IF2(!M4OSA_OPTION_ID_IS_READABLE(optionID),
    390                                    M4ERR_WRITE_ONLY, "M4OSA_fileReadGetOption");
    391 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE
    392     M4OSA_DEBUG_IF2(M4OSA_NULL == pFileContext->semaphore_context,
    393                                   M4ERR_BAD_CONTEXT,
    394                                   "M4OSA_fileReadGetOption: semaphore_context is M4OSA_NULL");
    395 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */
    396 
    397     switch(optionID)
    398     {
    399 #if(M4OSA_OPTIONID_FILE_READ_GET_FILE_POSITION == M4OSA_TRUE)
    400     case M4OSA_kFileReadGetFilePosition:
    401         {
    402             M4OSA_FilePosition* pPosition = (M4OSA_FilePosition*)pOptionValue;
    403 
    404 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE
    405             M4OSA_semaphoreWait(pFileContext->semaphore_context, M4OSA_WAIT_FOREVER);
    406 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */
    407 
    408             *pPosition = pFileContext->read_position;
    409 
    410 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE
    411             M4OSA_semaphorePost(pFileContext->semaphore_context);
    412 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */
    413 
    414             return M4NO_ERROR;
    415         }
    416 #endif /*M4OSA_OPTIONID_FILE_READ_GET_FILE_POSITION*/
    417 
    418 #if(M4OSA_OPTIONID_FILE_READ_IS_EOF == M4OSA_TRUE)
    419     case M4OSA_kFileReadIsEOF:
    420         {
    421             M4OSA_Bool* bIsEndOfFile = (M4OSA_Bool*)pOptionValue;
    422 
    423 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE
    424             M4OSA_semaphoreWait(pFileContext->semaphore_context, M4OSA_WAIT_FOREVER);
    425 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */
    426 
    427             *bIsEndOfFile = pFileContext->b_is_end_of_file;
    428 
    429 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE
    430             M4OSA_semaphorePost(pFileContext->semaphore_context);
    431 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */
    432 
    433             return M4NO_ERROR;
    434         }
    435 #endif /*M4OSA_OPTIONID_FILE_READ_IS_EOF*/
    436 
    437 
    438 #if(M4OSA_OPTIONID_FILE_READ_GET_FILE_SIZE == M4OSA_TRUE)
    439     case M4OSA_kFileReadGetFileSize:
    440         {
    441             M4OSA_FilePosition* pPosition = (M4OSA_FilePosition*)pOptionValue;
    442             M4OSA_Int32 iSavePos    = 0;
    443             M4OSA_Int32 iSize        = 0;
    444 
    445 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE
    446             M4OSA_semaphoreWait(pFileContext->semaphore_context, M4OSA_WAIT_FOREVER);
    447 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */
    448             /**
    449             * Bugfix: update the file size.
    450             * When a file is in read mode, may be another application is writing in.
    451             * So, we have to update the file size */
    452             iSavePos = ftell(pFileContext->file_desc);            /*1- Check the first position */
    453             fseek(pFileContext->file_desc, 0, SEEK_END);        /*2- Go to the end of the file */
    454             iSize = ftell(pFileContext->file_desc);                /*3- Check the file size*/
    455             fseek(pFileContext->file_desc, iSavePos, SEEK_SET);    /*4- go to the first position*/
    456             pFileContext->file_size = iSize;
    457 
    458             *pPosition = pFileContext->file_size;
    459 
    460 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE
    461             M4OSA_semaphorePost(pFileContext->semaphore_context);
    462 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */
    463 
    464             return M4NO_ERROR;
    465         }
    466 #endif /*M4OSA_OPTIONID_FILE_READ_GET_FILE_SIZE*/
    467 
    468 #if(M4OSA_OPTIONID_FILE_READ_GET_FILE_ATTRIBUTE == M4OSA_TRUE)
    469     case M4OSA_kFileReadGetFileAttribute:
    470         {
    471             return M4OSA_fileCommonGetAttribute(pContext,
    472                                             (M4OSA_FileAttribute*)pOptionValue);
    473         }
    474 #endif /*M4OSA_OPTIONID_FILE_READ_GET_FILE_ATTRIBUTE*/
    475 
    476 #if(M4OSA_OPTIONID_FILE_READ_GET_URL == M4OSA_TRUE)
    477     case M4OSA_kFileReadGetURL:
    478         {
    479             return M4OSA_fileCommonGetURL(pContext, (M4OSA_Char**)pOptionValue);
    480         }
    481 #endif /*M4OSA_OPTIONID_FILE_READ_GET_URL*/
    482 
    483         case M4OSA_kFileReadLockMode:
    484         {
    485             *(M4OSA_UInt32*)pOptionValue = pFileContext->m_uiLockMode;
    486             return M4NO_ERROR;
    487         }
    488     }
    489 
    490     M4OSA_DEBUG(M4ERR_NOT_IMPLEMENTED, "M4OSA_fileReadGetOption");
    491 
    492     return M4ERR_NOT_IMPLEMENTED;
    493 }
    494 
    495 /**
    496  ************************************************************************
    497  * @fn         M4OSA_ERR M4OSA_fileReadSetOption (M4OSA_Context context,
    498  *                       M4OSA_OptionID optionID, M4OSA_DataOption optionValue))
    499  * @brief      This function asks the core file reader to set the value associated with the optionID.
    500  *             The caller is responsible for allocating/de-allocating the memory of the value field.
    501  * @note       As the caller is responsible for allocating/de-allocating the 'value' field, the callee must copy this field
    502  *             to its internal variable.
    503  * @param      pContext: (IN/OUT) Context of the core file reader
    504  * @param      optionID: (IN) ID of the option
    505  * @param      value: (IN) Value of the option
    506  * @return     M4NO_ERROR: there is no error
    507  * @return     M4ERR_PARAMETER: at least one parameter is NULL
    508  * @return     M4ERR_BAD_CONTEXT: provided context is not a valid one
    509  * @return     M4ERR_BAD_OPTION_ID: the optionID is not a valid one
    510  * @return     M4ERR_READ_ONLY: this option is a read only one
    511  * @return     M4ERR_NOT_IMPLEMENTED: this option is not implemented
    512  ************************************************************************
    513 */
    514 M4OSA_ERR M4OSA_fileReadSetOption(M4OSA_Context pContext,
    515                                   M4OSA_FileReadOptionID optionID,
    516                                   M4OSA_DataOption optionValue)
    517 {
    518     M4OSA_FileContext* pFileContext = pContext;
    519 
    520     M4OSA_TRACE2_1("M4OSA_fileReadSetOption : option = 0x%x", optionID);
    521 
    522     M4OSA_DEBUG_IF2(M4OSA_NULL == pContext, M4ERR_PARAMETER,
    523                              "M4OSA_fileReadSetOption: pContext is M4OSA_NULL");
    524     M4OSA_DEBUG_IF2(0 == optionID, M4ERR_PARAMETER,
    525                                                      "M4OSA_fileReadSetOption");
    526     M4OSA_DEBUG_IF2(!M4OSA_OPTION_ID_IS_COREID(optionID, M4OSA_FILE_READER),
    527                                 M4ERR_BAD_OPTION_ID, "M4OSA_fileReadSetOption");
    528 
    529     M4OSA_DEBUG_IF2(!M4OSA_OPTION_ID_IS_WRITABLE(optionID),
    530                                     M4ERR_READ_ONLY, "M4OSA_fileReadSetOption");
    531 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE
    532     M4OSA_DEBUG_IF2(M4OSA_NULL == pFileContext->semaphore_context,
    533                                   M4ERR_BAD_CONTEXT,
    534                                   "M4OSA_fileReadSetOption: semaphore_context is M4OSA_NULL");
    535 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */
    536 
    537     switch(optionID)
    538     {
    539         case M4OSA_kFileReadLockMode:
    540         {
    541             pFileContext->m_uiLockMode= (M4OSA_UInt32)*(M4OSA_UInt32*)optionValue;
    542             return M4NO_ERROR;
    543         }
    544         default:
    545             M4OSA_DEBUG(M4ERR_NOT_IMPLEMENTED, "M4OSA_fileReadSetOption");
    546             return M4ERR_NOT_IMPLEMENTED;
    547     }
    548 }
    549 
    550