📄 file.c
字号:
if(fs_findFile(fs,filename,&loc,0)) { return(-2); } 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); return(0); } else { return(-3); } break; case MODE_APPEND: if(fs_findFile(fs,filename,&loc,0)==1) /* File exists */ { dir_getFileStructure(fs,&(file->DirEntry), &loc); file_initFile(file,fs,&loc); if(file->Cache.FirstCluster==0){ sec=fs_getNextFreeCluster(file->fs,fs_giveFreeClusterHint(file->fs)); dir_setFirstCluster(file->fs,&(file->Location),sec); fs_setFirstClusterInDirEntry(&(file->DirEntry),sec); fat_setNextClusterAddress(fs,sec,fat_giveEocMarker(fs)); file_initFile(file,fs,&loc); } 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 file_fclose(File *file) * Description: This function closes a file, by clearing the object. * Return value: 0 on success.*/esint8 file_fclose(File *file){ if(fs_hasTimeSupport()){ 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); } } 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){ hc = fat_countClustersInChain(file->fs,file->Cache.FirstCluster); 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 + -