📄 fileio.c
字号:
/*
DM270 ARM Evaluation Software
(c)Texas Instruments 2003
*/
#include <ata.h>
#include <system/armsys270.h>
#include <fileio/ata_init.h>
#include <fileio/fileio.h>
#include <util/file_name_gen.h>
#define FTBL_MAX_FILES 4
#define BLK_SIZE (63*1024)
void charToUnicode(char *src, AtaChar *dst);
#pragma DATA_SECTION( ftbl, "ata_buf" )
FTBL_Entry ftbl[FTBL_MAX_FILES];
FILE_ID FILE_open(char *fname, char *options, Uint16 mode) {
FTBL_Entry *fp;
char name[MAX_FILE_NAME_LEN];
char drvName[10];
AtaChar unicodeName[MAX_FILE_NAME_LEN];
int i, ix;
int len;
int first;
char ch;
len=strlen(fname);
ix=0;
first=1;
name[ix]=0;
drvName[0]=0;
fp = FTBL_findEntry();
if(fp==NULL)
return NULL;
// parse, path and goto file directory
i=0;
while(i<len) {
ch=fname[i];
switch(ch) {
case '/':
case '\\':
name[ix]=0;
if(ix==0)
break;
if(first) {
first=0;
strcpy( drvName, name );
// name contains drive name, get drive info and switch to root dir
if( FILE_gotoRootDir(&(fp->file), name) != E_PASS )
return NULL;
if(mode&FILEIO_MFW_MODE) {
ATA_enableMFW(FILE_getDrive(drvName));
} else {
ATA_disableMFW(FILE_getDrive(drvName));
}
} else {
int stat;
stat = FILE_searchDir( &(fp->file), name );
if(stat==E_PASS) {
if( ATA_isDir(&(fp->file)) ) {
if( ATA_cd(&(fp->file) ) != ATA_ERROR_NONE )
return NULL;
}
} else {
return NULL;
}
}
ix=0;
break;
default:
name[ix]=ch;
ix++;
break;
}
i++;
}
// name contains file name
name[ix]=0;
if(first==0) {
int stat, found=0;
stat = FILE_searchDir(&(fp->file), name);
if(stat==E_PASS)
found=1;
else
found=0;
// if read, open file
if(options[0]=='r') {
if(found) {
FTBL_lockEntry(fp);
fp->readOnly=1;
return (void*)fp;
}
}
// if append mode, open file
if(options[0]=='a') {
if(found) {
FTBL_lockEntry(fp);
fp->readOnly=0;
return (void*)fp;
}
}
// if write, create file
if(options[0]=='w') {
if(found) {
// file is already present, delete it first and then create new file
if( ATA_deleteLong(&(fp->file)) != ATA_ERROR_NONE )
return NULL;
}
charToUnicode(name, unicodeName);
if( ATA_setLongFileName( &(fp->file), unicodeName) != ATA_ERROR_NONE )
return NULL;
if( ATA_createLong(&(fp->file), unicodeName ) != ATA_ERROR_NONE )
return NULL;
if( ATA_close(&(fp->file)) != ATA_ERROR_NONE )
return NULL;
if( FILE_searchDir(&(fp->file), name) != E_PASS )
return NULL;
FTBL_lockEntry(fp);
fp->readOnly=0;
return (void*)fp;
}
}
return NULL;
}
int FILE_close(FILE_ID fp, Uint16 mode) {
FTBL_Entry *ftblEntry;
if(fp==NULL)
return E_DEVICE;
ftblEntry = (FTBL_Entry *)fp;
if(ftblEntry->readOnly==0) {
ATA_close(&(ftblEntry->file) );
if(mode & FILEIO_NO_FAT_CACHE_FLUSH ) {
} else {
FILE_driveFlush(&(ftblEntry->file));
}
}
FTBL_releaseEntry(ftblEntry);
return 0;
}
int FILE_sizeGet(FILE_ID fp, int *size) {
FTBL_Entry *ftblEntry;
if(fp==NULL)
return 0;
ftblEntry = (FTBL_Entry *)fp;
*size = ftblEntry->file.Size;
return 0;
}
int FILE_write(FILE_ID fp, char *addr, int size) {
FTBL_Entry *ftblEntry;
Uint16 blksize;
Uint32 cursize;
if(fp==NULL)
return 0;
ftblEntry = (FTBL_Entry *)fp;
size=(size+1)/2;
cursize=0;
while(cursize < size) {
if(size - cursize < BLK_SIZE )
blksize = size - cursize;
else
blksize = BLK_SIZE;
if( ATA_write( &(ftblEntry->file), (AtaUint16*)addr, blksize ) != ATA_ERROR_NONE )
return ((cursize+1)/2)*2;
cursize+=blksize;
addr+=blksize*2;
}
return ((cursize+1)/2)*2;
}
int FILE_read(FILE_ID fp, char *addr, int size) {
AtaError status;
Uint16 blksize;
Uint32 cursize;
FTBL_Entry *ftblEntry;
if(fp==NULL)
return 0;
ftblEntry = (FTBL_Entry *)fp;
size=(size+1)/2;
cursize=0;
while(cursize < size) {
if(size - cursize < BLK_SIZE )
blksize = size - cursize;
else
blksize = BLK_SIZE;
if( ( status = ATA_readLittleEndian( &(ftblEntry->file), (AtaUint16*)addr, blksize ) )!= ATA_ERROR_NONE ) {
if(status==ATA_ERROR_EOF)
ftblEntry->eof=1;
return ((cursize+1)/2)*2;
}
cursize+=blksize;
addr+=blksize*2;
}
return ((cursize+1)/2)*2;
}
int FILE_seek(FILE_ID fp, int offset, int pos) {
FTBL_Entry *ftblEntry;
if(fp==NULL)
return 0;
ftblEntry = (FTBL_Entry *)fp;
if( ATA_seek( &(ftblEntry->file), (offset+1)/2 ) != ATA_ERROR_NONE )
return -1;
return 0;
}
int FILE_eof(FILE_ID fp) {
FTBL_Entry *ftblEntry;
if(fp==NULL)
return 0;
ftblEntry = (FTBL_Entry *)fp;
if(ftblEntry->eof)
return 1;
else
return 0;
}
int FILE_driveFlush(AtaFile *file) {
return MEDIA_FAT_cacheFlush(file->pDrive->pAtaMediaState);
}
void charToUnicode(char *src, AtaChar *dst) {
int i;
for(i = 0; i < strlen(src)+1; i++) {
dst[i] = 0;
dst[i] = (AtaChar)src[i];
}
}
void unicodeToChar(AtaChar *src, char *dst) {
int i;
for(i = 0; i < _AtaStrlen(src)+1; i++) {
dst[i] = 0;
dst[i] = (char)src[i];
}
}
int FTBL_init() {
int i;
for(i=0; i<FTBL_MAX_FILES; i++ ) {
ftbl[i].freeEntry=1;
}
return 0;
}
FTBL_Entry *FTBL_findEntry() {
int i;
for(i=0; i<FTBL_MAX_FILES; i++ ) {
if(ftbl[i].freeEntry) {
ftbl[i].eof = 0;
return &ftbl[i];
}
}
return NULL;
}
int FTBL_lockEntry(FTBL_Entry *fp) {
fp->freeEntry=0;
return 0;
}
int FTBL_releaseEntry(FTBL_Entry *fp) {
fp->freeEntry=1;
fp->eof=0;
return 0;
}
int _AtaStrcmp( AtaChar *src, AtaChar *dst) {
while( *src != 0 && *dst!=0 && *src == *dst ) {
src++;
dst++;
}
return (int)*src - (int)*dst;
}
STATUS FILE_searchDir( AtaFile *dir, char *name) {
int found=0, done=0;
AtaChar unicodeName[MAX_FILE_NAME_LEN], longname[MAX_FILE_NAME_LEN];
charToUnicode( name, unicodeName);
if( ATA_findFirst( dir ) != ATA_ERROR_NONE )
return E_DEVICE;
while( !done ) {
ATA_getLongName( dir, longname, 0, MAX_FILE_NAME_LEN-1 );
if(_AtaStrcmp(longname, unicodeName)==0) {
found=1;
done =1;
}
if(!found) {
if(ATA_findNext( dir )!=ATA_ERROR_NONE)
done=1;
}
}
if(found) {
return E_PASS;
} else {
return E_DEVICE;
}
}
STATUS FILE_gotoRootDir( AtaFile *root, char *driveName) {
AtaState *drive;
// name contains drive name, get drive info and switch to root dir
drive = FILE_getDrive(driveName);
if(drive==NULL)
return E_DEVICE;
if( ATA_fileInit(drive, root ) != ATA_ERROR_NONE )
return E_DEVICE;
if( ATA_cdRoot( root ) != ATA_ERROR_NONE )
return E_DEVICE;
return E_PASS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -