📄 file.c
字号:
}
file_setpos(file,file->FileSize);
file_setAttr(file,FILE_STATUS_OPEN,1);
file_setAttr(file,FILE_STATUS_WRITE,1);
}
else /* File does not excist */
{
if(fs_findFreeFile(fs,filename,&loc,0))
{
dir_createDefaultEntry(fs,&wtmp,fatfilename);
dir_createDirectoryEntry(fs,&wtmp,&loc);
memCpy(&wtmp,&(file->DirEntry),sizeof(wtmp));
file_initFile(file,fs,&loc);
sec=fs_getNextFreeCluster(file->fs,fs_giveFreeClusterHint(file->fs));
dir_setFirstCluster(file->fs,&(file->Location),sec);
fs_setFirstClusterInDirEntry(&(file->DirEntry),sec);
fs_initClusterChain(fs,&(file->Cache),sec);
fat_setNextClusterAddress(fs,sec,fat_giveEocMarker(fs));
file_setAttr(file,FILE_STATUS_OPEN,1);
file_setAttr(file,FILE_STATUS_WRITE,1);
}
else
{
return(-3);
}
}
return(0);
break;
default:
return(-4);
break;
}
return(-5);
}
esint8 findFile(FileSystem *fs, eint8* filename, FileLocation *loc);
/* ***************************************************************************\
* signed eint8 file_fopen(FileSystem *fs,File* file,eint8* filename)
* Description: This functions opens a file.
* This function is about to be redesigned. No Docs.
* Return value:
*/
esint8 file_ropen(File* file, FileSystem *fs, eint8* filename)
{
FileLocation loc;
if(findFile(fs, filename, &loc) == 1)
{
dir_getFileStructure(fs, &(file->DirEntry), &loc);
file_initFile(file, fs, &loc);
file_setAttr(file, FILE_STATUS_OPEN, 1);
file_setAttr(file, FILE_STATUS_WRITE, 0);
return(0);
}
return(-1);
}
esint8 findFile(FileSystem *fs, eint8* filename, FileLocation *loc)
{
euint32 currentDir = fs->FirstClusterCurrentDir;
if(dir_findinDir(fs, filename, currentDir, loc, DIRFIND_FILE) == 0)
{
// didn't find the file in the current working directory.
return(0);
}
if(loc->attrib & ATTR_DIRECTORY)
{
// found the "file," but it turned out to be a directory...
return(2);
}
return(1); // alls well, we found the file and loc is updated by dir_findinDir with it's location information.
}
/*****************************************************************************/
/* ****************************************************************************
* esint8 file_fclose(File *file)
* Description: This function closes a file, by clearing the object.
* Return value: 0 on success.
*/
esint8 file_fclose(File *file)
{
#ifdef DATE_TIME_SUPPORT
file->DirEntry.AccessDate = time_getDate();
if(file_getAttr(file,FILE_STATUS_WRITE)){
file->DirEntry.FileSize = file->FileSize;
file->DirEntry.WriteDate = file->DirEntry.AccessDate;
file->DirEntry.WriteTime = time_getTime();
}
dir_updateDirectoryEntry(file->fs,&(file->DirEntry),&(file->Location));
#else
if(file_getAttr(file,FILE_STATUS_WRITE)){
dir_setFileSize(file->fs,&(file->Location),file->FileSize);
}
#endif
memClr(file,sizeof(*file));
file_setAttr(file,FILE_STATUS_OPEN,0);
file_setAttr(file,FILE_STATUS_WRITE,0);
return(0);
}
/* ****************************************************************************
* void file_initFile(File *file, FileSystem *fs, FileLocation *loc)
* Description: This function initialises a new file object, by filling in
* the fs pointer, filesize (note, that DirEntry must already be filled in)
* and known cache parameters.
* Return value: void
*/
void file_initFile(File *file, FileSystem *fs, FileLocation *loc)
{
file->fs=fs;
file->FileSize=file->DirEntry.FileSize;
file->FilePtr=0;
file->Location.Sector=loc->Sector;
file->Location.Offset=loc->Offset;
file->Cache.Linear=0;
file->Cache.FirstCluster=(((euint32)file->DirEntry.FirstClusterHigh)<<16)+
file->DirEntry.FirstClusterLow;
file->Cache.LastCluster=0;
file->Cache.LogicCluster=0;
file->Cache.DiscCluster=file->Cache.FirstCluster;
}
/*****************************************************************************/
/* ****************************************************************************
* euint8* file_normalToFatName(eint8* filename,eint8* fatfilename)
* Description: This function converts a human readable filename (limited to
* 8.3 eint8 character) to a valid FAT (not VFAT) filename. Invalid characters are
* changed to capital X and only the first 11 characters are used.
* Furthermore all letters are capitalised.
* Return value: pointer after the filename
*/
eint8* file_normalToFatName(eint8* filename,eint8* fatfilename)
{
euint8 c, dot = 0, vc = 0;
for(c = 0; c < 11; c++)
{
fatfilename[c] = ' ';
}
c = 0;
if(*filename == '.')
{
fatfilename[0] = '.';
vc++;
if(*(filename+1) == '.')
{
fatfilename[1] = '.';
filename += 2;
}
else
{
filename++;
}
}
else
{
while(*filename != '\0' && *filename != ' ' && *filename != '/')
{
if(*filename == '.' && !dot)
{
dot = 1;
c = 8;
}
else
{
if(dot)
{
if(c <= 10)
{
fatfilename[c] = file_validateChar(*filename);
c++;
}
}
else
{
if(c <= 7)
{
fatfilename[c] = file_validateChar(*filename);
c++;
vc++;
}
}
}
filename++;
}
}
if(vc > 0)
{
if(*filename == '\0')
{
return(filename);
}
else
{
return(filename+1);
}
}
else
{
return(0);
}
}
/*****************************************************************************/
/* ****************************************************************************
*
* Description: This function takes the character c, and if it is not a *
* valid FAT Filename character returns X. If it is a lowercase letter the *
* uppercase equivalent is returned. The remaining characters are returned *
* as they are.
* Return value: The validated char
*/
euint8 file_validateChar(euint8 c)
{
if( (c<0x20) || (c>0x20&&c<0x30&&c!='-') || (c>0x39&&c<0x41) || (c>0x5A&&c<0x61&&c!='_') || (c>0x7A&&c!='~') )
return(0x58);
if( c>=0x61 && c<=0x7A )
return(c-32);
return(c);
}
/*****************************************************************************/
/* ****************************************************************************
* void ioman_setAttr(IOManager *ioman,euint16 bufplace,euint8 attribute,euint8 val)
* Description: This sets the attribute of 'bufplace' to the given value (binary).
*
* Return value: void
*/
void file_setAttr(File* file,euint8 attribute,euint8 val)
{
if(val){
file->FileStatus|=1<<attribute;
}else{
file->FileStatus&=~(1<<attribute);
}
}
/*****************************************************************************/
/* ****************************************************************************
* euint8 ioman_getAttr(IOManager *ioman,euint16 bufplace,euint8 attribute)
* Description: This function retrieves an attribute from the bufstat array.
* It returns nonzero when it attribute is true and 0 when it is false.
* Please note, I said "nonzero", not 1.
* Return value: Attribute.
*/
euint8 file_getAttr(File* file,euint8 attribute)
{
return(file->FileStatus&(1<<attribute));
}
/*****************************************************************************/
euint32 file_requiredCluster(File *file,euint32 offset, euint32 size)
{
euint32 clusters_required,clustersize;
euint32 hc;
if((offset+size)>file->FileSize){
if(file->Cache.ClusterCount==0){ /* Number of cluster unknown */
hc = fat_countClustersInChain(file->fs,file->Cache.FirstCluster);
file->Cache.ClusterCount = hc;
}else{
hc = file->Cache.ClusterCount; /* This better be right */
}
clustersize = file->fs->volumeId.BytesPerSector * file->fs->volumeId.SectorsPerCluster;
if((size-file->FileSize+offset)>
((hc-((file->FileSize+clustersize-1)/clustersize))*clustersize)){
clusters_required = (((offset+size)-(hc*clustersize))+clustersize-1)/clustersize;
}else{
clusters_required = 0;
}
}else{
clusters_required = 0;
}
return(clusters_required);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -