📄 zfsread.c
字号:
/*
* File : ZFSRead.c
* Description: This file contains the implementation of ZFSRead APIs
* Author : Mahadev K C
* Created on : 30-APR-2003
*
* Copyright 2004 ZiLOG Inc. ALL RIGHTS RESERVED.
*
* This file contains unpublished confidential and proprietary information
* of ZiLOG, Inc.
* NO PART OF THIS WORK MAY BE DUPLICATED, STORED, PUBLISHED OR DISCLOSED
* IN ANY FORM WITHOUT THE PRIOR WRITTEN CONSENT OF ZiLOG, INC.
* This is not a license and no use of any kind of this work is authorized
* in the absence of a written license granted by ZiLOG, Inc. in ZiLOG's
* sole discretion
*/
#include "ZSysgen.h"
#include "ZTypes.h"
#include "ZThread.h"
#include "ZSemaphore.h"
#include "glextern.h"
extern RZK_SEMAPHOREHANDLE_t hSem_FS;
//Function Name: ZFSRead
//Description: This API will read the specified number of bytes from the file
INT32 ZFSRead( IN ZFS_HANDLE_t handle, IN_OUT UINT8 *buf, IN UINT numBytesToRead )
{
#define handle ((PZFS_OPEN_REC_t)handle)
UINT numBytesRead = 0 ;
UINT bytesleft_in_sec ;
UINT curNumBytesToRead ;
UINT bytes_read ;
UINT8 *pAddr ;
ZFS_SEC_ID_t cur_sec_id ;
ZFS_SEC_HDR_t sec_hdr ;
UINT umod = 0 ;
UINT actNumBytesRead = 0 ;
UINT8 *pbuf = buf ;
UINT8 *ptr ;
UINT idx = 0 ;
UINT8 tmp_read_lf = ZFS_FALSE ;
UINT actBytesWithoutCRLF = 0 ;
UINT ttlBytesToRet = 0 ;
UINT ctr = 0 ;
UINT8 crlf_byte ;
UINT8 btmp_flag ;
// if ZFS is not initialized, return error
if( !IsZFSInited() )
return ZFSERR_NOT_INITIALIZED ;
// first check whether the handle is valid or not
if( handle->status != ZFS_OR_MAGIC_NUM )
return ZFSERR_INVALID_HANDLE ;
if( buf == NULL || numBytesToRead == 0 )
return ZFSERR_INVALID_ARGUMENTS ;
RZKAcquireSemaphore(hSem_FS,INFINITE_SUSPEND);
// preempt_status = DisablePreemption() ;
if( ( ( PZFS_OPEN_REC_t) handle )->mode & ( ZFS_APPEND | ZFS_WRITE ) )
{
RZKReleaseSemaphore(hSem_FS);
// EnablePreemption( preempt_status ) ;
return ZFSERR_INVALID_OPERATION ;
}
// first check whether the offset surpasses the size
if( (numBytesToRead + handle->offset) > handle->size )
numBytesToRead = handle->size - handle->offset ;
// If number of bytes to read is ZERO, return an error
if( numBytesToRead == 0 )
{
RZKReleaseSemaphore(hSem_FS);
// EnablePreemption( preempt_status ) ;
return ZFSERR_INVALID_OPERATION ;
}
// first get the sector where offset lies and related values,
umod = handle->offset % ZFS_SEC_DATA_SIZE ;
bytesleft_in_sec = ( ZFS_SEC_DATA_SIZE - umod ) ;
if( numBytesToRead <= bytesleft_in_sec )
curNumBytesToRead = numBytesToRead ;
else
curNumBytesToRead = bytesleft_in_sec ;
cur_sec_id = handle->cur_secnum ;
if( umod == 0 && handle->offset != 0 )
{
// the offset is at the end of the sector. Just move to next sector.
handle->pvol->pcfg->pfn_drv_read( GetSecAddr( handle->pvol, cur_sec_id), &sec_hdr, sizeof( ZFS_SEC_HDR_t ) ) ;
cur_sec_id = sec_hdr.nxtsecnum ;
}
pAddr = GetSecAddr( handle->pvol, cur_sec_id ) + umod + sizeof( ZFS_SEC_HDR_t ) ;
// now read in loop till you get all bytes
while( numBytesToRead != 0 )
{
actBytesWithoutCRLF = 0 ;
idx = 0 ;
btmp_flag = ZFS_FALSE ;
if( tmp_read_lf == ZFS_TRUE && !(handle->attr & ZFS_MODE_BINARY ) )
{
bytes_read = handle->pvol->pcfg->pfn_drv_read( pAddr, &crlf_byte, 1 ) ;
if( bytes_read == 0 )
{
// some problem is occured in the device.
RZKReleaseSemaphore(hSem_FS);
// EnablePreemption( preempt_status ) ;
return ZFSERR_DEVICE ;
}
tmp_read_lf = ZFS_FALSE ;
// now the byte is read. just check whether the byte is a \n, if it is increment the counter
if( crlf_byte == '\n' )
{
// it is a valid sequence, just replace the previous character with \n
*buf = '\n' ;
actBytesWithoutCRLF = 1 ;
buf++ ;
idx = 1 ;
}
else
{
// it is not a valid sequence, just add at buf for the bytes read.
buf++ ;
*buf = crlf_byte ;
buf++ ;
idx = 1 ;
actBytesWithoutCRLF = 1 ;
}
if( curNumBytesToRead == 1 )
{
// this is last byte that need to be read,
actNumBytesRead ++ ;
ttlBytesToRet ++ ;
goto _read_exit ;
}
else
{
btmp_flag = ZFS_TRUE ;
curNumBytesToRead -- ;
pAddr ++ ;
}
}
pbuf = buf ;
ptr = pbuf ;
if( curNumBytesToRead > 0 )
{
bytes_read = handle->pvol->pcfg->pfn_drv_read( pAddr, buf, curNumBytesToRead ) ;
if( bytes_read == 0 )
{
// some problem is occured in the device.
RZKReleaseSemaphore(hSem_FS);
// EnablePreemption( preempt_status ) ;
return ZFSERR_DEVICE ;
}
}
// for ASCII or text mode, check whether any \r(0x0D) is present in the
// data read, and if next byte is an \n(0x0A), then advance the pointer to next byte
// and remove the \r and place only \n in the buffer.
if( (handle->attr & ZFS_MODE_BINARY ) )
{
ttlBytesToRet += bytes_read ;
idx = bytes_read ;
}
else
{
if( btmp_flag == ZFS_TRUE )
{
curNumBytesToRead ++ ;
bytes_read++ ;
}
while( idx < bytes_read )
{
if( *pbuf == '\r' )
{
// if the character is a \r,
if( idx == (bytes_read -1 ) )
{
// this is the last byte present in the buffer for \r that means that \n is present in next sector's data
// so set a flag.
tmp_read_lf = ZFS_TRUE ;
idx++ ;
pbuf++ ;
}
else if( *(pbuf+1) == '\n' )
{
// it is valid sequence , just store \n in the buf
*ptr = '\n' ;
pbuf += 2 ;
idx += 2 ;
ptr++ ;
actBytesWithoutCRLF ++ ;
}
else
{
// the character is not a \n, just store whatever that is present.
*ptr = *pbuf ;
pbuf++ ;
ptr++ ;
idx++ ;
actBytesWithoutCRLF ++ ;
}
}
else
{
*ptr = *pbuf ;
ptr++ ;
pbuf++ ;
idx++ ;
actBytesWithoutCRLF ++ ;
}
}
ctr += bytes_read ;
bytes_read = actBytesWithoutCRLF ;
}
buf += bytes_read ;
numBytesRead += bytes_read ;
numBytesToRead -= bytes_read ;
actNumBytesRead += idx ;
ttlBytesToRet += actBytesWithoutCRLF ;
if( numBytesToRead > 0 )
{
// move to next sector.
// read the sector header of current sector
// check if for ASCII mode, the bytes actually read are equal to the bytes after CRLF conversion. If not, loopback without
// assigning the new address.
if( !(handle->attr & ZFS_MODE_BINARY ) )
{
// just check out if the bytes read actually crosses the size, then break here
if( ( handle->offset + actNumBytesRead ) == handle->size )
{
*(pbuf - 1 ) = 0x00 ;
break ;
}
if( ( ( umod + idx ) % ZFS_SEC_DATA_SIZE ) == 0 )
{
if( ( actNumBytesRead + handle->offset + numBytesToRead ) > handle->size )
{
numBytesToRead = (actNumBytesRead + handle->offset + numBytesToRead ) - handle->size ;
}
goto _next_read ;
}
if( bytes_read != curNumBytesToRead )
{
umod += idx ;
pAddr += idx ;
if( ( umod + numBytesToRead ) > ZFS_SEC_DATA_SIZE )
curNumBytesToRead = ZFS_SEC_DATA_SIZE - umod ;
else
curNumBytesToRead = numBytesToRead ;
// curNumBytesToRead -= bytes_read ;
// if( curNumBytesToRead < bytes_read )
// curNumBytesToRead -= bytes_read ;
// else
// curNumBytesToRead -= (ZFS_SEC_DATA_SIZE - ( umod + ctr ) ) ; //bytes_read ;
continue ;
}
}
_next_read:
handle->pvol->pcfg->pfn_drv_read( GetSecAddr(handle->pvol, cur_sec_id), &sec_hdr, sizeof(ZFS_SEC_HDR_t)) ;
cur_sec_id = sec_hdr.nxtsecnum ;
pAddr = GetSecAddr(handle->pvol, cur_sec_id ) + sizeof( ZFS_SEC_HDR_t ) ;
if( numBytesToRead > ZFS_SEC_DATA_SIZE )
curNumBytesToRead = ZFS_SEC_DATA_SIZE ;
else
curNumBytesToRead = numBytesToRead ;
umod = 0 ;
}
}
_read_exit:
handle->cur_secnum = cur_sec_id ;
handle->offset += actNumBytesRead ;
RZKReleaseSemaphore(hSem_FS);
// EnablePreemption( preempt_status) ;
return ttlBytesToRet ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -