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