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

📄 pmp_fs_api_za.c

📁 嵌入式系统下的文件管理处理,和基本图片jpg格式处理原代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	
	// 申请内存
	len = strlen(pCWD);
	pbuf = (UINT8 *)MEM_ALLOC( len+4 );
	if(NULL == pbuf){
		ERROR_REPORT;
		return;
	}
	// reset memory
	memset(pbuf, '\0', len+4);
	// copy cwd to pbuf
	strcpy(pbuf, pCWD);	

	// 如果是根目录,添加"\\"
	if ( pbuf[len-1] == ':' ){
		pbuf[len] = '\\';
	}

	// changd dir to root NAND
	fsDirSet("D:\\",0);

	err = fsDirSet( pbuf,0 );
	
	// 进行第一次的搜索
	err = fsFirstFileFind( );

	DEBUG_OUTPUT(("err 0x%x\r\n",err));

	// free memory 
	MEM_FREE( pbuf );

	return;	
}

/************************************************************************/
/*	  
input:	
		stream	[in]	文件句柄
		len		[in]	文件的截取长度

  output:	0 成功  非0值 失败

func:	将一个已经打开的文件裁剪为需要的长度

note:	只能将一个长文件,裁剪为短文件,
		不能将一个短文件,裁剪为长文件
		不能将文件的长度,裁剪为 0 字节	
                                                                        */
/************************************************************************/
#ifndef _FOR_A3K_PROG
INT32 QFS_ftruncate (ZA_FILE * stream, UINT32 len)
#else
INT32 ZA_ftruncate (ZA_FILE * stream, UINT32 len)			 
#endif
{
	ERROR_REPORT;	
	return QFS_ERR;		
}

/************************************************************************/
/*	进行整个目录内容的删除动作
input:	
		path		路径名字符串指针
		pcontinue	存放删除是否结束的标志 

output:		0	成功删除一个文件 或者 一个空目录
		非	0	删除文件或者空目录失败
		*pcontinue	0		表示整个删除过程,已经结束了		
		*pcontinue	非0		表示删除过程,还没有结束,需要继续进行删除动作
func:	
		目录删除是一个较复杂的过程, 将一个复杂的事情,分解为一系列简单的
		事情来进行, 每执行一次该函数,删除一个文件或者一个空的目录

		输入的path 举例:		
			ABC
			C:\\abc
			C:\\ABC\\test

                                                                        */
/************************************************************************/
#ifndef _FOR_A3K_PROG
INT32 QFS_rmdirEx(INT8 * path, INT32 *pcontinue)
#else
INT32 ZA_rmdirEx(INT8 * path,  INT32 *pcontinue)
#endif
{
	ERROR_REPORT;	
	return QFS_ERR;			
}

/************************************************************************/
/* 
  input:
			path	[in]	路径名字符串指针
  output:		
			0 成功, 其他值 失败
  func:	
  note:
			目前仅支持一级目录
                                                                        */
/************************************************************************/
#ifndef _FOR_A3K_PROG
INT32 QFS_mkdir(const INT8 * pPath)
#else
INT32 ZA_mkdir(const INT8 * pPath)
#endif
{
	UINT16	err; 
	INT32	i,ret,offset;
	UINT8	*pCurrPath;
	UINT8	*pPathBackup;	
	UINT8	*path;
	UINT8   now_path[0x100];

	// 判断输入参数是否合法
	if (NULL == pPath) {
		ERROR_REPORT;
		return QFS_ERR;
	}

#ifndef CHANGE_CODE
	path = pPath;						// 直接使用进来的字符串
#else
	// 进行编码的转换
	path = get_unicode_ptr( pPath );
#endif

	// 获得当前路径字符串
	err = fsDirGet(&pCurrPath);
	if (err) {
		ERROR_REPORT;
		return QFS_ERR;		
	}

	// 申请内存保存原来的工作路径
	i = strlen(pCurrPath) +4;
	pPathBackup = (UINT8 *)MEM_ALLOC( i );	
	if (NULL == pPathBackup) {
		ERROR_REPORT;
		return QFS_ERR;				
	}

	// 获得当前的工作路径
	strcpy(pPathBackup, pCurrPath);
	// 如果是根目录,添加"\\"
	if ( pPathBackup[ strlen(pPathBackup) -1 ] == ':' ) 
	{
		pPathBackup[ strlen(pPathBackup) ] = '\\';
	}

	// 进行目录的建立动作
	ret = QFS_OK;						// 初始化为成功	
	offset = 0x00;

	while (path[offset] == '\\') {		// 越过前面的'\\', 直接指向实际的字符串		
		offset ++;
	}
	
	for(i=THE_LAST_DIR+1;  i!= THE_LAST_DIR; ) {
		if( offset && (path[offset] == '\0') ) {
			break;
		}

		i = get_dir_from_str((char *)path+offset, now_path);	// 取出一级目录名 

		DEBUG_OUTPUT(("now path :%s\r\n", now_path));


		offset += strlen(now_path);		// 指向下一级目录,注意跳过了一个'\\'
		
		while (path[offset] == '\\') {	// 越过 '\\' 
			offset++;
		}

		// 检查输入的字符串是否合法
		ret = QFS_check_fname(now_path);

		// 字符串检查失败,再看看是否为"C:\\"
		if( ret ) {
			if( !strcmp(now_path, "C:\\") || !strcmp(now_path, "D:\\")) {
				ret = 0x00;
			}
		}

		// 再给一次机会,进行判断
		if(ret) { break; }

		// 尝试着进入该级目录		
		err = fsDirSet( now_path, 0x00);

		// 可以进入该级目录,表示该级目录已经存在了, 不需要进行目录的建立
		if( !err ){
			continue;
		} 

		if( now_path[strlen(now_path)-1] == '\\' ) {
			now_path[ strlen(now_path)-1 ] = '\0'; 
		}
		
		// 建立该目录
		err = fsDirMake( now_path,  strlen(now_path));
		// 建立目录成功,进入该目录	
		if( !err )
		{
			DEBUG_OUTPUT(("进入该目录\r\n"));	
			fsDirSet( now_path, strlen(now_path) );
		}
		else {
			ERROR_REPORT;
			break;
		}

	}

	// 将工作目录恢复到原来的工作目录
	fsDirSet( pPathBackup, 0x00 );
	MEM_FREE( pPathBackup );

	return ret;
}

/************************************************************************/
/* 
		--------------  只在本文件内使用的函数 -----------------------
																		*/
/************************************************************************/

/************************************************************************/
/*	输入一个字符串, 获得该字符串对应的逻辑盘的内部代码值

  input:
			pDevName	[in]	逻辑盘字符串的指针
			pDevID		[out]	获得的设备内部代码存放的地址
  output:
			0 成功, 非0值失败
  func:
  note:
                                                                        */
/************************************************************************/
static UINT16 get_devid_by_name( UINT8 * pDevName, UINT16 *pDevID)
{
	UINT16	i,ret;

	// 将首字符转换为大写的格式
	i = toupper( (int)pDevName[0] );

	ret = QFS_OK;

	if (i == 'D') {
		*pDevID = FS_DRIVE_NAND;
	}
	else if ( i == 'C') {
		*pDevID = FS_DRIVE_SD_MMC;		
	}
	else{
		*pDevID = 0xffff;
		ret = QFS_ERR;
	}

	return ret;
}

/************************************************************************/
/*
  input:
			in_str	[in]	模式字符串的指针
  output:
			(-1)表示输入的参数不正常,正常为:内部定义的类型值
  func:

  note:
                                                                        */
