不含stm32 底层的代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MyStm32Code/libraries/file_list.c

663 lines
22 KiB

2 years ago
/**
* @file file_list.c
* @author Chen Jihang (embedded@eseaoptics.com)
* @brief
* @version 1.0
* @date 2022-08-25
*
* @copyright ESEA (c) 2020
*
*/
#include "file_list.h"
/**
* @brief
*
* @param p_list file_list描述符
* @param p_head
* @return int 0: 0:
*/
int file_list_get_head(struct file_list *p_list,struct file_list_head *p_head)
{
FRESULT ret;
UINT btr;
UINT br;
ret=f_lseek(&p_list->fp,0);
if(ret!=FR_OK){
return -1;
}
btr=sizeof(struct file_list_head);
ret=f_read(&p_list->fp,p_head,btr,&br);
if(ret!=FR_OK || btr!=br){
return -2;
}
return 0;
}
/**
* @brief
*
* @param p_list file_list描述符
* @param p_head
* @return int 0: 0:
*/
int file_list_put_head(struct file_list *p_list,struct file_list_head *p_head)
{
FRESULT ret;
UINT btw;
UINT bw;
ret=f_lseek(&p_list->fp,0);
if(ret!=FR_OK){
return -1;
}
btw=sizeof(struct file_list_head);
ret=f_write(&p_list->fp,p_head,btw,&bw);
if(ret!=FR_OK || btw!=bw){
return -2;
}
return 0;
}
/**
* @brief
*
* @param p_list file_list描述符
* @param p_node
* @param file_pointer
* @return int 0: 0:
*/
int file_list_get_node(struct file_list *p_list,struct file_list_node *p_node,uint64_t file_pointer)
{
FRESULT ret;
UINT btr;
UINT br;
ret=f_lseek(&p_list->fp,file_pointer);
if(ret!=FR_OK){
return -1;
}
btr=sizeof(struct file_list_node);
ret=f_read(&p_list->fp,p_node,btr,&br);
if(ret!=FR_OK || btr!=br){
return -2;
}
return 0;
}
/**
* @brief
*
* @param p_list file_list描述符
* @param p_node
* @return int 0: 0:
*/
int file_list_put_node(struct file_list *p_list,struct file_list_node *p_node)
{
FRESULT ret;
UINT btw;
UINT bw;
ret=f_lseek(&p_list->fp,p_node->file_pointer_this);
if(ret!=FR_OK){
return -1;
}
btw=sizeof(struct file_list_node);
ret=f_write(&p_list->fp,p_node,btw,&bw);
if(ret!=FR_OK || btw!=bw){
return -2;
}
return 0;
}
/**
* @brief
*
* @param p_list file_list描述符
* @param p_node
* @param p_data
* @param base_addr
* @param size
* @return int 0: 0:
*/
int file_list_get_data(struct file_list *p_list,struct file_list_node *p_node,uint8_t *p_data,uint64_t base_addr,uint64_t size)
{
FRESULT ret;
UINT btr;
UINT br;
ret=f_lseek(&p_list->fp,p_node->file_pointer_this+sizeof(struct file_list_node)+base_addr);
if(ret!=FR_OK){
return -1;
}
btr=size;
ret=f_read(&p_list->fp,p_data,btr,&br);
if(ret!=FR_OK || btr!=br){
return -2;
}
return 0;
}
/**
* @brief
*
* @param p_list file_list描述符
* @param p_node
* @param p_data
* @param base_addr
* @param size
* @return int 0: 0:
*/
int file_list_put_data(struct file_list *p_list,struct file_list_node *p_node,uint8_t *p_data,uint64_t base_addr,uint64_t size)
{
FRESULT ret;
UINT btw;
UINT bw;
ret=f_lseek(&p_list->fp,p_node->file_pointer_this+sizeof(struct file_list_node)+base_addr);
if(ret!=FR_OK){
return -1;
}
btw=size;
ret=f_write(&p_list->fp,p_data,btw,&bw);
if(ret!=FR_OK || btw!=bw){
return -2;
}
return 0;
}
/**
* @brief 使
*
* @param p_list file_list描述符
* @param p_node
* @param data_to_fill
* @return int 0: 0:
*/
int file_list_fill_data(struct file_list *p_list,struct file_list_node *p_node,uint8_t data_to_fill)
{
FRESULT ret;
UINT btw;
UINT bw;
uint64_t i;
ret=f_lseek(&p_list->fp,p_node->file_pointer_this+sizeof(struct file_list_node));
if(ret!=FR_OK){
return -1;
}
for(i=0;i<p_node->size;i++){
btw=1;
ret=f_write(&p_list->fp,&data_to_fill,btw,&bw);
if(ret!=FR_OK || btw!=bw){
return -2;
}
}
return 0;
}
/**
* @brief 使
*
* @param p_list file_list描述符
* @param path
* @return struct file_list* :p_list :NULL
*/
struct file_list *file_list_create(struct file_list *p_list,char *path)
{
FRESULT ret;
ret=f_open(&p_list->fp,path,FA_CREATE_ALWAYS|FA_READ|FA_WRITE);
if(ret!=FR_OK){
return NULL;
}
p_list->list_head.file_pointer_used_first=0;
p_list->list_head.file_pointer_used_last=0;
p_list->list_head.file_pointer_free_first=sizeof(struct file_list_head);
p_list->list_head.file_pointer_free_last=p_list->list_head.file_pointer_free_first;
p_list->free_node_now.file_pointer_last=0;
p_list->free_node_now.file_pointer_next=0;
p_list->free_node_now.file_pointer_this=p_list->list_head.file_pointer_free_last;
p_list->free_node_now.size=0xffffffffffffffff;
p_list->used_node_now.size_used=0;
p_list->used_node_now.file_pointer_last=0;
p_list->used_node_now.file_pointer_next=0;
p_list->used_node_now.file_pointer_this=0;
p_list->used_node_now.size=0;
p_list->used_node_now.size_used=0;
if(file_list_put_head(p_list,&p_list->list_head)!=0){
return NULL;
}
if(file_list_put_node(p_list,&p_list->free_node_now)!=0){
return NULL;
}
f_sync(&p_list->fp);
return p_list;
}
/**
* @brief 使,
*
* @param p_list file_list描述符
* @param path
* @return struct file_list* :p_list :NULL
*/
struct file_list *file_list_open(struct file_list *p_list,char *path)
{
FRESULT ret;
ret=f_open(&p_list->fp,path,FA_READ|FA_WRITE);
if(ret!=FR_OK){
return file_list_create(p_list,path);
}
if(file_list_get_head(p_list,&p_list->list_head)!=0){
return NULL;
}
if(p_list->list_head.file_pointer_used_first!=0){
if(file_list_get_node(p_list,&p_list->used_node_now,p_list->list_head.file_pointer_used_first)!=0){
return NULL;
}
}
else{
p_list->used_node_now.file_pointer_last=0;
p_list->used_node_now.file_pointer_next=0;
p_list->used_node_now.file_pointer_this=0;
p_list->used_node_now.size=0;
}
if(file_list_get_node(p_list,&p_list->free_node_now,p_list->list_head.file_pointer_free_first)!=0){
return NULL;
}
f_sync(&p_list->fp);
return p_list;
}
/**
* @brief
*
* @param p_list file_list描述符
* @return int 0: 0:
*/
int file_list_close(struct file_list *p_list)
{
FRESULT ret;
ret=f_sync(&p_list->fp);
if(ret!=FR_OK){
return -1;
}
ret=f_close(&p_list->fp);
if(ret!=FR_OK){
return -1;
}
return 0;
}
/**
* @brief 使
*
* @param p_list file_list描述符
* @param p_free_node 使
* @return int 0: 0:
*/
int file_list_merge_free_node(struct file_list *p_list,struct file_list_node *p_free_node)
{
struct file_list_node last_free_node;
struct file_list_node next_free_node;
struct file_list_node this_free_node;
this_free_node.size=p_free_node->size;
this_free_node.file_pointer_last=p_free_node->file_pointer_last;
this_free_node.file_pointer_next=p_free_node->file_pointer_next;
this_free_node.file_pointer_this=p_free_node->file_pointer_this;
if(p_free_node->file_pointer_last!=0){
if(file_list_get_node(p_list,&last_free_node,p_free_node->file_pointer_last)!=0){
return -1;
}
if(last_free_node.file_pointer_this+last_free_node.size+sizeof(struct file_list_node)==last_free_node.file_pointer_next){
// printf("<Merge [%llX,%llX]-->%llX,Size [%llX,%llX]-->%llX\n",last_free_node.file_pointer_this,this_free_node.file_pointer_this,last_free_node.file_pointer_this,last_free_node.size,this_free_node.size,this_free_node.size+last_free_node.size+sizeof(struct file_list_node));
this_free_node.file_pointer_last=last_free_node.file_pointer_last;
this_free_node.file_pointer_this=last_free_node.file_pointer_this;
this_free_node.size+=last_free_node.size+sizeof(struct file_list_node);
}
}
if(p_free_node->file_pointer_next!=0){
if(file_list_get_node(p_list,&next_free_node,p_free_node->file_pointer_next)!=0){
return -1;
}
if(this_free_node.file_pointer_this+this_free_node.size+sizeof(struct file_list_node)==this_free_node.file_pointer_next){
// printf(">Merge [%llX,%llX]-->%llX,Size [%llX,%llX]-->%llX\n",this_free_node.file_pointer_this,next_free_node.file_pointer_this,this_free_node.file_pointer_this,this_free_node.size,next_free_node.size,this_free_node.size+next_free_node.size+sizeof(struct file_list_node));
this_free_node.file_pointer_next=next_free_node.file_pointer_next;
this_free_node.size+=next_free_node.size+sizeof(struct file_list_node);
if(this_free_node.file_pointer_next!=0){
if(file_list_get_node(p_list,&next_free_node,this_free_node.file_pointer_next)!=0){
return -1;
}
next_free_node.file_pointer_last=this_free_node.file_pointer_this;
if(file_list_put_node(p_list,&next_free_node)!=0){
return -1;
}
}
else{
p_list->list_head.file_pointer_free_last=this_free_node.file_pointer_this;
if(file_list_put_head(p_list,&p_list->list_head)!=0){
return -1;
}
}
}
else{
next_free_node.file_pointer_last=this_free_node.file_pointer_this;
}
}
if(file_list_put_node(p_list,&this_free_node)!=0){
return -1;
}
if(this_free_node.file_pointer_next!=0){
if(file_list_put_node(p_list,&next_free_node)!=0){
return -1;
}
}
p_list->free_node_now.file_pointer_last=this_free_node.file_pointer_last;
p_list->free_node_now.file_pointer_next=this_free_node.file_pointer_next;
p_list->free_node_now.file_pointer_this=this_free_node.file_pointer_this;
p_list->free_node_now.size=this_free_node.size;
return 0;
}
/**
* @brief
*
* @param p_list file_list描述符
* @param size
* @return struct file_list_node* : :NULL
*/
struct file_list_node *file_list_alloc(struct file_list *p_list,uint64_t size)
{
struct file_list_node last_free_node;
struct file_list_node this_free_node;
struct file_list_node next_free_node;
uint64_t file_pointer;
this_free_node.file_pointer_last=0;
this_free_node.file_pointer_next=0;
this_free_node.file_pointer_this=0;
this_free_node.size=0;
file_pointer=p_list->list_head.file_pointer_free_first;
do{
last_free_node.file_pointer_last=this_free_node.file_pointer_last;
last_free_node.file_pointer_next=this_free_node.file_pointer_next;
last_free_node.file_pointer_this=this_free_node.file_pointer_this;
last_free_node.size=this_free_node.size;
if(file_list_get_node(p_list,&this_free_node,file_pointer)!=0){
return NULL;
}
file_pointer=this_free_node.file_pointer_next;
}while(this_free_node.size<size);
p_list->used_node_now.size=this_free_node.size;
p_list->free_node_now.file_pointer_last=this_free_node.file_pointer_last;
p_list->free_node_now.file_pointer_next=this_free_node.file_pointer_next;
p_list->free_node_now.file_pointer_this=this_free_node.file_pointer_this;
p_list->free_node_now.size=this_free_node.size;
p_list->used_node_now.file_pointer_this=this_free_node.file_pointer_this;
p_list->used_node_now.file_pointer_next=0;
p_list->used_node_now.size_used=size;
if(this_free_node.file_pointer_last!=0){
if(file_list_get_node(p_list,&last_free_node,this_free_node.file_pointer_last)!=0){
return NULL;
}
if(this_free_node.size>=size+sizeof(struct file_list_node)){
p_list->free_node_now.file_pointer_last=last_free_node.file_pointer_this;
p_list->free_node_now.file_pointer_this=p_list->used_node_now.file_pointer_this+size+sizeof(struct file_list_node);
last_free_node.file_pointer_next=p_list->free_node_now.file_pointer_this;
}
else{
last_free_node.file_pointer_next=this_free_node.file_pointer_next;
}
if(file_list_put_node(p_list,&last_free_node)!=0){
return NULL;
}
}
else{
if(this_free_node.size>=size+sizeof(struct file_list_node)){
p_list->free_node_now.file_pointer_this=p_list->used_node_now.file_pointer_this+size+sizeof(struct file_list_node);
p_list->list_head.file_pointer_free_first=p_list->free_node_now.file_pointer_this;
}
else{
p_list->list_head.file_pointer_free_first=this_free_node.file_pointer_next;
}
}
if(this_free_node.file_pointer_next!=0){
if(file_list_get_node(p_list,&next_free_node,this_free_node.file_pointer_next)!=0){
return NULL;
}
if(this_free_node.size>=size+sizeof(struct file_list_node)){
p_list->free_node_now.file_pointer_this=p_list->used_node_now.file_pointer_this+size+sizeof(struct file_list_node);
p_list->free_node_now.file_pointer_next=next_free_node.file_pointer_this;
next_free_node.file_pointer_last=p_list->free_node_now.file_pointer_this;
}
else{
next_free_node.file_pointer_last=this_free_node.file_pointer_last;
}
if(file_list_put_node(p_list,&next_free_node)!=0){
return NULL;
}
}
else{
if(this_free_node.size>=size+sizeof(struct file_list_node)){
p_list->free_node_now.file_pointer_this=p_list->used_node_now.file_pointer_this+size+sizeof(struct file_list_node);
p_list->list_head.file_pointer_free_last=p_list->free_node_now.file_pointer_this;
}
else{
p_list->list_head.file_pointer_free_last=this_free_node.file_pointer_last;
}
}
if(this_free_node.size>=size+sizeof(struct file_list_node)){
p_list->used_node_now.size=size;
p_list->free_node_now.size-=size+sizeof(struct file_list_node);
if(file_list_put_node(p_list,&p_list->free_node_now)!=0){
return NULL;
}
}
if(file_list_put_head(p_list,&p_list->list_head)!=0){
return NULL;
}
return &p_list->used_node_now;
}
/**
* @brief
*
* @param p_list file_list描述符
* @param p_node_to_free
* @return int 0: 0:
*/
int file_list_free_node(struct file_list *p_list,struct file_list_node *p_node_to_free)
{
struct file_list_node last_free_node;
struct file_list_node next_free_node;
uint64_t file_pointer;
next_free_node.file_pointer_this=0;
next_free_node.file_pointer_last=0;
next_free_node.size=0;
file_pointer=p_list->list_head.file_pointer_free_first;
do{
last_free_node.file_pointer_last=next_free_node.file_pointer_last;
last_free_node.file_pointer_this=next_free_node.file_pointer_this;
last_free_node.size=next_free_node.size;
if(file_list_get_node(p_list,&next_free_node,file_pointer)!=0){
return -1;
}
file_pointer=next_free_node.file_pointer_next;
}while(next_free_node.file_pointer_this<p_node_to_free->file_pointer_this);
if(last_free_node.file_pointer_this!=0){
last_free_node.file_pointer_next=p_node_to_free->file_pointer_this;
if(file_list_put_node(p_list,&last_free_node)!=0){
return -1;
}
}
else{
p_list->list_head.file_pointer_free_first=p_node_to_free->file_pointer_this;
}
next_free_node.file_pointer_last=p_node_to_free->file_pointer_this;
p_node_to_free->file_pointer_last=last_free_node.file_pointer_this;
p_node_to_free->file_pointer_next=next_free_node.file_pointer_this;
if(file_list_put_node(p_list,&next_free_node)!=0){
return -1;
}
if(file_list_put_node(p_list,p_node_to_free)!=0){
return -1;
}
return file_list_merge_free_node(p_list,p_node_to_free);
}
/**
* @brief
*
* @param p_list file_list描述符
* @param p_used_node
* @return int 0: 0:
*/
int file_list_del_node(struct file_list *p_list,struct file_list_node *p_used_node)
{
struct file_list_node last_used_node;
struct file_list_node next_used_node;
if(p_used_node->file_pointer_last!=0){
if(file_list_get_node(p_list,&last_used_node,p_used_node->file_pointer_last)!=0){
return -1;
}
last_used_node.file_pointer_next=p_used_node->file_pointer_next;
if(file_list_put_node(p_list,&last_used_node)!=0){
return -1;
}
}
else{
p_list->list_head.file_pointer_used_first=p_used_node->file_pointer_next;
}
if(p_used_node->file_pointer_next!=0){
if(file_list_get_node(p_list,&next_used_node,p_used_node->file_pointer_next)!=0){
return -1;
}
next_used_node.file_pointer_last=p_used_node->file_pointer_last;
if(file_list_put_node(p_list,&next_used_node)!=0){
return -1;
}
}
else{
p_list->list_head.file_pointer_used_last=p_used_node->file_pointer_last;
}
if(file_list_put_head(p_list,&p_list->list_head)!=0){
return -1;
}
return file_list_free_node(p_list,p_used_node);
}
/**
* @brief
*
* @param p_list file_list描述符
* @param size
* @return struct file_list_node* : :NULL
*/
struct file_list_node *file_list_add_node(struct file_list *p_list,uint64_t size)
{
struct file_list_node last_used_node;
struct file_list_node *pnode;
pnode=file_list_alloc(p_list,size);
if(pnode==NULL){
return NULL;
}
pnode->file_pointer_last=0;
pnode->file_pointer_next=0;
if(p_list->list_head.file_pointer_used_last!=0){
pnode->file_pointer_last=p_list->list_head.file_pointer_used_last;
if(file_list_get_node(p_list,&last_used_node,pnode->file_pointer_last)!=0){
return NULL;
}
last_used_node.file_pointer_next=pnode->file_pointer_this;
if(file_list_put_node(p_list,&last_used_node)!=0){
return NULL;
}
}
p_list->list_head.file_pointer_used_last=pnode->file_pointer_this;
if(p_list->list_head.file_pointer_used_first==0){
p_list->list_head.file_pointer_used_first=pnode->file_pointer_this;
}
if(file_list_put_head(p_list,&p_list->list_head)!=0){
return NULL;
}
if(file_list_put_node(p_list,pnode)!=0){
return NULL;
}
f_sync(&p_list->fp);
return pnode;
}
/**
* @brief
*
* @param p_list file_list描述符
* @return struct file_list_node* : :NULL
*/
struct file_list_node *file_list_get_first_node(struct file_list *p_list)
{
if(p_list->list_head.file_pointer_used_first==0){
return NULL;
}
if(file_list_get_node(p_list,&p_list->used_node_now,p_list->list_head.file_pointer_used_first)!=0){
return NULL;
}
return &p_list->used_node_now;
}
/**
* @brief
*
* @param p_list file_list描述符
* @return struct file_list_node* : :NULL
*/
struct file_list_node *file_list_get_next_node(struct file_list *p_list)
{
if(p_list->used_node_now.file_pointer_next==0){
return NULL;
}
if(file_list_get_node(p_list,&p_list->used_node_now,p_list->used_node_now.file_pointer_next)!=0){
return NULL;
}
return &p_list->used_node_now;
}
/**
* @brief
*
* @param p_list file_list描述符
* @return struct file_list_node* : :NULL
*/
struct file_list_node *file_list_get_last_node(struct file_list *p_list)
{
if(p_list->used_node_now.file_pointer_last==0){
return NULL;
}
if(file_list_get_node(p_list,&p_list->used_node_now,p_list->used_node_now.file_pointer_last)!=0){
return NULL;
}
return &p_list->used_node_now;
}
/**
* @brief
*
* @param p_list file_list描述符
* @param p_node
* @return uint64_t
*/
uint64_t file_list_get_node_size(struct file_list *p_list,struct file_list_node *p_node)
{
return p_node->size_used;
}
/**
* @brief
*
* @param p_list file_list描述符
* @param p_node
* @param buf
* @param base_addr
* @param size
* @return uint64_t
*/
uint64_t file_list_get_node_data(struct file_list *p_list,struct file_list_node *p_node,void *buf,uint64_t base_addr,uint64_t size)
{
size=(base_addr+size>p_node->size_used)?p_node->size_used-base_addr:size;
if(file_list_get_data(p_list,p_node,buf,base_addr,size)!=0){
return 0;
}
return size;
}
/**
* @brief
*
* @param p_list file_list描述符
* @param p_node
* @param buf
* @param base_addr
* @param size
* @return uint64_t
*/
uint64_t file_list_put_node_data(struct file_list *p_list,struct file_list_node *p_node,void *buf,uint64_t base_addr,uint64_t size)
{
size=(base_addr+size>p_node->size_used)?p_node->size_used-base_addr:size;
if(file_list_put_data(p_list,p_node,buf,base_addr,size)!=0){
return 0;
}
f_sync(&p_list->fp);
return size;
}