MTK优美代码赏析7:文件搜索与匹配

    最近因需要拓展音乐播放器功能,研究了下MTK的文件系统,趁周末我总结一下关于文件系统关键的接口<文件搜索与匹配>MTK实现的方法。
    关于文件搜索,因为都是基于FAT格式的系统,所以MTK文件处理的思路和Window是很相似的。
    通过FindFirstFile函数获取操作句柄HANDLE,将此句柄作为参数传入FindNextFile函数,通过FindNextFile不断搜索下一个文件/文件夹,当FindNextFile返回值为0时表示搜索完成,查询完成后通过FindClose关闭句柄。
    对应MTK中的接口为FS_FindFirst,FS_FindNext和FS_FindClose,下面拿一段代码来看(来自aud_vr_sd.c)
//作者:张素丰,转载请注明出处:http://www.zhangsufeng.cn/?p=237
/* ****************************************************************************
 * FUNCTION
 *  aud_vr_sd_scan_tags_in_group_folder
 * DESCRIPTION
 *  vr sd scan all tags in a group folder
 * PARAMETERS
 *  group_id        [IN]        
 *  path            [?]         
 * RETURNS
 *  void
 ****************************************************************************
*/
void  aud_vr_sd_scan_tags_in_group_folder(kal_uint16 group_id, kal_uint16  * path)
{
    
/* ---------------------------------------------------------------- */
    
/*  Local Variables                                                 */
    
/* ---------------------------------------------------------------- */
    kal_uint16 filename[VR_MAX_DB_PATH_LEN 
+   1 ];
    kal_uint16 filename_expr[VR_MAX_DB_PATH_LEN 
+   1 ];
    kal_int32 word_id;
    FS_HANDLE fd_cursor;
    FS_DOSDirEntry file_info;

    
/* ---------------------------------------------------------------- */
    
/*  Code Body                                                       */
    
/* ---------------------------------------------------------------- */
    vr_sd_ctx.id_length[group_id] 
=   0 ;
    kal_wsprintf(filename_expr, 
" %wMTKVR_????.vrd " , path);

    
if  ((fd_cursor  =  FS_FindFirst(filename_expr,  0 0 & file_info, filename, (VR_MAX_DB_PATH_LEN  +   1 <<   1 ))  >=   0 )
    {
        
/*  loop through all vrd files in a group folder  */
        
do
        {
            
/*  filter out folder results  */
            
if  ( ! (file_info.Attributes  &  FS_ATTR_DIR))
            {
                
/*  parse word id and add to id array and increment id length  */
                
if  ((word_id  =  aud_vr_sd_extract_word_id(filename))  >=   0 )
                {
                    vr_sd_ctx.id_array[group_id][vr_sd_ctx.id_length[group_id]
++ =  word_id;
                }
            }
        } 
while  (FS_FindNext(fd_cursor,  & file_info, filename, (VR_MAX_DB_PATH_LEN  +   1 <<   1 ==  FS_NO_ERROR);
        FS_FindClose(fd_cursor);
    }
}

 


    下面讲一讲匹配,这里所说的匹配主要是将文件格式(即后缀名)的匹配,在获取到文件名以后进行。

    思路也都是相同的,那就是从文件名末端开始搜索到第一个".",然后截取"."后面这一段作为拓展名,然后把这个拓展名拿到自己的需要的格式列表中对比即可。

    MTK中有两种方式实现了这个需求,

    方式1(来自FileManagerSrc.c):

 /*****************************************************************************

 * FUNCTION
 *  mmi_fmgr_get_file_group
 * DESCRIPTION
 *  check file type belongs to which file group
 * PARAMETERS
 *  path        [?]     
 * RETURNS
 *  void
 ****************************************************************************
*/
U8 mmi_fmgr_get_file_group(S8 
* path)
{
    
/* ---------------------------------------------------------------- */
    
/*  Local Variables                                                 */
    
/* ---------------------------------------------------------------- */
    FMGR_FILTER file_type;
    S32 result;

    
/* ---------------------------------------------------------------- */
    
/*  Code Body                                                       */
    
/* ---------------------------------------------------------------- */
    result 
=  mmi_fmgr_get_file_type(path,  & file_type);

    
if  (result  ==  FS_FILE_NOT_FOUND)
    {
        
return  FMGR_GROUP_UNKNOWN;
    }
    
    
if  (FMGR_FILTER_IS_SET_AUDIO( & file_type))
    {
        
return  FMGR_GROUP_AUDIO;
    }
    
else   if  (FMGR_FILTER_IS_SET_IMAGE( & file_type))
    {
        
return  FMGR_GROUP_IMAGE;
    }
    
else   if  (FMGR_FILTER_IS_SET_VIDEO( & file_type))
    {
        
return  FMGR_GROUP_VIDEO;
    }
    
else   if  (FMGR_FILTER_IS_SET_SWFLASH( & file_type))
    {
        
return  FMGR_GROUP_SWFLASH;
    }
    
else
    {
        
return  FMGR_GROUP_UNKNOWN;
    }
}

 

 在mmi_fmgr_get_file_type函数内实现了相应的逻辑,这个流程依赖于FileMgr.c中

const fmgr_filter_struct fmgr_filter[FMGR_MAX_FILTER_COUNT];

    方式2: 依赖于系统的全局变量的东西有时并不能满足我们应用的需求,这个时候我们需要自己定义一个私有的fmgr_filter,来实现拓展名的判断。

    这个流程的实现可以参照09A代码AudioPlayerPlayList.c中mmi_audply_playlist_generate_search函数。

    下面来对比两个获取后缀名的函数:

 /*****************************************************************************

 * FUNCTION
 *  mmi_fmgr_extract_ext_file_name
 * DESCRIPTION
 *  get pointer to the extension file name in the file path
 * PARAMETERS
 *  path        [?]     
 * RETURNS
 *  void
 ****************************************************************************
*/
PS8 mmi_fmgr_extract_ext_file_name(S8 
* path)
{
    
/* ---------------------------------------------------------------- */
    
/*  Local Variables                                                 */
    
/* ---------------------------------------------------------------- */
    S16 i, length;

    
/* ---------------------------------------------------------------- */
    
/*  Code Body                                                       */
    
/* ---------------------------------------------------------------- */
    length 
=  (S16) mmi_ucs2strlen(path);
    i 
=  length  -   1 ;

    
while  (i  >=   0 )
    {
        
if  (path[i  <<   1 ==   ' \\ '   &&  path[(i  <<   1 +   1 ==   0 )
        {
            
return  NULL;
        }
        
if  (path[i  <<   1 ==   ' . '   &&  path[(i  <<   1 +   1 ==   0   &&  (i  !=  length  -   1 ))
        {
            
break ;
        }
        i
-- ;
    }

    
if  (i  <   0 )
    {
        
return  NULL;
    }

    
return   & path[(i  +   1 <<   1 ];
}

 

    另一种系统string处理的接口:

/* ****************************************************************************
 * FUNCTION
 *  app_ucs2_strrchr
 * DESCRIPTION
 *  Scan a UCS2 encoded string for the last occurrence of a character.
 * PARAMETERS
 *  string        [IN]  UCS2 encoded string to search in.       
 *  ch            [IN]  UCS2 encoded wide-character to search for.      
 * RETURNS
 *  returns pointer to the last occurrence of ch in string
 *  returns NULL if ch does not occur in string
 ****************************************************************************
*/
kal_int8 
* app_ucs2_strrchr( const  kal_int8  *   string , kal_wchar ch)
{
    
/* ---------------------------------------------------------------- */
    
/*  Local Variables                                                 */
    
/* ---------------------------------------------------------------- */
    kal_int8 
* cursor  =  (kal_int8  * ) string ;
    
    
/* ---------------------------------------------------------------- */
    
/*  Code Body                                                       */
    
/* ---------------------------------------------------------------- */     
    
while  ( * cursor  ||   * (cursor + 1 ))               /*  find end of string  */
    {
        cursor 
+=   2 ;
    }
    
    
/*  search towards front  */
    
while  ((kal_int8  * ) string   !=  cursor  &&  
           (
* (cursor + 1 ) << 8 | (kal_uint8)( * cursor))  !=  ch)
    {
        cursor 
-=   2 ;
    }
    
    
if  (( * (cursor + 1 ) << 8 | (kal_uint8)( * cursor))  ==  ch)           /*  found ? */
    {
        
return  cursor;
    }
    
    
return  NULL;
}
PS8  test(
const  UI_string_type ext)
{
     
/* ---------------------------------------------------------------- */
    
/*  Local Variables                                                 */
    
/* ---------------------------------------------------------------- */
    U8 i 
=   0 ;
    U32 ext_len 
=   0 ;
    UI_character_type file_ext[FMGR_MAX_EXT_LEN 
+   1 ];
    
/* ---------------------------------------------------------------- */
    
/*  Code Body                                                       */
    
/* ---------------------------------------------------------------- */
   
/*  skip ".".  */
    {
        PS8 dot 
=  (PS8)app_ucs2_strrchr(( const  PS8)ext, (U16)L ' . ' );
        
if  (dot)
        {
            dot 
+=   2 ;
        }
        
else
        {
            dot 
=  (PS8)ext;
        }
        mmi_ucs2ncpy((PS8)file_ext, (
const  PS8)dot, FMGR_MAX_EXT_LEN);
        ext_len 
=  mmi_ucs2strlen(( const  PS8)dot);
        
return  dot;
    }
}

 

 

 

 

posted on 2010-10-10 12:06  Anpher Zhang 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/zhangsufeng/archive/2010/10/10/1847122.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值