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