📄 fileio.c
字号:
* Function: MYFILE * __fopen (const char * fileName, const char *mode, MYFILE* filePtr )
*
* PreCondition: For read or append mode, file exists
*
* Input: fileName - The name of the file to open
* mode - WRITE - Create a new file or replace an existing file
* READ - Read data from an existing file
* APPEND - Append data to an existing file
* filePte - The pointer to the file that will be returned
* in the parent function of __fopen
*
* Output: MYFILE * - The pointer to the file object
*
* Side Effects: None
*
* Overview: File open function
*
* Note: None
*****************************************************************************/
MYFILE * __fopen (const char * fileName, const char *mode, MYFILE* filePtr )
{
BYTE ModeC;
WORD fHandle;
CETYPE final;
MYFILE gblFileTemp;
//Read the mode character
ModeC = mode[0];
if (WriteProtectState())
{
return NULL;
}
//Format the source string to FAT16 lib spec.
if( !FormatFileName(fileName, filePtr->name) )
return NULL; //bad filename
filePtr->dsk = &glbDiskData;
filePtr->cluster = 0;
filePtr->ccls = 0;
// start at the root directory
filePtr->dirclus = 0;
filePtr->dirccls = 0;
// copy file object over
FileObjectCopy(&gblFileTemp, filePtr);
// See if the file is found
if(FILEfind (filePtr, &gblFileTemp, 1) == CE_GOOD)
{
// File is Found
switch(ModeC)
{
case 'w':
case 'W':
{
// File exists, we want to create a new one, remove it first
fHandle = filePtr->entry;
final = FILEerase(filePtr, &fHandle, TRUE);
if (final == CE_GOOD)
{
// now create a new one
final = CreateFileEntry (filePtr, &fHandle);
if (final == CE_GOOD)
{
final = FILEopen (filePtr, &fHandle, 'w');
if (final == CE_GOOD)
{
final = __fseek (filePtr, 0, SEEK_END);
if (final != CE_GOOD)
filePtr = NULL;
}
else
filePtr = NULL;
}
else
filePtr = NULL;
}
else
filePtr = NULL;
break;
}
case 'A':
case 'a':
{
if(filePtr->size != 0)
{
fHandle = filePtr->entry;
final = FILEopen (filePtr, &fHandle, 'w');
if (final == CE_GOOD)
{
final = __fseek (filePtr, 0, SEEK_END);
if (final != CE_GOOD)
filePtr = NULL;
}
else
filePtr = NULL;
}
else
{
fHandle = filePtr->entry;
final = FILEerase(filePtr, &fHandle, TRUE);
if (final == CE_GOOD)
{
// now create a new one
final = CreateFileEntry (filePtr, &fHandle);
if (final == CE_GOOD)
{
final = FILEopen (filePtr, &fHandle, 'w');
if (final == CE_GOOD)
{
final = __fseek (filePtr, 0, SEEK_END);
if (final != CE_GOOD)
filePtr = NULL;
}
else
filePtr = NULL;
}
else
filePtr = NULL;
}
else
filePtr = NULL;
}
break;
}
case 'R':
case 'r':
{
fHandle = filePtr->entry;
final = FILEopen (filePtr, &fHandle, 'r');
if (final != CE_GOOD)
filePtr = NULL;
break;
}
default:
filePtr = NULL; //indicate error condition
break;
}
}
else
{
// the file was not found, reset to the default asked
FileObjectCopy(filePtr, &gblFileTemp);
// File is not Found
if(ModeC == 'w' || ModeC == 'W')
{
// use the user requested name
fHandle = 0;
final = CreateFileEntry (filePtr, &fHandle);
if (final == CE_GOOD)
{
final = FILEopen (filePtr, &fHandle, 'w');
if (final == CE_GOOD)
{
final = __fseek (filePtr, 0, SEEK_END);
if (final != CE_GOOD)
filePtr = NULL;
}
else
filePtr = NULL;
}
else
filePtr = NULL;
}
else
filePtr = NULL;
}
return(filePtr);
}
/******************************************************************************
* Function: CETYPE __fseek (FILEOBJ fo, DWORD offset, BYTE origin)
*
* PreCondition: File exists
*
* Input: fo - Pointer to file structure
* offset - Offset from origin location
* origin - SEEK_SET - Seek from start of file
* SEEK_CUR - Seek from current location
* SEEK_END - Seek from end of file
*
* Output: CE_GOOD - Operation successful
* CE_INVALID_CLUSTER - Invalid cluster value > maxcls
* CE_BAD_SECTOR_READ - A bad read occured of a sector
*
* Side Effects: None
*
* Overview: User called function to set the starting position of the stream to the offset
*
* Note: None
*****************************************************************************/
CETYPE __fseek (FILEOBJ fo, DWORD offset, BYTE origin)
{
DWORD numsector, temp; // lba of first sector of first cluster
DISK* dsk; // pointer to disk structure
dsk = fo->dsk;
switch(origin)
{
case SEEK_CUR:
// Apply the offset to the current position
offset += fo->seek;
break;
case SEEK_END:
// Apply the offset to the end of the file
offset = fo->size - offset;
break;
case SEEK_SET:
// automatically there
default:
break;
}
// start from the beginning
temp = fo->cluster;
fo->ccls = temp;
temp = fo->size;
if (offset > temp)
return (-1); // past the limits
else
{
// if we are writing we are no longer at the end
fo->Flags.FileWriteEOF = FALSE;
// set the new postion
fo->seek = offset;
// figure out how many sectors
numsector = offset / MEDIA_SECTOR_SIZE;
// figure out how many bytes off of the offset
offset = offset - (numsector * MEDIA_SECTOR_SIZE);
fo->pos = offset;
// figure out how many clusters
temp = numsector / dsk->SecPerClus;
// figure out the stranded sectors
numsector = numsector - (dsk->SecPerClus * temp);
fo->sec = numsector;
// if we are in the current cluster stay there
if (temp > 0)
{
if (FILEget_next_cluster(fo, temp) != CE_GOOD)
return (CE_INVALID_CLUSTER); // past the limits
}
// Determine the lba of the selected sector and load
temp = Cluster2Sector(dsk,fo->ccls);
// now the extra sectors
numsector = fo->sec;
temp += numsector;
gBufferOwner = fo;
if( !SECTORread(temp, dsk->buffer) )
return (CE_BAD_SECTOR_READ); // Bad read
}
return (CE_GOOD);
}
/******************************************************************************
* Function: long my_ftell (FILEOBJ fo)
*
* PreCondition: File opened
*
* Input: fo - Pointer to file structure
*
* Output: fo->seek - Current location of the file
*
* Side Effects: None
*
* Overview: User called function to determine the current location of a file
*
* Note: None
*****************************************************************************/
long my_ftell (MYFILE * fo)
{
return (fo->seek);
}
/******************************************************************************
* Function: int my_remove (const char * fileName)
*
* PreCondition: File not opened, file exists
*
* Input: compare - Pointer to file to be erased
*
* Output: 0 - File removed
* -1 - File was not removed
*
* Side Effects: None
*
* Overview: User called function to erase a file
*
* Note: None
*****************************************************************************/
int my_remove (const char * fileName)
{
MYFILE f;
MYFILE gblFileTemp;
FILEOBJ fo = &f;
CETYPE result;
if (WriteProtectState())
{
return (-1);
}
//Format the source string to FAT16 lib spec.
if( !FormatFileName(fileName, fo->name) )
return -1;
fo->dsk = &glbDiskData;
fo->cluster = 0;
fo->ccls = 0;
// start at the root directory
fo->dirclus = 0;
fo->dirccls = 0;
// copy file object over
FileObjectCopy(&gblFileTemp, fo);
// See if the file is found
result = FILEfind (fo, &gblFileTemp, 1);
if (result != CE_GOOD)
return -1;
result = FILEerase(fo, &fo->entry, TRUE);
if( result == CE_GOOD )
return 0;
else
return -1;
}
/******************************************************************************
* Function: int my_fseek(MYFILE *stream, long offset, int whence)
*
* PreCondition: File exists
*
* Input: stream - Pointer to file structure
* offset - Offset from origin location
* whence - SEEK_SET - Seek from start of file
* SEEK_CUR - Seek from current location
* SEEK_END - Seek from end of file
*
* Output: 0 - Operation successful
* -1 - Operation unsuccesful
*
* Side Effects: None
*
* Overview: User called function to set the starting position of the stream to the offset
*
* Note: None
*****************************************************************************/
int my_fseek(MYFILE *stream, long offset, int whence)
{
CETYPE err;
err = __fseek (stream, offset, (BYTE)whence);
if( err == CE_GOOD )
return 0;
else
return -1;
}
/******************************************************************************
* Function: void my_rewind (FILEOBJ fo)
*
* PreCondition: File opened, file exists
*
* Input: fo - Pointer to file structure
*
* Output: void
*
* Side Effects: None
*
* Overview: User called function to reset the position of the file
*
* Note: None
*****************************************************************************/
void my_rewind (FILEOBJ fo)
{
fo->seek = 0;
fo->pos = 0;
fo->sec = 0;
fo->ccls = fo->cluster;
gBufferOwner = NULL;
return;
}
/******************************************************************************
* Function: void FileObjectCopy(FILEOBJ foDest,FILEOBJ foSource)
*
*
* Input: foDest - The destination
* foSource - the source
*
* Output: None
*
* Side Effects: None
*
* Overview: Makes a replica of an existing file object
*
* Note: None
*****************************************************************************/
void FileObjectCopy(FILEOBJ foDest,FILEOBJ foSource)
{
BYTE i;
BYTE size;
BYTE *dest;
BYTE *source;
dest = (BYTE *)foDest;
source = (BYTE *)foSource;
size = sizeof(MYFILE);
for(i=0; i< size; i++)
{
dest[i] = source[i];
}
}
/******************************************************************************
* Function: CETYPE FILECreateHeadCluster( FILEOBJ fo, WORD *cluster)
*
* PreCondition: Disk mounted
*
* Input: fo - Pointer to file structure
* cluster - Cluster location
*
* Output: CE_GOOD - File closed successfully
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -