//-----------------------------------------------------------------------------
// 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;
}
Esempio n. 4
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;
}
Esempio n. 6
0
//-----------------------------------------------------------------------------
// fl_shutdown: Call before shutting down system
//-----------------------------------------------------------------------------
void fl_shutdown()
{
	// If first call to library, initialise
	CHECK_FL_INIT();

	FAT32_PurgeFATBuffer();
}
Esempio n. 7
0
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);
}
Esempio n. 9
0
//-----------------------------------------------------------------------------
// _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;
}
Esempio n. 11
0
//-----------------------------------------------------------------------------
// 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;
}
Esempio n. 13
0
//-----------------------------------------------------------------------------
// 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();
	}
}
Esempio n. 14
0
//-----------------------------------------------------------------------------
// 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;
}
Esempio n. 15
0
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;
}
Esempio n. 16
0
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;
}
Esempio n. 19
0
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);
}
Esempio n. 21
0
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;
}
Esempio n. 22
0
//-----------------------------------------------------------------------------
// 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;	
}
Esempio n. 24
0
//-----------------------------------------------------------------------------
// 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;
}