• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  ******************************************************************************
19  * @file         M4OSA_FileReader_optim.c
20  * @brief
21  * @note         This file implements functions to manipulate filesystem access
22  ******************************************************************************
23 */
24 
25 /** Addition of Trace ID **/
26 #include "M4OSA_CoreID.h"
27 #include "M4OSA_Error.h"
28 
29 #ifdef M4TRACE_ID
30 #undef M4TRACE_ID
31 #endif
32 #define M4TRACE_ID    M4OSA_FILE_READER
33 
34 
35 #include "M4OSA_FileCommon.h"
36 #include "M4OSA_FileReader.h"
37 #include "M4OSA_FileWriter.h"
38 #include "M4OSA_Memory.h"
39 #include "M4OSA_Debug.h"
40 
41 #include "LVOSA_FileReader_optim.h"
42 
43 #define M4OSA_READER_OPTIM_USE_OSAL_IF
44 #ifndef M4OSA_READER_OPTIM_USE_OSAL_IF
45     #include "M4OSA_FileAccess.h"
46 #endif
47 
48 #define M4ERR_CHECK_NULL_RETURN_VALUE(retval, pointer) if ((pointer) == M4OSA_NULL) return (retval);
49 
50 
51 
52 
53 /**
54  ******************************************************************************
55  * File reader cache buffers parameters (size, number of buffers, etc)
56  ******************************************************************************
57 */
58 #define M4OSA_READBUFFER_SIZE    1024*16
59 #define M4OSA_READBUFFER_NB        2
60 #define M4OSA_READBUFFER_NONE    -1
61 #define M4OSA_EOF               -1
62 
63 #define MAX_FILLS_SINCE_LAST_ACCESS    M4OSA_READBUFFER_NB*2
64 
65 /**
66  ******************************************************************************
67  * structure    M4OSA_FileReader_Buffer
68  * @brief       This structure defines the File reader Buffers context (private)
69  ******************************************************************************
70 */
71 typedef struct
72 {
73     M4OSA_MemAddr8      data;        /**< buffer data */
74     M4OSA_FilePosition  size;        /**< size of the buffer */
75     M4OSA_FilePosition  filepos;    /**< position in the file where the buffer starts */
76     M4OSA_FilePosition  remain;        /**< data amount not already copied from buffer */
77     M4OSA_UInt32        nbFillSinceLastAcess;    /**< To know since how many time we didn't use this buffer */
78 } M4OSA_FileReader_Buffer_optim;
79 
80 /**
81  ******************************************************************************
82  * structure    M4OSA_FileReader_Context
83  * @brief       This structure defines the File reader context (private)
84  * @note        This structure is used for all File Reader calls to store the context
85  ******************************************************************************
86 */
87 typedef struct
88 {
89     M4OSA_Bool              IsOpened;       /**< Micro state machine */
90     M4OSA_FileAttribute     FileAttribute;  /**< Opening mode */
91     M4OSA_FilePosition         readFilePos;    /**< Effective position of the GFL read pointer */
92     M4OSA_FilePosition         absolutePos;    /**< Virtual position for next reading */
93     M4OSA_FilePosition         fileSize;        /**< Size of the file */
94 
95     M4OSA_FileReader_Buffer_optim buffer[M4OSA_READBUFFER_NB];  /**< Read buffers */
96 
97     M4OSA_Void*             aFileDesc;  /**< File descriptor */
98 
99 #ifdef M4OSA_READER_OPTIM_USE_OSAL_IF
100     M4OSA_FileReadPointer*     FS;            /**< Filesystem interface */
101 #else
102     M4OSA_FileSystem_FctPtr *FS;        /**< Filesystem interface */
103 #endif
104 
105 } M4OSA_FileReader_Context_optim;
106 
107 /* __________________________________________________________ */
108 /*|                                                          |*/
109 /*|    Global function for handling low level read access    |*/
110 /*|__________________________________________________________|*/
111 
112 static M4OSA_FileReadPointer* gv_NXPSW_READOPT_lowLevelFunctions;
113 
NXPSW_FileReaderOptim_init(M4OSA_Void * lowLevel_functionPointers,M4OSA_Void * optimized_functionPointers)114 M4OSA_ERR NXPSW_FileReaderOptim_init(M4OSA_Void *lowLevel_functionPointers, M4OSA_Void *optimized_functionPointers)
115 {
116     M4OSA_FileReadPointer* lowLevel_fp  = (M4OSA_FileReadPointer*) lowLevel_functionPointers;
117     M4OSA_FileReadPointer* optimized_fp = (M4OSA_FileReadPointer*) optimized_functionPointers;
118 
119     //Set the optimized functions, to be called by the user
120     optimized_fp->openRead  = M4OSA_fileReadOpen_optim;
121     optimized_fp->readData  = M4OSA_fileReadData_optim;
122     optimized_fp->seek      = M4OSA_fileReadSeek_optim;
123     optimized_fp->closeRead = M4OSA_fileReadClose_optim;
124     optimized_fp->setOption = M4OSA_fileReadSetOption_optim;
125     optimized_fp->getOption = M4OSA_fileReadGetOption_optim;
126 
127 
128     return M4NO_ERROR;
129 }
130 
NXPSW_FileReaderOptim_cleanUp()131 M4OSA_ERR NXPSW_FileReaderOptim_cleanUp()
132 {
133 
134     gv_NXPSW_READOPT_lowLevelFunctions = M4OSA_NULL;
135 
136     return M4NO_ERROR;
137 }
138 
139 
NXPSW_FileReaderOptim_getLowLevelFunctions(M4OSA_Void ** FS)140 M4OSA_ERR NXPSW_FileReaderOptim_getLowLevelFunctions(M4OSA_Void **FS)
141 {
142     M4OSA_FileReadPointer** pFunctionsPointer = (M4OSA_FileReadPointer**) FS;
143     *pFunctionsPointer = gv_NXPSW_READOPT_lowLevelFunctions;
144     return M4NO_ERROR;
145 }
146 
147 
148 /* __________________________________________________________ */
149 /*|                                                          |*/
150 /*|        Buffer handling functions for Read access         |*/
151 /*|__________________________________________________________|*/
152 
153 /**************************************************************/
M4OSA_FileReader_BufferInit(M4OSA_FileReader_Context_optim * apContext)154 M4OSA_ERR M4OSA_FileReader_BufferInit(M4OSA_FileReader_Context_optim* apContext)
155 /**************************************************************/
156 {
157     M4OSA_UInt8 i;
158 
159     for(i=0; i<M4OSA_READBUFFER_NB; i++)
160     {
161         apContext->buffer[i].data = M4OSA_NULL;
162         apContext->buffer[i].size = 0;
163         apContext->buffer[i].filepos = 0;
164         apContext->buffer[i].remain = 0;
165     }
166 
167     for(i=0; i<M4OSA_READBUFFER_NB; i++)
168     {
169         apContext->buffer[i].data = (M4OSA_MemAddr8) M4OSA_32bitAlignedMalloc(M4OSA_READBUFFER_SIZE,
170             M4OSA_FILE_READER, (M4OSA_Char *)"M4OSA_FileReader_BufferInit");
171         M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_ALLOC, apContext->buffer[i].data);
172     }
173 
174     return M4NO_ERROR;
175 }
176 
177 /**************************************************************/
M4OSA_FileReader_BufferFree(M4OSA_FileReader_Context_optim * apContext)178 M4OSA_Void M4OSA_FileReader_BufferFree(M4OSA_FileReader_Context_optim* apContext)
179 /**************************************************************/
180 {
181     M4OSA_Int8 i;
182 
183     for(i=0; i<M4OSA_READBUFFER_NB; i++)
184         if(apContext->buffer[i].data != M4OSA_NULL)
185             free(apContext->buffer[i].data);
186 }
187 
188 /**************************************************************/
M4OSA_FileReader_BufferCopy(M4OSA_FileReader_Context_optim * apContext,M4OSA_Int8 i,M4OSA_FilePosition pos,M4OSA_FilePosition size,M4OSA_MemAddr8 pData)189 M4OSA_FilePosition M4OSA_FileReader_BufferCopy(M4OSA_FileReader_Context_optim* apContext,
190                                                M4OSA_Int8 i, M4OSA_FilePosition pos,
191                                                M4OSA_FilePosition size, M4OSA_MemAddr8 pData)
192 /**************************************************************/
193 {
194     M4OSA_FilePosition copysize;
195     M4OSA_FilePosition offset;
196 
197     if(apContext->buffer[i].size == M4OSA_EOF) return M4OSA_EOF;
198 
199     if(   (pos < apContext->buffer[i].filepos)
200        || (pos > (apContext->buffer[i].filepos + apContext->buffer[i].size - 1)) )
201     {
202         return 0; /* nothing copied */
203     }
204 
205     offset = pos - apContext->buffer[i].filepos;
206 
207     copysize = apContext->buffer[i].size - offset;
208     copysize = (size < copysize) ? size : copysize;
209 
210     memcpy((void *)pData, (void *)(apContext->buffer[i].data + offset), copysize);
211 
212     apContext->buffer[i].remain -= copysize;
213     apContext->buffer[i].nbFillSinceLastAcess = 0;
214 
215     return copysize;
216 }
217 
218 /**************************************************************/
M4OSA_FileReader_BufferFill(M4OSA_FileReader_Context_optim * apContext,M4OSA_Int8 i,M4OSA_FilePosition pos)219 M4OSA_ERR M4OSA_FileReader_BufferFill(M4OSA_FileReader_Context_optim* apContext,
220                                        M4OSA_Int8 i, M4OSA_FilePosition pos)
221 /**************************************************************/
222 {
223     M4OSA_FilePosition     gridPos;
224     M4OSA_FilePosition    tempPos;
225     M4OSA_UInt32        bufferSize;
226     M4OSA_FilePosition     diff;
227     M4OSA_FilePosition     size;
228     M4OSA_ERR             err = M4NO_ERROR;
229 #ifdef M4OSA_READER_OPTIM_USE_OSAL_IF
230     M4OSA_ERR             errno = M4NO_ERROR;
231     M4OSA_UInt32         fileReadSize = 0;
232     M4OSA_FilePosition     fileSeekPosition = 0;
233 #else
234     M4OSA_Int32         ret_val;
235     M4OSA_UInt16         errno;
236 #endif
237 
238     M4OSA_TRACE3_4("BufferFill  i = %d  pos = %ld  read = %ld  old = %ld", i, pos,
239                               apContext->readFilePos, apContext->buffer[i].filepos);
240 
241     /* Avoid cycling statement because of EOF */
242     if(pos >= apContext->fileSize)
243         return M4WAR_NO_MORE_AU;
244 
245     /* Relocate to absolute postion if necessary */
246     bufferSize = M4OSA_READBUFFER_SIZE;
247     tempPos = (M4OSA_FilePosition) (pos / bufferSize);
248     gridPos = tempPos * M4OSA_READBUFFER_SIZE;
249     diff = gridPos - apContext->readFilePos;
250 
251     if(diff != 0)
252     {
253 #ifdef M4OSA_READER_OPTIM_USE_OSAL_IF
254         fileSeekPosition = diff;
255         errno = apContext->FS->seek(apContext->aFileDesc, M4OSA_kFileSeekCurrent,
256                                     &fileSeekPosition);
257         apContext->readFilePos = gridPos;
258 
259         if(M4NO_ERROR != errno)
260         {
261             err = errno;
262             M4OSA_TRACE1_1("M4OSA_FileReader_BufferFill ERR1 = 0x%x", err);
263             return err;
264         }
265 
266 #else
267         ret_val = apContext->FS->pFctPtr_Seek(apContext->aFileDesc, diff,
268                                                M4OSA_kFileSeekCurrent, &errno);
269         apContext->readFilePos = gridPos;
270 
271         if(ret_val != 0)
272         {
273             err = M4OSA_ERR_CREATE(M4_ERR, M4OSA_FILE_READER, errno);
274             M4OSA_TRACE1_1("M4OSA_FileReader_BufferFill ERR1 = 0x%x", err);
275             return err;
276         }
277 #endif /*M4OSA_READER_OPTIM_USE_OSAL_IF*/
278     }
279 
280     apContext->buffer[i].filepos = apContext->readFilePos;
281 
282     /* Read Data */
283 #ifdef M4OSA_READER_OPTIM_USE_OSAL_IF
284     fileReadSize = M4OSA_READBUFFER_SIZE;
285     errno = apContext->FS->readData(apContext->aFileDesc,
286                       (M4OSA_MemAddr8)apContext->buffer[i].data, &fileReadSize);
287 
288     size = (M4OSA_FilePosition)fileReadSize;
289     if ((M4NO_ERROR != errno)&&(M4WAR_NO_DATA_YET != errno))
290     {
291         apContext->buffer[i].size = M4OSA_EOF;
292         apContext->buffer[i].remain = 0;
293 
294         err = errno;
295         M4OSA_TRACE1_1("M4OSA_FileReader_BufferFill ERR2 = 0x%x", err);
296         return err;
297     }
298 #else
299     size = apContext->FS->pFctPtr_Read(apContext->aFileDesc,
300         (M4OSA_UInt8 *)apContext->buffer[i].data, M4OSA_READBUFFER_SIZE, &errno);
301     if(size == -1)
302     {
303         apContext->buffer[i].size = M4OSA_EOF;
304         apContext->buffer[i].remain = 0;
305 
306         err = M4OSA_ERR_CREATE(M4_ERR, M4OSA_FILE_READER, errno);
307         M4OSA_TRACE1_1("M4OSA_FileReader_BufferFill ERR2 = 0x%x", err);
308         return err;
309     }
310 #endif
311 
312     apContext->buffer[i].size = size;
313     apContext->buffer[i].remain = size;
314     apContext->buffer[i].nbFillSinceLastAcess = 0;
315 
316     /* Retrieve current position */
317 #ifdef M4OSA_READER_OPTIM_USE_OSAL_IF
318     errno = apContext->FS->getOption(apContext->aFileDesc,
319                                      M4OSA_kFileReadGetFilePosition,
320                                      (M4OSA_DataOption*) &apContext->readFilePos);
321 
322     if (M4NO_ERROR != errno)
323     {
324         err = errno;
325         M4OSA_TRACE1_1("M4OSA_FileReader_BufferFill ERR3 = 0x%x", err);
326     }
327     else if(   (apContext->buffer[i].size >= 0)
328        && (apContext->buffer[i].size < M4OSA_READBUFFER_SIZE) )
329     {
330         err = M4WAR_NO_DATA_YET;
331         M4OSA_TRACE2_0("M4OSA_FileReader_BufferFill returns NO DATA YET");
332         return err;
333     }
334 #else
335     apContext->readFilePos = apContext->FS->pFctPtr_Tell(apContext->aFileDesc, &errno);
336 
337     if(   (apContext->buffer[i].size >= 0)
338        && (apContext->buffer[i].size < M4OSA_READBUFFER_SIZE) )
339     {
340         err = M4WAR_NO_DATA_YET;
341         M4OSA_TRACE1_1("M4OSA_FileReader_BufferFill ERR3 = 0x%x", err);
342         return err;
343     }
344 #endif /*M4OSA_READER_OPTIM_USE_OSAL_IF*/
345 
346     /* Return without error */
347     return M4NO_ERROR;
348 }
349 
350 /**************************************************************/
M4OSA_FileReader_BufferMatch(M4OSA_FileReader_Context_optim * apContext,M4OSA_FilePosition pos)351 M4OSA_Int8 M4OSA_FileReader_BufferMatch(M4OSA_FileReader_Context_optim* apContext,
352                                         M4OSA_FilePosition pos)
353 /**************************************************************/
354 {
355     M4OSA_Int8 i;
356 
357 
358     /* Select the buffer which matches with given pos */
359     for(i=0; i<M4OSA_READBUFFER_NB; i++)
360     {
361         if(   (pos >= apContext->buffer[i].filepos)
362            && (pos < (apContext->buffer[i].filepos + apContext->buffer[i].size)) )
363         {
364             return i;
365         }
366     }
367     return M4OSA_READBUFFER_NONE;
368 }
369 
370 /**************************************************************/
M4OSA_FileReader_BufferSelect(M4OSA_FileReader_Context_optim * apContext,M4OSA_Int8 current_i)371 M4OSA_Int8 M4OSA_FileReader_BufferSelect(M4OSA_FileReader_Context_optim* apContext,
372                                          M4OSA_Int8 current_i)
373 /**************************************************************/
374 {
375     M4OSA_Int8 i,j;
376     M4OSA_FilePosition min_amount,max_amount;
377     M4OSA_Int8 min_i,max_count;
378 
379     /* update nbFillSinceLastAcess field */
380     for(i=0; i<M4OSA_READBUFFER_NB; i++)
381     {
382         apContext->buffer[i].nbFillSinceLastAcess ++;
383     }
384 
385     /* Plan A : Scan for empty buffer */
386     for(i=0; i<M4OSA_READBUFFER_NB; i++)
387     {
388         if(apContext->buffer[i].remain == 0)
389         {
390             return i;
391         }
392     }
393 
394     max_count = M4OSA_READBUFFER_NB;
395     max_amount = MAX_FILLS_SINCE_LAST_ACCESS;
396 
397     /* Plan B : Scan for dead buffer */
398     for(i=0; i<M4OSA_READBUFFER_NB; i++)
399     {
400         if(apContext->buffer[i].nbFillSinceLastAcess >= (M4OSA_UInt32) max_amount)
401         {
402             max_amount = apContext->buffer[i].nbFillSinceLastAcess;
403             max_count = i;
404         }
405     }
406     if(max_count<M4OSA_READBUFFER_NB)
407     {
408         M4OSA_TRACE2_2("DEAD BUFFER: %d, %d",max_count,apContext->buffer[max_count].nbFillSinceLastAcess);
409         return max_count;
410     }
411 
412     min_i = current_i;
413     min_amount = M4OSA_READBUFFER_SIZE;
414 
415     /* Select the buffer which is the most "empty" */
416     for(i=0; i<M4OSA_READBUFFER_NB; i++)
417     {
418         j = (i+current_i)%M4OSA_READBUFFER_NB;
419 
420         if(apContext->buffer[j].remain < min_amount)
421         {
422             min_amount = apContext->buffer[j].remain;
423             min_i = j;
424         }
425     }
426 
427     return min_i;
428 
429 }
430 
431 /**************************************************************/
M4OSA_FileReader_CalculateSize(M4OSA_FileReader_Context_optim * apContext)432 M4OSA_ERR M4OSA_FileReader_CalculateSize(M4OSA_FileReader_Context_optim* apContext)
433 /**************************************************************/
434 {
435     M4OSA_ERR            err = M4NO_ERROR;
436 #ifdef M4OSA_READER_OPTIM_USE_OSAL_IF
437     M4OSA_ERR            errno = M4NO_ERROR;
438 #else
439     M4OSA_Int32          ret_val;
440     M4OSA_UInt16         errno;
441 #endif
442 
443     /* go to the end of file*/
444 #ifdef M4OSA_READER_OPTIM_USE_OSAL_IF
445     errno = apContext->FS->getOption(apContext->aFileDesc, M4OSA_kFileReadGetFileSize,
446                                         (M4OSA_DataOption*) &apContext->fileSize);
447     if (M4NO_ERROR != errno)
448     {
449         err = errno;
450         M4OSA_TRACE1_1("M4OSA_FileReader_CalculateSize ERR = 0x%x", err);
451     }
452 #else
453     ret_val = apContext->FS->pFctPtr_Seek(apContext->aFileDesc, 0, M4OSA_kFileSeekEnd, &errno);
454 
455     if (ret_val != 0)
456     {
457         apContext->readFilePos = M4OSA_EOF;
458         err = M4OSA_ERR_CREATE(M4_ERR, M4OSA_FILE_READER, errno);
459         M4OSA_TRACE1_1("M4OSA_FileReader_CalculateSize ERR = 0x%x", err);
460     }
461     else
462     {
463         /* Retrieve size of the file */
464         apContext->fileSize = apContext->FS->pFctPtr_Tell(apContext->aFileDesc, &errno);
465         apContext->readFilePos = apContext->fileSize;
466     }
467 #endif /*M4OSA_READER_OPTIM_USE_OSAL_IF*/
468 
469     return err;
470 }
471 
472 
473 /* __________________________________________________________ */
474 /*|                                                          |*/
475 /*|                   OSAL filesystem API                    |*/
476 /*|__________________________________________________________|*/
477 
478 /**
479 ******************************************************************************
480 * @brief       This method opens the provided fileDescriptor and returns its context.
481 * @param       pContext:       (OUT) File reader context.
482 * @param       pFileDescriptor :       (IN) File Descriptor of the input file.
483 * @param       FileModeAccess :        (IN) File mode access.
484 * @return      M4NO_ERROR: there is no error
485 * @return      M4ERR_PARAMETER pContext or fileDescriptor is NULL
486 * @return      M4ERR_ALLOC     there is no more memory available
487 * @return      M4ERR_FILE_BAD_MODE_ACCESS      the file mode access is not correct (it must be either isTextMode or read)
488 * @return      M4ERR_FILE_NOT_FOUND The file can not be opened.
489 ******************************************************************************
490 */
491 #ifdef M4OSA_READER_OPTIM_USE_OSAL_IF
M4OSA_fileReadOpen_optim(M4OSA_Context * pContext,M4OSA_Void * pFileDescriptor,M4OSA_UInt32 FileModeAccess)492     M4OSA_ERR M4OSA_fileReadOpen_optim(M4OSA_Context* pContext,
493                                        M4OSA_Void* pFileDescriptor,
494                                        M4OSA_UInt32 FileModeAccess)
495 #else
496     M4OSA_ERR M4OSA_fileReadOpen_optim(M4OSA_Context* pContext,
497                                        M4OSA_Void* pFileDescriptor,
498                                        M4OSA_UInt32 FileModeAccess,
499                                        M4OSA_FileSystem_FctPtr *FS)
500 #endif
501 {
502     M4OSA_FileReader_Context_optim* apContext = M4OSA_NULL;
503 
504     M4OSA_ERR   err       = M4NO_ERROR;
505     M4OSA_Void* aFileDesc = M4OSA_NULL;
506     M4OSA_Bool  buffers_allocated = M4OSA_FALSE;
507 #ifdef M4OSA_READER_OPTIM_USE_OSAL_IF
508     M4OSA_ERR errno = M4NO_ERROR;
509 #else
510     M4OSA_UInt16 errno;
511 #endif /*M4OSA_READER_OPTIM_USE_OSAL_IF*/
512 
513     M4OSA_TRACE2_3("M4OSA_fileReadOpen_optim p = 0x%p fd = %s mode = %lu", pContext,
514                                                    pFileDescriptor, FileModeAccess);
515 
516     /*      Check input parameters */
517     M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_PARAMETER, pContext);
518     M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_PARAMETER, pFileDescriptor);
519 
520     *pContext = M4OSA_NULL;
521 
522     /*      Allocate memory for the File reader context. */
523     apContext = (M4OSA_FileReader_Context_optim *)M4OSA_32bitAlignedMalloc(sizeof(M4OSA_FileReader_Context_optim),
524                                       M4OSA_FILE_READER, (M4OSA_Char *)"M4OSA_FileReader_Context_optim");
525 
526     M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_ALLOC, apContext);
527 
528     /* Set filesystem interface */
529 #ifdef M4OSA_READER_OPTIM_USE_OSAL_IF
530 
531     /*Set the optimized functions, to be called by the user*/
532 
533     apContext->FS = (M4OSA_FileReadPointer*) M4OSA_32bitAlignedMalloc(sizeof(M4OSA_FileReadPointer),
534                                        M4OSA_FILE_READER, (M4OSA_Char *)"M4OSA_FileReaderOptim_init");
535     if (M4OSA_NULL==apContext->FS)
536     {
537         M4OSA_TRACE1_0("M4OSA_FileReaderOptim_init - ERROR : allocation failed");
538         return M4ERR_ALLOC;
539     }
540     apContext->FS->openRead  = M4OSA_fileReadOpen;
541     apContext->FS->readData  = M4OSA_fileReadData;
542     apContext->FS->seek      = M4OSA_fileReadSeek;
543     apContext->FS->closeRead = M4OSA_fileReadClose;
544     apContext->FS->setOption = M4OSA_fileReadSetOption;
545     apContext->FS->getOption = M4OSA_fileReadGetOption;
546 #else
547     apContext->FS = FS;
548 #endif
549 
550     /* Verify access mode */
551     if (   ((FileModeAccess & M4OSA_kFileAppend) != 0)
552         || ((FileModeAccess & M4OSA_kFileRead) == 0))
553     {
554         err = M4ERR_FILE_BAD_MODE_ACCESS;
555         goto cleanup;
556     }
557 
558     /* Open file in read mode */
559     if((FileModeAccess & M4OSA_kFileCreate) != 0)
560     {
561         err = M4ERR_FILE_BAD_MODE_ACCESS;
562     }
563     else
564     {
565         if ((FileModeAccess & M4OSA_kFileRead))
566         {
567             /* File is opened in read only*/
568 #ifdef M4OSA_READER_OPTIM_USE_OSAL_IF
569             errno = apContext->FS->openRead(&aFileDesc, pFileDescriptor, FileModeAccess);
570 
571             if ((aFileDesc == M4OSA_NULL)||(M4NO_ERROR != errno))
572             {
573                 /* converts the error to PSW format*/
574                 err = errno;
575                 M4OSA_TRACE2_1("M4OSA_fileReadOpen_optim ERR1 = 0x%x", err);
576                 apContext->IsOpened = M4OSA_FALSE;
577             }
578 #else
579             aFileDesc = apContext->FS->pFctPtr_Open(pFileDescriptor, FileModeAccess, &errno);
580 
581             if (aFileDesc == M4OSA_NULL)
582             {
583                 /* converts the error to PSW format*/
584                 err = M4OSA_ERR_CREATE(M4_ERR, M4OSA_FILE_READER, errno);
585                 M4OSA_TRACE2_1("M4OSA_fileReadOpen_optim ERR1 = 0x%x", err);
586                 apContext->IsOpened = M4OSA_FALSE;
587             }
588 #endif
589 
590             else
591             {
592                 apContext->IsOpened = M4OSA_TRUE;
593             }
594         }
595         else
596         {
597             err = M4ERR_FILE_BAD_MODE_ACCESS;
598         }
599     }
600 
601     if (M4NO_ERROR != err) goto cleanup;
602 
603     /* Allocate buffers */
604     err = M4OSA_FileReader_BufferInit(apContext);
605     buffers_allocated = M4OSA_TRUE;
606 
607     if (M4NO_ERROR != err) goto cleanup;
608 
609     /* Initialize parameters */
610     apContext->fileSize = 0;
611     apContext->absolutePos = 0;
612     apContext->readFilePos = 0;
613 
614     /* Retrieve the File Descriptor*/
615     apContext->aFileDesc = aFileDesc;
616 
617     /* Retrieve the File mode Access */
618     apContext->FileAttribute.modeAccess = (M4OSA_FileModeAccess) FileModeAccess;
619 
620     /*Retrieve the File reader context */
621     *pContext= (M4OSA_Context)apContext;
622 
623     /* Compute file size */
624     err = M4OSA_FileReader_CalculateSize(apContext);
625 
626     if (M4NO_ERROR != err) goto cleanup;
627 
628     return M4NO_ERROR;
629 
630 cleanup:
631 
632     /* free context */
633     if (M4OSA_NULL != apContext)
634     {
635         if(buffers_allocated == M4OSA_TRUE)
636         {
637             M4OSA_FileReader_BufferFree(apContext);
638         }
639 
640         free( apContext);
641         *pContext = M4OSA_NULL;
642     }
643 
644     M4OSA_TRACE2_1 ("M4OSA_fileReadOpen_optim: returns error 0x%0x", err)
645     return err;
646 }
647 
648 /**
649 ******************************************************************************
650 * @brief       This method reads the 'size' bytes in the core file reader (selected by its 'context')
651 *                      and writes the data to the 'data' pointer. If 'size' byte can not be read in the core file reader,
652 *                      'size' parameter is updated to match the correct number of read bytes.
653 * @param       pContext:       (IN) File reader context.
654 * @param       pData : (OUT) Data pointer of the read data.
655 * @param       pSize : (INOUT) Size of the data to read (in byte).
656 * @return      M4NO_ERROR: there is no error
657 * @return      M4ERR_PARAMETER pSize, fileDescriptor or pData is NULL
658 * @return      M4ERR_ALLOC     there is no more memory available
659 * @return      M4ERR_BAD_CONTEXT       provided context is not a valid one.
660 ******************************************************************************
661 */
M4OSA_fileReadData_optim(M4OSA_Context pContext,M4OSA_MemAddr8 pData,M4OSA_UInt32 * pSize)662 M4OSA_ERR M4OSA_fileReadData_optim(M4OSA_Context pContext,M4OSA_MemAddr8 pData,
663                                                             M4OSA_UInt32* pSize)
664 {
665     M4OSA_FileReader_Context_optim* apContext =
666                                      (M4OSA_FileReader_Context_optim*) pContext;
667 
668     M4OSA_ERR err;
669     M4OSA_FilePosition aSize;
670     M4OSA_FilePosition copiedSize;
671     M4OSA_Int8 selected_buffer, current_buffer;
672 
673     M4OSA_TRACE3_3("M4OSA_fileReadData_optim p = 0x%p  d = 0x%p  s = %lu",
674                                                        pContext, pData, *pSize);
675 
676     /* Check input parameters */
677     M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_BAD_CONTEXT, apContext);
678     M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_PARAMETER, pData);
679     M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_PARAMETER, pSize);
680 
681     if (apContext->IsOpened != M4OSA_TRUE)
682     {
683         return M4ERR_BAD_CONTEXT;
684     }
685 
686     /* Prevent reading beyond EOF */
687     if((*pSize > 0) && (apContext->absolutePos >= apContext->fileSize))
688     {
689         copiedSize = 0;
690         err = M4WAR_NO_MORE_AU;
691         goto cleanup;
692     }
693 
694     /* Check if data can be read from a buffer */
695     /* If not, fill one according to quantized positions */
696     copiedSize = 0;
697     err = M4NO_ERROR;
698 
699     selected_buffer = M4OSA_FileReader_BufferMatch(apContext, apContext->absolutePos);
700 
701     if(selected_buffer == M4OSA_READBUFFER_NONE)
702     {
703         selected_buffer = M4OSA_FileReader_BufferSelect(apContext, 0);
704         err = M4OSA_FileReader_BufferFill(apContext, selected_buffer,
705                                                         apContext->absolutePos);
706     }
707 
708     if(err != M4NO_ERROR)
709     {
710         if(err == M4WAR_NO_DATA_YET)
711         {
712             if (*pSize <= (M4OSA_UInt32)apContext->buffer[selected_buffer].size)
713             {
714                 err = M4NO_ERROR;
715             }
716             else
717             {
718                 copiedSize = (M4OSA_UInt32)apContext->buffer[selected_buffer].size;
719                 /*copy the content into pData*/
720                 M4OSA_FileReader_BufferCopy(apContext, selected_buffer,
721                                      apContext->absolutePos, copiedSize, pData);
722                 goto cleanup;
723             }
724         }
725         else
726         {
727             goto cleanup;
728         }
729     }
730 
731     M4OSA_TRACE3_3("read  size = %lu  buffer = %d  pos = %ld", *pSize,
732                                        selected_buffer, apContext->absolutePos);
733 
734     /* Copy buffer into pData */
735     while(((M4OSA_UInt32)copiedSize < *pSize) && (err == M4NO_ERROR))
736     {
737         aSize = M4OSA_FileReader_BufferCopy(apContext, selected_buffer,
738                                             apContext->absolutePos+copiedSize,
739                                             *pSize-copiedSize, pData+copiedSize);
740         copiedSize += aSize;
741 
742         if(aSize == 0)
743         {
744             err = M4WAR_NO_DATA_YET;
745         }
746         else
747         {
748             if((M4OSA_UInt32)copiedSize < *pSize)
749             {
750                 current_buffer = selected_buffer;
751                 selected_buffer = M4OSA_FileReader_BufferMatch(apContext,
752                                              apContext->absolutePos+copiedSize);
753 
754                 if(selected_buffer == M4OSA_READBUFFER_NONE)
755                 {
756                     selected_buffer = M4OSA_FileReader_BufferSelect(apContext,
757                                                                 current_buffer);
758                     err = M4OSA_FileReader_BufferFill(apContext, selected_buffer,
759                                              apContext->absolutePos+copiedSize);
760 
761                     if(err != M4NO_ERROR)
762                     {
763                         if(err == M4WAR_NO_DATA_YET)
764                         {
765                             /*If we got all the data that we wanted, we should return no error*/
766                             if ((*pSize-copiedSize) <= (M4OSA_UInt32)apContext->buffer[selected_buffer].size)
767                             {
768                                 err = M4NO_ERROR;
769                             }
770                             /*If we did not get enough data, we will return NO_DATA_YET*/
771 
772                             /*copy the data read*/
773                             aSize = M4OSA_FileReader_BufferCopy(apContext, selected_buffer,
774                                                                apContext->absolutePos+copiedSize,
775                                                                *pSize-copiedSize, pData+copiedSize);
776                             copiedSize += aSize;
777 
778                             /*we reached end of file, so stop trying to read*/
779                             goto cleanup;
780                         }
781                         if (err == M4WAR_NO_MORE_AU)
782                         {
783                             err = M4WAR_NO_DATA_YET;
784 
785                             /*copy the data read*/
786                             aSize = M4OSA_FileReader_BufferCopy(apContext, selected_buffer,
787                                                              apContext->absolutePos+copiedSize,
788                                                              *pSize-copiedSize, pData+copiedSize);
789                             copiedSize += aSize;
790 
791                             /*we reached end of file, so stop trying to read*/
792                             goto cleanup;
793 
794                         }
795                         else
796                         {
797                             goto cleanup;
798                         }
799                     }
800                 }
801             }
802         }
803     }
804 
805 cleanup :
806 
807     /* Update the new position of the pointer */
808     apContext->absolutePos = apContext->absolutePos + copiedSize;
809 
810     if((err != M4NO_ERROR)&&(err!=M4WAR_NO_DATA_YET))
811     {
812         M4OSA_TRACE2_3("M4OSA_fileReadData_optim size = %ld  copied = %ld  err = 0x%x",
813                                                            *pSize, copiedSize, err);
814     }
815 
816     /* Effective copied size must be returned */
817     *pSize = copiedSize;
818 
819 
820     /* Read is done */
821     return err;
822 }
823 
824 /**
825 ******************************************************************************
826 * @brief       This method seeks at the provided position in the core file reader (selected by its 'context').
827 *              The position is related to the seekMode parameter it can be either :
828 *              From the beginning (position MUST be positive) : end position = position
829 *              From the end (position MUST be negative) : end position = file size + position
830 *              From the current position (signed offset) : end position = current position + position.
831 * @param       pContext:       (IN) File reader context.
832 * @param       SeekMode :      (IN) Seek access mode.
833 * @param       pPosition :     (IN) Position in the file.
834 * @return      M4NO_ERROR: there is no error
835 * @return      M4ERR_PARAMETER Seekmode or fileDescriptor is NULL
836 * @return      M4ERR_ALLOC     there is no more memory available
837 * @return      M4ERR_BAD_CONTEXT       provided context is not a valid one.
838 * @return      M4ERR_FILE_INVALID_POSITION the position cannot be reached.
839 ******************************************************************************
840 */
M4OSA_fileReadSeek_optim(M4OSA_Context pContext,M4OSA_FileSeekAccessMode SeekMode,M4OSA_FilePosition * pPosition)841 M4OSA_ERR M4OSA_fileReadSeek_optim( M4OSA_Context pContext, M4OSA_FileSeekAccessMode SeekMode,
842                                                               M4OSA_FilePosition* pPosition)
843 {
844     M4OSA_FileReader_Context_optim* apContext = (M4OSA_FileReader_Context_optim*) pContext;
845     M4OSA_ERR err = M4NO_ERROR;
846     M4OSA_TRACE3_3("M4OSA_fileReadSeek_optim p = 0x%p mode = %d pos = %d", pContext,
847                                                              SeekMode, *pPosition);
848 
849     /* Check input parameters */
850     M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_BAD_CONTEXT, apContext);
851     M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_PARAMETER, pPosition);
852     M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_PARAMETER, SeekMode);
853 
854     if (apContext->IsOpened != M4OSA_TRUE)
855     {
856         return M4ERR_BAD_CONTEXT;       /*< The context can not be correct */
857     }
858 
859     /* Go to the desired position */
860     switch(SeekMode)
861     {
862         case M4OSA_kFileSeekBeginning :
863             if(*pPosition < 0) {
864                 return M4ERR_PARAMETER; /**< Bad SeekAcess mode */
865             }
866             apContext->absolutePos = *pPosition;
867             *pPosition = apContext->absolutePos;
868             break;
869 
870         case M4OSA_kFileSeekEnd :
871             if(*pPosition > 0) {
872                 return M4ERR_PARAMETER; /**< Bad SeekAcess mode */
873             }
874             apContext->absolutePos = apContext->fileSize + *pPosition;
875             *pPosition = apContext->absolutePos;
876             break;
877 
878         case M4OSA_kFileSeekCurrent :
879             if(((apContext->absolutePos + *pPosition) > apContext->fileSize) ||
880                 ((apContext->absolutePos + *pPosition) < 0)){
881                 return M4ERR_PARAMETER; /**< Bad SeekAcess mode */
882             }
883             apContext->absolutePos = apContext->absolutePos + *pPosition;
884             *pPosition = apContext->absolutePos;
885             break;
886 
887         default :
888             err = M4ERR_PARAMETER; /**< Bad SeekAcess mode */
889             break;
890     }
891 
892     /* Return without error */
893     return err;
894 }
895 
896 /**
897 ******************************************************************************
898 * @brief       This method asks the core file reader to close the file
899 *              (associated to the context) and also frees the context.
900 * @param       pContext:       (IN) File reader context.
901 * @return      M4NO_ERROR: there is no error
902 * @return      M4ERR_BAD_CONTEXT       provided context is not a valid one.
903 ******************************************************************************
904 */
M4OSA_fileReadClose_optim(M4OSA_Context pContext)905 M4OSA_ERR M4OSA_fileReadClose_optim(M4OSA_Context pContext)
906 {
907     M4OSA_FileReader_Context_optim* apContext = (M4OSA_FileReader_Context_optim*) pContext;
908 
909     M4OSA_ERR err = M4NO_ERROR;
910 #ifdef M4OSA_READER_OPTIM_USE_OSAL_IF
911     M4OSA_ERR errno = M4NO_ERROR;
912 #else
913     M4OSA_UInt16 errno;
914 #endif
915 
916     M4OSA_TRACE2_1("M4OSA_fileReadClose_optim p = 0x%p", pContext );
917 
918     /* Check input parameters */
919     M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_BAD_CONTEXT, apContext);
920 
921     if (apContext->IsOpened != M4OSA_TRUE)
922     {
923         return M4ERR_BAD_CONTEXT;       /**< The context can not be correct */
924     }
925 
926     /* buffer */
927     M4OSA_FileReader_BufferFree(apContext);
928 
929     /* Close the file */
930 #ifdef M4OSA_READER_OPTIM_USE_OSAL_IF
931     errno = apContext->FS->closeRead(apContext->aFileDesc);
932 
933     if (M4NO_ERROR != errno)
934     {
935         /* converts the error to PSW format*/
936         err = errno;
937         M4OSA_TRACE2_1("M4OSA_fileReadClose_optim ERR1 = 0x%x", err);
938     }
939 #else
940     aRet_Val = apContext->FS->pFctPtr_Close(apContext->aFileDesc, &errno);
941 
942     if (aRet_Val != 0)
943     {
944         /* converts the error to PSW format*/
945         err = M4OSA_ERR_CREATE(M4_ERR, M4OSA_FILE_READER, errno);
946         M4OSA_TRACE2_1("M4OSA_fileReadClose_optim ERR1 = 0x%x", err);
947     }
948 #endif /*M4OSA_READER_OPTIM_USE_OSAL_IF*/
949 
950     apContext->IsOpened = M4OSA_FALSE;
951 
952     //>>>> GLM20090212 : set the low level function statically
953     if (apContext->FS != M4OSA_NULL)
954     {
955         free( apContext->FS);
956     }
957     //<<<< GLM20090212 : set the low level function statically
958 
959     /* Free the context */
960     free(apContext);
961 
962     /* Return without error */
963     return err;
964 }
965 
966 /**
967 ******************************************************************************
968 * @brief       This is a dummy function required to maintain function pointer
969 *              structure.
970 * @note        This is a dummy function required to maintain function pointer
971 *              structure.
972 * @param       pContext:       (IN) Execution context.
973 * @param       OptionId :      (IN) Id of the option to set.
974 * @param       OptionValue :   (IN) Value of the option.
975 * @return      M4NO_ERROR: there is no error
976 ******************************************************************************
977 */
M4OSA_fileReadSetOption_optim(M4OSA_Context pContext,M4OSA_FileReadOptionID OptionID,M4OSA_DataOption OptionValue)978 M4OSA_ERR M4OSA_fileReadSetOption_optim(M4OSA_Context pContext,
979                                         M4OSA_FileReadOptionID OptionID,
980                                         M4OSA_DataOption OptionValue)
981 {
982     M4OSA_ERR err = M4NO_ERROR;
983     return err;
984 }
985 
986 /**
987 ******************************************************************************
988 * @brief       This method asks the core file reader to return the value associated
989 *              with the optionID.The caller is responsible for allocating/de-allocating
990 *              the memory of the value field.
991 * @note        The options handled by the component depend on the implementation
992 *                                                               of the component.
993 * @param       pContext:       (IN) Execution context.
994 * @param       OptionId :      (IN) Id of the option to set.
995 * @param       pOptionValue :  (OUT) Value of the option.
996 * @return      M4NO_ERROR: there is no error
997 * @return      M4ERR_BAD_CONTEXT       pContext is NULL
998 * @return      M4ERR_BAD_OPTION_ID the option id is not valid.
999 * @return      M4ERR_NOT_IMPLEMENTED The option is not implemented yet.
1000 ******************************************************************************
1001 */
M4OSA_fileReadGetOption_optim(M4OSA_Context pContext,M4OSA_FileReadOptionID OptionID,M4OSA_DataOption * pOptionValue)1002 M4OSA_ERR M4OSA_fileReadGetOption_optim(M4OSA_Context pContext,
1003                                         M4OSA_FileReadOptionID OptionID,
1004                                         M4OSA_DataOption* pOptionValue)
1005 {
1006     M4OSA_FileReader_Context_optim* apContext = (M4OSA_FileReader_Context_optim*) pContext;
1007     M4OSA_ERR err = M4NO_ERROR;
1008 
1009     /*  Check input parameters */
1010     M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_BAD_CONTEXT, apContext);
1011 
1012     if (apContext->IsOpened != M4OSA_TRUE)
1013     {
1014         return M4ERR_BAD_CONTEXT;       /**< The context can not be correct */
1015     }
1016 
1017     /* Get the desired option if it is avalaible */
1018     switch(OptionID)
1019     {
1020         /* Get File Size */
1021         case M4OSA_kFileReadGetFileSize:/**< Get size of the file, limited to 32 bit size */
1022 
1023             (*(M4OSA_UInt32 *)pOptionValue) = apContext->fileSize;
1024             break;
1025 
1026         /* Check End of file Occurs */
1027         case M4OSA_kFileReadIsEOF :     /**< See if we are at the end of the file */
1028 
1029             (*(M4OSA_Bool *)pOptionValue) = (apContext->absolutePos >= apContext->fileSize) ? M4OSA_TRUE : M4OSA_FALSE;
1030             break;
1031 
1032         /* Get File Position */
1033         case M4OSA_kFileReadGetFilePosition :   /**< Get file position */
1034 
1035             *(M4OSA_FilePosition *)pOptionValue = apContext->absolutePos;
1036             break;
1037 
1038         /* Get Attribute */
1039         case M4OSA_kFileReadGetFileAttribute :  /**< Get the file attribute = access mode */
1040 
1041             (*(M4OSA_FileAttribute *)pOptionValue).modeAccess = apContext->FileAttribute.modeAccess;
1042             break;
1043 
1044         default:
1045             /**< Bad option ID */
1046             err = M4ERR_BAD_OPTION_ID;
1047             break;
1048     }
1049 
1050     /*Return without error */
1051     return err;
1052 }
1053