📄 filesys.c
字号:
}
/* test if a directory is empty */
sint_t fs_isDirEmpty(const char *pathname, char **fnout)
{
sint_t l;
s32_t rc;
l = fsys_buildPathName(fsearch_g.mask, pathname, "*");
if (l < 0)
return -1;
if ((fsearch_g.mask[0] == 0) || (fsearch_g.mask[0] == '*'))
return -1;
fsearch_g.image = -1;
rc = fs_findnext(&fsearch_g, &finfo_g);
if (rc >= 0)
return 0; /* directory not empty */
if (fnout != NULL)
{
fsearch_g.mask[l-2] = 0;
*fnout = fsearch_g.mask;
}
return 1;
}
#endif /* FS_SUBDIRECTORIES */
/*-------------------------------------------------------------------------*/
static sint_t fs_seek(const sint_t file, const sint_t position,
const sint_t origin)
{
FSROOTBLOCK_t *rb;
FSFILE_t *f;
u32_t i, b, pb, lb, r, p, n;
s32_t t;
f = &fsFileList_g[file];
if (!(f->flags & FSFILE_F_USED))
return -1;
rb = FSROOTBLOCK(f->image);
switch (origin)
{
case FSSEEK_SET:
{
t = 0;
break;
}
case FSSEEK_CUR:
{
t = (s32_t) f->curPosition;
break;
}
case FSSEEK_END:
{
t = (s32_t) f->dblockptr->filesize;
break;
}
default:
{
return -1;
}
}
t += (s32_t) position;
if (t < 0)
return -1;
p = (u32_t) t;
i = (p + (FS_DATABYTESPERBLOCK(rb) - 1)) / FS_DATABYTESPERBLOCK(rb);
if (p > f->dblockptr->filesize)
{
if (f->mode & FSO_RDONLY)
return -1;
/* increase the file size */
lb = fs_lastBlock(rb, f->dirblock, &n);
i -= n;
b = lb;
pb = 0;
r = 0;
while (i > 0)
{
b = fs_allocBlock(rb);
if (b == 0)
{
fs_freeBlockChain(rb, r);
return -1;
}
if (r == 0)
{
r = b;
pb = b;
}
else
{
fs_getBlock(rb, pb)->nextBlock = b;
pb = b;
}
i--;
}
if (lb == 0)
{
f->dblockptr->firstFileBlock = r;
}
else
{
fs_getBlock(rb, lb)->nextBlock = r;
}
f->dblockptr->filesize = p;
}
else
{
b = 0;
if (p != 0)
{
b = f->dblockptr->firstFileBlock;
while ((b != 0) && (i > 1))
{
b = fs_getBlock(rb, b)->nextBlock;
i--;
}
if (i > 1)
return -1; /* error, should never happen */
}
}
f->curDataPtr = p % FS_DATABYTESPERBLOCK(rb);
f->curBlock = b;
f->curPosition = p;
return (sint_t) p;
}
static u32_t fs_lastBlock(FSROOTBLOCK_t *rb, u32_t dirblock, u32_t *blocks)
{
FSBLOCK_t *bl;
u32_t b, l, n;
n = 0;
l = 0;
b = fs_getDirBlock(rb, dirblock)->firstFileBlock;
while (b != 0)
{
l = b;
bl = fs_getBlock(rb, b);
b = bl->nextBlock;
n++;
}
if (blocks != NULL)
*blocks = n;
return l;
}
static sint_t fs_isFileOpened(const char* filename, sint_t forWriting)
{
sint_t i;
for (i=0; i<FS_MAXFILES; i++)
{
if (fsFileList_g[i].flags & FSFILE_F_USED)
{
if (!(fsFileList_g[i].dblockptr->flags & FSDIR_F_IGNORE) &&
(sysStrncmp(fsFileList_g[i].dblockptr->filename, filename,
FSROOTBLOCK(fsFileList_g[i].image)->maxFilenameLength) == 0))
{
if ((forWriting == 0) || !(fsFileList_g[i].mode & FSO_RDONLY))
return 1;
}
}
}
return 0;
}
static void fs_incRefCount(sint_t img, u32_t dirblock)
{
sint_t i, f = -1;
for (i=0; i<FS_MAXFILES; i++)
{
if (fsRefList_g[i].refcount != 0)
{
if ((fsRefList_g[i].image == img) &&
(fsRefList_g[i].dirblock == dirblock))
{
fsRefList_g[i].refcount++;
return;
}
}
else
{
if (f < 0)
f = i;
}
}
fsRefList_g[f].image = img;
fsRefList_g[f].dirblock = dirblock;
fsRefList_g[f].refcount = 1;
}
static void fs_decRefCount(sint_t img, u32_t dirblock)
{
FSROOTBLOCK_t *rb;
FSDIRBLOCK_t *dbl;
sint_t i;
rb = FSROOTBLOCK(img);
for (i=0; i<FS_MAXFILES; i++)
{
if ((fsRefList_g[i].refcount != 0) &&
(fsRefList_g[i].image == img) &&
(fsRefList_g[i].dirblock == dirblock))
{
if (--fsRefList_g[i].refcount == 0)
{
dbl = fs_getDirBlock(rb, dirblock);
if (dbl->flags & FSDIR_F_DELONCLOSE)
{
/* remove directory entry */
fs_removeDirEntry(rb, dirblock);
}
}
break;
}
}
}
static FSBLOCK_t* fs_getBlock(FSROOTBLOCK_t *rb, u32_t blocknbr)
{
FSBLOCK_t *bl;
bl = (FSBLOCK_t*) (void*)
(((u32_t*)rb) + ((rb->bytesPerBlock * blocknbr) / sizeof(u32_t)));
return bl;
}
static FSDIRBLOCK_t* fs_getDirBlock(FSROOTBLOCK_t *rb, u32_t blocknbr)
{
FSDIRBLOCK_t *db;
u32_t bofs;
bofs = rb->bytesPerBlock * (blocknbr / rb->dirBlocksPerBlock);
db = (FSDIRBLOCK_t*)(void*)
(((u32_t*)rb) + ((bofs + (rb->bytesPerDirBlock *
(blocknbr % rb->dirBlocksPerBlock))) / sizeof(u32_t)));
return db;
}
/*-------------------------------------------------------------------------*/
static sint_t fs_containWildcard(const char* filename)
{
char *c = (char*) filename;
if (filename != NULL)
{
while (*c != 0)
{
if ((*c == '?') || (*c == '*'))
return 1;
c++;
}
}
return 0;
}
static char* fs_validateFileName(const char* filename)
{
char *s = (char*) filename;
char *d = fnbuffer_g;
#if FS_SUBDIRECTORIES
sint_t img;
u32_t b;
sint_t j;
#else
sint_t i, j;
#endif
if (s == d)
return d;
*d = 0;
if (s == NULL)
return d;
while ((*s != 0) && ((*s <= ' ') || (*s == '/') || (*s =='\\'))) s++;
#if !FS_SUBDIRECTORIES
for (i=0, j=0; (s[i] != 0) && (j < (FS_MAXFNAMELEN-1)); i++)
{
if ((s[i] == '\\') || (s[i] == '/'))
{
if ((j == 0) || (d[j-1] != '/'))
{
d[j++] = '/';
}
}
else
{
d[j++] = s[i];
}
}
while ((j > 0) && (d[j-1] <= ' ')) j--;
if ((j > 0) && (d[j-1] == '/')) j = 0;
d[j] = 0;
#else /* !FS_SUBDIRECTORIES */
j = sysStrlen(s);
while ((j > 0) && (s[j-1] != '/')) j--;
sysStrcpy(d, s);
if (j > 0)
{
d[j-1] = 0;
j = fsys_buildPathName(d, d, &d[j]);
if (j < 0)
return d;
}
/* validate the directory path */
while ((j > 0) && (d[--j] != '/'));
if (j > 0)
{
d[j] = 0;
b = fs_findFile(&img, d);
if (b == 0)
{
*d = 0;
}
else
{
if ((fs_getDirBlock(FSROOTBLOCK(img), b)->flags & FSDIR_F_SUBDIR) == 0)
{
*d = 0;
}
else
{
d[j] = '/';
}
}
}
#endif
return d;
}
#if FS_SUBDIRECTORIES
sint_t fsys_buildPathName(char *outbuf, const char *pathname,
const char *filename)
{
sint_t s = 0, d = 0;
const char *p, *f;
char b, c;
p = pathname;
f = filename;
if ((*f == '/') || (*f == '\\'))
{
p = filename;
f = NULL;
}
while ((p[s] == '/') || (p[s] == '\\') ||
(p[s] == ' ')) s++;
while ((c = p[s++]) != 0)
{
if ((c == '?') || (c == '*') || (d >= (FS_MAXFNAMELEN-4)))
{
*outbuf = 0;
return -1;
}
if (c == '\\')
c = '/';
if ((c == '/') && (s > 1) &&
((p[s-2] == '/') || (p[s-2] == '\\')))
{
continue;
}
if ((d == 0) || (outbuf[d-1] == '/'))
{
if (c == '.')
{
b = p[s];
if ((b == '/') || (b == '\\') || (b == 0))
{
s += 1;
continue;
}
if ((b == '.') &&
((p[s+1] == '\\') || (p[s+1] == '/') ||
(p[s+1] == 0)))
{
if ((d > 0) && (outbuf[d-1] == '/')) d--;
while ((d > 0) && (outbuf[d-1] != '/')) d--;
if (p[s+1] == 0)
break;
s += 2;
continue;
}
}
}
if ((d != 0) || (c != '/'))
{
outbuf[d++] = c;
}
}
if ((d > 0) && (outbuf[d-1] != '/'))
outbuf[d++] = '/';
if (f == NULL)
{
d--;
}
else
{
s = 0;
while ((f[s] == '/') || (f[s] == '\\') ||
(f[s] == ' ')) s++;
if ((f[s] == '.') &&
((f[s+1] == 0) ||
((f[s+1] == '.') && (f[s+2] == '0'))))
{
*outbuf = 0;
return -1;
}
while (f[s] != 0)
{
outbuf[d++] = f[s++];
}
}
outbuf[d] = 0;
return d;
}
#endif /* FS_SUBDIRECTORIES */
static void fs_getCurrentTime(struct fsys_time *fstime)
{
#ifdef HAVE_LOCALTIME
time_t ltime;
struct tm *today;
time(<ime);
today = localtime(<ime);
if (today == NULL)
return;
fstime->year = (u16_t) today->tm_year + 1900;
fstime->month = (u8_t) today->tm_mon + 1;
fstime->day = (u8_t) today->tm_mday;
fstime->hour = (u8_t) today->tm_hour;
fstime->min = (u8_t) today->tm_min;
fstime->sec = (u8_t) today->tm_sec;
#else
fstime->year = 2000;
fstime->month = 1;
fstime->day = 1;
fstime->hour = 0;
fstime->min = 0;
fstime->sec = 0;
#endif
}
/*-------------------------------------------------------------------------*/
static u32_t fs_findFile(sint_t *img, const char *filename)
{
FSROOTBLOCK_t *rb;
FSDIRBLOCK_t *dbl;
u32_t b, pb;
sint_t i;
if (*filename == 0)
return 0;
for (i=0; i<FS_MAXIMAGES; i++)
{
rb = FSROOTBLOCK(i);
if (rb == NULL)
continue;
pb = 0;
b = rb->firstDirBlock;
while (b != 0)
{
dbl = fs_getDirBlock(rb, b);
if (!(dbl->flags & FSDIR_F_IGNORE) &&
(sysStricmp(dbl->filename, filename) == 0))
{
if (img != NULL)
*img = i;
return b;
}
pb = b;
b = dbl->nextBlock;
}
}
return 0;
}
static sint_t fs_open(const char *filename, const sint_t mode)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -