⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pmp_file_list.c

📁 嵌入式系统下的文件管理处理,和基本图片jpg格式处理原代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*-------------------------------------------------*
* $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 + -