LVOSA_FileReader_optim.c revision 3b25fdc4a33b53cfcf67315c2d42ad699b8cefe2
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#else 454 ret_val = apContext->FS->pFctPtr_Seek(apContext->aFileDesc, 0, M4OSA_kFileSeekEnd, &errno); 455 456 if (ret_val != 0) 457 { 458 apContext->readFilePos = M4OSA_EOF; 459 err = M4OSA_ERR_CREATE(M4_ERR, M4OSA_FILE_READER, errno); 460 M4OSA_TRACE1_1("M4OSA_FileReader_CalculateSize ERR = 0x%x", err); 461 } 462 else 463 { 464 /* Retrieve size of the file */ 465 apContext->fileSize = apContext->FS->pFctPtr_Tell(apContext->aFileDesc, &errno); 466 apContext->readFilePos = apContext->fileSize; 467 } 468#endif /*M4OSA_READER_OPTIM_USE_OSAL_IF*/ 469 470 return err; 471} 472 473 474/* __________________________________________________________ */ 475/*| |*/ 476/*| OSAL filesystem API |*/ 477/*|__________________________________________________________|*/ 478 479/** 480****************************************************************************** 481* @brief This method opens the provided fileDescriptor and returns its context. 482* @param pContext: (OUT) File reader context. 483* @param pFileDescriptor : (IN) File Descriptor of the input file. 484* @param FileModeAccess : (IN) File mode access. 485* @return M4NO_ERROR: there is no error 486* @return M4ERR_PARAMETER pContext or fileDescriptor is NULL 487* @return M4ERR_ALLOC there is no more memory available 488* @return M4ERR_FILE_BAD_MODE_ACCESS the file mode access is not correct (it must be either isTextMode or read) 489* @return M4ERR_FILE_NOT_FOUND The file can not be opened. 490****************************************************************************** 491*/ 492#ifdef M4OSA_READER_OPTIM_USE_OSAL_IF 493 M4OSA_ERR M4OSA_fileReadOpen_optim(M4OSA_Context* pContext, 494 M4OSA_Void* pFileDescriptor, 495 M4OSA_UInt32 FileModeAccess) 496#else 497 M4OSA_ERR M4OSA_fileReadOpen_optim(M4OSA_Context* pContext, 498 M4OSA_Void* pFileDescriptor, 499 M4OSA_UInt32 FileModeAccess, 500 M4OSA_FileSystem_FctPtr *FS) 501#endif 502{ 503 M4OSA_FileReader_Context_optim* apContext = M4OSA_NULL; 504 505 M4OSA_ERR err = M4NO_ERROR; 506 M4OSA_Void* aFileDesc = M4OSA_NULL; 507 M4OSA_Bool buffers_allocated = M4OSA_FALSE; 508#ifdef M4OSA_READER_OPTIM_USE_OSAL_IF 509 M4OSA_ERR errno = M4NO_ERROR; 510#else 511 M4OSA_UInt16 errno; 512#endif /*M4OSA_READER_OPTIM_USE_OSAL_IF*/ 513 514 M4OSA_TRACE2_3("M4OSA_fileReadOpen_optim p = 0x%p fd = %s mode = %lu", pContext, 515 pFileDescriptor, FileModeAccess); 516 517 /* Check input parameters */ 518 M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_PARAMETER, pContext); 519 M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_PARAMETER, pFileDescriptor); 520 521 *pContext = M4OSA_NULL; 522 523 /* Allocate memory for the File reader context. */ 524 apContext = (M4OSA_FileReader_Context_optim *)M4OSA_32bitAlignedMalloc(sizeof(M4OSA_FileReader_Context_optim), 525 M4OSA_FILE_READER, (M4OSA_Char *)"M4OSA_FileReader_Context_optim"); 526 527 M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_ALLOC, apContext); 528 529 /* Set filesystem interface */ 530#ifdef M4OSA_READER_OPTIM_USE_OSAL_IF 531 532 /*Set the optimized functions, to be called by the user*/ 533 534 apContext->FS = (M4OSA_FileReadPointer*) M4OSA_32bitAlignedMalloc(sizeof(M4OSA_FileReadPointer), 535 M4OSA_FILE_READER, (M4OSA_Char *)"M4OSA_FileReaderOptim_init"); 536 if (M4OSA_NULL==apContext->FS) 537 { 538 M4OSA_TRACE1_0("M4OSA_FileReaderOptim_init - ERROR : allocation failed"); 539 return M4ERR_ALLOC; 540 } 541 apContext->FS->openRead = M4OSA_fileReadOpen; 542 apContext->FS->readData = M4OSA_fileReadData; 543 apContext->FS->seek = M4OSA_fileReadSeek; 544 apContext->FS->closeRead = M4OSA_fileReadClose; 545 apContext->FS->setOption = M4OSA_fileReadSetOption; 546 apContext->FS->getOption = M4OSA_fileReadGetOption; 547#else 548 apContext->FS = FS; 549#endif 550 551 /* Verify access mode */ 552 if ( ((FileModeAccess & M4OSA_kFileAppend) != 0) 553 || ((FileModeAccess & M4OSA_kFileRead) == 0)) 554 { 555 err = M4ERR_FILE_BAD_MODE_ACCESS; 556 goto cleanup; 557 } 558 559 /* Open file in read mode */ 560 if((FileModeAccess & M4OSA_kFileCreate) != 0) 561 { 562 err = M4ERR_FILE_BAD_MODE_ACCESS; 563 } 564 else 565 { 566 if ((FileModeAccess & M4OSA_kFileRead)) 567 { 568 /* File is opened in read only*/ 569#ifdef M4OSA_READER_OPTIM_USE_OSAL_IF 570 errno = apContext->FS->openRead(&aFileDesc, pFileDescriptor, FileModeAccess); 571 572 if ((aFileDesc == M4OSA_NULL)||(M4NO_ERROR != errno)) 573 { 574 /* converts the error to PSW format*/ 575 err = errno; 576 M4OSA_TRACE2_1("M4OSA_fileReadOpen_optim ERR1 = 0x%x", err); 577 apContext->IsOpened = M4OSA_FALSE; 578 } 579#else 580 aFileDesc = apContext->FS->pFctPtr_Open(pFileDescriptor, FileModeAccess, &errno); 581 582 if (aFileDesc == M4OSA_NULL) 583 { 584 /* converts the error to PSW format*/ 585 err = M4OSA_ERR_CREATE(M4_ERR, M4OSA_FILE_READER, errno); 586 M4OSA_TRACE2_1("M4OSA_fileReadOpen_optim ERR1 = 0x%x", err); 587 apContext->IsOpened = M4OSA_FALSE; 588 } 589#endif 590 591 else 592 { 593 apContext->IsOpened = M4OSA_TRUE; 594 } 595 } 596 else 597 { 598 err = M4ERR_FILE_BAD_MODE_ACCESS; 599 } 600 } 601 602 if (M4NO_ERROR != err) goto cleanup; 603 604 /* Allocate buffers */ 605 err = M4OSA_FileReader_BufferInit(apContext); 606 buffers_allocated = M4OSA_TRUE; 607 608 if (M4NO_ERROR != err) goto cleanup; 609 610 /* Initialize parameters */ 611 apContext->fileSize = 0; 612 apContext->absolutePos = 0; 613 apContext->readFilePos = 0; 614 615 /* Retrieve the File Descriptor*/ 616 apContext->aFileDesc = aFileDesc; 617 618 /* Retrieve the File mode Access */ 619 apContext->FileAttribute.modeAccess = (M4OSA_FileModeAccess) FileModeAccess; 620 621 /*Retrieve the File reader context */ 622 *pContext= (M4OSA_Context)apContext; 623 624 /* Compute file size */ 625 err = M4OSA_FileReader_CalculateSize(apContext); 626 627 if (M4NO_ERROR != err) goto cleanup; 628 629 return M4NO_ERROR; 630 631cleanup: 632 633 /* free context */ 634 if (M4OSA_NULL != apContext) 635 { 636 if(buffers_allocated == M4OSA_TRUE) 637 { 638 M4OSA_FileReader_BufferFree(apContext); 639 } 640 641 free( apContext); 642 *pContext = M4OSA_NULL; 643 } 644 645 M4OSA_TRACE2_1 ("M4OSA_fileReadOpen_optim: returns error 0x%0x", err) 646 return err; 647} 648 649/** 650****************************************************************************** 651* @brief This method reads the 'size' bytes in the core file reader (selected by its 'context') 652* and writes the data to the 'data' pointer. If 'size' byte can not be read in the core file reader, 653* 'size' parameter is updated to match the correct number of read bytes. 654* @param pContext: (IN) File reader context. 655* @param pData : (OUT) Data pointer of the read data. 656* @param pSize : (INOUT) Size of the data to read (in byte). 657* @return M4NO_ERROR: there is no error 658* @return M4ERR_PARAMETER pSize, fileDescriptor or pData is NULL 659* @return M4ERR_ALLOC there is no more memory available 660* @return M4ERR_BAD_CONTEXT provided context is not a valid one. 661****************************************************************************** 662*/ 663M4OSA_ERR M4OSA_fileReadData_optim(M4OSA_Context pContext,M4OSA_MemAddr8 pData, 664 M4OSA_UInt32* pSize) 665{ 666 M4OSA_FileReader_Context_optim* apContext = 667 (M4OSA_FileReader_Context_optim*) pContext; 668 669 M4OSA_ERR err; 670 M4OSA_FilePosition aSize; 671 M4OSA_FilePosition copiedSize; 672 M4OSA_Int8 selected_buffer, current_buffer; 673 674 M4OSA_TRACE3_3("M4OSA_fileReadData_optim p = 0x%p d = 0x%p s = %lu", 675 pContext, pData, *pSize); 676 677 /* Check input parameters */ 678 M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_BAD_CONTEXT, apContext); 679 M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_PARAMETER, pData); 680 M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_PARAMETER, pSize); 681 682 if (apContext->IsOpened != M4OSA_TRUE) 683 { 684 return M4ERR_BAD_CONTEXT; 685 } 686 687 /* Prevent reading beyond EOF */ 688 if((*pSize > 0) && (apContext->absolutePos >= apContext->fileSize)) 689 { 690 copiedSize = 0; 691 err = M4WAR_NO_MORE_AU; 692 goto cleanup; 693 } 694 695 /* Check if data can be read from a buffer */ 696 /* If not, fill one according to quantized positions */ 697 copiedSize = 0; 698 err = M4NO_ERROR; 699 700 selected_buffer = M4OSA_FileReader_BufferMatch(apContext, apContext->absolutePos); 701 702 if(selected_buffer == M4OSA_READBUFFER_NONE) 703 { 704 selected_buffer = M4OSA_FileReader_BufferSelect(apContext, 0); 705 err = M4OSA_FileReader_BufferFill(apContext, selected_buffer, 706 apContext->absolutePos); 707 } 708 709 if(err != M4NO_ERROR) 710 { 711 if(err == M4WAR_NO_DATA_YET) 712 { 713 if (*pSize <= (M4OSA_UInt32)apContext->buffer[selected_buffer].size) 714 { 715 err = M4NO_ERROR; 716 } 717 else 718 { 719 copiedSize = (M4OSA_UInt32)apContext->buffer[selected_buffer].size; 720 /*copy the content into pData*/ 721 M4OSA_FileReader_BufferCopy(apContext, selected_buffer, 722 apContext->absolutePos, copiedSize, pData); 723 goto cleanup; 724 } 725 } 726 else 727 { 728 goto cleanup; 729 } 730 } 731 732 M4OSA_TRACE3_3("read size = %lu buffer = %d pos = %ld", *pSize, 733 selected_buffer, apContext->absolutePos); 734 735 /* Copy buffer into pData */ 736 while(((M4OSA_UInt32)copiedSize < *pSize) && (err == M4NO_ERROR)) 737 { 738 aSize = M4OSA_FileReader_BufferCopy(apContext, selected_buffer, 739 apContext->absolutePos+copiedSize, 740 *pSize-copiedSize, pData+copiedSize); 741 copiedSize += aSize; 742 743 if(aSize == 0) 744 { 745 err = M4WAR_NO_DATA_YET; 746 } 747 else 748 { 749 if((M4OSA_UInt32)copiedSize < *pSize) 750 { 751 current_buffer = selected_buffer; 752 selected_buffer = M4OSA_FileReader_BufferMatch(apContext, 753 apContext->absolutePos+copiedSize); 754 755 if(selected_buffer == M4OSA_READBUFFER_NONE) 756 { 757 selected_buffer = M4OSA_FileReader_BufferSelect(apContext, 758 current_buffer); 759 err = M4OSA_FileReader_BufferFill(apContext, selected_buffer, 760 apContext->absolutePos+copiedSize); 761 762 if(err != M4NO_ERROR) 763 { 764 if(err == M4WAR_NO_DATA_YET) 765 { 766 /*If we got all the data that we wanted, we should return no error*/ 767 if ((*pSize-copiedSize) <= (M4OSA_UInt32)apContext->buffer[selected_buffer].size) 768 { 769 err = M4NO_ERROR; 770 } 771 /*If we did not get enough data, we will return NO_DATA_YET*/ 772 773 /*copy the data read*/ 774 aSize = M4OSA_FileReader_BufferCopy(apContext, selected_buffer, 775 apContext->absolutePos+copiedSize, 776 *pSize-copiedSize, pData+copiedSize); 777 copiedSize += aSize; 778 779 /*we reached end of file, so stop trying to read*/ 780 goto cleanup; 781 } 782 if (err == M4WAR_NO_MORE_AU) 783 { 784 err = M4WAR_NO_DATA_YET; 785 786 /*copy the data read*/ 787 aSize = M4OSA_FileReader_BufferCopy(apContext, selected_buffer, 788 apContext->absolutePos+copiedSize, 789 *pSize-copiedSize, pData+copiedSize); 790 copiedSize += aSize; 791 792 /*we reached end of file, so stop trying to read*/ 793 goto cleanup; 794 795 } 796 else 797 { 798 goto cleanup; 799 } 800 } 801 } 802 } 803 } 804 } 805 806cleanup : 807 808 /* Update the new position of the pointer */ 809 apContext->absolutePos = apContext->absolutePos + copiedSize; 810 811 if((err != M4NO_ERROR)&&(err!=M4WAR_NO_DATA_YET)) 812 { 813 M4OSA_TRACE2_3("M4OSA_fileReadData_optim size = %ld copied = %ld err = 0x%x", 814 *pSize, copiedSize, err); 815 } 816 817 /* Effective copied size must be returned */ 818 *pSize = copiedSize; 819 820 821 /* Read is done */ 822 return err; 823} 824 825/** 826****************************************************************************** 827* @brief This method seeks at the provided position in the core file reader (selected by its 'context'). 828* The position is related to the seekMode parameter it can be either : 829* From the beginning (position MUST be positive) : end position = position 830* From the end (position MUST be negative) : end position = file size + position 831* From the current position (signed offset) : end position = current position + position. 832* @param pContext: (IN) File reader context. 833* @param SeekMode : (IN) Seek access mode. 834* @param pPosition : (IN) Position in the file. 835* @return M4NO_ERROR: there is no error 836* @return M4ERR_PARAMETER Seekmode or fileDescriptor is NULL 837* @return M4ERR_ALLOC there is no more memory available 838* @return M4ERR_BAD_CONTEXT provided context is not a valid one. 839* @return M4ERR_FILE_INVALID_POSITION the position cannot be reached. 840****************************************************************************** 841*/ 842M4OSA_ERR M4OSA_fileReadSeek_optim( M4OSA_Context pContext, M4OSA_FileSeekAccessMode SeekMode, 843 M4OSA_FilePosition* pPosition) 844{ 845 M4OSA_FileReader_Context_optim* apContext = (M4OSA_FileReader_Context_optim*) pContext; 846 M4OSA_ERR err = M4NO_ERROR; 847 M4OSA_TRACE3_3("M4OSA_fileReadSeek_optim p = 0x%p mode = %d pos = %d", pContext, 848 SeekMode, *pPosition); 849 850 /* Check input parameters */ 851 M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_BAD_CONTEXT, apContext); 852 M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_PARAMETER, pPosition); 853 M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_PARAMETER, SeekMode); 854 855 if (apContext->IsOpened != M4OSA_TRUE) 856 { 857 return M4ERR_BAD_CONTEXT; /*< The context can not be correct */ 858 } 859 860 /* Go to the desired position */ 861 switch(SeekMode) 862 { 863 case M4OSA_kFileSeekBeginning : 864 if(*pPosition < 0) { 865 return M4ERR_PARAMETER; /**< Bad SeekAcess mode */ 866 } 867 apContext->absolutePos = *pPosition; 868 *pPosition = apContext->absolutePos; 869 break; 870 871 case M4OSA_kFileSeekEnd : 872 if(*pPosition > 0) { 873 return M4ERR_PARAMETER; /**< Bad SeekAcess mode */ 874 } 875 apContext->absolutePos = apContext->fileSize + *pPosition; 876 *pPosition = apContext->absolutePos; 877 break; 878 879 case M4OSA_kFileSeekCurrent : 880 if(((apContext->absolutePos + *pPosition) > apContext->fileSize) || 881 ((apContext->absolutePos + *pPosition) < 0)){ 882 return M4ERR_PARAMETER; /**< Bad SeekAcess mode */ 883 } 884 apContext->absolutePos = apContext->absolutePos + *pPosition; 885 *pPosition = apContext->absolutePos; 886 break; 887 888 default : 889 err = M4ERR_PARAMETER; /**< Bad SeekAcess mode */ 890 break; 891 } 892 893 /* Return without error */ 894 return err; 895} 896 897/** 898****************************************************************************** 899* @brief This method asks the core file reader to close the file 900* (associated to the context) and also frees the context. 901* @param pContext: (IN) File reader context. 902* @return M4NO_ERROR: there is no error 903* @return M4ERR_BAD_CONTEXT provided context is not a valid one. 904****************************************************************************** 905*/ 906M4OSA_ERR M4OSA_fileReadClose_optim(M4OSA_Context pContext) 907{ 908 M4OSA_FileReader_Context_optim* apContext = (M4OSA_FileReader_Context_optim*) pContext; 909 910 M4OSA_ERR err = M4NO_ERROR; 911#ifdef M4OSA_READER_OPTIM_USE_OSAL_IF 912 M4OSA_ERR errno = M4NO_ERROR; 913#else 914 M4OSA_UInt16 errno; 915#endif 916 917 M4OSA_TRACE2_1("M4OSA_fileReadClose_optim p = 0x%p", pContext ); 918 919 /* Check input parameters */ 920 M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_BAD_CONTEXT, apContext); 921 922 if (apContext->IsOpened != M4OSA_TRUE) 923 { 924 return M4ERR_BAD_CONTEXT; /**< The context can not be correct */ 925 } 926 927 /* buffer */ 928 M4OSA_FileReader_BufferFree(apContext); 929 930 /* Close the file */ 931#ifdef M4OSA_READER_OPTIM_USE_OSAL_IF 932 errno = apContext->FS->closeRead(apContext->aFileDesc); 933 934 if (M4NO_ERROR != errno) 935 { 936 /* converts the error to PSW format*/ 937 err = errno; 938 M4OSA_TRACE2_1("M4OSA_fileReadClose_optim ERR1 = 0x%x", err); 939 } 940#else 941 aRet_Val = apContext->FS->pFctPtr_Close(apContext->aFileDesc, &errno); 942 943 if (aRet_Val != 0) 944 { 945 /* converts the error to PSW format*/ 946 err = M4OSA_ERR_CREATE(M4_ERR, M4OSA_FILE_READER, errno); 947 M4OSA_TRACE2_1("M4OSA_fileReadClose_optim ERR1 = 0x%x", err); 948 } 949#endif /*M4OSA_READER_OPTIM_USE_OSAL_IF*/ 950 951 apContext->IsOpened = M4OSA_FALSE; 952 953 //>>>> GLM20090212 : set the low level function statically 954 if (apContext->FS != M4OSA_NULL) 955 { 956 free( apContext->FS); 957 } 958 //<<<< GLM20090212 : set the low level function statically 959 960 /* Free the context */ 961 free(apContext); 962 963 /* Return without error */ 964 return err; 965} 966 967/** 968****************************************************************************** 969* @brief This is a dummy function required to maintain function pointer 970* structure. 971* @note This is a dummy function required to maintain function pointer 972* structure. 973* @param pContext: (IN) Execution context. 974* @param OptionId : (IN) Id of the option to set. 975* @param OptionValue : (IN) Value of the option. 976* @return M4NO_ERROR: there is no error 977****************************************************************************** 978*/ 979M4OSA_ERR M4OSA_fileReadSetOption_optim(M4OSA_Context pContext, 980 M4OSA_FileReadOptionID OptionID, 981 M4OSA_DataOption OptionValue) 982{ 983 M4OSA_ERR err = M4NO_ERROR; 984 return err; 985} 986 987/** 988****************************************************************************** 989* @brief This method asks the core file reader to return the value associated 990* with the optionID.The caller is responsible for allocating/de-allocating 991* the memory of the value field. 992* @note The options handled by the component depend on the implementation 993* of the component. 994* @param pContext: (IN) Execution context. 995* @param OptionId : (IN) Id of the option to set. 996* @param pOptionValue : (OUT) Value of the option. 997* @return M4NO_ERROR: there is no error 998* @return M4ERR_BAD_CONTEXT pContext is NULL 999* @return M4ERR_BAD_OPTION_ID the option id is not valid. 1000* @return M4ERR_NOT_IMPLEMENTED The option is not implemented yet. 1001****************************************************************************** 1002*/ 1003M4OSA_ERR M4OSA_fileReadGetOption_optim(M4OSA_Context pContext, 1004 M4OSA_FileReadOptionID OptionID, 1005 M4OSA_DataOption* pOptionValue) 1006{ 1007 M4OSA_FileReader_Context_optim* apContext = (M4OSA_FileReader_Context_optim*) pContext; 1008 M4OSA_ERR err = M4NO_ERROR; 1009 1010 /* Check input parameters */ 1011 M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_BAD_CONTEXT, apContext); 1012 1013 if (apContext->IsOpened != M4OSA_TRUE) 1014 { 1015 return M4ERR_BAD_CONTEXT; /**< The context can not be correct */ 1016 } 1017 1018 /* Get the desired option if it is avalaible */ 1019 switch(OptionID) 1020 { 1021 /* Get File Size */ 1022 case M4OSA_kFileReadGetFileSize:/**< Get size of the file, limited to 32 bit size */ 1023 1024 (*(M4OSA_UInt32 *)pOptionValue) = apContext->fileSize; 1025 break; 1026 1027 /* Check End of file Occurs */ 1028 case M4OSA_kFileReadIsEOF : /**< See if we are at the end of the file */ 1029 1030 (*(M4OSA_Bool *)pOptionValue) = (apContext->absolutePos >= apContext->fileSize) ? M4OSA_TRUE : M4OSA_FALSE; 1031 break; 1032 1033 /* Get File Position */ 1034 case M4OSA_kFileReadGetFilePosition : /**< Get file position */ 1035 1036 *(M4OSA_FilePosition *)pOptionValue = apContext->absolutePos; 1037 break; 1038 1039 /* Get Attribute */ 1040 case M4OSA_kFileReadGetFileAttribute : /**< Get the file attribute = access mode */ 1041 1042 (*(M4OSA_FileAttribute *)pOptionValue).modeAccess = apContext->FileAttribute.modeAccess; 1043 break; 1044 1045 default: 1046 /**< Bad option ID */ 1047 err = M4ERR_BAD_OPTION_ID; 1048 break; 1049 } 1050 1051 /*Return without error */ 1052 return err; 1053} 1054