📄 pmp_file_list.c
字号:
/*-------------------------------------------------*
* $RCSfile: pmp_file_list.c,v $
* $Date: 2007/01/17 12:28:43 $
* $Author: lanzhu $
* $Log: pmp_file_list.c,v $
* Revision 1.1.1.1 2007/01/17 12:28:43 lanzhu
* 齐兰柱 准备一个新的代码分支
*
* Revision 1.5 2007/01/04 01:32:16 lanzhu
* 修改设定文件属性不正确的BUG
*
* Revision 1.4 2007/01/02 00:49:30 lanzhu
* 在退出时,增加对fsDirSet的容错判断
*
* Revision 1.3 2006/12/18 02:14:27 taiyun
* Modify include filename
*
* Revision 1.2 2006/12/12 00:29:54 lanzhu
* 去除WARNING
*
* Revision 1.1.1.1 2006/12/05 03:01:16 lanzhu
* no message
*
* Revision 1.1.1.1 2006/12/01 09:49:35 lanzhu
* no message
*
* Revision 1.3 2006/11/06 00:01:45 lanzhu
* 修改 dongyu 反映的bug, 不能找出 xxxx..MP3 的问题
*
* Revision 1.2 2006/09/16 01:39:08 lanzhu
* 完成 file list 几个功能函数的编写、调试。
*
* Revision 1.1 2006/09/05 01:12:58 lanzhu
* just test ds dfdfgg fg
*
*
*--------------------------------------------------*/
#define FLIST_DEBUG_1231
//#define DEBUG_FILE_LIST
#include "SPMP_define.h"
#include <ctype.h>
#include <string.h>
#include "os_api.h"
#include "fs_api.h"
#include "SysUtility.h"
#include "file_list.h"
/**************************************************************************
* G E N E R A L C O N S T A N T S *
**************************************************************************/
#ifndef APP_DRV_OK
#define APP_DRV_OK (0)
#endif
#ifndef APP_DRV_ERR
#define APP_DRV_ERR (-1)
#endif
// 目标路径名字符串的最大长度
#define TARGET_PATH_MAX (255)
// 进行目录搜索时目录名(文件名)
#define DIR_COUNT_MAX (512)
// 进行目录搜索时目录名字符串所占用的总空间的最大值
#define DIR_CONTENT_MAX (1024L*16)
#define DUMMY_OFFSET (0xffff)
/* 以下6个定义 为 FAT中文件的属性 */
#define FAT_READ_ONLY (1<<0)
#define FAT_HIDDEN (1<<1)
#define FAT_SYSTEM (1<<2)
#define FAT_VOLUME (1<<3)
#define FAT_DIRECTORY (1<<4)
#define FAT_ARCHIVE (1<<5)
/**************************************************************************
* M A C R O S *
**************************************************************************/
/**************************************************************************
* D A T A T Y P E S *
**************************************************************************/
/**************************************************************************
* G L O B A L D A T A *
**************************************************************************/
// 是否需要滤除 空文件的标志
#define BIT_EMPTY_FILE_MASK (1<<0)
static UINT16 gEmptyFileFlag = 0x00;
// bit0 --------- 0 不需要特殊处理 空文件
// 1 需要将空文件滤除
// 存放目标字符串的指针
static UINT8 * gpTargetDir = NULL;
// 存放滤波器设定的属性
static UINT16 gFilterAttr = 0xffff;
// 当前工作目录的备份
static UINT8 *gpCWDBack = NULL;
// 存放文件扩展名的数组
static UINT8 gFilterStr[8][8];
// 存放字符串偏移的指针
static UINT16 *gpStrOffet = NULL;
// 存放字符串内容佛如指针
static UINT8 *gpStrContent = NULL;
// 文件名的总数
static UINT32 gFileTotal = 0x00;
/**************************************************************************
* E X T E R N A L R E F E R E N C E S *
**************************************************************************/
/**************************************************************************
* F U N C T I O N D E C L A R A T I O N S *
**************************************************************************/
static UINT8 * get_target_dir( void ); // 返回目标路径名的指针
static UINT16 search_dir_prepare( void ); // 进行目录寻找前的准备工作
static UINT16 judge_file_name( File_Info_t *pFinfo ); // 判断得到的文件信息是否符合设定的要求
static UINT16 judge_ext_name( UINT8 * pExtName ); // 判断输入的字符串是否在设定的字符串中
static UINT16 caculate_addr(UINT16 index, // [in] 索引值
UINT32 *pNameAddr, // [out] 文件名的地址
UINT32 *pInfoAddr); // [out] 信息的地址
static UINT16 logical_2_physical( UINT16 index ); // 输入一个逻辑索引值,返回物理索引值
static UINT16 clear_one_file( UINT16 index ); // 清除掉一个文件
static UINT16 copy_file_info(UINT8 * pbuf, File_Info_t *pInfo ); // 复制文件的信息
#ifdef DEBUG_FILE_LIST
/*
test program for file list
【9/15/2006】 test OK!!!
*/
void test_file_list( void )
{
UINT16 i,err;
UINT16 count;
UINT8 *pCWD;
struct F_Information * pInfo;
sio_printf("Test Begin!\r\n");
// set target dir
SPMP_SetTargetDir("D:\\VIDEOPLAY");
// set Filter
SPMP_SetFileNameExtFilter(SPMP_FILTER_PASS, "*.JPG");
// search file
SPMP_SearchFName(&count);
// SPMP_DelOneFile( 0x00 );
SPMP_GetOneFileInfo(0x00, &pInfo);
SPMP_SetOneFileAttr(0x00, SPMP_FATTR_ACCESS );
SPMP_FileListExit();
fsDirGet(&pCWD); // 获得当前的工作目录
DEBUG_OUTPUT(("%s\r\n", pCWD));
while (1);
}
#endif
/************************************************************************/
/* 设定需要进行检索的目录路径路径名
input:
pparth [in] 存放路径名字符串的地址值指针
output:
0 成功, 非0值失败
func:
设定所要寻找的目录
note:
字符串的最大长度为 255 字节
在使用该模块前,必须调用此函数。(只需调用一次)
example:
UINT16 err;
err = SPMP_SetTargetDir("D:\\my music\\蔡琴经典");
if( err ){
WARNING_OUTPUT(("SetTargetDir Err!\r\n"));
ERROR_STOP;
}
*/
/************************************************************************/
UINT16 SPMP_SetTargetDir( UINT8 * pParth )
{
UINT16 len;
UINT8 *pbuf;
// 判断全局指针是否有效
if (NULL != gpTargetDir ) {
MEM_FREE( gpTargetDir );
gpTargetDir = NULL;
}
// 判断输入参数是否合法
if ( NULL == pParth ) {
ERROR_REPORT;
return APP_DRV_ERR;
}
// 获得输入字符串的长度,判断长度值是否合法
len = strlen( pParth );
if (!len || (len > TARGET_PATH_MAX) ){
ERROR_REPORT;
return APP_DRV_ERR;
}
// 进行内存的申请动作
pbuf = MEM_ALLOC( (UINT32)len+1 );
if (NULL == pbuf) {
ERROR_REPORT;
return APP_DRV_ERR;
}
// 进行字符串的复制动作
strcpy(pbuf, pParth);
// 将指针保存到全局变量中,返回成功
gpTargetDir = pbuf;
return APP_DRV_OK; // 返回成功
}
/************************************************************************/
/* 设定滤波器的属性和 后缀名字符串
input:
FilterAttr [in] 滤波的属性
SPMP_NO_FILTER // 滤波器无效
SPMP_FILTER_PASS // 带通属性
SPMP_FILTER_STOP // 带阻属性
pExtStr [in] 文件后缀名字符串指针
FilterAttr == SPMP_NO_FILTER 此字符串不起作用
示例:
"*.DOC"
"*.DOC|*.BIN"
output:
0 成功, 非0值失败
func:
设定滤波器的属性,设定后缀名字符串
note:
最多支持 8 种后缀名的组合
每个后缀名的最大长度为 7 个字符
后缀名是不区分大小写的, 当输入"*.DOC", 对 "A.DOC" "b.doc" 同时起作用
example:
UINT16 err;
err = SPMP_SetFileNameExtFilter((UINT16)SPMP_FILTER_PASS, "*.BIN|*.C");
if( err ){
WARNING_OUTPUT(("SetFileNameExtFilter!\r\n"));
ERROR_STOP;
}
*/
/************************************************************************/
UINT16 SPMP_SetFileNameExtFilter(UINT16 FilterAttr, UINT8 * pExtStr)
{
UINT16 i,j,k;
// UINT8 *pstart;
// UINT8 *pfound;
UINT8 *pdata;
UINT8 tmp;
// DEBUG_OUTPUT(("%s\r\n", pExtStr));
// 保存滤波器的属性
if ( FilterAttr <= SPMP_FILTER_STOP ) {
gFilterAttr = FilterAttr;
}
// 进行数组的清空动作
memset(gFilterStr, '\0', sizeof(gFilterStr));
// 判断输入的参数是否合法
if ( NULL == pExtStr ) {
ERROR_REPORT;
return APP_DRV_ERR;
}
// 对整个字符串进行扫描
for(k=0x00, i=0x00; ; k++)
{
// 获得目的指针的地址
pdata = &(gFilterStr[k][0]);
for(j=0x00; ; j++)
{
// 取出一个字符
tmp = pExtStr[i++];
// 判断是否为 间隔符 或者 结束符
if ((tmp == '|') || (tmp == '\0') ) {
break;
}
else{
pdata[j] = toupper(tmp);
}
}
if (tmp == '\0') {
break; // return
}
}
// 返回成功
return APP_DRV_OK;
}
/************************************************************************/
/* 在指定的目录下进行文件名的寻找,返回符合要求的文件名的总数
input:
pCount [out] 返回该目录下符合条件的文件名的总数
output:
0 成功,非0值失败
func:
在指定的目录下进行文件名的寻找,返回符合要求的文件名的总数
note:
最多支持找出1024个文件
[注意] 失败时,数量要清零
example:
UINT16 err;
UINT16 FileCount;
err = SPMP_SearchFName(&FileCount);
if( err ){
WARNING_OUTPUT(("SearchFName!\r\n"));
ERROR_STOP;
}
DEBUG_OUTPUT(("FileCount = 0x%x\r\n", FileCount));
typedef struct File_Info_s
{
Time_Attr_t tCreate;
Time_Attr_t tModify;
Time_Attr_t tAccess;
UINT32 attr;
UINT32 fileSize;
UINT32 longLen;
UINT32 s8_3Len;
UINT8 sLongFileName[LONG_FILENAME_LEN];
UINT8 s8_3_FileName[SHORT_FILENAME_LEN];
}File_Info_t;
*/
/************************************************************************/
UINT16 SPMP_SearchFName(UINT16 *pCount )
{
UINT8 *ptemp, *pInfo;
UINT16 err,i,offset,count;
File_Info_t FileInfoAttr;
if (NULL == pCount) { // 判断输入参数是否合法
ERROR_REPORT;
return APP_DRV_ERR;
}
*pCount = 0x00; // reset file count
err = search_dir_prepare(); // prepare for search dir
if (err) {
ERROR_REPORT;
return APP_DRV_ERR;
}
// 为保存偏移量准备内存
if (NULL != gpStrOffet) {
MEM_FREE( gpStrOffet );
gpStrOffet = NULL;
}
// 申请定长的内存(最多可以存放 DIR_COUNT_MAX 个目录名)
gpStrOffet = (UINT16 *) MEM_ALLOC( DIR_COUNT_MAX * sizeof(UINT16));
if (NULL == gpStrOffet) {
ERROR_REPORT;
return APP_DRV_ERR;
}
// 将全部的偏移空间,清空为 0xFFFF
memset(gpStrOffet, 0xff, DIR_COUNT_MAX*sizeof(UINT16));
// 为保存目录名内容准备内存
if (NULL != gpStrContent) {
MEM_FREE( gpStrContent );
gpStrContent = NULL;
}
gpStrContent = (UINT8 *) MEM_ALLOC( DIR_CONTENT_MAX );
if (NULL == gpStrContent) {
ERROR_REPORT;
return APP_DRV_ERR;
}
// 将全部的内容空间, 清空为0x0000
memset(gpStrContent, 0x00, DIR_CONTENT_MAX);
// 将文件信息保存到内容空间的后半段
pInfo = gpStrContent + DIR_CONTENT_MAX/2;
err = fsFirstFileFind( ); // 进行第一次的搜索
if (err) {
ERROR_REPORT;
return APP_DRV_ERR; // 返回失败
}
count = 0x00;
// 进行目录的循环读取过程
for(offset=0x00, i=0x00; ; )
{
err = fsNextFileFind(&FileInfoAttr); // 获取文件信息
if ( !err )
{
ptemp = FileInfoAttr.s8_3_FileName; // 默认采用短文件名字符串
if ( FileInfoAttr.longLen ) { // 如果长文件名存在的话,使用长文件名
ptemp = (UINT8 *)FileInfoAttr.sLongFileName;
}
// DEBUG_OUTPUT(("+++ %s\r\n", ptemp));
// 判断该文件是否合法,检查不通过,继续寻找文件
if ( judge_file_name(&FileInfoAttr) ){
continue;
}
strcpy(gpStrContent+offset, ptemp); // 进行文件名的复制
gpStrOffet[i++] = offset; // 保存字符串的偏移地址
offset += strlen(ptemp)+1; // 进行偏移量的更新
// DEBUG_OUTPUT(("Save pInfo = %x\r\n", pInfo));
copy_file_info(pInfo, &FileInfoAttr); // 将文件信息复制到内存中
pInfo += sizeof(struct F_Information) ; // 移动信息指针
count ++; // 总数加一
}
else{
break; // 失败 或者 读目录结束 退出
}
}
*pCount = count; // 返回文件名
gFileTotal = count; // 保存文件名到私有变量中
// 返回成功
return APP_DRV_OK;
}
/************************************************************************/
/* 输入一个索引值,返回文件名字符串
input:
index [in] 索引值 (0x00 -- (总数减一) )
pbuf [out] 存放得到的文件名字符串的指针
pAttr [out] 存放得到的文件属性的指针
output:
0 成功,
非0值失败
func:
输入一个索引值,得到一个文件名字符串
note:
文件名字符串的最大长度 255 字节
example:
UINT16 i,err;
UINT16 FileAttr;
UINT8 FileName[0x100];
for(i=0x00; i<FileCount; i++)
{
err = SPMP_GetOneFileName(i, Filename, &FileAttr);
if( err ){
WARNING_OUTPUT(("SearchFName!\r\n"));
ERROR_STOP;
}
DEBUG_OUTPUT(("%s\r\n", Filename));
// 进行得到文件名后的处理,将文件名添加到列表中去
}
*/
/************************************************************************/
UINT16 SPMP_GetOneFileName(UINT16 index, UINT8 **pbuf, UINT16 *pAttr)
{
UINT32 NameAddr;
UINT32 InfoAddr;
struct F_Information * pInfo;
// 判断输入的参数是否合法, 输入的索引值超过文件的总数
if ((NULL == pbuf) || (NULL == pAttr) || (index >= gFileTotal) ) {
ERROR_REPORT;
return APP_DRV_ERR;
}
// 根据输入的索引值,计算文件名字符串的地址 和信息存放的地址
caculate_addr(index, &NameAddr, &InfoAddr);
// 获得文件名的地址指针
*pbuf = (UINT8 *)NameAddr;
pInfo = (struct F_Information * )InfoAddr;
// 返回本模块所定义的属性值
*pAttr = SPMP_FATTR_RDONLY;
if (!(pInfo->attr & FAT_READ_ONLY) )
{
*pAttr = SPMP_FATTR_ACCESS;
}
// 返回成功
return APP_DRV_OK;
}
/************************************************************************/
/* 输入一个索引值,删除该文件
input:
index [in] 索引值 (0x00 -- (总数减一) )
output:
0 成功,
非0值失败
func:
输入一个索引值,删除该文件
note:
[注意] 输入的索引值,不能 >= 文件的总数
[注意] 删除一个文件后,索引值是自动向前对齐的。
example:
UINT16 index,err;
index = ListBox 中获得光标行的位置;
// 删除该文件
err = SPMP_DelOneFile(index);
if( err ){
WARNING_OUTPUT(("SearchFName!\r\n"));
ERROR_STOP;
}
*/
/************************************************************************/
UINT16 SPMP_DelOneFile( UINT16 index )
{
UINT16 err;
UINT32 NameAddr;
// 判断输入参数是否合法
if ( index >= gFileTotal ) {
ERROR_REPORT;
return APP_DRV_ERR;
}
// 根据索引值,计算索引对应的文件名的地址
caculate_addr(index, &NameAddr, NULL);
// 删除文件
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -