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