#include "list.h" #include "stdlib.h" #include "string.h" #include "stdio.h" #include "board.h" #include "mystdlib.h" #include "debug.h" #include "bytearray.h" #include "rtthread.h" #define LIST_APPEND_SKIP 10 typedef struct{ int32_t next; int32_t prev; uint32_t data[0]; }list_node_def; struct _list_def{ int32_t all; int32_t used; int32_t block_size; int32_t block_size4; rt_mutex_t mutex; int32_t head; int32_t tail; sub_fun_def sub; del_fun_def del; str_fun_def str; uint32_t data[0]; }; //#define list_enter_mutex(l)\ // rt_mutex_take((l)->mutex,RT_WAITING_FOREVER) // //#define list_exit_mutex(l)\ // rt_mutex_release((l)->mutex) #define list_enter_mutex(l) #define list_exit_mutex(l) #define rt_mutex_create(...) 0 #define rt_mutex_delete(l) list_def *list_creat(int block_size,sub_fun_def sub,del_fun_def del,str_fun_def str) { static uint16_t count=0; char s1[16]={0}; sprintf(s1,"list_mut#%d",count); int size=0; int block_size4; list_def *l; size+=sizeof(list_def); // 4字节对齐 block_size4=((block_size+3)/4)*4; size+=(sizeof(list_node_def)+block_size4)*LIST_APPEND_SKIP; l=malloc(size); param_check(l); l->all=LIST_APPEND_SKIP; l->used=0; l->block_size=block_size; l->block_size4=block_size4; l->mutex=rt_mutex_create(s1,RT_IPC_FLAG_FIFO); l->head=-1; l->tail=-1; l->sub=sub; l->del=del; l->str=str; // 初始化列表 list_node_def *node; node=(list_node_def *)l->data; for(int i=0;iall;i++) { node->next=-1; node->prev=-1; node=(list_node_def *)((uint32_t)node+sizeof(list_node_def)+l->block_size4); } count++; return l; } // 对于数据里有指针数据的成员,需要提供del函数 void _list_delete(list_def **l) { param_check(l); param_check(*l); list_enter_mutex(*l); if((*l)->del) { for(int i=0;i<(*l)->used;i++) { (*l)->del(list_get(*l,i)); } } list_exit_mutex(*l); rt_mutex_delete((*l)->mutex); free(*l); *l=0; } int list_block_size4(list_def *l) { param_check(l); return l->block_size4; } //static void cpy4byte(uint32_t *dst,uint32_t *src,int num_4byte) //{ // for(int i=0;iblock_size4)*(l->all); cpysize=size; size+=(sizeof(list_node_def)+l->block_size4)*(LIST_APPEND_SKIP); r=malloc(size); param_check(r); cpy4byte((uint32_t *)r,(uint32_t *)l,cpysize/4); // 初始化列表 list_node_def *node; node=(list_node_def *)((uint32_t)r->data+r->all*(sizeof(list_node_def)+r->block_size4)); for(int i=0;inext=-1; node->prev=-1; node=(list_node_def *)((uint32_t)node+sizeof(list_node_def)+r->block_size4); } r->all+=LIST_APPEND_SKIP; free(l); return r; } // 查找一个未使用的节点 static list_node_def *list_unused_node(list_def *l,int *index) { list_node_def *node=0; node=(list_node_def *)l->data; for(int i=0;iall;i++) { if((node->next==-1)&&(node->prev==-1)){ if(index) *index=i; return node; } node=(list_node_def *)((uint32_t)node+sizeof(list_node_def)+l->block_size4); } return node; } // 取得指定序号的节点 static list_node_def *list_node(list_def *l,int index) { list_node_def *node; param_check(index>=0&&indexall); node=(list_node_def *)((uint32_t)l->data+index*(sizeof(list_node_def)+l->block_size4)); return node; } // 取得节点的物理索引 static int list_phy_index(list_def *l,list_node_def *n) { return ((uint32_t)n-(uint32_t)l->data)/(sizeof(list_node_def)+l->block_size4); } /* // 改为统一使用insert函数 list_def *list_append(list_def **l,void *data) { param_check(l); param_check(*l); list_def *r=*l; if((*l)->used>=(*l)->all) { r=list_expend(*l); } list_node_def *node; int index; node=list_unused_node(r,&index); param_check(node); memcpy(node->data,data,r->block_size); if(r->head==-1&&r->tail==-1) { r->head=index; r->tail=index; node->next=index; node->prev=index; } else if(r->head!=-1&&r->tail!=-1) { node->prev=r->tail; node->next=list_node(r,r->tail)->next; list_node(r,r->tail)->next=index; r->tail=index; list_node(r,r->head)->prev=index; } else { param_check(0); } r->used++; *l=r; return r; } */ // 返回指定index的已使用节点 static list_node_def *list_used_node(list_def *l,int index) { list_node_def *node=0; if(index>l->used/2) { index=l->used-1-index; node=list_node(l,l->tail); for(int i=0;iprev); } } else{ node=list_node(l,l->head); for(int i=0;inext); } } return node; } // 获取第index项数据,不删除 // index支持负数,-1表示最后一项 // 返回数据引用 void *list_get(list_def *l,int index) { param_check(l); void *ret=0; list_enter_mutex(l); list_node_def *node; if(index<0) index=l->used+index; if((index>=0&&indexused)==0) ret=0; else{ node=list_used_node(l,index); param_check(node); ret=node->data; } list_exit_mutex(l); return ret; } // 删除第index项数据 // index支持负数,-1表示最后一项 void list_remove(list_def *l,int index) { param_check(l); list_node_def *node; int phy_index; if(index<0) index=l->used+index; list_enter_mutex(l); if((index>=0&&indexused)){ node=list_used_node(l,index); param_check(node); phy_index=list_phy_index(l,node); if(l->used==1) { l->head=-1; l->tail=-1; } else { if(l->head==phy_index) { l->head=node->next; } if(l->tail==phy_index) { l->tail=node->prev; } list_node(l,node->prev)->next=node->next; list_node(l,node->next)->prev=node->prev; } node->next=-1; node->prev=-1; if(l->del) l->del(node->data); l->used--; } list_enter_mutex(l); } // 获取指定index的数据,随后删除 // 返回数据的临时指针 // 对于存在动态指针的对象,由于take之后会自动删除,take操作会出现野指针 // 建议使用list_get + list_remove的方式代替list_take void *list_take(list_def *l,int index) { param_check(l); void *p; p=list_get(l,index); void *t=tmalloc(l->block_size); param_check(t); memcpy(t,p,l->block_size); list_remove(l,index); return t; } // 清空 void list_clear(list_def *l) { param_check(l); list_enter_mutex(l); while(l->used>0) { list_remove(l,0); } list_exit_mutex(l); } int list_length(list_def *l) { param_check(l); return l->used; } // 在指定位置插入 // index为节点插入之后所在的位置 list_def *_list_insert(list_def **l,void *data,int index) { param_check(l); param_check(*l); list_enter_mutex(*l); if(index<0) index=(*l)->used+index+1; if((index>=0&&index<=(*l)->used)==0){ list_exit_mutex(*l); return *l; } list_def *r=*l; if((*l)->used>=(*l)->all) { r=list_expend(*l); } list_node_def *node; int phy_index; node=list_unused_node(r,&phy_index); param_check(node); memcpy(node->data,data,r->block_size); if(r->head==-1&&r->tail==-1) { r->head=phy_index; r->tail=phy_index; node->next=phy_index; node->prev=phy_index; } else if(r->head!=-1&&r->tail!=-1) { list_node_def *n; int n_phy_index; if(indexused) { n=list_used_node(r,index); n_phy_index=list_phy_index(r,n); list_node(r,n->prev)->next=phy_index; node->prev=n->prev; node->next=n_phy_index; n->prev=phy_index; if(index==0) { r->head=phy_index; } } else { node->prev=r->tail; node->next=list_node(r,r->tail)->next; list_node(r,r->tail)->next=phy_index; r->tail=index; list_node(r,r->head)->prev=phy_index; } } else { param_check(0); } r->used++; *l=r; list_exit_mutex(*l); return r; } void list_sort(list_def *l) { param_check(l); list_enter_mutex(l); if(l->sub){ _list_sort(l,l->sub); } else{ DBG_WARN("obj->sub fun is null."); } list_exit_mutex(l); } // 在列表内返回1,不在返回0 int list_contains(list_def *l,void *d) { param_check(l); list_enter_mutex(l); if(l->sub) { for(int i=0;isub(list_get(l,i),d)==0){ list_exit_mutex(l); return 1; } } } else{ DBG_WARN("obj->sub fun is null."); } list_exit_mutex(l); return 0; } // 交换两个位置 void list_swap(list_def *l,int index_a,int index_b) { param_check(l); list_enter_mutex(l); void *a_=list_get(l,index_a); void *b_=list_get(l,index_b); void *t_=0; if(a_&&b_) { t_=calloc(1,sizeof(l->block_size4)); cpy4byte(t_,a_,l->block_size4/4); cpy4byte(a_,b_,l->block_size4/4); cpy4byte(b_,t_,l->block_size4/4); free(t_); } list_exit_mutex(l); } // 向后循环移动 void list_shift(list_def *l) { param_check(l); list_enter_mutex(l); if(l->used>0){ l->head=list_node(l,l->head)->next; l->tail=list_node(l,l->tail)->next; } list_exit_mutex(l); } // 输出打印字符串 char *list_string(list_def *l) { param_check(l); list_enter_mutex(l); array_def *d=arr_creat(); param_check(d); int len=0; char *s=0; arr_append(d,'('); if(l->str) { for(int i=0;istr(list_get(l,i)); len=strlen(s); arr_appends(d,s,len); free(s); arr_append(d,','); arr_append(d,' '); } } arr_append(d,')'); len=arr_length(d); s=malloc(len+1); param_check(s); memcpy(s,arr_data(d),len); arr_delete(d); s[len]=0; list_exit_mutex(l); return s; } // int sub函数 int _list_int_sub(void *a,void *b) { return *(int *)a-*(int *)b; } // int 打印函数 char *_list_int_str(void *a) { char *s=malloc(20); param_check(s); sprintf(s,"%d",*(int *)a); return s; } // str sub函数 int _list_str_sub(void *a,void *b) { char *a_=*(char **)a; char *b_=*(char **)b; return strcmp(a_,b_); } // str删除函数 int _list_str_del(void *d) { char **c=d; if(*c) free(*c); return 0; } // str 打印函数 char *_list_str_str(void *a) { char *a_=*(char **)a; int len=strlen(a_); char *s=malloc(len+1); param_check(s); memcpy(s,a_,len+1); return s; } // 延迟删除,不需要修改指针 void _list_delete_later(list_def *l) { _list_delete(&l); }