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*/ 71typedef 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*/ 87typedef 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 112static M4OSA_FileReadPointer* gv_NXPSW_READOPT_lowLevelFunctions; 113 114M4OSA_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 131M4OSA_ERR NXPSW_FileReaderOptim_cleanUp() 132{ 133 134 gv_NXPSW_READOPT_lowLevelFunctions = M4OSA_NULL; 135 136 return M4NO_ERROR; 137} 138 139 140M4OSA_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/**************************************************************/ 154M4OSA_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/**************************************************************/ 178M4OSA_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/**************************************************************/ 189M4OSA_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/**************************************************************/ 219M4OSA_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/**************************************************************/ 351M4OSA_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/**************************************************************/ 371M4OSA_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/**************************************************************/ 432M4OSA_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 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 630cleanup: 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*/ 662M4OSA_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 805cleanup : 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*/ 841M4OSA_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*/ 905M4OSA_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*/ 978M4OSA_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*/ 1002M4OSA_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