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