diff options
Diffstat (limited to 'libvideoeditor/osal/src/LVOSA_FileReader_optim.c')
-rwxr-xr-x | libvideoeditor/osal/src/LVOSA_FileReader_optim.c | 1076 |
1 files changed, 1076 insertions, 0 deletions
diff --git a/libvideoeditor/osal/src/LVOSA_FileReader_optim.c b/libvideoeditor/osal/src/LVOSA_FileReader_optim.c new file mode 100755 index 0000000..36541f0 --- /dev/null +++ b/libvideoeditor/osal/src/LVOSA_FileReader_optim.c @@ -0,0 +1,1076 @@ +/* + * Copyright (C) 2004-2011 NXP Software + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + ****************************************************************************** + * @file M4OSA_FileReader_optim.c + * @brief + * @note This file implements functions to manipulate filesystem access + ****************************************************************************** +*/ + +/** Addition of Trace ID **/ +#include "M4OSA_CoreID.h" +#include "M4OSA_Error.h" + +#ifdef M4TRACE_ID +#undef M4TRACE_ID +#endif +#define M4TRACE_ID M4OSA_FILE_READER + + +#include "M4OSA_FileCommon.h" +#include "M4OSA_FileReader.h" +#include "M4OSA_FileWriter.h" +#include "M4OSA_Memory.h" +#include "M4OSA_Debug.h" + +#include "LVOSA_FileReader_optim.h" + +#define M4OSA_READER_OPTIM_USE_OSAL_IF +#ifndef M4OSA_READER_OPTIM_USE_OSAL_IF + #include "M4OSA_FileAccess.h" +#endif + +#define M4ERR_CHECK_NULL_RETURN_VALUE(retval, pointer) if ((pointer) == M4OSA_NULL) return (retval); + + + + +/** + ****************************************************************************** + * File reader cache buffers parameters (size, number of buffers, etc) + ****************************************************************************** +*/ +#define M4OSA_READBUFFER_SIZE 1024*16 +#define M4OSA_READBUFFER_NB 2 +#define M4OSA_READBUFFER_NONE -1 +#define M4OSA_EOF -1 + +#define MAX_FILLS_SINCE_LAST_ACCESS M4OSA_READBUFFER_NB*2 + +/** + ****************************************************************************** + * structure M4OSA_FileReader_Buffer + * @brief This structure defines the File reader Buffers context (private) + ****************************************************************************** +*/ +typedef struct +{ + M4OSA_MemAddr8 data; /**< buffer data */ + M4OSA_FilePosition size; /**< size of the buffer */ + M4OSA_FilePosition filepos; /**< position in the file where the buffer starts */ + M4OSA_FilePosition remain; /**< data amount not already copied from buffer */ + M4OSA_UInt32 nbFillSinceLastAcess; /**< To know since how many time we didn't use this buffer */ +} M4OSA_FileReader_Buffer_optim; + +/** + ****************************************************************************** + * structure M4OSA_FileReader_Context + * @brief This structure defines the File reader context (private) + * @note This structure is used for all File Reader calls to store the context + ****************************************************************************** +*/ +typedef struct +{ + M4OSA_Bool IsOpened; /**< Micro state machine */ + M4OSA_FileAttribute FileAttribute; /**< Opening mode */ + M4OSA_FilePosition readFilePos; /**< Effective position of the GFL read pointer */ + M4OSA_FilePosition absolutePos; /**< Virtual position for next reading */ + M4OSA_FilePosition fileSize; /**< Size of the file */ + + M4OSA_FileReader_Buffer_optim buffer[M4OSA_READBUFFER_NB]; /**< Read buffers */ + + M4OSA_Void* aFileDesc; /**< File descriptor */ + +#ifdef M4OSA_READER_OPTIM_USE_OSAL_IF + M4OSA_FileReadPointer* FS; /**< Filesystem interface */ +#else + M4OSA_FileSystem_FctPtr *FS; /**< Filesystem interface */ +#endif + +} M4OSA_FileReader_Context_optim; + +/* __________________________________________________________ */ +/*| |*/ +/*| Global function for handling low level read access |*/ +/*|__________________________________________________________|*/ + +static M4OSA_FileReadPointer* gv_NXPSW_READOPT_lowLevelFunctions; + +M4OSA_ERR NXPSW_FileReaderOptim_init(M4OSA_Void *lowLevel_functionPointers, M4OSA_Void *optimized_functionPointers) +{ + M4OSA_FileReadPointer* lowLevel_fp = (M4OSA_FileReadPointer*) lowLevel_functionPointers; + M4OSA_FileReadPointer* optimized_fp = (M4OSA_FileReadPointer*) optimized_functionPointers; + + //Set the optimized functions, to be called by the user + optimized_fp->openRead = M4OSA_fileReadOpen_optim; + optimized_fp->readData = M4OSA_fileReadData_optim; + optimized_fp->seek = M4OSA_fileReadSeek_optim; + optimized_fp->closeRead = M4OSA_fileReadClose_optim; + optimized_fp->setOption = M4OSA_fileReadSetOption_optim; + optimized_fp->getOption = M4OSA_fileReadGetOption_optim; + + + return M4NO_ERROR; +} + +M4OSA_ERR NXPSW_FileReaderOptim_cleanUp() +{ + + gv_NXPSW_READOPT_lowLevelFunctions = M4OSA_NULL; + + return M4NO_ERROR; +} + + +M4OSA_ERR NXPSW_FileReaderOptim_getLowLevelFunctions(M4OSA_Void **FS) +{ + M4OSA_FileReadPointer** pFunctionsPointer = (M4OSA_FileReadPointer**) FS; + *pFunctionsPointer = gv_NXPSW_READOPT_lowLevelFunctions; + return M4NO_ERROR; +} + + +/* __________________________________________________________ */ +/*| |*/ +/*| Buffer handling functions for Read access |*/ +/*|__________________________________________________________|*/ + +/**************************************************************/ +M4OSA_ERR M4OSA_FileReader_BufferInit(M4OSA_FileReader_Context_optim* apContext) +/**************************************************************/ +{ + M4OSA_UInt8 i; + + for(i=0; i<M4OSA_READBUFFER_NB; i++) + { + apContext->buffer[i].data = M4OSA_NULL; + apContext->buffer[i].size = 0; + apContext->buffer[i].filepos = 0; + apContext->buffer[i].remain = 0; + } + + for(i=0; i<M4OSA_READBUFFER_NB; i++) + { + apContext->buffer[i].data = (M4OSA_MemAddr8) M4OSA_malloc(M4OSA_READBUFFER_SIZE, M4OSA_FILE_READER, "M4OSA_FileReader_BufferInit"); + M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_ALLOC, apContext->buffer[i].data); + } + + return M4NO_ERROR; +} + +/**************************************************************/ +M4OSA_Void M4OSA_FileReader_BufferFree(M4OSA_FileReader_Context_optim* apContext) +/**************************************************************/ +{ + M4OSA_Int8 i; + + for(i=0; i<M4OSA_READBUFFER_NB; i++) + if(apContext->buffer[i].data != M4OSA_NULL) + M4OSA_free((M4OSA_MemAddr32)apContext->buffer[i].data); +} + +/**************************************************************/ +M4OSA_FilePosition M4OSA_FileReader_BufferCopy(M4OSA_FileReader_Context_optim* apContext, + M4OSA_Int8 i, M4OSA_FilePosition pos, + M4OSA_FilePosition size, M4OSA_MemAddr8 pData) +/**************************************************************/ +{ + M4OSA_FilePosition copysize; + M4OSA_FilePosition offset; + + if(apContext->buffer[i].size == M4OSA_EOF) return M4OSA_EOF; + + if( (pos < apContext->buffer[i].filepos) + || (pos > (apContext->buffer[i].filepos + apContext->buffer[i].size - 1)) ) + { + return 0; /* nothing copied */ + } + + offset = pos - apContext->buffer[i].filepos; + + copysize = apContext->buffer[i].size - offset; + copysize = (size < copysize) ? size : copysize; + + M4OSA_memcpy(pData, apContext->buffer[i].data + offset, copysize); + + apContext->buffer[i].remain -= copysize; + apContext->buffer[i].nbFillSinceLastAcess = 0; + + return copysize; +} + +/**************************************************************/ +M4OSA_ERR M4OSA_FileReader_BufferFill(M4OSA_FileReader_Context_optim* apContext, + M4OSA_Int8 i, M4OSA_FilePosition pos) +/**************************************************************/ +{ + M4OSA_FilePosition gridPos; + M4OSA_FilePosition tempPos; + M4OSA_UInt32 bufferSize; + M4OSA_FilePosition diff; + M4OSA_FilePosition size; + M4OSA_ERR err = M4NO_ERROR; +#ifdef M4OSA_READER_OPTIM_USE_OSAL_IF + M4OSA_ERR errno = M4NO_ERROR; + M4OSA_UInt32 fileReadSize = 0; + M4OSA_FilePosition fileSeekPosition = 0; +#else + M4OSA_Int32 ret_val; + M4OSA_UInt16 errno; +#endif + + M4OSA_TRACE3_4("BufferFill i = %d pos = %ld read = %ld old = %ld", i, pos, + apContext->readFilePos, apContext->buffer[i].filepos); + + /* Avoid cycling statement because of EOF */ + if(pos >= apContext->fileSize) + return M4WAR_NO_MORE_AU; + + /* Relocate to absolute postion if necessary */ + bufferSize = M4OSA_READBUFFER_SIZE; + tempPos = (M4OSA_FilePosition) (pos / bufferSize); + gridPos = tempPos * M4OSA_READBUFFER_SIZE; + diff = gridPos - apContext->readFilePos; + + if(diff != 0) + { +#ifdef M4OSA_READER_OPTIM_USE_OSAL_IF + fileSeekPosition = diff; + errno = apContext->FS->seek(apContext->aFileDesc, M4OSA_kFileSeekCurrent, + &fileSeekPosition); + apContext->readFilePos = gridPos; + + if(M4NO_ERROR != errno) + { + err = errno; + M4OSA_TRACE1_1("M4OSA_FileReader_BufferFill ERR1 = 0x%x", err); + return err; + } + +#else + ret_val = apContext->FS->pFctPtr_Seek(apContext->aFileDesc, diff, + M4OSA_kFileSeekCurrent, &errno); + apContext->readFilePos = gridPos; + + if(ret_val != 0) + { + err = M4OSA_ERR_CREATE(M4_ERR, M4OSA_FILE_READER, errno); + M4OSA_TRACE1_1("M4OSA_FileReader_BufferFill ERR1 = 0x%x", err); + return err; + } +#endif /*M4OSA_READER_OPTIM_USE_OSAL_IF*/ + } + + apContext->buffer[i].filepos = apContext->readFilePos; + + /* Read Data */ +#ifdef M4OSA_READER_OPTIM_USE_OSAL_IF + fileReadSize = M4OSA_READBUFFER_SIZE; + errno = apContext->FS->readData(apContext->aFileDesc, + (M4OSA_MemAddr8)apContext->buffer[i].data, &fileReadSize); + + size = (M4OSA_FilePosition)fileReadSize; + if ((M4NO_ERROR != errno)&&(M4WAR_NO_DATA_YET != errno)) + { + apContext->buffer[i].size = M4OSA_EOF; + apContext->buffer[i].remain = 0; + + err = errno; + M4OSA_TRACE1_1("M4OSA_FileReader_BufferFill ERR2 = 0x%x", err); + return err; + } +#else + size = apContext->FS->pFctPtr_Read(apContext->aFileDesc, + (M4OSA_UInt8 *)apContext->buffer[i].data, M4OSA_READBUFFER_SIZE, &errno); + if(size == -1) + { + apContext->buffer[i].size = M4OSA_EOF; + apContext->buffer[i].remain = 0; + + err = M4OSA_ERR_CREATE(M4_ERR, M4OSA_FILE_READER, errno); + M4OSA_TRACE1_1("M4OSA_FileReader_BufferFill ERR2 = 0x%x", err); + return err; + } +#endif + + apContext->buffer[i].size = size; + apContext->buffer[i].remain = size; + apContext->buffer[i].nbFillSinceLastAcess = 0; + + /* Retrieve current position */ +#ifdef M4OSA_READER_OPTIM_USE_OSAL_IF + errno = apContext->FS->getOption(apContext->aFileDesc, + M4OSA_kFileReadGetFilePosition, + (M4OSA_DataOption*) &apContext->readFilePos); + + if (M4NO_ERROR != errno) + { + err = errno; + M4OSA_TRACE1_1("M4OSA_FileReader_BufferFill ERR3 = 0x%x", err); + } + else if( (apContext->buffer[i].size >= 0) + && (apContext->buffer[i].size < M4OSA_READBUFFER_SIZE) ) + { + err = M4WAR_NO_DATA_YET; + M4OSA_TRACE2_0("M4OSA_FileReader_BufferFill returns NO DATA YET"); + return err; + } +#else + apContext->readFilePos = apContext->FS->pFctPtr_Tell(apContext->aFileDesc, &errno); + + if( (apContext->buffer[i].size >= 0) + && (apContext->buffer[i].size < M4OSA_READBUFFER_SIZE) ) + { + err = M4WAR_NO_DATA_YET; + M4OSA_TRACE1_1("M4OSA_FileReader_BufferFill ERR3 = 0x%x", err); + return err; + } +#endif /*M4OSA_READER_OPTIM_USE_OSAL_IF*/ + + /* Return without error */ + return M4NO_ERROR; +} + +/**************************************************************/ +M4OSA_Int8 M4OSA_FileReader_BufferMatch(M4OSA_FileReader_Context_optim* apContext, + M4OSA_FilePosition pos) +/**************************************************************/ +{ + M4OSA_Int8 i; + + + /* Select the buffer which matches with given pos */ + for(i=0; i<M4OSA_READBUFFER_NB; i++) + { + if( (pos >= apContext->buffer[i].filepos) + && (pos < (apContext->buffer[i].filepos + apContext->buffer[i].size)) ) + { + return i; + } + } + return M4OSA_READBUFFER_NONE; +} + +/**************************************************************/ +M4OSA_Int8 M4OSA_FileReader_BufferSelect(M4OSA_FileReader_Context_optim* apContext, + M4OSA_Int8 current_i) +/**************************************************************/ +{ + M4OSA_Int8 i,j; + M4OSA_FilePosition min_amount,max_amount; + M4OSA_Int8 min_i,max_count; + + /* update nbFillSinceLastAcess field */ + for(i=0; i<M4OSA_READBUFFER_NB; i++) + { + apContext->buffer[i].nbFillSinceLastAcess ++; + } + + /* Plan A : Scan for empty buffer */ + for(i=0; i<M4OSA_READBUFFER_NB; i++) + { + if(apContext->buffer[i].remain == 0) + { + return i; + } + } + + max_count = M4OSA_READBUFFER_NB; + max_amount = MAX_FILLS_SINCE_LAST_ACCESS; + + /* Plan B : Scan for dead buffer */ + for(i=0; i<M4OSA_READBUFFER_NB; i++) + { + if(apContext->buffer[i].nbFillSinceLastAcess >= (M4OSA_UInt32) max_amount) + { + max_amount = apContext->buffer[i].nbFillSinceLastAcess; + max_count = i; + } + } + if(max_count<M4OSA_READBUFFER_NB) + { + M4OSA_TRACE2_2("DEAD BUFFER: %d, %d",max_count,apContext->buffer[max_count].nbFillSinceLastAcess); + return max_count; + } + + min_i = current_i; + min_amount = M4OSA_READBUFFER_SIZE; + + /* Select the buffer which is the most "empty" */ + for(i=0; i<M4OSA_READBUFFER_NB; i++) + { + j = (i+current_i)%M4OSA_READBUFFER_NB; + + if(apContext->buffer[j].remain < min_amount) + { + min_amount = apContext->buffer[j].remain; + min_i = j; + } + } + + return min_i; + +} + +/**************************************************************/ +M4OSA_ERR M4OSA_FileReader_CalculateSize(M4OSA_FileReader_Context_optim* apContext) +/**************************************************************/ +{ + M4OSA_ERR err = M4NO_ERROR; +#ifdef M4OSA_READER_OPTIM_USE_OSAL_IF + M4OSA_ERR errno = M4NO_ERROR; +#else + M4OSA_Int32 ret_val; + M4OSA_UInt16 errno; +#endif + + /* go to the end of file*/ +#ifdef M4OSA_READER_OPTIM_USE_OSAL_IF + errno = apContext->FS->getOption(apContext->aFileDesc, M4OSA_kFileReadGetFileSize, + (M4OSA_DataOption*) &apContext->fileSize); + if (M4NO_ERROR != errno) + { + err = errno; + M4OSA_TRACE1_1("M4OSA_FileReader_CalculateSize ERR = 0x%x", err); + } +#if 0 + fileSeekPosition = 0; + errno = apContext->FS->seek(apContext->aFileDesc, M4OSA_kFileSeekEnd, &fileSeekPosition); + + if (M4NO_ERROR != errno) + { + apContext->readFilePos = M4OSA_EOF; + err = errno; + M4OSA_TRACE1_1("M4OSA_FileReader_CalculateSize ERR1 = 0x%x", err); + } + else + { + /* Retrieve size of the file */ + errno = apContext->FS->getOption(apContext->aFileDesc, + M4OSA_kFileReadGetFilePosition, + (M4OSA_DataOption*) &apContext->fileSize); + if (M4NO_ERROR != errno) + { + err = errno; + M4OSA_TRACE1_1("M4OSA_FileReader_CalculateSize ERR2 = 0x%x", err); + } + apContext->readFilePos = apContext->fileSize; + } +#endif +#else + ret_val = apContext->FS->pFctPtr_Seek(apContext->aFileDesc, 0, M4OSA_kFileSeekEnd, &errno); + + if (ret_val != 0) + { + apContext->readFilePos = M4OSA_EOF; + err = M4OSA_ERR_CREATE(M4_ERR, M4OSA_FILE_READER, errno); + M4OSA_TRACE1_1("M4OSA_FileReader_CalculateSize ERR = 0x%x", err); + } + else + { + /* Retrieve size of the file */ + apContext->fileSize = apContext->FS->pFctPtr_Tell(apContext->aFileDesc, &errno); + apContext->readFilePos = apContext->fileSize; + } +#endif /*M4OSA_READER_OPTIM_USE_OSAL_IF*/ + + return err; +} + + +/* __________________________________________________________ */ +/*| |*/ +/*| OSAL filesystem API |*/ +/*|__________________________________________________________|*/ + +/** +****************************************************************************** +* @brief This method opens the provided fileDescriptor and returns its context. +* @param pContext: (OUT) File reader context. +* @param pFileDescriptor : (IN) File Descriptor of the input file. +* @param FileModeAccess : (IN) File mode access. +* @return M4NO_ERROR: there is no error +* @return M4ERR_PARAMETER pContext or fileDescriptor is NULL +* @return M4ERR_ALLOC there is no more memory available +* @return M4ERR_FILE_BAD_MODE_ACCESS the file mode access is not correct (it must be either isTextMode or read) +* @return M4ERR_FILE_NOT_FOUND The file can not be opened. +****************************************************************************** +*/ +#ifdef M4OSA_READER_OPTIM_USE_OSAL_IF + M4OSA_ERR M4OSA_fileReadOpen_optim(M4OSA_Context* pContext, + M4OSA_Void* pFileDescriptor, + M4OSA_UInt32 FileModeAccess) +#else + M4OSA_ERR M4OSA_fileReadOpen_optim(M4OSA_Context* pContext, + M4OSA_Void* pFileDescriptor, + M4OSA_UInt32 FileModeAccess, + M4OSA_FileSystem_FctPtr *FS) +#endif +{ + M4OSA_FileReader_Context_optim* apContext = M4OSA_NULL; + + M4OSA_ERR err = M4NO_ERROR; + M4OSA_Void* aFileDesc = M4OSA_NULL; + M4OSA_Bool buffers_allocated = M4OSA_FALSE; +#ifdef M4OSA_READER_OPTIM_USE_OSAL_IF + M4OSA_ERR errno = M4NO_ERROR; +#else + M4OSA_UInt16 errno; +#endif /*M4OSA_READER_OPTIM_USE_OSAL_IF*/ + + M4OSA_TRACE2_3("M4OSA_fileReadOpen_optim p = 0x%p fd = %s mode = %lu", pContext, + pFileDescriptor, FileModeAccess); + + /* Check input parameters */ + M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_PARAMETER, pContext); + M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_PARAMETER, pFileDescriptor); + + *pContext = M4OSA_NULL; + + /* Allocate memory for the File reader context. */ + apContext = (M4OSA_FileReader_Context_optim *)M4OSA_malloc(sizeof(M4OSA_FileReader_Context_optim), + M4OSA_FILE_READER, "M4OSA_FileReader_Context_optim"); + + M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_ALLOC, apContext); + + /* Set filesystem interface */ +#ifdef M4OSA_READER_OPTIM_USE_OSAL_IF + + /*Set the optimized functions, to be called by the user*/ + + apContext->FS = (M4OSA_FileReadPointer*) M4OSA_malloc(sizeof(M4OSA_FileReadPointer), + M4OSA_FILE_READER, "NXPSW_FileReaderOptim_init"); + if (M4OSA_NULL==apContext->FS) + { + M4OSA_TRACE1_0("NXPSW_FileReaderOptim_init - ERROR : allocation failed"); + return M4ERR_ALLOC; + } + apContext->FS->openRead = M4OSA_fileReadOpen; + apContext->FS->readData = M4OSA_fileReadData; + apContext->FS->seek = M4OSA_fileReadSeek; + apContext->FS->closeRead = M4OSA_fileReadClose; + apContext->FS->setOption = M4OSA_fileReadSetOption; + apContext->FS->getOption = M4OSA_fileReadGetOption; + #else + apContext->FS = FS; +#endif + + /* Verify access mode */ + if ( ((FileModeAccess & M4OSA_kFileAppend) != 0) + || ((FileModeAccess & M4OSA_kFileRead) == 0)) + { + err = M4ERR_FILE_BAD_MODE_ACCESS; + goto cleanup; + } + + /* Open file in read mode */ + if((FileModeAccess & M4OSA_kFileCreate) != 0) + { + err = M4ERR_FILE_BAD_MODE_ACCESS; + } + else + { + if ((FileModeAccess & M4OSA_kFileRead)) + { + /* File is opened in read only*/ +#ifdef M4OSA_READER_OPTIM_USE_OSAL_IF + errno = apContext->FS->openRead(&aFileDesc, pFileDescriptor, FileModeAccess); + + if ((aFileDesc == M4OSA_NULL)||(M4NO_ERROR != errno)) + { + /* converts the error to PSW format*/ + err = errno; + M4OSA_TRACE2_1("M4OSA_fileReadOpen_optim ERR1 = 0x%x", err); + apContext->IsOpened = M4OSA_FALSE; + } +#else + aFileDesc = apContext->FS->pFctPtr_Open(pFileDescriptor, FileModeAccess, &errno); + + if (aFileDesc == M4OSA_NULL) + { + /* converts the error to PSW format*/ + err = M4OSA_ERR_CREATE(M4_ERR, M4OSA_FILE_READER, errno); + M4OSA_TRACE2_1("M4OSA_fileReadOpen_optim ERR1 = 0x%x", err); + apContext->IsOpened = M4OSA_FALSE; + } +#endif + + else + { + apContext->IsOpened = M4OSA_TRUE; + } + } + else + { + err = M4ERR_FILE_BAD_MODE_ACCESS; + } + } + + if (M4NO_ERROR != err) goto cleanup; + + /* Allocate buffers */ + err = M4OSA_FileReader_BufferInit(apContext); + buffers_allocated = M4OSA_TRUE; + + if (M4NO_ERROR != err) goto cleanup; + + /* Initialize parameters */ + apContext->fileSize = 0; + apContext->absolutePos = 0; + apContext->readFilePos = 0; + + /* Retrieve the File Descriptor*/ + apContext->aFileDesc = aFileDesc; + + /* Retrieve the File mode Access */ + apContext->FileAttribute.modeAccess = (M4OSA_FileModeAccess) FileModeAccess; + + /*Retrieve the File reader context */ + *pContext= (M4OSA_Context)apContext; + + /* Compute file size */ + err = M4OSA_FileReader_CalculateSize(apContext); + + if (M4NO_ERROR != err) goto cleanup; + + return M4NO_ERROR; + +cleanup: + + /* free context */ + if (M4OSA_NULL != apContext) + { + if(buffers_allocated == M4OSA_TRUE) + { + M4OSA_FileReader_BufferFree(apContext); + } + + M4OSA_free((M4OSA_MemAddr32) apContext); + *pContext = M4OSA_NULL; + } + + M4OSA_TRACE2_1 ("M4OSA_fileReadOpen_optim: returns error 0x%0x", err) + return err; +} + +/** +****************************************************************************** +* @brief This method reads the 'size' bytes in the core file reader (selected by its 'context') +* and writes the data to the 'data' pointer. If 'size' byte can not be read in the core file reader, +* 'size' parameter is updated to match the correct number of read bytes. +* @param pContext: (IN) File reader context. +* @param pData : (OUT) Data pointer of the read data. +* @param pSize : (INOUT) Size of the data to read (in byte). +* @return M4NO_ERROR: there is no error +* @return M4ERR_PARAMETER pSize, fileDescriptor or pData is NULL +* @return M4ERR_ALLOC there is no more memory available +* @return M4ERR_BAD_CONTEXT provided context is not a valid one. +****************************************************************************** +*/ +M4OSA_ERR M4OSA_fileReadData_optim(M4OSA_Context pContext,M4OSA_MemAddr8 pData, + M4OSA_UInt32* pSize) +{ + M4OSA_FileReader_Context_optim* apContext = + (M4OSA_FileReader_Context_optim*) pContext; + + M4OSA_ERR err; + M4OSA_FilePosition aSize; + M4OSA_FilePosition copiedSize; + M4OSA_Int8 selected_buffer, current_buffer; + + M4OSA_TRACE3_3("M4OSA_fileReadData_optim p = 0x%p d = 0x%p s = %lu", + pContext, pData, *pSize); + + /* Check input parameters */ + M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_BAD_CONTEXT, apContext); + M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_PARAMETER, pData); + M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_PARAMETER, pSize); + + if (apContext->IsOpened != M4OSA_TRUE) + { + return M4ERR_BAD_CONTEXT; + } + + /* Prevent reading beyond EOF */ + if((*pSize > 0) && (apContext->absolutePos >= apContext->fileSize)) + { + copiedSize = 0; + err = M4WAR_NO_MORE_AU; + goto cleanup; + } + + /* Check if data can be read from a buffer */ + /* If not, fill one according to quantized positions */ + copiedSize = 0; + err = M4NO_ERROR; + + selected_buffer = M4OSA_FileReader_BufferMatch(apContext, apContext->absolutePos); + + if(selected_buffer == M4OSA_READBUFFER_NONE) + { + selected_buffer = M4OSA_FileReader_BufferSelect(apContext, 0); + err = M4OSA_FileReader_BufferFill(apContext, selected_buffer, + apContext->absolutePos); + } + + if(err != M4NO_ERROR) + { + if(err == M4WAR_NO_DATA_YET) + { + if (*pSize <= (M4OSA_UInt32)apContext->buffer[selected_buffer].size) + { + err = M4NO_ERROR; + } + else + { + copiedSize = (M4OSA_UInt32)apContext->buffer[selected_buffer].size; + /*copy the content into pData*/ + M4OSA_FileReader_BufferCopy(apContext, selected_buffer, + apContext->absolutePos, copiedSize, pData); + goto cleanup; + } + } + else + { + goto cleanup; + } + } + + M4OSA_TRACE3_3("read size = %lu buffer = %d pos = %ld", *pSize, + selected_buffer, apContext->absolutePos); + + /* Copy buffer into pData */ + while(((M4OSA_UInt32)copiedSize < *pSize) && (err == M4NO_ERROR)) + { + aSize = M4OSA_FileReader_BufferCopy(apContext, selected_buffer, + apContext->absolutePos+copiedSize, + *pSize-copiedSize, pData+copiedSize); + copiedSize += aSize; + + if(aSize == 0) + { + err = M4WAR_NO_DATA_YET; + } + else + { + if((M4OSA_UInt32)copiedSize < *pSize) + { + current_buffer = selected_buffer; + selected_buffer = M4OSA_FileReader_BufferMatch(apContext, + apContext->absolutePos+copiedSize); + + if(selected_buffer == M4OSA_READBUFFER_NONE) + { + selected_buffer = M4OSA_FileReader_BufferSelect(apContext, + current_buffer); + err = M4OSA_FileReader_BufferFill(apContext, selected_buffer, + apContext->absolutePos+copiedSize); + + if(err != M4NO_ERROR) + { + if(err == M4WAR_NO_DATA_YET) + { + /*If we got all the data that we wanted, we should return no error*/ + if ((*pSize-copiedSize) <= (M4OSA_UInt32)apContext->buffer[selected_buffer].size) + { + err = M4NO_ERROR; + } + /*If we did not get enough data, we will return NO_DATA_YET*/ + + /*copy the data read*/ + aSize = M4OSA_FileReader_BufferCopy(apContext, selected_buffer, + apContext->absolutePos+copiedSize, + *pSize-copiedSize, pData+copiedSize); + copiedSize += aSize; + + /*we reached end of file, so stop trying to read*/ + goto cleanup; + } + if (err == M4WAR_NO_MORE_AU) + { + err = M4WAR_NO_DATA_YET; + + /*copy the data read*/ + aSize = M4OSA_FileReader_BufferCopy(apContext, selected_buffer, + apContext->absolutePos+copiedSize, + *pSize-copiedSize, pData+copiedSize); + copiedSize += aSize; + + /*we reached end of file, so stop trying to read*/ + goto cleanup; + + } + else + { + goto cleanup; + } + } + } + } + } + } + +cleanup : + + /* Update the new position of the pointer */ + apContext->absolutePos = apContext->absolutePos + copiedSize; + + if((err != M4NO_ERROR)&&(err!=M4WAR_NO_DATA_YET)) + { + M4OSA_TRACE2_3("M4OSA_fileReadData_optim size = %ld copied = %ld err = 0x%x", + *pSize, copiedSize, err); + } + + /* Effective copied size must be returned */ + *pSize = copiedSize; + + + /* Read is done */ + return err; +} + +/** +****************************************************************************** +* @brief This method seeks at the provided position in the core file reader (selected by its 'context'). +* The position is related to the seekMode parameter it can be either : +* From the beginning (position MUST be positive) : end position = position +* From the end (position MUST be negative) : end position = file size + position +* From the current position (signed offset) : end position = current position + position. +* @param pContext: (IN) File reader context. +* @param SeekMode : (IN) Seek access mode. +* @param pPosition : (IN) Position in the file. +* @return M4NO_ERROR: there is no error +* @return M4ERR_PARAMETER Seekmode or fileDescriptor is NULL +* @return M4ERR_ALLOC there is no more memory available +* @return M4ERR_BAD_CONTEXT provided context is not a valid one. +* @return M4ERR_FILE_INVALID_POSITION the position cannot be reached. +****************************************************************************** +*/ +M4OSA_ERR M4OSA_fileReadSeek_optim( M4OSA_Context pContext, M4OSA_FileSeekAccessMode SeekMode, + M4OSA_FilePosition* pPosition) +{ + M4OSA_FileReader_Context_optim* apContext = (M4OSA_FileReader_Context_optim*) pContext; + M4OSA_ERR err = M4NO_ERROR; + M4OSA_TRACE3_3("M4OSA_fileReadSeek_optim p = 0x%p mode = %d pos = %d", pContext, + SeekMode, *pPosition); + + /* Check input parameters */ + M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_BAD_CONTEXT, apContext); + M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_PARAMETER, pPosition); + M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_PARAMETER, SeekMode); + + if (apContext->IsOpened != M4OSA_TRUE) + { + return M4ERR_BAD_CONTEXT; /*< The context can not be correct */ + } + + /* Go to the desired position */ + switch(SeekMode) + { + case M4OSA_kFileSeekBeginning : + if(*pPosition < 0) { + return M4ERR_PARAMETER; /**< Bad SeekAcess mode */ + } + apContext->absolutePos = *pPosition; + *pPosition = apContext->absolutePos; + break; + + case M4OSA_kFileSeekEnd : + if(*pPosition > 0) { + return M4ERR_PARAMETER; /**< Bad SeekAcess mode */ + } + apContext->absolutePos = apContext->fileSize + *pPosition; + *pPosition = apContext->absolutePos; + break; + + case M4OSA_kFileSeekCurrent : + if(((apContext->absolutePos + *pPosition) > apContext->fileSize) || + ((apContext->absolutePos + *pPosition) < 0)){ + return M4ERR_PARAMETER; /**< Bad SeekAcess mode */ + } + apContext->absolutePos = apContext->absolutePos + *pPosition; + *pPosition = apContext->absolutePos; + break; + + default : + err = M4ERR_PARAMETER; /**< Bad SeekAcess mode */ + break; + } + + /* Return without error */ + return err; +} + +/** +****************************************************************************** +* @brief This method asks the core file reader to close the file +* (associated to the context) and also frees the context. +* @param pContext: (IN) File reader context. +* @return M4NO_ERROR: there is no error +* @return M4ERR_BAD_CONTEXT provided context is not a valid one. +****************************************************************************** +*/ +M4OSA_ERR M4OSA_fileReadClose_optim(M4OSA_Context pContext) +{ + M4OSA_FileReader_Context_optim* apContext = (M4OSA_FileReader_Context_optim*) pContext; + + M4OSA_ERR err = M4NO_ERROR; +#ifdef M4OSA_READER_OPTIM_USE_OSAL_IF + M4OSA_ERR errno = M4NO_ERROR; +#else + M4OSA_UInt16 errno; +#endif + + M4OSA_TRACE2_1("M4OSA_fileReadClose_optim p = 0x%p", pContext ); + + /* Check input parameters */ + M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_BAD_CONTEXT, apContext); + + if (apContext->IsOpened != M4OSA_TRUE) + { + return M4ERR_BAD_CONTEXT; /**< The context can not be correct */ + } + + /* buffer */ + M4OSA_FileReader_BufferFree(apContext); + + /* Close the file */ +#ifdef M4OSA_READER_OPTIM_USE_OSAL_IF + errno = apContext->FS->closeRead(apContext->aFileDesc); + + if (M4NO_ERROR != errno) + { + /* converts the error to PSW format*/ + err = errno; + M4OSA_TRACE2_1("M4OSA_fileReadClose_optim ERR1 = 0x%x", err); + } +#else + aRet_Val = apContext->FS->pFctPtr_Close(apContext->aFileDesc, &errno); + + if (aRet_Val != 0) + { + /* converts the error to PSW format*/ + err = M4OSA_ERR_CREATE(M4_ERR, M4OSA_FILE_READER, errno); + M4OSA_TRACE2_1("M4OSA_fileReadClose_optim ERR1 = 0x%x", err); + } +#endif /*M4OSA_READER_OPTIM_USE_OSAL_IF*/ + + apContext->IsOpened = M4OSA_FALSE; + + //>>>> GLM20090212 : set the low level function statically + if (apContext->FS != M4OSA_NULL) + { + M4OSA_free((M4OSA_MemAddr32) apContext->FS); + } + //<<<< GLM20090212 : set the low level function statically + + /* Free the context */ + M4OSA_free((M4OSA_MemAddr32)apContext); + + /* Return without error */ + return err; +} + +/** +****************************************************************************** +* @brief This is a dummy function required to maintain function pointer +* structure. +* @note This is a dummy function required to maintain function pointer +* structure. +* @param pContext: (IN) Execution context. +* @param OptionId : (IN) Id of the option to set. +* @param OptionValue : (IN) Value of the option. +* @return M4NO_ERROR: there is no error +****************************************************************************** +*/ +M4OSA_ERR M4OSA_fileReadSetOption_optim(M4OSA_Context pContext, + M4OSA_FileReadOptionID OptionID, + M4OSA_DataOption OptionValue) +{ + M4OSA_ERR err = M4NO_ERROR; + return err; +} + +/** +****************************************************************************** +* @brief This method asks the core file reader to return the value associated +* with the optionID.The caller is responsible for allocating/de-allocating +* the memory of the value field. +* @note The options handled by the component depend on the implementation +* of the component. +* @param pContext: (IN) Execution context. +* @param OptionId : (IN) Id of the option to set. +* @param pOptionValue : (OUT) Value of the option. +* @return M4NO_ERROR: there is no error +* @return M4ERR_BAD_CONTEXT pContext is NULL +* @return M4ERR_BAD_OPTION_ID the option id is not valid. +* @return M4ERR_NOT_IMPLEMENTED The option is not implemented yet. +****************************************************************************** +*/ +M4OSA_ERR M4OSA_fileReadGetOption_optim(M4OSA_Context pContext, + M4OSA_FileReadOptionID OptionID, + M4OSA_DataOption* pOptionValue) +{ + M4OSA_FileReader_Context_optim* apContext = (M4OSA_FileReader_Context_optim*) pContext; + M4OSA_ERR err = M4NO_ERROR; + + /* Check input parameters */ + M4ERR_CHECK_NULL_RETURN_VALUE(M4ERR_BAD_CONTEXT, apContext); + + if (apContext->IsOpened != M4OSA_TRUE) + { + return M4ERR_BAD_CONTEXT; /**< The context can not be correct */ + } + + /* Get the desired option if it is avalaible */ + switch(OptionID) + { + /* Get File Size */ + case M4OSA_kFileReadGetFileSize:/**< Get size of the file, limited to 32 bit size */ + + (*(M4OSA_UInt32 *)pOptionValue) = apContext->fileSize; + break; + + /* Check End of file Occurs */ + case M4OSA_kFileReadIsEOF : /**< See if we are at the end of the file */ + + (*(M4OSA_Bool *)pOptionValue) = (apContext->absolutePos >= apContext->fileSize) ? M4OSA_TRUE : M4OSA_FALSE; + break; + + /* Get File Position */ + case M4OSA_kFileReadGetFilePosition : /**< Get file position */ + + *(M4OSA_FilePosition *)pOptionValue = apContext->absolutePos; + break; + + /* Get Attribute */ + case M4OSA_kFileReadGetFileAttribute : /**< Get the file attribute = access mode */ + + (*(M4OSA_FileAttribute *)pOptionValue).modeAccess = apContext->FileAttribute.modeAccess; + break; + + default: + /**< Bad option ID */ + err = M4ERR_BAD_OPTION_ID; + break; + } + + /*Return without error */ + return err; +} |