📄 fsread.c
字号:
/***********************************************************************/
/* */
/* Module: fsread.c */
/* Release: 2004.5 */
/* Version: 2003.5 */
/* Purpose: Implements the function for reading bytes from a file */
/* */
/*---------------------------------------------------------------------*/
/* */
/* Copyright 2004, Blunk Microsystems */
/* ALL RIGHTS RESERVED */
/* */
/* Licensees have the non-exclusive right to use, modify, or extract */
/* this computer program for software development at a single site. */
/* This program may be resold or disseminated in executable format */
/* only. The source code may not be redistributed or resold. */
/* */
/***********************************************************************/
#include "flashfsp.h"
#if NUM_FFS_VOLS
/***********************************************************************/
/* Global Function Definitions */
/***********************************************************************/
/***********************************************************************/
/* FlashRead: Read len worth of bytes from a file */
/* */
/* Inputs: stream = pointer to file control block */
/* buf = buffer in which to read the data */
/* len = number of bytes to be read */
/* */
/* Returns: Number of bytes succesfully read or -1 if error */
/* */
/***********************************************************************/
int FlashRead(FILE *stream, ui8 *buf, ui32 len)
{
FFIL_T *link_ptr = &((FFSEnt *)stream->handle)->entry.file;
int unfinished = FALSE, status = GET_OK;
ui32 i, num_sectors, space_left, remaining = len;
ui32 full_len = Flash->sect_sz;
ui8 *sector;
/*-------------------------------------------------------------------*/
/* If the file mode does not permit reading, return error. */
/*-------------------------------------------------------------------*/
if (!(link_ptr->comm->open_mode & F_READ))
{
set_errno(EACCES);
return -1;
}
/*-------------------------------------------------------------------*/
/* If len is 0, return 0. */
/*-------------------------------------------------------------------*/
if (len == 0)
return 0;
/*-------------------------------------------------------------------*/
/* If curr_ptr is invalid, return zero. */
/*-------------------------------------------------------------------*/
if (stream->curr_ptr.sector == (ui16)-1 ||
stream->curr_ptr.sector == FDRTY_SECT ||
(stream->curr_ptr.sector == link_ptr->comm->one_past_last.sector &&
stream->curr_ptr.offset == link_ptr->comm->one_past_last.offset))
return 0;
/*-------------------------------------------------------------------*/
/* If we're in the middle of a sector, read what's left from it. */
/*-------------------------------------------------------------------*/
if (stream->curr_ptr.offset)
{
/*-----------------------------------------------------------------*/
/* If the stream does not have a cache entry, get the sector from */
/* the cache. */
/*-----------------------------------------------------------------*/
if (stream->cached == NULL)
{
status = GetSector(&Flash->cache, (int)stream->curr_ptr.sector,
FALSE, link_ptr->comm, &stream->cached);
if (status == GET_WRITE_ERROR)
return -1;
}
/*-----------------------------------------------------------------*/
/* Get the pointer to the sector data. */
/*-----------------------------------------------------------------*/
sector = ((CacheEntry *)stream->cached)->sector;
/*-----------------------------------------------------------------*/
/* Figure out how much space is left in current sector. */
/*-----------------------------------------------------------------*/
space_left = (ui32)(Flash->sect_sz - stream->curr_ptr.offset);
/*-----------------------------------------------------------------*/
/* If what has to be read comes only from this sector, read it and */
/* set remaining to 0 so that we're done. */
/*-----------------------------------------------------------------*/
if (space_left >= remaining)
{
/*---------------------------------------------------------------*/
/* If we're trying to read from past the end of the file, set */
/* unfinished flag to true and read as much as possible. */
/*---------------------------------------------------------------*/
if (link_ptr->comm->one_past_last.sector ==
stream->curr_ptr.sector &&
link_ptr->comm->one_past_last.offset <stream->curr_ptr.offset +
(int)remaining)
{
unfinished = TRUE;
remaining = (ui32)(link_ptr->comm->one_past_last.offset -
stream->curr_ptr.offset);
len = remaining;
}
/*---------------------------------------------------------------*/
/* Use memcpy to copy from sector to buf, remaining bytes. */
/*---------------------------------------------------------------*/
memcpy(buf, §or[stream->curr_ptr.offset], remaining);
/*---------------------------------------------------------------*/
/* If there was an error reading sector, stop. */
/*---------------------------------------------------------------*/
if (status == GET_READ_ERROR)
{
unfinished = TRUE;
len = (ui32)-1;
goto read_exit;
}
/*---------------------------------------------------------------*/
/* Adjust current offset. */
/*---------------------------------------------------------------*/
stream->curr_ptr.offset += (ui16)remaining;
/*---------------------------------------------------------------*/
/* We're done reading so return. */
/*---------------------------------------------------------------*/
goto read_exit;
}
/*-----------------------------------------------------------------*/
/* Else read what's left of this sector, adjust remaining and */
/* later, continue reading the other sectors. */
/*-----------------------------------------------------------------*/
else
{
/*---------------------------------------------------------------*/
/* If we're trying to read from past the end of the file, read */
/* as much as possible before returning. */
/*---------------------------------------------------------------*/
if (stream->curr_ptr.sector == link_ptr->comm->last_sect)
{
/*-------------------------------------------------------------*/
/* If we don't have to the end of the sector, adjust how many */
/* more bytes are available for read. */
/*-------------------------------------------------------------*/
if (link_ptr->comm->one_past_last.sector != (ui16)-1)
space_left = (ui32)(link_ptr->comm->one_past_last.offset -
stream->curr_ptr.offset);
len = space_left;
}
/*---------------------------------------------------------------*/
/* Use memcpy to copy space_left bytes from sector to buffer. */
/*---------------------------------------------------------------*/
memcpy(buf, §or[stream->curr_ptr.offset], space_left);
/*---------------------------------------------------------------*/
/* If there was an error reading sector, stop. */
/*---------------------------------------------------------------*/
if (status == GET_READ_ERROR)
{
unfinished = TRUE;
len = (ui32)-1;
goto read_exit;
}
/*---------------------------------------------------------------*/
/* Adjust remaining (number of bytes left to be read) and the */
/* buf pointer. */
/*---------------------------------------------------------------*/
remaining -= space_left;
buf += space_left;
/*---------------------------------------------------------------*/
/* Adjust current offset. */
/*---------------------------------------------------------------*/
stream->curr_ptr.offset = 0;
/*---------------------------------------------------------------*/
/* If this is the last sector, we have to stop, else get next */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -