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