?? 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 + -