Code:
//============================================================================== // Copyright (c) 2013, Isaac Marino Bavaresco // All rights reserved // isaacbavaresco@yahoo.com.br //============================================================================== /*============================================================================*/ #include <asf.h> #include <stdio.h> #include <fcntl.h> #include <errno.h> #include <string.h> #include "FileIO.h" /*============================================================================*/ #define MAX_FILES 10 /*============================================================================*/ typedef struct { unsigned int Next; int Valid; FIL File; } files_t; /*============================================================================*/ #define HandleIsValid(h) ( (unsigned int)(h) < sizeof Files / sizeof Files[0] ) /*============================================================================*/ static files_t Files[MAX_FILES]; static unsigned int FreeList = 0; static unsigned int OpenFiles = -1; /*============================================================================*/ static int TranslateErrNo( FRESULT Result ) { switch( Result ) { default: case FR_INT_ERR: /* (2) Assertion failed */ case FR_NOT_READY: /* (3) The physical drive cannot work */ case FR_WRITE_PROTECTED: /* (10) The physical drive is write protected */ case FR_NOT_ENABLED: /* (12) The volume has no work area */ case FR_NO_FILESYSTEM: /* (13) There is no valid FAT volume */ case FR_MKFS_ABORTED: /* (14) The f_mkfs() aborted due to any parameter error */ case FR_TIMEOUT: /* (15) Could not get a grant to access the volume within defined period */ case FR_LOCKED: /* (16) The operation is rejected according to the file shareing policy */ case FR_NOT_ENOUGH_CORE: /* (17) LFN working buffer could not be allocated */ return ENOSPC; case FR_DISK_ERR: /* (1) A hard error occured in the low level disk I/O layer */ return EIO; case FR_NO_FILE: /* (4) Could not find the file */ case FR_NO_PATH: /* (5) Could not find the path */ return ENOENT; case FR_INVALID_NAME: /* (6) The path name format is invalid */ case FR_INVALID_OBJECT: /* (9) The file/directory object is invalid */ case FR_INVALID_DRIVE: /* (11) The logical drive number is invalid */ case FR_INVALID_PARAMETER: /* (19) Given parameter is invalid */ return EINVAL; case FR_DENIED: /* (7) Acces denied due to prohibited access or directory full */ return EACCES; case FR_EXIST: /* (8) Acces denied due to prohibited access */ return EEXIST; case FR_TOO_MANY_OPEN_FILES: /* (18) Number of open files > _FS_SHARE */ return ENFILE; } } /*============================================================================*/ int FileIOInit( void ) { int i; for( i = 0; i < sizeof Files / sizeof Files[0] - 1; i++ ) { memset( &Files[i], 0, sizeof Files[i] ); Files[i].Next = i + 1; } memset( &Files[i], 0, sizeof Files[i] ); Files[i].Next = -1; FreeList = 0; OpenFiles = -1; return 0; } /*============================================================================*/ int open( const char *path, int oflag, ... ) { FRESULT Result; int Handle, Flags = 0; if( !HandleIsValid( FreeList )) { errno = ENFILE; return EOF; } #if _FS_READONLY if( oflag & O_RDWR || oflag & O_WRONLY || oflag & O_CREAT ) { errno = EACCES; return EOF; } else Flags |= FA_READ; #else // _FS_READONLY if( oflag & O_RDWR ) Flags |= FA_READ | FA_WRITE; else if( oflag & O_WRONLY ) Flags |= FA_WRITE; else Flags |= FA_READ; if( oflag & O_CREAT ) if( oflag & O_EXCL ) Flags |= FA_CREATE_NEW; else Flags |= FA_CREATE_ALWAYS; #endif // _FS_READONLY Handle = FreeList; Result = f_open( &Files[Handle].File, path, Flags ); if( Result != FR_OK ) { errno = TranslateErrNo( Result ); return EOF; } FreeList = Files[FreeList].Next; Files[Handle].Next = OpenFiles; Files[Handle].Valid = 1; OpenFiles = Handle; errno = 0; return Handle; } /*============================================================================*/ int close( int fildes ) { FRESULT Result; int i, j; if( !HandleIsValid( fildes ) || !Files[fildes].Valid ) { errno = EBADF; return EOF; } Result = f_close( &Files[fildes].File ); if( OpenFiles == fildes ) OpenFiles = Files[fildes].Next; else { for( i = sizeof Files / sizeof Files[0], j = OpenFiles; i > 0 && Files[j].Next != fildes; i--, j = Files[j].Next ) {} /* Should always be true. Testing just for safety */ if( Files[j].Next == fildes ) Files[j].Next = Files[fildes].Next; } memset( &Files[fildes], 0, sizeof Files[fildes] ); Files[fildes].Next = FreeList; FreeList = fildes; if( Result != FR_OK ) { errno = TranslateErrNo( Result ); return EOF; } errno = 0; return 0; } /*============================================================================*/ ssize_t read( int fildes, void *buf, ssize_t nbyte ) { FRESULT Result; UINT BytesRead; if( !HandleIsValid( fildes ) || !Files[fildes].Valid ) { errno = EBADF; return EOF; } Result = f_read( &Files[fildes].File, buf, nbyte, &BytesRead ); if( Result != FR_OK ) { errno = TranslateErrNo( Result ); return EOF; } errno = 0; return BytesRead; } /*============================================================================*/ ssize_t write( int fildes, const void *buf, ssize_t nbyte ) { #if _FS_READONLY errno = EACCES; return EOF; #else // _FS_READONLY FRESULT Result; UINT BytesRead; if( !HandleIsValid( fildes ) || !Files[fildes].Valid ) { errno = EBADF; return EOF; } Result = f_write( &Files[fildes].File, buf, nbyte, &BytesRead ); if( Result != FR_OK ) { errno = TranslateErrNo( Result ); return EOF; } errno = 0; return BytesRead; #endif // _FS_READONLY } /*============================================================================*/ off_t lseek( int fildes, off_t offset, int whence ) { FRESULT Result; if( !HandleIsValid( fildes ) || !Files[fildes].Valid ) { errno = EBADF; return EOF; } if( whence == SEEK_SET ) { if( offset < 0 ) offset = 0; else if( offset > Files[fildes].File.fsize ) offset = Files[fildes].File.fsize; } else if( whence == SEEK_END ) { if( offset > 0 ) offset = Files[fildes].File.fsize; else if( offset < -(long)Files[fildes].File.fsize ) offset = 0; else offset = Files[fildes].File.fsize - offset; } else if( whence == SEEK_CUR ) { if( Files[fildes].File.fptr + offset < 0 ) offset = 0; else if( Files[fildes].File.fptr + offset > Files[fildes].File.fsize ) offset = Files[fildes].File.fsize; else offset = Files[fildes].File.fptr + offset; } else { errno = EINVAL; return EOF; } Result = f_lseek( &Files[fildes].File, offset ); if( Result != FR_OK ) { errno = EOVERFLOW; return EOF; } errno = 0; return Files[fildes].File.fptr; } /*============================================================================*/ int remove( const char *path ) { #if _FS_READONLY errno = EACCES; return EOF; #else // _FS_READONLY FRESULT Result; Result = f_unlink( path ); if( Result != FR_OK ) { errno = TranslateErrNo( Result ); return EOF; } errno = 0; return 0; #endif // _FS_READONLY } /*============================================================================*/ int rename( const char *old, const char *new ) { #if _FS_READONLY errno = EACCES; return EOF; #else // _FS_READONLY FRESULT Result; Result = f_rename( old, new ); if( Result != FR_OK ) { errno = TranslateErrNo( Result ); return EOF; } errno = 0; return 0; #endif // _FS_READONLY } /*============================================================================*/ int eof( int fildes ) { if( !HandleIsValid( fildes ) || !Files[fildes].Valid ) { errno = EBADF; return EOF; } errno = 0; return ( Files[fildes].File.fptr >= Files[fildes].File.fsize) ? 1 : 0; } /*============================================================================*/ #if 0 // Doesn't work yet because the way FatFS implements truncate is too different from the standard int truncate( const char *path, off_t length ) { FRESULT Result; DWORD CurrentPosition; if( !HandleIsValid( fildes ) || !Files[fildes].Valid ) { errno = EBADF; return EOF; } } #endif /*============================================================================*/ #if 0 // Needs some more work int fileno( FILE *stream ) { if(( (unsigned)stream & 0xfffffff0 ) != 0x015aac00 || ( (unsigned)stream & 0x000000ff ) >= sizeof Files / sizeof Files[0] ) { errno = EBADF; return EOF; } errno = 0; return (unsigned)stream & 0x000000ff; } /*============================================================================*/ FILE *fdopen( int fildes, const char *mode ) { if( !HandleIsValid( fildes )) { errno = EBADF; return NULL; } errno = 0; return (FILE*)( fildes | 0x015aac00 ); } #endif /*============================================================================*/
file: /Techref/member/IMB-yahoo-J86/FileIO.c.htm, 11KB, , updated: 2013/10/31 10:29, local time: 2024/12/27 04:10,
owner: IMB-yahoo-J86,
3.141.12.236:LOG IN
|
©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://linistepper.com/techref/member/IMB-yahoo-J86/FileIO.c.htm"> member IMB-yahoo-J86 FileIO</A> |
Did you find what you needed? |