//----------------------------------------------------------------------------- // fl_list_opendir: Opens a directory for listing //----------------------------------------------------------------------------- int fl_list_opendir(const char *path, struct fs_dir_list_status *dirls) { int levels; UINT32 cluster = FAT32_INVALID_CLUSTER; // If first call to library, initialise CHECK_FL_INIT(); FL_LOCK(&_fs); levels = fatfs_total_path_levels((char*)path) + 1; // If path is in the root dir if (levels == 0) cluster = fatfs_get_root_cluster(&_fs); // Find parent directory start cluster else _open_directory((char*)path, &cluster); fatfs_list_directory_start(&_fs, dirls, cluster); FL_UNLOCK(&_fs); return cluster != FAT32_INVALID_CLUSTER ? 1 : 0; }
void fl_listdirectory(const char *path) { struct fs_dir_list_status dirstat; // int filenumber = 0; // If first call to library, initialise CHECK_FL_INIT(); FL_LOCK(&_fs); FAT_PRINT(("\r\nNo. Filename\r\n")); if (fl_list_opendir(path, &dirstat)) { struct fs_dir_ent dirent; while (fl_list_readdir(&dirstat, &dirent)) { FAT_PRINT(dirent.filename); if (dirent.is_dir) { FAT_PRINT(" <DIR>"); } FAT_PRINT("\r\n"); } } FL_UNLOCK(&_fs); }
//----------------------------------------------------------------------------- // fl_fflush: Flush un-written data to the file //----------------------------------------------------------------------------- int fl_fflush(void *f) { #ifdef FATFS_INC_WRITE_SUPPORT FL_FILE *file = (FL_FILE *)f; // If first call to library, initialise CHECK_FL_INIT(); if (file) { FL_LOCK(&_fs); // If some write data still in buffer if (file->file_data.dirty) { // Write back current sector before loading next if (_write_sector(file, file->file_data.address, file->file_data.sector)) file->file_data.dirty = 0; } FL_UNLOCK(&_fs); } #endif return 0; }
int fl_fputc(int c, FL_FILE *file) { BYTE Buffer[1]; // If first call to library, initialise CHECK_FL_INIT(); if (file==NULL) return -1; // Check if file open if (file->inUse==FALSE) return -1; // Append writes to end of file if (file->Append) file->bytenum = file->filelength; // Else write to current position // Write single byte Buffer[0] = (BYTE)c; if (_write_block(file, Buffer, 1)) return c; else return -1; }
//----------------------------------------------------------------------------- // fl_attach_media: //----------------------------------------------------------------------------- int fl_attach_media(fn_diskio_read rd, fn_diskio_write wr) { int res; // If first call to library, initialise CHECK_FL_INIT(); _fs.disk_io.read_sector = rd; _fs.disk_io.write_sector = wr; // Initialise FAT parameters if ((res = fatfs_init(&_fs)) != FAT_INIT_OK) { #ifdef FAT_PRINT FAT_PRINT("FAT_FS: Error could not load FAT details! Formatting...\r\n"); #endif if(fl_format() != 1) { #ifdef FAT_PRINT FAT_PRINT("FAT_FS: Could not format"); #endif res = FAT_INIT_COULD_NOT_FORMAT; return res; } } _filelib_valid = 1; return FAT_INIT_OK; }
//----------------------------------------------------------------------------- // fl_shutdown: Call before shutting down system //----------------------------------------------------------------------------- void fl_shutdown() { // If first call to library, initialise CHECK_FL_INIT(); FAT32_PurgeFATBuffer(); }
int fl_remove( const char * filename ) { FL_FILE* file; FAT32_ShortEntry sfEntry; // If first call to library, initialise CHECK_FL_INIT(); file = _find_spare_file(); if (file==NULL) return -1; // Clear filename memset(file->path, '\n', sizeof(file->path)); memset(file->filename, '\n', sizeof(file->filename)); // Split full path into filename and directory path FileString_SplitPath((char*)filename, file->path, file->filename); // If file is in the root dir if (file->path[0]==0) { file->parentcluster = FAT32_GetRootCluster(); file->inRoot = TRUE; } else { file->inRoot = FALSE; // Find parent directory start cluster if (!_open_directory(file->path, &file->parentcluster)) return -1; } // Using dir cluster address search for filename if (FAT32_GetFileEntry(file->parentcluster, file->filename,&sfEntry)) { // Initialise file details memcpy(file->shortfilename, sfEntry.Name, 11); file->filelength = sfEntry.FileSize; file->bytenum = 0; file->startcluster = (((UINT32)sfEntry.FstClusHI)<<16) + sfEntry.FstClusLO; file->currentBlock = 0xFFFFFFFF; // Delete allocated space if (!FAT32_FreeClusterChain(file->startcluster)) return -1; // Remove directory entries if (!FAT32_MarkFileDeleted(file->parentcluster, (char*)file->shortfilename)) return -1; FAT32_PurgeFATBuffer(); return 0; } else return -1; }
//----------------------------------------------------------------------------- // fl_shutdown: Call before shutting down system //----------------------------------------------------------------------------- void fl_shutdown(void) { // If first call to library, initialise CHECK_FL_INIT(); FL_LOCK(&_fs); fatfs_fat_purge(&_fs); FL_UNLOCK(&_fs); }
//----------------------------------------------------------------------------- // _read_file: Open a file for reading //----------------------------------------------------------------------------- static FL_FILE* _read_file(char *path) { FL_FILE* file; FAT32_ShortEntry sfEntry; // If first call to library, initialise CHECK_FL_INIT(); file = _find_spare_file(); if (file==NULL) return NULL; // Clear filename memset(file->path, '\n', sizeof(file->path)); memset(file->filename, '\n', sizeof(file->filename)); // Split full path into filename and directory path FileString_SplitPath(path, file->path, file->filename); // Check if file already open if (_check_file_open(file)) return FALSE; // If file is in the root dir if (file->path[0]==0) { file->parentcluster = FAT32_GetRootCluster(); file->inRoot = TRUE; } else { file->inRoot = FALSE; // Find parent directory start cluster if (!_open_directory(file->path, &file->parentcluster)) return NULL; } // Using dir cluster address search for filename if (FAT32_GetFileEntry(file->parentcluster, file->filename,&sfEntry)) { // Initialise file details memcpy(file->shortfilename, sfEntry.Name, 11); file->filelength = sfEntry.FileSize; file->bytenum = 0; file->startcluster = (((UINT32)sfEntry.FstClusHI)<<16) + sfEntry.FstClusLO; file->currentBlock = 0xFFFFFFFF; file->inUse = TRUE; FAT32_PurgeFATBuffer(); return file; } return NULL; }
int fl_createdirectory(const char *path) { int res; // If first call to library, initialise CHECK_FL_INIT(); FL_LOCK(&_fs); res =_create_directory((char*)path); FL_UNLOCK(&_fs); return res; }
//----------------------------------------------------------------------------- // fl_fgetc: Get a character in the stream //----------------------------------------------------------------------------- int fl_fgetc(FL_FILE *file) { UINT32 sector; UINT32 offset; BYTE returnchar=0; // If first call to library, initialise CHECK_FL_INIT(); if (file==NULL) return -1; // Check if file open if (file->inUse==FALSE) return -1; // No read permissions if (file->Read==FALSE) return -1; // Check if read past end of file if (file->bytenum>=file->filelength) return -1; // Calculations for file position sector = file->bytenum / 512; offset = file->bytenum - (sector*512); // If file block not already loaded if (file->currentBlock!=sector) { // Read the appropriate sector if (!FAT32_SectorReader(file->startcluster, sector)) return -1; // Copy to file's buffer memcpy(file->filebuf, FATFS_Internal.currentsector, 512); file->currentBlock=sector; } // Get the data block returnchar = file->filebuf[offset]; // Increase next read position file->bytenum++; // Return character read return returnchar; }
//----------------------------------------------------------------------------- // fl_list_readdir: Get next item in directory //----------------------------------------------------------------------------- int fl_list_readdir(struct fs_dir_list_status *dirls, struct fs_dir_ent *entry) { int res = 0; // If first call to library, initialise CHECK_FL_INIT(); FL_LOCK(&_fs); res = fatfs_list_directory_next(&_fs, dirls, entry); FL_UNLOCK(&_fs); return res; }
//----------------------------------------------------------------------------- // fl_fclose: Close an open file //----------------------------------------------------------------------------- void fl_fclose(FL_FILE *file) { // If first call to library, initialise CHECK_FL_INIT(); if (file!=NULL) { file->bytenum = 0; file->filelength = 0; file->startcluster = 0; file->currentBlock = 0xFFFFFFFF; file->inUse = FALSE; FAT32_PurgeFATBuffer(); } }
//----------------------------------------------------------------------------- // fl_fseek: Seek to a specific place in the file // TODO: This should support -ve numbers with SEEK END and SEEK CUR //----------------------------------------------------------------------------- int fl_fseek( FL_FILE *file , UINT32 offset , int origin ) { // If first call to library, initialise CHECK_FL_INIT(); if (file==NULL) return -1; // Check if file open if (file->inUse==FALSE) return -1; if ( (origin == SEEK_END) && (offset!=0) ) return -1; // Invalidate file buffer file->currentBlock = 0xFFFFFFFF; if (origin==SEEK_SET) { file->bytenum = offset; if (file->bytenum>file->filelength) file->bytenum = file->filelength; return 0; } else if (origin==SEEK_CUR) { file->bytenum+= offset; if (file->bytenum>file->filelength) file->bytenum = file->filelength; return 0; } else if (origin==SEEK_END) { file->bytenum = file->filelength; return 0; } else return -1; }
int fl_fputs(const char * str, FL_FILE *file) { // If first call to library, initialise CHECK_FL_INIT(); if (file==NULL) return -1; // Check if file open if (file->inUse==FALSE) return -1; // Append writes to end of file if (file->Append) file->bytenum = file->filelength; // Else write to current position if (_write_block(file, (BYTE*)str, (UINT32)strlen(str))) return (int)strlen(str); else return -1; }
int fl_fwrite(const void * data, int size, int count, FL_FILE *file ) { // If first call to library, initialise CHECK_FL_INIT(); if (file==NULL) return -1; // Check if file open if (file->inUse==FALSE) return -1; // Append writes to end of file if (file->Append) file->bytenum = file->filelength; // Else write to current position if (_write_block(file, (BYTE*)data, (size*count) )) return count; else return -1; }
//----------------------------------------------------------------------------- // fl_fclose: Close an open file //----------------------------------------------------------------------------- void fl_fclose(void *f) { FL_FILE *file = (FL_FILE *)f; // If first call to library, initialise CHECK_FL_INIT(); if (file) { FL_LOCK(&_fs); // Flush un-written data to file fl_fflush(f); // File size changed? if (file->filelength_changed) { #ifdef FATFS_INC_WRITE_SUPPORT // Update filesize in directory fatfs_update_file_length(&_fs, file->parentcluster, (char*)file->shortfilename, file->filelength); #endif file->filelength_changed = 0; } file->bytenum = 0; file->filelength = 0; file->startcluster = 0; file->file_data.address = 0xFFFFFFFF; file->file_data.dirty = 0; file->filelength_changed = 0; // Free file handle _free_file(file); fatfs_fat_purge(&_fs); FL_UNLOCK(&_fs); } }
//----------------------------------------------------------------------------- // fl_fread: Read a block of data from the file //----------------------------------------------------------------------------- int fl_fread(void * buffer, int size, int length, void *f ) { unsigned long sector; unsigned long offset; int copyCount; int count = size * length; int bytesRead = 0; FL_FILE *file = (FL_FILE *)f; // If first call to library, initialise CHECK_FL_INIT(); if (buffer==NULL || file==NULL) return -1; // No read permissions if (!(file->flags & FILE_READ)) return -1; // Nothing to be done if (!count) return 0; // Check if read starts past end of file if (file->bytenum >= file->filelength) return -1; // Limit to file size if ( (file->bytenum + count) > file->filelength ) count = file->filelength - file->bytenum; // Calculate start sector sector = file->bytenum / FAT_SECTOR_SIZE; // Offset to start copying data from first sector offset = file->bytenum % FAT_SECTOR_SIZE; while (bytesRead < count) { // Do we need to re-read the sector? if (file->file_data.address != sector) { // Flush un-written data to file if (file->file_data.dirty) fl_fflush(file); // Get LBA of sector offset within file if (!_read_sector(file, sector)) // Read failed - out of range (probably) break; file->file_data.address = sector; file->file_data.dirty = 0; } // We have upto one sector to copy copyCount = FAT_SECTOR_SIZE - offset; // Only require some of this sector? if (copyCount > (count - bytesRead)) copyCount = (count - bytesRead); // Copy to application buffer memcpy( (unsigned char*)((unsigned char*)buffer + bytesRead), (unsigned char*)(file->file_data.sector + offset), copyCount); // Increase total read count bytesRead += copyCount; // Increment file pointer file->bytenum += copyCount; // Move onto next sector and reset copy offset sector++; offset = 0; } return bytesRead; }
static BOOL _write_block(FL_FILE *file, BYTE *data, UINT32 length) { UINT32 sector; UINT32 offset; UINT32 i; BOOL dirtySector = FALSE; // If first call to library, initialise CHECK_FL_INIT(); if (file==NULL) return FALSE; // Check if file open if (file->inUse==FALSE) return FALSE; // No write permissions if (file->Write==FALSE) return FALSE; for (i=0;i<length;i++) { // Calculations for file position sector = file->bytenum / 512; offset = file->bytenum - (sector*512); // If file block not already loaded if (file->currentBlock!=sector) { if (dirtySector) { // Copy from file buffer to FAT driver buffer memcpy(FATFS_Internal.currentsector, file->filebuf, 512); // Write back current sector before loading next if (!FAT32_SectorWriter(file->startcluster, file->currentBlock)) return FALSE; } // Read the appropriate sector // NOTE: This does not have succeed; if last sector of file // reached, no valid data will be read in, but write will // allocate some more space for new data. FAT32_SectorReader(file->startcluster, sector); // Copy to file's buffer memcpy(file->filebuf, FATFS_Internal.currentsector, 512); file->currentBlock=sector; dirtySector = FALSE; } // Get the data block file->filebuf[offset] = data[i]; dirtySector = TRUE; // Increase next read/write position file->bytenum++; } // If some write data still in buffer if (dirtySector) { // Copy from file buffer to FAT driver buffer memcpy(FATFS_Internal.currentsector, file->filebuf, 512); // Write back current sector before loading next if (!FAT32_SectorWriter(file->startcluster, file->currentBlock)) return FALSE; } // Increase file size file->filelength+=length; // Update filesize in directory FAT32_UpdateFileLength(file->parentcluster, (char*)file->shortfilename, file->filelength); return TRUE; }
int fl_fwrite(const void * data, int size, int count, void *f ) { FL_FILE *file = (FL_FILE *)f; unsigned long sector; unsigned long offset; unsigned long length = (size*count); unsigned char *buffer = (unsigned char *)data; // int dirtySector = 0; unsigned long bytesWritten = 0; unsigned long copyCount; // If first call to library, initialise CHECK_FL_INIT(); if (!file) return -1; FL_LOCK(&_fs); // No write permissions if (!(file->flags & FILE_WRITE)) { FL_UNLOCK(&_fs); return -1; } // Append writes to end of file if (file->flags & FILE_APPEND) file->bytenum = file->filelength; // Else write to current position // Calculate start sector sector = file->bytenum / FAT_SECTOR_SIZE; // Offset to start copying data from first sector offset = file->bytenum % FAT_SECTOR_SIZE; while (bytesWritten < length) { // We have upto one sector to copy copyCount = FAT_SECTOR_SIZE - offset; // Only require some of this sector? if (copyCount > (length - bytesWritten)) copyCount = (length - bytesWritten); // Do we need to read a new sector? if (file->file_data.address != sector) { // Flush un-written data to file if (file->file_data.dirty) fl_fflush(file); // If we plan to overwrite the whole sector, we don't need to read it first! if (copyCount != FAT_SECTOR_SIZE) { // NOTE: This does not have succeed; if last sector of file // reached, no valid data will be read in, but write will // allocate some more space for new data. // Get LBA of sector offset within file if (!_read_sector(file, sector)) memset(file->file_data.sector, 0x00, FAT_SECTOR_SIZE); } file->file_data.address = sector; file->file_data.dirty = 0; } // Copy from application buffer into sector buffer memcpy((unsigned char*)(file->file_data.sector + offset), (unsigned char*)(buffer + bytesWritten), copyCount); // Mark buffer as dirty file->file_data.dirty = 1; // Increase total read count bytesWritten += copyCount; // Increment file pointer file->bytenum += copyCount; // Move onto next sector and reset copy offset sector++; offset = 0; } // Write increased extent of the file? if (file->bytenum > file->filelength) { // Increase file size to new point file->filelength = file->bytenum; // We are changing the file length and this // will need to be writen back at some point file->filelength_changed = 1; } FL_UNLOCK(&_fs); return (size*count); }
static FL_FILE* _create_file(char *filename, UINT32 size) { FL_FILE* file; FAT32_ShortEntry sfEntry; char shortFilename[11]; int tailNum; // If first call to library, initialise CHECK_FL_INIT(); file = _find_spare_file(); if (file==NULL) return NULL; // Clear filename memset(file->path, '\n', sizeof(file->path)); memset(file->filename, '\n', sizeof(file->filename)); // Split full path into filename and directory path FileString_SplitPath(filename, file->path, file->filename); // Check if file already open if (_check_file_open(file)) return FALSE; // If file is in the root dir if (file->path[0]==0) { file->parentcluster = FAT32_GetRootCluster(); file->inRoot = TRUE; } else { file->inRoot = FALSE; // Find parent directory start cluster if (!_open_directory(file->path, &file->parentcluster)) return NULL; } // Check if same filename exists in directory if (FAT32_GetFileEntry(file->parentcluster, file->filename,&sfEntry)==TRUE) return NULL; // Create the file space for the file file->startcluster = 0; file->filelength = size; if (!FAT32_AllocateFreeSpace(TRUE, &file->startcluster, (file->filelength==0)?1:file->filelength)) return NULL; // Generate a short filename & tail tailNum = 0; do { // Create a standard short filename (without tail) FATMisc_CreateSFN(shortFilename, file->filename); // If second hit or more, generate a ~n tail if (tailNum!=0) FATMisc_GenerateTail((char*)file->shortfilename, shortFilename, tailNum); // Try with no tail if first entry else memcpy(file->shortfilename, shortFilename, 11); // Check if entry exists already or not if (FAT32_SFNexists(file->parentcluster, (char*)file->shortfilename)==FALSE) break; tailNum++; } while (tailNum<9999); if (tailNum==9999) return NULL; // Add file to disk if (!FAT32_AddFileEntry(file->parentcluster, (char*)file->filename, (char*)file->shortfilename, file->startcluster, file->filelength)) return NULL; // General file->bytenum = 0; file->currentBlock = 0xFFFFFFFF; file->inUse = TRUE; FAT32_PurgeFATBuffer(); return file; }
//----------------------------------------------------------------------------- // fl_fread: Read a block of data from the file //----------------------------------------------------------------------------- int fl_fread (FL_FILE *file, BYTE * buffer, UINT32 count) { UINT32 sector; UINT32 offset; UINT32 totalSectors; UINT32 bytesRead; UINT32 thisReadCount; UINT32 i; // If first call to library, initialise CHECK_FL_INIT(); if (buffer==NULL || file==NULL) return -1; // Check if file open if (file->inUse==FALSE) return -1; // No read permissions if (file->Read==FALSE) return -1; // Nothing to be done if (count==0) return 0; // Check if read starts past end of file if (file->bytenum>=file->filelength) return -1; // Limit to file size if ( (file->bytenum + count) > file->filelength ) count = file->filelength - file->bytenum; // Calculations for file position sector = file->bytenum / 512; offset = file->bytenum - (sector*512); // Calculate how many sectors this is totalSectors = (count+offset) / 512; // Take into account partial sector read if ((count+offset) % 512) totalSectors++; bytesRead = 0; for (i=0;i<totalSectors;i++) { // Read sector of file if ( FAT32_SectorReader(file->startcluster, (sector+i)) ) { // Read length - full sector or remainder if ( (bytesRead+512) > count ) thisReadCount = count - bytesRead; else thisReadCount = 512; // Copy to file buffer (for continuation reads) memcpy(file->filebuf, FATFS_Internal.currentsector, 512); file->currentBlock = (sector+i); // Copy to application buffer // Non aligned start if ( (i==0) && (offset!=0) ) memcpy( (BYTE*)(buffer+bytesRead), (BYTE*)(file->filebuf+offset), thisReadCount); else memcpy( (BYTE*)(buffer+bytesRead), file->filebuf, thisReadCount); bytesRead+=thisReadCount; file->bytenum+=thisReadCount; if (thisReadCount>=count) return bytesRead; } // Read failed - out of range (probably) else { return (int)bytesRead; } } return bytesRead; }
//----------------------------------------------------------------------------- // fopen: Open or Create a file for reading or writing //----------------------------------------------------------------------------- void* fl_fopen(const char *path, const char *mode) { int i; FL_FILE* file; unsigned char flags = 0; // If first call to library, initialise CHECK_FL_INIT(); if (!_filelib_valid) return NULL; if (!path || !mode) return NULL; // Supported Modes: // "r" Open a file for reading. The file must exist. // "w" Create an empty file for writing. If a file with the same name already exists its content is erased and the file is treated as a new empty file. // "a" Append to a file. Writing operations append data at the end of the file. The file is created if it does not exist. // "r+" Open a file for update both reading and writing. The file must exist. // "w+" Create an empty file for both reading and writing. If a file with the same name already exists its content is erased and the file is treated as a new empty file. // "a+" Open a file for reading and appending. All writing operations are performed at the end of the file, protecting the previous content to be overwritten. You can reposition (fseek, rewind) the internal pointer to anywhere in the file for reading, but writing operations will move it back to the end of file. The file is created if it does not exist. for (i=0;i<(int)strlen(mode);i++) { switch (tolower(mode[i])) { case 'r': flags |= FILE_READ; break; case 'w': flags |= FILE_WRITE; flags |= FILE_ERASE; flags |= FILE_CREATE; break; case 'a': flags |= FILE_WRITE; flags |= FILE_APPEND; flags |= FILE_CREATE; break; case '+': if (flags & FILE_READ) flags |= FILE_WRITE; else if (flags & FILE_WRITE) { flags |= FILE_READ; flags |= FILE_ERASE; flags |= FILE_CREATE; } else if (flags & FILE_APPEND) { flags |= FILE_READ; flags |= FILE_WRITE; flags |= FILE_APPEND; flags |= FILE_CREATE; } break; case 'b': flags |= FILE_BINARY; break; } } file = NULL; #ifndef FATFS_INC_WRITE_SUPPORT // No write support! flags &= ~(FILE_CREATE | FILE_WRITE | FILE_APPEND); #endif // No write access - remove write/modify flags if (!_fs.disk_io.write_sector) flags &= ~(FILE_CREATE | FILE_WRITE | FILE_APPEND); FL_LOCK(&_fs); // Read file = _open_file(path); //if (!(flags & FILE_READ)) // _free_file(file); // Create New #ifdef FATFS_INC_WRITE_SUPPORT // Remove old file if(flags & FILE_ERASE) { fl_remove(path); if(file) _free_file(file); } if (!file && (flags & FILE_CREATE)) file = _create_file(path); #endif // Write Existing (and not open due to read or create) //if (!(flags & FILE_READ)) // if (!(flags & FILE_CREATE)) // if (flags & (FILE_WRITE | FILE_APPEND)) // file = _open_file(path); if (file) file->flags = flags; FL_UNLOCK(&_fs); return file; }
//----------------------------------------------------------------------------- // fopen: Open or Create a file for reading or writing //----------------------------------------------------------------------------- FL_FILE* fl_fopen(char *path, char *mode) { int modlen, i; FL_FILE* file; BOOL read = FALSE; BOOL write = FALSE; BOOL append = FALSE; BOOL binary = FALSE; BOOL create = FALSE; BOOL erase = FALSE; // If first call to library, initialise CHECK_FL_INIT(); if ((path==NULL) || (mode==NULL)) return NULL; modlen = (int)strlen(mode); // Supported Modes: // "r" Open a file for reading. The file must exist. // "w" Create an empty file for writing. If a file with the same name already exists its content is erased and the file is treated as a new empty file. // "a" Append to a file. Writing operations append data at the end of the file. The file is created if it does not exist. // "r+" Open a file for update both reading and writing. The file must exist. // "w+" Create an empty file for both reading and writing. If a file with the same name already exists its content is erased and the file is treated as a new empty file. // "a+" Open a file for reading and appending. All writing operations are performed at the end of the file, protecting the previous content to be overwritten. You can reposition (fseek, rewind) the internal pointer to anywhere in the file for reading, but writing operations will move it back to the end of file. The file is created if it does not exist. for (i=0;i<modlen;i++) { switch (tolower(mode[i])) { case 'r': read = TRUE; break; case 'w': write = TRUE; erase = TRUE; create = TRUE; break; case 'a': write = TRUE; append = TRUE; create = TRUE; break; case '+': if (read) write = TRUE; else if (write) { read = TRUE; erase = TRUE; create = TRUE; } else if (append) { read = TRUE; write = TRUE; append = TRUE; create = TRUE; } break; case 'b': binary = TRUE; break; } } file = NULL; // Read if (read) file = _read_file(path); // Create New #ifdef INCLUDE_WRITE_SUPPORT if ( (file==NULL) && (create) ) file = _create_file(path, 0); #else create = FALSE; write = FALSE; append = FALSE; #endif // Write Existing if ( !create && !read && (write || append) ) file = _read_file(path); if (file!=NULL) { file->Read = read; file->Write = write; file->Append = append; file->Binary = binary; file->Erase = erase; } return file; }
//----------------------------------------------------------------------------- // fl_fseek: Seek to a specific place in the file //----------------------------------------------------------------------------- int fl_fseek( void *f, long offset, int origin ) { FL_FILE *file = (FL_FILE *)f; int res = -1; // If first call to library, initialise CHECK_FL_INIT(); if (!file) return -1; if (origin == SEEK_END && offset != 0) return -1; FL_LOCK(&_fs); // Invalidate file buffer file->file_data.address = 0xFFFFFFFF; file->file_data.dirty = 0; if (origin == SEEK_SET) { file->bytenum = (unsigned long)offset; if (file->bytenum > file->filelength) file->bytenum = file->filelength; res = 0; } else if (origin == SEEK_CUR) { // Positive shift if (offset >= 0) { file->bytenum += offset; if (file->bytenum > file->filelength) file->bytenum = file->filelength; } // Negative shift else { // Make shift positive offset = -offset; // Limit to negative shift to start of file if ((unsigned long)offset > file->bytenum) file->bytenum = 0; else file->bytenum-= offset; } res = 0; } else if (origin == SEEK_END) { file->bytenum = file->filelength; res = 0; } else res = -1; FL_UNLOCK(&_fs); return res; }