记录项目中用到的一点小东西
结构体定义
#define MAX_NAME_LENTH 64
struct list_head
{
struct list_head *next;
struct list_head *prev;
};
struct dir_list_head{
struct list_head video_dir_head;//video文件链表头
struct list_head audio_dir_head;//audio文件链表头
struct list_head image_dir_head;//image文件链表头
struct list_head face_dir_head;//image文件链表头
};
typedef struct _file_list{
char file_name[MAX_NAME_LENTH];
struct list_head list_node;
}file_list_t,*p_file_list_t;
typedef struct _dir_list{
char dir_name[MAX_NAME_LENTH];
struct list_head file_list_head;
struct list_head list_node;
}dir_list_t,*p_dir_list_t;
头文件.h
void list_head_init(struct list_head *list);
void list_add_prev(struct list_head *new, struct list_head *pos);
void list_add_next(struct list_head *new, struct list_head *pos);
void list_add_tail(struct list_head *_new, struct list_head *head);
void list_del(struct list_head *entry);
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
#ifndef container_of
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
#endif
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
/**
* list_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the &struct list_head to use as a loop cursor.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
#endif //_LIST_H_
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
list.c
#include "list.h"
#include <stdio.h>
static void __list_add(struct list_head *_new, struct list_head *prev, struct list_head *next)
{
next->prev = _new;
_new->next = next;
_new->prev = prev;
prev->next = _new;
}
static void __list_del(struct list_head *prev, struct list_head *next)
{
next->prev = prev;
prev->next = next;
}
void list_head_init(struct list_head *list)
{
list->next = list;
list->prev = list;
}
/**
* list_add_tail - insert a new entry before the specified head
* @_new: new entry to be added
* @head: list pos to add it before
*/
void list_add_prev(struct list_head *new, struct list_head *pos)
{
__list_add(new, pos->prev, pos);
}
/**
* list_add_tail - insert a new entry before the specified head
* @_new: new entry to be added
* @head: list pos to add it behind
*/
void list_add_next(struct list_head *new, struct list_head *pos)
{
__list_add(new, pos, pos->next);
}
/**
* list_add_tail - insert a new entry before the specified head
* @_new: new entry to be added
* @head: list head to add it before
*/
void list_add_tail(struct list_head *_new, struct list_head *head)
{
__list_add(_new, head->prev, head);
}
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
*/
void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = NULL;
entry->prev = NULL;
}
文件排序
文件夹基于xxxx_20200401_xxx 和 xxxx_20210305
文件排序名字基于xxxxxx_20200401_013013_xxx.xxx和xxxxxx_20200401_013013.xxx(可自行根据需求,更改代码strcmp)
//parma1:字符串
//parma2:需要查找的字符
//parma3:需要查找第几个字符 正数从左到右,负数从右到左
char *SearchStrChr(char *str,char ch,int count)
{
char *p = str;
unsigned int num = abs(count);
if(count < 0){
int i = 0;
p = strrchr(p,ch);
if(!p)
return NULL;
while(1){
i++;
if(i >= num)
return p;
for(;;){
p--;
if(p <= str){
if(*p != ch){
return NULL;
}else
return p;
}
if(*p == ch)
break;
}
}
}else if(count > 0){
int i = 0;
while(1){
p = strchr(p,ch);
if(!p)
return NULL;
i++;
if(i < num)
p++;
else
return p;
}
}else
return NULL;
if(*p != ch){
return NULL;
}
return p;
}
//return dir name
//找出最大的文件夹名字
char* str_sort(void)
{
int num = 0;
struct list_head *p_list_node = (struct list_head *)&dir_head_node;
for(int i = 0;i < (sizeof(dir_head_node)/sizeof(struct list_head));i++){
if(i)
p_list_node ++;
num = i;
if(p_list_node != p_list_node->prev)
break;
}
if(p_list_node == p_list_node->prev)
return NULL;
struct list_head *list_node_min = NULL;
struct list_head *list_node_max = p_list_node;
for(int i = 1;i < (sizeof(dir_head_node)/sizeof(struct list_head)) - num;i++){
list_node_min = p_list_node + i;
if(list_node_min == list_node_min->prev)
continue;
dir_list_t *p_min = list_entry(list_node_min->prev,dir_list_t ,list_node);
dir_list_t *p_max = list_entry(list_node_max->prev,dir_list_t ,list_node);
if(strcmp(p_min->dir_name,p_max->dir_name) > 0){
list_node_max = list_node_min;
}
}
return list_entry(list_node_max->prev,dir_list_t ,list_node)->dir_name;
}
//基于内核链表的快速排序
//指针交换
void dir_quick_sort(struct list_head *head_node,struct list_head *end_node)
{
//当只有一个文件或者没有文件时
if (head_node == end_node) {
return;
}
struct list_head *low = NULL,*high = NULL,*base_node = NULL;
//初始化基准值,和左右max值,tmp_head记录链表头list head
base_node = head_node,low = head_node,high = end_node;
dir_list_t *p_cur = NULL,*p_base = NULL;
//记录head和end值
head_node = head_node->prev;
end_node = end_node->next;
p_base = list_entry(base_node,dir_list_t,list_node);
while(low != high){
//high ->low
//右到左同base比较,比他小就放到它左边,比它小就原地不动
while(low != high){
p_cur = list_entry(high,dir_list_t,list_node);
if(strcmp(p_cur->dir_name,p_base->dir_name) < 0){
if(low->next != high){
low = low->next;
list_del(base_node);
list_add_prev(base_node,high);
list_del(high);
list_add_prev(high,low);
high = base_node;
}else{
list_del(base_node);
list_add_next(base_node,high);
high = base_node;
}
break;
}else{
high = high->prev;
}
}
//low ->high
//左到右同base比较,比他大就放到它右边,比它小就原地不动
while(low != high){
p_cur = list_entry(low,dir_list_t,list_node);
if(strcmp(p_cur->dir_name,p_base->dir_name) > 0){
if(high->prev != low){
high = high->prev;
list_del(base_node);
list_add_prev(base_node,low);
list_del(low);
list_add_next(low,high);
low = base_node;
}else{
list_del(base_node);
list_add_prev(base_node,low);
low = base_node;
}
break;
}else{
low = low->next;
}
}
}
//重置head和end 使其永远指向头和尾
head_node = head_node->next;
end_node = end_node->prev;
if(head_node != base_node){
dir_quick_sort(head_node,base_node->prev);//前半段
}
if(base_node != end_node){
dir_quick_sort(base_node->next,end_node);//后半段
}
}
void file_quick_sort(struct list_head *head_node,struct list_head *end_node)
{
//当只有一个文件或者没有文件时
if (head_node == end_node) {
return;
}
struct list_head *low = NULL,*high = NULL,*base_node = NULL;
//初始化基准值,和左右max值,tmp_head记录链表头list head
base_node = head_node,low = head_node,high = end_node;
file_list_t *p_cur = NULL,*p_base = NULL;
//记录head和end值
head_node = head_node->prev;
end_node = end_node->next;
p_base = list_entry(base_node,file_list_t,list_node);
while(low != high){
//high ->low
//右到左同base比较,比他小就放到它左边,比它小就原地不动
while(low != high){
p_cur = list_entry(high,file_list_t,list_node);
char *p1_prefix = SearchStrChr(p_cur->file_name,'.',-1);
char *p1 = SearchStrChr(p_cur->file_name,'_',-1);
if((p1_prefix - p1) != 7){
p1 = SearchStrChr(p_cur->file_name,'_',-3);
}else{
p1 = SearchStrChr(p_cur->file_name,'_',-2);
}
char *p2_prefix = SearchStrChr(p_base->file_name,'.',-1);
char *p2 = SearchStrChr(p_base->file_name,'_',-1);
if((p2_prefix - p2) != 7){
p2 = SearchStrChr(p_base->file_name,'_',-3);
}else{
p2 = SearchStrChr(p_base->file_name,'_',-2);
}
if(strcmp(p1,p2) < 0){
if(low->next != high){
low = low->next;
list_del(base_node);
list_add_prev(base_node,high);
list_del(high);
list_add_prev(high,low);
high = base_node;
}else{
list_del(base_node);
list_add_next(base_node,high);
high = base_node;
}
break;
}else{
high = high->prev;
}
}
//low ->high
//左到右同base比较,比他大就放到它右边,比它小就原地不动
while(low != high){
p_cur = list_entry(low,file_list_t,list_node);
char *p1_prefix = SearchStrChr(p_cur->file_name,'.',-1);
char *p1 = SearchStrChr(p_cur->file_name,'_',-1);
if((p1_prefix - p1) != 7){
p1 = SearchStrChr(p_cur->file_name,'_',-3);
}else{
p1 = SearchStrChr(p_cur->file_name,'_',-2);
}
char *p2_prefix = SearchStrChr(p_base->file_name,'.',-1);
char *p2 = SearchStrChr(p_base->file_name,'_',-1);
if((p2_prefix - p2) != 7){
p2 = SearchStrChr(p_base->file_name,'_',-3);
}else{
p2 = SearchStrChr(p_base->file_name,'_',-2);
}
if(strcmp(p1,p2) > 0){
if(high->prev != low){
high = high->prev;
list_del(base_node);
list_add_prev(base_node,low);
list_del(low);
list_add_next(low,high);
low = base_node;
}else{
list_del(base_node);
list_add_prev(base_node,low);
low = base_node;
}
break;
}else{
low = low->next;
}
}
}
//重置head和end 使其永远指向头和尾
head_node = head_node->next;
end_node = end_node->prev;
if(head_node != base_node){
file_quick_sort(head_node,base_node->prev);//前半段
}
if(base_node != end_node){
file_quick_sort(base_node->next,end_node);//后半段
}
}
文件列表加载
int load_file_list(const char *dirname,struct list_head *head_node,enum CODEC_MEDIA_TYPE media_type)
{
/* 打开要进行匹配的文件目录 */
struct dirent *ent = NULL;
char folderName[260] = {0};
char fileName[520] = {0};
char *old_file = NULL,*new_file = NULL;//区别id不同产生错误判断,如果没有id,可以取'.'用mp4后缀判断
char *pType = NULL,*p = NULL;//判断是否为mp4文件
//打开ADUIO IMAGE VIDEO 目录
DIR *firstDir = opendir(dirname);
if (firstDir == NULL){
ERR_PRINT("opendir %s fail\n",dirname);
return -1;
}
list_head_init(head_node);
//***********************dir*********************
while(1){
//read ADUIO IMAGE VIDEO 目录
u8 file_exsit = 0;
ent = readdir (firstDir);
if (ent == NULL){
break;
}
if ((strcmp(".", ent->d_name)==0) || (strcmp("..", ent->d_name)==0)||(ent->d_type != DT_DIR)){
continue;
}
if(VIDEO == media_type){
if(strlen(ent->d_name) != 13&&strlen(ent->d_name) != 17)
continue;
}else{
if(strlen(ent->d_name) != 13)
continue;
}
//将文件夹名字填入链表中存储
p_dir_list_t dir_node = (p_dir_list_t)malloc(sizeof(dir_list_t));
if(dir_node == NULL){
DEBUG_PRINT("dir_node malloc fail");
return -1;
}
sprintf(dir_node->dir_name,"%s",ent->d_name);
list_add_tail(&dir_node->list_node,head_node);
memset(folderName,0,sizeof(folderName));
sprintf(folderName,"%s/%s",dirname,ent->d_name);
//打开日期文件夹
DIR *secDir = opendir(folderName);
if (secDir == NULL){
ERR_PRINT("opendir %s fail\n",folderName);
return -1;
}
//*********************file***********************
//file tmp node
p_file_list_t file_tmp_node = NULL;
list_head_init(&dir_node->file_list_head);
while(1){
//read 日期文件夹
ent = readdir (secDir);
if (ent == NULL){
break;
}
if ((strcmp(".", ent->d_name)==0) || (strcmp("..", ent->d_name)==0)||ent->d_type != DT_REG){
continue;
}
file_exsit = 1;
char *p = strrchr(ent->d_name,'_');
char *p1 = strrchr(ent->d_name,'.');
if(NULL == p || p1 == NULL)
continue;
if(VIDEO == media_type){
if((p1-p) != 7&&(p1-p) != 4)
continue;
}else if(AUDIO == media_type){
if((p1-p) != 7)
continue;
}else if(IMAGE == media_type){
if((p1-p) != 7
&&(p1-p) != 3)
continue;
}
p_file_list_t file_node = (p_file_list_t)malloc(sizeof(file_list_t));
if(file_node == NULL){
DEBUG_PRINT("file_node malloc fail");
return -1;
}
sprintf(file_node->file_name,"%s",ent->d_name);
if(NULL == file_tmp_node){
list_add_tail(&file_node->list_node,&dir_node->file_list_head);
file_tmp_node = file_node;
}else{
list_add_next(&file_node->list_node,&file_tmp_node->list_node);
file_tmp_node = file_node;
}
}
closedir(secDir);
//*******************************************
if(!file_exsit){
list_del(&dir_node->list_node);
free(dir_node);
dir_node = NULL;
char cmd_buf[128] = {0};
sprintf(cmd_buf,"rm -rf %s",folderName);
if(exeCmd(cmd_buf) < 0){
DEBUG_PRINT("remove dir fail");
return -1;
}
}else{
file_quick_sort(dir_node->file_list_head.next,dir_node->file_list_head.prev);
}
}
//******************************************************
closedir(firstDir);
return 0;
}