📄 fsal_buffer.c
字号:
/*****************************************************************************
* Copyright Statement:
* --------------------
* This software is protected by Copyright and the information contained
* herein is confidential. The software may not be copied and the information
* contained herein may not be used or disclosed except with the written
* permission of MediaTek Inc. (C) 2005
*
* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
*
* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
*
*****************************************************************************/
/*******************************************************************************
*
* Filename:
* ---------
* fsal_buffer.c
*
* Project:
* --------
* MAUI
*
* Description:
* ------------
* File System Abstraction Layer, buffered read/write handling.
*
* Author:
* -------
* -------
*
*==============================================================================
* HISTORY
* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*------------------------------------------------------------------------------
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
* removed!
*
* removed!
* removed!
*
* removed!
* removed!
*
* removed!
* removed!
*
* removed!
* removed!
*
* removed!
* removed!
*
* removed!
* removed!
*
* removed!
* removed!
* removed!
*
* removed!
* removed!
*
*------------------------------------------------------------------------------
* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*==============================================================================
*******************************************************************************/
#include "fsal.h"
/* read the block from file system into buffer */
static FSAL_Status FSAL_CacheFill(STFSAL *pstFSAL, kal_uint32 uBlock)
{
FSAL_Status ret;
kal_uint32 uFileOffsetOfBlock, uBytesToRead;
FSAL_CHECK_ARG(pstFSAL!=NULL);
uFileOffsetOfBlock = uBlock * pstFSAL->uBufSize;
#if FSAL_VERBOSE
printf("seek to %d\n", uFileOffsetOfBlock);
#endif
if((ret=FSAL_Direct_Seek(pstFSAL, uFileOffsetOfBlock))!=FSAL_OK) {
#if FSAL_VERBOSE
printf("seek fail\n");
#endif
return ret;
}
/* handle the last block of the file */
if (uFileOffsetOfBlock + pstFSAL->uBufSize > pstFSAL->uFileSize)
uBytesToRead = pstFSAL->uFileSize - uFileOffsetOfBlock;
else
uBytesToRead = pstFSAL->uBufSize;
if (uBytesToRead != 0) {
#if FSAL_VERBOSE
printf("read len=%d\n", uBytesToRead);
#endif
if ((ret = FSAL_Direct_Read(pstFSAL, pstFSAL->pbBuf, uBytesToRead)) != FSAL_OK) {
#if FSAL_VERBOSE
printf("read fail\n");
#endif
return ret;
}
}
pstFSAL->uCachedBlock = uBlock;
pstFSAL->bDirty = KAL_FALSE;
return FSAL_OK;
}
static FSAL_Status fsal_read_block(STFSAL *pstFSAL, kal_uint8* pbBuf, kal_uint32 uBlock, kal_uint32 uOffset, kal_uint32 uLen)
{
FSAL_Status ret;
FSAL_CHECK_ARG(pstFSAL!=NULL);
FSAL_CHECK_ARG(uBlock!=0xFFFFFFFF);
FSAL_CHECK_ARG(pstFSAL->bBuffering==KAL_TRUE);
if (pstFSAL->uCachedBlock != uBlock) {
/* cache miss */
if ((ret = FSAL_CacheFlush(pstFSAL))!=FSAL_OK)
return ret;
if ((ret = FSAL_CacheFill(pstFSAL, uBlock))!=FSAL_OK)
return ret;
}
FSAL_ASSERT(uOffset+uLen<=pstFSAL->uBufSize);
kal_mem_cpy(pbBuf, (pstFSAL->pbBuf) + uOffset, uLen);
pstFSAL->uFileOffset += uLen;
return FSAL_OK;
}
FSAL_Status FSAL_Read(STFSAL *pstFSAL, kal_uint8* pbBuf, kal_uint32 uSize)
{
FSAL_CHECK_ARG(pstFSAL!=NULL);
FSAL_CHECK_ARG(pbBuf!=NULL);
if (uSize==0)
return FSAL_OK;
if (KAL_TRUE==pstFSAL->bBuffering) {
kal_uint32 uStartBlock, uEndBlock;
kal_uint32 uOffsetInBlock, uLenInBlock;
uStartBlock = (pstFSAL->uFileOffset) / pstFSAL->uBufSize;
uEndBlock = (pstFSAL->uFileOffset + uSize - 1) / pstFSAL->uBufSize;
/* handle the first block */
uOffsetInBlock = (pstFSAL->uFileOffset) % pstFSAL->uBufSize;
if (uEndBlock==uStartBlock)
uLenInBlock = uSize;
else
uLenInBlock = pstFSAL->uBufSize - uOffsetInBlock;
if (fsal_read_block(pstFSAL, pbBuf, uStartBlock, uOffsetInBlock, uLenInBlock) != FSAL_OK)
return FSAL_READ_ERROR;
pbBuf += uLenInBlock;
uSize -= uLenInBlock;
/* handle the middle blocks */
/*
for(uEachBlock=uStartBlock+1; uEachBlock<uEndBlock; uEachBlock++) {
if(fsal_read_block(pstFSAL, pbBuf, uEachBlock, 0, pstFSAL->uBufSize)!=FSAL_OK)
return FSAL_READ_ERROR;
pbBuf += pstFSAL->uBufSize;
uSize -= pstFSAL->uBufSize;
}
*/
/* handle the middle blocks, optimized version */
if (uEndBlock>uStartBlock+1) {
kal_uint32 read_length;
FSAL_Status ret;
if ((ret = FSAL_Direct_Seek(pstFSAL, pstFSAL->uFileOffset)) != FSAL_OK)
return ret;
read_length = (uEndBlock-uStartBlock-1)*pstFSAL->uBufSize;
if ((ret = FSAL_Direct_Read(pstFSAL, pbBuf, read_length)) != FSAL_OK)
return ret;
pbBuf += read_length;
uSize -= read_length;
pstFSAL->uFileOffset += read_length;
}
/* handle the last block */
if(uEndBlock!=uStartBlock) {
FSAL_Status ret;
if ((ret = fsal_read_block(pstFSAL, pbBuf, uEndBlock, 0, uSize)) != FSAL_OK)
return ret;
uSize -= uSize;
}
FSAL_ASSERT(uSize==0);
return FSAL_OK;
} else if (KAL_FALSE==pstFSAL->bBuffering) {
return FSAL_Direct_Read(pstFSAL, pbBuf, uSize);
} else {
return FSAL_MEMORY_CORRUPTION;
}
}
FSAL_Status FSAL_CacheFlush(STFSAL *pstFSAL)
{
FSAL_Status ret;
kal_uint32 uFileOffsetOfBlock, uBytesToWrite;
FSAL_CHECK_ARG(pstFSAL!=NULL);
if (pstFSAL->bBuffering!=KAL_TRUE)
return FSAL_OK;
if (pstFSAL->uCachedBlock==0xFFFFFFFF) {
return FSAL_OK;
}
if (pstFSAL->bDirty!=KAL_TRUE) {
return FSAL_OK;
}
uFileOffsetOfBlock = (pstFSAL->uCachedBlock) * (pstFSAL->uBufSize);
if ((ret = FSAL_Direct_Seek(pstFSAL, uFileOffsetOfBlock)) != FSAL_OK) {
return ret;
}
/* handle the last block of the file */
if (uFileOffsetOfBlock + pstFSAL->uBufSize > pstFSAL->uFileSize)
uBytesToWrite = pstFSAL->uFileSize - uFileOffsetOfBlock;
else
uBytesToWrite = pstFSAL->uBufSize;
if (uBytesToWrite != 0) {
if ((ret = FSAL_Direct_Write(pstFSAL, pstFSAL->pbBuf, uBytesToWrite)) != FSAL_OK) {
return ret;
}
}
pstFSAL->bDirty = KAL_FALSE;
return FSAL_OK;
}
static FSAL_Status fsal_write_block(STFSAL *pstFSAL, kal_uint8* pbBuf, kal_uint32 uBlock, kal_uint32 uOffset, kal_uint32 uLen)
{
FSAL_Status ret;
FSAL_CHECK_ARG(pstFSAL!=NULL);
FSAL_CHECK_ARG(uBlock!=0xFFFFFFFF); /* XXX: SHOULD BE ABLE To HANDLE */
FSAL_CHECK_ARG(KAL_TRUE==pstFSAL->bBuffering);
#if FSAL_VERBOSE
printf("fsal_write_block(uBlock=%d)\n", uBlock);
#endif
if (pstFSAL->uCachedBlock != uBlock) {
/* cache miss */
if ((ret = FSAL_CacheFlush(pstFSAL)) != FSAL_OK) {
#if FSAL_VERBOSE
printf("flush fail\n");
#endif
return ret;
}
if ((ret = FSAL_CacheFill(pstFSAL, uBlock)) != FSAL_OK) {
#if FSAL_VERBOSE
printf("fill fail\n");
#endif
return ret;
}
}
FSAL_ASSERT(uOffset+uLen<=pstFSAL->uBufSize);
kal_mem_cpy((pstFSAL->pbBuf) + uOffset, pbBuf, uLen);
pstFSAL->uFileOffset += uLen;
if (pstFSAL->uFileOffset>pstFSAL->uFileSize)
pstFSAL->uFileSize = pstFSAL->uFileOffset;
#if FSAL_VERBOSE
printf("file size = %d\n", pstFSAL->uFileSize);
#endif
pstFSAL->bDirty = KAL_TRUE;
return FSAL_OK;
}
FSAL_Status FSAL_Write(STFSAL *pstFSAL, kal_uint8 *pbBuf, kal_uint32 uSize)
{
FSAL_CHECK_ARG(pstFSAL!=NULL);
FSAL_CHECK_ARG(pbBuf!=NULL);
if (uSize==0)
return FSAL_OK;
if (KAL_TRUE==pstFSAL->bBuffering) {
kal_uint32 uStartBlock, uEndBlock;
kal_uint32 uOffsetInBlock, uSizeInBlock;
uStartBlock = (pstFSAL->uFileOffset) / pstFSAL->uBufSize;
uEndBlock = (pstFSAL->uFileOffset + uSize - 1) / pstFSAL->uBufSize;
/* handle the first block */
uOffsetInBlock = (pstFSAL->uFileOffset) % pstFSAL->uBufSize;
if (uEndBlock==uStartBlock)
uSizeInBlock = uSize;
else
uSizeInBlock = pstFSAL->uBufSize - uOffsetInBlock;
if(fsal_write_block(pstFSAL, pbBuf, uStartBlock, uOffsetInBlock, uSizeInBlock)!=FSAL_OK)
return FSAL_WRITE_ERROR;
pbBuf += uSizeInBlock;
uSize -= uSizeInBlock;
/* handle the middle blocks */
/*
for(uEachBlock=uStartBlock+1; uEachBlock<uEndBlock; uEachBlock++) {
if(fsal_write_block(pstFSAL, pbBuf, uEachBlock, 0, pstFSAL->uBufSize)!=FSAL_OK)
return FSAL_WRITE_ERROR;
pbBuf += pstFSAL->uBufSize;
uSize -= pstFSAL->uBufSize;
}
*/
/* handle the middle blocks, optimized version */
if (uEndBlock>uStartBlock+1) {
kal_uint32 write_length;
FSAL_Status ret;
write_length = (uEndBlock-uStartBlock-1)*pstFSAL->uBufSize;
if ((ret = FSAL_CacheFlush(pstFSAL)) != FSAL_OK)
return ret;
if ((ret = FSAL_Direct_Write(pstFSAL, pbBuf, write_length)) != FSAL_OK)
return ret;
pbBuf += write_length;
uSize -= write_length;
pstFSAL->uFileOffset += write_length;
pstFSAL->uFileSize += write_length;
}
/* handle the last block */
if(uEndBlock!=uStartBlock) {
FSAL_Status ret;
if ((ret = fsal_write_block(pstFSAL, pbBuf, uEndBlock, 0, uSize)) != FSAL_OK)
return ret;
uSize -= uSize;
}
FSAL_ASSERT(uSize==0);
return FSAL_OK;
} else if (KAL_FALSE==pstFSAL->bBuffering) {
return FSAL_Direct_Write(pstFSAL, pbBuf, uSize);
} else {
return FSAL_MEMORY_CORRUPTION;
}
}
FSAL_Status FSAL_Seek(STFSAL *pstFSAL, kal_uint32 uOffset)
{
FSAL_CHECK_ARG(pstFSAL!=NULL);
if (KAL_TRUE==pstFSAL->bBuffering) {
pstFSAL->uFileOffset = uOffset;
return FSAL_OK;
} else if (KAL_FALSE==pstFSAL->bBuffering) {
return FSAL_Direct_Seek(pstFSAL, uOffset);
} else {
return FSAL_MEMORY_CORRUPTION;
}
}
FSAL_Status FSAL_GetCurPos(STFSAL *pstFSAL, kal_uint32 *puPosition)
{
FSAL_CHECK_ARG(pstFSAL!=NULL);
FSAL_CHECK_ARG(puPosition!=NULL);
if (KAL_TRUE==pstFSAL->bBuffering) {
*puPosition = pstFSAL->uFileOffset;
return FSAL_OK;
} else if (KAL_FALSE==pstFSAL->bBuffering) {
return FSAL_Direct_GetCurPos(pstFSAL, puPosition);
} else {
return FSAL_MEMORY_CORRUPTION;
}
}
FSAL_Status FSAL_GetFileSize(STFSAL *pstFSAL, kal_uint32 *puFileSize)
{
FSAL_CHECK_ARG(pstFSAL!=NULL);
FSAL_CHECK_ARG(puFileSize!=NULL);
if (KAL_TRUE==pstFSAL->bBuffering) {
*puFileSize = pstFSAL->uFileSize;
return FSAL_OK;
} else if (KAL_FALSE==pstFSAL->bBuffering) {
return FSAL_Direct_GetFileSize(pstFSAL, puFileSize);
} else {
return FSAL_MEMORY_CORRUPTION;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -