⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zfsread.c

📁 zilog的实时操作系统RZK,可以移植到多种处理器上
💻 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 + -