/************************************************************************/
static INT16 QFS_get_open_mode( INT8 * in_str)
{
	INT16 i,j, len;
	INT8 temp[6];

	len = strlen(in_str);	// 获得字符串长度

	// 判断输入参数是否合法
	if( len>(sizeof(temp)-1) || !len){	
		ERROR_REPORT;
		return QFS_ERR;
	}	

	// 将所有的字符转换为小写, 获得字符串的累加和
	for(i=0x00, j=0x00; i<len; i++)	
	{
		temp[i] = tolower(in_str[i]);
		j += temp[i];
	}

	// 根据累加和判断结果
	if( j == 'r' || j == 'r'+'b') {
		return F_O_RDONLY;
	}
	else if (j == 'w' || j == 'w' + 'b') {
		return F_O_WRONLY;
	}
	else if (j == 'a' || j == 'a' + 'b') {
		return F_O_APPEND;
	}
	else if (j == 'r' + '+' ||  j == 'r' + 'b' + '+' ) {
		return F_O_RD_PLUS;
	}
	else if (j == 'w' + '+' ||  j == 'w' + 'b' + '+' ) {
		return F_O_WR_PLUS;
	}
	else if (j == 'a' + '+' ||  j == 'a' + 'b' + '+' ) {
		return F_O_APPEND_PLUS;
	}
	
	return QFS_ERR;
}

/************************************************************************/
/*
  input:	
			name	[in]	文件名字符串的指针
  output:	
			0 成功 非0 失败	
  func:
			判断输入的文件名字符串是否符合 WINDOWS FAT 规范。
                                                                        */
/************************************************************************/
#define INVALID_FNAME	(-1)
#define BANJIAO_CHAR	(0x80)

static INT32 QFS_check_fname(INT8 *name )
{
	INT32	i,j;

	// 首字符不能为 '.' 和 ' '
	if(name[0] == '.' || name[0] == ' ') {
		ERROR_REPORT;
		return INVALID_FNAME;	
	}

	// 取得关键字字符串的长度
	j = strlen(name);

	// 文件名字符串的结尾不能为 '.' 和 ' '
	if( (name[j-1] == ' ') || (name[j-1] == '.') ) {
		ERROR_REPORT;
		return INVALID_FNAME;
	}
	
	// 检查是否含有小于 0x20 的字符
	for(i=0x00; i<j; i++)		
	{
		if( (UINT8) name[i]< (UINT8)' ')
		{
			ERROR_REPORT;			
			return INVALID_FNAME;	// 如果存在小于' ' 的字符,直接返回失败 
		}
	}

	// 上面的程序没有考虑 繁体汉字 BIG5 编码中 后面一个字节为ASCII 的情形 
	for(i=0x00; i<strlen(name); i++)	
	{
		// 遇到汉字就跳过一个字节
		if((UINT8)name[i] > (UINT8)BANJIAO_CHAR ) {
			i++;
			continue;
		}
		
		// 判断该字符是否为FAT 禁止的字符
		for(j=0x00; j<sizeof(fnamekeyword); j++)
		{
			if(fnamekeyword[j] == name[i]){
				ERROR_REPORT;				
				return INVALID_FNAME;	
			}
		}
		
	}

	// 检查文件名是否与 WINDOWS 保留字符串一致
	for(i=0x00; i< PERSVSUM; i++)
	{
		if(!strcmp(name, fnamepersive[i])) 
		{
			ERROR_REPORT;
			return INVALID_FNAME;	// 如果使用了 WINDOWS FAT 保留的字符串,返回失败
		}
	}	
	return 0;
}

/************************************************************************/
/* 
//			get_dir_from_str
//
//func:		从一个多级目录串中,只取出一级目录文本串
//  
//input:	PSTR in_str			输入的字符串的指针
//			PSTR out_str		得到的目录的存放的指针

//output:	THE_LAST_DIR		已经是最后的目录,没有后续目录了
//			THE_LAST_DIR+1 		还有后续目录,还需要继续进行

 //note:
//example:	
//
//note:	
			[6/14/2006] 修改取出目录字符串时,不带有'\\'

			[3/17/2005] 对函数进行调整,处理如此的情形 "C:\\123\\\\DEBUG\\9876"	
//
//			在目录名之间有多于一个 '\\'出现的情形	
//
//
//change:	7/22/2005 需要考虑繁体汉字 BIG5 编码中出现 0x5c 的情形
                                                                        */
/************************************************************************/
static INT16 get_dir_from_str(const INT8 *in_str, INT8 *out_str)
{
	INT16 i,j, str_len;
	out_str[0] = '\0';

	// 获得输入字符串的长度
	str_len = strlen(in_str);

	// 只有"\\" 的情形
	if((in_str[0] == '\\') && (in_str[1] == '\0')){
		strcpy(out_str, in_str);
		return THE_LAST_DIR;
	}
	
	// 根目录的情形
	if((in_str[0] == '\\') && (in_str[1] != '\0')){
		strcpy(out_str, "\\");
		return THE_LAST_DIR+1;	
	}
	
	// "C:\\ABCD\\998HGF" 有":"的情形
	if((in_str[1] == ':') && (in_str[2] == '\\')){
		memcpy(out_str, in_str, 0x03);
		out_str[3] = '\0';
		if(in_str[3] == '\0'){
			return THE_LAST_DIR;
		}
		return   THE_LAST_DIR+1;
	}

	// 获得需要复制的长度
	// 需要处理如此的情形	"C:\\123\\\\\\DEBUG\\987"
	for(i=0x00; i<str_len; i++)
	{
		// 如果是汉字字符,就跳过下一个字符
		if(( UINT8)in_str[i] > (UINT8)BANJIAO_CHAR ) {
			i++;
			continue;
		}

		// 如果不是最后一个'\\', 还有继续
		if((in_str[i] == '\\') && (in_str[i+1] == '\\')){
			continue;
		}

		// 如果遇到了 '\\' 或者 '\0', 也就是找到结束标志了
		if(in_str[i] == '\\' || in_str[i] == '\0') {
#if 0
			if(in_str[i+1] != '\\') {
				i++;
			}
#endif
			break;
		}
	}

	// 复制字符串
	for(j=0x00; j<i; j++)
	{
		if(in_str[j] != '\\'){
			out_str[j] = in_str[j];
		}
		else
		{
			// 考虑 繁体汉字 编码为 0xZZ 0x5C 的情形
			if(	j && (in_str[j] == '\\') && ((UINT8)in_str[j-1] > BANJIAO_CHAR) ) {
				out_str[j] = in_str[j];				
				continue;
			}
			else{
				out_str[j] = in_str[j];
				j++;
				i = j;
				break;				
			}
		}
	}

	// 给得到的字符串补零
	out_str[i] = '\0';
	
	// 判断需要返回的值
//	if(in_str[i+1] != '\0')	
	if( strlen(in_str) != i ){
		return THE_LAST_DIR+1;
	}
	else{
		return THE_LAST_DIR;		
	}
}

/************************************************************************/
/*	将一个地址指针转换为内部句柄
  input:
			stream	[in]	void * ZA 接口层的文件句柄指针
  output:
  func:
  note:
                                                                        */
/************************************************************************/
static INT16 get_file_handle( void * stream, UINT32 *pHandle )
{
	if ( (UINT32)stream < (UINT32)&pFHandleBegin) 
	{
		ERROR_REPORT;
		return QFS_ERR;
	}
	*pHandle = (UINT32) ( (UINT32)stream - (UINT32)&pFHandleBegin );		
	return QFS_OK;
}

/************************************************************************/
/*	输入本地编码的地址指针
  input:
			plocal	[in]	本地编码数据存放的地址指针
  output:
			获得的UNICODE 编码存放的地址指针
  func:
  note:
                                                                        */
/************************************************************************/
static UINT8 * get_unicode_ptr(const INT8 *plocal )
{
	UINT8 *pbuf;

	pbuf = NULL;

	if (NULL == gpFS_strbuf)
	{
		pbuf = (UINT8 *) MEM_ALLOC(FS_NAME_BUF);

		if (NULL == pbuf) 
		{
			ERROR_REPORT;
			return NULL;
		}
		// 保存全局指针
		gpFS_strbuf = pbuf;
	}
	else
	{
		pbuf = gpFS_strbuf;		// 使用全局变量保存的内存地址值
	}

	SPMP_local2uni((UINT8 *)plocal, pbuf);

	return pbuf;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -